diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index f593d1b7e2e4111d049d9fc2c4bac63e7666b703..9bc66dde380552dd9e5e08972f8e4863ebcd94af 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -7,8 +7,8 @@ // //==================================================================== -#ifndef DD4hep_LCDD_DETECTOR_H -#define DD4hep_LCDD_DETECTOR_H +#ifndef DD4HEP_LCDD_DETECTOR_H +#define DD4HEP_LCDD_DETECTOR_H // Framework include files #include "DD4hep/Handle.h" @@ -198,7 +198,6 @@ namespace DD4hep { /// Full path to this detector element. May be invalid std::string path; int combineHits; - Volume volume; Alignment alignment; Conditions conditions; PlacedVolume placement; @@ -428,4 +427,4 @@ namespace DD4hep { } /* End namespace Geometry */ } /* End namespace DD4hep */ -#endif /* DD4hep_LCDD_DETECTOR_H */ +#endif /* DD4HEP_LCDD_DETECTOR_H */ diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index bb1e4154bf2e98b5a6c6e0f205929a0a2e1bf72f..0b7ad394ceed0d56713f4953943de278d9e41282 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -15,15 +15,8 @@ #include <string> #include <typeinfo> #include <stdexcept> -#include <TNamed.h> -#ifdef DD4HEP_INSTANCE_COUNTS -#include "DD4hep/InstanceCount.h" -#endif - -class TObject; -class TObjArray; -class TGeoManager; +class TNamed; // Conversion factor from radians to degree: 360/(2*PI) #ifndef RAD_2_DEGREE @@ -129,49 +122,6 @@ namespace DD4hep { return 0xFEEDAFFEDEADFACEULL; } - /** @class Value Handle.h - * - * @author M.Frank - * @version 1.0 - */ - struct Counted { - /// Standard constructor - Counted(); - /// Standard destructor - virtual ~Counted(); - }; - - /** @class Value Handle.h - * - * Class to simply combine to object types to one - * - * @author M.Frank - * @version 1.0 - */ - template <typename Q, typename P> struct Value: public Q, public P -#ifdef DD4HEP_INSTANCE_COUNTS - , public Counted -#endif - { - typedef Q first_base; - typedef P second_base; - /// Standard constructor - Value(); - /// Standard destructor - virtual ~Value(); - }; - - template <typename Q, typename P> inline Value<Q, P>::Value() { -#ifdef DD4HEP_INSTANCE_COUNTS - InstanceCount::increment(this); -#endif - } - template <typename Q, typename P> inline Value<Q, P>::~Value() { -#ifdef DD4HEP_INSTANCE_COUNTS - InstanceCount::decrement(this); -#endif - } - /** @class Handle Handle.h * * @author M.Frank @@ -242,7 +192,6 @@ namespace DD4hep { static void bad_assignment(const std::type_info& from, const std::type_info& to); void assign(Implementation* n, const std::string& nam, const std::string& title); }; - typedef Handle<> Elt_t; typedef Handle<TNamed> Ref_t; /// Helper to delete objects from heap and reset the handle @@ -254,13 +203,13 @@ namespace DD4hep { releasePtr(h.m_element); } /// Functor to destroy handles and delete the cached object - template <typename T = Ref_t> struct DestroyHandle { + template <typename T> struct DestroyHandle { void operator()(T p) const { destroyHandle(p); } }; /// Functor to destroy handles and delete the cached object - template <typename T = Ref_t> struct ReleaseHandle { + template <typename T> struct ReleaseHandle { void operator()(T p) const { releaseHandle(p); } diff --git a/DDCore/include/DD4hep/IDDescriptor.h b/DDCore/include/DD4hep/IDDescriptor.h index c5d70b40a07d7daf6fecac449e7bebe96cdfffd1..774ef2a875e81a868bb062f5a35ec668fd0b97c2 100644 --- a/DDCore/include/DD4hep/IDDescriptor.h +++ b/DDCore/include/DD4hep/IDDescriptor.h @@ -14,6 +14,7 @@ #include "DD4hep/Handle.h" #include "DD4hep/Primitives.h" #include "DDSegmentation/BitField64.h" +#include "TNamed.h" // C++ include files #include <string> diff --git a/DDCore/include/DD4hep/InstanceCount.h b/DDCore/include/DD4hep/InstanceCount.h index cbbb686f4cace0158dabc0e063e323741c7043a1..059fe78fbbd56e0e2336c1ce1c1055cd952c1483 100644 --- a/DDCore/include/DD4hep/InstanceCount.h +++ b/DDCore/include/DD4hep/InstanceCount.h @@ -93,36 +93,28 @@ namespace DD4hep { static Counter* getCounter(const std::string& typ); /// Increment count according to type information template <class T> static void increment(T*) { - getCounter(typeid(T))->increment(); + increment(typeid(T)); } /// Decrement count according to type information template <class T> static void decrement(T*) { - getCounter(typeid(T))->decrement(); + decrement(typeid(T)); } /// Access current counter template <class T> static counter_t get(T*) { return getCounter(typeid(T))->value(); } /// Increment count according to type information - static void increment(const std::type_info& typ) { - getCounter(typ)->increment(); - } + static void increment(const std::type_info& typ); /// Decrement count according to type information - static void decrement(const std::type_info& typ) { - getCounter(typ)->decrement(); - } + static void decrement(const std::type_info& typ); /// Access current counter static counter_t get(const std::type_info& typ) { return getCounter(typ)->value(); } /// Increment count according to string information - static void increment(const std::string& typ) { - getCounter(typ)->increment(); - } + static void increment(const std::string& typ); /// Decrement count according to string information - static void decrement(const std::string& typ) { - getCounter(typ)->decrement(); - } + static void decrement(const std::string& typ); /// Access current counter static counter_t get(const std::string& typ) { return getCounter(typ)->value(); diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h index 563b3acaa37ee9f3bd1d8cc8e52f6ffca10ffbdf..d810e045caa6fc6771c400d33889907b36c67acf 100644 --- a/DDCore/include/DD4hep/Objects.h +++ b/DDCore/include/DD4hep/Objects.h @@ -108,6 +108,7 @@ namespace DD4hep { */ struct Header: public Ref_t { struct Object: public TNamed { + public: std::string url; std::string author; std::string status; @@ -117,6 +118,11 @@ namespace DD4hep { Object(); /// Default destructor virtual ~Object(); + private: + /// Private copy constructor + Object(const Object&) : TNamed() {} + /// Private assignment operator + Object& operator=(const Object&) { return *this; } }; /// Default constructor Header() diff --git a/DDCore/include/DD4hep/VolumeManager.h b/DDCore/include/DD4hep/VolumeManager.h index f1424b5bedaa7144fa8f8b09b0280be5b402e1dd..31419cc42e446d228c43f66512aa41730351e4fb 100644 --- a/DDCore/include/DD4hep/VolumeManager.h +++ b/DDCore/include/DD4hep/VolumeManager.h @@ -231,7 +231,7 @@ namespace DD4hep { /// Assignment operator VolumeManager& operator=(const VolumeManager& m) { - m_element = m.m_element; + if ( this != &m ) m_element = m.m_element; return *this; } /// Add a new Volume manager section according to a new subdetector diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index ff8c6d15ba4659959eda90507c30542428e5f78f..ae70060aa2bafeed7e5e81bc84e53a6a31c6ce31 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -14,6 +14,7 @@ #include "DD4hep/Handle.h" #include "DD4hep/Shapes.h" #include "DD4hep/Objects.h" +//#include "DD4hep/Detector.h" // C/C++ include files #include <map> @@ -22,6 +23,24 @@ #include "TGeoNode.h" #include "TGeoPatternFinder.h" +#if ROOT_VERSION_CODE > ROOT_VERSION(5,34,9) +// Recent ROOT versions +#include "TGeoExtension.h" + +#else +// Older ROOT version +#define DD4HEP_EMULATE_TGEOEXTENSIONS +class TGeoExtension : public TObject { + public: + virtual ~TGeoExtension() {} + /// TGeoExtension overload: Method called whenever requiring a pointer to the extension + virtual TGeoExtension *Grab() = 0; + /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore + virtual void Release() const = 0; +}; + +#endif + /* * DD4hep namespace declaration */ @@ -39,6 +58,7 @@ namespace DD4hep { struct Material; struct VisAttr; struct Volume; + struct DetElement; struct PlacedVolume; struct SensitiveDetector; @@ -59,11 +79,15 @@ namespace DD4hep { Base::const_iterator find(const std::string& name) const; std::pair<Base::iterator, bool> insert(const std::string& name, int value); }; - struct Object { - /// Magic word + struct Object : public TGeoExtension { + /// Magic word to detect memory corruptions unsigned long magic; + /// Reference count on object (used to implement Grab/Release) + long refCount; /// ID container VolIDs volIDs; + /// Detector element with the placement + Ref_t detector; /// Default constructor Object(); /// Copy constructor @@ -76,6 +100,10 @@ namespace DD4hep { volIDs = c.volIDs; return *this; } + /// TGeoExtension overload: Method called whenever requiring a pointer to the extension + virtual TGeoExtension *Grab(); + /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore + virtual void Release() const; }; /// Constructor to be used when reading the already parsed DOM tree PlacedVolume(const TGeoNode* e) @@ -109,11 +137,15 @@ namespace DD4hep { Volume motherVol() const; /// Access to the volume IDs const VolIDs& volIDs() const; + /// Set the detector element if appropriate (requires degenerate geometry subtree) + void setDetector(const DetElement& e) const; + /// Access the corresponding detector element of this placement (if set) + //const DetElement detector() const; /// String dump std::string toString() const; }; - /** @class Volume Volume.h DD4hep/lcdd/Volume.h + /** @class Volume Volume.h DD4hep/Volume.h * * Handle describing a Volume * @@ -124,8 +156,19 @@ namespace DD4hep { public: typedef Handle<TGeoVolume> Base; - struct Object { + + /** @class Volume::Object Volume.h DD4hep/Volume.h + * + * Internal data structure optional to TGeo data + * + * @author M.Frank + * @version 1.0 + */ + struct Object : public TGeoExtension { + /// Magic word to detect memory corruptions unsigned long magic; + /// Reference count on object (used to implement Grab/Release) + long refCount; Region region; LimitSet limits; VisAttr vis; @@ -144,6 +187,10 @@ namespace DD4hep { sens_det = c.sens_det; referenced = c.referenced; } + /// TGeoExtension overload: Method called whenever requiring a pointer to the extension + virtual TGeoExtension *Grab(); + /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore + virtual void Release() const; }; public: diff --git a/DDCore/include/DD4hep/config.h b/DDCore/include/DD4hep/config.h index 337ca06ea28e58b6c2603421226ddb8edf445b71..e6eb9c81bf3996a9302a26733ce9df53cb5fbd02 100644 --- a/DDCore/include/DD4hep/config.h +++ b/DDCore/include/DD4hep/config.h @@ -11,6 +11,13 @@ #define DD4HEP_CONFIG_H #define DD4HEP_INSTANCE_COUNTS +#ifdef DD4HEP_INSTANCE_COUNTS +#define INCREMENT_COUNTER InstanceCount::increment(this) +#define DECREMENT_COUNTER InstanceCount::decrement(this) +#else +#define INCREMENT_COUNTER +#define DECREMENT_COUNTER +#endif /* * DD4hep namespace declaration diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h index 45af4e37b1cc2a03f41329894e6b891e29040f08..556eb8e9b050716f69b77831359e92c727591b75 100644 --- a/DDCore/include/XML/XMLElements.h +++ b/DDCore/include/XML/XMLElements.h @@ -94,8 +94,9 @@ namespace DD4hep { XmlChar* m_tag; XmlElement* m_node; #ifndef __TIXML__ - XmlNodeList* m_ptr; - mutable XmlSize_t m_index; + //XmlNodeList* m_ptr; + //mutable XmlSize_t m_index; + mutable XmlElement* m_ptr; #else mutable XmlElement* m_ptr; #endif diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index 44fa516850be394bb4144677f759ca3de00614d8..184e56be351cf6a3518b9b2755fe289367764797 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -139,8 +139,6 @@ DetElement::Object::~Object() { deletePtr (worldTrafo); deletePtr (parentTrafo); deletePtr (referenceTrafo); - volume.clear(); - //readout.clear(); alignment.clear(); conditions.clear(); placement.clear(); @@ -168,8 +166,6 @@ DetElement::Object* DetElement::Object::clone(int new_id, int flag) const { Ref_t det(obj); obj->id = new_id; obj->combineHits = combineHits; - //obj->readout = readout; - obj->volume = volume; obj->alignment = Alignment(); obj->conditions = Conditions(); obj->parent = DetElement(); @@ -458,7 +454,8 @@ DetElement& DetElement::setPlacement(const PlacedVolume& placement) { if (placement.isValid()) { Object& o = object<Object>(); o.placement = placement; - o.volume = placement.volume(); + //o.volume = placement.volume(); + placement.setDetector(*this); return *this; } throw runtime_error("DD4hep: DetElement::setPlacement: Placement is not defined [Invalid Handle]"); @@ -469,7 +466,7 @@ DetElement& DetElement::setPlacement(const PlacedVolume& placement) { /// Access to the logical volume of the placements (all daughters have the same!) Volume DetElement::volume() const { if (isValid()) { - return object<Object>().volume; + return object<Object>().placement.volume(); } throw runtime_error("DD4hep: DetElement::volume: Self is not defined [Invalid Handle]"); } diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index 32125d4a2379e8f4d5504b1ea955c2846a932783..19d4a338988eb89d41b71f27511d16b8475caf88 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -11,11 +11,15 @@ #include "DD4hep/Handle.h" #include "XML/Evaluator.h" #include <iostream> +#include <cstring> +#include <cstdio> #if !defined(WIN32) && !defined(__ICC) #include "cxxabi.h" #endif +class TObject; + namespace DD4hep { XmlTools::Evaluator& evaluator(); } @@ -28,16 +32,6 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -/// Standard constructor -Counted::Counted() { - InstanceCount::increment(this); -} - -/// Standard destructor -Counted::~Counted() { - InstanceCount::decrement(this); -} - int DD4hep::Geometry::_toInt(const string& value) { string s(value); size_t idx = s.find("(int)"); diff --git a/DDCore/src/InstanceCount.cpp b/DDCore/src/InstanceCount.cpp index e1bb6278c67d9e01e5353720cd31b83f350ef36c..86dd570c371e10a615f41b8608818b078f81f39c 100644 --- a/DDCore/src/InstanceCount.cpp +++ b/DDCore/src/InstanceCount.cpp @@ -36,6 +36,19 @@ namespace { inline StringCounter& strings() { return *(s_strCounts.get()); } + int s_global = 1; + struct _Global { + _Global() {} + ~_Global() { s_global = 0; } + } s_globalObj; + int on_exit_destructors() { + static bool first = true; + if ( first && s_global == 0 && s_trace_instances ) { + first = false; + ::printf("Static out of order destructors occurred. Reference count table is unreliable.....\n"); + } + return 1; + } } /// Standard Constructor @@ -70,11 +83,45 @@ InstanceCount::Counter* InstanceCount::getCounter(const std::type_info& typ) { Counter* cnt = s_trace_instances ? types()[&typ] : &s_nullCount; return (0 != cnt) ? cnt : types()[&typ] = new Counter(); } + /// Access counter object for local caching on optimizations InstanceCount::Counter* InstanceCount::getCounter(const std::string& typ) { Counter* cnt = s_trace_instances ? strings()[&typ] : &s_nullCount; return (0 != cnt) ? cnt : strings()[&typ] = new Counter(); } + +/// Increment count according to string information +void InstanceCount::increment(const std::string& typ) { + if ( s_global ) + getCounter(typ)->increment(); + else + on_exit_destructors(); +} + +/// Decrement count according to string information +void InstanceCount::decrement(const std::string& typ) { + if ( s_global ) + getCounter(typ)->decrement(); + else + on_exit_destructors(); +} + +/// Increment count according to type information +void InstanceCount::increment(const std::type_info& typ) { + if ( s_global ) + getCounter(typ)->increment(); + else + on_exit_destructors(); +} + +/// Decrement count according to type information +void InstanceCount::decrement(const std::type_info& typ) { + if ( s_global ) + getCounter(typ)->decrement(); + else + on_exit_destructors(); +} + /// Force dump of counters void InstanceCount::dump(int typ) { bool need_footer = false; diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index 423688edaa7b1dfb26dcea9ee1337da2000fa852..b5b563f51ade6f601d990d01ee724bb114bf2c1f 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -44,7 +44,7 @@ namespace { struct TopDetElement: public DetElement { TopDetElement(const string& nam, Volume vol) : DetElement(nam,/* "structure", */0) { - object<Object>().volume = vol; + //object<Object>().volume = vol; } }; struct TypePreserve { @@ -241,6 +241,11 @@ Handle<TObject> LCDDImp::getRefChild(const HandleMap& e, const string& name, boo return (*i).second; } if (do_throw) { + int cnt = 0; + cout << "GetRefChild: Failed to find child with name: " << name + << " Map contains " << e.size() << " elements." << endl; + for(i=e.begin(); i!=e.end(); ++i) + cout << " " << cnt << " " << (*i).first << endl; throw runtime_error("Cannot find a child with the reference name:" + name); } return 0; @@ -392,9 +397,11 @@ void LCDDImp::fromXML(const string& xmlfile, LCDDBuildType build_type) { long result = PluginService::Create<long>(type, lcdd, &xml_root); if (0 == result) { PluginDebug dbg; - PluginService::Create<long>(type, lcdd, &xml_root); - throw runtime_error("DD4hep: Failed to locate plugin to interprete files of type" - " \"" + tag + "\" - no factory:" + type + ". " + dbg.missingFactory(type)); + result = PluginService::Create<long>(type, lcdd, &xml_root); + if ( 0 == result ) { + throw runtime_error("DD4hep: Failed to locate plugin to interprete files of type" + " \"" + tag + "\" - no factory:" + type + ". " + dbg.missingFactory(type)); + } } result = *(long*) result; if (result != 1) { @@ -427,8 +434,11 @@ void LCDDImp::apply(const char* factory_type, int argc, char** argv) { long result = PluginService::Create<long>(fac, (LCDD*) this, argc, argv); if (0 == result) { PluginDebug dbg; - PluginService::Create<long>(fac, (LCDD*) this, argc, argv); - throw runtime_error("DD4hep: apply-plugin: Failed to locate plugin " + fac + ". " + dbg.missingFactory(fac)); + result = PluginService::Create<long>(fac, (LCDD*) this, argc, argv); + if ( 0 == result ) { + throw runtime_error("DD4hep: apply-plugin: Failed to locate plugin " + + fac + ". " + dbg.missingFactory(fac)); + } } result = *(long*) result; if (result != 1) { diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 944007fe7d11d3199017de152da008d3f9310adc..8ecbf19e48f53e82f4eaf6d270a68a2421d325df 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -31,25 +31,56 @@ using namespace std; using namespace DD4hep::Geometry; +#ifdef DD4HEP_EMULATE_TGEOEXTENSIONS namespace DD4hep { namespace Geometry { - template <> struct Value<TGeoNodeMatrix, PlacedVolume::Object> : public TGeoNodeMatrix, public PlacedVolume::Object { - Value(const TGeoVolume* v, const TGeoMatrix* m) - : TGeoNodeMatrix(v, m), PlacedVolume::Object() { - magic = magic_word(); - InstanceCount::increment(this); + /** @class Value Handle.h + * + * Class to simply combine to object types to one + * + * @author M.Frank + * @version 1.0 + */ + template <typename Q, typename P> struct Value: public Q, public P { + typedef Q first_base; + typedef P second_base; + /// Standard constructor + Value(); + /// Standard destructor + virtual ~Value(); + }; + + template <typename Q, typename P> inline Value<Q, P>::Value() { + INCREMENT_COUNTER; + } + template <typename Q, typename P> inline Value<Q, P>::~Value() { + DECREMENT_COUNTER; + } + + struct DD_TGeoNodeMatrix : public TGeoNodeMatrix { + TGeoExtension* m_extension; + DD_TGeoNodeMatrix(const TGeoVolume* v, const TGeoMatrix* m) + : TGeoNodeMatrix(v, m), m_extension(0) { + INCREMENT_COUNTER; } - Value(const Value& c) - : TGeoNodeMatrix(c.GetVolume(), c.GetMatrix()), PlacedVolume::Object(c) { - InstanceCount::increment(this); + DD_TGeoNodeMatrix(const DD_TGeoNodeMatrix& c) + : TGeoNodeMatrix(c.GetVolume(), c.GetMatrix()), m_extension(0) { + if ( c.m_extension ) m_extension = c.m_extension->Grab(); + INCREMENT_COUNTER; } - virtual ~Value() { - InstanceCount::decrement(this); + virtual ~DD_TGeoNodeMatrix() { + if ( m_extension ) m_extension->Release(); + DECREMENT_COUNTER; + } + void SetUserExtension(TGeoExtension *ext) { + if (m_extension) m_extension->Release(); + m_extension = 0; + if (ext) m_extension = ext->Grab(); } virtual TGeoNode *MakeCopyNode() const { - TGeoNodeMatrix *node = new Value<TGeoNodeMatrix, PlacedVolume::Object>(*this); - node->SetName(GetName()); + TGeoNodeMatrix *node = new DD_TGeoNodeMatrix(*this); + node->SetName(this->TGeoNodeMatrix::GetName()); // set the mother node->SetMotherVolume(fMother); // set the copy number @@ -101,7 +132,7 @@ namespace DD4hep { return; } - TGeoNodeMatrix *node = new Value<TGeoNodeMatrix, PlacedVolume::Object>(vol, matrix); + TGeoNodeMatrix *node = new DD_TGeoNodeMatrix(vol, matrix); //node = new TGeoNodeMatrix(vol, matrix); node->SetMotherVolume(this); this->T::fNodes->Add(node); @@ -124,14 +155,14 @@ namespace DD4hep { Value(const char* name, TGeoShape* s = 0, TGeoMedium* m = 0) : _VolWrap<TGeoVolume>(name, s, m) { magic = magic_word(); - InstanceCount::increment(this); + INCREMENT_COUNTER; } virtual ~Value() { - InstanceCount::decrement(this); + DECREMENT_COUNTER; } TGeoVolume *_copyVol(TGeoShape *newshape) const { typedef Value<TGeoVolume, Volume::Object> _Vol; - _Vol *vol = new _Vol(GetName(), newshape, fMedium); + _Vol *vol = new _Vol(this->TGeoVolume::GetName(), newshape, fMedium); vol->copy(*this); return vol; } @@ -165,13 +196,13 @@ namespace DD4hep { for (i = 0; i < nbits; i++) vol->SetAttBit(1 << i, TGeoAtt::TestAttBit(1 << i)); for (i = 14; i < 24; i++) - vol->SetBit(1 << i, TestBit(1 << i)); + vol->SetBit(1 << i, this->TGeoVolume::TestBit(1 << i)); // copy field vol->SetField(fField); // Set bits for (i = 0; i < nbits; i++) - vol->SetBit(1 << i, TObject::TestBit(1 << i)); + vol->SetBit(1 << i, this->TGeoVolume::TestBit(1 << i)); vol->SetBit(kVolumeClone); // copy nodes // CloneNodesAndConnect(vol); @@ -197,26 +228,26 @@ namespace DD4hep { Value(const char* name) : _VolWrap<TGeoVolumeAssembly>(name, 0, 0) { magic = magic_word(); - InstanceCount::increment(this); + INCREMENT_COUNTER; } virtual ~Value() { - InstanceCount::decrement(this); + DECREMENT_COUNTER; } TGeoVolume *CloneVolume() const { - TGeoVolume *vol = new Value<TGeoVolumeAssembly, Assembly::Object>(GetName()); + TGeoVolume *vol = new Value<TGeoVolumeAssembly, Assembly::Object>(this->TGeoVolumeAssembly::GetName()); Int_t i; // copy other attributes Int_t nbits = 8 * sizeof(UInt_t); for (i = 0; i < nbits; i++) vol->SetAttBit(1 << i, TGeoAtt::TestAttBit(1 << i)); for (i = 14; i < 24; i++) - vol->SetBit(1 << i, TestBit(1 << i)); + vol->SetBit(1 << i, this->TGeoVolumeAssembly::TestBit(1 << i)); // copy field vol->SetField(fField); // Set bits for (i = 0; i < nbits; i++) - vol->SetBit(1 << i, TObject::TestBit(1 << i)); + vol->SetBit(1 << i, this->TGeoVolumeAssembly::TestBit(1 << i)); vol->SetBit(kVolumeClone); // make copy nodes vol->MakeCopyNodes(this); @@ -237,22 +268,76 @@ namespace DD4hep { } } +typedef DD_TGeoNodeMatrix geo_node_t; + +TGeoVolume* _createTGeoVolume(const string& name, TGeoShape* s, TGeoMedium* m) { + TGeoVolume* v = new Value<TGeoVolume,Volume::Object>(name.c_str()); + v->SetShape(s); + v->SetMedium(m); +} +TGeoVolume* _createTGeoVolumeAssembly(const string& name) { + return new Value<TGeoVolumeAssembly,Assembly::Object>(name.c_str()); +} +PlacedVolume::Object* _userExtension(const PlacedVolume& v) { + geo_node_t* n = (geo_node_t*)v.ptr(); + return (PlacedVolume::Object*)n->m_extension; +} +template <typename T> static typename T::Object* _userExtension(const T& v) { + return dynamic_cast<typename T::Object*>(v.ptr()); +} +#else +typedef TGeoNode geo_node_t; +TGeoVolume* _createTGeoVolume(const string& name, TGeoShape* s, TGeoMedium* m) { + TGeoVolume* e = new TGeoVolume(name.c_str(),s,m); + e->SetUserExtension(new Volume::Object()); + return e; +} +TGeoVolume* _createTGeoVolumeAssembly(const string& name) { + TGeoVolume* e = new TGeoVolumeAssembly(name.c_str()); // It is important to use the correct constructor!! + e->SetUserExtension(new Assembly::Object()); + return e; +} +template <typename T> static typename T::Object* _userExtension(const T& v) { + typedef typename T::Object O; + O* o = (O*)(v.ptr()->GetUserExtension()); + return o; +} +#endif /// Default constructor PlacedVolume::Object::Object() - : magic(0), volIDs() { - InstanceCount::increment(this); + : TGeoExtension(), magic(0), refCount(-1), volIDs(), detector() { + magic = magic_word(); + INCREMENT_COUNTER; } /// Copy constructor PlacedVolume::Object::Object(const Object& c) - : magic(c.magic), volIDs(c.volIDs) { - InstanceCount::increment(this); + : TGeoExtension(), magic(c.magic), refCount(-1), volIDs(c.volIDs), detector(c.detector) { + INCREMENT_COUNTER; } /// Default destructor PlacedVolume::Object::~Object() { - InstanceCount::decrement(this); + DECREMENT_COUNTER; +} + +/// TGeoExtension overload: Method called whenever requiring a pointer to the extension +TGeoExtension* PlacedVolume::Object::Grab() { + Object* ext = const_cast<Object*>(this); + ++ext->refCount; +#ifdef ___print_vols + if ( detector.ptr() ) cout << "Placement grabbed with valid detector element....." << endl; + else cout << "Placement grabbed....." << endl; +#endif + return ext; +} + +/// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore +void PlacedVolume::Object::Release() const { + Object* ext = const_cast<Object*>(this); + --ext->refCount; + if ( 0 == ext->refCount ) delete ext; } /// Lookup volume ID @@ -278,7 +363,7 @@ std::pair<vector<PlacedVolume::VolID>::iterator, bool> PlacedVolume::VolIDs::ins } static PlacedVolume::Object* _data(const PlacedVolume& v) { - PlacedVolume::Object* o = dynamic_cast<PlacedVolume::Object*>(v.ptr()); + PlacedVolume::Object* o = _userExtension(v); if (o) return o; throw runtime_error("DD4hep: Attempt to access invalid handle of type: PlacedVolume"); @@ -311,6 +396,18 @@ const PlacedVolume::VolIDs& PlacedVolume::volIDs() const { return _data(*this)->volIDs; } +/// Set the detector element if appropriate (requires degenerate geometry subtree) +void PlacedVolume::setDetector(const DetElement& e) const { + PlacedVolume::Object* o = _userExtension(*this); + if ( o ) o->detector = e; +} +#if 0 +/// Access the corresponding detector element of this placement (if set) +DetElement PlacedVolume::detector() const { + DetElement e(_data(*this)->detector.ptr()); + return e; +} +#endif /// String dump string PlacedVolume::toString() const { stringstream s; @@ -325,8 +422,8 @@ string PlacedVolume::toString() const { /// Default constructor Volume::Object::Object() - : magic(0), region(), limits(), vis(), sens_det(), referenced(0) { - InstanceCount::increment(this); + : TGeoExtension(), magic(0), refCount(0), region(), limits(), vis(), sens_det(), referenced(0) { + INCREMENT_COUNTER; } /// Default destructor @@ -335,13 +432,43 @@ Volume::Object::~Object() { limits.clear(); vis.clear(); sens_det.clear(); - InstanceCount::decrement(this); + DECREMENT_COUNTER; +} + +/// TGeoExtension overload: Method called whenever requiring a pointer to the extension +TGeoExtension* Volume::Object::Grab() { + Object* ext = const_cast<Object*>(this); + ++ext->refCount; +#ifdef ___print_vols + if ( ext->sens_det.isValid() ) + cout << "Volume grabbed with valid sensitive detector....." << endl; + else + cout << "Volume grabbed....." << endl; +#endif + return ext; +} + +/// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore +void Volume::Object::Release() const { + Object* ext = const_cast<Object*>(this); + --ext->refCount; + if ( 0 == ext->refCount ) { +#ifdef ___print_vols + cout << "Volume deleted....." << endl; +#endif + delete ext; + } + else { +#ifdef ___print_vols + cout << "Volume::Object::Release::refCount:" << ext->refCount << endl; +#endif + } } /// Accessor to the data part of the Volume Volume::Object* _data(const Volume& v, bool throw_exception = true) { //if ( v.ptr() && v.ptr()->IsA() == TGeoVolume::Class() ) return v.data<Volume::Object>(); - Volume::Object* o = dynamic_cast<Volume::Object*>(v.ptr()); + Volume::Object* o = _userExtension<Volume>(v); if (o) return o; else if (!throw_exception) @@ -351,13 +478,12 @@ Volume::Object* _data(const Volume& v, bool throw_exception = true) { /// Constructor to be used when creating a new geometry tree. Volume::Volume(const string& name) { - m_element = new Value<TGeoVolume, Volume::Object>(name.c_str()); + m_element = _createTGeoVolume(name,0,0); } /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes Volume::Volume(const string& name, const Solid& s, const Material& m) { - m_element = new Value<TGeoVolume, Volume::Object>(name.c_str(), s); - setMaterial(m); + m_element = _createTGeoVolume(name,s.ptr(),m.ptr()); } static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* transform) { @@ -369,7 +495,8 @@ static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* transform->SetName(nam.c_str()); } parent->AddNode(daughter, id, transform); - TGeoNode* n = parent->GetNode(id); + geo_node_t* n = (geo_node_t*)parent->GetNode(id); + n->geo_node_t::SetUserExtension(new PlacedVolume::Object()); return PlacedVolume(n); } @@ -575,6 +702,6 @@ bool Volume::isSensitive() const { /// Constructor to be used when creating a new geometry tree. Assembly::Assembly(const string& name) { - m_element = new Value<TGeoVolumeAssembly, Volume::Object>(name.c_str()); + m_element = _createTGeoVolumeAssembly(name); } diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp index 4f7bc16070da649139b5368174fdb64155951a25..b6b81d0aa444617fae7db3c2ce8d5102ce8dee21 100644 --- a/DDCore/src/XML/XMLElements.cpp +++ b/DDCore/src/XML/XMLElements.cpp @@ -115,12 +115,32 @@ void DD4hep::XML::XmlString::release(char** p) { namespace { size_t node_count(XmlElement* e, const XmlChar* t) { - xercesc::DOMNodeList* l = e ? Xml(e).e->getElementsByTagName(t) : 0; - return l ? l->getLength() : INVALID_NODE; + size_t cnt = 0; + string tag = _toString(t); + xercesc::DOMElement* elt, *ee = e ? Xml(e).e : 0; + for(elt=ee->getFirstElementChild(); elt; elt=elt->getNextElementSibling()) { + if ( elt->getParentNode() == ee ) { + string child_tag = _toString(elt->getTagName()); + if ( child_tag == tag ) ++cnt; + } + } + return cnt; + //xercesc::DOMNodeList* l = e ? Xml(e).e->getElementsByTagName(t) : 0; + //return l ? l->getLength() : INVALID_NODE; } XmlElement* node_first(XmlElement* e, const XmlChar* t) { - xercesc::DOMNodeList* l = e ? Xml(e).e->getElementsByTagName(t) : 0; - return Xml(l ? l->item(0) : 0).xe; + //xercesc::DOMNodeList* l = e ? Xml(e).e->getElementsByTagName(t) : 0; + //return Xml(l ? l->item(0) : 0).xe; + size_t cnt = 0; + string tag = _toString(t); + xercesc::DOMElement* elt, *ee = e ? Xml(e).e : 0; + for(elt=ee->getFirstElementChild(); elt; elt=elt->getNextElementSibling()) { + if ( elt->getParentNode() == ee ) { + string child_tag = _toString(elt->getTagName()); + if ( child_tag == tag ) return _XE(elt); + } + } + return 0; } } string DD4hep::XML::_toString(const XmlChar *toTranscode) { @@ -404,7 +424,7 @@ Tag_t& Tag_t::operator=(const string& s) { NodeList::NodeList(const NodeList& copy) : m_node(copy.m_node), m_ptr(0) #ifndef DD4HEP_USE_TINYXML - , m_index(0) + // , m_index(0) #endif { m_tag = XmlString::replicate(copy.m_tag); @@ -415,7 +435,7 @@ NodeList::NodeList(const NodeList& copy) NodeList::NodeList(XmlElement* node, const XmlChar* tag) : m_node(node), m_ptr(0) #ifndef DD4HEP_USE_TINYXML - , m_index(0) + // , m_index(0) #endif { m_tag = XmlString::replicate(tag); @@ -433,9 +453,10 @@ XmlElement* NodeList::reset() { #ifdef DD4HEP_USE_TINYXML return m_ptr=node_first(m_node,m_tag); #else - xercesc::DOMNodeList* l = Xml(m_node).e->getElementsByTagName(m_tag); - m_ptr = (XmlNodeList*) l; - return _XE(l->item(m_index=0)); + return m_ptr=node_first(m_node,m_tag); + //xercesc::DOMNodeList* l = Xml(m_node).e->getElementsByTagName(m_tag); + //m_ptr = (XmlNodeList*) l; + //return _XE(l->item(m_index=0)); #endif } @@ -444,7 +465,13 @@ XmlElement* NodeList::next() const { #ifdef DD4HEP_USE_TINYXML return m_ptr = _XE(m_ptr ? _E(m_ptr)->NextSiblingElement(m_tag) : 0); #else - return _XE(_L(m_ptr)->item(++m_index)); + //return _XE(_L(m_ptr)->item(++m_index)); + xercesc::DOMElement *elt = Xml(m_ptr).e; + for(elt=elt->getNextElementSibling(); elt; elt=elt->getNextElementSibling()) { + string child_tag = _toString(elt->getTagName()); + if ( child_tag == m_tag ) return m_ptr=Xml(elt).xe; + } + return m_ptr=0; #endif } @@ -453,7 +480,13 @@ XmlElement* NodeList::previous() const { #ifdef DD4HEP_USE_TINYXML return m_ptr = _XE(m_ptr ? _E(m_ptr)->PreviousSiblingElement(m_tag) : 0); #else - return _XE(m_index>0 ? _L(m_ptr)->item(--m_index) : 0); + //return _XE(m_index>0 ? _L(m_ptr)->item(--m_index) : 0); + xercesc::DOMElement *elt = Xml(m_ptr).e; + for(elt=elt->getPreviousElementSibling(); elt; elt=elt->getPreviousElementSibling()) { + string child_tag = _toString(elt->getTagName()); + if ( child_tag == m_tag ) return m_ptr=Xml(elt).xe; + } + return m_ptr=0; #endif } diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 56adf568a13d62c47387cfed526a33e8057b8dae..52251ad0a302298dbd2857aefeeae541bec64137 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -452,13 +452,13 @@ template <> void Converter<Readout>::operator()(xml_h e) const { if (seg.hasAttr(Unicode(p->name()))) { string pType = p->type(); if (pType.compare("int") == 0) { - p->setValue(_toString(seg.attr<int>(Unicode(p->name())))); + p->setValue(_toString(seg.attr<int>(Unicode(p->name())))); } else if (pType.compare("float") == 0) { - p->setValue(_toString(seg.attr<float>(Unicode(p->name())))); + p->setValue(_toString(seg.attr<float>(Unicode(p->name())))); } else if (pType.compare("double") == 0) { - p->setValue(_toString(seg.attr<double>(Unicode(p->name())))); + p->setValue(_toString(seg.attr<double>(Unicode(p->name())))); } else { - p->setValue(seg.attr<string>(Unicode(p->name()))); + p->setValue(seg.attr<string>(Unicode(p->name()))); } } else if (not p->isOptional()) { throw_print("FAILED to create segmentation: " + type + ". Missing mandatory parameter: " + p->name() + "!"); @@ -474,6 +474,7 @@ template <> void Converter<Readout>::operator()(xml_h e) const { ro.setIDDescriptor(idSpec); lcdd.addIDSpecification(idSpec); } + printout(DEBUG, "Compact", "++ Registered readout structure: %s.",ro.name()); lcdd.addReadout(ro); } @@ -752,8 +753,11 @@ template <> void Converter<Compact>::operator()(xml_h element) const { xml_coll_t(compact, _U(limits)).for_each(_U(limitset), Converter < LimitSet > (lcdd)); xml_coll_t(compact, _U(display)).for_each(_U(include), Converter < DetElementInclude > (lcdd)); xml_coll_t(compact, _U(display)).for_each(_U(vis), Converter < VisAttr > (lcdd)); + printout(DEBUG, "Compact", "++ Converting readout structures..."); xml_coll_t(compact, _U(readouts)).for_each(_U(readout), Converter < Readout > (lcdd)); + printout(DEBUG, "Compact", "++ Converting included files with subdetector structures..."); xml_coll_t(compact, _U(detectors)).for_each(_U(include), Converter < DetElementInclude > (lcdd)); + printout(DEBUG, "Compact", "++ Converting detector structures..."); xml_coll_t(compact, _U(detectors)).for_each(_U(detector), Converter < DetElement > (lcdd)); xml_coll_t(compact, _U(includes)).for_each(_U(alignment), Converter < AlignmentFile > (lcdd)); xml_coll_t(compact, _U(alignments)).for_each(_U(alignment), Converter < AlignmentEntry > (lcdd));