|
DD4hep
1.30.0
Detector Description Toolkit for High Energy Physics
|
Go to the documentation of this file.
14 #define DD4HEP_MUST_USE_DETECTORIMP_H 1
38 #include <TGeoSystemOfUnits.h>
39 #include <TGeoCompositeShape.h>
40 #include <TGeoBoolNode.h>
41 #include <TGeoManager.h>
42 #include <TGeoMatrix.h>
43 #include <TGeoVolume.h>
44 #include <TGeoShape.h>
50 #include <xercesc/dom/DOMException.hpp>
64 std::recursive_mutex s_detector_apply_lock;
77 std::recursive_mutex lock;
78 std::map<std::string, Detector*>
detectors;
79 Instances() =
default;
82 Detector* get(
const std::string& name) {
84 return i ==
detectors.end() ? 0 : (*i).second;
86 void insert(
const std::string& name,
Detector* detector) {
92 except(
"DD4hep",
"Cannot insert detector instance %s [Already present]",name.c_str());
94 Detector* remove(
const std::string& name) {
105 class DetectorGuard final {
107 static std::pair<std::recursive_mutex, std::map<DetectorImp*, TGeoManager*> >& detector_lock() {
108 static std::pair<std::recursive_mutex, std::map<DetectorImp*, TGeoManager*> > s_inst;
114 ~DetectorGuard() =
default;
115 void lock(TGeoManager* mgr)
const {
116 auto& lock = detector_lock();
118 lock.second[detector] = mgr;
120 TGeoManager* unlock()
const {
121 TGeoManager* mgr =
nullptr;
122 auto& lock = detector_lock();
123 auto i = lock.second.find(detector);
124 if ( i != lock.second.end() ) {
126 lock.second.erase(i);
133 Instances& detector_instances() {
134 static Instances s_inst;
140 std::string vs(
"vXX-YY") ;
141 std::sprintf( &vs[0] ,
"v%2.2d-%2.2d", DD4HEP_MAJOR_VERSION, DD4HEP_MINOR_VERSION ) ;
147 return std::unique_ptr<Detector>(description);
151 std::lock_guard<std::recursive_mutex> lock(detector_instances().lock);
152 Detector* description = detector_instances().get(name);
153 if ( 0 == description ) {
156 detector_instances().insert(name,description);
163 std::lock_guard<std::recursive_mutex> lock(detector_instances().lock);
164 Detector* description = detector_instances().remove(name);
183 #if defined(DD4HEP_USE_GEANT4_UNITS)
184 printout(INFO,
"DD4hep",
"++ Using globally Geant4 unit system (mm,ns,MeV)");
185 if ( TGeoManager::GetDefaultUnits() != TGeoManager::kG4Units ) {
186 TGeoManager::LockDefaultUnits(kFALSE);
187 TGeoManager::SetDefaultUnits(TGeoManager::kG4Units);
188 TGeoManager::LockDefaultUnits(kTRUE);
191 if ( TGeoManager::GetDefaultUnits() != TGeoManager::kRootUnits ) {
192 TGeoManager::LockDefaultUnits(kFALSE);
193 TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
194 TGeoManager::LockDefaultUnits(kTRUE);
198 SetName(name.c_str());
199 SetTitle(
"DD4hep detector description object");
201 gGeoManager =
nullptr;
203 m_manager =
new TGeoManager(name.c_str(),
"Detector Geometry");
208 #if 1 //FIXME: eventually this should be set to 1 - needs fixes in examples ...
209 TGeoElementTable* table =
m_manager->GetElementTable();
210 table->TGeoElementTable::~TGeoElementTable();
211 new(table) TGeoElementTable();
213 table->AddElement(
"VACUUM",
"VACUUM", 1, 1, 1e-15);
216 if ( 0 == gGeoIdentity )
218 gGeoIdentity =
new TGeoIdentity();
237 DetectorGuard(
this).lock(gGeoManager);
239 std::lock_guard<std::recursive_mutex> lock(detector_instances().lock);
240 if (
m_manager == gGeoManager ) gGeoManager = 0;
242 if ( 0 != description ) {
243 detector_instances().remove(
m_manager->GetName());
254 DetectorGuard(
this).unlock();
263 nbytes = TNamed::Write(name, option, bufsize);
271 except(
"Detector",
"Exception %s while saving dd4hep::Detector object", e.what());
276 except(
"Detector",
"UNKNOWN exception while saving dd4hep::Detector object.");
304 if ( !detector_name.empty() ) {
309 if ( parent_volume.
isValid() ) {
313 except(
"DD4hep",
"+++ Failed to access valid parent volume of %s from %s",
314 detector_name.c_str(), parent.
name());
317 "+++ A parent to the detector %s was already registered.",
318 detector_name.c_str());
321 "+++ Attempt to register invalid parent for detector: %s [Invalid-Handle].",
322 detector_name.c_str());
325 "+++ Attempt to register parent to invalid detector [Invalid-detector-name].");
331 std::string de_name = de.
name();
338 "+++ The world volume is not (yet) valid. "
339 "Are you correctly building detector %s?",
342 if ( (*i).second.isValid() ) {
343 Volume vol = (*i).second.volume();
349 "+++ The mother volume of %s is not valid. "
350 "Are you correctly building detectors?",
353 except(
"DD4hep",
"Detector: Attempt access mother volume of invalid detector [Invalid-handle]");
362 printout(WARNING,
"DD4hep",
"++ STD conditions NOT defined by client. NTP defaults taken.");
372 if ( std::abs(temp-Temperature_NTP) < 1e-10 && std::abs(pressure-Pressure_NTP) < 1e-10 )
374 else if ( std::abs(temp-Temperature_STP) < 1e-10 && std::abs(pressure-Pressure_STP) < 1e-10 )
382 if ( type ==
"STP" ) {
387 else if ( type ==
"NTP" ) {
394 "++ Attempt to set standard conditions to "
395 "unknown conventions (Only STP and NTP allowed).");
401 HandleMap::const_iterator i =
m_detectors.find(name);
414 if ( existing_det.
isValid() ) {
417 std::stringstream str;
418 str <<
"Detector: The sensitive sub-detectors " << det_element.
name() <<
" and "
419 << existing_det.
name() <<
" have the identical ID:" << det_element.
id() <<
".";
420 except(
"DD4hep",str.str());
427 std::stringstream str;
428 str <<
"Detector: Adding subdetectors with no valid placement is not allowed: "
429 << det_element.
name() <<
" ID:" << det_element.
id() <<
".";
430 except(
"DD4hep",str.str());
432 Volume volume = pv->GetMotherVolume();
434 printout(DEBUG,
"DD4hep",
"+++ Detector: Added detector %s to the world instance.",
443 parent.
add(det_element);
444 printout(DEBUG,
"DD4hep",
"+++ Detector: Added detector %s to parent %s.",
453 if ( vol == volume ) {
454 printout(INFO,
"DD4hep",
"+++ Detector: Added detector %s to the parent:%s.",
456 parent.
add(det_element);
460 except(
"DD4hep",
"+++ Detector: The detector %s has no known parent.", det_element.
name());
461 throw std::runtime_error(
"Detector-Error");
466 if ( strcmp(x.
name(),
"Detector_InhibitConstants") == 0 ) {
468 char c = ::toupper(title[0]);
480 throw std::runtime_error(
"Detector:constant("+name+
"): Access to global constants is inhibited.");
489 throw std::runtime_error(
"Detector:constantAsString: The constant " + name +
" is not known to the system.");
491 throw std::runtime_error(
"Detector:constantAsString("+name+
"):: Access to global constants is inhibited.");
499 throw std::runtime_error(
"Detector:constantAsLong("+name+
"): Access to global constants is inhibited.");
507 throw std::runtime_error(
"Detector:constantAsDouble("+name+
"): Access to global constants is inhibited.");
519 TGeoMedium* mat =
m_manager->GetMedium(name.c_str());
523 throw std::runtime_error(
"Cannot find a material referenced by name:" + name);
531 if (
det.parent().isValid() ) {
537 else if (
det.type() ==
"compound" ) {
550 std::vector<std::string>
v;
553 v.emplace_back(t.first);
556 throw std::runtime_error(
"detectorTypes: Call only available once the geometry is closed!");
565 throw std::runtime_error(
"detectors("+type+
"): Detectors of this type do not exist in the current setup!");
570 throw std::runtime_error(
"detectors("+type+
"): Detectors can only selected by type once the geometry is closed!");
575 throw std::runtime_error(
"detectors(typeFlag): Detectors can only selected by typeFlag once the geometry is closed!");
577 std::vector<DetElement> dets ;
582 if (
det.parent().isValid() ) {
587 if( (
det.typeFlag() & includeFlag ) == includeFlag &&
588 (
det.typeFlag() & excludeFlag ) == 0 )
589 dets.emplace_back(
det ) ;
597 const std::string& type2,
598 const std::string& type3,
599 const std::string& type4,
600 const std::string& type5 ) {
602 std::vector<DetElement>
v;
605 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
607 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
609 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
611 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
613 v.insert(
v.end(),(*i).second.begin(),(*i).second.end());
616 throw std::runtime_error(
"detectors("+type1+
","+type2+
",...): Detectors can only selected by type once the geometry is closed!");
620 HandleMap::const_iterator it = e.find(name);
629 ptr(
const void* p) { other = p; }
631 std::string nam =
"";
632 ptr mptr(&e), ref(
this);
633 if ( ref.c > mptr.c && mptr.c < ref.c+
sizeof(*
this) ) {
634 nam = mptr.omap->name;
636 std::stringstream err;
637 err <<
"getRefChild: Failed to find child with name: " << name
638 <<
" Map " << nam <<
" contains " << e.size() <<
" elements: {";
639 for (it = e.begin(); it != e.end(); ++it) {
640 if (it != e.begin()) {
646 throw std::runtime_error(err.str());
656 : detail::
GeoScan(e), m_volManager(m), m_world(e) {
659 auto& data = *m_data;
662 printout(INFO,
"Detector",
"+++ Patching names of anonymous shapes....");
663 for (
auto i = data.rbegin(); i != data.rend(); ++i) {
664 for(
const TGeoNode* n : (*i).second ) {
665 TGeoVolume* vol = n->GetVolume();
666 TGeoShape* s = vol->GetShape();
667 const char* sn = s->GetName();
668 ::snprintf(text,
sizeof(text),
"_shape_%p",(
void*)s);
669 if (0 == sn || 0 == ::strlen(sn)) {
670 nam = vol->GetName();
672 s->SetName(nam.c_str());
674 else if (0 == ::strcmp(sn, s->IsA()->GetName())) {
675 nam = vol->GetName();
677 s->SetName(nam.c_str());
681 if (nam.find(
"_shape") == std::string::npos)
683 s->SetName(nam.c_str());
685 if (s->IsA() == TGeoCompositeShape::Class()) {
686 TGeoCompositeShape* c = (TGeoCompositeShape*) s;
687 const TGeoBoolNode*
boolean = c->GetBoolNode();
688 s =
boolean->GetLeftShape();
690 if (0 == sn || 0 == ::strlen(sn)) {
691 s->SetName((nam +
"_left").c_str());
693 else if (0 == ::strcmp(sn, s->IsA()->GetName())) {
694 s->SetName((nam +
"_left").c_str());
696 s =
boolean->GetRightShape();
698 if (0 == sn || 0 == ::strlen(sn)) {
699 s->SetName((nam +
"_right").c_str());
701 else if (0 == ::strcmp(s->GetName(), s->IsA()->GetName())) {
702 s->SetName((nam +
"_right").c_str());
714 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
715 if ( close_geometry && !mgr->IsClosed() ) {
717 Region trackingRegion(
"TrackingRegion");
723 VisAttr trackingVis(
"TrackingVis");
732 mgr->CloseGeometry();
734 auto*
extension = pv->GetUserExtension();
743 patcher.patchShapes();
753 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
764 printout(INFO,
"Detector",
"*********** Use Top Node from manager as "
765 "world volume [%s]. Material: %s BBox: %4.0f %4.0f %4.0f",
767 worldSolid->GetDX(), worldSolid->GetDY(), worldSolid->GetDZ());
771 Solid parallelWorldSolid =
Box(
"world_x",
"world_y",
"world_z");
772 worldSolid =
Box(
"world_x",
"world_y",
"world_z");
775 parallelWorldSolid->SetName(
"parallel_world_solid");
776 printout(INFO,
"Detector",
"*********** Created World volume with size: %4.0f %4.0f %4.0f",
777 worldSolid->GetDX(), worldSolid->GetDY(), worldSolid->GetDZ());
783 worldVis =
VisAttr(
"WorldVis");
813 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
820 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
828 mgr->SetVisOption(1);
834 std::lock_guard<std::recursive_mutex> lock(s_detector_apply_lock);
835 std::string fac = factory_type;
838 long result = PluginService::Create<long>(fac, thisPtr, argc, argv);
841 result = PluginService::Create<long>(fac, thisPtr, argc, argv);
843 throw std::runtime_error(
"dd4hep: apply-plugin: Failed to locate plugin " +
847 result = *(
long*) result;
849 throw std::runtime_error(
"dd4hep: apply-plugin: Failed to execute plugin " + fac);
854 throw std::runtime_error(
xml::_toString(e.msg) +
"\ndd4hep: XML-DOM Exception with plugin:" + fac);
857 throw std::runtime_error(std::string(e.what()) +
"\ndd4hep: with plugin:" + fac);
860 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
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 availible 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.