Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:20

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 //  \author Markus Frank
0011 //  \date   2015-11-09
0012 //
0013 //==========================================================================
0014 
0015 // Framework include files
0016 #include <DDG4/Geant4DetectorConstruction.h>
0017 
0018 // C/C++ include files
0019 #include <set>
0020 #include <regex>
0021 
0022 /// Namespace for the AIDA detector description toolkit
0023 namespace dd4hep {
0024 
0025   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0026   namespace sim {
0027 
0028     /// Class to create Geant4 detector geometry from TGeo representation in memory
0029     /**
0030      *  On demand the sensitive detectors are created and attached to all sensitive
0031      *  volumes. The relevant  callback is executed when the call to 
0032      *  ConstructSDandField() of the corresponding G4VUserDetectorConstruction
0033      *  instance is called. The call is thread-local!
0034      *
0035      *  \author  M.Frank
0036      *  \version 1.0
0037      *  \ingroup DD4HEP_SIMULATION
0038      */
0039     class Geant4RegexSensitivesConstruction : public Geant4DetectorConstruction   {
0040     public:
0041       std::string detector_name;
0042       std::vector<std::string> regex_values;
0043       std::size_t collect_volumes(std::set<Volume>&  volumes,
0044                                   PlacedVolume       pv,
0045                                   const std::string& path,
0046                                   const std::vector<std::regex>& matches);
0047     public:
0048       /// Initializing constructor for DDG4
0049       Geant4RegexSensitivesConstruction(Geant4Context* ctxt, const std::string& nam);
0050       /// Default destructor
0051       virtual ~Geant4RegexSensitivesConstruction();
0052       /// Sensitives construction callback. Called at "ConstructSDandField()"
0053       void constructSensitives(Geant4DetectorConstructionContext* ctxt);
0054     };
0055   }    // End namespace sim
0056 }      // End namespace dd4hep
0057 
0058 
0059 // Framework include files
0060 #include <DD4hep/InstanceCount.h>
0061 #include <DD4hep/Printout.h>
0062 #include <DD4hep/Plugins.h>
0063 #include <DD4hep/Detector.h>
0064 #include <DD4hep/DetectorTools.h>
0065 
0066 #include <DDG4/Geant4Mapping.h>
0067 #include <DDG4/Geant4Kernel.h>
0068 #include <DDG4/Factories.h>
0069 
0070 // ROOT include files
0071 #include <TTimeStamp.h>
0072 #include <TGeoManager.h>
0073 // Geant4 include files
0074 #include <G4PVPlacement.hh>
0075 #include <G4VSensitiveDetector.hh>
0076 
0077 using namespace dd4hep::sim;
0078 
0079 DECLARE_GEANT4ACTION(Geant4RegexSensitivesConstruction)
0080 
0081 /// Initializing constructor for other clients
0082 Geant4RegexSensitivesConstruction::Geant4RegexSensitivesConstruction(Geant4Context* ctxt, const std::string& nam)
0083 : Geant4DetectorConstruction(ctxt,nam)
0084 {
0085   declareProperty("Detector", detector_name);
0086   declareProperty("Match",    regex_values);
0087   InstanceCount::increment(this);
0088 }
0089 
0090 /// Default destructor
0091 Geant4RegexSensitivesConstruction::~Geant4RegexSensitivesConstruction() {
0092   InstanceCount::decrement(this);
0093 }
0094 
0095 std::size_t
0096 Geant4RegexSensitivesConstruction::collect_volumes(std::set<Volume>&  volumes,
0097                                                    PlacedVolume       pv,
0098                                                    const std::string& path,
0099                                                    const std::vector<std::regex>& matches)
0100 {
0101   std::size_t count = 0;
0102   // Try to minimize a bit the number of regex matches.
0103   if ( volumes.find(pv.volume()) == volumes.end() )  {
0104     if( !path.empty() )  {
0105       for( const auto& match : matches )  {
0106         std::smatch sm;
0107         bool stat = std::regex_search(path, sm, match);
0108         if( stat )  {
0109           volumes.insert(pv.volume());
0110           ++count;
0111           break;
0112         }
0113       }
0114     }
0115     // Now recurse down the daughters
0116     for( int i=0, num = pv->GetNdaughters(); i < num; ++i )  {
0117       PlacedVolume daughter = pv->GetDaughter(i);
0118       std::string  daughter_path = path + "/" + daughter.name();
0119       count += this->collect_volumes(volumes, daughter, daughter_path, matches);
0120     }
0121   }
0122   return count;
0123 }
0124 
0125 /// Sensitive detector construction callback. Called at "ConstructSDandField()"
0126 void Geant4RegexSensitivesConstruction::constructSensitives(Geant4DetectorConstructionContext* ctxt)   {
0127   Geant4GeometryInfo* g4info = Geant4Mapping::instance().ptr();
0128   const Geant4Kernel& kernel = context()->kernel();
0129   const auto&         types  = kernel.sensitiveDetectorTypes();
0130   const std::string&  dflt   = kernel.defaultSensitiveDetectorType();
0131   const char*         det    = detector_name.c_str();
0132   
0133   DetElement de = detail::tools::findElement(ctxt->description, detector_name);
0134   if( !de.isValid() )  {
0135     except("Failed to locate subdetector DetElement %s to manage Geant4 energy deposits.", det);
0136   }
0137   SensitiveDetector sd = ctxt->description.sensitiveDetector(detector_name);
0138   if( !sd.isValid() )  {
0139     except("Failed to locate sensitive detector %s to manage Geant4 energy deposits.", det);
0140   }
0141   std::string nam  = sd.name();
0142   auto        iter = types.find(nam);
0143   std::string typ  = (iter != types.end()) ? (*iter).second : dflt;
0144   G4VSensitiveDetector* g4sd = this->createSensitiveDetector(typ, nam);
0145 
0146   std::set<Volume> volumes;
0147   int flags = std::regex_constants::icase | std::regex_constants::ECMAScript;
0148   std::vector<std::regex> expressions;
0149   for( const auto& val : regex_values )  {
0150     std::regex e(val, (std::regex_constants::syntax_option_type)flags);
0151     expressions.emplace_back(e);
0152   }
0153   TTimeStamp start;
0154   info("%s Starting to scan volume....", det);
0155   std::size_t num_nodes = this->collect_volumes(volumes, de.placement(), de.placementPath(), expressions);
0156   for( const auto& vol : volumes )  {
0157     G4LogicalVolume* g4vol = g4info->g4Volumes[vol];
0158     if( !g4vol )  {
0159       except("+++ Failed to access G4LogicalVolume for SD %s of type %s", nam.c_str(), typ.c_str());
0160     }
0161     debug("%s Assign sensitive detector [%s] to volume: %s.",
0162           nam.c_str(), typ.c_str(), vol.name());
0163     ctxt->setSensitiveDetector(g4vol, g4sd);
0164   }
0165   TTimeStamp stop;
0166   info("%s Handled %ld nodes with %ld sensitive volume type(s). Total of %7.3f seconds.",
0167        det, num_nodes, volumes.size(), stop.AsDouble()-start.AsDouble() );
0168 }