 |
DD4hep
1.38.0
Detector Description Toolkit for High Energy Physics
|
Go to the documentation of this file.
14 #define DD4HEP_MUST_USE_DETECTORIMP_H 1
39 #include <TGeoSystemOfUnits.h>
40 #include <TGeoCompositeShape.h>
41 #include <TGeoBoolNode.h>
42 #include <TGeoManager.h>
43 #include <TGeoMatrix.h>
44 #include <TGeoVolume.h>
45 #include <TGeoShape.h>
51 #include <xercesc/dom/DOMException.hpp>
65 std::recursive_mutex s_detector_apply_lock;
68 std::recursive_mutex lock;
69 std::map<std::string, Detector*>
detectors;
70 Detector* get(
const std::string& name) {
72 return i ==
detectors.end() ? nullptr : (*i).second;
74 void insert(
const std::string& name,
Detector* detector) {
75 const auto [_, emplaced] =
detectors.emplace(name,detector);
77 except(
"DD4hep",
"Cannot insert detector instance %s [Already present]",name.c_str());
80 Detector* remove(
const std::string& name) {
90 class DetectorGuard final {
92 static std::pair<std::recursive_mutex, std::map<DetectorImp*, TGeoManager*> >& detector_lock() {
93 static std::pair<std::recursive_mutex, std::map<DetectorImp*, TGeoManager*> > s_inst;
99 void lock(TGeoManager* mgr)
const {
100 auto& lock = detector_lock();
102 lock.second[detector] = mgr;
104 TGeoManager* unlock()
const {
105 TGeoManager* mgr =
nullptr;
106 auto& lock = detector_lock();
107 auto i = lock.second.find(detector);
108 if ( i != lock.second.end() ) {
110 lock.second.erase(i);
117 Instances& detector_instances() {
118 static Instances s_inst;
125 std::snprintf(vsn,
sizeof(vsn),
"v%2.2d-%2.2d", DD4HEP_MAJOR_VERSION, DD4HEP_MINOR_VERSION);
130 return std::unique_ptr<Detector>(
new DetectorImp(name));
134 std::lock_guard<std::recursive_mutex> lock(detector_instances().lock);
135 Detector* description = detector_instances().get(name);
136 if ( !description ) {
137 gGeoManager =
nullptr;
139 detector_instances().insert(name,description);
146 std::lock_guard<std::recursive_mutex> lock(detector_instances().lock);
147 Detector* description = detector_instances().remove(name);
165 #if defined(DD4HEP_USE_GEANT4_UNITS)
166 printout(INFO,
"DD4hep",
"++ Using globally Geant4 unit system (mm,ns,MeV)");
167 if ( TGeoManager::GetDefaultUnits() != TGeoManager::kG4Units ) {
168 TGeoManager::LockDefaultUnits(kFALSE);
169 TGeoManager::SetDefaultUnits(TGeoManager::kG4Units);
170 TGeoManager::LockDefaultUnits(kTRUE);
173 if ( TGeoManager::GetDefaultUnits() != TGeoManager::kRootUnits ) {
174 TGeoManager::LockDefaultUnits(kFALSE);
175 TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
176 TGeoManager::LockDefaultUnits(kTRUE);
180 SetName(name.c_str());
181 SetTitle(
"DD4hep detector description object");
183 gGeoManager =
nullptr;
185 m_manager =
new TGeoManager(name.c_str(),
"Detector Geometry");
190 #if 1 //FIXME: eventually this should be set to 1 - needs fixes in examples ...
191 TGeoElementTable* table =
m_manager->GetElementTable();
192 table->TGeoElementTable::~TGeoElementTable();
193 new(table) TGeoElementTable();
195 table->AddElement(
"VACUUM",
"VACUUM", 1, 1, 1e-15);
200 gGeoIdentity =
new TGeoIdentity();
219 DetectorGuard(
this).lock(gGeoManager);
221 std::lock_guard<std::recursive_mutex> lock(detector_instances().lock);
222 if (
m_manager == gGeoManager ) gGeoManager =
nullptr;
225 detector_instances().remove(
m_manager->GetName());
234 DetectorGuard(
this).unlock();
243 nbytes = TNamed::Write(name, option, bufsize);
251 except(
"Detector",
"Exception %s while saving dd4hep::Detector object", e.what());
256 except(
"Detector",
"UNKNOWN exception while saving dd4hep::Detector object.");
284 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
291 if ( !detector_name.empty() ) {
296 if ( parent_volume.
isValid() ) {
300 except(
"DD4hep",
"+++ Failed to access valid parent volume of %s from %s",
301 detector_name.c_str(), parent.
name());
304 "+++ A parent to the detector %s was already registered.",
305 detector_name.c_str());
308 "+++ Attempt to register invalid parent for detector: %s [Invalid-Handle].",
309 detector_name.c_str());
312 "+++ Attempt to register parent to invalid detector [Invalid-detector-name].");
318 except(
"DD4hep",
"Detector: Attempt to access mother volume of invalid detector [Invalid-handle]");
321 std::string de_name = de.
name();
328 "+++ The world volume is not (yet) valid. "
329 "Are you correctly building the detector %s?",
332 if ( (*i).second.isValid() ) {
333 Volume vol = (*i).second.volume();
339 "+++ The mother volume of %s is not valid. "
340 "Are you correctly building detectors?",
350 printout(WARNING,
"DD4hep",
"++ STD conditions NOT defined by client. NTP defaults taken.");
360 if ( std::abs(temp-Temperature_NTP) < 1e-10 && std::abs(pressure-Pressure_NTP) < 1e-10 )
362 else if ( std::abs(temp-Temperature_STP) < 1e-10 && std::abs(pressure-Pressure_STP) < 1e-10 )
370 if ( type ==
"STP" ) {
375 else if ( type ==
"NTP" ) {
382 "++ Attempt to set standard conditions to "
383 "unknown conventions (Only STP and NTP allowed).");
389 HandleMap::const_iterator i =
m_detectors.find(name);
402 if ( existing_det.
isValid() ) {
405 std::stringstream str;
406 str <<
"Detector: The sensitive sub-detectors " << det_element.
name() <<
" and "
407 << existing_det.
name() <<
" have the identical ID:" << det_element.
id() <<
".";
408 except(
"DD4hep",str.str());
415 std::stringstream str;
416 str <<
"Detector: Adding subdetectors with no valid placement is not allowed: "
417 << det_element.
name() <<
" ID:" << det_element.
id() <<
".";
418 except(
"DD4hep",str.str());
420 Volume volume = pv->GetMotherVolume();
422 printout(DEBUG,
"DD4hep",
"+++ Detector: Added detector %s to the world instance.",
431 parent.
add(det_element);
432 printout(DEBUG,
"DD4hep",
"+++ Detector: Added detector %s to parent %s.",
441 if ( vol == volume ) {
442 printout(INFO,
"DD4hep",
"+++ Detector: Added detector %s to the parent:%s.",
444 parent.
add(det_element);
448 except(
"DD4hep",
"+++ Detector: The detector %s has no known parent.", det_element.
name());
449 throw std::runtime_error(
"Detector-Error");
454 if ( strcmp(x.
name(),
"Detector_InhibitConstants") == 0 ) {
456 char c = ::toupper(title[0]);
468 throw std::runtime_error(
"Detector:constant("+name+
"): Access to global constants is inhibited.");
477 throw std::runtime_error(
"Detector:constantAsString: The constant " + name +
" is not known to the system.");
479 throw std::runtime_error(
"Detector:constantAsString("+name+
"):: Access to global constants is inhibited.");
487 throw std::runtime_error(
"Detector:constantAsLong("+name+
"): Access to global constants is inhibited.");
495 throw std::runtime_error(
"Detector:constantAsDouble("+name+
"): Access to global constants is inhibited.");
507 TGeoMedium* mat =
m_manager->GetMedium(name.c_str());
511 throw std::runtime_error(
"Cannot find a material referenced by name:" + name);
519 if (
det.parent().isValid() ) {
525 else if (
det.type() ==
"compound" ) {
538 std::vector<std::string>
v;
541 v.emplace_back(t.first);
544 throw std::runtime_error(
"detectorTypes: Call only available once the geometry is closed!");
553 throw std::runtime_error(
"detectors("+type+
"): Detectors of this type do not exist in the current setup!");
558 throw std::runtime_error(
"detectors("+type+
"): Detectors can only selected by type once the geometry is closed!");
563 throw std::runtime_error(
"detectors(typeFlag): Detectors can only selected by typeFlag once the geometry is closed!");
565 std::vector<DetElement> dets ;
570 if (
det.parent().isValid() ) {
575 if( (
det.typeFlag() & includeFlag ) == includeFlag &&
576 (
det.typeFlag() & excludeFlag ) == 0 )
577 dets.emplace_back(
det ) ;
585 const std::string& type2,
586 const std::string& type3,
587 const std::string& type4,
588 const std::string& type5 ) {
590 std::vector<DetElement>
v;
593 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
595 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
597 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
599 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
601 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
604 throw std::runtime_error(
"detectors("+type1+
","+type2+
",...): Detectors can only selected by type once the geometry is closed!");
608 HandleMap::const_iterator it = e.find(name);
617 ptr(
const void* p) { other = p; }
619 std::string nam =
"";
620 ptr mptr(&e), ref(
this);
621 if ( ref.c > mptr.c && mptr.c < ref.c+
sizeof(*
this) ) {
622 nam = mptr.omap->name;
624 std::stringstream err;
625 err <<
"getRefChild: Failed to find child with name: " << name
626 <<
" Map " << nam <<
" contains " << e.size() <<
" elements";
627 if ( std::getenv(
"DD4HEP_LIST_CHILDREN") ) {
629 for (it = e.begin(); it != e.end(); ++it) {
630 if (it != e.begin()) {
638 err <<
". Set the environment variable DD4HEP_LIST_CHILDREN to list them.";
640 throw std::runtime_error(err.str());
650 : detail::
GeoScan(e), m_volManager(m), m_world(e) {
653 auto& data = *m_data;
656 printout(INFO,
"Detector",
"+++ Patching names of anonymous shapes....");
657 for (
auto i = data.rbegin(); i != data.rend(); ++i) {
658 for(
const TGeoNode* n : (*i).second ) {
659 TGeoVolume* vol = n->GetVolume();
660 TGeoShape* s = vol->GetShape();
661 const char* sn = s->GetName();
662 ::snprintf(text,
sizeof(text),
"_shape_%p",(
void*)s);
663 if ( !sn || 0 == ::strlen(sn)) {
664 nam = vol->GetName();
666 s->SetName(nam.c_str());
668 else if (0 == ::strcmp(sn, s->IsA()->GetName())) {
669 nam = vol->GetName();
671 s->SetName(nam.c_str());
675 if (nam.find(
"_shape") == std::string::npos)
677 s->SetName(nam.c_str());
679 if (s->IsA() == TGeoCompositeShape::Class()) {
680 TGeoCompositeShape* c = (TGeoCompositeShape*) s;
681 const TGeoBoolNode*
boolean = c->GetBoolNode();
682 s =
boolean->GetLeftShape();
684 if ( !sn || 0 == ::strlen(sn)) {
685 s->SetName((nam +
"_left").c_str());
687 else if (0 == ::strcmp(sn, s->IsA()->GetName())) {
688 s->SetName((nam +
"_left").c_str());
690 s =
boolean->GetRightShape();
692 if ( !sn || 0 == ::strlen(sn)) {
693 s->SetName((nam +
"_right").c_str());
695 else if (0 == ::strcmp(s->GetName(), s->IsA()->GetName())) {
696 s->SetName((nam +
"_right").c_str());
707 const char* option = (close_geometry) ?
"close" :
nullptr;
714 TString clopt, opt(option ==
nullptr ?
"" : option);
715 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
717 if ( opt.Contains(
"close") && !mgr->IsClosed() ) {
719 Region trackingRegion(
"TrackingRegion");
725 VisAttr trackingVis(
"TrackingVis");
734 if( opt.Contains(
"i") ) clopt +=
"i";
735 if( opt.Contains(
"nv") ) clopt +=
"nv";
736 (clopt.Length()>0) ? mgr->CloseGeometry(clopt) : mgr->CloseGeometry();
737 if( clopt.Contains(
"nv") ) {
738 printout(INFO,
"Detector",
"++ Geometry voxelization is disabled.");
741 auto*
extension = pv->GetUserExtension();
752 patcher.patchShapes();
762 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
773 printout(INFO,
"Detector",
"*********** Use Top Node from manager as "
774 "world volume [%s]. Material: %s BBox: %4.0f %4.0f %4.0f",
776 worldSolid->GetDX(), worldSolid->GetDY(), worldSolid->GetDZ());
780 Solid parallelWorldSolid =
Box(
"world_x",
"world_y",
"world_z");
781 worldSolid =
Box(
"world_x",
"world_y",
"world_z");
784 parallelWorldSolid->SetName(
"parallel_world_solid");
785 printout(INFO,
"Detector",
"*********** Created World volume with size: %4.0f %4.0f %4.0f",
786 worldSolid->GetDX(), worldSolid->GetDY(), worldSolid->GetDZ());
792 worldVis =
VisAttr(
"WorldVis");
822 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
829 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
837 mgr->SetVisOption(1);
843 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
844 std::string fac = factory_type;
847 long result = PluginService::Create<long>(fac, thisPtr, argc, argv);
850 result = PluginService::Create<long>(fac, thisPtr, argc, argv);
852 throw std::runtime_error(
"dd4hep: apply-plugin: Failed to locate plugin " +
856 result = *(
long*) result;
858 throw std::runtime_error(
"dd4hep: apply-plugin: Failed to execute plugin " + fac);
863 throw std::runtime_error(
xml::_toString(e.msg) +
"\ndd4hep: XML-DOM Exception with plugin:" + fac);
866 throw std::runtime_error(std::string(e.what()) +
"\ndd4hep: with plugin:" + fac);
869 throw std::runtime_error(
"UNKNOWN exception from plugin:" + fac);
virtual const HandleMap & detectors() const override
Accessor to the map of sub-detectors.
DetectorImp()
Default constructor used by ROOT I/O.
@ LOADING
The geometry is being created and loaded. (parsing ongoing)
virtual Detector & add(Constant x) override
Add a new constant to the detector description.
This structure describes the internal data of the volume manager object.
ObjectHandleMap m_sensitive
The map of top level sub-detector sensitive detector objects indexed by the detector name.
Definition of the extension entry interface class.
virtual void init() override
Open the geometry at startup.
std::map< std::string, DetElement > m_detectorParents
virtual DetectorBuildType buildType() const override
Access flag to steer the detail of building of the geometry/detector description.
DetectorBuildType m_buildType
VolumeManager m_volManager;.
xercesc::DOMException XmlException
void destroyHandle(T &handle)
Helper to delete objects from heap and reset the handle.
Data class with properties of a detector element.
Handle class to hold the information of a sensitive detector.
void append(const Handle< NamedObject > &e, bool throw_on_doubles=true)
Append entry to map.
void exception(const std::string &src, const std::string &msg)
Region & setStoreSecondaries(bool value)
Set flag to store secondaries.
Handle class holding a placed volume (also called physical volume)
Handle class describing visualization attributes.
virtual Detector & addConstant(const Handle< NamedObject > &x) override
Add a new constant by named reference to the detector description.
PlacedVolume placement() const
Access to the physical volume of this detector element.
virtual Detector & addField(const Handle< NamedObject > &x) override
Add a field component by named reference to the detector description.
void * removeExtension(unsigned long long int key, bool destroy)
Remove an existing extension object from the instance.
void setShowDaughters(bool value)
Set Flag to show/hide daughter elements.
std::string versionString()
return a string with the current dd4hep version in the form vXX-YY.
Solid solid() const
Access to Solid (Shape)
STD_Conditions m_std_conditions
Standard conditions.
bool isValid() const
Check the validity of the object held by the handle.
const Volume & setRegion(const Detector &description, const std::string &name) const
Set the regional attributes to the volume. Note: If the name string is empty, the action is ignored.
PlacedVolumeExtension Object
void add(CartesianField field)
Add a new field component.
static void increment(T *)
Increment count according to type information.
virtual Detector & addDetector(const Handle< NamedObject > &x) override
Add a new subdetector by named reference to the detector description.
void setLineStyle(int style)
Set line style.
DetElement & add(DetElement sub_element)
Add new child to the detector structure.
virtual DetElement detector(const std::string &name) const override
Retrieve a subdetector element by its name from the detector description.
const char * name() const
Access the object name (or "" if not supported by the object)
static void patchRootStreamer(TClass *cl)
Assignment operator.
virtual DetElement world() const override
Return reference to the top-most (world) detector element.
bool m_inhibitConstants
Flag to inhibit the access to global constants. Value set by constants section 'Detector_InhibitConst...
long _toLong(const std::string &value)
String conversions: string to long integer value.
Geometry scanner (handle object)
Class describing a field overlay with several sources.
Material material() const
Access to the Volume material.
virtual long constantAsLong(const std::string &name) const override
Typed access to constants: long values.
Handle class describing a material.
virtual void declareParent(const std::string &detector_name, const DetElement &parent) override
Register new mother volume using the detector name.
DetectorTypeMap m_detectorTypes
Inventory of detector types.
DetElement detectorByID(int id) const
Find a detector element by its system ID.
void setDrawingStyle(int style)
Set drawing style.
static Detector & getInstance(const std::string &name="default")
—Factory method----—
Helper class to access default temperature and pressure.
Handle class describing a detector element.
const char * GetName(T *p)
Handle class describing a constant (define) object in description.
Handle class holding a placed volume (also called physical volume)
Class to support the retrieval of detector elements and volumes given a valid identifier.
virtual ~DetectorImp()
Standard destructor.
Detector::State m_state
Detector description state.
VolumeManager m_volManager
Volume manager reference.
void setVisible(bool value)
Set visibility flag.
virtual void dump() const override
Stupid legacy method.
virtual const HandleMap & visAttributes() const override
Accessor to the map of visualisation attributes.
ObjectHandleMap m_detectors
The map of top level sub-detector objects indexed by name.
virtual Constant constant(const std::string &name) const override
Retrieve a constant by its name from the detector description.
static void decrement(T *)
Decrement count according to type information.
Namespace for the AIDA detector description toolkit supporting XML utilities.
virtual long apply(const char *factory, int argc, char **argv) const override
Manipulate geometry using facroy converter.
static void destroyInstance(const std::string &name="default")
Destroy the singleton instance.
virtual void * removeUserExtension(unsigned long long int key, bool destroy=true) override
Remove an existing extension object from the Detector instance. If not destroyed, the instance is ret...
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Int_t saveObject(const char *name=0, Int_t option=0, Int_t bufsize=0) const
ROOT I/O call.
Handle class describing a region as used in simulation.
Helper to debug plugin manager calls.
DetectorHelper: class to shortcut certain questions to the dd4hep detector description interface.
void destroyData(bool destroy_mgr=true)
Clear data content: releases all allocated resources.
std::string _toString(const Attribute attr)
Convert xml attribute to STL string.
virtual void endDocument(bool close_geometry) override
Close the geometry.
virtual Material material(const std::string &name) const override
Retrieve a matrial by its name from the detector description.
static std::unique_ptr< Detector > make_unique(const std::string &name)
Unique creation without internal registration.
Data implementation class of the Detector interface.
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
ObjectHandleMap m_fields
The map of electro magnet field components for the global overlay field.
virtual const STD_Conditions & stdConditions() const override
Access default conditions (temperature and pressure.
virtual Volume pickMotherVolume(const DetElement &sd) const override
Access mother volume by detector element.
DetElement & setPlacement(const PlacedVolume &volume)
Set the physical volumes of the detector element.
const char * GetTitle() const
Get name (used by Handle)
Class supporting to read data given a URI.
std::string type() const
Access the type of the sensitive detector.
std::map< std::string, Handle< NamedObject > > HandleMap
Type definition of a map of named handles.
Implementation of a map of named dd4hep Handles.
detail::OpticalSurfaceManagerObject * m_surfaceManager
Optical surface manager.
SensitiveDetector sensitiveDetector(const std::string &detector) const
Access the sensitive detector of a given subdetector (if the sub-detector is sensitive!...
virtual void * userExtension(unsigned long long int key, bool alert=true) const override
Access an existing extension object from the Detector instance.
double _toDouble(const std::string &value)
String conversions: string to double value.
virtual void * addUserExtension(unsigned long long int key, ExtensionEntry *entry) override
Add an extension object to the Detector instance.
virtual std::string constantAsString(const std::string &name) const override
Typed access to constants: access string values.
Class describing a box shape.
virtual Detector & addVisAttribute(const Handle< NamedObject > &x) override
Add a new visualisation attribute by named reference to the detector description.
virtual void fromXML(const std::string &fname, DetectorBuildType type=BUILD_DEFAULT) override
Read any XML file.
Volume m_parallelWorldVol
T * ptr() const
Access to the held object.
Material m_materialVacuum
ObjectExtensions m_extensions
Definition of the extension type.
void clear(bool destroy=true)
Clear all extensions.
virtual void setStdConditions(double temp, double pressure) override
Set the STD temperature and pressure.
const Volume & setVisAttributes(const VisAttr &obj) const
Set Visualization attributes to the volume.
IFACE * extension(bool alert=true) const
Access extension element by the type.
DetectorBuildType
Detector description build types.
Namespace for the AIDA detector description toolkit.
Data implementation class of the Detector interface.
Volume volume() const
Logical volume of this placement.
void mapDetectorTypes()
Internal helper to map detector types once the geometry is closed.
The main interface to the dd4hep detector description package.
Handle to the implementation of the readout structure of a subdetector.
TGeoManager * m_manager
Reference to the geometry manager object from ROOT.
virtual std::vector< std::string > detectorTypes() const override
Access the available detector types.
int id() const
Get the detector identifier.
virtual Handle< NamedObject > getRefChild(const HandleMap &e, const std::string &name, bool throw_if_not=true) const
void setColor(float alpha, float red, float green, float blue)
Set object color.
ClassImp(DetectorImp) namespace
void imp_loadVolumeManager()
Local method (no interface): Load volume manager.
virtual double constantAsDouble(const std::string &name) const override
Typed access to constants: double values.
static void unpatchRootStreamer(TClass *cl)
UNPatch the ROOT streamers to adapt for DD4hep (set fUserExtension transient)
Concrete implementation class of the Detector interface.
void * addExtension(unsigned long long int key, ExtensionEntry *entry)
Add an extension object to the detector element.
virtual void processXML(const std::string &fname, xml::UriReader *entity_resolver=0)
Process XML unit and adopt all data from source structure.
void * extension(unsigned long long int key, bool alert) const
Access an existing extension object from the detector element.
@ READY
The geometry is loaded.
Region & setThreshold(double value)
Set threshold in MeV.