diff --git a/DDCore/include/DD4hep/DD4hepUnits.h b/DDCore/include/DD4hep/DD4hepUnits.h index d6b8a2503f89b9e28001291f89a11baa2b132497..6bdc5042cd1121638ba7ba7b7a8053c041b04897 100644 --- a/DDCore/include/DD4hep/DD4hepUnits.h +++ b/DDCore/include/DD4hep/DD4hepUnits.h @@ -274,7 +274,6 @@ namespace dd4hep { static const double perMillion = 0.000001; // -*- C++ -*- - // $Id: $ // ---------------------------------------------------------------------- // HEP coherent Physical Constants // diff --git a/DDCore/include/DD4hep/DetType.h b/DDCore/include/DD4hep/DetType.h index fae95081c6e14cf3f80c8f83eb4d6b41e0e07aa7..f5a36398cc0ce4014ed61ae2b2c5ba1392e87155 100644 --- a/DDCore/include/DD4hep/DetType.h +++ b/DDCore/include/DD4hep/DetType.h @@ -26,7 +26,6 @@ namespace DD4hep { * * @author F.gaede, DESY * @date 05.02.2016 - * @version $Id: $ */ class DetType { diff --git a/DDCore/include/DD4hep/IDDescriptor.h b/DDCore/include/DD4hep/IDDescriptor.h index db785ad497fed471f51b25a5f318dc0db7765534..bbe6d9019775c644866c57f2e0c2a863b9b3bc38 100644 --- a/DDCore/include/DD4hep/IDDescriptor.h +++ b/DDCore/include/DD4hep/IDDescriptor.h @@ -30,7 +30,7 @@ namespace DD4hep { class IDDescriptorObject; - /// Class implementing the ID encoding of detector response + /// Class implementing the ID encoding of the detector response /** @class IDDescriptor IDDescriptor.h DDCore/IDDescriptor.h * * @author M.Frank @@ -73,12 +73,16 @@ namespace DD4hep { VolumeID encode(const std::vector<VolID>& ids) const; #endif /// Decode volume IDs and return filled descriptor with all fields - void decodeFields(VolumeID vid, VolIDFields& fields); + void decodeFields(VolumeID vid, VolIDFields& fields) const; + /// Decode volume IDs and return string reprensentation for debugging purposes + std::string str(VolumeID vid) const; + /// Decode volume IDs and return string reprensentation for debugging purposes + std::string str(VolumeID vid, VolumeID mask) const; /// Access string representation std::string toString() const; /// Access the BitField64 object BitField64* decoder(); }; - } /* End namespace Geometry */ -} /* End namespace DD4hep */ + } /* End namespace Geometry */ +} /* End namespace DD4hep */ #endif /* DD4hep_IDDESCRIPTOR_H */ diff --git a/DDCore/include/DD4hep/MatrixHelpers.h b/DDCore/include/DD4hep/MatrixHelpers.h index dc9da135e9a8f5abab4a88f45e9f7be0d3319500..99e9dd1e4de34812315e279d6f806ed949fd8283 100644 --- a/DDCore/include/DD4hep/MatrixHelpers.h +++ b/DDCore/include/DD4hep/MatrixHelpers.h @@ -77,6 +77,20 @@ namespace DD4hep { /// Convert a the rotation part of a TGeoMatrix to XYZAngles \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY XYZAngles _XYZangles(const TGeoMatrix* matrix); + enum MatrixEqualityCode { + MATRICES_EQUAL = 1, + MATRICES_DIFFER_TRANSLATION = 2, + MATRICES_DIFFER_ROTATION = 4 + }; + /// Check matrices for equality + /** Return codes: + * MATRICES_EQUAL: matrices left and right are equal + * MATRICES_DIFFER_TRANSLATION: matrices differ in translation + * MATRICES_DIFFER_ROTATION: matrices differ in rotation + * or combination: MATRICES_DIFFER_TRANSLATION|MATRICES_DIFFER_ROTATION + */ + int _matrixEqual(const TGeoMatrix& left, const TGeoMatrix& right); + } /* End namespace Geometry */ } /* End namespace DD4hep */ diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index 3736ac69379aac178815e00e341f525c69b310a2..69a361c829042f8a905f89533404a795c66adfcd 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -234,6 +234,9 @@ namespace DD4hep { using DDSegmentation::BitFieldValue; #endif + /// Convert volumeID to string format (016X) + std::string volumeID(VolumeID vid); + template<typename C> struct ClearOnReturn { C& container; ClearOnReturn(C& c) : container(c) { } diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index fc7139d7def74d2f63f1d7b36a6c2ece0c55ee48..c7c210c75cbe267278d79562b949dfb18ac42044 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -94,8 +94,18 @@ namespace DD4hep { } /// Find entry std::vector<VolID>::const_iterator find(const std::string& name) const; - /// Inert new entry + /// Insert new entry std::pair<std::vector<VolID>::iterator, bool> insert(const std::string& name, int value); + /// Insert bunch of entries + template< class InputIt> + iterator insert(InputIt first, InputIt last) + { return this->Base::insert(this->Base::end(), first, last); } + /// Insert bunch of entries + template< class InputIt> + iterator insert(std::vector<VolID>::const_iterator pos, InputIt first, InputIt last) + { return this->Base::insert(pos, first, last); } + /// String representation for debugging + std::string str() const; }; /// Magic word to detect memory corruptions unsigned long magic; diff --git a/DDCore/include/DD4hep/objects/VolumeManagerInterna.h b/DDCore/include/DD4hep/objects/VolumeManagerInterna.h index 3a75d33f1e713d154053e0024cd4a51f37c314fd..a347e679f77b8c3ec58d2c3a347b162e80a66173 100644 --- a/DDCore/include/DD4hep/objects/VolumeManagerInterna.h +++ b/DDCore/include/DD4hep/objects/VolumeManagerInterna.h @@ -54,20 +54,20 @@ namespace DD4hep { /// Placement identifier VolumeID identifier; /// Ignore mask of the placement identifier - [[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] + //[[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] VolumeID mask; /// The placement - [[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] + //[[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] PlacedVolume placement; /// Handle to the subdetector element handle - [[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] + //[[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] DetElement detector; /// Handle to the closest Detector element DetElement element; /// The transformation of space-points to the world corrdinate system TGeoHMatrix toWorld; /// The transformation of space-points to the corrdinate system of the closests detector element - [[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] + //[[gnu::deprecated("This member variable might get axed if it is not used, please tell us if you do")]] TGeoHMatrix toDetector; public: /// Default constructor diff --git a/DDCore/include/XML/Evaluator.h b/DDCore/include/XML/Evaluator.h index 5a6cdafc37fc25445cdfc5776b220cce2cb0d897..77883f2bbdd45e4c4710dbfb856d3f44a8ed570f 100644 --- a/DDCore/include/XML/Evaluator.h +++ b/DDCore/include/XML/Evaluator.h @@ -9,7 +9,6 @@ // //========================================================================== // -*- C++ -*- -// $Id$ // --------------------------------------------------------------------------- #ifndef XMLTOOLS_EVALUATOR_H diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index f75f01cf10dade98f88acb03aa3e6e47706f4781..33d5633f71434ef3306e604c07777bd1ef840053 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -72,6 +72,7 @@ namespace DD4hep { UNICODE (chambers); UNICODE (check); UNICODE (checksum); + UNICODE (close); UNICODE (cm); UNICODE (coefficient); UNICODE (coefficients); @@ -154,6 +155,7 @@ namespace DD4hep { UNICODE (generator); UNICODE (gdml); UNICODE (gdmlFile); + UNICODE (geometry); UNICODE (glass); UNICODE (global); UNICODE (global_grid_xy); @@ -274,6 +276,7 @@ namespace DD4hep { UNICODE (o); UNICODE (O); UNICODE (offset); + UNICODE (open); UNICODE (overlap); UNICODE (outer); UNICODE (outer_field); diff --git a/DDCore/include/XML/Utilities.h b/DDCore/include/XML/Utilities.h index 2772a73a704b9c73c67d84384f6983577f023286..dae9a38c412d706623ad8b9f791a202e413c65e7 100644 --- a/DDCore/include/XML/Utilities.h +++ b/DDCore/include/XML/Utilities.h @@ -41,7 +41,6 @@ namespace DD4hep { </envelope> @endverbatim * @author S.Lu DESY, F. Gaede CERN/DESY - * @version $Id: $ */ Geometry::Volume createPlacedEnvelope( DD4hep::Geometry::LCDD& lcdd, DD4hep::XML::Handle_t e , DD4hep::Geometry::DetElement sdet ) ; diff --git a/DDCore/include/XML/config.h b/DDCore/include/XML/config.h index 084d2f4122930ecea0d8bc100734dc5397ca8dfd..4d88bfb6754220a934f28cf06846e4e124cbdfda 100644 --- a/DDCore/include/XML/config.h +++ b/DDCore/include/XML/config.h @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/python/lcdd.py b/DDCore/python/lcdd.py index 6c62ef0cd557c0d36af84366f2ca38e4c0d785d8..61b51ff95914d28cc7a3fb12b746f2017338d8cf 100644 --- a/DDCore/python/lcdd.py +++ b/DDCore/python/lcdd.py @@ -1,4 +1,3 @@ -# $Id: $ #========================================================================== # AIDA Detector description implementation for LCD #-------------------------------------------------------------------------- diff --git a/DDCore/src/BasicGrammar.cpp b/DDCore/src/BasicGrammar.cpp index 21570df2a34dc56cbe241829d2d468143c43cb9e..65c45444633a0e04608168bfedf77135a853e55f 100644 --- a/DDCore/src/BasicGrammar.cpp +++ b/DDCore/src/BasicGrammar.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/Callback.cpp b/DDCore/src/Callback.cpp index ec08ff678782689e6dbbb749da60c440f709d7c7..1447425b02e18202fe65df7cc41904e9840f5eaa 100644 --- a/DDCore/src/Callback.cpp +++ b/DDCore/src/Callback.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/ConditionDerived.cpp b/DDCore/src/ConditionDerived.cpp index 643077791a93ee78f0c053b1d1d10940859b0cd7..49e3450aec168f62d6160d8020c5cc03d27e3106 100644 --- a/DDCore/src/ConditionDerived.cpp +++ b/DDCore/src/ConditionDerived.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/DD4hepRootPersistency.cpp b/DDCore/src/DD4hepRootPersistency.cpp index f1398382ae8c8f11b72d794fa076c6fdfe85f2ba..272253a076505ac96fcd8bc086c3a7ea45faf2d6 100644 --- a/DDCore/src/DD4hepRootPersistency.cpp +++ b/DDCore/src/DD4hepRootPersistency.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/DetAlign.cpp b/DDCore/src/DetAlign.cpp index cc9b9f9286d5cf7e8387913671ed81b72b67e106..ef811a8c76b00de7737a5a60f9b177be13d7a5d2 100644 --- a/DDCore/src/DetAlign.cpp +++ b/DDCore/src/DetAlign.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/DetectorSelector.cpp b/DDCore/src/DetectorSelector.cpp index 27419a804b950430d66b5b0ca70b8d8f54386c2f..c693e128d8f1460f8286aec8ba4ab7ddb599210c 100644 --- a/DDCore/src/DetectorSelector.cpp +++ b/DDCore/src/DetectorSelector.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/Evaluator/hash_map.src b/DDCore/src/Evaluator/hash_map.src index 6ca44e7a9c36c7b28567a5e76a946bcea7628f87..ddb1376d45543d726154234aaed9e73af80cbba2 100644 --- a/DDCore/src/Evaluator/hash_map.src +++ b/DDCore/src/Evaluator/hash_map.src @@ -1,5 +1,4 @@ // -*- C++ -*- -// $Id: hash_map.src,v 1.1 2005-12-07 15:08:51 jpalac Exp $ // --------------------------------------------------------------------------- #ifdef DEBUG_MODE diff --git a/DDCore/src/Evaluator/setStdMath.cpp b/DDCore/src/Evaluator/setStdMath.cpp index 6cb9ab28a358a9c253e1619b9e47e0f0f99d3701..9daab49dfd265b033e80d96f019f2e2acec1568a 100644 --- a/DDCore/src/Evaluator/setStdMath.cpp +++ b/DDCore/src/Evaluator/setStdMath.cpp @@ -1,5 +1,4 @@ // -*- C++ -*- -// $Id$ // ---------------------------------------------------------------------- #include "XML/Evaluator.h" diff --git a/DDCore/src/Evaluator/setSystemOfUnits.cpp b/DDCore/src/Evaluator/setSystemOfUnits.cpp index 68858c76d68669223ac645534be52fe0961379f6..f53cdd461824c83f3ac8fca7f05de0223303c310 100644 --- a/DDCore/src/Evaluator/setSystemOfUnits.cpp +++ b/DDCore/src/Evaluator/setSystemOfUnits.cpp @@ -1,5 +1,4 @@ // -*- C++ -*- -// $Id$ // ---------------------------------------------------------------------- #include "XML/Evaluator.h" diff --git a/DDCore/src/Evaluator/stack.src b/DDCore/src/Evaluator/stack.src index 0da7e55315c100b70312bbe87dc020c40d003853..8079c56d50c2caab495e10bf4cd7056b1ca8fb9f 100644 --- a/DDCore/src/Evaluator/stack.src +++ b/DDCore/src/Evaluator/stack.src @@ -1,5 +1,4 @@ // -*- C++ -*- -// $Id: stack.src,v 1.1 2005-12-07 15:08:51 jpalac Exp $ // --------------------------------------------------------------------------- #ifndef HEP_STACK_SRC diff --git a/DDCore/src/Evaluator/string.src b/DDCore/src/Evaluator/string.src index 86da311c0df315928d9f3e9420f66ab44c020a17..c118dd93947274add6fde4b186c9f867649280fc 100644 --- a/DDCore/src/Evaluator/string.src +++ b/DDCore/src/Evaluator/string.src @@ -1,5 +1,4 @@ // -*- C++ -*- -// $Id: string.src,v 1.1 2005-12-07 15:08:51 jpalac Exp $ // --------------------------------------------------------------------------- #ifndef HEP_STRING_SRC diff --git a/DDCore/src/Exceptions.cpp b/DDCore/src/Exceptions.cpp index 90acc12a8d167e026c3dd23462ae3095a1f3b4f2..ad2b253566f2a51990c4b73504738db4f0c02243 100644 --- a/DDCore/src/Exceptions.cpp +++ b/DDCore/src/Exceptions.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/FieldTypes.cpp b/DDCore/src/FieldTypes.cpp index 99f933bfb66659e8463d6153482f1977bb6a6db6..0ba32c5b1e6ee66ade00161d2e7a2864f0e97c85 100644 --- a/DDCore/src/FieldTypes.cpp +++ b/DDCore/src/FieldTypes.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/Fields.cpp b/DDCore/src/Fields.cpp index 37a9d105dede9f3345fd9573384ec13e12f1a580..8bf79cd875138020c823600a13fe0710ab4620fb 100644 --- a/DDCore/src/Fields.cpp +++ b/DDCore/src/Fields.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/GeoHandler.cpp b/DDCore/src/GeoHandler.cpp index 625614957ded154bf4a73774e993bc4d3045e721..4f3952274794f6a11d0bf26ff3fe4ff12609b8f6 100644 --- a/DDCore/src/GeoHandler.cpp +++ b/DDCore/src/GeoHandler.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/GeometryTreeDump.cpp b/DDCore/src/GeometryTreeDump.cpp index ce5a8b5789137a8d75028e22e9f8f4abe097633b..1b355af381f7aacff6ce8bd849f79dea00301606 100644 --- a/DDCore/src/GeometryTreeDump.cpp +++ b/DDCore/src/GeometryTreeDump.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/GeometryTreeDump.h b/DDCore/src/GeometryTreeDump.h index ed1730ee28c7f8ee7f8ab5c74f51ef83b050aae1..91a60d79408b021d2b3d29ff38a85fcde6497f91 100644 --- a/DDCore/src/GeometryTreeDump.h +++ b/DDCore/src/GeometryTreeDump.h @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/GlobalAlignment.cpp b/DDCore/src/GlobalAlignment.cpp index cb2625850098058c03b0e3b57b3ae6f1bbd6b617..86816ded9e0524ea738ba85135752a75af46b307 100644 --- a/DDCore/src/GlobalAlignment.cpp +++ b/DDCore/src/GlobalAlignment.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index b5649de57bd5973c2fed9d64048a6a73ae7cfbd3..aed23a176515cc661c330b9663d24e0a4c46e9d0 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/IDDescriptor.cpp b/DDCore/src/IDDescriptor.cpp index 74acf99007d352dadc5a7500414b0846c50972cd..592512c81cb9218a5fb3d746a971a463d54a088f 100644 --- a/DDCore/src/IDDescriptor.cpp +++ b/DDCore/src/IDDescriptor.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -16,6 +15,7 @@ #include "DD4hep/IDDescriptor.h" #include "DD4hep/objects/ObjectsInterna.h" #include "DD4hep/InstanceCount.h" +#include "DD4hep/Volumes.h" #include "DD4hep/Printout.h" #include <stdexcept> #include <cstdlib> @@ -47,7 +47,7 @@ IDDescriptor::IDDescriptor(const string& description) { /// Acces string representation string IDDescriptor::toString() const { - if (isValid()) { + if ( isValid() ) { return m_element->GetName(); } return "----"; @@ -110,24 +110,45 @@ size_t IDDescriptor::fieldID(const string& field_name) const { /// Encode a set of volume identifiers (corresponding to this description of course!) to a volumeID. VolumeID IDDescriptor::encode(const std::vector<VolID>& id_vector) const { VolumeID id = 0; + //const PlacedVolume::VolIDs* ids = (const PlacedVolume::VolIDs*)&id_vector; + //printout(INFO,"IDDescriptor","VolIDs: %s",ids->str().c_str()); for (const auto& i : id_vector ) { - Field f = field(i.first); - int offset = f->offset(); - id |= ((f->value(i.second<<offset) << offset)&f->mask()); + Field fld = field(i.first); + int off = fld->offset(); + VolumeID val = i.second; + id |= ((fld->value(val<<off) << off)&fld->mask()); } return id; } /// Decode volume IDs and return filled descriptor with all fields -void IDDescriptor::decodeFields(VolumeID vid, VolIDFields& flds) { +void IDDescriptor::decodeFields(VolumeID vid, VolIDFields& flds) const { + const vector<BitFieldValue*>& v = access()->fields(); flds.clear(); - if ( isValid() ) { - const vector<BitFieldValue*>& v = ptr()->fields(); - for (auto f : v ) - flds.push_back(VolIDField(f, f->value(vid))); - return; + for (auto f : v ) + flds.push_back(VolIDField(f, f->value(vid))); +} + +/// Decode volume IDs and return string reprensentation for debugging purposes +string IDDescriptor::str(VolumeID vid) const { + const vector<BitFieldValue*>& v = access()->fields(); + stringstream str; + for (auto f : v ) + str << f->name() << ":" << setw(4) << setfill('0') << hex << right << f->value(vid) + << left << dec << " "; + return str.str().substr(0,str.str().length()-1); +} + +/// Decode volume IDs and return string reprensentation for debugging purposes +string IDDescriptor::str(VolumeID vid, VolumeID mask) const { + const vector<BitFieldValue*>& v = access()->fields(); + stringstream str; + for (auto f : v ) { + if ( 0 == (mask&f->mask()) ) continue; + str << f->name() << ":" << setw(4) << setfill('0') << hex << right << f->value(vid) + << left << dec << " "; } - except("IDDescriptor","DD4hep: Attempt to access an invalid IDDescriptor object."); + return str.str().substr(0,str.str().length()-1); } /// Access the BitField64 object diff --git a/DDCore/src/IOV.cpp b/DDCore/src/IOV.cpp index 09ffc46472d3a0d1a66887e443516ba5775a7839..5d6d5358d0d3dec33c6f34f4b05e3652f301e791 100644 --- a/DDCore/src/IOV.cpp +++ b/DDCore/src/IOV.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/InstanceCount.cpp b/DDCore/src/InstanceCount.cpp index 16796c28c12f467706fcc1e59ae8edac32591d8b..3436585807ba5f9e9e7587fbd13495b4e882e99c 100644 --- a/DDCore/src/InstanceCount.cpp +++ b/DDCore/src/InstanceCount.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/LCDDData.cpp b/DDCore/src/LCDDData.cpp index d0fb90e5b521963a1d1794454e59d5a7b9a4c6d5..2d89d54c1d470f128cd431c2abe799a88b84169d 100644 --- a/DDCore/src/LCDDData.cpp +++ b/DDCore/src/LCDDData.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/LCDDHelper.cpp b/DDCore/src/LCDDHelper.cpp index 6cc1f730d2ba5fe6bc604397b6c2b68d3b1c6684..a391a8bc087f124764cb7e1c03dc5c0f03138a26 100644 --- a/DDCore/src/LCDDHelper.cpp +++ b/DDCore/src/LCDDHelper.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index f307b843544949898d242d7fde9d2156741352c8..ac31e6ef373c771ad367555d6d0c116271f34e0f 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h index ddd5cbb4cb2d71b6be8e0704844ef0263c0ddc11..6f4373170a19fed699f5a6ea468ae13ccf701751 100644 --- a/DDCore/src/LCDDImp.h +++ b/DDCore/src/LCDDImp.h @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/LCDDLoad.cpp b/DDCore/src/LCDDLoad.cpp index 8936dd412d9b2db18aacc1e3ea05b345f18e982e..182d1bc80b0242370ed8afcd7f6f0795d90cd087 100644 --- a/DDCore/src/LCDDLoad.cpp +++ b/DDCore/src/LCDDLoad.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/MatrixHelpers.cpp b/DDCore/src/MatrixHelpers.cpp index bd3d18ffa62b0b414db4002b623efa0acbef2af3..19a5422a42523d17af2409105cdf03e7594e74f2 100644 --- a/DDCore/src/MatrixHelpers.cpp +++ b/DDCore/src/MatrixHelpers.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -145,3 +144,28 @@ void DD4hep::Geometry::_decompose(const Transform3D& trafo, Position& pos, XYZAn trafo.GetDecomposition(r,pos); rot.SetXYZ(r.Psi(),r.Theta(),r.Phi()); } + +/// Check matrices for equality +int DD4hep::Geometry::_matrixEqual(const TGeoMatrix& left, const TGeoMatrix& right) { + double epsilon = 1e-12; + int result = MATRICES_EQUAL; + const Double_t* t1 = left.GetTranslation(); + const Double_t* t2 = right.GetTranslation(); + for(int i=0; i<3; ++i) { + if ( std::fabs(t1[i]-t2[i]) > epsilon ) { + result = MATRICES_DIFFER_TRANSLATION; + break; + } + } + const Double_t* r1 = left.GetRotationMatrix(); + const Double_t* r2 = right.GetRotationMatrix(); + for(int i=0; i<9; ++i) { + if ( std::fabs(r1[i]-r2[i]) > epsilon ) { + result |= MATRICES_DIFFER_ROTATION; + break; + } + } + return result; +} + + diff --git a/DDCore/src/NamedObject.cpp b/DDCore/src/NamedObject.cpp index 3b8566f2d545706a068fa4ccf8cceda0db209d4b..825f227e7fcf7750bbe54265ac9c5c089cb276eb 100644 --- a/DDCore/src/NamedObject.cpp +++ b/DDCore/src/NamedObject.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp index f2d02e57ecf360c2ee9c41fe56a0c98347ef73a3..5116e26a8004e9d145a478d967d4034b885b25ce 100644 --- a/DDCore/src/Objects.cpp +++ b/DDCore/src/Objects.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/ObjectsInterna.cpp b/DDCore/src/ObjectsInterna.cpp index a842a0d3b8de2b8e6d1c29e811abc2c600f04217..4361f4216d05f1388a625034040850a9f3bafd11 100644 --- a/DDCore/src/ObjectsInterna.cpp +++ b/DDCore/src/ObjectsInterna.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/Path.cpp b/DDCore/src/Path.cpp index d3929b1d33542f2d0c0a3c30ca5b50194bb1b8fc..432867874c43000209a4df17fe5a6c29b6be1b67 100644 --- a/DDCore/src/Path.cpp +++ b/DDCore/src/Path.cpp @@ -1,3 +1,4 @@ +//========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) @@ -11,7 +12,6 @@ // \version 1.0 // //========================================================================== -// $Id$ #include "DD4hep/Path.h" #include <climits> diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp index f84da1cadc3f4bfa7d0490781d33f3f2e19ef2d7..54c32cec8bb39dccb25ebc0a3308a4f93e187265 100644 --- a/DDCore/src/Primitives.cpp +++ b/DDCore/src/Primitives.cpp @@ -144,6 +144,13 @@ namespace { }; } +/// Convert volumeID to string format (016X) +std::string DD4hep::volumeID(VolumeID vid) { + char text[32]; + ::snprintf(text,sizeof(text),"%016llx",vid); + return text; +} + /// We need it so often: one-at-time 64 bit hash function unsigned long long int DD4hep::hash64(const char* key) { //return murmur_hash_64(key, strlen(key)); diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp index 3c57df3ed299bd6f52289870a9ec3d234b3a61dc..2d361546d12b390c6900f055816e4d8a96c9fc83 100644 --- a/DDCore/src/VolumeManager.cpp +++ b/DDCore/src/VolumeManager.cpp @@ -14,6 +14,7 @@ // Framework include files #include "DD4hep/LCDD.h" #include "DD4hep/Printout.h" +#include "DD4hep/MatrixHelpers.h" #include "DD4hep/objects/DetectorInterna.h" #include "DD4hep/objects/VolumeManagerInterna.h" @@ -48,11 +49,15 @@ namespace DD4hep { VolumeManager m_volManager; /// Set of already added entries set<VolumeID> m_entries; + /// Debug flag + bool m_debug; public: /// Default constructor VolumeManager_Populator(LCDD& lcdd, VolumeManager vm) - : m_lcdd(lcdd), m_volManager(vm) { + : m_lcdd(lcdd), m_volManager(vm) + { + m_debug = (0 != ::getenv("DD4HEP_VOLMGR_DEBUG")); } /// Populate the Volume manager @@ -69,43 +74,16 @@ namespace DD4hep { PlacedVolume pv = de.placement(); if (pv.isValid()) { Chain chain; + Encoding coding(0, 0); SensitiveDetector sd = parent_sd; m_entries.clear(); -#if 0 - if ( typ ) { - Encoding coding(0, 0); - scanPhysicalVolume(de, de, pv, coding, sd, chain); - continue; - } - VolIDs ids; - scanPhysicalVolume(de, de, pv, ids, sd, chain); -#else - Encoding coding(0, 0); scanPhysicalVolume(de, de, pv, coding, sd, chain); -#endif continue; } printout(WARNING, "VolumeManager", "++ Detector element %s of type %s has no placement.", de.name(), de.type().c_str()); } } - /// Find a detector element below with the corresponding placement - DetElement findElt(DetElement e, PlacedVolume pv) { - const DetElement::Children& c = e.children(); - if (e.placement().ptr() == pv.ptr()) - return e; - for (const auto& i : c ) { - DetElement de = i.second; - if ( de.placement().ptr() == pv.ptr() ) - return de; - } - for (const auto& i : c ) { - DetElement de = findElt(i.second, pv); - if ( de.isValid() ) - return de; - } - return DetElement(); - } /// Scan a single physical volume and look for sensitive elements below size_t scanPhysicalVolume(DetElement& parent, DetElement e, PlacedVolume pv, Encoding parent_encoding, @@ -151,7 +129,16 @@ namespace DD4hep { PlacedVolume placement(daughter); if ( placement.data() ) { PlacedVolume pv_dau(daughter); - DetElement de_dau = findElt(e, daughter); + DetElement de_dau; + /// Check if this particular volume is the placement of one of the + /// children of this detector element. If the daughter placement is also + /// a detector child, then we must reset the node chain. + for( const auto& de : e.children() ) { + if ( de.second.placement().ptr() == daughter ) { + de_dau = de.second; + break; + } + } if ( de_dau.isValid() ) { Chain dau_chain; count += scanPhysicalVolume(parent, de_dau, pv_dau, vol_encoding, sd, dau_chain); @@ -171,98 +158,40 @@ namespace DD4hep { } if ( sd.isValid() ) { if ( !have_encoding ) { - printout(ERROR, "VolumeManager","%s: Missing SD encoding. Volume manager won't work!", + printout(ERROR, "VolumeManager","Element %s: Missing SD encoding. Volume manager won't work!", e.path().c_str()); } - bool add_det_vol_id = (is_sensitive || count > 0) && node == e.placement().ptr(); - if ( add_det_vol_id ) { - // 1) We recuperate volumes from lower levels by reusing the subdetector - // This only works if there is exactly one sensitive detector per subdetector! - // 2) DetElements in the upper hierarchy of the sensitive also get al volume id, - // and the volume is registered. (to be discussed) - // - // I hate this, but I could not talk Frank out of this! M.F. - // - printout(VERBOSE,"VolumeManager","++++ %-11s SD:%s VolID=%p Mask=%p",e.path().c_str(), - have_encoding ? "RECUPERATED" : "REGULAR", sd.name(), - (void*)vol_encoding.first, (void*)vol_encoding.second); - e.object<DetElement::Object>().volumeID = vol_encoding.first; - } - if ( is_sensitive || add_det_vol_id ) { - add_entry(sd, parent, e, node, vol_encoding, chain); - ++count; - } - } - chain.pop_back(); - } - return count; - } - /// Scan a single physical volume and look for sensitive elements below - size_t scanPhysicalVolume(DetElement& parent, DetElement e, PlacedVolume pv, - VolIDs ids, SensitiveDetector& sd, Chain& chain) - { - TGeoNode* node = pv.ptr(); - size_t count = 0; - if (node) { - Volume vol = pv.volume(); - chain.push_back(node); - VolIDs pv_ids = pv.volIDs(); - ids.VolIDs::Base::insert(ids.end(), pv_ids.begin(), pv_ids.end()); - bool got_readout = false; - if ( vol.isSensitive() ) { - sd = vol.sensitiveDetector(); - Readout ro = sd.readout(); - if ( sd.isValid() && ro.isValid() ) { - got_readout = true; - add_entry(sd, parent, e, node, ids, chain); - ++count; - } - else { - printout(WARNING, "VolumeManager", - "%s: Strange constellation volume %s is sensitive, but has no readout! sd:%p", - parent.name(), pv.volume().name(), sd.ptr()); - } - } - for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) { - TGeoNode* daughter = node->GetDaughter(idau); - PlacedVolume placement(daughter); - if ( placement.data() ) { - size_t cnt; - PlacedVolume pv_dau = Ref_t(daughter); - DetElement de_dau = findElt(e, daughter); - if ( de_dau.isValid() ) { - Chain dau_chain; - cnt = scanPhysicalVolume(parent, de_dau, pv_dau, ids, sd, dau_chain); + if ( is_sensitive || count > 0 ) { + /// Distinguish logically the two following cases for our understanding.... + /// Though the treatment is identical + if ( node == e.placement().ptr() ) { + // These here are placement nodes, which at the same time are DetElement placements + // 1) We recuperate volumes from lower levels by reusing the subdetector + // This only works if there is exactly one sensitive detector per subdetector! + // 2) DetElements in the upper hierarchy of the sensitive also get al volume id, + // and the volume is registered. (to be discussed) + // + // I hate this, but I could not talk Frank out of this! M.F. + // + e.object<DetElement::Object>().volumeID = vol_encoding.first; } - else { - cnt = scanPhysicalVolume(parent, e, pv_dau, ids, sd, chain); + else { + // These here are placement nodes, which are no DetElement placement + // used e.g. to model a very fine grained sensitive volume structure + // without always having DetElements. } - // There was a sensitive daughter volume, also add the parent entry. - if ( count == 0 && cnt > 0 && sd.isValid() && !pv_ids.empty()) { - add_entry(sd, parent, e, node, ids, chain); + add_entry(sd, parent, e, node, vol_encoding, chain); + ++count; + if ( m_debug ) { + IDDescriptor id(sd.readout().idSpec()); + printout(INFO,"VolumeManager","Parent: %-44s id:%016llx Encoding: %s", + parent.path().c_str(), parent.volumeID(), id.str(parent_encoding.first,parent_encoding.second).c_str()); + printout(INFO,"VolumeManager","Element:%-44s id:%016llx Encoding: %s", + e.path().c_str(), e.volumeID(), id.str(vol_encoding.first,vol_encoding.second).c_str()); + printout(INFO, "VolumeManager", "%s SD:%s VolIDs:%s id:%016llx mask:%016llx", + node == e.placement().ptr() ? "DETELEMENT PLACEMENT" : "VOLUME PLACEMENT ", + sd.name(), pv_ids.str().c_str(), vol_encoding.first, vol_encoding.second); } - count += cnt; - } - else { - throw runtime_error("Invalid not instrumented placement:"+string(daughter->GetName())+ - " [Internal error -- bad detector constructor]"); - } - } - if ( count == 0 ) { - sd = SensitiveDetector(0); - } - else if ( count > 0 && sd.isValid() ) { - // We recuperate volumes from lower levels by reusing the subdetector - // This only works if there is exactly one sensitive detector per subdetector! - // I hate this, but I could not talk Frank out of this! M.F. - Readout ro = sd.readout(); - if ( ro.isValid() ) { - IDDescriptor iddesc = ro.idSpec(); - Encoding det_encoding = encoding(iddesc,ids); - printout(VERBOSE,"VolumeManager","++++ %-11s SD:%s VolID=%p Mask=%p",e.path().c_str(), - got_readout ? "RECUPERATED" : "REGULAR", sd.name(), - (void*)det_encoding.first, (void*)det_encoding.second); - e.object<DetElement::Object>().volumeID = det_encoding.first; } } chain.pop_back(); @@ -277,8 +206,9 @@ namespace DD4hep { const PlacedVolume::VolID& id = (*i); IDDescriptor::Field f = iddesc.field(id.first); VolumeID msk = f->mask(); - int offset = f->offset(); - volume_id |= ((f->value(id.second << offset) << offset)&msk); + int off = f->offset(); + VolumeID val = id.second; // Necessary to extend volume IDs > 32 bit + volume_id |= ((f->value(val << off) << off)&msk); mask |= msk; } return make_pair(volume_id, mask); @@ -291,7 +221,8 @@ namespace DD4hep { IDDescriptor::Field f = iddesc.field(id.first); VolumeID msk = f->mask(); int off = f->offset(); - volume_id |= ((f->value(id.second<<off)<<off)&msk); + VolumeID val = id.second; // Necessary to extend volume IDs > 32 bit + volume_id |= ((f->value(val << off) << off)&msk); mask |= msk; } return make_pair(volume_id, mask); @@ -322,7 +253,7 @@ namespace DD4hep { context->toDetector = context->toWorld; context->toDetector.MultiplyLeft(nodes[0]->GetMatrix()); context->toWorld.MultiplyLeft(&parent.nominal().worldTransformation()); - if (!section.adoptPlacement(context)) { + if ( !section.adoptPlacement(context) || m_debug ) { print_node(sd, parent, e, n, code, nodes); } m_entries.insert(code.first); @@ -331,88 +262,43 @@ namespace DD4hep { * These are only consistentcyu tests */ - // We HAVE to check at least once if the matrices from the original DetElement - // and from the nominal alignment are identical.... - string p = ""; - for (size_t i=0; i<nodes.size(); ++i) { // Omit the placement of the parent DetElement - p += "/"; - p += nodes[i]->GetName(); - } { - double epsilon = 1e-12; - const Double_t* t1 = e->__worldTransformation().GetTranslation(); - const Double_t* t2 = e.nominal().worldTransformation().GetTranslation(); - for(int i=0; i<3; ++i) { - if ( std::fabs(t1[i]-t2[i]) > epsilon ) { - stringstream log; - log << "Alignment:"; - for(size_t j=0; j<e.nominal()->nodes.size(); ++j) - log << " " << (void*)e.nominal()->nodes[j].ptr(); - log << " Nodes:"; - for (size_t j = 0; j<nodes.size(); ++j) { - log << " " << (void*)nodes[j]; - } - printout(WARNING,"Volumes", - "+++ World matrix of %s // %s is NOT equal (translation) [diff[%d]=%g]! Pointers:%s", - e.placementPath().c_str(),p.c_str(),i,std::fabs(t1[i]-t2[i]),log.str().c_str()); - break; + int res1 = _matrixEqual(e->__worldTransformation(),e.nominal().worldTransformation()); + int res2 = _matrixEqual(e->__parentTransformation(),e.nominal().detectorTransformation()); + if ( res1 != MATRICES_EQUAL || res2 != MATRICES_EQUAL ) { + stringstream log; + // We HAVE to check at least once if the matrices from the original DetElement + // and from the nominal alignment are identical.... + string p = ""; + for (size_t i=0; i<nodes.size(); ++i) { // Omit the placement of the parent DetElement + p += "/"; + p += nodes[i]->GetName(); } - } - const Double_t* r1 = e->__worldTransformation().GetRotationMatrix(); - const Double_t* r2 = e.nominal().worldTransformation().GetRotationMatrix(); - for(int i=0; i<9; ++i) { - if ( std::fabs(r1[i]-r2[i]) > epsilon ) { - stringstream log; - log << "Alignment:"; - for(size_t j=0; j<e.nominal()->nodes.size(); ++j) - log << " " << (void*)e.nominal()->nodes[j].ptr(); - log << " Nodes:"; - for (size_t j = 0; j<nodes.size(); ++j) { - log << " " << (void*)nodes[j]; - } - printout(WARNING,"Volumes", - "+++ World matrix of %s // %s is NOT equal (rotation) [diff[%d]=%g]! Pointers:%s", - e.placementPath().c_str(),p.c_str(),i,std::fabs(r1[i]-r2[i]),log.str().c_str()); - break; + + log << "Alignment:"; + for(size_t j=0; j<e.nominal()->nodes.size(); ++j) + log << " " << (void*)e.nominal()->nodes[j].ptr(); + log << " Nodes:"; + for (size_t j = 0; j<nodes.size(); ++j) { + log << " " << (void*)nodes[j]; } - } - } - { - double epsilon = 1e-12; - const Double_t* t1 = e->__parentTransformation().GetTranslation(); - const Double_t* t2 = e.nominal().detectorTransformation().GetTranslation(); - for(int i=0; i<3; ++i) { - if ( std::fabs(t1[i]-t2[i]) > epsilon ) { - stringstream log; - log << "Alignment:"; - for(size_t j=0; j<e.nominal()->nodes.size(); ++j) - log << " " << (void*)e.nominal()->nodes[j].ptr(); - log << " Nodes:"; - for (size_t j = 0; j<nodes.size(); ++j) { - log << " " << (void*)nodes[j]; - } - printout(WARNING,"Volumes", - "+++ Parent matrix of %s // %s is NOT equal (translation) [diff[%d]=%g]! Pointers:%s ", - e.placementPath().c_str(),p.c_str(),i,std::fabs(t1[i]-t2[i]), log.str().c_str()); - break; + if ( res1 != MATRICES_EQUAL ) { + res1 = _matrixEqual(e->__worldTransformation(),e.nominal().worldTransformation()); + const char* tag = (res1==MATRICES_DIFFER_TRANSLATION) ? "translation" + : (res1==MATRICES_DIFFER_ROTATION) ? "rotation" + : "translation+rotation"; + printout(WARNING,"VolumeManager", + "+++ World matrix of %s // %s is NOT equal (%s)! Pointers:%s", + e.placementPath().c_str(),p.c_str(),tag,log.str().c_str()); } - } - const Double_t* r1 = e->__parentTransformation().GetRotationMatrix(); - const Double_t* r2 = e.nominal().detectorTransformation().GetRotationMatrix(); - for(int i=0; i<9; ++i) { - if ( std::fabs(r1[i]-r2[i]) > epsilon ) { - stringstream log; - log << "Alignment:"; - for(size_t j=0; j<e.nominal()->nodes.size(); ++j) - log << " " << (void*)e.nominal()->nodes[j].ptr(); - log << " Nodes:"; - for (size_t j = 0; j<nodes.size(); ++j) { - log << " " << (void*)nodes[j]; - } - printout(WARNING,"Volumes", - "+++ Parent matrix of %s // %s is NOT equal (rotation) [diff[%d]=%g]! %s", - e.placementPath().c_str(),p.c_str(),i,std::fabs(r1[i]-r2[i]), log.str().c_str()); - break; + if ( res2 != MATRICES_EQUAL ) { + res2 = _matrixEqual(e->__parentTransformation(),e.nominal().detectorTransformation()); + const char* tag = (res2==MATRICES_DIFFER_TRANSLATION) ? "translation" + : (res2==MATRICES_DIFFER_ROTATION) ? "rotation" + : "translation+rotation"; + printout(WARNING,"VolumeManager", + "+++ Parent matrix of %s // %s is NOT equal (%s)! Pointers:%s ", + e.placementPath().c_str(),p.c_str(), tag, log.str().c_str()); } } } @@ -420,101 +306,27 @@ namespace DD4hep { } } - void add_entry(SensitiveDetector sd, DetElement parent, DetElement e, - const TGeoNode* n, const VolIDs& ids, Chain& nodes) - { - if ( sd.isValid() ) { - Readout ro = sd.readout(); - IDDescriptor iddesc = ro.idSpec(); - Encoding code = encoding(iddesc, ids); - - if (m_entries.find(code.first) == m_entries.end()) { - string sd_name = sd.name(); - DetElement sub_detector = m_lcdd.detector(sd_name); - VolumeManager section = m_volManager.addSubdetector(sub_detector, ro); - // This is the block, we effectively have to save for each physical volume with a VolID - VolumeManager::Context* context = new VolumeManager::Context; - context->identifier = code.first; - context->mask = code.second; - context->detector = parent; - context->placement = PlacedVolume(n); - context->element = e; -#if 0 - context->volID = ids; - context->path = nodes; -#endif - for (size_t i = nodes.size(); i > 1; --i) { // Omit the placement of the parent DetElement - TGeoMatrix* m = nodes[i - 1]->GetMatrix(); - context->toWorld.MultiplyLeft(m); - } - context->toDetector = context->toWorld; - context->toDetector.MultiplyLeft(nodes[0]->GetMatrix()); - context->toWorld.MultiplyLeft(&parent.worldTransformation()); - if (!section.adoptPlacement(context)) { - print_node(sd, parent, e, n, ids, nodes); - } - m_entries.insert(code.first); - } - } - } - void print_node(SensitiveDetector sd, DetElement parent, DetElement e, - const TGeoNode* n, const VolIDs& ids, const Chain& /* nodes */) const + const TGeoNode* n, const Encoding& code, const Chain& nodes) const { - static int s_count = 0; - Readout ro = sd.readout(); - const IDDescriptor& en = ro.idSpec(); - PlacedVolume pv = Ref_t(n); + PlacedVolume pv = n; + Readout ro = sd.readout(); bool sensitive = pv.volume().isSensitive(); - Encoding code = encoding(en, ids); - VolumeID volume_id = code.first; //if ( !sensitive ) return; - ++s_count; stringstream log; - log << s_count << ": " << parent.name() << ": " << e.name() - << " ro:" << ro.ptr() << " pv:" << n->GetName() << " id:" - << (void*) volume_id << " : "; - for (VolIDs::const_iterator i = ids.begin(); i != ids.end(); ++i) { - const PlacedVolume::VolID& id = (*i); - IDDescriptor::Field f = ro.idSpec().field(id.first); - VolumeID value = f->value(volume_id); - log << id.first << "=" << id.second << "," << value - << " [" << f->offset() << "," << f->width() << "] "; - } - log << " Sensitive:" << yes_no(sensitive); - printout(DEBUG, "VolumeManager", log.str().c_str()); -#if 0 - log.str(""); - log << s_count << ": " << e.name() << " Detector GeoNodes:"; - for(vector<const TGeoNode*>::const_iterator j=nodes.begin(); j!=nodes.end();++j) - log << (void*)(*j) << " "; - printout(DEBUG,"VolumeManager",log.str().c_str()); -#endif - } - void print_node(SensitiveDetector sd, DetElement parent, DetElement e, - const TGeoNode* n, const Encoding& code, const Chain& /* nodes */) const - { - static int s_count = 0; - Readout ro = sd.readout(); - PlacedVolume pv = Ref_t(n); - bool sensitive = pv.volume().isSensitive(); - VolumeID volume_id = code.first; + log << m_entries.size() << ": Detector: " << e.path() + << " id:" << volumeID(code.first) + << " Nodes(" << int(nodes.size()) << "):" << ro.idSpec().str(code.first,code.second); + printout(m_debug ? INFO : DEBUG,"VolumeManager",log.str().c_str()); + //for(const auto& i : nodes ) + // log << i->GetName() << "/"; - //if ( !sensitive ) return; - ++s_count; - stringstream log; - log << s_count << ": " << parent.name() << ": " << e.name() - << " ro:" << ro.ptr() << " pv:" << n->GetName() << " id:" - << (void*) volume_id << " Sensitive:" << yes_no(sensitive); - printout(DEBUG, "VolumeManager", log.str().c_str()); -#if 0 log.str(""); - log << s_count << ": " << e.name() << " Detector GeoNodes:"; - for(vector<const TGeoNode*>::const_iterator j=nodes.begin(); j!=nodes.end();++j) - log << (void*)(*j) << " "; - printout(DEBUG,"VolumeManager",log.str().c_str()); -#endif + log << m_entries.size() << ": " << parent.name() + << " ro:" << ro.name() << " pv:" << n->GetName() + << " Sensitive:" << yes_no(sensitive); + printout(m_debug ? INFO : DEBUG, "VolumeManager", log.str().c_str()); } }; } /* End namespace Geometry */ @@ -638,12 +450,13 @@ bool VolumeManager::adoptPlacement(VolumeID /* sys_id */, Context* context) { stringstream err; Object& o = _data(); VolumeID vid = context->identifier; + VolumeID mask = context->mask; PlacedVolume pv = context->placement; Volumes::iterator i = o.volumes.find(vid); - if ( (context->identifier&context->mask) != context->identifier ) { - err << "Bad context mask:" << (void*)context->mask - << " id:" << (void*)context->identifier + if ( (vid&mask) != vid ) { + err << "Bad context mask:" << (void*)mask + << " id:" << (void*)vid << " pv:" << pv.name() << " Sensitive:" << yes_no(pv.volume().isSensitive()) << endl; goto Fail; @@ -651,53 +464,35 @@ bool VolumeManager::adoptPlacement(VolumeID /* sys_id */, Context* context) { if (i == o.volumes.end()) { o.volumes[vid] = context; - o.detMask |= context->mask; + o.detMask |= mask; err << "Inserted new volume:" << setw(6) << left << o.volumes.size() - << " Ptr:" << (void*) pv.ptr() - << " [" << pv.name() << "]" - << " ID:" << (void*) context->identifier - << " Mask:" << (void*) context->mask; + << " Ptr:" << (void*) pv.ptr() + << " [" << pv.name() << "]" + << " id:" << setw(16) << hex << right << setfill('0') << vid << dec << setfill(' ') + << " mask:" << setw(16) << hex << right << setfill('0') << mask << dec << setfill(' ') + << " Det:" << context->element.path(); printout(VERBOSE, "VolumeManager", err.str().c_str()); + //printout(INFO, "VolumeManager", err.str().c_str()); return true; } err << "+++ Attempt to register duplicate" - << " volID " << (void*) context->identifier - << " Mask:" << (void*) context->mask + << " id:" << setw(16) << hex << right << setfill('0') << vid << dec << setfill(' ') + << " mask:" << setw(16) << hex << right << setfill('0') << mask << dec << setfill(' ') << " to detector " << o.detector.name() << " ptr:" << (void*) pv.ptr() << " Name:" << pv.name() << " Sensitive:" << yes_no(pv.volume().isSensitive()) << endl; printout(ERROR, "VolumeManager", "%s", err.str().c_str()); -#if 0 - err.str(""); - err << " !!!!! ++++ VolIDS "; - const VolIDs::Base& id_vector = context->volID; - for (VolIDs::Base::const_iterator vit = id_vector.begin(); vit != id_vector.end(); ++vit) - err << (*vit).first << "=" << (*vit).second << "; "; - printout(ERROR, "VolumeManager", "%s", err.str().c_str()); -#endif err.str(""); context = (*i).second; pv = context->placement; err << " !!!!! +++ Clashing" - << " volID " << (void*) context->identifier - << " Mask:" << (void*) context->mask + << " id:" << setw(16) << hex << right << setfill('0') << vid << dec << setfill(' ') + << " mask:" << setw(16) << hex << right << setfill('0') << mask << dec << setfill(' ') << " to detector " << o.detector.name() << " ptr:" << (void*) pv.ptr() << " Name:" << pv.name() << " Sensitive:" << yes_no(pv.volume().isSensitive()) << endl; -#if 0 - printout(ERROR, "VolumeManager", "%s", err.str().c_str()); - err.str(""); - - goto Fail; - Fail: { - err << " !!!!! ++++ VolIDS "; - const VolIDs::Base& ids = context->volID; - for (VolIDs::Base::const_iterator vit = ids.begin(); vit != ids.end(); ++vit) - err << (*vit).first << "=" << (*vit).second << "; "; - } -#endif Fail: printout(ERROR, "VolumeManager", "%s", err.str().c_str()); // throw runtime_error(err.str()); diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index ea66ff0461ae071dfbe3fab933cc089c478f6820..255e14da76ed8a502e3e45df2e50c5996361a651 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -360,6 +360,17 @@ PlacedVolumeExtension::VolIDs::insert(const string& name, int value) { return make_pair(i, true); } +/// String representation for debugging +string PlacedVolumeExtension::VolIDs::str() const { + stringstream str; + str << hex; + for(const auto& i : *this ) { + str << i.first << "=" << setw(4) << right + << setfill('0') << i.second << setfill(' ') << " "; + } + return str.str(); +} + static PlacedVolume::Object* _data(const PlacedVolume& v) { PlacedVolume::Object* o = _userExtension(v); if (o) diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 69c0020d730926c975f616eeeb19129ead87cb48..760afdacdb7f0301c1585d86d52c9b208ade1852 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -1000,7 +1000,16 @@ template <> void Converter<Compact>::operator()(xml_h element) const { ++num_calls; xml_elt_t compact(element); + bool steer_geometry = compact.hasChild(_U(geometry)); + bool open_geometry = true; + bool close_geometry = true; + if ( steer_geometry ) { + xml_elt_t steer = compact.child(_U(geometry)); + if ( steer.hasAttr(_U(open)) ) open_geometry = steer.attr<bool>(_U(open)); + if ( steer.hasAttr(_U(close)) ) close_geometry = steer.attr<bool>(_U(close)); + } + xml_coll_t(compact, _U(define)).for_each(_U(include), Converter<DetElementInclude>(lcdd)); xml_coll_t(compact, _U(define)).for_each(_U(constant), Converter<Constant>(lcdd)); xml_coll_t(compact, _U(includes)).for_each(_U(gdmlFile), Converter<GdmlFile>(lcdd)); @@ -1011,7 +1020,7 @@ template <> void Converter<Compact>::operator()(xml_h element) const { xml_coll_t(compact, _U(materials)).for_each(_U(element), Converter<Atom>(lcdd)); xml_coll_t(compact, _U(materials)).for_each(_U(material), Converter<Material>(lcdd)); xml_coll_t(compact, _U(properties)).for_each(_U(attributes), Converter<Property>(lcdd)); - lcdd.init(); + if ( open_geometry ) lcdd.init(); 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)); @@ -1032,7 +1041,7 @@ template <> void Converter<Compact>::operator()(xml_h element) const { xml_coll_t(compact, _U(sensitive_detectors)).for_each(_U(sd), Converter<SensitiveDetector>(lcdd)); ::snprintf(text, sizeof(text), "%u", xml_h(element).checksum(0)); lcdd.addConstant(Constant("compact_checksum", text)); - if ( --num_calls == 0 ) { + if ( --num_calls == 0 && close_geometry ) { lcdd.endDocument(); } xml_coll_t(compact, _U(plugins)).for_each(_U(plugin), Converter<Plugin> (lcdd)); diff --git a/DDCore/src/plugins/VolumeMgrTest.cpp b/DDCore/src/plugins/VolumeMgrTest.cpp index 50da8b29ceb2fad5cb8d008bb241f3f64029cab6..3b11aaa3f9629954d2bf5ec5c0ad8462d1c09cf9 100644 --- a/DDCore/src/plugins/VolumeMgrTest.cpp +++ b/DDCore/src/plugins/VolumeMgrTest.cpp @@ -17,6 +17,8 @@ #include "DD4hep/Factories.h" #include "DD4hep/IDDescriptor.h" #include "DD4hep/VolumeManager.h" +#include "DD4hep/DetectorTools.h" +#include "DD4hep/objects/VolumeManagerInterna.h" // C/C++ include files #include <stdexcept> @@ -36,7 +38,8 @@ namespace { * @version 1.0 */ struct VolIDTest { - typedef vector<PlacedVolume::VolID> VolIDs; + typedef DetectorTools::PlacementPath Chain; + typedef PlacedVolume::VolIDs VolIDs; /// Helper to scan volume ids struct FND { const string& test; @@ -52,11 +55,11 @@ namespace { /// Default destructor virtual ~VolIDTest() {} /// Check volume integrity - void checkVolume(DetElement e, PlacedVolume pv, const VolIDs& child_ids) const; + void checkVolume(DetElement e, PlacedVolume pv, const VolIDs& child_ids, const Chain& chain) const; /// Walk through tree of detector elements - void walk(DetElement de, VolIDs ids, size_t depth, size_t mx_depth) const; + //void walk(DetElement de, VolIDs ids, const Chain& chain, size_t depth, size_t mx_depth) const; /// Walk through tree of volume placements - void walkVolume(DetElement e, PlacedVolume pv, VolIDs ids, size_t depth, size_t mx_depth) const; + void walkVolume(DetElement e, PlacedVolume pv, VolIDs ids, const Chain& chain, size_t depth, size_t mx_depth) const; /// Action routine to execute the test static long run(LCDD& lcdd,int argc,char** argv); @@ -81,99 +84,177 @@ VolIDTest::VolIDTest(LCDD& lcdd, DetElement sdet, size_t depth) : m_det(sdet) { return; } m_iddesc = lcdd.sensitiveDetector(m_det.name()).readout().idSpec(); - walk(m_det,VolIDs(),0,depth); + //walk(m_det,VolIDs(),Chain(),0,depth); + PlacedVolume pv = sdet.placement(); + VolIDs ids = pv.volIDs(); + Chain chain; + chain.push_back(pv); + checkVolume(sdet, pv, ids, chain); + walkVolume(sdet, pv, ids, chain, 1, depth); } /// Check volume integrity -void VolIDTest::checkVolume(DetElement e, PlacedVolume pv, const VolIDs& child_ids) const { +void VolIDTest::checkVolume(DetElement detector, PlacedVolume pv, const VolIDs& child_ids, const Chain& chain) const { stringstream err, log; - bool is_sensitive = pv.volume().isSensitive(); - if ( is_sensitive ) { - VolumeID vid = m_iddesc.encode(child_ids); - try { - DetElement det = m_mgr.lookupDetector(vid); - DetElement det_elem = m_mgr.lookupDetElement(vid); + VolumeID det_vol_id = detector.volumeID(); + VolumeID vid = det_vol_id; + DetElement top_sdet, det_elem; + VolumeManager::Context* mgr_ctxt = 0; + + try { + vid = m_iddesc.encode(child_ids); + top_sdet = m_mgr.lookupDetector(vid); + det_elem = m_mgr.lookupDetElement(vid); + mgr_ctxt = m_mgr.lookupContext(vid); + + if ( pv.volume().isSensitive() ) { PlacedVolume det_place = m_mgr.lookupPlacement(vid); if ( pv.ptr() != det_place.ptr() ) { - err << "Wrong placement " + err << "VolumeMgrTest: Wrong placement " << " got " << det_place.name() << " (" << (void*)det_place.ptr() << ")" << " instead of " << pv.name() << " (" << (void*)pv.ptr() << ") " - << " vid:" << (void*)vid; + << " vid:" << volumeID(vid); } - else if ( det_elem.ptr() != e.ptr() ) { - err << "Wrong associated detector element vid=" << (void*)vid + else if ( top_sdet.ptr() != detector.ptr() ) { + err << "VolumeMgrTest: Wrong associated sub-detector element vid=" << volumeID(vid) + << " got " << top_sdet.path() << " (" << (void*)top_sdet.ptr() << ") " + << " instead of " << detector.path() << " (" << (void*)detector.ptr() << ")" + << " vid:" << volumeID(vid); + } + // This is sort of a bit wischi-waschi.... + else if ( !DetectorTools::isParentElement(detector,det_elem) ) { + err << "VolumeMgrTest: Wrong associated detector element vid=" << volumeID(vid) << " got " << det_elem.path() << " (" << (void*)det_elem.ptr() << ") " - << " instead of " << e.path() << " (" << (void*)e.ptr() << ")" - << " vid:" << (void*)vid; + << " instead of " << detector.path() << " (" << (void*)detector.ptr() << ")" + << " vid:" << volumeID(vid); } - else if ( det.ptr() != m_det.ptr() ) { - err << "Wrong associated detector " - << " vid:" << (void*)vid; + else if ( top_sdet.ptr() != m_det.ptr() ) { + err << "VolumeMgrTest: Wrong associated detector " + << " vid:" << volumeID(vid); } } - catch(const exception& ex) { - err << "Lookup " << pv.name() << " id:" << (void*)vid << " path:" << e.path() << " error:" << ex.what(); + } + catch(const exception& ex) { + err << "Lookup " << pv.name() << " id:" << volumeID(vid) + << " path:" << detector.path() << " error:" << ex.what(); + } + if ( pv.volume().isSensitive() || (0 != det_vol_id) ) { + string id_desc; + log << "Volume:" << setw(50) << left << pv.name(); + if ( pv.volume().isSensitive() ) { + IDDescriptor dsc = SensitiveDetector(pv.volume().sensitiveDetector()).readout().idSpec(); + log << " IDDesc:" << (char*)(dsc.ptr() == m_iddesc.ptr() ? "OK " : "BAD"); } - const IDDescriptor::FieldMap& m = m_iddesc.fields(); - log << "IDS(" << pv.name() << ") "; - log << " vid:" << setw(16) << hex << setfill('0') << vid << dec << setfill(' ') << " "; - for ( size_t fi=0; fi<m.size(); ++fi ) { - IDDescriptor::Field fld = m_iddesc.field(fi); - long val = fld->value(vid); - if ( find_if(child_ids.begin(),child_ids.end(),FND(fld->name())) == child_ids.end() ) continue; - log << fld->name() << (val>=0?": ":":") << val << " "; + else { + log << setw(11) << " "; } + id_desc = m_iddesc.str(vid); + log << " [" << char(pv.volume().isSensitive() ? 'S' : 'N') << "] " << right + << " vid:" << volumeID(vid) + << " " << id_desc; if ( !err.str().empty() ) { printout(ERROR,m_det.name(),err.str()+" "+log.str()); //throw runtime_error(err.str()); return; } - printout(INFO,m_det.name(),"OK "+log.str()); + id_desc = m_iddesc.str(det_elem.volumeID()); + printout(INFO,m_det.name(),log.str()); + printout(INFO,m_det.name()," Elt:%-64s vid:%s %s Parent-OK:%3s", + det_elem.path().c_str(),volumeID(det_elem.volumeID()).c_str(), + id_desc.c_str(), + yes_no(DetectorTools::isParentElement(detector,det_elem))); + + try { + if ( pv.volume().isSensitive() ) { + TGeoHMatrix trafo; + //for (size_t i = chain.size(); i > 1; --i) { + for (size_t i = 0; i<chain.size(); ++i ) { + const TGeoMatrix* mat = chain[i]->GetMatrix(); + trafo.MultiplyLeft(mat); + } + if ( pv.ptr() == det_elem.placement().ptr() ) { + for (size_t i = chain.size(); i > 0; --i) { + const TGeoMatrix* mat = chain[i-1]->GetMatrix(); + ::printf("Placement [%d] VolID:%s\t\t",int(i),chain[i-1].volIDs().str().c_str()); + mat->Print(); + } + ::printf("Computed Trafo (from placements):\t\t"); + trafo.Print(); + det_elem = m_mgr.lookupDetElement(vid); + ::printf("DetElement Trafo: %s [%s]\t\t", + det_elem.path().c_str(),volumeID(det_elem.volumeID()).c_str()); + det_elem.nominal().worldTransformation().Print(); + ::printf("VolumeMgr Trafo: %s \t\t",det_elem.path().c_str()); + m_mgr.worldTransformation(vid).Print(); + int ii=1; + DetElement par = det_elem; + while( (par.isValid()) ) { + const TGeoMatrix* mat = par.placement()->GetMatrix(); + ::printf("Element placement [%d] VolID:%s %s\t\t",int(ii), + par.placement().volIDs().str().c_str(), par.path().c_str()); + mat->Print(); + par = par.parent(); + ++ii; + } + } + else { + } + } + } + catch(const exception& ex) { + err << "Matrix " << pv.name() << " id:" << volumeID(vid) + << " path:" << detector.path() << " error:" << ex.what(); + } + } } /// Walk through tree of detector elements -void VolIDTest::walkVolume(DetElement e, PlacedVolume pv, VolIDs ids, size_t depth, size_t mx_depth) const { +void VolIDTest::walkVolume(DetElement detector, PlacedVolume pv, VolIDs ids, const Chain& chain, + size_t depth, size_t mx_depth) const +{ if ( depth <= mx_depth ) { - const TGeoNode* current = pv.ptr(); - TObjArray* nodes = current->GetNodes(); - int num_children = nodes ? nodes->GetEntriesFast() : 0; + const TGeoNode* current = pv.ptr(); + TObjArray* nodes = current->GetNodes(); + int num_children = nodes ? nodes->GetEntriesFast() : 0; + for(int i=0; i<num_children; ++i) { TGeoNode* node = (TGeoNode*)nodes->At(i); PlacedVolume place(node); VolIDs child_ids(ids); + Chain child_chain(chain); - child_ids.insert(child_ids.end(),place.volIDs().begin(),place.volIDs().end()); - bool is_sensitive = place.volume().isSensitive(); - if ( is_sensitive ) { - checkVolume(e,place,child_ids); - } - walkVolume(e,place,child_ids,depth+1,mx_depth); + place.access(); // Test validity + child_chain.push_back(place); + child_ids.insert(child_ids.end(), place.volIDs().begin(), place.volIDs().end()); + //bool is_sensitive = place.volume().isSensitive(); + //if ( is_sensitive || !child_ids.empty() ) { + checkVolume(detector, place, child_ids, child_chain); + //} + walkVolume(detector, place, child_ids, child_chain, depth+1, mx_depth); } } } - +#if 0 /// Walk through tree of volume placements -void VolIDTest::walk(DetElement e, VolIDs ids, size_t depth, size_t mx_depth) const { +void VolIDTest::walk(DetElement detector, VolIDs ids, const Chain& chain, size_t depth, size_t mx_depth) const { if ( depth <= mx_depth ) { DetElement::Children::const_iterator i; - const DetElement::Children& children = e.children(); - PlacedVolume pv = e.placement(); - VolIDs child_ids(ids); - bool is_sensitive = pv.volume().isSensitive(); - child_ids.insert(child_ids.end(),pv.volIDs().begin(),pv.volIDs().end()); - for (i=children.begin(); i!=children.end(); ++i) { - walk((*i).second,child_ids,depth+1,mx_depth); - } - if ( !is_sensitive && children.empty() ) { - walkVolume(e,pv,child_ids,depth+1,mx_depth); - } - else if ( is_sensitive ) { - checkVolume(e, pv,child_ids); - } + PlacedVolume pv = detector.placement(); + VolIDs child_ids(ids); + Chain child_chain(chain); + VolumeID det_vol_id = detector.volumeID(); + //bool is_sensitive = pv.volume().isSensitive() || (0 != det_vol_id); + + child_chain.push_back(pv); + child_ids.insert(child_ids.end(), pv.volIDs().begin(), pv.volIDs().end()); + //if ( is_sensitive ) { + checkVolume(detector, pv, child_ids, child_chain); + //} + walkVolume(detector, pv, child_ids, child_chain, depth+1, mx_depth); } } - +#endif /// Action routine to execute the test long VolIDTest::run(LCDD& lcdd,int argc,char** argv) { printout(ALWAYS,"DD4hepVolumeMgrTest","++ Processing plugin..."); diff --git a/DDDetectors/src/SiTrackerBarrel_geo.cpp b/DDDetectors/src/SiTrackerBarrel_geo.cpp index b951ceaee0931baedc70ee6736cb21c0053123cd..78f1349c7fcba6a219fcd1dc1da814e2b4357246 100644 --- a/DDDetectors/src/SiTrackerBarrel_geo.cpp +++ b/DDDetectors/src/SiTrackerBarrel_geo.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/doc/release.notes b/doc/release.notes index bc7bd73844a9dc40feebc8b70810021b69f5b458..97c8c7d2e2c716823b3655626a80b7be1ffdee13 100644 --- a/doc/release.notes +++ b/doc/release.notes @@ -4,8 +4,15 @@ DD4hep ---- Release Notes ================================= + Markus Frank 2017-03-09 + -- Fix issue with long volume ids exceeding 32 bits. + Test added in examples/ClientTests + -- Fix volume manager id identical placed volumes are used in different places of the hierarchy. + Test added in examples/ClientTests + -- Remove various svn left-overs (ID$ strings etc.) -Frank Gaede 2017-02-10 + + Frank Gaede 2017-02-10 - allow event readers to create more than one vertex per event this should be possible as most generator formats allow to specify more than one event vertex diff --git a/examples/ClientTests/CMakeLists.txt b/examples/ClientTests/CMakeLists.txt index 5059df48760d7eed80ab4fbf276459a4e3b669b0..11ef904ea0131b3ddf5b54aa1410308443824f4b 100644 --- a/examples/ClientTests/CMakeLists.txt +++ b/examples/ClientTests/CMakeLists.txt @@ -1,4 +1,3 @@ -# $Id: $ #========================================================================== # AIDA Detector description implementation for LCD #-------------------------------------------------------------------------- @@ -34,6 +33,25 @@ dd4hep_add_test_reg( ClientTests_DumpElements EXEC_ARGS geoPluginRun -plugin DD4hepElementTable -type xml REGEX_PASS "formula=\"UUB\" name=\"UUB\"" ) # +# Test long volume IDs Detector setups with placements of +# identical volumes at different levels of the hierarchy +dd4hep_add_test_reg( ClientTests_MultiPlace + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" + EXEC_ARGS geoPluginRun + -input file:${CMAKE_CURRENT_SOURCE_DIR}/compact/SiBarrelMultiSensitiveLongVolID.xml -volmgr -destroy + -plugin DD4hepVolumeMgrTest SiTrackerBarrel + + REGEX_PASS "Volume:component1_1 IDDesc:OK \\[S\\] vid:00200668000000ff system:00ff barrel:0000 layer:0001 module:0033 sensor:0001") +# +# Test long volume IDs exceeding 32 bit addressing of the form: <id>system:32,barrel:16:-5....</id> +dd4hep_add_test_reg( ClientTests_Bitfield64_LongVoldID + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" + EXEC_ARGS geoPluginRun + -input file:${CMAKE_CURRENT_SOURCE_DIR}/compact/SiBarrelMultiSensitiveLongVolID.xml -volmgr -destroy + -plugin DD4hepVolumeMgrTest SiTrackerBarrel + + REGEX_PASS "Volume:component1_1 IDDesc:OK \\[S\\] vid:00200668000000ff system:00ff barrel:0000 layer:0001 module:0033 sensor:0001") +# # Test readout strings of the form: <id>system:8,barrel:-2</id> dd4hep_add_test_reg( ClientTests_Bitfield64_BarrelSides COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" @@ -42,7 +60,7 @@ dd4hep_add_test_reg( ClientTests_Bitfield64_BarrelSides -plugin DD4hepDetectorVolumeDump -plugin DD4hepVolumeDump volids -plugin DD4hepVolumeMgrTest all - REGEX_PASS "OK IDS\\(Shell_1\\) vid\\:0000000000000302 system\\: 2 barrel\\:-1" ) + REGEX_PASS "Volume:Shell_2 IDDesc:OK \\[S\\] vid:0000000000000102 system:0002 barrel:0001") # # Test readout strings of the form: <id>system:16,barrel:16:-5</id> dd4hep_add_test_reg( ClientTests_Bitfield64_BarrelSides2 @@ -52,7 +70,7 @@ dd4hep_add_test_reg( ClientTests_Bitfield64_BarrelSides2 -plugin DD4hepDetectorVolumeDump -plugin DD4hepVolumeDump volids -plugin DD4hepVolumeMgrTest all - REGEX_PASS "OK IDS\\(Shell_1\\) vid\\:00000000001f0002 system\\: 2 barrel\\:-1" ) + REGEX_PASS "Volume:Shell_2 IDDesc:OK \\[S\\] vid:0000000000010002 system:0002 barrel:0001") # # foreach (test Assemblies BoxTrafos IronCylinder LheD_tracker MagnetFields MaterialTester diff --git a/examples/ClientTests/compact/SiBarrelMultiSensitiveDetector.xml b/examples/ClientTests/compact/SiBarrelMultiSensitiveDetector.xml new file mode 100644 index 0000000000000000000000000000000000000000..03e38ae3d4595c61590275c850f75ea541347c2a --- /dev/null +++ b/examples/ClientTests/compact/SiBarrelMultiSensitiveDetector.xml @@ -0,0 +1,83 @@ +<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd"> + + <info name="Nested_Detectors_test" + title="Test for nested detector descriptions" + author="Markus Frank" + url="None" + status="development" + version="$Id: compact.xml 1374 2014-11-05 10:49:55Z markus.frank@cern.ch $"> + <comment>Test for nested detector descriptions</comment> + </info> + + <includes> + <gdmlFile ref="${DDDetectors_dir}/elements.xml"/> + <gdmlFile ref="${DDDetectors_dir}/materials.xml"/> + </includes> + + <define> + <constant name="DDDetectors_dir" value="${DD4hepINSTALL}/DDDetectors/compact" type="string"/>; + <constant name="SiD_dir" value="${DDDetectors_dir}/SiD" type="string"/>; + <constant name="world_side" value="30000*mm"/> + <constant name="world_x" value="world_side"/> + <constant name="world_y" value="world_side"/> + <constant name="world_z" value="world_side"/> + + <constant name="SiTrackerBarrel_ID" value="5"/> + + <constant name="tracker_region_rmax" value="world_side"/> + <constant name="tracker_region_zmax" value="world_side"/> + + </define> + + <limits><limitset name="SiTrackerBarrelRegionLimitSet"/></limits> + <regions><region name="SiTrackerBarrelRegion" eunit="MeV" lunit="mm" cut="0.001" threshold="0.001"/></regions> + + <comment>Common Generic visualization attributes</comment> + <display> + <vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/> + <vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/> + <vis name="BlueVis" alpha="1" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/> + <vis name="BlueVisTrans" alpha="0.1" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/> + <vis name="SiTrackerLayerVis" alpha="1.0" r="1.0" g="1.0" b="0.6" showDaughters="true" visible="true"/> + <vis name="SiTrackerModuleVis" alpha="0.1" r="0.0" g="1.0" b="0.6" showDaughters="false" visible="true"/> + + </display> + + <comment>Tracking detectors</comment> + <readouts> + <readout name="SiTrackerBarrelHits"> + <id>system:8,barrel:3,layer:2,module:16,sensor:2,side:32:-2,strip:20</id> + </readout> + </readouts> + +<detectors> + <detector id="SiTrackerBarrel_ID" name="SiTrackerBarrel" type="DD4hep_SiBarrelMultiSensitiveDetector" readout="SiTrackerBarrelHits" region="SiTrackerBarrelRegion" limits="SiTrackerBarrelRegionLimitSet"> + + <comment>Silicon Outer Tracker Barrel</comment> + + <module name="SiTrackerModule_Layer1" vis="SiTrackerModuleVis"> + <module_envelope width="97.79*mm" length="97.79*mm" thickness="0.3*cm"/> + <module_component width="97.79*mm" length="97.79*mm" thickness="0.016*cm" material="CarbonFiber_50D" sensitive="false"> + <position z="0.0915*cm" /> + </module_component> + <module_component width="92.031*mm" length="92.031*mm" thickness="0.03*cm" material="Silicon" sensitive="true"> + <position z="0.1145*cm"/> + </module_component> + <module_component width="97.79*mm" length="97.79*mm" thickness="0.00048*cm" material="Silicon" sensitive="false"> + <position z="0.12974*cm"/> + </module_component> + <module_component width="97.79*mm" length="97.79*mm" thickness="0.00038*cm" material="Copper" sensitive="false"> + <position z="0.146*cm"/> + </module_component> + </module> + + <layer module="SiTrackerModule_Layer1" id="1" vis="SiTrackerLayerVis"> + <barrel_envelope inner_r="215.075*mm" outer_r="245.0*mm" z_length="578 * 2*mm"/> + <rphi_layout phi_tilt="0.17506*rad" nphi="4" phi0="0." rc="(216.355 + 5.0)*mm" dr="0.0"/> + <z_layout dr="4.0*mm" z0="512.128*mm" nz="13"/> + </layer> + </detector> +</detectors> +</lccdd> diff --git a/examples/ClientTests/compact/SiBarrelMultiSensitiveLongVolID.xml b/examples/ClientTests/compact/SiBarrelMultiSensitiveLongVolID.xml new file mode 100644 index 0000000000000000000000000000000000000000..d4f9af458109d0ec41a377cfda33f1108268b03c --- /dev/null +++ b/examples/ClientTests/compact/SiBarrelMultiSensitiveLongVolID.xml @@ -0,0 +1,83 @@ +<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd"> + + <info name="Nested_Detectors_test" + title="Test for nested detector descriptions" + author="Markus Frank" + url="None" + status="development" + version="$Id: compact.xml 1374 2014-11-05 10:49:55Z markus.frank@cern.ch $"> + <comment>Test for nested detector descriptions</comment> + </info> + + <includes> + <gdmlFile ref="${DDDetectors_dir}/elements.xml"/> + <gdmlFile ref="${DDDetectors_dir}/materials.xml"/> + </includes> + + <define> + <constant name="DDDetectors_dir" value="${DD4hepINSTALL}/DDDetectors/compact" type="string"/>; + <constant name="SiD_dir" value="${DDDetectors_dir}/SiD" type="string"/>; + <constant name="world_side" value="30000*mm"/> + <constant name="world_x" value="world_side"/> + <constant name="world_y" value="world_side"/> + <constant name="world_z" value="world_side"/> + + <constant name="SiTrackerBarrel_ID" value="255"/> + + <constant name="tracker_region_rmax" value="world_side"/> + <constant name="tracker_region_zmax" value="world_side"/> + + </define> + + <limits><limitset name="SiTrackerBarrelRegionLimitSet"/></limits> + <regions><region name="SiTrackerBarrelRegion" eunit="MeV" lunit="mm" cut="0.001" threshold="0.001"/></regions> + + <comment>Common Generic visualization attributes</comment> + <display> + <vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/> + <vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/> + <vis name="BlueVis" alpha="1" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/> + <vis name="BlueVisTrans" alpha="0.1" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/> + <vis name="SiTrackerLayerVis" alpha="1.0" r="1.0" g="1.0" b="0.6" showDaughters="true" visible="true"/> + <vis name="SiTrackerModuleVis" alpha="0.1" r="0.0" g="1.0" b="0.6" showDaughters="false" visible="true"/> + + </display> + + <comment>Tracking detectors</comment> + <readouts> + <readout name="SiTrackerBarrelHits"> + <id>system:32,barrel:3,layer:2,module:16,sensor:2</id> + </readout> + </readouts> + +<detectors> + <detector id="SiTrackerBarrel_ID" name="SiTrackerBarrel" type="DD4hep_SiBarrelMultiSensitiveDetector" readout="SiTrackerBarrelHits" region="SiTrackerBarrelRegion" limits="SiTrackerBarrelRegionLimitSet"> + + <comment>Silicon Outer Tracker Barrel</comment> + + <module name="SiTrackerModule_Layer1" vis="SiTrackerModuleVis"> + <module_envelope width="97.79*mm" length="97.79*mm" thickness="0.3*cm"/> + <module_component width="97.79*mm" length="97.79*mm" thickness="0.016*cm" material="CarbonFiber_50D" sensitive="false"> + <position z="0.0915*cm" /> + </module_component> + <module_component width="92.031*mm" length="92.031*mm" thickness="0.03*cm" material="Silicon" sensitive="true"> + <position z="0.1145*cm"/> + </module_component> + <module_component width="97.79*mm" length="97.79*mm" thickness="0.00048*cm" material="Silicon" sensitive="false"> + <position z="0.12974*cm"/> + </module_component> + <module_component width="97.79*mm" length="97.79*mm" thickness="0.00038*cm" material="Copper" sensitive="false"> + <position z="0.146*cm"/> + </module_component> + </module> + + <layer module="SiTrackerModule_Layer1" id="1" vis="SiTrackerLayerVis"> + <barrel_envelope inner_r="215.075*mm" outer_r="245.0*mm" z_length="578 * 2*mm"/> + <rphi_layout phi_tilt="0.17506*rad" nphi="4" phi0="0." rc="(216.355 + 5.0)*mm" dr="0.0"/> + <z_layout dr="4.0*mm" z0="512.128*mm" nz="13"/> + </layer> + </detector> +</detectors> +</lccdd> diff --git a/examples/ClientTests/src/SiBarrelMultiSensitiveDetector_geo.cpp b/examples/ClientTests/src/SiBarrelMultiSensitiveDetector_geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..916e179b83a14ad25644332289af6bb49a525ef8 --- /dev/null +++ b/examples/ClientTests/src/SiBarrelMultiSensitiveDetector_geo.cpp @@ -0,0 +1,182 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// Specialized generic detector constructor +// +//========================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/MatrixHelpers.h" +#include "DD4hep/Printout.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { + typedef vector<PlacedVolume> Placements; + xml_det_t x_det = e; + Material air = lcdd.air(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + DetElement sdet (det_name,det_id); + Assembly assembly (det_name); + map<string, Volume> volumes; + map<string, Placements> sensitives; + PlacedVolume pv; + + sens.setType("tracker"); + for(xml_coll_t mi(x_det,_U(module)); mi; ++mi) { + xml_comp_t x_mod = mi; + xml_comp_t m_env = x_mod.child(_U(module_envelope)); + string m_nam = x_mod.nameStr(); + Volume m_vol(m_nam,Box(m_env.width()/2,m_env.length()/2,m_env.thickness()/2),air); + int ncomponents = 0, sensor_number = 1; + + if ( volumes.find(m_nam) != volumes.end() ) { + printout(ERROR,"SiTrackerBarrel","Logics error in building modules."); + throw runtime_error("Logics error in building modules."); + } + volumes[m_nam] = m_vol; + m_vol.setVisAttributes(lcdd.visAttributes(x_mod.visStr())); + printout(INFO,"Detector","++ Building module: %s",m_nam.c_str()); + for(xml_coll_t ci(x_mod,_U(module_component)); ci; ++ci, ++ncomponents) { + xml_comp_t x_comp = ci; + xml_comp_t x_pos = x_comp.position(false); + xml_comp_t x_rot = x_comp.rotation(false); + string c_nam = _toString(ncomponents,"component%d"); + Box c_box(x_comp.width()/2,x_comp.length()/2,x_comp.thickness()/2); + Volume c_vol(c_nam,c_box,lcdd.material(x_comp.materialStr())); + + if ( x_pos && x_rot ) { + Position c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0)); + RotationZYX c_rot(x_rot.z(0),x_rot.y(0),x_rot.x(0)); + pv = m_vol.placeVolume(c_vol, Transform3D(c_rot,c_pos)); + } + else if ( x_rot ) { + pv = m_vol.placeVolume(c_vol,RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0))); + } + else if ( x_pos ) { + pv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0))); + } + else { + pv = m_vol.placeVolume(c_vol); + } + c_vol.setRegion(lcdd, x_comp.regionStr()); + c_vol.setLimitSet(lcdd, x_comp.limitsStr()); + c_vol.setVisAttributes(lcdd, x_comp.visStr()); + if ( x_comp.isSensitive() ) { + pv.addPhysVolID(_U(sensor),sensor_number++); + c_vol.setSensitiveDetector(sens); + sensitives[m_nam].push_back(pv); + } + } + } + for(xml_coll_t li(x_det,_U(layer)); li; ++li) { + xml_comp_t x_layer = li; + xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope)); + xml_comp_t x_layout = x_layer.child(_U(rphi_layout)); + xml_comp_t z_layout = x_layer.child(_U(z_layout)); // Get the <z_layout> element. + int lay_id = x_layer.id(); + string m_nam = x_layer.moduleStr(); + string lay_nam = _toString(x_layer.id(),"layer%d"); + Tube lay_tub (x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()/2); + Volume lay_vol (lay_nam,lay_tub,air); // Create the layer envelope volume. + double phi0 = x_layout.phi0(); // Starting phi of first module. + double phi_tilt = x_layout.phi_tilt(); // Phi tilt of a module. + double rc = x_layout.rc(); // Radius of the module center. + int nphi = x_layout.nphi(); // Number of modules in phi. + double rphi_dr = x_layout.dr(); // The delta radius of every other module. + double phi_incr = (M_PI * 2) / nphi; // Phi increment for one module. + double phic = phi0; // Phi of the module center. + double z0 = z_layout.z0(); // Z position of first module in phi. + double nz = z_layout.nz(); // Number of modules to place in z. + double z_dr = z_layout.dr(); // Radial displacement parameter, of every other module. + Volume m_env = volumes[m_nam]; + DetElement lay_elt(sdet,_toString(x_layer.id(),"layer%d"),lay_id); + Placements& sensVols = sensitives[m_nam]; + + // Z increment for module placement along Z axis. + // Adjust for z0 at center of module rather than + // the end of cylindrical envelope. + double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0; + // Starting z for module placement along Z axis. + double module_z = -z0; + int module = 1; + + printout(INFO,"Detector","++ Placing module: %s",m_nam.c_str()); + // Loop over the number of modules in phi. + for (int ii = 0; ii < nphi; ii++) { + double dx = z_dr * std::cos(phic + phi_tilt); // Delta x of module position. + double dy = z_dr * std::sin(phic + phi_tilt); // Delta y of module position. + double x = rc * std::cos(phic); // Basic x module position. + double y = rc * std::sin(phic); // Basic y module position. + + // Loop over the number of modules in z. + for (int j = 0; j < nz; j++) { + // Module PhysicalVolume. + // Transform3D tr(RotationZYX(0,-((M_PI/2)-phic-phi_tilt),M_PI/2),Position(x,y,module_z)); + //NOTE (Nikiforos, 26/08 Rotations needed to be fixed so that component1 (silicon) is on the outside + Transform3D tr(RotationZYX(0,((M_PI/2)-phic-phi_tilt),-M_PI/2),Position(x,y,module_z)); + pv = lay_vol.placeVolume(m_env,tr); + pv.addPhysVolID("module", module); + + if ( 0 == (module%2) ) { + // Not terribly physical: we only make a child-element for every second module. + // Need this for testing the volume manager! + string module_name = _toString(module,"module%d"); + DetElement mod_elt(lay_elt,module_name,module); + mod_elt.setPlacement(pv); +#if 0 + ::printf("+++ Module: %s %s [%p]", + module_name.c_str(),pv->GetMatrix()->GetName(),(void*)pv->GetMatrix()); + pv->GetMatrix()->Print(); +#endif + for(size_t ic=0; ic<sensVols.size(); ++ic) { + PlacedVolume sens_pv = sensVols[ic]; + DetElement comp_elt(mod_elt,sens_pv.volume().name(),module); + comp_elt.setPlacement(sens_pv); + } + } + + /// Increase counters etc. + module++; + // Adjust the x and y coordinates of the module. + x += dx; + y += dy; + // Flip sign of x and y adjustments. + dx *= -1; + dy *= -1; + // Add z increment to get next z placement pos. + module_z += z_incr; + } + phic += phi_incr; // Increment the phi placement of module. + rc += rphi_dr; // Increment the center radius according to dr parameter. + rphi_dr *= -1; // Flip sign of dr parameter. + module_z = -z0; // Reset the Z placement parameter for module. + } + // Create the PhysicalVolume for the layer. + pv = assembly.placeVolume(lay_vol); // Place layer in mother + pv.addPhysVolID("layer", lay_id); // Set the layer ID. + lay_elt.setAttributes(lcdd,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + lay_elt.setPlacement(pv); + } + sdet.setAttributes(lcdd,assembly,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + assembly.setVisAttributes(lcdd.invisible()); + pv = lcdd.pickMotherVolume(sdet).placeVolume(assembly); + pv.addPhysVolID("system", det_id); // Set the subdetector system ID. + pv.addPhysVolID("barrel", 0); // Flag this as a barrel subdetector. + sdet.setPlacement(pv); + return sdet; +} + +DECLARE_DETELEMENT(DD4hep_SiBarrelMultiSensitiveDetector,create_detector)