diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index a41f17b645996fafb6dfb23bc2c50cf8f6a70578..daaa1c84454ed91289de416e715416b512f732ca 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -325,28 +325,28 @@ namespace dd4hep { /// Constructor to assign an object template <typename Q> Tube(const Handle<Q>& e) : Solid_type<Object>(e) { } /// Constructor to create a new anonymous tube object with attribute initialization - Tube(double rmin, double rmax, double z) - { make("", rmin, rmax, z, 0, 2*M_PI); } + Tube(double rmin, double rmax, double dz) + { make("", rmin, rmax, dz, 0, 2*M_PI); } /// Constructor to create a new anonymous tube object with attribute initialization - Tube(double rmin, double rmax, double z, double deltaPhi) - { make("", rmin, rmax, z, 0, deltaPhi); } + Tube(double rmin, double rmax, double dz, double deltaPhi) + { make("", rmin, rmax, dz, 0, deltaPhi); } /// Constructor to create a new anonymous tube object with attribute initialization - Tube(double rmin, double rmax, double z, double startPhi, double deltaPhi) - { make("", rmin, rmax, z, startPhi, deltaPhi); } + Tube(double rmin, double rmax, double dz, double startPhi, double deltaPhi) + { make("", rmin, rmax, dz, startPhi, deltaPhi); } /// Legacy: Constructor to create a new identifiable tube object with attribute initialization - Tube(const std::string& nam, double rmin, double rmax, double z) - { make(nam, rmin, rmax, z, 0, 2*M_PI); } + Tube(const std::string& nam, double rmin, double rmax, double dz) + { make(nam, rmin, rmax, dz, 0, 2*M_PI); } /// Legacy: Constructor to create a new identifiable tube object with attribute initialization - Tube(const std::string& nam, double rmin, double rmax, double z, double deltaPhi) - { make(nam, rmin, rmax, z, 0, deltaPhi); } + Tube(const std::string& nam, double rmin, double rmax, double dz, double deltaPhi) + { make(nam, rmin, rmax, dz, 0, deltaPhi); } /// Constructor to create a new anonymous tube object with attribute initialization template <typename RMIN, typename RMAX, typename Z, typename DELTAPHI> - Tube(const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi) - { make("", _toDouble(rmin), _toDouble(rmax), _toDouble(z), 0, _toDouble(deltaPhi)); } + Tube(const RMIN& rmin, const RMAX& rmax, const Z& dz, const DELTAPHI& deltaPhi) + { make("", _toDouble(rmin), _toDouble(rmax), _toDouble(dz), 0, _toDouble(deltaPhi)); } /// Assignment operator Tube& operator=(const Tube& copy) = default; /// Set the tube dimensions - Tube& setDimensions(double rmin, double rmax, double z, double startPhi=0.0, double deltaPhi=2*M_PI); + Tube& setDimensions(double rmin, double rmax, double dz, double startPhi=0.0, double deltaPhi=2*M_PI); }; /// Class describing a tube shape of a section of a cut tube segment diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 9ffecd72199bc2bc90d1c81c1840bd8088402b26..f0bbe256ade3d91d8e14538b3e49e30548fabbd2 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -181,6 +181,10 @@ namespace dd4hep { Volume volume() const; /// Parent volume (envelope) Volume motherVol() const; + /// Access the full transformation matrix to the parent volume + const TGeoMatrix& matrix() const; + /// Access the translation vector to the parent volume + Position position() const; /// Access to the volume IDs const PlacedVolumeExtension::VolIDs& volIDs() const; /// String dump diff --git a/DDCore/include/XML/VolumeBuilder.h b/DDCore/include/XML/VolumeBuilder.h index 3e465cd68a7ff556781bc8294af8de7263de477d..28ee06671d2c28fe3faa30f9c39ec24892660ee4 100644 --- a/DDCore/include/XML/VolumeBuilder.h +++ b/DDCore/include/XML/VolumeBuilder.h @@ -152,6 +152,7 @@ namespace dd4hep { Materials materials; Transformations transformations; std::set<std::string> shape_veto, vol_veto; + bool debug = false; /// Inhibit default constructor VolumeBuilder() = delete; @@ -177,6 +178,12 @@ namespace dd4hep { Solid getShape(const std::string& nam) const; /// Create a new shape from the information given in the xml handle Solid makeShape(Handle_t handle); + /// Access a registered volume by name + Volume volume(const std::string& nam) const; + /// Register shape to map + void registerShape(const std::string& nam, Solid shape); + /// Register volume to map + void registerVolume(const std::string& nam, Volume volume); /// Build all <shape/> identifiers in the passed parent xml element size_t buildShapes(Handle_t handle); /// Build all <volume/> identifiers in the passed parent xml element diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 01af6b037882bb9d94556181ee70d80651e2b71b..039be1bf55b92312bf1ff0c4dbf25068aba95dab 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -442,11 +442,26 @@ const PlacedVolume::VolIDs& PlacedVolume::volIDs() const { return _data(*this)->volIDs; } +/// Translation vector within parent volume +const TGeoMatrix& PlacedVolume::matrix() const { + if ( !isValid() ) { + except("PlacedVolume","+++ matrix: Failed to access invalid PlacedVolume! [Invalid handle]"); + } + return *(m_element->GetMatrix()); +} + +/// Translation vector within parent volume +Position PlacedVolume::position() const { + const double* ptr = matrix().GetTranslation(); + return Position(ptr[0],ptr[1],ptr[2]); +} + /// String dump string PlacedVolume::toString() const { stringstream s; Object* obj = _data(*this); - s << m_element->GetName() << ": vol='" << m_element->GetVolume()->GetName() << "' mat:'" << m_element->GetMatrix()->GetName() + s << m_element->GetName() << ": vol='" << m_element->GetVolume()->GetName() + << "' mat:'" << m_element->GetMatrix()->GetName() << "' volID[" << obj->volIDs.size() << "] "; for (VolIDs::const_iterator i = obj->volIDs.begin(); i != obj->volIDs.end(); ++i) s << (*i).first << "=" << (*i).second << " "; diff --git a/DDCore/src/XML/VolumeBuilder.cpp b/DDCore/src/XML/VolumeBuilder.cpp index 37d43138ef1c70868ff8e951bf70516ae4afa632..c2924347399e5ad2006ea134541764ed4162e863 100644 --- a/DDCore/src/XML/VolumeBuilder.cpp +++ b/DDCore/src/XML/VolumeBuilder.cpp @@ -53,6 +53,44 @@ size_t VolumeBuilder::collectMaterials(xml_h element) { return materials.size()-len; } +/// Register shape to map +void VolumeBuilder::registerShape(const std::string& nam, Solid shape) { + auto is = shapes.find(nam); + if ( is == shapes.end() ) { + shapes[nam] = make_pair(xml_h(0), shape); + return; + } + except("VolumeBuilder","+++ Shape %s is already known to this builder unit. ",nam.c_str()); +} + +/// Register volume to map +void VolumeBuilder::registerVolume(const std::string& nam, Volume volume) { + auto is = volumes.find(nam); + if ( is == volumes.end() ) { + volumes[nam] = make_pair(xml_h(0), volume); + return; + } + except("VolumeBuilder","+++ Volume %s is already known to this builder unit. ",nam.c_str()); +} + +/// Access a registered volume by name +Volume VolumeBuilder::volume(const std::string& nam) const { + auto iv = volumes.find(nam); + if ( iv == volumes.end() ) { + auto ib = vol_veto.find(nam); + if ( ib != vol_veto.end() ) { + // Veto'ed shape. Ignore it. + return Volume(); + } + except("VolumeBuilder","+++ Volume %s is not known to this builder unit. ",nam.c_str()); + } + Volume vol = (*iv).second.second; + if ( !vol.isValid() ) { + except("VolumeBuilder","+++ Failed to access volume %s from the local cache.",nam.c_str()); + } + return vol; +} + /// Access element from shape cache by name. Invalid returns means 'veto'. Otherwise exception Solid VolumeBuilder::getShape(const string& nam) const { auto is = shapes.find(nam); @@ -190,7 +228,9 @@ size_t VolumeBuilder::buildVolumes(xml_h handle) { if ( c.attr_nothrow(_U(sensitive)) ) { vol.setSensitiveDetector(sensitive); } - printout(ALWAYS,"VolumeBuilder","+++ Building volume %s",nam.c_str()); + if ( debug ) { + printout(ALWAYS,"VolumeBuilder","+++ Building volume %s",nam.c_str()); + } continue; } bool is_assembly = true; diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index a5c975a05cddf78e82248113ac728fbe3900f128..3ac559c1714f2cac9ea4a82ee5df05ee7f3fcbe3 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -1138,11 +1138,11 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c string path; long count = 0; int have_match = -1, analysis_level = 999999; - bool dump_materials = false, dump_shapes = false; + bool dump_materials = false, dump_shapes = false, dump_positions = false; bool sensitive_only = false; - Actor(const string& p, int level, bool mat, bool shap, bool sens) - : path(p), analysis_level(level), dump_materials(mat), dump_shapes(shap), sensitive_only(sens) {} + Actor(const string& p, int level, bool mat, bool shap, bool pos, bool sens) + : path(p), analysis_level(level), dump_materials(mat), dump_shapes(shap), dump_positions(pos), sensitive_only(sens) {} ~Actor() { printout(ALWAYS,"DetectorDump", "+++ Scanned a total of %ld elements.",count); } @@ -1199,6 +1199,14 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c ::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Material: %%-12s Shape: %%s", level+1,2*level+3); printout(INFO,"DetectorDump",fmt,"", mat.name(), toStringSolid(vol->GetShape()).c_str()); } + if ( dump_positions && place.isValid() ) { + Position pos = place.position(); + Box box = place.volume().solid(); + ::snprintf(fmt,sizeof(fmt), "%03d %%-%ds BBox: (%%9.4f,%%9.4f,%%9.4f) [cm]", level+1,2*level+3); + printout(INFO,"DetectorDump",fmt,"", box.x(), box.y(), box.z()); + ::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Position: (%%9.4f,%%9.4f,%%9.4f) [cm]", level+1,2*level+3); + printout(INFO,"DetectorDump",fmt,"", pos.X(), pos.Y(), pos.Z()); + } } } for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) @@ -1207,7 +1215,7 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c } }; int level = 999999; - bool sensitive_only = false, materials = false, shapes = false; + bool sensitive_only = false, materials = false, shapes = false, positions = false; string path; for(int i=0; i<argc; ++i) { if ( ::strncmp(argv[i],"--sensitive", 5)==0 ) { sensitive_only = true; } @@ -1217,6 +1225,8 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c else if ( ::strncmp(argv[i], "--materials", 5)==0 ) { materials = true; } else if ( ::strncmp(argv[i], "-shapes", 4)==0 ) { shapes = true; } else if ( ::strncmp(argv[i], "--shapes", 5)==0 ) { shapes = true; } + else if ( ::strncmp(argv[i], "-positions", 4)==0 ) { positions = true; } + else if ( ::strncmp(argv[i], "--positions", 5)==0 ) { positions = true; } else if ( ::strncmp(argv[i], "-no-sensitive", 7)==0 ) { sensitive_only = false; } else if ( ::strncmp(argv[i], "--detector", 5)==0 ) { path = argv[++i]; } else if ( ::strncmp(argv[i], "-detector", 5)==0 ) { path = argv[++i]; } @@ -1229,6 +1239,8 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c " -sensitive dto. \n" " --shapes Print shape information. \n" " -shapes dto. \n" + " --positions Print position information. \n" + " -positions dto. \n" " --materials Print material information. \n" " -materials dto. \n" " --detector <path> Process elements only if <path> is part of the DetElement path.\n" @@ -1237,7 +1249,7 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c ::exit(EINVAL); } } - Actor a(path, level, materials, shapes, sensitive_only); + Actor a(path, level, materials, shapes, positions, sensitive_only); return a.dump(description.world(),0); } DECLARE_APPLY(DD4hep_DetectorDump,dump_detelement_tree<0>)