diff --git a/DDG4/plugins/Geant4RegexSensitivesConstruction.cpp b/DDG4/plugins/Geant4RegexSensitivesConstruction.cpp index 6bb17fecb..8aa24ed26 100644 --- a/DDG4/plugins/Geant4RegexSensitivesConstruction.cpp +++ b/DDG4/plugins/Geant4RegexSensitivesConstruction.cpp @@ -104,7 +104,7 @@ Geant4RegexSensitivesConstruction::collect_volumes(std::set& volumes, if( !path.empty() ) { for( const auto& match : matches ) { std::smatch sm; - bool stat = std::regex_match(path, sm, match); + bool stat = std::regex_search(path, sm, match); if( stat ) { volumes.insert(pv.volume()); ++count; @@ -151,18 +151,18 @@ void Geant4RegexSensitivesConstruction::constructSensitives(Geant4DetectorConstr expressions.emplace_back(e); } TTimeStamp start; - print("+++ Detector: %s Starting to scan volume....", det); + info("%s Starting to scan volume....", det); std::size_t num_nodes = this->collect_volumes(volumes, de.placement(), de.placementPath(), expressions); for( const auto& vol : volumes ) { G4LogicalVolume* g4vol = g4info->g4Volumes[vol]; if( !g4vol ) { except("+++ Failed to access G4LogicalVolume for SD %s of type %s", nam.c_str(), typ.c_str()); } - print("+++ Detector: %s Assign sensitive detector [%s] to volume: %s.", + debug("%s Assign sensitive detector [%s] to volume: %s.", nam.c_str(), typ.c_str(), vol.name()); ctxt->setSensitiveDetector(g4vol, g4sd); } TTimeStamp stop; - print("+++ Detector: %s Handled %ld nodes with %ld sensitive volume type(s). Total of %7.3f seconds.", - det, num_nodes, volumes.size(), stop.AsDouble()-start.AsDouble() ); + info("%s Handled %ld nodes with %ld sensitive volume type(s). Total of %7.3f seconds.", + det, num_nodes, volumes.size(), stop.AsDouble()-start.AsDouble() ); } diff --git a/DDG4/python/DDSim/Helper/Geometry.py b/DDG4/python/DDSim/Helper/Geometry.py index c7c7e85d2..dbc84602a 100644 --- a/DDG4/python/DDSim/Helper/Geometry.py +++ b/DDG4/python/DDSim/Helper/Geometry.py @@ -35,8 +35,46 @@ def __init__(self): self._dumpDGDML_EXTRA = {"help": "If not empty, filename to dump the Geometry as GDML"} self.dumpGDML = "" + + self._regexSDDetectorList = [] + self._closeProperties() + @property + def regexSensitiveDetector(self): + """Configure a sensitive detector for a given detector matched by regular expression (regex). + + 'Detector' and 'Match' are mandatory elements of the dictionary, other Keys are assigned as property to the object. + + >>> SIM.geometry.regexSensitiveDetector = {'Detector': 'DRcalo', + 'Match': ['(core|clad)'], + 'OutputLevel': 3, + } + + This can be assigned repeatedly to add multiple RegexSDs + """ + return self._regexSDDetectorList + + @regexSensitiveDetector.setter + def regexSensitiveDetector(self, val): + if not val: + return + if isinstance(val, dict): + self.__checkRegexKeys(val) + self._regexSDDetectorList.append(val) + elif isinstance(val, list): + for value in val: + self.__checkRegexKeys(value) + self._regexSDDetectorList.append(value) + raise RuntimeError(f"Unsupported type for regexSensitiveDetector: {val!r}") + + @staticmethod + def __checkRegexKeys(val): + """Check the regex SD arguments for required keys.""" + requiredKeys = ('Detector', 'Match') + if not all(key in val for key in requiredKeys): + raise RuntimeError(f"RegexSD configuration {val} is missing mandatory key(s): {', '.join(requiredKeys)}") + def constructGeometry(self, kernel, geant4, geoPrintLevel=2, numberOfThreads=1): """Construct Geant4 geometry.""" from DDG4 import DetectorConstruction @@ -60,3 +98,9 @@ def constructGeometry(self, kernel, geant4, geoPrintLevel=2, numberOfThreads=1): sensitives = DetectorConstruction(kernel, str('Geant4DetectorSensitivesConstruction/ConstructSD')) sensitives.enableUI() seq.adopt(sensitives) + + for index, regexDetectors in enumerate(self._regexSDDetectorList): + seq, act = geant4.addDetectorConstruction(f'Geant4RegexSensitivesConstruction/ConstrSDRegEx_{index}') + # this will set Match and Detector, and other properties if possible + for key, value in regexDetectors.items(): + setattr(act, key, value) diff --git a/examples/ClientTests/scripts/BoxOfStraws.py b/examples/ClientTests/scripts/BoxOfStraws.py index f4f5d4a67..00cc33d03 100644 --- a/examples/ClientTests/scripts/BoxOfStraws.py +++ b/examples/ClientTests/scripts/BoxOfStraws.py @@ -73,7 +73,7 @@ def run(): seq, act = geant4.addDetectorConstruction('Geant4RegexSensitivesConstruction/ConstructSDRegEx') act.Detector = 'BoxOfStrawsDet' act.OutputLevel = Output.ALWAYS - act.Match = ['/world_volume_(.*)/BoxOfStrawsDet_(.*)/layer_(.*)/straw_(.*)/gas_(.*)'] + act.Match = ['gas_'] # seq, act = geant4.addDetectorConstruction('Geant4DetectorConstructionResources/ResourcesAfterConstruction') act.When = "sensitives"