File indexing completed on 2025-01-18 09:14:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <DDG4/Geant4DetectorConstruction.h>
0017
0018
0019 #include <set>
0020 #include <regex>
0021
0022
0023 namespace dd4hep {
0024
0025
0026 namespace sim {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
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
0049 Geant4RegexSensitivesConstruction(Geant4Context* ctxt, const std::string& nam);
0050
0051 virtual ~Geant4RegexSensitivesConstruction();
0052
0053 void constructSensitives(Geant4DetectorConstructionContext* ctxt);
0054 };
0055 }
0056 }
0057
0058
0059
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
0071 #include <TTimeStamp.h>
0072 #include <TGeoManager.h>
0073
0074 #include <G4PVPlacement.hh>
0075 #include <G4VSensitiveDetector.hh>
0076
0077 using namespace dd4hep::sim;
0078
0079 DECLARE_GEANT4ACTION(Geant4RegexSensitivesConstruction)
0080
0081
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
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
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
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
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 }