|
DD4hep
1.30.0
Detector Description Toolkit for High Energy Physics
|
Go to the documentation of this file.
24 #include <G4VTouchable.hh>
25 #include <G4LogicalVolume.hh>
26 #include <G4VPhysicalVolume.hh>
35 using VolIDDescriptor = std::pair<VolumeID,std::vector<std::pair<const BitFieldElement*, VolumeID> > >;
42 typedef std::vector<const TGeoNode*> Chain;
43 typedef std::map<VolumeID,Geant4GeometryInfo::Geant4PlacementPath> Registries;
54 : m_detDesc(description), m_geo(g) {
60 for (
const auto& i : c) {
69 scanPhysicalVolume(pv.
ptr(), std::move(ids), sd, chain);
72 printout(WARNING,
"Geant4VolumeManager",
73 "++ Detector element %s of type %s has no placement.", de.
name(), de.
type().c_str());
77 if ( pv.second->IsParameterised() )
79 if ( pv.second->IsReplicated() )
90 chain.emplace_back(node);
91 ids.PlacedVolume::VolIDs::Base::insert(ids.end(), pv_ids.begin(), pv_ids.end());
95 add_entry(sd, node, ids, chain);
98 printout(WARNING,
"Geant4VolumeManager",
99 "populate: Strange constellation volume %s is sensitive, but has no readout! sd:%p", pv.
volume().
name(),
103 for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
104 TGeoNode* daughter = node->GetDaughter(idau);
106 if ( placement.
data() ) {
107 scanPhysicalVolume(daughter, ids, sd, chain);
116 const TGeoNode* node =
nullptr;
121 Registries::const_iterator i = m_entries.find(code);
123 PrintLevel print_action = print_level;
124 PrintLevel print_chain = print_level;
125 PrintLevel print_res = print_level;
127 printout(print_action,
"Geant4VolumeManager",
"+++ Add path:%s vid:%016X",
130 if( i == m_entries.end() ) {
131 path.reserve(nodes.size());
132 for( Chain::const_reverse_iterator k = nodes.rbegin(), kend=nodes.rend(); k != kend; ++k ) {
136 G4VPhysicalVolume* phys = g4pit->second;
137 if( phys->IsParameterised() ) {
144 path.emplace_back(phys);
145 printout(print_chain,
"Geant4VolumeManager",
"+++ Chain: Node OK: %s [%s]",
146 node->GetName(), phys->GetName().c_str());
149 control.insert(control.begin(),node);
150 vol =
Volume(node->GetVolume());
153 for(
const auto& imp : iVolImp->second ) {
154 const auto& c = imp.first;
155 if ( c.size() <= control.size() && control == c ) {
156 path.emplace_back(imp.second);
157 printout(print_chain,
"Geant4VolumeManager",
"+++ Chain: Node OK: %s %s -> %s",
159 imp.second->GetName().c_str());
166 if ( control.empty() ) {
167 printout(print_res,
"Geant4VolumeManager",
"+++ Volume IDs:%s",
169 path.erase(path.begin()+path.size()-1);
170 printout(print_res,
"Geant4VolumeManager",
"+++ Map %016X to Geant4 Path:%s",
174 for(
const auto* phys : path) {
181 m_entries.emplace(code,path);
185 if ( !path.empty() && (path.front()->IsParameterised() || path.front()->IsReplicated()) ) {
188 printout(ERROR,
"Geant4VolumeManager",
"populate: Severe error: Duplicated Geant4 path!!!! %s %s",
192 printout(INFO,
"Geant4VolumeManager",
"Control block has still %d entries:%s",
198 if ( !path.empty() && (path.front()->IsParameterised() || path.front()->IsReplicated()) ) {
202 printout(ERROR,
"Geant4VolumeManager",
"populate: Severe error: Duplicated Volume entry: 0x%X"
203 " [THIS SHOULD NEVER HAPPEN]", code);
206 if ( i != m_entries.end() )
210 if ( !nodes.empty() )
213 throw std::runtime_error(
"Failed to populate Geant4 volume manager!");
222 Populator p(description, *
info);
223 p.populate(description.
world());
226 except(
"Geant4VolumeManager",
"Attempt populate from invalid Geant4 geometry info [Invalid-Info]");
230 std::vector<const G4VPhysicalVolume*>
239 except(
"Geant4VolumeManager",
"Attempt to use invalid Geant4 volume manager [Invalid-Handle]");
242 except(
"Geant4VolumeManager",
"Attempt to use invalid Geant4 geometry info [Invalid-Info]");
254 return (*i).second.first;
258 else if (!path[0]->GetLogicalVolume()->GetSensitiveDetector())
261 printout(INFO,
"Geant4VolumeManager",
"+++ Bad volume Geant4 Path: %s",
270 std::vector<const G4VPhysicalVolume*> path = handler.
placementPath();
275 const auto& e = (*i).second;
281 const auto& paramterised =
ptr()->g4Parameterised;
282 const auto& replicated =
ptr()->g4Replicated;
284 for( std::size_t j=0; j < path.size(); ++j ) {
285 const auto* phys = path[j];
286 if( phys->IsParameterised() ) {
287 int copy_no = touchable->GetCopyNumber(j);
288 const auto it = paramterised.find(phys);
289 if( it != paramterised.end() ) {
292 const auto* field = (*it).second.data()->params->field;
296 except(
"Geant4VolumeManager",
"Error Geant4VolumeManager::volumeID(const G4VTouchable* touchable)");
298 else if( phys->IsReplicated() ) {
299 int copy_no = touchable->GetCopyNumber(j);
300 const auto it = replicated.find(phys);
301 if( it != replicated.end() ) {
302 const auto* field = (*it).second.data()->params->field;
306 except(
"Geant4VolumeManager",
"Error Geant4VolumeManager::volumeID(const G4VTouchable* touchable)");
313 else if( !path[0]->GetLogicalVolume()->GetSensitiveDetector() )
316 printout(INFO,
"Geant4VolumeManager",
"+++ Bad volume Geant4 Path: %s",
325 vol_desc.second.clear();
331 VolumeID vid = (*i).second.volumeID;
332 G4LogicalVolume* lvol = path[0]->GetLogicalVolume();
333 if( lvol->GetSensitiveDetector() ) {
334 const auto* node = path[0];
335 const auto& pm =
ptr()->g4Placements;
336 for(
const auto& ipm : pm ) {
337 if ( ipm.second == node ) {
341 vol_desc.first = vid;
352 else if( !path[0]->GetLogicalVolume()->GetSensitiveDetector() )
void decodeFields(VolumeID vid, std::vector< std::pair< const BitFieldElement *, VolumeID > > &fields) const
Decode volume IDs and return filled descriptor with all fields.
const Children & children() const
Access to the list of children.
Geant4VolumeManager()=default
Default constructor.
static std::string placementPath(const Geant4PlacementPath &path, bool reverse=true)
Assemble Geant4 volume path.
Helper class to ease the extraction of information from a G4Touchable object.
virtual DetElement world() const =0
Return reference to the top-most (world) detector element.
Geant4PlacementPath placementPath(bool exception=false) const
Helper: Generate placement path from touchable object.
Handle class to hold the information of a sensitive detector.
Implementation class extending the ROOT placed volume.
const BitFieldElement * field(const std::string &field_name) const
Get the field descriptor of one field by name.
std::size_t info(const std::string &src, const std::string &msg)
void exception(const std::string &src, const std::string &msg)
std::string type() const
Access detector type (structure, tracker, calorimeter, etc.).
Handle class holding a placed volume (also called physical volume)
PlacedVolume placement() const
Access to the physical volume of this detector element.
struct dd4hep::sim::Geant4GeometryInfo::PlacementFlags::_flags flags
Class implementing the ID encoding of the detector response.
bool isValid() const
Check the validity of the object held by the handle.
Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects...
VolIDs volIDs
ID container.
bool isSensitive() const
Accessor if volume is sensitive (ie. is attached to a sensitive detector)
const char * name() const
Access the object name (or "" if not supported by the object)
static const VolumeID InvalidPath
static const VolumeID Insensitive
Geant4GeometryMaps::G4PlacementMap g4Parameterised
VolumeID volumeID(const G4VTouchable *touchable) const
Access CELLID by placement path.
std::pair< VolumeID, std::vector< std::pair< const BitFieldElement *, VolumeID > > > VolIDDescriptor
Handle class describing a detector element.
Handle class holding a placed volume (also called physical volume)
static const VolumeID NonExisting
unsigned path_has_parametrised
Geant4GeometryMaps::PlacementMap g4Placements
static VolumeID encode(const Field *fld, VolumeID value)
Encode partial volume identifiers to a volumeID.
std::vector< const G4VPhysicalVolume * > placementPath(const G4VTouchable *touchable, bool exception=true) const
Helper: Generate placement path from touchable object.
Geant4GeometryMaps::VolumeImprintMap g4VolumeImprints
IDDescriptor IDDescriptor
Geant4GeometryMaps::G4PlacementMap g4Replicated
unsigned path_has_replicated
dd4hep::DDSegmentation::VolumeID VolumeID
Namespace for the Geant4 based simulation part of the AIDA detector description toolkit.
std::map< std::string, DetElement > Children
Concreate class holding the relation information between geant4 objects and dd4hep objects.
T * ptr() const
Access to the held object.
std::map< Geant4PlacementPath, Placement > g4Paths
std::vector< const G4VPhysicalVolume * > Geant4PlacementPath
Namespace for the AIDA detector description toolkit.
Readout readout() const
Access readout structure of the sensitive detector.
Volume volume() const
Logical volume of this placement.
Object * data() const
Check if placement is properly instrumented.
The main interface to the dd4hep detector description package.
const detail::BitFieldElement * field
Bitfield from sensitive detector to encode the volume ID on the fly.
Handle to the implementation of the readout structure of a subdetector.
IDDescriptor idSpec() const
Access IDDescription structure.
const PlacedVolumeExtension::VolIDs & volIDs() const
Access to the volume IDs.
void volumeDescriptor(const std::vector< const G4VPhysicalVolume * > &path, std::pair< VolumeID, std::vector< std::pair< const BitFieldElement *, VolumeID > > > &volume_desc) const
Accessfully decoded volume fields by placement path.
Parameterisation * params
Reference to the parameterised transformation.
bool checkValidity() const
Check the validity of the information before accessing it.
Handle< NamedObject > sensitiveDetector() const
Access to the handle to the sensitive detector.