DD4hep  1.37.0
Detector Description Toolkit for High Energy Physics
Geant4RegexSensitivesConstruction.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // \author Markus Frank
11 // \date 2015-11-09
12 //
13 //==========================================================================
14 
15 // Framework include files
17 
18 // C/C++ include files
19 #include <set>
20 #include <regex>
21 
23 namespace dd4hep {
24 
26  namespace sim {
27 
29 
40  public:
41  std::string detector_name;
42  std::vector<std::string> regex_values;
43  // Cached result from the first call: TGeo geometry is shared across worker
44  // threads so the matching volume set is identical every call. Subsequent
45  // calls skip the tree traversal and reuse this directly.
46  std::set<Volume> m_cached_volumes;
47  bool m_volumes_cached {false};
48  std::size_t collect_volumes(std::set<Volume>& volumes,
49  std::set<Volume>& visited,
50  PlacedVolume pv,
51  std::string& path,
52  const std::vector<std::regex>& matches);
53  public:
55  Geant4RegexSensitivesConstruction(Geant4Context* ctxt, const std::string& nam);
60  };
61  } // End namespace sim
62 } // End namespace dd4hep
63 
64 
65 // Framework include files
66 #include <DD4hep/InstanceCount.h>
67 #include <DD4hep/Printout.h>
68 #include <DD4hep/Plugins.h>
69 #include <DD4hep/Detector.h>
70 #include <DD4hep/DetectorTools.h>
71 
72 #include <DDG4/Geant4Mapping.h>
73 #include <DDG4/Geant4Kernel.h>
74 #include <DDG4/Factories.h>
75 
76 // ROOT include files
77 #include <TTimeStamp.h>
78 #include <TGeoManager.h>
79 // Geant4 include files
80 #include <G4PVPlacement.hh>
81 #include <G4VSensitiveDetector.hh>
82 
83 using namespace dd4hep::sim;
84 
86 
90 {
91  declareProperty("Detector", detector_name);
92  declareProperty("Match", regex_values);
94 }
95 
99 }
100 
101 std::size_t
103  std::set<Volume>& visited,
104  PlacedVolume pv,
105  std::string& path,
106  const std::vector<std::regex>& matches)
107 {
108  std::size_t count = 0;
109  // visited guards on logical volume: each unique Volume is walked exactly once
110  // regardless of how many times it is placed in the geometry tree.
111  if ( visited.insert(pv.volume()).second ) {
112  for( const auto& match : matches ) {
113  std::smatch sm;
114  if( std::regex_search(path, sm, match) ) {
115  volumes.insert(pv.volume());
116  ++count;
117  break;
118  }
119  }
120  // Recurse into daughters, reusing the path string in-place.
121  const std::size_t base_len = path.size();
122  for( int i=0, num = pv->GetNdaughters(); i < num; ++i ) {
123  PlacedVolume daughter = pv->GetDaughter(i);
124  path += '/';
125  path += daughter.name();
126  count += this->collect_volumes(volumes, visited, daughter, path, matches);
127  path.resize(base_len);
128  }
129  }
130  return count;
131 }
132 
136  const Geant4Kernel& kernel = context()->kernel();
137  const auto& types = kernel.sensitiveDetectorTypes();
138  const std::string& dflt = kernel.defaultSensitiveDetectorType();
139  const char* det = detector_name.c_str();
140 
142  if( !de.isValid() ) {
143  except("Failed to locate subdetector DetElement %s to manage Geant4 energy deposits.", det);
144  }
146  if( !sd.isValid() ) {
147  except("Failed to locate sensitive detector %s to manage Geant4 energy deposits.", det);
148  }
149  std::string nam = sd.name();
150  auto iter = types.find(nam);
151  std::string typ = (iter != types.end()) ? (*iter).second : dflt;
152  G4VSensitiveDetector* g4sd = this->createSensitiveDetector(typ, nam);
153 
154  TTimeStamp start;
155  std::size_t num_nodes = 0;
156  if( !m_volumes_cached ) {
157  int flags = std::regex_constants::icase | std::regex_constants::ECMAScript;
158  std::vector<std::regex> expressions;
159  for( const auto& val : regex_values ) {
160  std::regex e(val, (std::regex_constants::syntax_option_type)flags);
161  expressions.emplace_back(e);
162  }
163  info("%s Starting to scan volume....", det);
164  std::set<Volume> visited;
165  std::string placement_path = de.placementPath();
166  num_nodes = this->collect_volumes(m_cached_volumes, visited, de.placement(), placement_path, expressions);
167  m_volumes_cached = true;
168  }
169  else {
170  info("%s Reusing cached volume set (%zu volumes).", det, m_cached_volumes.size());
171  }
172  const std::set<Volume>& volumes = m_cached_volumes;
173  for( const auto& vol : volumes ) {
174  G4LogicalVolume* g4vol = g4info->g4Volumes[vol];
175  if( !g4vol ) {
176  except("+++ Failed to access G4LogicalVolume for SD %s of type %s", nam.c_str(), typ.c_str());
177  }
178  debug("%s Assign sensitive detector [%s] to volume: %s.",
179  nam.c_str(), typ.c_str(), vol.name());
180  ctxt->setSensitiveDetector(g4vol, g4sd);
181  }
182  TTimeStamp stop;
183  info("%s Handled %ld nodes with %ld sensitive volume type(s). Total of %7.3f seconds.",
184  det, num_nodes, volumes.size(), stop.AsDouble()-start.AsDouble() );
185 }
Geant4DetectorConstruction.h
Geant4Mapping.h
dd4hep::sim::Geant4RegexSensitivesConstruction::~Geant4RegexSensitivesConstruction
virtual ~Geant4RegexSensitivesConstruction()
Default destructor.
Definition: Geant4RegexSensitivesConstruction.cpp:97
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:43
Detector.h
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:164
dd4hep::sim::Geant4RegexSensitivesConstruction
Class to create Geant4 detector geometry from TGeo representation in memory.
Definition: Geant4RegexSensitivesConstruction.cpp:39
dd4hep::DetElement::placement
PlacedVolume placement() const
Access to the physical volume of this detector element.
Definition: DetElement.cpp:321
dd4hep::sim::Geant4Kernel
Class, which allows all Geant4Action derivatives to access the DDG4 kernel structures.
Definition: Geant4Kernel.h:64
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
dd4hep::InstanceCount::increment
static void increment(T *)
Increment count according to type information.
Definition: InstanceCount.h:98
dd4hep::sim::Geant4Mapping::instance
static Geant4Mapping & instance()
Possibility to define a singleton instance.
Definition: Geant4Mapping.cpp:36
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
DECLARE_GEANT4ACTION
#define DECLARE_GEANT4ACTION(name)
Plugin defintion to create Geant4Action objects.
Definition: Factories.h:210
dd4hep::detail::tools::findElement
DetElement findElement(const Detector &description, const std::string &path)
Find DetElement as child of the top level volume by its absolute path.
Definition: DetectorTools.cpp:221
dd4hep::sim::Geant4Action::info
void info(const char *fmt,...) const
Support of info messages.
Definition: Geant4Action.cpp:215
dd4hep::sim::Geant4Action::except
void except(const char *fmt,...) const
Support of exceptions: Print fatal message and throw runtime_error.
Definition: Geant4Action.cpp:256
dd4hep::sim::Geant4DetectorConstructionContext
Geant4 detector construction context definition.
Definition: Geant4DetectorConstruction.h:61
dd4hep::sim::Geant4Kernel::sensitiveDetectorTypes
const std::map< std::string, std::string > & sensitiveDetectorTypes() const
Property access: Names with specialized factories to create G4VSensitiveDetector instances.
Definition: Geant4Kernel.h:224
dd4hep::sim::Geant4RegexSensitivesConstruction::m_cached_volumes
std::set< Volume > m_cached_volumes
Definition: Geant4RegexSensitivesConstruction.cpp:46
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::sim::Geant4DetectorConstructionContext::description
Detector & description
Reference to geometry object.
Definition: Geant4DetectorConstruction.h:67
dd4hep::sim::Geant4Mapping::ptr
Geant4GeometryInfo * ptr() const
Access to the data pointer.
Definition: Geant4Mapping.h:70
G4VSensitiveDetector
Class of the Geant4 toolkit. See http://www-geant4.kek.jp/Reference.
Definition: Geant4Classes.h:59
dd4hep::sim::Geant4RegexSensitivesConstruction::m_volumes_cached
bool m_volumes_cached
Definition: Geant4RegexSensitivesConstruction.cpp:47
DetectorTools.h
dd4hep::Detector::sensitiveDetector
virtual SensitiveDetector sensitiveDetector(const std::string &name) const =0
Retrieve a sensitive detector by its name from the detector description.
dd4hep::sim::Geant4Action::declareProperty
Geant4Action & declareProperty(const std::string &nam, T &val)
Declare property.
Definition: Geant4Action.h:366
dd4hep::InstanceCount::decrement
static void decrement(T *)
Decrement count according to type information.
Definition: InstanceCount.h:102
dd4hep::sim::Geant4Kernel::defaultSensitiveDetectorType
const std::string defaultSensitiveDetectorType() const
Property access: Name of the default factory to create G4VSensitiveDetector instances.
Definition: Geant4Kernel.h:220
dd4hep::sim::Geant4RegexSensitivesConstruction::constructSensitives
void constructSensitives(Geant4DetectorConstructionContext *ctxt)
Sensitives construction callback. Called at "ConstructSDandField()".
Definition: Geant4RegexSensitivesConstruction.cpp:134
Plugins.h
dd4hep::DetElement::placementPath
const std::string & placementPath() const
Access to the full path to the placed object.
Definition: DetElement.cpp:85
Factories.h
dd4hep::sim::Geant4RegexSensitivesConstruction::detector_name
std::string detector_name
Definition: Geant4RegexSensitivesConstruction.cpp:41
dd4hep::sim
Namespace for the Geant4 based simulation part of the AIDA detector description toolkit.
Definition: EDM4hepFileReader.cpp:46
dd4hep::sim::Geant4Context::kernel
Geant4Kernel & kernel() const
Access to the kernel object.
Definition: Geant4Context.h:233
dd4hep::sim::Geant4GeometryInfo
Concreate class holding the relation information between geant4 objects and dd4hep objects.
Definition: Geant4GeometryInfo.h:91
dd4hep::sim::Geant4RegexSensitivesConstruction::collect_volumes
std::size_t collect_volumes(std::set< Volume > &volumes, std::set< Volume > &visited, PlacedVolume pv, std::string &path, const std::vector< std::regex > &matches)
Definition: Geant4RegexSensitivesConstruction.cpp:102
dd4hep::sim::Geant4DetectorConstructionContext::setSensitiveDetector
void setSensitiveDetector(G4LogicalVolume *vol, G4VSensitiveDetector *sd)
Helper: Assign sensitive detector to logical volume.
Definition: Geant4DetectorConstruction.cpp:27
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::PlacedVolume::volume
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:468
dd4hep::sim::Geant4Action::debug
void debug(const char *fmt,...) const
Support of debug messages.
Definition: Geant4Action.cpp:207
Geant4Kernel.h
InstanceCount.h
dd4hep::sim::Geant4DetectorConstruction
Basic implementation of the Geant4 detector construction action.
Definition: Geant4DetectorConstruction.h:102
dd4hep::sim::Geant4RegexSensitivesConstruction::regex_values
std::vector< std::string > regex_values
Definition: Geant4RegexSensitivesConstruction.cpp:42
Printout.h
dd4hep::sim::Geant4Context
Generic context to extend user, run and event information.
Definition: Geant4Context.h:201
dd4hep::sim::Geant4RegexSensitivesConstruction::Geant4RegexSensitivesConstruction
Geant4RegexSensitivesConstruction(Geant4Context *ctxt, const std::string &nam)
Initializing constructor for DDG4.
Definition: Geant4RegexSensitivesConstruction.cpp:88
dd4hep::sim::Geant4Action::context
Geant4Context * context() const
Access the context.
Definition: Geant4Action.h:270
dd4hep::sim::Geant4GeometryInfo::g4Volumes
Geant4GeometryMaps::VolumeMap g4Volumes
Definition: Geant4GeometryInfo.h:114