diff --git a/CMakeLists.txt b/CMakeLists.txt index 02710d7dc9cef5cf2e93f39e9913f2a0cdac3cc3..21195b3c27d599e7bc4a9bda6497a4aa89d5e8f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ if(DD4HEP_WITH_GEANT4) endif() #---Examples------------------------------------------------------------------------ +add_subdirectory(DDExamples/AlignDet) add_subdirectory(DDExamples/ILDExDet) add_subdirectory(DDExamples/CLICSiD) add_subdirectory(DDExamples/ILDExDisplay) diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h index 1ef2eb9eee6aae315d20a18b59ddbb48630334b3..40cad19f94231c48b23a04735362c8dfcbabc901 100644 --- a/DDCore/include/DD4hep/LCDD.h +++ b/DDCore/include/DD4hep/LCDD.h @@ -64,18 +64,20 @@ namespace DD4hep { virtual const HandleMap& readouts() const = 0; virtual const HandleMap& visAttributes() const = 0; virtual const HandleMap& limitsets() const = 0; + virtual const HandleMap& alignments() const = 0; - virtual Region region(const std::string& name) const = 0; - virtual VisAttr visAttributes(const std::string& name) const = 0; - virtual LimitSet limitSet(const std::string& name) const = 0; - virtual Material material(const std::string& name) const = 0; - virtual Readout readout(const std::string& name) const = 0; - virtual Ref_t idSpec(const std::string& name) const = 0; - virtual Volume pickMotherVolume(const DetElement& sd) const = 0; - virtual Constant constant(const std::string& name) const = 0; - virtual Solid solid(const std::string& name) const = 0; - virtual Volume volume(const std::string& name) const = 0; - virtual DetElement detector(const std::string& name) const = 0; + virtual Region region(const std::string& name) const = 0; + virtual VisAttr visAttributes(const std::string& name) const = 0; + virtual LimitSet limitSet(const std::string& name) const = 0; + virtual Material material(const std::string& name) const = 0; + virtual Readout readout(const std::string& name) const = 0; + virtual Ref_t idSpec(const std::string& name) const = 0; + virtual Volume pickMotherVolume(const DetElement& sd) const = 0; + virtual Constant constant(const std::string& name) const = 0; + virtual Solid solid(const std::string& name) const = 0; + virtual Volume volume(const std::string& name) const = 0; + virtual AlignmentEntry alignment(const std::string& path) const = 0; + virtual DetElement detector(const std::string& name) const = 0; virtual LCDD& add(const Constant& constant) = 0; //virtual LCDD& add(const Solid& solid) = 0; @@ -85,6 +87,7 @@ namespace DD4hep { virtual LCDD& add(const VisAttr& attr) = 0; virtual LCDD& add(const LimitSet& limset) = 0; virtual LCDD& add(const DetElement& detector) = 0; + virtual LCDD& add(const AlignmentEntry& x) = 0; virtual LCDD& addIDSpec(const Ref_t& element) = 0; virtual LCDD& addConstant(const Ref_t& element) = 0; @@ -96,13 +99,21 @@ namespace DD4hep { virtual LCDD& addReadout(const Ref_t& readout) = 0; virtual LCDD& addDetector(const Ref_t& detector) = 0; virtual LCDD& addSolid(const Ref_t& detector) = 0; + /// Add identifyable volume virtual LCDD& addVolume(const Ref_t& detector) = 0; + /// Add alignment entry + virtual LCDD& addAlignment(const Ref_t& alignment) = 0; - //---Factory method------- - static LCDD& getInstance(void); + /// Read compact geometry description or alignment file virtual void fromCompact(const std::string& fname) = 0; + /// Apply & lock realigments + virtual void applyAlignment() = 0; + + /// Dump geometry description virtual void dump() const = 0; + ///---Factory method------- + static LCDD& getInstance(void); }; } /* End namespace Geometry */ } /* End namespace DD4hep */ diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h index 71cb1b1888811060c8f0fc84fe63b324b60b649c..615dba424c1ab1a640539c5dda003d0e39b10f86 100644 --- a/DDCore/include/DD4hep/Objects.h +++ b/DDCore/include/DD4hep/Objects.h @@ -18,6 +18,8 @@ class TGeoMaterial; class TGeoMatrix; class TGeoRotation; class TGeoTranslation; +class TGeoPhysicalNode; +#include "TGeoPhysicalNode.h" // C/C++ include files #define _USE_MATH_DEFINES @@ -103,6 +105,8 @@ namespace DD4hep { Position() : x(0), y(0), z(0) {} /// Initializing constructor Position(double xval, double yval, double zval) : x(xval), y(yval), z(zval) {} + /// Is it a identity rotation ? + bool isNull() const { return x==0 && x==0 && x==0; } }; /** @class IdentityPos Objects.h @@ -126,6 +130,8 @@ namespace DD4hep { Rotation() : theta(0), phi(0), psi(0) {} /// Initializing constructor Rotation(double thetaval, double phival, double psival) : theta(thetaval), phi(phival), psi(psival) {} + /// Is it a identity rotation ? + bool isNull() const { return theta==0 && phi==0 && psi==0; } }; /** @class IdentityRot Objects.h @@ -224,7 +230,7 @@ namespace DD4hep { /// Constructor to be used when reading the already parsed DOM tree template <typename Q> VisAttr(const Handle<Q>& e) : Ref_t(e) {} - /// Constructor to be used when creating a new DOM tree + /// Constructor to be used when creating a new registered visualization object VisAttr(LCDD& doc, const std::string& name); /// Additional data accessor Object& _data() const { return *data<Object>(); } @@ -244,6 +250,29 @@ namespace DD4hep { std::string toString() const; }; + /**@class AligmentEntry + * + * Class representing an alignment entry + * + * @author M.Frank + * @version 1.0 + */ + struct AlignmentEntry : public Handle<TGeoPhysicalNode> { + typedef Handle<TGeoPhysicalNode> Base; + /// Constructor to be used when reading the already parsed DOM tree + template <typename Q> + AlignmentEntry(const Handle<Q>& h) : Base(h) {} + /// Constructor to be used when creating a new aligment entry + AlignmentEntry(LCDD& doc, const std::string& path); + /// Align the PhysicalNode (translation only) + int align(const Position& pos, bool check=false, double overlap=0.001); + /// Align the PhysicalNode (rotation only) + int align(const Rotation& rot, bool check=false, double overlap=0.001); + /// Align the PhysicalNode (translation + rotation) + int align(const Position& pos, const Rotation& rot, bool check=false, double overlap=0.001); + }; + + /** @class Limit Objects.h * * @author M.Frank @@ -252,7 +281,7 @@ namespace DD4hep { struct Limit : public Ref_t { typedef std::pair<std::string,double> Object; - /// Constructor to be used when creating a new DOM tree + /// Constructor to be used when creating a new limit object Limit(LCDD& doc, const std::string& name); /// Additional data accessor Object& _data() const { return *data<Object>(); } diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index fea424652d012bc84534248b2b88a13c31c1b047..ef8729cef4bb13c375d1463478ca269b402dbb16 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -84,6 +84,8 @@ namespace DD4hep { /** @class Volume Volume.h DD4hep/lcdd/Volume.h * + * Handle describing a Volume + * * @author M.Frank * @version 1.0 */ @@ -169,6 +171,27 @@ namespace DD4hep { operator TGeoVolume*() const { return m_element; } }; + /** @class Assembly Volume.h DD4hep/lcdd/Volume.h + * + * Handle describing a volume assembly + * + * @author M.Frank + * @version 1.0 + */ + struct Assembly : public Volume { + /// Default constructor + Assembly() : Volume() {} + + /// Copy from handle + Assembly(const Assembly& v) : Volume(v) {} + + /// Copy from arbitrary Element + template <typename T> Assembly(const Handle<T>& v) : Volume(v) {} + + /// Constructor to be used when creating a new geometry tree. + Assembly(LCDD& lcdd, const std::string& name); + }; + } /* End namespace Geometry */ } /* End namespace DD4hep */ #endif /* DD4hep_GEOMETRY_VOLUMES_H */ diff --git a/DDCore/include/XML/XMLDetector.h b/DDCore/include/XML/XMLDetector.h index 5695ba02f7de50201bf2f0c604d4a5f8ffb32966..cf3f8ecaf2197e49e4820447ba969a58ae93858c 100644 --- a/DDCore/include/XML/XMLDetector.h +++ b/DDCore/include/XML/XMLDetector.h @@ -27,10 +27,16 @@ namespace DD4hep { Dimension() : Element(Handle_t(0)) {} Dimension(Handle_t e) : Element(e) {} Dimension(const Element& e) : Element(e) {} - // Box: + // Rotation: + double theta() const; + double phi() const; + double psi() const; + + // Box/Position: double x() const; double y() const; double z() const; + // Functions return defaults rather than throwing exceptions double x(double default_val) const; double y(double default_val) const; diff --git a/DDCore/include/XML/XMLLCDD.h b/DDCore/include/XML/XMLLCDD.h deleted file mode 100644 index eab502aa351b097bf2deba37d898433ed1931712..0000000000000000000000000000000000000000 --- a/DDCore/include/XML/XMLLCDD.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef DD4hep_XMLLCDD_H -#define DD4hep_XMLLCDD_H -#include "XML/XMLElements.h" - -/* - * DD4hep namespace declaration - */ -namespace DD4hep { - - /* - * XML namespace declaration - */ - namespace XML { - - struct Subdetector; - struct Readout; - struct Document; - struct Solid; - struct Constant; - struct Volume; - struct Region; - struct Material; - struct Materials; - struct Position; - struct Rotation; - struct LimitSet; - struct VisAttr; - struct Compact; - struct LCDD; - - template <class T> struct XMLConverter { - LCDD& lcdd; - XMLConverter(LCDD& l) : lcdd(l) {} - void operator()(const Handle_t& c) const; - }; - - struct LCDD { - - virtual ~LCDD() {} - - virtual Document document() const = 0; - virtual Document create() = 0; - virtual void endDocument() = 0; - virtual void addStdMaterials() = 0; - - virtual Handle_t header() const = 0; - virtual Handle_t structure() const = 0; - virtual Handle_t solids() const = 0; - virtual Handle_t materials() const = 0; - virtual RefElement worldVolume() const = 0; - virtual RefElement trackingVolume() const = 0; - - virtual RefElement region(const XMLCh* name) const = 0; - virtual RefElement visAttributes(const XMLCh* name) const = 0; - virtual RefElement limitSet(const XMLCh* name) const = 0; - virtual RefElement material(const XMLCh* name) const = 0; - virtual RefElement readout(const XMLCh* name) const = 0; - virtual RefElement idSpec(const XMLCh* name) const = 0; - virtual RefElement pickMotherVolume(const Subdetector& sd) const = 0; - virtual RefElement constant(const XMLCh* name) const = 0; - virtual RefElement position(const XMLCh* name) const = 0; - virtual RefElement rotation(const XMLCh* name) const = 0; - virtual RefElement solid(const XMLCh* name) const = 0; - virtual RefElement define(const XMLCh* tag, const XMLCh* name) const = 0; - - virtual LCDD& add(const Constant& constant) = 0; - virtual LCDD& add(const Solid& solid) = 0; - virtual LCDD& add(const Region& region) = 0; - virtual LCDD& add(const Volume& vol) = 0; - virtual LCDD& add(const Material& mat) = 0; - virtual LCDD& add(const VisAttr& attr) = 0; - virtual LCDD& add(const Position& pos) = 0; - virtual LCDD& add(const Rotation& rot) = 0; - virtual LCDD& add(const LimitSet& limset) = 0; - - virtual LCDD& addIDSpec(const RefElement& element) = 0; - virtual LCDD& addConstant(const RefElement& element) = 0; - virtual LCDD& addMaterial(const RefElement& element) = 0; - virtual LCDD& addVisAttribute(const RefElement& element) = 0; - virtual LCDD& addSensitiveDetector(const RefElement& e) = 0; - virtual LCDD& addLimitSet(const RefElement& limset) = 0; - virtual LCDD& addRegion(const RefElement& region) = 0; - virtual LCDD& addReadout(const RefElement& readout) = 0; - }; - } -} /* End namespace DD4hep */ -#endif /* DD4hep_XMLLCDD_H */ diff --git a/DDCore/include/XML/XMLTags.h b/DDCore/include/XML/XMLTags.h index d0f5e56d8925f83ec15bcc58a3e147832ea3079c..bd27d26fbebddd415cbb013e32209f8e48280274 100644 --- a/DDCore/include/XML/XMLTags.h +++ b/DDCore/include/XML/XMLTags.h @@ -26,6 +26,10 @@ namespace DD4hep { namespace XML { extern const Tag_t Tag_mm; extern const Tag_t Tag_cm; + + extern const Tag_t Attr_overlap; + extern const Tag_t Attr_check; + // RefElement parameters extern const Tag_t Tag_ref; @@ -70,6 +74,7 @@ namespace DD4hep { namespace XML { extern const Tag_t Attr_name; extern const Tag_t Attr_nphi; extern const Tag_t Attr_ntheta; + extern const Tag_t Attr_outer_r; extern const Tag_t Attr_outer_z; extern const Tag_t Attr_outgoing_r; @@ -251,7 +256,15 @@ namespace DD4hep { namespace XML { extern const Tag_t Attr_label; extern const Tag_t Attr_start; extern const Tag_t Attr_length; + // -- Alignment + extern const Tag_t Tag_alignments; + extern const Tag_t Tag_alignment; + //================================ Objects: ================================ + // -- Rotation + extern const Tag_t Attr_theta; + extern const Tag_t Attr_phi; + extern const Tag_t Attr_psi; //================================ Volumes: ================================ // -- Volume extern const Tag_t Tag_volume; @@ -318,8 +331,6 @@ namespace DD4hep { namespace XML { extern const Tag_t Tag_trap; extern const Tag_t Attr_aunit; extern const Tag_t Attr_lunit; - extern const Tag_t Attr_theta; - extern const Tag_t Attr_phi; extern const Tag_t Attr_x1; extern const Tag_t Attr_x2; extern const Tag_t Attr_x3; diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index 29a83722e10d8a75879a2627634f28641016e8a6..4634570c8aa5945b5970df8531ee3ca28403fdda 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -189,3 +189,5 @@ INSTANTIATE(TGeoSphere); INSTANTIATE(TGeoTorus); INSTANTIATE(TGeoShape); INSTANTIATE(TGeoCompositeShape); +#include "TGeoPhysicalNode.h" +INSTANTIATE(TGeoPhysicalNode); diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index a3cc354417e8a96cdfb87d4a3a0867030395f4d8..5ad33a7e0aeb6727c547e422ec03b78b3b1ca56a 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -152,6 +152,9 @@ void LCDDImp::fromCompact(const std::string& xmlfile) { #endif } +void LCDDImp::applyAlignment() { +} + void LCDDImp::dump() const { TGeoManager* mgr = gGeoManager; mgr->CloseGeometry(); diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h index d2f5a853a747a7f83f5fef748cfadb4d1546767e..d75392df330f0a2ec11d6dcc43f76d5bb6a18c2f 100644 --- a/DDCore/src/LCDDImp.h +++ b/DDCore/src/LCDDImp.h @@ -70,6 +70,8 @@ namespace DD4hep { ObjectHandleMap m_limits; ObjectHandleMap m_regions; ObjectHandleMap m_detectors; + ObjectHandleMap m_alignments; + ObjectHandleMap m_sensitive; ObjectHandleMap m_display; ObjectHandleMap m_fields; @@ -94,8 +96,11 @@ namespace DD4hep { //void convertMaterials(XML::Handle_t doc_element); LCDDImp(); - //void fromCompact(XML::Handle_t doc_element); + + /// Read compact geometry description or alignment file virtual void fromCompact(const std::string& fname); + /// Apply & lock realigments + virtual void applyAlignment(); virtual void create(); virtual void init(); @@ -131,6 +136,8 @@ namespace DD4hep { { return getRefChild(m_readouts,name); } virtual DetElement detector(const std::string& name) const { return getRefChild(m_detectors,name); } + virtual AlignmentEntry alignment(const std::string& path) const + { return getRefChild(alignments(),path); } virtual const HandleMap& header() const { return m_header; } virtual const HandleMap& constants() const { return m_define; } @@ -142,6 +149,7 @@ namespace DD4hep { virtual const HandleMap& materials() const { return m_materials; } virtual const HandleMap& readouts() const { return m_readouts; } virtual const HandleMap& detectors() const { return m_detectors; } + virtual const HandleMap& alignments() const { return m_alignments; } virtual LCDD& add(const Constant& x) { return addConstant(x); } virtual LCDD& add(const Solid& x) { return addSolid(x); } @@ -150,6 +158,7 @@ namespace DD4hep { virtual LCDD& add(const LimitSet& x) { return addLimitSet(x); } virtual LCDD& add(const Region& x) { return addRegion(x); } virtual LCDD& add(const VisAttr& x) { return addVisAttribute(x); } + virtual LCDD& add(const AlignmentEntry& x) { return addAlignment(x); } virtual LCDD& add(const Readout& x) { return addReadout(x); } virtual LCDD& add(const DetElement& x) { return addDetector(x); } @@ -168,6 +177,8 @@ namespace DD4hep { virtual LCDD& addVisAttribute(const Ref_t& x) { m_display.append(x); __R;} virtual LCDD& addSensitiveDetector(const Ref_t& x){ m_sensitive.append(x); __R;} virtual LCDD& addDetector(const Ref_t& x) { m_detectors.append_noCheck(x); __R;} + + virtual LCDD& addAlignment(const Ref_t& x) { m_alignments.append(x); __R;} #undef __R }; diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp index f2c6585685dfb18ba42cd65c53d2a5d8e7acce0f..59b6a22f1d2f75fa521ba7363752041c979fa1a3 100644 --- a/DDCore/src/Objects.cpp +++ b/DDCore/src/Objects.cpp @@ -157,7 +157,49 @@ string VisAttr::toString() const { return text; } -/// Constructor to be used when creating a new DOM tree +/// Constructor to be used when creating a new aligment entry +AlignmentEntry::AlignmentEntry(LCDD& /* lcdd */, const string& path) { + TGeoPhysicalNode* obj = new TGeoPhysicalNode(path.c_str()); + assign(obj,path,"*"); +} + +/// Align the PhysicalNode (translation only) +int AlignmentEntry::align(const Position& pos, bool check, double overlap) { + return align(pos,Rotation(),check,overlap); +} + +/// Align the PhysicalNode (rotation only) +int AlignmentEntry::align(const Rotation& rot, bool check, double overlap) { + return align(Position(),rot,check,overlap); +} + +/// Align the PhysicalNode (translation + rotation) +int AlignmentEntry::align(const Position& pos, const Rotation& rot, bool check, double overlap) { + if ( isValid() ) { + if ( pos.isNull() && rot.isNull() ) + return 0; + TGeoHMatrix* new_matrix = dynamic_cast<TGeoHMatrix*>(m_element->GetOriginalMatrix()->MakeClone()); + if ( rot.isNull() ) { + TGeoTranslation m(pos.x,pos.y,pos.z); + new_matrix->Multiply(&m); + } + else if ( pos.isNull() ) { + TGeoRotation m("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + new_matrix->Multiply(&m); + } + else { + TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + TGeoCombiTrans m(pos.x,pos.y,pos.z,0); + m.SetRotation(rotation); + new_matrix->Multiply(&m); + } + m_element->Align(new_matrix,0,check,overlap); + return 1; + } + throw std::runtime_error("Callot align non existing physical node."); +} + +/// Constructor to be used when creating a limit object Limit::Limit(LCDD& /* lcdd */, const string& name) { Value<TNamed,Object>* obj = new Value<TNamed,Object>(); assign(obj,name,"*"); diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 500834a38a21fac8e55c7d9a5d3b506c97702f11..de6da0f03363a85086b1b69d9a2a699f7e570e11 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -36,45 +36,58 @@ namespace DD4hep { namespace Geometry { } }; - template <> struct Value<TGeoVolume,Volume::Object> - : public TGeoVolume, public Volume::Object - { - Value(const char* name, TGeoShape* s=0, TGeoMedium* m=0) : TGeoVolume(name,s,m) { - magic = magic_word(); - } - virtual ~Value() {} + template <class T> struct _VolWrap : public T { + _VolWrap(const char* name, TGeoShape* s=0, TGeoMedium* m=0); + virtual ~_VolWrap() {} virtual void AddNode(const TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t* = "") { TGeoMatrix *matrix = mat; if (matrix==0) matrix = gGeoIdentity; else matrix->RegisterYourself(); if (!vol) { - Error("AddNode", "Volume is NULL"); + this->T::Error("AddNode", "Volume is NULL"); return; } if (!vol->IsValid()) { - Error("AddNode", "Won't add node with invalid shape"); + this->T::Error("AddNode", "Won't add node with invalid shape"); printf("### invalid volume was : %s\n", vol->GetName()); return; } - if (!fNodes) fNodes = new TObjArray(); + if (!this->T::fNodes) this->T::fNodes = new TObjArray(); - if (fFinder) { + if (this->T::fFinder) { // volume already divided. - Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, GetName()); + this->T::Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, this->T::GetName()); return; } TGeoNodeMatrix *node = new Value<TGeoNodeMatrix,PlacedVolume::Object>(vol, matrix); //node = new TGeoNodeMatrix(vol, matrix); node->SetMotherVolume(this); - fNodes->Add(node); + this->T::fNodes->Add(node); TString name = TString::Format("%s_%d", vol->GetName(), copy_no); - if (fNodes->FindObject(name)) - Warning("AddNode", "Volume %s : added node %s with same name", GetName(), name.Data()); + if (this->T::fNodes->FindObject(name)) + this->T::Warning("AddNode", "Volume %s : added node %s with same name", this->T::GetName(), name.Data()); node->SetName(name); node->SetNumber(copy_no); } }; + + template <> _VolWrap<TGeoVolume>::_VolWrap(const char* name, TGeoShape* s, TGeoMedium* m) + : TGeoVolume(name,s,m) {} + template <> _VolWrap<TGeoVolumeAssembly>::_VolWrap(const char* name, TGeoShape* s, TGeoMedium* m) + : TGeoVolumeAssembly(name) {} + + template <> struct Value<TGeoVolume,Volume::Object> + : public _VolWrap<TGeoVolume>, public Volume::Object { + Value(const char* name, TGeoShape* s=0, TGeoMedium* m=0) : _VolWrap<TGeoVolume>(name,s,m) {magic = magic_word();} + virtual ~Value() {} + }; + + template <> struct Value<TGeoVolumeAssembly,Assembly::Object> + : public _VolWrap<TGeoVolumeAssembly>, public Assembly::Object { + Value(const char* name) : _VolWrap<TGeoVolumeAssembly>(name,0,0) { magic = magic_word(); } + virtual ~Value() {} + }; }} @@ -106,7 +119,7 @@ void Volume::setSolid(const Solid& solid) const { } static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* transform) { - Value<TGeoVolume,Volume::Object>* parent = (Value<TGeoVolume,Volume::Object>*)par; + TGeoVolume* parent = par; TObjArray* a = parent->GetNodes(); Int_t id = a ? a->GetEntries() : 0; parent->AddNode(daughter,id,transform); @@ -214,14 +227,22 @@ void Volume::setAttributes(const LCDD& lcdd, setVisAttributes(lcdd,vis); } +/// Assign the sensitive detector structure void Volume::setSensitiveDetector(const SensitiveDetector& obj) const { data<Object>()->sens_det = obj; } +/// Access to Solid (Shape) Solid Volume::solid() const { return Solid((*this)->GetShape()); } +/// Constructor to be used when creating a new geometry tree. +Assembly::Assembly(LCDD& lcdd, const std::string& name) { + m_element = new Value<TGeoVolumeAssembly,Volume::Object>(name.c_str()); + lcdd.addVolume(*this); +} + Material Volume::material() const { return Handle<TGeoMaterial>(m_element->GetMaterial()); } diff --git a/DDCore/src/XML/XMLDetector.cpp b/DDCore/src/XML/XMLDetector.cpp index 8313f173b78ff63bf85e044c7634d5794ea9dbf8..e27c99bf31f219152c80e26b409213d67f35c36a 100644 --- a/DDCore/src/XML/XMLDetector.cpp +++ b/DDCore/src/XML/XMLDetector.cpp @@ -171,6 +171,10 @@ string Dimension::padStr() const { return m_element.attr<string>(Attr_pads); } +double Dimension::phi() const { + return m_element.attr<double>(Attr_phi); +} + double Dimension::phi0() const { return m_element.attr<double>(Attr_phi0); } @@ -188,6 +192,14 @@ int Dimension::nphi() const { return m_element.attr<int>(Attr_nphi); } +double Dimension::theta() const { + return m_element.attr<double>(Attr_theta); +} + +double Dimension::psi() const { + return m_element.attr<double>(Attr_psi); +} + double Dimension::rc() const { return m_element.attr<double>(Attr_rc); } diff --git a/DDCore/src/XML/XMLTags.cpp b/DDCore/src/XML/XMLTags.cpp index f72a3c21dfa3975c3f2d8c64e869ea6c8162b5dc..fcb14b542d2f1227038a6eb7916719274439d236 100644 --- a/DDCore/src/XML/XMLTags.cpp +++ b/DDCore/src/XML/XMLTags.cpp @@ -91,6 +91,11 @@ namespace DD4hep { namespace XML { TAG(volumeref); TAG(zplane); + TAG(alignments); + TAG(alignment); + + ATTR(overlap); + ATTR(check); ATTR(InvisibleNoDaughters); ATTR(InvisibleWithDaughters); @@ -239,6 +244,7 @@ namespace DD4hep { namespace XML { ATTR(thetaBins); TAG(trap); + ATTR(psi); ATTR(phi); ATTR(theta); ATTR(aunit); diff --git a/DDCore/src/compact/Compact2Objects.cpp b/DDCore/src/compact/Compact2Objects.cpp index 4c19c638c74a9bb2b5d21a3f18f91909f9d435ce..3df518b4e4600cded6cebf441daac09f2ddfe9fc 100644 --- a/DDCore/src/compact/Compact2Objects.cpp +++ b/DDCore/src/compact/Compact2Objects.cpp @@ -31,9 +31,9 @@ namespace { namespace DD4hep { namespace Geometry { struct Compact; - struct Materials; struct Includes; struct GdmlFile; + struct AlignmentFile; typedef DD4hep::IDDescriptor IDDescriptor; template <typename T> Handle<> toObject(LCDD& lcdd, const XML::Handle_t& xml); @@ -267,6 +267,39 @@ namespace DD4hep { namespace Geometry { } return ro; } + + template <> Ref_t toRefObject<AlignmentEntry>(lcdd_t& lcdd, const xml_h& e) { + /* <alignment name="<path/to/object>" shortcut="short_cut_name"> + <position x="x-value" y="y-value" z="z-value"/> + <rotation theta="theta-value" phi="phi-value" psi="psi-value"/> + </alignment> + */ + xml_comp_t child(e); + string path = e.attr<string>(_A(name)); + bool check = e.hasAttr(_A(check)); + bool overlap = e.hasAttr(_A(overlap)); + AlignmentEntry alignment(lcdd,path); + Position pos; + Rotation rot; + if ( (child=e.child(_X(position),false)) ) { // Position is not mandatory! + pos.x = child.x(); + pos.y = child.y(); + pos.z = child.z(); + } + if ( (child=e.child(_X(rotation),false)) ) { // Rotation is not mandatory + rot.theta = child.x(); // child.theta(); + rot.phi = child.y(); // child.phi(); + rot.psi = child.z(); // child.psi(); + } + if ( overlap ) { + double ovl = e.attr<double>(_A(overlap)); + alignment.align(pos,rot,check,ovl); + } + else { + alignment.align(pos,rot,check); + } + return alignment; + } namespace { template <typename T> static Ref_t toRefObject(LCDD& lcdd, const xml_h& xml, SensitiveDetector& sens) @@ -314,6 +347,9 @@ namespace DD4hep { namespace Geometry { template <> void Converter<VisAttr>::operator()(const xml_h& element) const { lcdd.addVisAttribute(toRefObject<to_type>(lcdd,element)); } + template <> void Converter<AlignmentEntry>::operator()(const xml_h& element) const { + lcdd.addAlignment(toRefObject<to_type>(lcdd,element)); + } template <> void Converter<Region>::operator()(const xml_h& element) const { lcdd.addRegion(toRefObject<to_type>(lcdd,element)); } @@ -356,32 +392,39 @@ namespace DD4hep { namespace Geometry { } } - template <> void Converter<Materials>::operator()(const xml_h& materials) const { - xml_coll_t(materials,_X(element) ).for_each(Converter<Atom>(lcdd)); - xml_coll_t(materials,_X(material)).for_each(Converter<Material>(lcdd)); - } - + /// Read material entries from a seperate file in one of the include sections of the geometry template <> void Converter<GdmlFile>::operator()(const xml_h& element) const { xercesc::XMLURL base(element.ptr()->getBaseURI()); xercesc::XMLURL ref(base, element.attr_value(_A(ref))); xml_h materials = XML::DocumentHandler().load(_toString(ref.getURLText())).root(); - Converter<Materials>(this->lcdd)(materials); + xml_coll_t(materials,_X(element) ).for_each(Converter<Atom>(this->lcdd)); + xml_coll_t(materials,_X(material)).for_each(Converter<Material>(this->lcdd)); + } + + /// Read alignment entries from a seperate file in one of the include sections of the geometry + template <> void Converter<AlignmentFile>::operator()(const xml_h& element) const { + xercesc::XMLURL base(element.ptr()->getBaseURI()); + xercesc::XMLURL ref(base, element.attr_value(_A(ref))); + xml_h alignments = XML::DocumentHandler().load(_toString(ref.getURLText())).root(); + xml_coll_t(alignments,_X(alignment)).for_each(Converter<AlignmentEntry>(this->lcdd)); } template <> void Converter<Compact>::operator()(const xml_h& element) const { XML::Element compact(element); lcdd.create(); - xml_coll_t(compact,_X(includes) ).for_each(_X(gdmlFile),Converter<GdmlFile>(lcdd)); + xml_coll_t(compact,_X(includes) ).for_each(_X(gdmlFile), Converter<GdmlFile>(lcdd)); //Header(lcdd.header()).fromCompact(doc,compact.child(Tag_info),Strng_t("In memory")); - xml_coll_t(compact,_X(define) ).for_each(_X(constant),Converter<Constant>(lcdd)); - xml_coll_t(compact,_X(materials)).for_each(_X(element), Converter<Atom>(lcdd)); - xml_coll_t(compact,_X(materials)).for_each(_X(material),Converter<Material>(lcdd)); + xml_coll_t(compact,_X(define) ).for_each(_X(constant), Converter<Constant>(lcdd)); + xml_coll_t(compact,_X(materials) ).for_each(_X(element), Converter<Atom>(lcdd)); + xml_coll_t(compact,_X(materials) ).for_each(_X(material), Converter<Material>(lcdd)); lcdd.init(); - xml_coll_t(compact,_X(limits) ).for_each(_X(limitset),Converter<LimitSet>(lcdd)); - xml_coll_t(compact,_X(display) ).for_each(_X(vis), Converter<VisAttr>(lcdd)); - xml_coll_t(compact,_X(readouts) ).for_each(_X(readout), Converter<Readout>(lcdd)); - xml_coll_t(compact,_X(detectors)).for_each(_X(detector),Converter<DetElement>(lcdd)); + xml_coll_t(compact,_X(limits) ).for_each(_X(limitset), Converter<LimitSet>(lcdd)); + xml_coll_t(compact,_X(display) ).for_each(_X(vis), Converter<VisAttr>(lcdd)); + xml_coll_t(compact,_X(readouts) ).for_each(_X(readout), Converter<Readout>(lcdd)); + xml_coll_t(compact,_X(detectors) ).for_each(_X(detector), Converter<DetElement>(lcdd)); + xml_coll_t(compact,_X(includes) ).for_each(_X(alignment),Converter<AlignmentFile>(lcdd)); + xml_coll_t(compact,_X(alignments)).for_each(_X(alignment),Converter<AlignmentEntry>(lcdd)); lcdd.endDocument(); } }} @@ -394,6 +437,6 @@ template Converter<VisAttr>; template Converter<Constant>; template Converter<LimitSet>; template Converter<Material>; -template Converter<Materials>; template Converter<DetElement>; +template Converter<AlignmentEntry>; #endif diff --git a/DDExamples/AlignDet/CMakeLists.txt b/DDExamples/AlignDet/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..91fc6a7eb10a13652b67aacefd3b0db36ea92de7 --- /dev/null +++ b/DDExamples/AlignDet/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) + + +include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/DDCore/include + ${ROOT_INCLUDE_DIR} + ${XERCESC_INCLUDE_DIR}) + +if(DD4HEP_USE_XERCESC) + file(GLOB sources src/*.cpp) +endif() + +add_executable(Aligntest test/main.cpp ${sources}) +target_link_libraries(Aligntest DD4hepCore ${ROOT_LIBRARIES} Rint Reflex) + diff --git a/DDExamples/AlignDet/compact/compact.xml b/DDExamples/AlignDet/compact/compact.xml new file mode 100644 index 0000000000000000000000000000000000000000..96751ac786be317fb1d9d5a37547f60ad4e4538b --- /dev/null +++ b/DDExamples/AlignDet/compact/compact.xml @@ -0,0 +1,72 @@ +<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="clic_sid_cdr" + title="CLIC Silicon Detector CDR" + author="Christian Grefe" + url="https://twiki.cern.ch/twiki/bin/view/CLIC/ClicSidCdr" + status="development" + version="$Id: compact.xml,v 1.3 2010/12/02 16:34:00 grefe Exp $"> + <comment>The compact format for the CLIC Silicon Detector used for the conceptual design report</comment> + </info> + + <includes> + <gdmlFile ref="elements.xml"/> + <gdmlFile ref="materials.xml"/> + </includes> + + <define> + <constant name="world_side" value="30000"/> + <constant name="world_x" value="world_side"/> + <constant name="world_y" value="world_side"/> + <constant name="world_z" value="world_side"/> + + <constant name="tracking_region_radius" value="10000"/> + <constant name="tracking_region_zmax" value="10000"/> + </define> + + <limits> + <limitset name="cal_limits"> + <limit name="step_length_max" particles="*" value="5.0" unit="mm" /> + </limitset> + </limits> + + <display> + <vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/> + <vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/> + <vis name="B1_vis" alpha="1.0" r="1" g="0" b="0" showDaughters="true" visible="true"/> + <vis name="B2_vis" alpha="1.0" r="0" g="1" b="0" showDaughters="true" visible="true"/> + </display> + + <detectors> + <comment>Boxes</comment> + <detector id="1" name="B1" type="BoxSegment" vis="B1_vis"> + <comment>Horizontal box</comment> + <material name="Steel235"/> + <box x="20" y="0.1" z="5"/> + <position x="20" y="10" z="10"/> + <rotation x="1" y="0" z="0"/> + </detector> + <detector id="2" name="B2" type="BoxSegment" vis="B2_vis"> + <comment>Vertical box</comment> + <material name="Steel235"/> + <box x="0.1" y="20" z="5"/> + <position x="0" y="30" z="10"/> + <rotation x="0" y="0" z="0"/> + </detector> + </detectors> + + + <alignments> + <alignment name="/world_volume_1/B1_envelope_volume_0" shortcut="Box1"> +<!-- + <position x="0" y="0" z="0"/> + <position x="20" y="10" z="10"/> +--> + <position x="-20" y="-10" z="-5"/> + <rotation x="0" y="0" z="0"/> + </alignment> + </alignments> + +</lccdd> diff --git a/DDExamples/AlignDet/compact/elements.xml b/DDExamples/AlignDet/compact/elements.xml new file mode 100644 index 0000000000000000000000000000000000000000..e714c3a5cd544e748dd2941967cff515c0b77efc --- /dev/null +++ b/DDExamples/AlignDet/compact/elements.xml @@ -0,0 +1,884 @@ +<materials> + <element Z="89" formula="Ac" name="Ac" > + <atom type="A" unit="g/mol" value="227.028" /> + </element> + <material formula="Ac" name="Actinium" state="solid" > + <RL type="X0" unit="cm" value="0.601558" /> + <NIL type="lambda" unit="cm" value="21.2048" /> + <D type="density" unit="g/cm3" value="10.07" /> + <composite n="1" ref="Ac" /> + </material> + <element Z="47" formula="Ag" name="Ag" > + <atom type="A" unit="g/mol" value="107.868" /> + </element> + <material formula="Ag" name="Silver" state="solid" > + <RL type="X0" unit="cm" value="0.854292" /> + <NIL type="lambda" unit="cm" value="15.8546" /> + <D type="density" unit="g/cm3" value="10.5" /> + <composite n="1" ref="Ag" /> + </material> + <element Z="13" formula="Al" name="Al" > + <atom type="A" unit="g/mol" value="26.9815" /> + </element> + <material formula="Al" name="Aluminum" state="solid" > + <RL type="X0" unit="cm" value="8.89632" /> + <NIL type="lambda" unit="cm" value="38.8766" /> + <D type="density" unit="g/cm3" value="2.699" /> + <composite n="1" ref="Al" /> + </material> + <element Z="95" formula="Am" name="Am" > + <atom type="A" unit="g/mol" value="243.061" /> + </element> + <material formula="Am" name="Americium" state="solid" > + <RL type="X0" unit="cm" value="0.42431" /> + <NIL type="lambda" unit="cm" value="15.9812" /> + <D type="density" unit="g/cm3" value="13.67" /> + <composite n="1" ref="Am" /> + </material> + <element Z="18" formula="Ar" name="Ar" > + <atom type="A" unit="g/mol" value="39.9477" /> + </element> + <material formula="Ar" name="Argon" state="gas" > + <RL type="X0" unit="cm" value="11762.1" /> + <NIL type="lambda" unit="cm" value="71926" /> + <D type="density" unit="g/cm3" value="0.00166201" /> + <composite n="1" ref="Ar" /> + </material> + <element Z="33" formula="As" name="As" > + <atom type="A" unit="g/mol" value="74.9216" /> + </element> + <material formula="As" name="Arsenic" state="solid" > + <RL type="X0" unit="cm" value="2.0838" /> + <NIL type="lambda" unit="cm" value="25.7324" /> + <D type="density" unit="g/cm3" value="5.73" /> + <composite n="1" ref="As" /> + </material> + <element Z="85" formula="At" name="At" > + <atom type="A" unit="g/mol" value="209.987" /> + </element> + <material formula="At" name="Astatine" state="solid" > + <RL type="X0" unit="cm" value="0.650799" /> + <NIL type="lambda" unit="cm" value="22.3202" /> + <D type="density" unit="g/cm3" value="9.32" /> + <composite n="1" ref="At" /> + </material> + <element Z="79" formula="Au" name="Au" > + <atom type="A" unit="g/mol" value="196.967" /> + </element> + <material formula="Au" name="Gold" state="solid" > + <RL type="X0" unit="cm" value="0.334436" /> + <NIL type="lambda" unit="cm" value="10.5393" /> + <D type="density" unit="g/cm3" value="19.32" /> + <composite n="1" ref="Au" /> + </material> + <element Z="5" formula="B" name="B" > + <atom type="A" unit="g/mol" value="10.811" /> + </element> + <material formula="B" name="Boron" state="solid" > + <RL type="X0" unit="cm" value="22.2307" /> + <NIL type="lambda" unit="cm" value="32.2793" /> + <D type="density" unit="g/cm3" value="2.37" /> + <composite n="1" ref="B" /> + </material> + <element Z="56" formula="Ba" name="Ba" > + <atom type="A" unit="g/mol" value="137.327" /> + </element> + <material formula="Ba" name="Barium" state="solid" > + <RL type="X0" unit="cm" value="2.37332" /> + <NIL type="lambda" unit="cm" value="51.6743" /> + <D type="density" unit="g/cm3" value="3.5" /> + <composite n="1" ref="Ba" /> + </material> + <element Z="4" formula="Be" name="Be" > + <atom type="A" unit="g/mol" value="9.01218" /> + </element> + <material formula="Be" name="Beryllium" state="solid" > + <RL type="X0" unit="cm" value="35.276" /> + <NIL type="lambda" unit="cm" value="39.4488" /> + <D type="density" unit="g/cm3" value="1.848" /> + <composite n="1" ref="Be" /> + </material> + <element Z="83" formula="Bi" name="Bi" > + <atom type="A" unit="g/mol" value="208.98" /> + </element> + <material formula="Bi" name="Bismuth" state="solid" > + <RL type="X0" unit="cm" value="0.645388" /> + <NIL type="lambda" unit="cm" value="21.3078" /> + <D type="density" unit="g/cm3" value="9.747" /> + <composite n="1" ref="Bi" /> + </material> + <element Z="97" formula="Bk" name="Bk" > + <atom type="A" unit="g/mol" value="247.07" /> + </element> + <material formula="Bk" name="Berkelium" state="solid" > + <RL type="X0" unit="cm" value="0.406479" /> + <NIL type="lambda" unit="cm" value="15.6902" /> + <D type="density" unit="g/cm3" value="14" /> + <composite n="1" ref="Bk" /> + </material> + <element Z="35" formula="Br" name="Br" > + <atom type="A" unit="g/mol" value="79.9035" /> + </element> + <material formula="Br" name="Bromine" state="gas" > + <RL type="X0" unit="cm" value="1615.12" /> + <NIL type="lambda" unit="cm" value="21299" /> + <D type="density" unit="g/cm3" value="0.0070721" /> + <composite n="1" ref="Br" /> + </material> + <element Z="6" formula="C" name="C" > + <atom type="A" unit="g/mol" value="12.0107" /> + </element> + <material formula="C" name="Carbon" state="solid" > + <RL type="X0" unit="cm" value="21.3485" /> + <NIL type="lambda" unit="cm" value="40.1008" /> + <D type="density" unit="g/cm3" value="2" /> + <composite n="1" ref="C" /> + </material> + <element Z="20" formula="Ca" name="Ca" > + <atom type="A" unit="g/mol" value="40.078" /> + </element> + <material formula="Ca" name="Calcium" state="solid" > + <RL type="X0" unit="cm" value="10.4151" /> + <NIL type="lambda" unit="cm" value="77.3754" /> + <D type="density" unit="g/cm3" value="1.55" /> + <composite n="1" ref="Ca" /> + </material> + <element Z="48" formula="Cd" name="Cd" > + <atom type="A" unit="g/mol" value="112.411" /> + </element> + <material formula="Cd" name="Cadmium" state="solid" > + <RL type="X0" unit="cm" value="1.03994" /> + <NIL type="lambda" unit="cm" value="19.46" /> + <D type="density" unit="g/cm3" value="8.65" /> + <composite n="1" ref="Cd" /> + </material> + <element Z="58" formula="Ce" name="Ce" > + <atom type="A" unit="g/mol" value="140.115" /> + </element> + <material formula="Ce" name="Cerium" state="solid" > + <RL type="X0" unit="cm" value="1.19506" /> + <NIL type="lambda" unit="cm" value="27.3227" /> + <D type="density" unit="g/cm3" value="6.657" /> + <composite n="1" ref="Ce" /> + </material> + <element Z="98" formula="Cf" name="Cf" > + <atom type="A" unit="g/mol" value="251.08" /> + </element> + <material formula="Cf" name="Californium" state="solid" > + <RL type="X0" unit="cm" value="0.568328" /> + <NIL type="lambda" unit="cm" value="22.085" /> + <D type="density" unit="g/cm3" value="10" /> + <composite n="1" ref="Cf" /> + </material> + <element Z="17" formula="Cl" name="Cl" > + <atom type="A" unit="g/mol" value="35.4526" /> + </element> + <material formula="Cl" name="Chlorine" state="gas" > + <RL type="X0" unit="cm" value="6437.34" /> + <NIL type="lambda" unit="cm" value="38723.9" /> + <D type="density" unit="g/cm3" value="0.00299473" /> + <composite n="1" ref="Cl" /> + </material> + <element Z="96" formula="Cm" name="Cm" > + <atom type="A" unit="g/mol" value="247.07" /> + </element> + <material formula="Cm" name="Curium" state="solid" > + <RL type="X0" unit="cm" value="0.428706" /> + <NIL type="lambda" unit="cm" value="16.2593" /> + <D type="density" unit="g/cm3" value="13.51" /> + <composite n="1" ref="Cm" /> + </material> + <element Z="27" formula="Co" name="Co" > + <atom type="A" unit="g/mol" value="58.9332" /> + </element> + <material formula="Co" name="Cobalt" state="solid" > + <RL type="X0" unit="cm" value="1.53005" /> + <NIL type="lambda" unit="cm" value="15.2922" /> + <D type="density" unit="g/cm3" value="8.9" /> + <composite n="1" ref="Co" /> + </material> + <element Z="24" formula="Cr" name="Cr" > + <atom type="A" unit="g/mol" value="51.9961" /> + </element> + <material formula="Cr" name="Chromium" state="solid" > + <RL type="X0" unit="cm" value="2.0814" /> + <NIL type="lambda" unit="cm" value="18.1933" /> + <D type="density" unit="g/cm3" value="7.18" /> + <composite n="1" ref="Cr" /> + </material> + <element Z="55" formula="Cs" name="Cs" > + <atom type="A" unit="g/mol" value="132.905" /> + </element> + <material formula="Cs" name="Cesium" state="solid" > + <RL type="X0" unit="cm" value="4.4342" /> + <NIL type="lambda" unit="cm" value="95.317" /> + <D type="density" unit="g/cm3" value="1.873" /> + <composite n="1" ref="Cs" /> + </material> + <element Z="29" formula="Cu" name="Cu" > + <atom type="A" unit="g/mol" value="63.5456" /> + </element> + <material formula="Cu" name="Copper" state="solid" > + <RL type="X0" unit="cm" value="1.43558" /> + <NIL type="lambda" unit="cm" value="15.5141" /> + <D type="density" unit="g/cm3" value="8.96" /> + <composite n="1" ref="Cu" /> + </material> + <element Z="66" formula="Dy" name="Dy" > + <atom type="A" unit="g/mol" value="162.497" /> + </element> + <material formula="Dy" name="Dysprosium" state="solid" > + <RL type="X0" unit="cm" value="0.85614" /> + <NIL type="lambda" unit="cm" value="22.2923" /> + <D type="density" unit="g/cm3" value="8.55" /> + <composite n="1" ref="Dy" /> + </material> + <element Z="68" formula="Er" name="Er" > + <atom type="A" unit="g/mol" value="167.256" /> + </element> + <material formula="Er" name="Erbium" state="solid" > + <RL type="X0" unit="cm" value="0.788094" /> + <NIL type="lambda" unit="cm" value="21.2923" /> + <D type="density" unit="g/cm3" value="9.066" /> + <composite n="1" ref="Er" /> + </material> + <element Z="63" formula="Eu" name="Eu" > + <atom type="A" unit="g/mol" value="151.964" /> + </element> + <material formula="Eu" name="Europium" state="solid" > + <RL type="X0" unit="cm" value="1.41868" /> + <NIL type="lambda" unit="cm" value="35.6178" /> + <D type="density" unit="g/cm3" value="5.243" /> + <composite n="1" ref="Eu" /> + </material> + <element Z="9" formula="F" name="F" > + <atom type="A" unit="g/mol" value="18.9984" /> + </element> + <material formula="F" name="Fluorine" state="gas" > + <RL type="X0" unit="cm" value="20838.2" /> + <NIL type="lambda" unit="cm" value="59094.3" /> + <D type="density" unit="g/cm3" value="0.00158029" /> + <composite n="1" ref="F" /> + </material> + <element Z="26" formula="Fe" name="Fe" > + <atom type="A" unit="g/mol" value="55.8451" /> + </element> + <material formula="Fe" name="Iron" state="solid" > + <RL type="X0" unit="cm" value="1.75749" /> + <NIL type="lambda" unit="cm" value="16.959" /> + <D type="density" unit="g/cm3" value="7.874" /> + <composite n="1" ref="Fe" /> + </material> + <element Z="87" formula="Fr" name="Fr" > + <atom type="A" unit="g/mol" value="223.02" /> + </element> + <material formula="Fr" name="Francium" state="solid" > + <RL type="X0" unit="cm" value="6.18826" /> + <NIL type="lambda" unit="cm" value="212.263" /> + <D type="density" unit="g/cm3" value="1" /> + <composite n="1" ref="Fr" /> + </material> + <element Z="31" formula="Ga" name="Ga" > + <atom type="A" unit="g/mol" value="69.7231" /> + </element> + <material formula="Ga" name="Gallium" state="solid" > + <RL type="X0" unit="cm" value="2.1128" /> + <NIL type="lambda" unit="cm" value="24.3351" /> + <D type="density" unit="g/cm3" value="5.904" /> + <composite n="1" ref="Ga" /> + </material> + <element Z="64" formula="Gd" name="Gd" > + <atom type="A" unit="g/mol" value="157.252" /> + </element> + <material formula="Gd" name="Gadolinium" state="solid" > + <RL type="X0" unit="cm" value="0.947208" /> + <NIL type="lambda" unit="cm" value="23.9377" /> + <D type="density" unit="g/cm3" value="7.9004" /> + <composite n="1" ref="Gd" /> + </material> + <element Z="32" formula="Ge" name="Ge" > + <atom type="A" unit="g/mol" value="72.6128" /> + </element> + <material formula="Ge" name="Germanium" state="solid" > + <RL type="X0" unit="cm" value="2.3013" /> + <NIL type="lambda" unit="cm" value="27.3344" /> + <D type="density" unit="g/cm3" value="5.323" /> + <composite n="1" ref="Ge" /> + </material> + <element Z="1" formula="H" name="H" > + <atom type="A" unit="g/mol" value="1.00794" /> + </element> + <material formula="H" name="Hydrogen" state="gas" > + <RL type="X0" unit="cm" value="752776" /> + <NIL type="lambda" unit="cm" value="421239" /> + <D type="density" unit="g/cm3" value="8.3748e-05" /> + <composite n="1" ref="H" /> + </material> + <element Z="2" formula="He" name="He" > + <atom type="A" unit="g/mol" value="4.00264" /> + </element> + <material formula="He" name="Helium" state="gas" > + <RL type="X0" unit="cm" value="567113" /> + <NIL type="lambda" unit="cm" value="334266" /> + <D type="density" unit="g/cm3" value="0.000166322" /> + <composite n="1" ref="He" /> + </material> + <element Z="72" formula="Hf" name="Hf" > + <atom type="A" unit="g/mol" value="178.485" /> + </element> + <material formula="Hf" name="Hafnium" state="solid" > + <RL type="X0" unit="cm" value="0.517717" /> + <NIL type="lambda" unit="cm" value="14.7771" /> + <D type="density" unit="g/cm3" value="13.31" /> + <composite n="1" ref="Hf" /> + </material> + <element Z="80" formula="Hg" name="Hg" > + <atom type="A" unit="g/mol" value="200.599" /> + </element> + <material formula="Hg" name="Mercury" state="solid" > + <RL type="X0" unit="cm" value="0.475241" /> + <NIL type="lambda" unit="cm" value="15.105" /> + <D type="density" unit="g/cm3" value="13.546" /> + <composite n="1" ref="Hg" /> + </material> + <element Z="67" formula="Ho" name="Ho" > + <atom type="A" unit="g/mol" value="164.93" /> + </element> + <material formula="Ho" name="Holmium" state="solid" > + <RL type="X0" unit="cm" value="0.822447" /> + <NIL type="lambda" unit="cm" value="21.8177" /> + <D type="density" unit="g/cm3" value="8.795" /> + <composite n="1" ref="Ho" /> + </material> + <element Z="53" formula="I" name="I" > + <atom type="A" unit="g/mol" value="126.904" /> + </element> + <material formula="I" name="Iodine" state="solid" > + <RL type="X0" unit="cm" value="1.72016" /> + <NIL type="lambda" unit="cm" value="35.6583" /> + <D type="density" unit="g/cm3" value="4.93" /> + <composite n="1" ref="I" /> + </material> + <element Z="49" formula="In" name="In" > + <atom type="A" unit="g/mol" value="114.818" /> + </element> + <material formula="In" name="Indium" state="solid" > + <RL type="X0" unit="cm" value="1.21055" /> + <NIL type="lambda" unit="cm" value="23.2468" /> + <D type="density" unit="g/cm3" value="7.31" /> + <composite n="1" ref="In" /> + </material> + <element Z="77" formula="Ir" name="Ir" > + <atom type="A" unit="g/mol" value="192.216" /> + </element> + <material formula="Ir" name="Iridium" state="solid" > + <RL type="X0" unit="cm" value="0.294142" /> + <NIL type="lambda" unit="cm" value="9.01616" /> + <D type="density" unit="g/cm3" value="22.42" /> + <composite n="1" ref="Ir" /> + </material> + <element Z="19" formula="K" name="K" > + <atom type="A" unit="g/mol" value="39.0983" /> + </element> + <material formula="K" name="Potassium" state="solid" > + <RL type="X0" unit="cm" value="20.0871" /> + <NIL type="lambda" unit="cm" value="138.041" /> + <D type="density" unit="g/cm3" value="0.862" /> + <composite n="1" ref="K" /> + </material> + <element Z="36" formula="Kr" name="Kr" > + <atom type="A" unit="g/mol" value="83.7993" /> + </element> + <material formula="Kr" name="Krypton" state="gas" > + <RL type="X0" unit="cm" value="3269.44" /> + <NIL type="lambda" unit="cm" value="43962.9" /> + <D type="density" unit="g/cm3" value="0.00347832" /> + <composite n="1" ref="Kr" /> + </material> + <element Z="57" formula="La" name="La" > + <atom type="A" unit="g/mol" value="138.905" /> + </element> + <material formula="La" name="Lanthanum" state="solid" > + <RL type="X0" unit="cm" value="1.32238" /> + <NIL type="lambda" unit="cm" value="29.441" /> + <D type="density" unit="g/cm3" value="6.154" /> + <composite n="1" ref="La" /> + </material> + <element Z="3" formula="Li" name="Li" > + <atom type="A" unit="g/mol" value="6.94003" /> + </element> + <material formula="Li" name="Lithium" state="solid" > + <RL type="X0" unit="cm" value="154.997" /> + <NIL type="lambda" unit="cm" value="124.305" /> + <D type="density" unit="g/cm3" value="0.534" /> + <composite n="1" ref="Li" /> + </material> + <element Z="71" formula="Lu" name="Lu" > + <atom type="A" unit="g/mol" value="174.967" /> + </element> + <material formula="Lu" name="Lutetium" state="solid" > + <RL type="X0" unit="cm" value="0.703651" /> + <NIL type="lambda" unit="cm" value="19.8916" /> + <D type="density" unit="g/cm3" value="9.84" /> + <composite n="1" ref="Lu" /> + </material> + <element Z="12" formula="Mg" name="Mg" > + <atom type="A" unit="g/mol" value="24.305" /> + </element> + <material formula="Mg" name="Magnesium" state="solid" > + <RL type="X0" unit="cm" value="14.3859" /> + <NIL type="lambda" unit="cm" value="58.7589" /> + <D type="density" unit="g/cm3" value="1.74" /> + <composite n="1" ref="Mg" /> + </material> + <element Z="25" formula="Mn" name="Mn" > + <atom type="A" unit="g/mol" value="54.938" /> + </element> + <material formula="Mn" name="Manganese" state="solid" > + <RL type="X0" unit="cm" value="1.96772" /> + <NIL type="lambda" unit="cm" value="17.8701" /> + <D type="density" unit="g/cm3" value="7.44" /> + <composite n="1" ref="Mn" /> + </material> + <element Z="42" formula="Mo" name="Mo" > + <atom type="A" unit="g/mol" value="95.9313" /> + </element> + <material formula="Mo" name="Molybdenum" state="solid" > + <RL type="X0" unit="cm" value="0.959107" /> + <NIL type="lambda" unit="cm" value="15.6698" /> + <D type="density" unit="g/cm3" value="10.22" /> + <composite n="1" ref="Mo" /> + </material> + <element Z="7" formula="N" name="N" > + <atom type="A" unit="g/mol" value="14.0068" /> + </element> + <material formula="N" name="Nitrogen" state="gas" > + <RL type="X0" unit="cm" value="32602.2" /> + <NIL type="lambda" unit="cm" value="72430.3" /> + <D type="density" unit="g/cm3" value="0.0011652" /> + <composite n="1" ref="N" /> + </material> + <element Z="11" formula="Na" name="Na" > + <atom type="A" unit="g/mol" value="22.9898" /> + </element> + <material formula="Na" name="Sodium" state="solid" > + <RL type="X0" unit="cm" value="28.5646" /> + <NIL type="lambda" unit="cm" value="102.463" /> + <D type="density" unit="g/cm3" value="0.971" /> + <composite n="1" ref="Na" /> + </material> + <element Z="41" formula="Nb" name="Nb" > + <atom type="A" unit="g/mol" value="92.9064" /> + </element> + <material formula="Nb" name="Niobium" state="solid" > + <RL type="X0" unit="cm" value="1.15783" /> + <NIL type="lambda" unit="cm" value="18.4846" /> + <D type="density" unit="g/cm3" value="8.57" /> + <composite n="1" ref="Nb" /> + </material> + <element Z="60" formula="Nd" name="Nd" > + <atom type="A" unit="g/mol" value="144.236" /> + </element> + <material formula="Nd" name="Neodymium" state="solid" > + <RL type="X0" unit="cm" value="1.11667" /> + <NIL type="lambda" unit="cm" value="26.6308" /> + <D type="density" unit="g/cm3" value="6.9" /> + <composite n="1" ref="Nd" /> + </material> + <element Z="10" formula="Ne" name="Ne" > + <atom type="A" unit="g/mol" value="20.18" /> + </element> + <material formula="Ne" name="Neon" state="gas" > + <RL type="X0" unit="cm" value="34504.8" /> + <NIL type="lambda" unit="cm" value="114322" /> + <D type="density" unit="g/cm3" value="0.000838505" /> + <composite n="1" ref="Ne" /> + </material> + <element Z="28" formula="Ni" name="Ni" > + <atom type="A" unit="g/mol" value="58.6933" /> + </element> + <material formula="Ni" name="Nickel" state="solid" > + <RL type="X0" unit="cm" value="1.42422" /> + <NIL type="lambda" unit="cm" value="15.2265" /> + <D type="density" unit="g/cm3" value="8.902" /> + <composite n="1" ref="Ni" /> + </material> + <element Z="93" formula="Np" name="Np" > + <atom type="A" unit="g/mol" value="237.048" /> + </element> + <material formula="Np" name="Neptunium" state="solid" > + <RL type="X0" unit="cm" value="0.289676" /> + <NIL type="lambda" unit="cm" value="10.6983" /> + <D type="density" unit="g/cm3" value="20.25" /> + <composite n="1" ref="Np" /> + </material> + <element Z="8" formula="O" name="O" > + <atom type="A" unit="g/mol" value="15.9994" /> + </element> + <material formula="O" name="Oxygen" state="gas" > + <RL type="X0" unit="cm" value="25713.8" /> + <NIL type="lambda" unit="cm" value="66233.9" /> + <D type="density" unit="g/cm3" value="0.00133151" /> + <composite n="1" ref="O" /> + </material> + <element Z="76" formula="Os" name="Os" > + <atom type="A" unit="g/mol" value="190.225" /> + </element> + <material formula="Os" name="Osmium" state="solid" > + <RL type="X0" unit="cm" value="0.295861" /> + <NIL type="lambda" unit="cm" value="8.92553" /> + <D type="density" unit="g/cm3" value="22.57" /> + <composite n="1" ref="Os" /> + </material> + <element Z="15" formula="P" name="P" > + <atom type="A" unit="g/mol" value="30.9738" /> + </element> + <material formula="P" name="Phosphorus" state="solid" > + <RL type="X0" unit="cm" value="9.63879" /> + <NIL type="lambda" unit="cm" value="49.9343" /> + <D type="density" unit="g/cm3" value="2.2" /> + <composite n="1" ref="P" /> + </material> + <element Z="91" formula="Pa" name="Pa" > + <atom type="A" unit="g/mol" value="231.036" /> + </element> + <material formula="Pa" name="Protactinium" state="solid" > + <RL type="X0" unit="cm" value="0.38607" /> + <NIL type="lambda" unit="cm" value="13.9744" /> + <D type="density" unit="g/cm3" value="15.37" /> + <composite n="1" ref="Pa" /> + </material> + <element Z="82" formula="Pb" name="Pb" > + <atom type="A" unit="g/mol" value="207.217" /> + </element> + <material formula="Pb" name="Lead" state="solid" > + <RL type="X0" unit="cm" value="0.561253" /> + <NIL type="lambda" unit="cm" value="18.2607" /> + <D type="density" unit="g/cm3" value="11.35" /> + <composite n="1" ref="Pb" /> + </material> + <element Z="46" formula="Pd" name="Pd" > + <atom type="A" unit="g/mol" value="106.415" /> + </element> + <material formula="Pd" name="Palladium" state="solid" > + <RL type="X0" unit="cm" value="0.765717" /> + <NIL type="lambda" unit="cm" value="13.7482" /> + <D type="density" unit="g/cm3" value="12.02" /> + <composite n="1" ref="Pd" /> + </material> + <element Z="61" formula="Pm" name="Pm" > + <atom type="A" unit="g/mol" value="144.913" /> + </element> + <material formula="Pm" name="Promethium" state="solid" > + <RL type="X0" unit="cm" value="1.04085" /> + <NIL type="lambda" unit="cm" value="25.4523" /> + <D type="density" unit="g/cm3" value="7.22" /> + <composite n="1" ref="Pm" /> + </material> + <element Z="84" formula="Po" name="Po" > + <atom type="A" unit="g/mol" value="208.982" /> + </element> + <material formula="Po" name="Polonium" state="solid" > + <RL type="X0" unit="cm" value="0.661092" /> + <NIL type="lambda" unit="cm" value="22.2842" /> + <D type="density" unit="g/cm3" value="9.32" /> + <composite n="1" ref="Po" /> + </material> + <element Z="59" formula="Pr" name="Pr" > + <atom type="A" unit="g/mol" value="140.908" /> + </element> + <material formula="Pr" name="Praseodymium" state="solid" > + <RL type="X0" unit="cm" value="1.1562" /> + <NIL type="lambda" unit="cm" value="27.1312" /> + <D type="density" unit="g/cm3" value="6.71" /> + <composite n="1" ref="Pr" /> + </material> + <element Z="78" formula="Pt" name="Pt" > + <atom type="A" unit="g/mol" value="195.078" /> + </element> + <material formula="Pt" name="Platinum" state="solid" > + <RL type="X0" unit="cm" value="0.305053" /> + <NIL type="lambda" unit="cm" value="9.46584" /> + <D type="density" unit="g/cm3" value="21.45" /> + <composite n="1" ref="Pt" /> + </material> + <element Z="94" formula="Pu" name="Pu" > + <atom type="A" unit="g/mol" value="244.064" /> + </element> + <material formula="Pu" name="Plutonium" state="solid" > + <RL type="X0" unit="cm" value="0.298905" /> + <NIL type="lambda" unit="cm" value="11.0265" /> + <D type="density" unit="g/cm3" value="19.84" /> + <composite n="1" ref="Pu" /> + </material> + <element Z="88" formula="Ra" name="Ra" > + <atom type="A" unit="g/mol" value="226.025" /> + </element> + <material formula="Ra" name="Radium" state="solid" > + <RL type="X0" unit="cm" value="1.22987" /> + <NIL type="lambda" unit="cm" value="42.6431" /> + <D type="density" unit="g/cm3" value="5" /> + <composite n="1" ref="Ra" /> + </material> + <element Z="37" formula="Rb" name="Rb" > + <atom type="A" unit="g/mol" value="85.4677" /> + </element> + <material formula="Rb" name="Rubidium" state="solid" > + <RL type="X0" unit="cm" value="7.19774" /> + <NIL type="lambda" unit="cm" value="100.218" /> + <D type="density" unit="g/cm3" value="1.532" /> + <composite n="1" ref="Rb" /> + </material> + <element Z="75" formula="Re" name="Re" > + <atom type="A" unit="g/mol" value="186.207" /> + </element> + <material formula="Re" name="Rhenium" state="solid" > + <RL type="X0" unit="cm" value="0.318283" /> + <NIL type="lambda" unit="cm" value="9.5153" /> + <D type="density" unit="g/cm3" value="21.02" /> + <composite n="1" ref="Re" /> + </material> + <element Z="45" formula="Rh" name="Rh" > + <atom type="A" unit="g/mol" value="102.906" /> + </element> + <material formula="Rh" name="Rhodium" state="solid" > + <RL type="X0" unit="cm" value="0.746619" /> + <NIL type="lambda" unit="cm" value="13.2083" /> + <D type="density" unit="g/cm3" value="12.41" /> + <composite n="1" ref="Rh" /> + </material> + <element Z="86" formula="Rn" name="Rn" > + <atom type="A" unit="g/mol" value="222.018" /> + </element> + <material formula="Rn" name="Radon" state="gas" > + <RL type="X0" unit="cm" value="697.777" /> + <NIL type="lambda" unit="cm" value="23532" /> + <D type="density" unit="g/cm3" value="0.00900662" /> + <composite n="1" ref="Rn" /> + </material> + <element Z="44" formula="Ru" name="Ru" > + <atom type="A" unit="g/mol" value="101.065" /> + </element> + <material formula="Ru" name="Ruthenium" state="solid" > + <RL type="X0" unit="cm" value="0.764067" /> + <NIL type="lambda" unit="cm" value="13.1426" /> + <D type="density" unit="g/cm3" value="12.41" /> + <composite n="1" ref="Ru" /> + </material> + <element Z="16" formula="S" name="S" > + <atom type="A" unit="g/mol" value="32.0661" /> + </element> + <material formula="S" name="Sulfur" state="solid" > + <RL type="X0" unit="cm" value="9.74829" /> + <NIL type="lambda" unit="cm" value="55.6738" /> + <D type="density" unit="g/cm3" value="2" /> + <composite n="1" ref="S" /> + </material> + <element Z="51" formula="Sb" name="Sb" > + <atom type="A" unit="g/mol" value="121.76" /> + </element> + <material formula="Sb" name="Antimony" state="solid" > + <RL type="X0" unit="cm" value="1.30401" /> + <NIL type="lambda" unit="cm" value="25.8925" /> + <D type="density" unit="g/cm3" value="6.691" /> + <composite n="1" ref="Sb" /> + </material> + <element Z="21" formula="Sc" name="Sc" > + <atom type="A" unit="g/mol" value="44.9559" /> + </element> + <material formula="Sc" name="Scandium" state="solid" > + <RL type="X0" unit="cm" value="5.53545" /> + <NIL type="lambda" unit="cm" value="41.609" /> + <D type="density" unit="g/cm3" value="2.989" /> + <composite n="1" ref="Sc" /> + </material> + <element Z="34" formula="Se" name="Se" > + <atom type="A" unit="g/mol" value="78.9594" /> + </element> + <material formula="Se" name="Selenium" state="solid" > + <RL type="X0" unit="cm" value="2.64625" /> + <NIL type="lambda" unit="cm" value="33.356" /> + <D type="density" unit="g/cm3" value="4.5" /> + <composite n="1" ref="Se" /> + </material> + <element Z="14" formula="Si" name="Si" > + <atom type="A" unit="g/mol" value="28.0854" /> + </element> + <material formula="Si" name="Silicon" state="solid" > + <RL type="X0" unit="cm" value="9.36607" /> + <NIL type="lambda" unit="cm" value="45.7531" /> + <D type="density" unit="g/cm3" value="2.33" /> + <composite n="1" ref="Si" /> + </material> + <element Z="62" formula="Sm" name="Sm" > + <atom type="A" unit="g/mol" value="150.366" /> + </element> + <material formula="Sm" name="Samarium" state="solid" > + <RL type="X0" unit="cm" value="1.01524" /> + <NIL type="lambda" unit="cm" value="24.9892" /> + <D type="density" unit="g/cm3" value="7.46" /> + <composite n="1" ref="Sm" /> + </material> + <element Z="50" formula="Sn" name="Sn" > + <atom type="A" unit="g/mol" value="118.71" /> + </element> + <material formula="Sn" name="Tin" state="solid" > + <RL type="X0" unit="cm" value="1.20637" /> + <NIL type="lambda" unit="cm" value="23.4931" /> + <D type="density" unit="g/cm3" value="7.31" /> + <composite n="1" ref="Sn" /> + </material> + <element Z="38" formula="Sr" name="Sr" > + <atom type="A" unit="g/mol" value="87.6166" /> + </element> + <material formula="Sr" name="Strontium" state="solid" > + <RL type="X0" unit="cm" value="4.237" /> + <NIL type="lambda" unit="cm" value="61.0238" /> + <D type="density" unit="g/cm3" value="2.54" /> + <composite n="1" ref="Sr" /> + </material> + <element Z="73" formula="Ta" name="Ta" > + <atom type="A" unit="g/mol" value="180.948" /> + </element> + <material formula="Ta" name="Tantalum" state="solid" > + <RL type="X0" unit="cm" value="0.409392" /> + <NIL type="lambda" unit="cm" value="11.8846" /> + <D type="density" unit="g/cm3" value="16.654" /> + <composite n="1" ref="Ta" /> + </material> + <element Z="65" formula="Tb" name="Tb" > + <atom type="A" unit="g/mol" value="158.925" /> + </element> + <material formula="Tb" name="Terbium" state="solid" > + <RL type="X0" unit="cm" value="0.893977" /> + <NIL type="lambda" unit="cm" value="23.0311" /> + <D type="density" unit="g/cm3" value="8.229" /> + <composite n="1" ref="Tb" /> + </material> + <element Z="43" formula="Tc" name="Tc" > + <atom type="A" unit="g/mol" value="97.9072" /> + </element> + <material formula="Tc" name="Technetium" state="solid" > + <RL type="X0" unit="cm" value="0.833149" /> + <NIL type="lambda" unit="cm" value="14.0185" /> + <D type="density" unit="g/cm3" value="11.5" /> + <composite n="1" ref="Tc" /> + </material> + <element Z="52" formula="Te" name="Te" > + <atom type="A" unit="g/mol" value="127.603" /> + </element> + <material formula="Te" name="Tellurium" state="solid" > + <RL type="X0" unit="cm" value="1.41457" /> + <NIL type="lambda" unit="cm" value="28.1797" /> + <D type="density" unit="g/cm3" value="6.24" /> + <composite n="1" ref="Te" /> + </material> + <element Z="90" formula="Th" name="Th" > + <atom type="A" unit="g/mol" value="232.038" /> + </element> + <material formula="Th" name="Thorium" state="solid" > + <RL type="X0" unit="cm" value="0.51823" /> + <NIL type="lambda" unit="cm" value="18.353" /> + <D type="density" unit="g/cm3" value="11.72" /> + <composite n="1" ref="Th" /> + </material> + <element Z="22" formula="Ti" name="Ti" > + <atom type="A" unit="g/mol" value="47.8667" /> + </element> + <material formula="Ti" name="Titanium" state="solid" > + <RL type="X0" unit="cm" value="3.5602" /> + <NIL type="lambda" unit="cm" value="27.9395" /> + <D type="density" unit="g/cm3" value="4.54" /> + <composite n="1" ref="Ti" /> + </material> + <element Z="81" formula="Tl" name="Tl" > + <atom type="A" unit="g/mol" value="204.383" /> + </element> + <material formula="Tl" name="Thallium" state="solid" > + <RL type="X0" unit="cm" value="0.547665" /> + <NIL type="lambda" unit="cm" value="17.6129" /> + <D type="density" unit="g/cm3" value="11.72" /> + <composite n="1" ref="Tl" /> + </material> + <element Z="69" formula="Tm" name="Tm" > + <atom type="A" unit="g/mol" value="168.934" /> + </element> + <material formula="Tm" name="Thulium" state="solid" > + <RL type="X0" unit="cm" value="0.754428" /> + <NIL type="lambda" unit="cm" value="20.7522" /> + <D type="density" unit="g/cm3" value="9.321" /> + <composite n="1" ref="Tm" /> + </material> + <element Z="92" formula="U" name="U" > + <atom type="A" unit="g/mol" value="238.029" /> + </element> + <material formula="U" name="Uranium" state="solid" > + <RL type="X0" unit="cm" value="0.31663" /> + <NIL type="lambda" unit="cm" value="11.4473" /> + <D type="density" unit="g/cm3" value="18.95" /> + <composite n="1" ref="U" /> + </material> + <element Z="23" formula="V" name="V" > + <atom type="A" unit="g/mol" value="50.9415" /> + </element> + <material formula="V" name="Vanadium" state="solid" > + <RL type="X0" unit="cm" value="2.59285" /> + <NIL type="lambda" unit="cm" value="21.2187" /> + <D type="density" unit="g/cm3" value="6.11" /> + <composite n="1" ref="V" /> + </material> + <element Z="74" formula="W" name="W" > + <atom type="A" unit="g/mol" value="183.842" /> + </element> + <material formula="W" name="Tungsten" state="solid" > + <RL type="X0" unit="cm" value="0.350418" /> + <NIL type="lambda" unit="cm" value="10.3057" /> + <D type="density" unit="g/cm3" value="19.3" /> + <composite n="1" ref="W" /> + </material> + <element Z="54" formula="Xe" name="Xe" > + <atom type="A" unit="g/mol" value="131.292" /> + </element> + <material formula="Xe" name="Xenon" state="gas" > + <RL type="X0" unit="cm" value="1546.2" /> + <NIL type="lambda" unit="cm" value="32477.9" /> + <D type="density" unit="g/cm3" value="0.00548536" /> + <composite n="1" ref="Xe" /> + </material> + <element Z="39" formula="Y" name="Y" > + <atom type="A" unit="g/mol" value="88.9058" /> + </element> + <material formula="Y" name="Yttrium" state="solid" > + <RL type="X0" unit="cm" value="2.32943" /> + <NIL type="lambda" unit="cm" value="34.9297" /> + <D type="density" unit="g/cm3" value="4.469" /> + <composite n="1" ref="Y" /> + </material> + <element Z="70" formula="Yb" name="Yb" > + <atom type="A" unit="g/mol" value="173.038" /> + </element> + <material formula="Yb" name="Ytterbium" state="solid" > + <RL type="X0" unit="cm" value="1.04332" /> + <NIL type="lambda" unit="cm" value="28.9843" /> + <D type="density" unit="g/cm3" value="6.73" /> + <composite n="1" ref="Yb" /> + </material> + <element Z="30" formula="Zn" name="Zn" > + <atom type="A" unit="g/mol" value="65.3955" /> + </element> + <material formula="Zn" name="Zinc" state="solid" > + <RL type="X0" unit="cm" value="1.74286" /> + <NIL type="lambda" unit="cm" value="19.8488" /> + <D type="density" unit="g/cm3" value="7.133" /> + <composite n="1" ref="Zn" /> + </material> + <element Z="40" formula="Zr" name="Zr" > + <atom type="A" unit="g/mol" value="91.2236" /> + </element> + <material formula="Zr" name="Zirconium" state="solid" > + <RL type="X0" unit="cm" value="1.56707" /> + <NIL type="lambda" unit="cm" value="24.2568" /> + <D type="density" unit="g/cm3" value="6.506" /> + <composite n="1" ref="Zr" /> + </material> +</materials> \ No newline at end of file diff --git a/DDExamples/AlignDet/compact/materials.xml b/DDExamples/AlignDet/compact/materials.xml new file mode 100644 index 0000000000000000000000000000000000000000..12107bafc23a2b39c32e457b34ec7568e5139993 --- /dev/null +++ b/DDExamples/AlignDet/compact/materials.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<materials> + + <!-- + Air by weight from + + http://www.engineeringtoolbox.com/air-composition-24_212.html + --> + <material name="Air"> + <D type="density" unit="g/cm3" value="0.0012"/> + <fraction n="0.754" ref="N"/> + <fraction n="0.234" ref="O"/> + <fraction n="0.012" ref="Ar"/> + </material> + + <material name="Vacuum"> + <D type="density" unit="g/cm3" value="0.00000001" /> + <fraction n="1" ref="H" /> + </material> + + <material name="Epoxy"> + <D type="density" value="1.3" unit="g/cm3"/> + <composite n="44" ref="H"/> + <composite n="15" ref="C"/> + <composite n="7" ref="O"/> + </material> + + <material name="Quartz"> + <D type="density" value="2.2" unit="g/cm3"/> + <composite n="1" ref="Si"/> + <composite n="2" ref="O"/> + </material> + + <material name="G10"> + <D type="density" value="1.7" unit="g/cm3"/> + <fraction n="0.08" ref="Cl"/> + <fraction n="0.773" ref="Quartz"/> + <fraction n="0.147" ref="Epoxy"/> + </material> + + <material name="Polystyrene"> + <D value="1.032" unit="g/cm3"/> + <composite n="19" ref="C"/> + <composite n="21" ref="H"/> + </material> + + <material name="Steel235"> + <D value="7.85" unit="g/cm3"/> + <fraction n="0.998" ref="Fe"/> + <fraction n=".002" ref="C"/> + </material> + + <material name="SiliconOxide"> + <D type="density" value="2.65" unit="g/cm3"/> + <composite n="1" ref="Si"/> + <composite n="2" ref="O"/> + </material> + + <material name="BoronOxide"> + <D type="density" value="2.46" unit="g/cm3"/> + <composite n="2" ref="B"/> + <composite n="3" ref="O"/> + </material> + + <material name="SodiumOxide"> + <D type="density" value="2.65" unit="g/cm3"/> + <composite n="2" ref="Na"/> + <composite n="1" ref="O"/> + </material> + + <material name="AluminumOxide"> + <D type="density" value="3.89" unit="g/cm3"/> + <composite n="2" ref="Al"/> + <composite n="3" ref="O"/> + </material> + + <material name="PyrexGlass"> + <D type="density" value="2.23" unit="g/cm3"/> + <fraction n="0.806" ref="SiliconOxide"/> + <fraction n="0.130" ref="BoronOxide"/> + <fraction n="0.040" ref="SodiumOxide"/> + <fraction n="0.023" ref="AluminumOxide"/> + </material> + + <material name="CarbonFiber"> + <D type="density" value="1.5" unit="g/cm3"/> + <fraction n="0.65" ref="C"/> + <fraction n="0.35" ref="Epoxy"/> + </material> + + <material name="CarbonFiber_50D"> + <D type="density" value="0.75" unit="g/cm3"/> + <fraction n="0.65" ref="C"/> + <fraction n="0.35" ref="Epoxy"/> + </material> + + <material name="Rohacell31"> + <D type="density" value="0.032" unit="g/cm3"/> + <composite n="9" ref="C"/> + <composite n="13" ref="H"/> + <composite n="2" ref="O"/> + <composite n="1" ref="N"/> + </material> + + <material name="Rohacell31_50D"> + <D type="density" value="0.016" unit="g/cm3"/> + <composite n="9" ref="C"/> + <composite n="13" ref="H"/> + <composite n="2" ref="O"/> + <composite n="1" ref="N"/> + </material> + + <material name="RPCGasDefault" state="gas"> + <D type="density" value="0.0037" unit="g/cm3"/> + <composite n="209" ref="C"/> + <composite n="239" ref="H"/> + <composite n="381" ref="F"/> + </material> + + <material name="PolystyreneFoam"> + <D type="density" value="0.0056" unit="g/cm3"/> + <fraction n="1.0" ref="Polystyrene"/> + </material> + + <material name="Kapton"> + <D value="1.43" unit="g/cm3" /> + <composite n="22" ref="C"/> + <composite n="10" ref="H" /> + <composite n="2" ref="N" /> + <composite n="5" ref="O" /> + </material> + + <material name="PEEK"> + <D value="1.37" unit="g/cm3" /> + <composite n="19" ref="C"/> + <composite n="12" ref="H" /> + <composite n="3" ref="O" /> + </material> + +</materials> diff --git a/DDExamples/AlignDet/src/BoxDetector_geo.cpp b/DDExamples/AlignDet/src/BoxDetector_geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25d4a9583eeb9298e725a3f1adc756f4c8167287 --- /dev/null +++ b/DDExamples/AlignDet/src/BoxDetector_geo.cpp @@ -0,0 +1,36 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector&) { + xml_det_t x_det = e; + string name = x_det.nameStr(); + xml_comp_t x_box (x_det.child(_X(box))); + xml_dim_t x_pos (x_det.child(_X(position))); + xml_dim_t x_rot (x_det.child(_X(rotation))); + Material mat (lcdd.material(x_det.materialStr())); + DetElement det (lcdd,name,x_det.typeStr(),x_det.id()); + Box det_box(lcdd,name+"_envelope",x_box.x(),x_box.y(),x_box.z()); + Volume det_vol(lcdd,name+"_envelope_volume",det_box, mat); + Volume mother = lcdd.pickMotherVolume(det); + + det_vol.setVisAttributes(lcdd, x_det.visStr()); + PlacedVolume phv = mother.placeVolume(det_vol,Position(x_pos.x(),x_pos.y(),x_pos.z()), + Rotation(x_rot.x(),x_rot.y(),x_rot.z())); + phv.addPhysVolID(_A(id),x_det.id()); + det.addPlacement(phv); + return det; +} + +// first argument is the type from the xml file +DECLARE_DETELEMENT(BoxSegment,create_element) diff --git a/DDExamples/AlignDet/test/main.cpp b/DDExamples/AlignDet/test/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e0a4518a88356d872bc87f196862b057244346f --- /dev/null +++ b/DDExamples/AlignDet/test/main.cpp @@ -0,0 +1,61 @@ +#include "DD4hep/LCDD.h" +//#include "TGDMLWrite.h" +#include "TGeoManager.h" +#include <iostream> +#include <vector> +#include <string> + + +using namespace std; +using namespace DD4hep; + +Geometry::LCDD& compact2geo(int argc, char **argv) { + string input; +#ifdef _WIN32 + input = "file:../cmt/compact.xml"; +#else + //input = "file:/afs/cern.ch/user/f/frankb/scratch0/ONLINE/ONLINE_HEAD/Online/GeoTest/cmt/compact.xml"; + + input = "compact.xml"; + //input = "file://../cmt/compact.xml"; + //input = "http://www.cern.ch/frankm/compact.xml"; + +#endif + if ( argc>1 ) { + input = argv[1]; + } + //Geometry::LCDDImp *lcdd = new Geometry::LCDDImp; + Geometry::LCDD& lcdd = Geometry::LCDD::getInstance(); + cout << argc << " Input file : " << input << endl; + lcdd.fromCompact(input); + lcdd.dump(); + return lcdd; +} + +#include "TRint.h" +//______________________________________________________________________________ +int run_interpreter(int argc, char **argv) { + vector<char*> args; + + for(int i=0; i<argc;++i) args.push_back((char*)argv[i]); + + // Create an interactive ROOT application + int r_argc = 0; + char** r_argv = 0; + TRint *theApp = new TRint("Rint", &r_argc, r_argv); + + Geometry::LCDD& lcdd = compact2geo((int)args.size(),&args[0]); + //TGDMLWrite wr; + //wr.WriteGDMLfile(gGeoManager,"ILCEx.gdml",""); + + // and enter the event loop... + theApp->Run(); + delete theApp; + return 0; +} + +int main(int argc,char** argv) { + //return read_compact(); + //return compact2lcdd(); + return run_interpreter(argc,argv); +} diff --git a/DDExamples/CLICSiD/include/CompactDetectors.h b/DDExamples/CLICSiD/include/CompactDetectors.h deleted file mode 100644 index 43eb1384fa0b80fd1035c26b36e3ff44471f5455..0000000000000000000000000000000000000000 --- a/DDExamples/CLICSiD/include/CompactDetectors.h +++ /dev/null @@ -1,36 +0,0 @@ -// $Id:$ -//==================================================================== -// AIDA Detector description for Sid Compact notation -//-------------------------------------------------------------------- -// -// Author : M.Frank -// -//==================================================================== -#ifndef DD4hep_DETECTORS_COMPACTDETECTORS_H -#define DD4hep_DETECTORS_COMPACTDETECTORS_H - -#include "DD4hep/Detector.h" - -namespace DD4hep { - namespace Geometry { - struct SensitiveDetector; - } - using namespace Geometry; - struct PolyconeSupport : public DetElement {}; - struct TubeSegment : public DetElement {}; - struct MultiLayerTracker : public DetElement {}; - struct DiskTracker : public DetElement {}; - struct SiVertexBarrel : public DetElement {}; - struct SiVertexEndcap2 : public DetElement {}; - struct SiTrackerBarrel : public DetElement {}; - struct SiTrackerEndcap : public DetElement {}; - struct SiTrackerEndcap2 : public DetElement {}; - struct CylindricalBarrelCalorimeter : public DetElement {}; - struct CylindricalEndcapCalorimeter : public DetElement {}; - struct EcalBarrel : public DetElement {}; - struct PolyhedraEndcapCalorimeter2 : public DetElement {}; - struct PolyhedraBarrelCalorimeter2 : public DetElement {}; - struct ForwardDetector : public DetElement {}; - -} -#endif // DD4hep_DETECTORS_COMPACTDETECTORS_H diff --git a/DDExamples/CLICSiD/src/CompactDetectors.h b/DDExamples/CLICSiD/src/CompactDetectors.h deleted file mode 100644 index 43eb1384fa0b80fd1035c26b36e3ff44471f5455..0000000000000000000000000000000000000000 --- a/DDExamples/CLICSiD/src/CompactDetectors.h +++ /dev/null @@ -1,36 +0,0 @@ -// $Id:$ -//==================================================================== -// AIDA Detector description for Sid Compact notation -//-------------------------------------------------------------------- -// -// Author : M.Frank -// -//==================================================================== -#ifndef DD4hep_DETECTORS_COMPACTDETECTORS_H -#define DD4hep_DETECTORS_COMPACTDETECTORS_H - -#include "DD4hep/Detector.h" - -namespace DD4hep { - namespace Geometry { - struct SensitiveDetector; - } - using namespace Geometry; - struct PolyconeSupport : public DetElement {}; - struct TubeSegment : public DetElement {}; - struct MultiLayerTracker : public DetElement {}; - struct DiskTracker : public DetElement {}; - struct SiVertexBarrel : public DetElement {}; - struct SiVertexEndcap2 : public DetElement {}; - struct SiTrackerBarrel : public DetElement {}; - struct SiTrackerEndcap : public DetElement {}; - struct SiTrackerEndcap2 : public DetElement {}; - struct CylindricalBarrelCalorimeter : public DetElement {}; - struct CylindricalEndcapCalorimeter : public DetElement {}; - struct EcalBarrel : public DetElement {}; - struct PolyhedraEndcapCalorimeter2 : public DetElement {}; - struct PolyhedraBarrelCalorimeter2 : public DetElement {}; - struct ForwardDetector : public DetElement {}; - -} -#endif // DD4hep_DETECTORS_COMPACTDETECTORS_H diff --git a/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp b/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp index 4ea4139b41475232e68c739ecc94b974799930cf..b1ed0e9f0abc4c864c09b68955c764506419dbeb 100644 --- a/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp +++ b/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp @@ -6,70 +6,65 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<CylindricalBarrelCalorimeter>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - xml_dim_t dim = x_det.dimensions(); - Material air = lcdd.air(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - Tube envelope (lcdd,det_name+"_envelope"); - Volume envelopeVol(lcdd,det_name+"_envelope_volume",envelope,air); - DetElement sdet (lcdd,det_name,det_type,x_det.id()); - double z = dim.outer_z(); - double rmin = dim.inner_r(); - double r = rmin; - int n = 0; +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + xml_dim_t dim = x_det.dimensions(); + Material air = lcdd.air(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + Tube envelope (lcdd,det_name+"_envelope"); + Volume envelopeVol(lcdd,det_name+"_envelope_volume",envelope,air); + DetElement sdet (lcdd,det_name,det_type,x_det.id()); + double z = dim.outer_z(); + double rmin = dim.inner_r(); + double r = rmin; + int n = 0; - for(xml_coll_t c(x_det,_X(layer)); c; ++c) { - xml_comp_t x_layer = c; - for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0) { - string layer_name = det_name + _toString(n,"_layer%d"); - Tube layer_tub(lcdd,layer_name); - Volume layer_vol(lcdd,layer_name+"_volume",layer_tub,air); - double rlayer = r; + for(xml_coll_t c(x_det,_X(layer)); c; ++c) { + xml_comp_t x_layer = c; + for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0) { + string layer_name = det_name + _toString(n,"_layer%d"); + Tube layer_tub(lcdd,layer_name); + Volume layer_vol(lcdd,layer_name+"_volume",layer_tub,air); + double rlayer = r; - for(xml_coll_t l(x_layer,_X(slice)); l; ++l, ++m) { - xml_comp_t x_slice = l; - Material slice_mat = lcdd.material(x_slice.materialStr()); - string slice_name = layer_name + _toString(m,"slice%d"); - Tube slice_tube(lcdd,slice_name); - Volume slice_vol (lcdd,slice_name+"_volume",slice_tube,slice_mat); - double router = r + x_slice.thickness(); + for(xml_coll_t l(x_layer,_X(slice)); l; ++l, ++m) { + xml_comp_t x_slice = l; + Material slice_mat = lcdd.material(x_slice.materialStr()); + string slice_name = layer_name + _toString(m,"slice%d"); + Tube slice_tube(lcdd,slice_name); + Volume slice_vol (lcdd,slice_name+"_volume",slice_tube,slice_mat); + double router = r + x_slice.thickness(); - if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens); - slice_tube.setDimensions(r,router,z * 2); - r = router; - slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); - // Instantiate physical volume - layer_vol.placeVolume(slice_vol,IdentityPos()); - } - layer_vol.setVisAttributes(lcdd,x_layer.visStr()); - layer_tub.setDimensions(rlayer,r,z * 2); - - PlacedVolume layer_physvol = envelopeVol.placeVolume(layer_vol,IdentityPos()); - layer_physvol.addPhysVolID(_A(layer),n); - ++n; + if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens); + slice_tube.setDimensions(r,router,z * 2); + r = router; + slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + // Instantiate physical volume + layer_vol.placeVolume(slice_vol,IdentityPos()); } + layer_vol.setVisAttributes(lcdd,x_layer.visStr()); + layer_tub.setDimensions(rlayer,r,z * 2); + + PlacedVolume layer_physvol = envelopeVol.placeVolume(layer_vol,IdentityPos()); + layer_physvol.addPhysVolID(_A(layer),n); + ++n; } - envelope.setDimensions(rmin,r,2.*z); - // Set region of slice - envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); - - PlacedVolume physvol = lcdd.pickMotherVolume(sdet).placeVolume(envelopeVol,IdentityPos()); - physvol.addPhysVolID(_A(system),sdet.id()).addPhysVolID(_A(barrel),0); - sdet.addPlacement(physvol); - return sdet; } -}} + envelope.setDimensions(rmin,r,2.*z); + // Set region of slice + envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + PlacedVolume physvol = lcdd.pickMotherVolume(sdet).placeVolume(envelopeVol,IdentityPos()); + physvol.addPhysVolID(_A(system),sdet.id()).addPhysVolID(_A(barrel),0); + sdet.addPlacement(physvol); + return sdet; +} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,CylindricalBarrelCalorimeter); +DECLARE_DETELEMENT(CylindricalBarrelCalorimeter,create_detector); diff --git a/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp b/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp index 528625533afbc0b6d038925a844527d05d98c12b..f10c1b4256bdc887c25fac1cd1728e62740401f1 100644 --- a/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp +++ b/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp @@ -6,84 +6,79 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" #include "XML/Layering.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<CylindricalEndcapCalorimeter>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - xml_dim_t dim = x_det.dimensions(); - Material air = lcdd.air(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - Tube envelope (lcdd,det_name+"_envelope"); - Volume envelopeVol(lcdd,det_name+"_envelope_volume",envelope,air); - bool reflect = dim.reflect(); - double zmin = dim.inner_z(); - double rmin = dim.inner_r(); - double rmax = dim.outer_r(); - double totWidth = Layering(x_det).totalThickness(); - double z = zmin; - int n = 0; +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + xml_dim_t dim = x_det.dimensions(); + Material air = lcdd.air(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + Tube envelope (lcdd,det_name+"_envelope"); + Volume envelopeVol(lcdd,det_name+"_envelope_volume",envelope,air); + bool reflect = dim.reflect(); + double zmin = dim.inner_z(); + double rmin = dim.inner_r(); + double rmax = dim.outer_r(); + double totWidth = Layering(x_det).totalThickness(); + double z = zmin; + int n = 0; - for(xml_coll_t c(x_det,_X(layer)); c; ++c) { - xml_comp_t x_layer = c; - double layerWidth = 0; - for(xml_coll_t l(x_layer,_X(slice)); l; ++l) - layerWidth += xml_comp_t(l).thickness(); - for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0) { - double zlayer = z; - string layer_name = det_name + _toString(n,"_layer%d"); - Tube layer_tub(lcdd,layer_name,rmin,rmax,layerWidth); - Volume layer_vol(lcdd,layer_name+"_volume",layer_tub,air); + for(xml_coll_t c(x_det,_X(layer)); c; ++c) { + xml_comp_t x_layer = c; + double layerWidth = 0; + for(xml_coll_t l(x_layer,_X(slice)); l; ++l) + layerWidth += xml_comp_t(l).thickness(); + for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0) { + double zlayer = z; + string layer_name = det_name + _toString(n,"_layer%d"); + Tube layer_tub(lcdd,layer_name,rmin,rmax,layerWidth); + Volume layer_vol(lcdd,layer_name+"_volume",layer_tub,air); - for(xml_coll_t l(x_layer,_X(slice)); l; ++l, ++m) { - xml_comp_t x_slice = l; - double w = x_slice.thickness(); - string slice_name = layer_name + _toString(m,"slice%d"); - Material slice_mat = lcdd.material(x_slice.materialStr()); - Tube slice_tube(lcdd,slice_name, rmin,rmax,w); - Volume slice_vol (lcdd,slice_name+"_volume", slice_tube, slice_mat); + for(xml_coll_t l(x_layer,_X(slice)); l; ++l, ++m) { + xml_comp_t x_slice = l; + double w = x_slice.thickness(); + string slice_name = layer_name + _toString(m,"slice%d"); + Material slice_mat = lcdd.material(x_slice.materialStr()); + Tube slice_tube(lcdd,slice_name, rmin,rmax,w); + Volume slice_vol (lcdd,slice_name+"_volume", slice_tube, slice_mat); - if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens); + if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens); - // Set attributes of slice - slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); - layer_vol.placeVolume(slice_vol,Position(0,0,z-zlayer-layerWidth/2+w/2)); - z += w; - } - layer_vol.setVisAttributes(lcdd,x_layer.visStr()); - - Position layer_pos(0,0,zlayer-zmin-totWidth/2+layerWidth/2); - PlacedVolume layer_phys = envelopeVol.placeVolume(layer_vol,layer_pos); - layer_phys.addPhysVolID("layer",n); - ++n; + // Set attributes of slice + slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + layer_vol.placeVolume(slice_vol,Position(0,0,z-zlayer-layerWidth/2+w/2)); + z += w; } + layer_vol.setVisAttributes(lcdd,x_layer.visStr()); + + Position layer_pos(0,0,zlayer-zmin-totWidth/2+layerWidth/2); + PlacedVolume layer_phys = envelopeVol.placeVolume(layer_vol,layer_pos); + layer_phys.addPhysVolID("layer",n); + ++n; } - envelope.setDimensions(rmin,rmax,totWidth,2.*M_PI); - // Set attributes of slice - envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + } + envelope.setDimensions(rmin,rmax,totWidth,2.*M_PI); + // Set attributes of slice + envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); - DetElement sdet(lcdd,det_name,det_type,x_det.id()); - Volume motherVol = lcdd.pickMotherVolume(sdet); - PlacedVolume phv=motherVol.placeVolume(envelopeVol,Position(0,0,zmin+totWidth/2)); - phv.addPhysVolID(_A(system),sdet.id()) + DetElement sdet(lcdd,det_name,det_type,x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + PlacedVolume phv=motherVol.placeVolume(envelopeVol,Position(0,0,zmin+totWidth/2)); + phv.addPhysVolID(_A(system),sdet.id()) .addPhysVolID(_A(barrel),1); - sdet.addPlacement(phv); - if ( reflect ) { - phv=motherVol.placeVolume(envelopeVol,Position(0,0,-zmin-totWidth/2),ReflectRot()); - phv.addPhysVolID(_A(system),sdet.id()) + sdet.addPlacement(phv); + if ( reflect ) { + phv=motherVol.placeVolume(envelopeVol,Position(0,0,-zmin-totWidth/2),ReflectRot()); + phv.addPhysVolID(_A(system),sdet.id()) .addPhysVolID(_A(barrel),2); - } - return sdet; } -}} + return sdet; +} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,CylindricalEndcapCalorimeter); +DECLARE_DETELEMENT(CylindricalEndcapCalorimeter,create_detector); diff --git a/DDExamples/CLICSiD/src/DiskTracker_geo.cpp b/DDExamples/CLICSiD/src/DiskTracker_geo.cpp index 4bddb83e1faed23b11124ea7ab8a0bcde13fc09a..2736cf2c72da1e6a467bd1cc6a29e3882d2489a3 100644 --- a/DDExamples/CLICSiD/src/DiskTracker_geo.cpp +++ b/DDExamples/CLICSiD/src/DiskTracker_geo.cpp @@ -6,74 +6,69 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<DiskTracker>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - Material air = lcdd.air(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - bool reflect = x_det.reflect(); - DetElement sdet (lcdd,det_name,det_type,x_det.id()); - Volume motherVol = lcdd.pickMotherVolume(sdet); - int l_num = 0; +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + Material air = lcdd.air(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + bool reflect = x_det.reflect(); + DetElement sdet(lcdd,det_name,det_type,x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + int l_num = 0; - for(xml_coll_t i(x_det,_X(layer)); i; ++i, ++l_num) { - xml_comp_t x_layer = i; - string l_nam = det_name+_toString(l_num,"_layer%d"); - double zmin = x_layer.inner_z(); - double rmin = x_layer.inner_r(); - double rmax = x_layer.outer_r(); - double z = zmin, layerWidth = 0.; - Tube l_tub(lcdd,l_nam,rmin,rmax,2*z,2*M_PI); - Volume l_vol(lcdd,l_nam+"_volume",l_tub,air); - int s_num = 0; + for(xml_coll_t i(x_det,_X(layer)); i; ++i, ++l_num) { + xml_comp_t x_layer = i; + string l_nam = det_name+_toString(l_num,"_layer%d"); + double zmin = x_layer.inner_z(); + double rmin = x_layer.inner_r(); + double rmax = x_layer.outer_r(); + double z = zmin, layerWidth = 0.; + Tube l_tub(lcdd,l_nam,rmin,rmax,2*z,2*M_PI); + Volume l_vol(lcdd,l_nam+"_volume",l_tub,air); + int s_num = 0; - for(xml_coll_t j(x_layer,_X(slice)); j; ++j) { - double thickness = xml_comp_t(j).thickness(); - layerWidth += thickness; - } - l_vol.setVisAttributes(lcdd,x_layer.visStr()); - for(xml_coll_t j(x_layer,_X(slice)); j; ++j, ++s_num) { - xml_comp_t x_slice = j; - double thick = x_slice.thickness(); - Material mat = lcdd.material(x_slice.materialStr()); - string s_nam = l_nam+_toString(s_num,"_slice%d"); - Tube s_tub(lcdd,s_nam,rmin,rmax,2*M_PI); - Volume s_vol(lcdd,s_nam+"_volume", s_tub, mat); + for(xml_coll_t j(x_layer,_X(slice)); j; ++j) { + double thickness = xml_comp_t(j).thickness(); + layerWidth += thickness; + } + l_vol.setVisAttributes(lcdd,x_layer.visStr()); + for(xml_coll_t j(x_layer,_X(slice)); j; ++j, ++s_num) { + xml_comp_t x_slice = j; + double thick = x_slice.thickness(); + Material mat = lcdd.material(x_slice.materialStr()); + string s_nam = l_nam+_toString(s_num,"_slice%d"); + Tube s_tub(lcdd,s_nam,rmin,rmax,2*M_PI); + Volume s_vol(lcdd,s_nam+"_volume", s_tub, mat); - if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); - s_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); + s_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); - PlacedVolume spv = l_vol.placeVolume(s_vol,Position(0,0,z-zmin-layerWidth/2+thick/2)); - spv.addPhysVolID(_X(layer),l_num); - spv.addPhysVolID(_X(slice),s_num); - } + PlacedVolume spv = l_vol.placeVolume(s_vol,Position(0,0,z-zmin-layerWidth/2+thick/2)); + spv.addPhysVolID(_X(layer),l_num); + spv.addPhysVolID(_X(slice),s_num); + } - PlacedVolume lpv = motherVol.placeVolume(l_vol,Position(0,0,zmin+layerWidth/2.)); - lpv.addPhysVolID(_X(system),sdet.id()); - lpv.addPhysVolID(_X(barrel),1); - DetElement layer(lcdd,l_nam,det_type+"/Layer",l_num); - sdet.add(layer.addPlacement(lpv)); - if ( reflect ) { - PlacedVolume lpvR = motherVol.placeVolume(l_vol,Position(0,0,-zmin-layerWidth/2),ReflectRot()); - lpvR.addPhysVolID(_X(system),sdet.id()); - lpvR.addPhysVolID(_X(barrel),2); - DetElement layerR(lcdd,l_nam+"_reflect",det_type+"/Layer",l_num); - sdet.add(layerR.addPlacement(lpvR)); - } + PlacedVolume lpv = motherVol.placeVolume(l_vol,Position(0,0,zmin+layerWidth/2.)); + lpv.addPhysVolID(_X(system),sdet.id()); + lpv.addPhysVolID(_X(barrel),1); + DetElement layer(lcdd,l_nam,det_type+"/Layer",l_num); + sdet.add(layer.addPlacement(lpv)); + if ( reflect ) { + PlacedVolume lpvR = motherVol.placeVolume(l_vol,Position(0,0,-zmin-layerWidth/2),ReflectRot()); + lpvR.addPhysVolID(_X(system),sdet.id()); + lpvR.addPhysVolID(_X(barrel),2); + DetElement layerR(lcdd,l_nam+"_reflect",det_type+"/Layer",l_num); + sdet.add(layerR.addPlacement(lpvR)); } - sdet.setCombineHits(x_det.attr<bool>(_A(combineHits)),sens); - return sdet; } -}} + sdet.setCombineHits(x_det.attr<bool>(_A(combineHits)),sens); + return sdet; +} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,DiskTracker); +DECLARE_DETELEMENT(DiskTracker,create_detector); diff --git a/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp b/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp index c3cafd1268d3d4f875ec07ed42e11e2b9b8f5e19..7f0fb57ff8cadee1ce4ce9f6c90afe809e1f99ba 100644 --- a/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp +++ b/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp @@ -6,9 +6,7 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" #include "XML/Layering.h" #include "TGeoTrd2.h" @@ -16,151 +14,148 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<EcalBarrel>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - static double tolerance = 0e0; - Layering layering (e); - xml_det_t x_det = e; - Material air = lcdd.air(); - Material vacuum = lcdd.vacuum(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - xml_comp_t x_staves = x_det.child(_X(staves)); - xml_comp_t x_dim = x_det.child(_X(dimensions)); - int nsides = x_dim.numsides(); - double inner_r = x_dim.rmin(); - double dphi = 2*M_PI / nsides; - double hphi = dphi/2; - double mod_z = layering.totalThickness(); - double outer_r = inner_r + mod_z; - double totThick = mod_z; - DetElement sdet (lcdd,det_name,det_type,det_id); - Volume motherVol = lcdd.pickMotherVolume(sdet); - PolyhedraRegular hedra(lcdd,det_name+"_polyhedra",nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z()); - Volume envelope (lcdd,det_name+"_envelope",hedra,air); - PlacedVolume env_phv = motherVol.placeVolume(envelope,Rotation(0,0,M_PI/nsides)); - - env_phv.addPhysVolID("system",det_id); - env_phv.addPhysVolID("barrel",0); - sdet.addPlacement(env_phv); - - double dx = mod_z / std::sin(dphi); // dx per layer - dx = 0; +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + static double tolerance = 0e0; + Layering layering (e); + xml_det_t x_det = e; + Material air = lcdd.air(); + Material vacuum = lcdd.vacuum(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + xml_comp_t x_staves = x_det.child(_X(staves)); + xml_comp_t x_dim = x_det.child(_X(dimensions)); + int nsides = x_dim.numsides(); + double inner_r = x_dim.rmin(); + double dphi = 2*M_PI / nsides; + double hphi = dphi/2; + double mod_z = layering.totalThickness(); + double outer_r = inner_r + mod_z; + double totThick = mod_z; + DetElement sdet (lcdd,det_name,det_type,det_id); + Volume motherVol = lcdd.pickMotherVolume(sdet); + PolyhedraRegular hedra(lcdd,det_name+"_polyhedra",nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z()); + Volume envelope (lcdd,det_name+"_envelope",hedra,air); + PlacedVolume env_phv = motherVol.placeVolume(envelope,Rotation(0,0,M_PI/nsides)); + + env_phv.addPhysVolID("system",det_id); + env_phv.addPhysVolID("barrel",0); + sdet.addPlacement(env_phv); + + double dx = mod_z / std::sin(dphi); // dx per layer + dx = 0; - // Compute the top and bottom face measurements. - double trd_x2 = (2 * std::tan(hphi) * outer_r - dx)/2 - tolerance; - double trd_x1 = (2 * std::tan(hphi) * inner_r + dx)/2 - tolerance; - double trd_y1 = x_dim.z()/2 - tolerance; - double trd_y2 = trd_y1; - double trd_z = mod_z/2 - tolerance; + // Compute the top and bottom face measurements. + double trd_x2 = (2 * std::tan(hphi) * outer_r - dx)/2 - tolerance; + double trd_x1 = (2 * std::tan(hphi) * inner_r + dx)/2 - tolerance; + double trd_y1 = x_dim.z()/2 - tolerance; + double trd_y2 = trd_y1; + double trd_z = mod_z/2 - tolerance; - // Create the trapezoid for the stave. - Trapezoid trd(lcdd,det_name + "_module_trd", - trd_x1, // Outer side, i.e. the "short" X side. - trd_x2, // Inner side, i.e. the "long" X side. - trd_y1, // Corresponds to subdetector (or module) Z. - trd_y2, // - trd_z); // Thickness, in Y for top stave, when rotated. - - Volume mod_vol(lcdd,det_name+"_module",trd,air); - - { // ===== buildBarrelStave(lcdd, sens, module_volume) ===== - // Parameters for computing the layer X dimension: - double stave_z = trd_y1/2; - double l_dim_x = trd_x1/2; // Starting X dimension for the layer. - double adj = (l_dim_x-trd_x2/2)/2; // Adjacent angle of triangle. - double hyp = std::sqrt(trd_z*trd_z/4 + adj*adj); // Hypotenuse of triangle. - double beta = std::acos(adj / hyp); // Lower-right angle of triangle. - double tan_beta = std::tan(beta); // Primary coefficient for figuring X. - double l_pos_z = -(layering.totalThickness() / 2); - - // Loop over the sets of layer elements in the detector. - int l_num = 0; - for(xml_coll_t li(x_det,_X(layer)); li; ++li) { - xml_comp_t x_layer = li; - int repeat = x_layer.repeat(); - // Loop over number of repeats for this layer. - for (int j=0; j<repeat; j++) { - string l_name = det_name + _toString(l_num,"_layer%d"); - double l_thickness = layering.layer(l_num)->thickness(); // Layer's thickness. - double xcut = (l_thickness / tan_beta); // X dimension for this layer. - l_dim_x -= xcut/2; - - Position l_pos(0,0,l_pos_z+l_thickness/2); // Position of the layer. - Box l_box(lcdd,l_name+"_box",l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance); - Volume l_vol(lcdd,l_name,l_box,air); - DetElement layer(lcdd,l_name,det_type+"/Layer",det_id); - - sdet.add(layer); - // Loop over the sublayers or slices for this layer. - int s_num = 0; - double s_pos_z = -(l_thickness / 2); - for(xml_coll_t si(x_layer,_X(slice)); si; ++si) { - xml_comp_t x_slice = si; - string s_name = l_name + _toString(s_num,"_slice%d"); - double s_thick = x_slice.thickness(); - Box s_box(lcdd,s_name+"_box",l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance); - Volume s_vol(lcdd,s_name,s_box,lcdd.material(x_slice.materialStr())); - DetElement slice(lcdd,s_name,det_type+"/Layer/Slice",det_id); - - layer.add(slice); - if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); + // Create the trapezoid for the stave. + Trapezoid trd(lcdd,det_name + "_module_trd", + trd_x1, // Outer side, i.e. the "short" X side. + trd_x2, // Inner side, i.e. the "long" X side. + trd_y1, // Corresponds to subdetector (or module) Z. + trd_y2, // + trd_z); // Thickness, in Y for top stave, when rotated. + + Volume mod_vol(lcdd,det_name+"_module",trd,air); + + { // ===== buildBarrelStave(lcdd, sens, module_volume) ===== + // Parameters for computing the layer X dimension: + double stave_z = trd_y1/2; + double l_dim_x = trd_x1/2; // Starting X dimension for the layer. + double adj = (l_dim_x-trd_x2/2)/2; // Adjacent angle of triangle. + double hyp = std::sqrt(trd_z*trd_z/4 + adj*adj); // Hypotenuse of triangle. + double beta = std::acos(adj / hyp); // Lower-right angle of triangle. + double tan_beta = std::tan(beta); // Primary coefficient for figuring X. + double l_pos_z = -(layering.totalThickness() / 2); + + // Loop over the sets of layer elements in the detector. + int l_num = 0; + for(xml_coll_t li(x_det,_X(layer)); li; ++li) { + xml_comp_t x_layer = li; + int repeat = x_layer.repeat(); + // Loop over number of repeats for this layer. + for (int j=0; j<repeat; j++) { + string l_name = det_name + _toString(l_num,"_layer%d"); + double l_thickness = layering.layer(l_num)->thickness(); // Layer's thickness. + double xcut = (l_thickness / tan_beta); // X dimension for this layer. + l_dim_x -= xcut/2; + + Position l_pos(0,0,l_pos_z+l_thickness/2); // Position of the layer. + Box l_box(lcdd,l_name+"_box",l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance); + Volume l_vol(lcdd,l_name,l_box,air); + DetElement layer(lcdd,l_name,det_type+"/Layer",det_id); + + sdet.add(layer); + // Loop over the sublayers or slices for this layer. + int s_num = 0; + double s_pos_z = -(l_thickness / 2); + for(xml_coll_t si(x_layer,_X(slice)); si; ++si) { + xml_comp_t x_slice = si; + string s_name = l_name + _toString(s_num,"_slice%d"); + double s_thick = x_slice.thickness(); + Box s_box(lcdd,s_name+"_box",l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance); + Volume s_vol(lcdd,s_name,s_box,lcdd.material(x_slice.materialStr())); + DetElement slice(lcdd,s_name,det_type+"/Layer/Slice",det_id); + + layer.add(slice); + if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); - slice.setAttributes(lcdd,s_vol,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); - - // Slice placement. - PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z+s_thick/2)); - slice_phv.addPhysVolID("layer", l_num); - slice_phv.addPhysVolID("slice", s_num); - slice.addPlacement(slice_phv); - // Increment Z position of slice. - s_pos_z += s_thick; + slice.setAttributes(lcdd,s_vol,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + + // Slice placement. + PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z+s_thick/2)); + slice_phv.addPhysVolID("layer", l_num); + slice_phv.addPhysVolID("slice", s_num); + slice.addPlacement(slice_phv); + // Increment Z position of slice. + s_pos_z += s_thick; - // Increment slice number. - ++s_num; - } - - // Set region, limitset, and vis of layer. - layer.setAttributes(lcdd,l_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); - - PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos); - layer_phv.addPhysVolID("layer", l_num); - layer.addPlacement(layer_phv); - // Increment to next layer Z position. - l_pos_z += l_thickness; - ++l_num; - } + // Increment slice number. + ++s_num; + } + + // Set region, limitset, and vis of layer. + layer.setAttributes(lcdd,l_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + + PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos); + layer_phv.addPhysVolID("layer", l_num); + layer.addPlacement(layer_phv); + // Increment to next layer Z position. + l_pos_z += l_thickness; + ++l_num; } } + } - // Set stave visualization. - if (x_staves) { - mod_vol.setVisAttributes(lcdd.visAttributes(x_staves.visStr())); - } - // Phi start for a stave. - double phi = M_PI / nsides; - double mod_x_off = dx / 2; // Stave X offset, derived from the dx. - double mod_y_off = inner_r + mod_z/2; // Stave Y offset - - // Create nsides staves. - for (int i = 0; i < nsides; i++, phi -= dphi) { // i is module number - // Compute the stave position - double m_pos_x = mod_x_off * std::cos(phi) - mod_y_off * std::sin(phi); - double m_pos_y = mod_x_off * std::sin(phi) + mod_y_off * std::cos(phi); - PlacedVolume pv = envelope.placeVolume(mod_vol, - Position(-m_pos_x,-m_pos_y,0), - Rotation(M_PI*0.5,phi,0)); - pv.addPhysVolID("module",i); - pv.addPhysVolID("system",det_id); - pv.addPhysVolID("barrel",0); - } - - // Set envelope volume attributes. - envelope.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); - return sdet; + // Set stave visualization. + if (x_staves) { + mod_vol.setVisAttributes(lcdd.visAttributes(x_staves.visStr())); + } + // Phi start for a stave. + double phi = M_PI / nsides; + double mod_x_off = dx / 2; // Stave X offset, derived from the dx. + double mod_y_off = inner_r + mod_z/2; // Stave Y offset + + // Create nsides staves. + for (int i = 0; i < nsides; i++, phi -= dphi) { // i is module number + // Compute the stave position + double m_pos_x = mod_x_off * std::cos(phi) - mod_y_off * std::sin(phi); + double m_pos_y = mod_x_off * std::sin(phi) + mod_y_off * std::cos(phi); + PlacedVolume pv = envelope.placeVolume(mod_vol, + Position(-m_pos_x,-m_pos_y,0), + Rotation(M_PI*0.5,phi,0)); + pv.addPhysVolID("module",i); + pv.addPhysVolID("system",det_id); + pv.addPhysVolID("barrel",0); } -}} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,EcalBarrel); + // Set envelope volume attributes. + envelope.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + return sdet; +} + +DECLARE_DETELEMENT(EcalBarrel,create_detector); diff --git a/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp b/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp index 7d0e9b2d75ae511b5094be33d857accf79aa2adf..2f2b05a0de22bf9aedaa0371b8b6c13e0b2a38f4 100644 --- a/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp +++ b/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp @@ -6,179 +6,175 @@ // Author : M.Frank // //==================================================================== - #include "XML/Layering.h" #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<ForwardDetector>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - xml_dim_t dim = x_det.dimensions(); - bool reflect = x_det.reflect(); - xml_comp_t beam = x_det.child(_X(beampipe)); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - int id = x_det.id(); - Material air = lcdd.air(); - DetElement sdet (lcdd,det_name,det_type,x_det.id()); - Layering layering(x_det); - - Volume motherVol = lcdd.pickMotherVolume(sdet); - - double rmax = dim.outer_r(); - double rmin = dim.inner_r(); - double zinner = dim.inner_z(); - double outgoingR = beam.outgoing_r(); - double incomingR = beam.incoming_r(); - double xangle = beam.crossing_angle(); - double xangleHalf = xangle / 2; - double thickness = layering.totalThickness(); - double zpos = zinner + (thickness / 2); - //double zouter = zinner + thickness; - // Beampipe position in envelope. - double beamPosX = std::tan(xangleHalf) * zpos; - - // Detector envelope solid. - Tube envelopeTube(lcdd,det_name+"_tube",rmin,rmax,thickness); - - // First envelope bool subtracion of outgoing beampipe. - // Incoming beampipe solid. - Tube beamInTube(lcdd,det_name + "_beampipe_incoming_tube",0,outgoingR,thickness * 2); - // Position of incoming beampipe. - Position beamInPos(beamPosX,0,0); - /// Rotation of incoming beampipe. - Rotation beamInRot(0,xangleHalf,0); - - // Second envelope bool subtracion of outgoing beampipe. - // Outgoing beampipe solid. - Tube beamOutTube(lcdd,det_name + "_beampipe_outgoing_tube",0,incomingR,thickness * 2); - // Position of outgoing beampipe. - Position beamOutPos(-beamPosX,0,0); - // Rotation of outgoing beampipe. - Rotation beamOutRot(0,-xangleHalf,0); - - // First envelope bool subtraction of incoming beampipe. - SubtractionSolid envelopeSubtraction1(lcdd,det_name+"_subtraction1_tube", - envelopeTube,beamInTube,beamInPos,beamInRot); - SubtractionSolid envelopeSubtraction2(lcdd,det_name+"_subtraction2_tube", - envelopeSubtraction1,beamOutTube,beamOutPos,beamOutRot); - - // Final envelope bool volume. - Volume envelopeVol(lcdd,det_name + "_envelope_volume", envelopeSubtraction2, air); - - // Process each layer element. - double layerPosZ = -thickness / 2; - double layerDisplZ = 0; - for(xml_coll_t c(x_det,XML::Tag_layer); c; ++c) { - xml_comp_t x_layer = c; - double layerThickness = layering.singleLayerThickness(x_layer); - - // Create tube envelope for this layer, which can be reused in bool definition - // in the repeat loop below. - Tube layerTube(lcdd, det_name + "_layer_tube",rmin,rmax,layerThickness); - - for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0) { - string layer_nam = det_name + _toString(i,"_layer%d"); - // Increment to new layer position. - layerDisplZ += layerThickness / 2; - layerPosZ += layerThickness / 2; - - // First layer subtraction solid. - DetElement layer(lcdd,layer_nam,"ForwardDetector/Layer",sdet.id()); - double layerGlobalZ = zinner + layerDisplZ; - double layerPosX = tan(xangleHalf) * layerGlobalZ; - Position layerSubtraction1Pos( layerPosX,0,0); - Position layerSubtraction2Pos(-layerPosX,0,0); - - SubtractionSolid layerSubtraction1(lcdd,layer_nam + "_subtraction1", - layerTube,beamInTube,layerSubtraction1Pos,beamInRot); - // Second layer subtraction solid. - SubtractionSolid layerSubtraction2(lcdd,layer_nam + "_subtraction2", - layerSubtraction1,beamOutTube,layerSubtraction2Pos,beamOutRot); - // Layer LV. - Volume layerVol(lcdd,layer_nam + "_volume", layerSubtraction2, air); +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + xml_dim_t dim = x_det.dimensions(); + bool reflect = x_det.reflect(); + xml_comp_t beam = x_det.child(_X(beampipe)); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + int id = x_det.id(); + Material air = lcdd.air(); + DetElement sdet (lcdd,det_name,det_type,x_det.id()); + Layering layering(x_det); + + Volume motherVol = lcdd.pickMotherVolume(sdet); + + double rmax = dim.outer_r(); + double rmin = dim.inner_r(); + double zinner = dim.inner_z(); + double outgoingR = beam.outgoing_r(); + double incomingR = beam.incoming_r(); + double xangle = beam.crossing_angle(); + double xangleHalf = xangle / 2; + double thickness = layering.totalThickness(); + double zpos = zinner + (thickness / 2); + //double zouter = zinner + thickness; + // Beampipe position in envelope. + double beamPosX = std::tan(xangleHalf) * zpos; + + // Detector envelope solid. + Tube envelopeTube(lcdd,det_name+"_tube",rmin,rmax,thickness); + + // First envelope bool subtracion of outgoing beampipe. + // Incoming beampipe solid. + Tube beamInTube(lcdd,det_name + "_beampipe_incoming_tube",0,outgoingR,thickness * 2); + // Position of incoming beampipe. + Position beamInPos(beamPosX,0,0); + /// Rotation of incoming beampipe. + Rotation beamInRot(0,xangleHalf,0); + + // Second envelope bool subtracion of outgoing beampipe. + // Outgoing beampipe solid. + Tube beamOutTube(lcdd,det_name + "_beampipe_outgoing_tube",0,incomingR,thickness * 2); + // Position of outgoing beampipe. + Position beamOutPos(-beamPosX,0,0); + // Rotation of outgoing beampipe. + Rotation beamOutRot(0,-xangleHalf,0); + + // First envelope bool subtraction of incoming beampipe. + SubtractionSolid envelopeSubtraction1(lcdd,det_name+"_subtraction1_tube", + envelopeTube,beamInTube,beamInPos,beamInRot); + SubtractionSolid envelopeSubtraction2(lcdd,det_name+"_subtraction2_tube", + envelopeSubtraction1,beamOutTube,beamOutPos,beamOutRot); + + // Final envelope bool volume. + Volume envelopeVol(lcdd,det_name + "_envelope_volume", envelopeSubtraction2, air); + + // Process each layer element. + double layerPosZ = -thickness / 2; + double layerDisplZ = 0; + for(xml_coll_t c(x_det,XML::Tag_layer); c; ++c) { + xml_comp_t x_layer = c; + double layerThickness = layering.singleLayerThickness(x_layer); + + // Create tube envelope for this layer, which can be reused in bool definition + // in the repeat loop below. + Tube layerTube(lcdd, det_name + "_layer_tube",rmin,rmax,layerThickness); + + for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0) { + string layer_nam = det_name + _toString(i,"_layer%d"); + // Increment to new layer position. + layerDisplZ += layerThickness / 2; + layerPosZ += layerThickness / 2; + + // First layer subtraction solid. + DetElement layer(lcdd,layer_nam,"ForwardDetector/Layer",sdet.id()); + double layerGlobalZ = zinner + layerDisplZ; + double layerPosX = tan(xangleHalf) * layerGlobalZ; + Position layerSubtraction1Pos( layerPosX,0,0); + Position layerSubtraction2Pos(-layerPosX,0,0); + + SubtractionSolid layerSubtraction1(lcdd,layer_nam + "_subtraction1", + layerTube,beamInTube,layerSubtraction1Pos,beamInRot); + // Second layer subtraction solid. + SubtractionSolid layerSubtraction2(lcdd,layer_nam + "_subtraction2", + layerSubtraction1,beamOutTube,layerSubtraction2Pos,beamOutRot); + // Layer LV. + Volume layerVol(lcdd,layer_nam + "_volume", layerSubtraction2, air); - // Slice loop. - int sliceCount = 0; - double slicePosZ = -layerThickness / 2; - double sliceDisplZ = 0; - for(xml_coll_t l(x_layer,XML::Tag_slice); l; ++l, ++m) { - xml_comp_t x_slice = l; - string slice_nam = layer_nam + _toString(sliceCount,"_slice%d"); - /** Get slice parameters. */ - double sliceThickness = x_slice.thickness(); - Material slice_mat = lcdd.material(x_slice.materialStr()); - - // Go to mid of this slice. - sliceDisplZ += sliceThickness / 2; - slicePosZ += sliceThickness / 2; - - // Slice's basic tube. - Tube sliceTube(lcdd, slice_nam + "_tube", rmin,rmax,sliceThickness); - DetElement slice(lcdd,slice_nam,"ForwardDetector/Layer/Slice",sdet.id()); - double sliceGlobalZ = zinner + (layerDisplZ - layerThickness / 2) + sliceDisplZ; - double slicePosX = std::tan(xangleHalf) * sliceGlobalZ; - - // First slice subtraction solid. - SubtractionSolid sliceSubtraction1(lcdd,slice_nam + "_subtraction1", - sliceTube,beamInTube,Position(slicePosX,0,0),beamInRot); - // Second slice subtraction solid. - SubtractionSolid sliceSubtraction2(lcdd,slice_nam + "_subtraction2", - sliceSubtraction1,beamOutTube,Position(-slicePosX,0,0),beamOutRot); - // Slice LV. - Volume sliceVol(lcdd,slice_nam + "_volume", sliceSubtraction2, slice_mat); + // Slice loop. + int sliceCount = 0; + double slicePosZ = -layerThickness / 2; + double sliceDisplZ = 0; + for(xml_coll_t l(x_layer,XML::Tag_slice); l; ++l, ++m) { + xml_comp_t x_slice = l; + string slice_nam = layer_nam + _toString(sliceCount,"_slice%d"); + /** Get slice parameters. */ + double sliceThickness = x_slice.thickness(); + Material slice_mat = lcdd.material(x_slice.materialStr()); + + // Go to mid of this slice. + sliceDisplZ += sliceThickness / 2; + slicePosZ += sliceThickness / 2; + + // Slice's basic tube. + Tube sliceTube(lcdd, slice_nam + "_tube", rmin,rmax,sliceThickness); + DetElement slice(lcdd,slice_nam,"ForwardDetector/Layer/Slice",sdet.id()); + double sliceGlobalZ = zinner + (layerDisplZ - layerThickness / 2) + sliceDisplZ; + double slicePosX = std::tan(xangleHalf) * sliceGlobalZ; + + // First slice subtraction solid. + SubtractionSolid sliceSubtraction1(lcdd,slice_nam + "_subtraction1", + sliceTube,beamInTube,Position(slicePosX,0,0),beamInRot); + // Second slice subtraction solid. + SubtractionSolid sliceSubtraction2(lcdd,slice_nam + "_subtraction2", + sliceSubtraction1,beamOutTube,Position(-slicePosX,0,0),beamOutRot); + // Slice LV. + Volume sliceVol(lcdd,slice_nam + "_volume", sliceSubtraction2, slice_mat); - if ( x_slice.isSensitive() ) sliceVol.setSensitiveDetector(sens); - // Set attributes of slice - slice.setAttributes(lcdd, sliceVol, - x_slice.attr<string>(_A(region)), - x_slice.attr<string>(_A(limits)), - x_slice.visStr()); - - // Place volume in layer - layerVol.placeVolume(sliceVol,Position(0,0,slicePosZ)); - layer.add(slice); - - // Start of next slice. - sliceDisplZ += sliceThickness / 2; - slicePosZ += sliceThickness / 2; - ++sliceCount; - } + if ( x_slice.isSensitive() ) sliceVol.setSensitiveDetector(sens); // Set attributes of slice - layer.setAttributes(lcdd, layerVol, - x_layer.attr<string>(_A(region)), - x_layer.attr<string>(_A(limits)), - x_layer.visStr()); - - // Layer PV. - PlacedVolume layerPV = envelopeVol.placeVolume(layerVol,Position(0,0,layerPosZ)); - layerPV.addPhysVolID(_X(layer), i); - sdet.add(layer); - - // Increment to start of next layer. - layerDisplZ += layerThickness / 2; - layerPosZ += layerThickness / 2; + slice.setAttributes(lcdd, sliceVol, + x_slice.attr<string>(_A(region)), + x_slice.attr<string>(_A(limits)), + x_slice.visStr()); + + // Place volume in layer + layerVol.placeVolume(sliceVol,Position(0,0,slicePosZ)); + layer.add(slice); + + // Start of next slice. + sliceDisplZ += sliceThickness / 2; + slicePosZ += sliceThickness / 2; + ++sliceCount; } + // Set attributes of slice + layer.setAttributes(lcdd, layerVol, + x_layer.attr<string>(_A(region)), + x_layer.attr<string>(_A(limits)), + x_layer.visStr()); + + // Layer PV. + PlacedVolume layerPV = envelopeVol.placeVolume(layerVol,Position(0,0,layerPosZ)); + layerPV.addPhysVolID(_X(layer), i); + sdet.add(layer); + + // Increment to start of next layer. + layerDisplZ += layerThickness / 2; + layerPosZ += layerThickness / 2; } - sdet.setVisAttributes(lcdd, x_det.visStr(), envelopeVol); + } + sdet.setVisAttributes(lcdd, x_det.visStr(), envelopeVol); - PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,Position(0,0,zpos)); - env_phv.addPhysVolID(_X(system), id); - env_phv.addPhysVolID(_X(barrel), 1); + PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,Position(0,0,zpos)); + env_phv.addPhysVolID(_X(system), id); + env_phv.addPhysVolID(_X(barrel), 1); - // Reflect it. - if ( reflect ) { - env_phv = motherVol.placeVolume(envelopeVol,Position(0,0,-zpos),ReflectRot()); - env_phv.addPhysVolID(_X(system), id); - env_phv.addPhysVolID(_X(barrel), 2); - } - return sdet; + // Reflect it. + if ( reflect ) { + env_phv = motherVol.placeVolume(envelopeVol,Position(0,0,-zpos),ReflectRot()); + env_phv.addPhysVolID(_X(system), id); + env_phv.addPhysVolID(_X(barrel), 2); } -}} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,ForwardDetector); + return sdet; +} + +DECLARE_DETELEMENT(ForwardDetector,create_detector); diff --git a/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp b/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp index 093aa9ac1cbb7313998e53797b40c31521042698..f29dc92c1328b132021c1e751b54f845fe297242 100644 --- a/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp +++ b/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp @@ -6,62 +6,57 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<MultiLayerTracker>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - Material air = lcdd.air(); - DetElement sdet(lcdd,det_name,det_type,x_det.id()); - Volume motherVol = lcdd.pickMotherVolume(sdet); - int n = 0; +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + Material air = lcdd.air(); + DetElement sdet(lcdd,det_name,det_type,x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + int n = 0; - for(xml_coll_t i(x_det,_X(layer)); i; ++i, ++n) { - xml_comp_t x_layer = i; - string l_name = det_name+_toString(n,"_layer%d"); - DetElement layer(lcdd,l_name,"MultiLayerTracker/Layer",x_layer.id()); - Tube l_tub(lcdd,l_name); - Volume l_vol(lcdd,l_name+"_volume",l_tub,air); - double z = x_layer.outer_z(); - double rmin = x_layer.inner_r(); - double r = rmin; - int m = 0; + for(xml_coll_t i(x_det,_X(layer)); i; ++i, ++n) { + xml_comp_t x_layer = i; + string l_name = det_name+_toString(n,"_layer%d"); + DetElement layer(lcdd,l_name,"MultiLayerTracker/Layer",x_layer.id()); + Tube l_tub(lcdd,l_name); + Volume l_vol(lcdd,l_name+"_volume",l_tub,air); + double z = x_layer.outer_z(); + double rmin = x_layer.inner_r(); + double r = rmin; + int m = 0; - for(xml_coll_t j(x_layer,_X(slice)); j; ++j, ++m) { - xml_comp_t x_slice = j; - Material mat = lcdd.material(x_slice.materialStr()); - string s_name= l_name+_toString(m,"_slice%d"); - Tube s_tub(lcdd,s_name); - Volume s_vol(lcdd,s_name+"_volume", s_tub, mat); + for(xml_coll_t j(x_layer,_X(slice)); j; ++j, ++m) { + xml_comp_t x_slice = j; + Material mat = lcdd.material(x_slice.materialStr()); + string s_name= l_name+_toString(m,"_slice%d"); + Tube s_tub(lcdd,s_name); + Volume s_vol(lcdd,s_name+"_volume", s_tub, mat); - r += x_slice.thickness(); - s_tub.setDimensions(r,r,2*z,2*M_PI); - if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); - // Set Attributes - s_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); - PlacedVolume spv = l_vol.placeVolume(s_vol,IdentityPos()); - // Slices have no extra id. Take the ID of the layer! - spv.addPhysVolID(_X(layer),n); - } - l_tub.setDimensions(rmin,r,2*z,2*M_PI); - l_vol.setVisAttributes(lcdd,x_layer.visStr()); - - PlacedVolume lpv = motherVol.placeVolume(l_vol,IdentityPos()); - lpv.addPhysVolID(_X(system),sdet.id()).addPhysVolID(_X(barrel),0); - sdet.add(layer.addPlacement(lpv)); + r += x_slice.thickness(); + s_tub.setDimensions(r,r,2*z,2*M_PI); + if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); + // Set Attributes + s_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + PlacedVolume spv = l_vol.placeVolume(s_vol,IdentityPos()); + // Slices have no extra id. Take the ID of the layer! + spv.addPhysVolID(_X(layer),n); } - sdet.setCombineHits(x_det.attr<bool>(_A(combineHits)),sens); - return sdet; + l_tub.setDimensions(rmin,r,2*z,2*M_PI); + l_vol.setVisAttributes(lcdd,x_layer.visStr()); + + PlacedVolume lpv = motherVol.placeVolume(l_vol,IdentityPos()); + lpv.addPhysVolID(_X(system),sdet.id()).addPhysVolID(_X(barrel),0); + sdet.add(layer.addPlacement(lpv)); } -}} + sdet.setCombineHits(x_det.attr<bool>(_A(combineHits)),sens); + return sdet; +} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,MultiLayerTracker); +DECLARE_DETELEMENT(MultiLayerTracker,create_detector); diff --git a/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp b/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp index 403ec19eb918de8e9933cc15950843d2c559ab09..fc6d036d0355b6c091005f91f2c8bf9c8f610b58 100644 --- a/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp +++ b/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp @@ -6,40 +6,35 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<PolyconeSupport>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector&) { - xml_det_t x_det = e; - string name = x_det.nameStr(); - DetElement sdet (lcdd,name,x_det.typeStr(),x_det.id()); - Polycone cone (lcdd,name+"_envelope_polycone"); - Material mat (lcdd.material(x_det.materialStr())); - Volume volume (lcdd,name+"_envelope_volume", cone, mat); - vector<double> rmin,rmax,z; - int num = 0; +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector&) { + xml_det_t x_det = e; + string name = x_det.nameStr(); + DetElement sdet (lcdd,name,x_det.typeStr(),x_det.id()); + Polycone cone (lcdd,name+"_envelope_polycone"); + Material mat (lcdd.material(x_det.materialStr())); + Volume volume (lcdd,name+"_envelope_volume", cone, mat); + vector<double> rmin,rmax,z; + int num = 0; - for(xml_coll_t c(e,_X(zplane)); c; ++c, ++num) { - xml_comp_t dim(c); - rmin.push_back(dim.rmin()); - rmax.push_back(dim.rmax()); - z.push_back(dim.z()/2); - } - if ( num < 2 ) { - throw runtime_error("PolyCone["+name+"]> Not enough Z planes. minimum is 2!"); - } - cone.addZPlanes(rmin,rmax,z); - volume.setVisAttributes(lcdd, x_det.visStr()); - sdet.addPlacement(lcdd.pickMotherVolume(sdet).placeVolume(volume)); - return sdet; + for(xml_coll_t c(e,_X(zplane)); c; ++c, ++num) { + xml_comp_t dim(c); + rmin.push_back(dim.rmin()); + rmax.push_back(dim.rmax()); + z.push_back(dim.z()/2); + } + if ( num < 2 ) { + throw runtime_error("PolyCone["+name+"]> Not enough Z planes. minimum is 2!"); } -}} + cone.addZPlanes(rmin,rmax,z); + volume.setVisAttributes(lcdd, x_det.visStr()); + sdet.addPlacement(lcdd.pickMotherVolume(sdet).placeVolume(volume)); + return sdet; +} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,PolyconeSupport); +DECLARE_DETELEMENT(PolyconeSupport,create_detector); diff --git a/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp b/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp index ce5b357fba6835cebb94f4f5420f3bcd272160a0..ba18c07a3f5f7482e9e205d808401cb48fe3cb25 100644 --- a/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp +++ b/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp @@ -6,177 +6,173 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" #include "XML/Layering.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - static void placeStaves(double rmin, - int numsides, - double total_thickness, - Volume envelopeVolume, - double innerAngle, - Volume sectVolume) - { - double innerRotation = innerAngle; - double offsetRotation = -innerRotation / 2; - double sectCenterRadius = rmin + total_thickness / 2; - double rotX = M_PI / 2; - double rotY = -offsetRotation; - double posX = -sectCenterRadius * std::sin(rotY); - double posY = sectCenterRadius * std::cos(rotY); - string nam = sectVolume.name(); - //numsides = 2; - for (int module = 0; module < numsides; ++module) { - PlacedVolume pv=envelopeVolume.placeVolume(sectVolume,Position(-posX,-posY,0),Rotation(rotX,rotY,0)); - pv.addPhysVolID(_X(stave), 0); - pv.addPhysVolID(_X(module),module); - - rotY -= innerRotation; - posX = -sectCenterRadius * std::sin(rotY); - posY = sectCenterRadius * std::cos(rotY); - } +static void placeStaves(double rmin, + int numsides, + double total_thickness, + Volume envelopeVolume, + double innerAngle, + Volume sectVolume) +{ + double innerRotation = innerAngle; + double offsetRotation = -innerRotation / 2; + double sectCenterRadius = rmin + total_thickness / 2; + double rotX = M_PI / 2; + double rotY = -offsetRotation; + double posX = -sectCenterRadius * std::sin(rotY); + double posY = sectCenterRadius * std::cos(rotY); + string nam = sectVolume.name(); + //numsides = 2; + for (int module = 0; module < numsides; ++module) { + PlacedVolume pv=envelopeVolume.placeVolume(sectVolume,Position(-posX,-posY,0),Rotation(rotX,rotY,0)); + pv.addPhysVolID(_X(stave), 0); + pv.addPhysVolID(_X(module),module); + + rotY -= innerRotation; + posX = -sectCenterRadius * std::sin(rotY); + posY = sectCenterRadius * std::cos(rotY); + } +} + +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + xml_comp_t staves = x_det.child(_X(staves)); + xml_dim_t dim = x_det.dimensions(); + + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + Material air = lcdd.air(); + Layering layering(x_det); + double totalThickness = layering.totalThickness(); + int totalRepeat = 0; + int totalSlices = 0; + double gap = xml_dim_t(x_det).gap(); + int numSides = dim.numsides(); + double detZ = dim.z(); + double rmin = dim.rmin(); + DetElement sdet(lcdd,det_name,det_type,x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + + cout << det_name << " Gap:" << gap << endl; + + for(xml_coll_t c(x_det,_X(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); + totalRepeat += repeat; + totalSlices += x_layer.numChildren(_X(slice)); } - template <> Ref_t DetElementFactory<PolyhedraBarrelCalorimeter2>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - xml_comp_t staves = x_det.child(_X(staves)); - xml_dim_t dim = x_det.dimensions(); - - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - Material air = lcdd.air(); - Layering layering(x_det); - double totalThickness = layering.totalThickness(); - int totalRepeat = 0; - int totalSlices = 0; - double gap = xml_dim_t(x_det).gap(); - int numSides = dim.numsides(); - double detZ = dim.z(); - double rmin = dim.rmin(); - DetElement sdet(lcdd,det_name,det_type,x_det.id()); - Volume motherVol = lcdd.pickMotherVolume(sdet); - - cout << det_name << " Gap:" << gap << endl; - - for(xml_coll_t c(x_det,_X(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - totalRepeat += repeat; - totalSlices += x_layer.numChildren(_X(slice)); - } - - PolyhedraRegular polyhedra(lcdd,det_name+"_polyhedra",numSides,rmin,rmin+totalThickness,detZ); - Volume envelopeVol(lcdd,det_name+"_envelope",polyhedra,air); - - // Add the subdetector envelope to the structure. - double innerAngle = 2*M_PI/numSides; - double halfInnerAngle = innerAngle/2; - double tan_inner = std::tan(halfInnerAngle) * 2; - double innerFaceLen = rmin * tan_inner; - double outerFaceLen = (rmin+totalThickness) * tan_inner; - double staveThickness = totalThickness; - - Trapezoid staveTrdOuter(lcdd,det_name+"_stave_trapezoid_outer", - innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2); - Volume staveOuterVol(lcdd,det_name+"_stave_outer",staveTrdOuter,air); - - Trapezoid staveTrdInner(lcdd,det_name+"_stave_trapezoid_inner", - innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2); - Volume staveInnerVol(lcdd,det_name+"_stave_inner",staveTrdInner,air); - - double layerOuterAngle = (M_PI-innerAngle)/2; - double layerInnerAngle = (M_PI/2 - layerOuterAngle); - double layer_pos_z = -(staveThickness / 2); - double layer_dim_x = innerFaceLen/2 - gap * 2; - int layer_num = 0; - - // Set envelope volume attributes. - envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); - - for(xml_coll_t c(x_det,_X(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); // Get number of times to repeat this layer. - const Layer* lay = layering.layer(layer_num); // Get the layer from the layering engine. - // Loop over repeats for this layer. - for (int j = 0; j < repeat; j++) { - string layer_name = det_name+_toString(layer_num,"_stave_layer%d"); - double layer_thickness = lay->thickness(); - DetElement layer(lcdd,layer_name,det_name+"/Layer",x_det.id()); - - // Layer position in Z within the stave. - layer_pos_z += layer_thickness / 2; - // Layer box. - Box layer_box(lcdd,layer_name+"_box", layer_dim_x, detZ/2, layer_thickness); - // Layer volume. - Volume layer_vol(lcdd,layer_name,layer_box,air); - - // Create the slices (sublayers) within the layer. - double slice_pos_z = -(layer_thickness / 2); - int slice_number = 0; - for(xml_coll_t k(x_layer,_X(slice)); k; ++k) { - xml_comp_t x_slice = k; - string slice_name = layer_name + _toString(slice_number,"_slice%d"); - double slice_thickness = x_slice.thickness(); - Material slice_material = lcdd.material(x_slice.materialStr()); - DetElement slice(lcdd,slice_name,det_name+"/Layer/Slice",x_det.id()); - - slice_pos_z += slice_thickness / 2; - // Slice box. - Box slice_box(lcdd,slice_name+"_box",layer_dim_x,detZ/2,slice_thickness); - - // Slice volume. - Volume slice_vol(lcdd,slice_name,slice_box,slice_material); - if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens); - // Set region, limitset, and vis. - slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); - // slice PlacedVolume - PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z)); - slice_phv.addPhysVolID(_X(slice),slice_number); - - layer.add(slice); - // Increment Z position for next slice. - slice_pos_z += slice_thickness / 2; - // Increment slice number. - ++slice_number; - } + PolyhedraRegular polyhedra(lcdd,det_name+"_polyhedra",numSides,rmin,rmin+totalThickness,detZ); + Volume envelopeVol(lcdd,det_name+"_envelope",polyhedra,air); + + // Add the subdetector envelope to the structure. + double innerAngle = 2*M_PI/numSides; + double halfInnerAngle = innerAngle/2; + double tan_inner = std::tan(halfInnerAngle) * 2; + double innerFaceLen = rmin * tan_inner; + double outerFaceLen = (rmin+totalThickness) * tan_inner; + double staveThickness = totalThickness; + + Trapezoid staveTrdOuter(lcdd,det_name+"_stave_trapezoid_outer", + innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2); + Volume staveOuterVol(lcdd,det_name+"_stave_outer",staveTrdOuter,air); + + Trapezoid staveTrdInner(lcdd,det_name+"_stave_trapezoid_inner", + innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2); + Volume staveInnerVol(lcdd,det_name+"_stave_inner",staveTrdInner,air); + + double layerOuterAngle = (M_PI-innerAngle)/2; + double layerInnerAngle = (M_PI/2 - layerOuterAngle); + double layer_pos_z = -(staveThickness / 2); + double layer_dim_x = innerFaceLen/2 - gap * 2; + int layer_num = 0; + + // Set envelope volume attributes. + envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + for(xml_coll_t c(x_det,_X(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); // Get number of times to repeat this layer. + const Layer* lay = layering.layer(layer_num); // Get the layer from the layering engine. + // Loop over repeats for this layer. + for (int j = 0; j < repeat; j++) { + string layer_name = det_name+_toString(layer_num,"_stave_layer%d"); + double layer_thickness = lay->thickness(); + DetElement layer(lcdd,layer_name,det_name+"/Layer",x_det.id()); + + // Layer position in Z within the stave. + layer_pos_z += layer_thickness / 2; + // Layer box. + Box layer_box(lcdd,layer_name+"_box", layer_dim_x, detZ/2, layer_thickness); + // Layer volume. + Volume layer_vol(lcdd,layer_name,layer_box,air); + + // Create the slices (sublayers) within the layer. + double slice_pos_z = -(layer_thickness / 2); + int slice_number = 0; + for(xml_coll_t k(x_layer,_X(slice)); k; ++k) { + xml_comp_t x_slice = k; + string slice_name = layer_name + _toString(slice_number,"_slice%d"); + double slice_thickness = x_slice.thickness(); + Material slice_material = lcdd.material(x_slice.materialStr()); + DetElement slice(lcdd,slice_name,det_name+"/Layer/Slice",x_det.id()); + + slice_pos_z += slice_thickness / 2; + // Slice box. + Box slice_box(lcdd,slice_name+"_box",layer_dim_x,detZ/2,slice_thickness); + + // Slice volume. + Volume slice_vol(lcdd,slice_name,slice_box,slice_material); + if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens); // Set region, limitset, and vis. - layer_vol.setAttributes(lcdd,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + // slice PlacedVolume + PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z)); + slice_phv.addPhysVolID(_X(slice),slice_number); + + layer.add(slice); + // Increment Z position for next slice. + slice_pos_z += slice_thickness / 2; + // Increment slice number. + ++slice_number; + } + // Set region, limitset, and vis. + layer_vol.setAttributes(lcdd,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); - // Layer physical volume. - PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol,Position(0,0,layer_pos_z)); - layer_phv.addPhysVolID(_X(layer),layer_num); + // Layer physical volume. + PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol,Position(0,0,layer_pos_z)); + layer_phv.addPhysVolID(_X(layer),layer_num); - sdet.add(layer); + sdet.add(layer); - // Increment the layer X dimension. - layer_dim_x += layer_thickness * std::tan(layerInnerAngle);// * 2; - // Increment the layer Z position. - layer_pos_z += layer_thickness / 2; - // Increment the layer number. - ++layer_num; - } + // Increment the layer X dimension. + layer_dim_x += layer_thickness * std::tan(layerInnerAngle);// * 2; + // Increment the layer Z position. + layer_pos_z += layer_thickness / 2; + // Increment the layer number. + ++layer_num; } + } - // Add stave inner physical volume to outer stave volume. - staveOuterVol.placeVolume(staveInnerVol,IdentityPos()); + // Add stave inner physical volume to outer stave volume. + staveOuterVol.placeVolume(staveInnerVol,IdentityPos()); - // Set the vis attributes of the outer stave section. - sdet.setVisAttributes(lcdd,staves.visStr(),staveOuterVol); + // Set the vis attributes of the outer stave section. + sdet.setVisAttributes(lcdd,staves.visStr(),staveOuterVol); - // Place the staves. - placeStaves(rmin,numSides,totalThickness,envelopeVol,innerAngle,staveOuterVol); + // Place the staves. + placeStaves(rmin,numSides,totalThickness,envelopeVol,innerAngle,staveOuterVol); - PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,Rotation(0,0,M_PI/numSides)); - env_phv.addPhysVolID(_X(system), sdet.id()); - env_phv.addPhysVolID(_X(barrel), 0); - return sdet; - } -}} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,PolyhedraBarrelCalorimeter2); + PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,Rotation(0,0,M_PI/numSides)); + env_phv.addPhysVolID(_X(system), sdet.id()); + env_phv.addPhysVolID(_X(barrel), 0); + return sdet; +} + +DECLARE_DETELEMENT(PolyhedraBarrelCalorimeter2,create_detector); diff --git a/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp b/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp index 16e3a0eb98b39fd922aa1c65fb90282e0bdad3e0..41e0ade855a7e6866b9bfdf9c786cd8c3b1991d7 100644 --- a/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp +++ b/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp @@ -6,97 +6,93 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" #include "XML/Layering.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<PolyhedraEndcapCalorimeter2>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - xml_dim_t dim = x_det.dimensions(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - bool reflect = x_det.reflect(true); - Material air = lcdd.air(); - int numsides = dim.numsides(); - double rmin = dim.rmin(); - double rmax = dim.rmax()*std::cos(M_PI/numsides); - double zmin = dim.zmin(); - Layering layering(x_det); - double totalThickness = layering.totalThickness(); +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + xml_dim_t dim = x_det.dimensions(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + bool reflect = x_det.reflect(true); + Material air = lcdd.air(); + int numsides = dim.numsides(); + double rmin = dim.rmin(); + double rmax = dim.rmax()*std::cos(M_PI/numsides); + double zmin = dim.zmin(); + Layering layering(x_det); + double totalThickness = layering.totalThickness(); - PolyhedraRegular polyhedra(lcdd,det_name+"_polyhedra",numsides,rmin,rmax,totalThickness); - Volume envelopeVol(lcdd,det_name+"_envelope",polyhedra,air); + PolyhedraRegular polyhedra(lcdd,det_name+"_polyhedra",numsides,rmin,rmax,totalThickness); + Volume envelopeVol(lcdd,det_name+"_envelope",polyhedra,air); - int l_num = 0; - int layerType = 0; - double layerZ = -totalThickness/2; + int l_num = 0; + int layerType = 0; + double layerZ = -totalThickness/2; - for(xml_coll_t c(x_det,_X(layer)); c; ++c) { - xml_comp_t x_layer = c; - double l_thick = layering.layer(l_num)->thickness(); - string l_name = det_name + _toString(layerType,"_layer%d"); - int l_repeat = x_layer.repeat(); - PolyhedraRegular l_solid(lcdd,l_name+"_solid",numsides,rmin,rmax,l_thick); - Volume l_vol (lcdd,l_name+"_volume", l_solid, air); + for(xml_coll_t c(x_det,_X(layer)); c; ++c) { + xml_comp_t x_layer = c; + double l_thick = layering.layer(l_num)->thickness(); + string l_name = det_name + _toString(layerType,"_layer%d"); + int l_repeat = x_layer.repeat(); + PolyhedraRegular l_solid(lcdd,l_name+"_solid",numsides,rmin,rmax,l_thick); + Volume l_vol (lcdd,l_name+"_volume", l_solid, air); - int s_num = 0; - double sliceZ = -l_thick/2; - for(xml_coll_t s(x_layer,_X(slice)); s; ++s) { - xml_comp_t x_slice = s; - string s_name = l_name + _toString(s_num,"_slice%d"); - double s_thick = x_slice.thickness(); - Material s_mat = lcdd.material(x_slice.materialStr()); - PolyhedraRegular s_solid(lcdd,s_name+"_solid",numsides,rmin,rmax,s_thick); - Volume s_vol (lcdd,s_name+"_volume",s_solid,s_mat); + int s_num = 0; + double sliceZ = -l_thick/2; + for(xml_coll_t s(x_layer,_X(slice)); s; ++s) { + xml_comp_t x_slice = s; + string s_name = l_name + _toString(s_num,"_slice%d"); + double s_thick = x_slice.thickness(); + Material s_mat = lcdd.material(x_slice.materialStr()); + PolyhedraRegular s_solid(lcdd,s_name+"_solid",numsides,rmin,rmax,s_thick); + Volume s_vol (lcdd,s_name+"_volume",s_solid,s_mat); - if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); - s_vol.setVisAttributes(lcdd.visAttributes(x_slice.visStr())); - sliceZ += s_thick/2; - PlacedVolume s_phv = l_vol.placeVolume(s_vol,Position(0,0,sliceZ)); - s_phv.addPhysVolID("slice",s_num); - s_num++; - } - l_vol.setVisAttributes(lcdd.visAttributes(x_layer.visStr())); - if ( l_repeat <= 0 ) throw std::runtime_error(det_name+"> Invalid repeat value"); - for(int j=0; j<l_repeat; ++j) { - string phys_lay = det_name + _toString(l_num,"_layer%d"); - layerZ += l_thick/2; - PlacedVolume phys_vol = envelopeVol.placeVolume(l_vol,Position(0,0,layerZ)); - phys_vol.addPhysVolID("layer", l_num); - layerZ += l_thick/2; - ++l_num; - } - ++layerType; + if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); + s_vol.setVisAttributes(lcdd.visAttributes(x_slice.visStr())); + sliceZ += s_thick/2; + PlacedVolume s_phv = l_vol.placeVolume(s_vol,Position(0,0,sliceZ)); + s_phv.addPhysVolID("slice",s_num); + s_num++; + } + l_vol.setVisAttributes(lcdd.visAttributes(x_layer.visStr())); + if ( l_repeat <= 0 ) throw std::runtime_error(det_name+"> Invalid repeat value"); + for(int j=0; j<l_repeat; ++j) { + string phys_lay = det_name + _toString(l_num,"_layer%d"); + layerZ += l_thick/2; + PlacedVolume phys_vol = envelopeVol.placeVolume(l_vol,Position(0,0,layerZ)); + phys_vol.addPhysVolID("layer", l_num); + layerZ += l_thick/2; + ++l_num; } + ++layerType; + } - envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); - DetElement sdet (lcdd,det_name,det_type,x_det.id()); - Volume motherVol = lcdd.pickMotherVolume(sdet); - PlacedVolume physvol = motherVol.placeVolume(envelopeVol, - Position(0,0,zmin+totalThickness/2), - Rotation(0,0,M_PI/numsides)); - physvol.addPhysVolID("system",det_id); - physvol.addPhysVolID("barrel",1); - sdet.addPlacement(physvol); + envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + DetElement sdet (lcdd,det_name,det_type,x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + PlacedVolume physvol = motherVol.placeVolume(envelopeVol, + Position(0,0,zmin+totalThickness/2), + Rotation(0,0,M_PI/numsides)); + physvol.addPhysVolID("system",det_id); + physvol.addPhysVolID("barrel",1); + sdet.addPlacement(physvol); - if ( reflect ) { - physvol = motherVol.placeVolume(envelopeVol, - Position(0,0,-(zmin+totalThickness/2)), - Rotation(M_PI,0,M_PI/numsides)); - physvol.addPhysVolID("system",det_id); - physvol.addPhysVolID("barrel",2); - DetElement rdet(lcdd,det_name+"_reflect",det_type,x_det.id()); - rdet.addPlacement(physvol); - } - return sdet; + if ( reflect ) { + physvol = motherVol.placeVolume(envelopeVol, + Position(0,0,-(zmin+totalThickness/2)), + Rotation(M_PI,0,M_PI/numsides)); + physvol.addPhysVolID("system",det_id); + physvol.addPhysVolID("barrel",2); + DetElement rdet(lcdd,det_name+"_reflect",det_type,x_det.id()); + rdet.addPlacement(physvol); } -}} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,PolyhedraEndcapCalorimeter2); + return sdet; +} + +DECLARE_DETELEMENT(PolyhedraEndcapCalorimeter2,create_detector); diff --git a/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp b/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp index 802c7999da1fb9e967a2a0717d525f5e1287bfc2..0989c39c1608e0a44f0048805d6ecf2f0804c47e 100644 --- a/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp +++ b/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp @@ -6,150 +6,145 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<SiTrackerBarrel>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - Material air = lcdd.air(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - DetElement sdet (lcdd,det_name,det_type,det_id); - Volume motherVol = lcdd.pickMotherVolume(sdet); +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + Material air = lcdd.air(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + DetElement sdet (lcdd,det_name,det_type,det_id); + Volume motherVol = lcdd.pickMotherVolume(sdet); - for(xml_coll_t mi(x_det,_X(module)); mi; ++mi) { - xml_comp_t x_mod = mi; - xml_comp_t m_env = x_mod.child(_X(module_envelope)); - string m_nam = det_name+"_"+x_mod.nameStr(); - Box m_box (lcdd,m_nam+"_box",m_env.width(),m_env.length(),m_env.thickness()); - Volume m_vol (lcdd,m_nam,m_box,air); - DetElement m_elt (lcdd,m_nam,det_type+"/Module",det_id); - int ncomponents = 0, sensor_number = 0; - for(xml_coll_t ci(x_mod,_X(module_component)); ci; ++ci, ++ncomponents) { - xml_comp_t x_comp = ci; - xml_comp_t x_pos = x_comp.child(_X(position),false); - xml_comp_t x_rot = x_comp.child(_X(rotation),false); - string c_nam = m_nam + _toString(ncomponents,"_component%d"); - Box c_box (lcdd,c_nam+"_box",x_comp.width(),x_comp.length(),x_comp.thickness()); - Volume c_vol (lcdd,c_nam,c_box,lcdd.material(x_comp.materialStr())); - DetElement c_elt (lcdd,c_nam,det_type+"/Module/Component",det_id); - PlacedVolume c_phv; + for(xml_coll_t mi(x_det,_X(module)); mi; ++mi) { + xml_comp_t x_mod = mi; + xml_comp_t m_env = x_mod.child(_X(module_envelope)); + string m_nam = det_name+"_"+x_mod.nameStr(); + Box m_box (lcdd,m_nam+"_box",m_env.width(),m_env.length(),m_env.thickness()); + Volume m_vol (lcdd,m_nam,m_box,air); + DetElement m_elt (lcdd,m_nam,det_type+"/Module",det_id); + int ncomponents = 0, sensor_number = 0; + for(xml_coll_t ci(x_mod,_X(module_component)); ci; ++ci, ++ncomponents) { + xml_comp_t x_comp = ci; + xml_comp_t x_pos = x_comp.child(_X(position),false); + xml_comp_t x_rot = x_comp.child(_X(rotation),false); + string c_nam = m_nam + _toString(ncomponents,"_component%d"); + Box c_box (lcdd,c_nam+"_box",x_comp.width(),x_comp.length(),x_comp.thickness()); + Volume c_vol (lcdd,c_nam,c_box,lcdd.material(x_comp.materialStr())); + DetElement c_elt (lcdd,c_nam,det_type+"/Module/Component",det_id); + PlacedVolume c_phv; - if ( x_pos && x_rot ) { - Position c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0)); - Rotation c_rot(x_rot.x(0),x_rot.y(0),x_rot.z(0)); - c_phv = m_vol.placeVolume(c_vol, c_pos, c_rot); - } - else if ( x_rot ) { - c_phv = m_vol.placeVolume(c_vol,Rotation(x_rot.x(0),x_rot.y(0),x_rot.z(0))); - } - else if ( x_pos ) { - c_phv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0))); - } - else { - c_phv = m_vol.placeVolume(c_vol,IdentityPos()); - } - if ( x_comp.isSensitive() ) { - c_phv.addPhysVolID(_X(sensor),sensor_number++); - c_vol.setSensitiveDetector(sens); - } - c_elt.setAttributes(lcdd,c_vol, - x_comp.attr<string>(_A(region)), - x_comp.attr<string>(_A(limits)), - x_comp.visStr()); - m_elt.add(c_elt); + if ( x_pos && x_rot ) { + Position c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0)); + Rotation c_rot(x_rot.x(0),x_rot.y(0),x_rot.z(0)); + c_phv = m_vol.placeVolume(c_vol, c_pos, c_rot); + } + else if ( x_rot ) { + c_phv = m_vol.placeVolume(c_vol,Rotation(x_rot.x(0),x_rot.y(0),x_rot.z(0))); + } + else if ( x_pos ) { + c_phv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0))); + } + else { + c_phv = m_vol.placeVolume(c_vol,IdentityPos()); } - m_vol.setVisAttributes(lcdd.visAttributes(x_mod.visStr())); - sdet.add(m_elt); + if ( x_comp.isSensitive() ) { + c_phv.addPhysVolID(_X(sensor),sensor_number++); + c_vol.setSensitiveDetector(sens); + } + c_elt.setAttributes(lcdd,c_vol, + x_comp.attr<string>(_A(region)), + x_comp.attr<string>(_A(limits)), + x_comp.visStr()); + m_elt.add(c_elt); } - for(xml_coll_t li(x_det,_X(layer)); li; ++li) { - xml_comp_t x_layer = li; - xml_comp_t x_barrel = x_layer.child(_X(barrel_envelope)); - xml_comp_t x_layout = x_layer.child(_X(rphi_layout)); - xml_comp_t z_layout = x_layer.child(_X(z_layout)); // Get the <z_layout> element. - int lay_id = x_layer.id(); - string m_nam = det_name+"_"+x_layer.moduleStr(); - DetElement m_elt = sdet.child(m_nam); - Volume m_env = lcdd.volume(m_nam); - string lay_nam = det_name+_toString(lay_id,"_layer%d"); - Tube lay_tub (lcdd,lay_nam+"_tube",x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()); - Volume lay_vol (lcdd,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. + m_vol.setVisAttributes(lcdd.visAttributes(x_mod.visStr())); + sdet.add(m_elt); + } + for(xml_coll_t li(x_det,_X(layer)); li; ++li) { + xml_comp_t x_layer = li; + xml_comp_t x_barrel = x_layer.child(_X(barrel_envelope)); + xml_comp_t x_layout = x_layer.child(_X(rphi_layout)); + xml_comp_t z_layout = x_layer.child(_X(z_layout)); // Get the <z_layout> element. + int lay_id = x_layer.id(); + string m_nam = det_name+"_"+x_layer.moduleStr(); + DetElement m_elt = sdet.child(m_nam); + Volume m_env = lcdd.volume(m_nam); + string lay_nam = det_name+_toString(lay_id,"_layer%d"); + Tube lay_tub (lcdd,lay_nam+"_tube",x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()); + Volume lay_vol (lcdd,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. - // 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 = (2.0 * z0) / (nz - 1); - // Starting z for module placement along Z axis. - double module_z = -z0; - int module = 0; + // 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 = (2.0 * z0) / (nz - 1); + // Starting z for module placement along Z axis. + double module_z = -z0; + int module = 0; - // 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 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++) { - // Create a unique name for the module in this logical volume, layer, phi, and z. - string m_place = lay_nam + _toString(ii,"_phi%d") + _toString(j,"_z%d"); - double z = module_z; - // Module PhysicalVolume. - PlacedVolume m_physvol = + // Loop over the number of modules in z. + for (int j = 0; j < nz; j++) { + // Create a unique name for the module in this logical volume, layer, phi, and z. + string m_place = lay_nam + _toString(ii,"_phi%d") + _toString(j,"_z%d"); + double z = module_z; + // Module PhysicalVolume. + PlacedVolume m_physvol = lay_vol.placeVolume(m_env,Position(x,y,z), Rotation(M_PI/2,-((M_PI/2)-phic-phi_tilt),0)); - m_physvol.addPhysVolID("module", module++); + m_physvol.addPhysVolID("module", 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; - } - // Increment the phi placement of module. - phic += phi_incr; - // Increment the center radius according to dr parameter. - rc += rphi_dr; - // Flip sign of dr parameter. - rphi_dr *= -1; - // Reset the Z placement parameter for module. - module_z = -z0; + // 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; } - m_elt.setAttributes(lcdd,lay_vol, - x_layer.attr<string>(_A(region)), - x_layer.attr<string>(_A(limits)), - x_layer.visStr()); - - // Create the PhysicalVolume for the layer. - PlacedVolume lpv = motherVol.placeVolume(lay_vol); // Place layer in mother - lpv.addPhysVolID("system", det_id); // Set the subdetector system ID. - lpv.addPhysVolID("barrel", 0); // Flag this as a barrel subdetector. - lpv.addPhysVolID("layer", lay_id); // Set the layer ID. + // Increment the phi placement of module. + phic += phi_incr; + // Increment the center radius according to dr parameter. + rc += rphi_dr; + // Flip sign of dr parameter. + rphi_dr *= -1; + // Reset the Z placement parameter for module. + module_z = -z0; } - return sdet; + m_elt.setAttributes(lcdd,lay_vol, + x_layer.attr<string>(_A(region)), + x_layer.attr<string>(_A(limits)), + x_layer.visStr()); + + // Create the PhysicalVolume for the layer. + PlacedVolume lpv = motherVol.placeVolume(lay_vol); // Place layer in mother + lpv.addPhysVolID("system", det_id); // Set the subdetector system ID. + lpv.addPhysVolID("barrel", 0); // Flag this as a barrel subdetector. + lpv.addPhysVolID("layer", lay_id); // Set the layer ID. } -}} + return sdet; +} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,SiTrackerBarrel); +DECLARE_DETELEMENT(SiTrackerBarrel,create_detector); diff --git a/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp b/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp index 77b3855efa99387fa924dced189c64252b6cf0c0..520c0841987094eeef0ef85119e8f4bf33d1b86e 100644 --- a/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp +++ b/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp @@ -8,117 +8,113 @@ //==================================================================== #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" #include <map> using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<SiTrackerEndcap2>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { - xml_det_t x_det = e; - Material air = lcdd.air(); - Material vacuum = lcdd.vacuum(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - bool reflect = x_det.reflect(); - DetElement sdet (lcdd,det_name,det_type,det_id); - Volume motherVol = lcdd.trackingVolume(); - int m_id=0, c_id=0, n_sensor=0; - double posY; - map<string,Volume> modules; +static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) { + xml_det_t x_det = e; + Material air = lcdd.air(); + Material vacuum = lcdd.vacuum(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + bool reflect = x_det.reflect(); + DetElement sdet (lcdd,det_name,det_type,det_id); + Volume motherVol = lcdd.trackingVolume(); + int m_id=0, c_id=0, n_sensor=0; + double posY; + map<string,Volume> modules; - for(xml_coll_t mi(x_det,_X(module)); mi; ++mi, ++m_id) { - xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); - string vol_nam = m_nam+"Volume"; - xml_comp_t trd = x_mod.child(_X(trd)); - double x1 = trd.x1(); - double x2 = trd.x2(); - double z = trd.z(); - double y1, y2, total_thickness=0.; - xml_coll_t ci(x_mod,_X(module_component)); - for(ci.reset(), total_thickness=0.0; ci; ++ci) - total_thickness += xml_comp_t(ci).thickness(); + for(xml_coll_t mi(x_det,_X(module)); mi; ++mi, ++m_id) { + xml_comp_t x_mod = mi; + string m_nam = x_mod.nameStr(); + string vol_nam = m_nam+"Volume"; + xml_comp_t trd = x_mod.child(_X(trd)); + double x1 = trd.x1(); + double x2 = trd.x2(); + double z = trd.z(); + double y1, y2, total_thickness=0.; + xml_coll_t ci(x_mod,_X(module_component)); + for(ci.reset(), total_thickness=0.0; ci; ++ci) + total_thickness += xml_comp_t(ci).thickness(); - y1 = y2 = total_thickness / 2; - Trapezoid m_envelope(lcdd, m_nam+"Trd", x1, x2, y1, y2, z); - Volume m_volume(lcdd, vol_nam, m_envelope, vacuum); + y1 = y2 = total_thickness / 2; + Trapezoid m_envelope(lcdd, m_nam+"Trd", x1, x2, y1, y2, z); + Volume m_volume(lcdd, vol_nam, m_envelope, vacuum); - m_volume.setVisAttributes(lcdd.visAttributes(x_mod.visStr())); + m_volume.setVisAttributes(lcdd.visAttributes(x_mod.visStr())); - for(ci.reset(), n_sensor=0, c_id=0, posY=-y1; ci; ++ci, ++c_id) { - xml_comp_t c = ci; - double c_thick = c.thickness(); - Material c_mat = lcdd.material(c.materialStr()); - string c_name = m_nam + _toString(c_id,"_component%d"); - Trapezoid trd(lcdd, c_name+"_trd", x1, x2, c_thick/2e0, c_thick/2e0, z); - Volume vol(lcdd, c_name, trd, c_mat); + for(ci.reset(), n_sensor=0, c_id=0, posY=-y1; ci; ++ci, ++c_id) { + xml_comp_t c = ci; + double c_thick = c.thickness(); + Material c_mat = lcdd.material(c.materialStr()); + string c_name = m_nam + _toString(c_id,"_component%d"); + Trapezoid trd(lcdd, c_name+"_trd", x1, x2, c_thick/2e0, c_thick/2e0, z); + Volume vol(lcdd, c_name, trd, c_mat); - vol.setVisAttributes(lcdd.visAttributes(c.visStr())); + vol.setVisAttributes(lcdd.visAttributes(c.visStr())); - PlacedVolume phv = m_volume.placeVolume(vol,Position(0,posY+c_thick/2,0)); - phv.addPhysVolID(_X(component),c_id); - if ( c.isSensitive() ) { - sdet.check(n_sensor > 1,"SiTrackerEndcap2::fromCompact: "+c_name+" Max of 2 modules allowed!"); - phv.addPhysVolID(_X(sensor),c_id); - vol.setSensitiveDetector(sens); - ++n_sensor; - } - posY += c_thick; + PlacedVolume phv = m_volume.placeVolume(vol,Position(0,posY+c_thick/2,0)); + phv.addPhysVolID(_X(component),c_id); + if ( c.isSensitive() ) { + sdet.check(n_sensor > 1,"SiTrackerEndcap2::fromCompact: "+c_name+" Max of 2 modules allowed!"); + phv.addPhysVolID(_X(sensor),c_id); + vol.setSensitiveDetector(sens); + ++n_sensor; } - modules[m_nam] = m_volume; + posY += c_thick; } - for(xml_coll_t li(x_det,_X(layer)); li; ++li) { - xml_comp_t x_layer(li); - int l_id = x_layer.id(); - int mod_num = 0; - for(xml_coll_t ri(x_layer,_X(ring)); ri; ++ri) { - xml_comp_t x_ring = ri; - double r = x_ring.r(); - double phi0 = x_ring.phi0(0); - double zstart = x_ring.zstart(); - double dz = x_ring.dz(0); - int nmodules = x_ring.attr<int>(_A(nmodules)); - string m_nam = x_ring.moduleStr(); - Volume m_vol = modules[m_nam]; + modules[m_nam] = m_volume; + } + for(xml_coll_t li(x_det,_X(layer)); li; ++li) { + xml_comp_t x_layer(li); + int l_id = x_layer.id(); + int mod_num = 0; + for(xml_coll_t ri(x_layer,_X(ring)); ri; ++ri) { + xml_comp_t x_ring = ri; + double r = x_ring.r(); + double phi0 = x_ring.phi0(0); + double zstart = x_ring.zstart(); + double dz = x_ring.dz(0); + int nmodules = x_ring.attr<int>(_A(nmodules)); + string m_nam = x_ring.moduleStr(); + Volume m_vol = modules[m_nam]; - double iphi = 2*M_PI/nmodules; - double phi = phi0; - for(int k=0; k<nmodules; ++k) { - string m_base = det_name + _toString(l_id,"_layer%d") + _toString(mod_num,"_module%d"); - double x = r*std::cos(phi); - double y = r*std::sin(phi); - PlacedVolume pv = motherVol.placeVolume(m_vol, - Position(x,y,zstart+dz), - Rotation(-M_PI/2,-M_PI/2-phi,0)); - pv.addPhysVolID("system",det_id).addPhysVolID("barrel",1); - pv.addPhysVolID("layer", l_id).addPhysVolID("module",mod_num); - DetElement module (lcdd,m_base,det_type+"/Module",det_id); - module.addPlacement(pv); - sdet.add(module); + double iphi = 2*M_PI/nmodules; + double phi = phi0; + for(int k=0; k<nmodules; ++k) { + string m_base = det_name + _toString(l_id,"_layer%d") + _toString(mod_num,"_module%d"); + double x = r*std::cos(phi); + double y = r*std::sin(phi); + PlacedVolume pv = motherVol.placeVolume(m_vol, + Position(x,y,zstart+dz), + Rotation(-M_PI/2,-M_PI/2-phi,0)); + pv.addPhysVolID("system",det_id).addPhysVolID("barrel",1); + pv.addPhysVolID("layer", l_id).addPhysVolID("module",mod_num); + DetElement module (lcdd,m_base,det_type+"/Module",det_id); + module.addPlacement(pv); + sdet.add(module); - if ( reflect ) { - pv = motherVol.placeVolume(m_vol, - Position(x,y,-zstart-dz), - Rotation(-M_PI/2,-M_PI/2-phi,M_PI)); - pv.addPhysVolID("system",det_id).addPhysVolID("barrel",2); - pv.addPhysVolID("layer", l_id).addPhysVolID("module",mod_num); - DetElement r_module (lcdd,m_base+"_reflect",det_type+"/Module",det_id); - r_module.addPlacement(pv); - sdet.add(r_module); - } - dz = -dz; - phi += iphi; - ++mod_num; - } + if ( reflect ) { + pv = motherVol.placeVolume(m_vol, + Position(x,y,-zstart-dz), + Rotation(-M_PI/2,-M_PI/2-phi,M_PI)); + pv.addPhysVolID("system",det_id).addPhysVolID("barrel",2); + pv.addPhysVolID("layer", l_id).addPhysVolID("module",mod_num); + DetElement r_module (lcdd,m_base+"_reflect",det_type+"/Module",det_id); + r_module.addPlacement(pv); + sdet.add(r_module); + } + dz = -dz; + phi += iphi; + ++mod_num; } } - return sdet; } -}} + return sdet; +} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,SiTrackerEndcap2); +DECLARE_DETELEMENT(SiTrackerEndcap2,create_detector); diff --git a/DDExamples/CLICSiD/src/TubeSegment_geo.cpp b/DDExamples/CLICSiD/src/TubeSegment_geo.cpp index bb5058e2a7f4ac3ad06181dba79aa9a787c0a668..79a8006aa6f13189a8225e118ed8b6546fa57ed2 100644 --- a/DDExamples/CLICSiD/src/TubeSegment_geo.cpp +++ b/DDExamples/CLICSiD/src/TubeSegment_geo.cpp @@ -6,34 +6,31 @@ // Author : M.Frank // //==================================================================== - #include "DD4hep/DetFactoryHelper.h" -#include "CompactDetectors.h" + using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace DD4hep { namespace Geometry { - - template <> Ref_t DetElementFactory<TubeSegment>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector&) { - xml_det_t x_det (e); - xml_comp_t x_tube (x_det.child(_X(tubs))); - xml_dim_t x_pos (x_det.child(_X(position))); - xml_dim_t x_rot (x_det.child(_X(rotation))); - string name = x_det.nameStr(); - Tube tub (lcdd,name+"_tube",x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); - Volume vol (lcdd,name,tub,lcdd.material(x_det.materialStr())); +static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector&) { + xml_det_t x_det (e); + xml_comp_t x_tube (x_det.child(_X(tubs))); + xml_dim_t x_pos (x_det.child(_X(position))); + xml_dim_t x_rot (x_det.child(_X(rotation))); + string name = x_det.nameStr(); + Tube tub (lcdd,name+"_tube",x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); + Volume vol (lcdd,name,tub,lcdd.material(x_det.materialStr())); - vol.setVisAttributes(lcdd, x_det.visStr()); + vol.setVisAttributes(lcdd, x_det.visStr()); - DetElement sdet(lcdd,name,x_det.typeStr(),x_det.id()); - Volume mother = lcdd.pickMotherVolume(sdet); - PlacedVolume phv = + DetElement sdet(lcdd,name,x_det.typeStr(),x_det.id()); + Volume mother = lcdd.pickMotherVolume(sdet); + PlacedVolume phv = mother.placeVolume(vol,Position(x_pos.x(),x_pos.y(),x_pos.z()), Rotation(x_rot.x(),x_rot.y(),x_rot.z())); - phv.addPhysVolID(_A(id),x_det.id()); - sdet.addPlacement(phv); - return sdet; - } -}} -DECLARE_NAMED_DETELEMENT_FACTORY(DD4hep,TubeSegment); + phv.addPhysVolID(_A(id),x_det.id()); + sdet.addPlacement(phv); + return sdet; +} + +DECLARE_DETELEMENT(TubeSegment,create_element);