From c03310882642579ce735987e2dff01ec335f9ad0 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Fri, 8 May 2015 18:57:08 +0000 Subject: [PATCH] Allow to access detectors by type from lcdd --- DDCore/include/DD4hep/LCDD.h | 28 +++++++- .../include/DD4hep/objects/DetectorInterna.h | 10 +-- DDCore/src/LCDDImp.cpp | 66 +++++++++++++++++++ DDCore/src/LCDDImp.h | 26 ++++++++ DDCore/src/plugins/StandardPlugins.cpp | 42 ++++++++++-- DDDetectors/src/SubdetectorAssembly_geo.cpp | 4 +- doc/release.notes | 9 +++ 7 files changed, 172 insertions(+), 13 deletions(-) diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h index 261cf2252..59a261830 100644 --- a/DDCore/include/DD4hep/LCDD.h +++ b/DDCore/include/DD4hep/LCDD.h @@ -24,6 +24,7 @@ // C/C++ include files #include <map> +#include <vector> // Forward declarations class TGeoManager; @@ -64,7 +65,8 @@ namespace DD4hep { class LCDD { public: /// Type definition of a map of named handles - typedef std::map<std::string, Handle<NamedObject> > HandleMap; + typedef Handle<NamedObject> NamedHandle; + typedef std::map<std::string, NamedHandle > HandleMap; typedef std::map<std::string, std::string> PropertyValues; typedef std::map<std::string, PropertyValues> Properties; @@ -132,6 +134,30 @@ namespace DD4hep { /// Accessor to the map of ID specifications virtual const HandleMap& idSpecifications() const = 0; + #ifndef __MAKECINT__ + /** Access to predefined caches of subdetectors according to the sensitive type */ + /// Access a set of subdetectors according to the sensitive type. + /** + Please note: + - The sensitive type of a detector is set in the 'detector constructor'. + - Not sensitive detector structures have the name 'passive' + - Compounds (ie. nested detectors) are of type 'compound' + */ + virtual const std::vector<DetElement>& detectors(const std::string& type) = 0; + + /// Access a set of subdetectors according to several sensitive types. + virtual std::vector<DetElement> detectors(const std::string& type1, + const std::string& type2, + const std::string& type3="", + const std::string& type4="", + const std::string& type5="" ) = 0; + + /// Access the availible detector types + virtual std::vector<std::string> detectorTypes() const = 0; + #endif + + /** Miscaneleous accessors to the detexctor description */ + /// Register new mother volume using the detector name. /** Volumes must be registered/declared PRIOR to be picked up! * The method throws an exception if another volume was already declared for this subdetector diff --git a/DDCore/include/DD4hep/objects/DetectorInterna.h b/DDCore/include/DD4hep/objects/DetectorInterna.h index 1864c073b..4e38457f7 100644 --- a/DDCore/include/DD4hep/objects/DetectorInterna.h +++ b/DDCore/include/DD4hep/objects/DetectorInterna.h @@ -67,11 +67,13 @@ namespace DD4hep { */ class DetElementObject: public NamedObject, public ObjectExtensions { public: - typedef DetElement::destruct_t destruct_t; - typedef DetElement::copy_t copy_t; + // Type definitions. + // The full namespace declaration is required by cint.... + typedef /* DD4hep::Geometry:: */ DetElement::destruct_t destruct_t; + typedef /* DD4hep::Geometry:: */ DetElement::copy_t copy_t; - typedef DetElement::Children Children; - typedef DetElement::Extensions Extensions; + typedef /* DD4hep::Geometry:: */ DetElement::Children Children; + typedef /* DD4hep::Geometry:: */ DetElement::Extensions Extensions; typedef std::pair<Callback,unsigned long> UpdateCall; typedef std::vector<UpdateCall> UpdateCallbacks; diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index 4209ff40c..7a0382e40 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -245,6 +245,71 @@ Material LCDDImp::material(const string& name) const { throw runtime_error("Cannot find a material the reference name:" + name); } +/// Internal helper to map detector types once the geometry is closed +void LCDDImp::mapDetectorTypes() { + for(HandleMap::const_iterator i=m_detectors.begin(); i!=m_detectors.end(); ++i) { + DetElement det((*i).second); + if ( det.parent().isValid() ) { // Exclude 'world' + HandleMap::const_iterator j=m_sensitive.find(det.name()); + if ( j != m_sensitive.end() ) { + SensitiveDetector sd((*j).second); + m_detectorTypes[sd.type()].push_back(det); + } + else if ( det.type() == "compound" ) { + m_detectorTypes[det.type()].push_back(det); + } + else { + m_detectorTypes["passive"].push_back(det); + } + } + } +} + +/// Access the availible detector types +vector<string> LCDDImp::detectorTypes() const { + if ( m_manager->IsClosed() ) { + vector<string> v; + for(DetectorTypeMap::const_iterator i=m_detectorTypes.begin(); i!=m_detectorTypes.end(); ++i) + v.push_back((*i).first); + return v; + } + throw runtime_error("detectorTypes: Call only available once the geometry is closed!"); +} + +/// Access a set of subdetectors according to the sensitive type. +const vector<DetElement>& LCDDImp::detectors(const string& type) { + if ( m_manager->IsClosed() ) { + DetectorTypeMap::const_iterator i=m_detectorTypes.find(type); + if ( i != m_detectorTypes.end() ) return (*i).second; + throw runtime_error("detectors("+type+"): Detectors of this type do not exist in the current setup!"); + } + throw runtime_error("detectors("+type+"): Detectors can only selected by type once the geometry is closed!"); +} + +/// Access a set of subdetectors according to several sensitive types. +vector<DetElement> LCDDImp::detectors(const string& type1, + const string& type2, + const string& type3, + const string& type4, + const string& type5 ) { + if ( m_manager->IsClosed() ) { + vector<DetElement> v; + DetectorTypeMap::const_iterator i, end=m_detectorTypes.end(); + if ( !type1.empty() && (i=m_detectorTypes.find(type1)) != end ) + v.insert(v.end(),(*i).second.begin(),(*i).second.end()); + if ( !type2.empty() && (i=m_detectorTypes.find(type2)) != end ) + v.insert(v.end(),(*i).second.begin(),(*i).second.end()); + if ( !type3.empty() && (i=m_detectorTypes.find(type3)) != end ) + v.insert(v.end(),(*i).second.begin(),(*i).second.end()); + if ( !type4.empty() && (i=m_detectorTypes.find(type4)) != end ) + v.insert(v.end(),(*i).second.begin(),(*i).second.end()); + if ( !type5.empty() && (i=m_detectorTypes.find(type5)) != end ) + v.insert(v.end(),(*i).second.begin(),(*i).second.end()); + return v; + } + throw runtime_error("detectors("+type1+","+type2+",...): Detectors can only selected by type once the geometry is closed!"); +} + Handle<TObject> LCDDImp::getRefChild(const HandleMap& e, const string& name, bool do_throw) const { HandleMap::const_iterator i = e.find(name); if (i != e.end()) { @@ -344,6 +409,7 @@ void LCDDImp::endDocument() { mgr->CloseGeometry(); ShapePatcher patcher(m_volManager, m_world); patcher.patchShapes(); + mapDetectorTypes(); } } diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h index 538d249d9..6b682347c 100644 --- a/DDCore/src/LCDDImp.h +++ b/DDCore/src/LCDDImp.h @@ -32,6 +32,11 @@ namespace DD4hep { * @version 1.0 */ class LCDDImp: public LCDD, public LCDDData, public LCDDLoad { + protected: + /// Cached map with detector types: + typedef std::map<std::string, std::vector<DetElement> > DetectorTypeMap; + DetectorTypeMap m_detectorTypes; + private: /// Disable copy constructor LCDDImp(const LCDDImp&); @@ -39,6 +44,8 @@ namespace DD4hep { /// Disable assignment operator LCDDImp& operator=(const LCDDImp&); + /// Internal helper to map detector types once the geometry is closed + void mapDetectorTypes(); public: /// Local method (no interface): Load volume manager. @@ -238,6 +245,25 @@ namespace DD4hep { return m_idDict; } + /// Access a set of subdetectors according to the sensitive type. + /** + Please note: + - The sensitive type of a detector is set in the 'detector constructor'. + - Not sensitive detector structures have the name 'passive' + - Compounds (ie. nested detectors) are of type 'compound' + */ + virtual const std::vector<DetElement>& detectors(const std::string& type); + + /// Access a set of subdetectors according to several sensitive types. + virtual std::vector<DetElement> detectors(const std::string& type1, + const std::string& type2, + const std::string& type3="", + const std::string& type4="", + const std::string& type5="" ); + + /// Access the availible detector types + virtual std::vector<std::string> detectorTypes() const; + #define __R return *this /// Add a new constant to the detector description virtual LCDD& add(Constant x) { diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index 0c9ec8d65..06c6a2553 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -199,14 +199,27 @@ DECLARE_APPLY(DD4hepVolumeDump,dump_volume_tree) * @version 1.0 * @date 01/04/2014 */ -static long dump_detelement_tree(LCDD& lcdd, int argc, char** argv) { +template <int flag> long dump_detelement_tree(LCDD& lcdd, int argc, char** argv) { struct Actor { static long dump(DetElement de,int level, bool sensitive_only) { const DetElement::Children& c = de.children(); if ( !sensitive_only || 0 != de.volumeID() ) { + int value = flag; char fmt[64]; - ::sprintf(fmt,"%03d %%-%ds %%s #Dau:%%d VolID:%%p",level+1,2*level+1); - printout(INFO,"+++",fmt,"",de.placementPath().c_str(),int(c.size()),(void*)de.volumeID()); + switch(value) { + case 0: + ::sprintf(fmt,"%03d %%-%ds %%s #Dau:%%d VolID:%%p",level+1,2*level+1); + printout(INFO,"+++",fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID()); + break; + case 1: + ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p",level+1,2*level+1); + printout(INFO,"+++",fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID()); + ::sprintf(fmt,"%03d %%-%ds Placement: %%s",level+1,2*level+3); + printout(INFO,"+++",fmt,"",de.placementPath().c_str()); + break; + default: + break; + } } for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) dump((*i).second,level+1,sensitive_only); @@ -219,7 +232,8 @@ static long dump_detelement_tree(LCDD& lcdd, int argc, char** argv) { } return Actor::dump(lcdd.world(),0,sensitive_only); } -DECLARE_APPLY(DD4hepDetectorDump,dump_detelement_tree) +DECLARE_APPLY(DD4hepDetectorDump,dump_detelement_tree<0>) +DECLARE_APPLY(DD4hepDetectorVolumeDump,dump_detelement_tree<1>) /** Basic entry point to print out the volume hierarchy * @@ -266,9 +280,27 @@ static long exec_SimpleGDMLWriter(LCDD& lcdd, int argc, char** argv) { } return 1; } - DECLARE_APPLY(DD4hepSimpleGDMLWriter,exec_SimpleGDMLWriter) +/** Basic entry point to print out detector type map + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ +static long detectortype_cache(LCDD& lcdd, int , char** ) { + vector<string> v = lcdd.detectorTypes(); + printout(INFO,"DetectorTypes","Detector type dump: %ld types:",long(v.size())); + for(vector<string>::const_iterator i=v.begin(); i!=v.end(); ++i) { + const vector<DetElement>& vv=lcdd.detectors(*i); + printout(INFO,"DetectorTypes","\t --> %ld %s detectors:",long(vv.size()),(*i).c_str()); + for(vector<DetElement>::const_iterator j=vv.begin(); j!=vv.end(); ++j) + printout(INFO,"DetectorTypes","\t\t %-16s --> %s [%s]",(*i).c_str(),(*j).name(),(*j).type().c_str()); + } + return 1; +} +DECLARE_APPLY(DD4hepDetectorTypes,detectortype_cache) + #include "DD4hep/SurfaceInstaller.h" typedef SurfaceInstaller TestSurfacesPlugin; DECLARE_SURFACE_INSTALLER(TestSurfaces,TestSurfacesPlugin) diff --git a/DDDetectors/src/SubdetectorAssembly_geo.cpp b/DDDetectors/src/SubdetectorAssembly_geo.cpp index 7d8edcd6b..a459a9ecf 100644 --- a/DDDetectors/src/SubdetectorAssembly_geo.cpp +++ b/DDDetectors/src/SubdetectorAssembly_geo.cpp @@ -25,6 +25,7 @@ static Ref_t create_element(LCDD& lcdd, xml_h e, Ref_t) { Position pos; RotationZYX rot; + sdet.setType("compound"); usePos = x_det.hasChild(_U(position)); useRot = x_det.hasChild(_U(rotation)); if( usePos ) { @@ -34,7 +35,6 @@ static Ref_t create_element(LCDD& lcdd, xml_h e, Ref_t) { rot = RotationZYX(x_det.rotation().x(), x_det.rotation().y(), x_det.rotation().z()); } - if ( x_det.hasChild(_U(shape)) ) { xml_comp_t x_shape = x_det.child(_U(shape)); string type = x_shape.typeStr(); @@ -42,8 +42,6 @@ static Ref_t create_element(LCDD& lcdd, xml_h e, Ref_t) { Material mat = lcdd.material(x_shape.materialStr()); printout(DEBUG,det_name,"+++ Creating detector assembly with shape of type:%s",type.c_str()); vol = Volume(det_name,solid,mat); - - } else { printout(DEBUG,det_name,"+++ Creating detector assembly without shape"); diff --git a/doc/release.notes b/doc/release.notes index 2456a06d9..0ceb8da0f 100644 --- a/doc/release.notes +++ b/doc/release.notes @@ -4,6 +4,15 @@ DD4hep ---- Release Notes ================================= +2015/05/09 Markus Frank +----------------------- + - Allow to access detectors by type from lcdd. + - The sensitive type of a detector is set in the 'detector constructor'. + - Not sensitive detector structures have the name 'passive' + - Compounds (ie. nested detectors) are of type 'compound' + - Dump detector types using plugin: + geoPluginRun -plugin DD4hepDetectorTypes -input <compact-file> + 2015/03/12 Markus Frank ----------------------- - Add support for ellipsoids in gdml/lcdd and geant4 conversion. -- GitLab