diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index fc44ab3c65be20329b79eae9aca97d8e86772f4d..5eada6c523bb2821070381063b33f185463ddc50 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -118,6 +118,7 @@ namespace DD4hep { TGeoMatrix* worldTrafo; TGeoMatrix* parentTrafo; TGeoMatrix* referenceTrafo; + std::string placementPath; /// Default constructor Object(); /// Construct new empty object @@ -129,7 +130,7 @@ namespace DD4hep { /// Conversion to reference object Ref_t asRef(); /// Top detector element - Ref_t top(); + //Ref_t top(); /// Create cached matrix to transform to world coordinates TGeoMatrix* worldTransformation(); /// Create cached matrix to transform to parent coordinates @@ -149,27 +150,36 @@ namespace DD4hep { /// Default constructor template<typename Q> DetElement(Q* data, const std::string& name, const std::string& type) : Ref_t(data) { this->assign(data, name, type); } + /// Templated constructor for handle conversions template<typename Q> DetElement(const Handle<Q>& e) : Ref_t(e) {} - /// DEPRECATED: Constructor for a new subdetector element. First argument lcdd is unused! - DetElement(const LCDD& lcdd, const std::string& name, const std::string& type, int id); + + /// Constructor to copy handle + DetElement(const DetElement& e) : Ref_t(e) {} /// Constructor for a new subdetector element DetElement(const std::string& name, const std::string& type, int id); + /// Constructor for a new subdetector element + DetElement(const std::string& name, int id); + + /// Constructor for a new subdetector element + DetElement(DetElement parent, const std::string& name, int id); + /// Clone (Deep copy) the DetElement structure with a new name DetElement clone(const std::string& new_name) const; + /// Clone (Deep copy) the DetElement structure with a new name and new identifier DetElement clone(const std::string& new_name, int new_id) const; DetElement& setCombineHits(bool value, SensitiveDetector& sens); - DetElement& add(const DetElement& sub_element); int id() const; std::string type() const; std::string path() const; + /// Access to the full path to the placed object + std::string placementPath() const; bool isTracker() const; bool isCalorimeter() const; - //bool isInsideTrackingVolume() const; bool combineHits() const; /// Set all attributes in one go @@ -189,24 +199,25 @@ namespace DD4hep { Readout readout() const; /// Assign readout definition DetElement& setReadout(const Readout& readout); - + + /// Access to the logical volume of the placements (all daughters have the same!) + Volume volume() const; + /// Set the logical volume of the placements (all daughters have the same!) + //void setVolume(Volume vol); + /// Access to the physical volume of this detector element PlacedVolume placement() const; /// Set the physical volumes of the detector element DetElement& setPlacement(const PlacedVolume& volume); - /// Access the physical volumes of the detector element - //Placements placements() const; - /// Set the physical volumes of the detector element - //DetElement& addPlacement(const PlacedVolume& volume); - - /// Access to the logical volume of the placements (all daughters have the same!) - Volume volume() const; - + /// Add new child to the detector structure + DetElement& add(DetElement sub_element); /// Access to the list of children const Children& children() const; /// Access to individual children by name DetElement child(const std::string& name) const; + /// Access to the detector elements's parent + DetElement parent() const; /// Set detector element for reference transformations. Will delete existing reference trafo. DetElement& setReference(DetElement reference); diff --git a/DDCore/include/DD4hep/GeoHandler.h b/DDCore/include/DD4hep/GeoHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..dc81703604eafb72ed0b09b3386504cb2b6d22c6 --- /dev/null +++ b/DDCore/include/DD4hep/GeoHandler.h @@ -0,0 +1,94 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_GEOHANDLER_H +#define DD4HEP_GEOHANDLER_H + +#include "DD4hep/LCDD.h" +#include <set> +#include <map> +#include <vector> + +// Forward declarations +class TGeoMatrix; +class TGeoVolume; +class TGeoMedium; +class TGeoShape; +class TGeoNode; + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /* + * Geometry namespace declaration + */ + namespace Geometry { + + /** @class GeoHandler GeoHandler.h + * + * @author M.Frank + * @version 1.0 + */ + class GeoHandler { + public: + typedef std::map<std::string, TGeoVolume*> VolumeSet; + typedef std::vector<std::pair<std::string, TGeoMatrix*> > TransformSet; + typedef std::map<std::string, TGeoShape*> SolidSet; + typedef std::map<std::string, TGeoMedium*> MaterialSet; + typedef std::map<int, std::set<const TGeoNode*> > Data; + typedef LCDD::HandleMap VisRefs; + + struct GeometryInfo { + SolidSet solids; + VolumeSet volumes; + TransformSet trafos; + VisRefs vis; + MaterialSet materials; + std::set<TGeoMedium*> media; + std::set<TGeoElement*> elements; + }; + protected: + Data* m_data; + + /// Internal helper to collect geometry information from traversal + GeoHandler& i_collect(const TGeoNode* node, int level); + + public: + /// Default constructor + GeoHandler(); + /// Initializing constructor + GeoHandler(Data* ptr); + /// Default destructor + virtual ~GeoHandler(); + /// Collect geometry information from traversal + GeoHandler& collect(DetElement top); + /// Collect geometry information from traversal with aggregated information + GeoHandler& collect(DetElement top, GeometryInfo& info); + /// Access to collected node list + Data* release(); + }; + + struct GeoScan { + protected: + /// Data holder + GeoHandler::Data* m_data; + public: + /// Initializing constructor + GeoScan(DetElement e); + /// Default destructor + virtual ~GeoScan(); + /// Work callback + virtual GeoScan& operator()(); + }; + } // End namespace Geometry +} // End namespace DD4hep + +#endif // DD4HEP_GEOHANDLER_H + diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index 49bca02770a395c26bddbc28c2e69ce15fdb02ea..d9d68a978ba7accf3bfa60ab9134b611b47d7219 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -23,6 +23,17 @@ class TGeoManager; #ifndef RAD_2_DEGREE #define RAD_2_DEGREE 57.295779513082320876798154814105 #endif +#ifndef DEGREE_2_RAD +#define DEGREE_2_RAD 0.017453292519943295769236907684886 +#endif +#ifndef CM_2_MM +#define CM_2_MM 10.0 +#endif +#ifndef MM_2_CM +#define MM_2_CM 0.1 +#endif + + #ifndef M_PI #define M_PI 3.14159265358979323846 #endif diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h index 40cad19f94231c48b23a04735362c8dfcbabc901..8af8ffb1e69de30bbdf7b51de2608265826f226e 100644 --- a/DDCore/include/DD4hep/LCDD.h +++ b/DDCore/include/DD4hep/LCDD.h @@ -42,7 +42,6 @@ namespace DD4hep { virtual ~LCDD() {} - //virtual Document document() const = 0; virtual void create() = 0; virtual void init() = 0; virtual void endDocument() = 0; @@ -51,14 +50,15 @@ namespace DD4hep { virtual Material air() const = 0; virtual Material vacuum() const = 0; + virtual DetElement world() const = 0; + virtual DetElement trackers() const = 0; + virtual Volume worldVolume() const = 0; virtual Volume trackingVolume() const = 0; virtual const HandleMap& header() const = 0; virtual const HandleMap& constants() const = 0; virtual const HandleMap& regions() const = 0; - virtual const HandleMap& structure() const = 0; - virtual const HandleMap& solids() const = 0; virtual const HandleMap& materials() const = 0; virtual const HandleMap& detectors() const = 0; virtual const HandleMap& readouts() const = 0; @@ -66,23 +66,19 @@ namespace DD4hep { virtual const HandleMap& limitsets() const = 0; virtual const HandleMap& alignments() const = 0; + virtual Volume pickMotherVolume(const DetElement& sd) 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; 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 LimitSet& limset) = 0; @@ -98,9 +94,6 @@ namespace DD4hep { virtual LCDD& addRegion(const Ref_t& region) = 0; 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; diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h index c7328b7efac38b4ef7b0deecbf36435a83ff19f3..e879bde4ea45422d93f55439df440b181955b446 100644 --- a/DDCore/include/DD4hep/Objects.h +++ b/DDCore/include/DD4hep/Objects.h @@ -236,12 +236,14 @@ namespace DD4hep { struct VisAttr : public Ref_t { struct Object { unsigned long magic; + void* col; int color; + float alpha; unsigned char drawingStyle, lineStyle, showDaughters, visible; - Object() : magic(magic_word()), color(0), drawingStyle(true), showDaughters(true), visible(true) {} + Object() : magic(magic_word()), col(0), color(0), alpha(0), drawingStyle(true), showDaughters(true), visible(true) {} }; enum DrawingStyle { - WIREFRAME=0x1, + WIREFRAME=0x2, LAST_DRAWING_STYLE }; enum LineStyle { @@ -251,25 +253,49 @@ namespace DD4hep { }; /// Default constructor VisAttr() : Ref_t() {} - /// Constructor to be used when reading the already parsed DOM tree + /// Constructor to be used for assignment from object handle template <typename Q> VisAttr(const Handle<Q>& e) : Ref_t(e) {} + /// Copy constructor for handle + VisAttr(const VisAttr& e) : Ref_t(e) {} /// 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>(); } + + /// Get Flag to show/hide daughter elements + bool showDaughters() const; /// Set Flag to show/hide daughter elements void setShowDaughters(bool value); + + /// Get visibility flag + bool visible() const; + /// Set visibility flag + void setVisible(bool value); + + /// Get line style + int lineStyle() const; /// Set line style void setLineStyle(LineStyle style); + + /// Get drawing style + int drawingStyle() const; /// Set drawing style void setDrawingStyle(DrawingStyle style); - /// Set visibility flag - void setVisible(bool value); + + /// Get alpha value + float alpha() const; /// Set alpha value void setAlpha(float value); + + /// Get object color + int color() const; /// Set object color void setColor(float red, float green, float blue); + + /// Get RGB values of the color (if valid) + bool rgb(float& red, float& green, float& blue) const; + /// String representation of this object std::string toString() const; }; diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index 09957c38114702b05d5aff4d764f44383416dd03..8e7f219dd0a76f091da27c3b8e8982595e3356ee 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -22,9 +22,12 @@ class TGeoBBox; class TGeoPcon; class TGeoPgon; class TGeoCone; +class TGeoSphere; class TGeoTrd2; +class TGeoTorus; class TGeoTrap; class TGeoTubeSeg; +class TGeoParaboloid; class TGeoCompositeShape; /* @@ -53,8 +56,7 @@ namespace DD4hep { typedef T Implementation; void _setDimensions(double* param); /// Assign pointrs and register solid to geometry - void _assign(LCDD& lcdd, Implementation* n, const std::string& nam, const std::string& tit, bool cbbox=true); - + void _assign(Implementation* n, const std::string& nam, const std::string& tit, bool cbbox=true); public: @@ -68,17 +70,16 @@ namespace DD4hep { Solid_type(const Handle<Implementation>& e) : Handle<Implementation>(e) {} /// Constructor to be used when reading the already parsed object: need to check pointers - template <typename Q> - Solid_type(const Handle<Q>& e) : Handle<T>(e) {} + template <typename Q> Solid_type(const Handle<Q>& e) : Handle<T>(e) {} /// Access to shape name const char* name() const; /// Auto conversion to underlying ROOT object - operator Implementation*() const { return this->m_element; } + operator Implementation*() const { return this->m_element; } /// Overloaded operator -> to access underlying object - Implementation* operator->() const { return this->m_element; } + Implementation* operator->() const { return this->m_element; } }; typedef Solid_type<TGeoShape> Solid; @@ -90,25 +91,38 @@ namespace DD4hep { */ struct Box : public Solid_type<TGeoBBox> { protected: - void make(LCDD& lcdd, const std::string& name, double x, double y, double z); + void make(const std::string& name, double x, double y, double z); public: /// Constructor to be used when reading the already parsed box object template <typename Q> Box(const Handle<Q>& e) : Solid_type<Implementation>(e) {} - /// Constructor to be used when creating a new box object - Box(LCDD& lcdd, const std::string& name) - { make(lcdd, name, 0, 0, 0); } + /// Constructor to be used when creating an identifiable new box object + Box(const std::string& name) + { make(name, 0, 0, 0); } + + /// Constructor to be used when creating an anonymous new box object (retrieves name from volume) + Box() + { make("", 0, 0, 0); } + + /// Constructor to be used when creating an identifiable new box object + Box(const std::string& name, double x, double y, double z) + { make(name, x, y, z); } - /// Constructor to be used when creating a new box object - Box(LCDD& lcdd, const std::string& name, double x, double y, double z) - { make(lcdd, name, x, y, z); } + /// Constructor to be used when creating an anonymous new box object (retrieves name from volume) + Box(double x, double y, double z) + { make("", x, y, z); } + + /// Constructor to be used when creating an identifiable new box object + template<typename X, typename Y, typename Z> + Box(const std::string& name, const X& x, const Y& y, const Z& z) + { make(name, _toDouble(x),_toDouble(y),_toDouble(z)); } - /// Constructor to be used when creating a new box object + /// Constructor to be used when creating an anonymous new box object (retrieves name from volume) template<typename X, typename Y, typename Z> - Box(LCDD& lcdd, const std::string& name, const X& x, const Y& y, const Z& z) - { make(lcdd, name, _toDouble(x),_toDouble(y),_toDouble(z)); } + Box(const X& x, const Y& y, const Z& z) + { make("", _toDouble(x),_toDouble(y),_toDouble(z)); } /// Set the box dimensions Box& setDimensions(double x, double y, double z); @@ -124,13 +138,19 @@ namespace DD4hep { template <typename Q> Polycone(const Handle<Q>& e) : Solid_type<Implementation>(e) {} /// Constructor to be used when creating a new polycone object - Polycone(LCDD& lcdd, const std::string& name); + Polycone(const std::string& name=""); /// Constructor to be used when creating a new polycone object - Polycone(LCDD& lcdd, const std::string& name, double start, double delta); + Polycone(double start, double delta); + + /// Constructor to be used when creating a new polycone object + Polycone(const std::string& name, double start, double delta); /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes - Polycone(LCDD& lcdd, const std::string& name, double start, double delta, const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z); + Polycone(double start, double delta, const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z); + + /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes + Polycone(const std::string& name, double start, double delta, const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z); /// Add Z-planes to the Polycone void addZPlanes(const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z); @@ -143,25 +163,40 @@ namespace DD4hep { */ struct Tube : public Solid_type<TGeoTubeSeg> { protected: - void make(LCDD& lcdd, const std::string& name,double rmin,double rmax,double z,double deltaPhi); + void make(const std::string& name,double rmin,double rmax,double z,double deltaPhi); public: /// Constructor to assign an object template <typename Q> Tube(const Handle<Q>& e) : Solid_type<Implementation>(e) {} - /// Constructor to be used when creating a new tube object - Tube(LCDD& lcdd, const std::string& name) - { make(lcdd,name,0, 0, 0, 0); } + /// Constructor to be used when creating a new anonymous tube object + Tube() + { make("",0, 0, 0, 0); } + + /// Constructor to be used when creating a new identifiable tube object + Tube(const std::string& name) + { make(name,0, 0, 0, 0); } - /// Constructor to be used when creating a new tube object with attribute initialization - Tube(LCDD& lcdd, const std::string& name, double rmin, double rmax, double z, double deltaPhi=2*M_PI) - { make(lcdd,name,rmin, rmax, z, deltaPhi); } + /// Constructor to be used when creating a new anonymous tube object with attribute initialization + Tube(double rmin, double rmax, double z, double deltaPhi=2*M_PI) + { make("",rmin, rmax, z, deltaPhi); } - /// Constructor to be used when creating a new tube object with attribute initialization + /// Constructor to be used when creating a new identifiable tube object with attribute initialization + Tube(const std::string& name, double rmin, double rmax, double z, double deltaPhi=2*M_PI) + { make(name,rmin, rmax, z, deltaPhi); } + + /// Constructor to be used when creating a new anonymous tube object with attribute initialization + template<typename RMIN, typename RMAX, typename Z, typename DELTAPHI> + Tube(const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi) + { + make("",_toDouble(rmin),_toDouble(rmax),_toDouble(z),_toDouble(deltaPhi)); + } + + /// Constructor to be used when creating a new identifiable tube object with attribute initialization template<typename RMIN, typename RMAX, typename Z, typename DELTAPHI> - Tube(LCDD& lcdd, const std::string& name, const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi) + Tube(const std::string& name, const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi) { - make(lcdd,name,_toDouble(rmin),_toDouble(rmax),_toDouble(z),_toDouble(deltaPhi)); + make(name,_toDouble(rmin),_toDouble(rmax),_toDouble(z),_toDouble(deltaPhi)); } /// Set the box dimensions @@ -175,29 +210,40 @@ namespace DD4hep { */ struct Cone : public Solid_type<TGeoCone> { protected: - void make(LCDD& lcdd, const std::string& name,double z,double rmin1,double rmax1,double rmin2,double rmax2); + void make(const std::string& name,double z,double rmin1,double rmax1,double rmin2,double rmax2); public: /// Constructor to be used when reading the already parsed object template <typename Q> Cone(const Handle<Q>& e) : Solid_type<Implementation>(e) {} + /// Constructor to be used when creating a new anonymous object + Cone() { make("",0, 0, 0, 0, 0); } /// Constructor to be used when creating a new object - Cone(LCDD& lcdd, const std::string& name) - { make(lcdd,name,0, 0, 0, 0, 0); } - + Cone(const std::string& name) { make(name,0, 0, 0, 0, 0); } + /// Constructor to be used when creating a new anonymous object with attribute initialization + Cone(double z, + double rmin1, + double rmax1, + double rmin2, + double rmax2) + { make("",z,rmin1,rmax1,rmin2,rmax2); } /// Constructor to be used when creating a new object with attribute initialization - Cone(LCDD& lcdd, const std::string& name, + Cone(const std::string& name, double z, double rmin1, double rmax1, double rmin2, double rmax2) - { make(lcdd,name,z,rmin1,rmax1,rmin2,rmax2); } + { make(name,z,rmin1,rmax1,rmin2,rmax2); } + + template<typename Z, typename RMIN1, typename RMAX1, typename RMIN2, typename RMAX2> + Cone(const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2) + { make("",_toDouble(z),_toDouble(rmin1),_toDouble(rmax1),_toDouble(rmin2),_toDouble(rmax2)); } template<typename Z, typename RMIN1, typename RMAX1, typename RMIN2, typename RMAX2> - Cone(LCDD& lcdd, const std::string& name, const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2) - { make(lcdd,name,_toDouble(z),_toDouble(rmin1),_toDouble(rmax1),_toDouble(rmin2),_toDouble(rmax2)); } + Cone(const std::string& name, const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2) + { make(name,_toDouble(z),_toDouble(rmin1),_toDouble(rmax1),_toDouble(rmin2),_toDouble(rmax2)); } /// Set the box dimensions Cone& setDimensions(double z,double rmin1,double rmax1,double rmin2,double rmax2); @@ -212,8 +258,8 @@ namespace DD4hep { /// Constructor to be used when reading the already parsed object template <typename Q> Trap( const Handle<Q>& e) : Solid_type<Implementation>(e) {} - /// Constructor to be used when creating a new object with attribute initialization - Trap( LCDD& lcdd, const std::string& name, + /// Constructor to be used when creating a new identified object with attribute initialization + Trap( const std::string& name, double z, double theta, double phi, @@ -225,6 +271,18 @@ namespace DD4hep { double x3, double x4, double alpha2); + /// Constructor to be used when creating a new anonymous object with attribute initialization + Trap( double z, + double theta, + double phi, + double y1, + double x1, + double x2, + double alpha1, + double y2, + double x3, + double x4, + double alpha2); /// Set the trap dimensions Trap& setDimensions(double z,double theta,double phi, @@ -241,14 +299,81 @@ namespace DD4hep { /// Constructor to be used when reading the already parsed object template <typename Q> Trapezoid(const Handle<Q>& e) : Solid_type<Implementation>(e) {} - /// Constructor to be used when creating a new object - Trapezoid(LCDD& lcdd, const std::string& name); - /// Constructor to be used when creating a new object with attribute initialization - Trapezoid(LCDD& lcdd, const std::string& name, double x1, double x2, double y1, double y2, double z); + /// Constructor to be used when creating a new anonymous object + Trapezoid(); + /// Constructor to be used when creating a new identified object + Trapezoid(const std::string& name); + /// Constructor to be used when creating a new anonymous object with attribute initialization + Trapezoid(double x1, double x2, double y1, double y2, double z); + /// Constructor to be used when creating a new identified object with attribute initialization + Trapezoid(const std::string& name, double x1, double x2, double y1, double y2, double z); /// Set the Trapezoid dimensions Trapezoid& setDimensions(double x1, double x2, double y1, double y2, double z); }; + /**@class Torus Shapes.h + * + * @author M.Frank + * @version 1.0 + */ + struct Torus : public Solid_type<TGeoTorus> { + /// Constructor to be used when reading the already parsed object + template <typename Q> Torus(const Handle<Q>& e) : Solid_type<Implementation>(e) {} + + /// Constructor to be used when creating a new anonymous object + Torus(); + /// Constructor to be used when creating a identified new object + Torus(const std::string& name); + /// Constructor to be used when creating a new anonymous object with attribute initialization + Torus(double r, double rmin, double rmax, double phi=M_PI, double delta_phi=2.*M_PI); + /// Constructor to be used when creating a new identified object with attribute initialization + Torus(const std::string& name, double r, double rmin, double rmax, double phi=M_PI, double delta_phi=2.*M_PI); + /// Set the Torus dimensions + Torus& setDimensions(double r, double rmin, double rmax, double phi, double delta_phi); + }; + + /**@class Sphere Shapes.h + * + * @author M.Frank + * @version 1.0 + */ + struct Sphere : public Solid_type<TGeoSphere> { + /// Constructor to be used when reading the already parsed object + template <typename Q> Sphere(const Handle<Q>& e) : Solid_type<Implementation>(e) {} + + /// Constructor to be used when creating a new anonymous object + Sphere(); + /// Constructor to be used when creating a identified new object + Sphere(const std::string& name); + /// Constructor to be used when creating a new anonymous object with attribute initialization + Sphere(double rmin, double rmax, double theta=0., double delta_theta=M_PI, double phi=0.0, double delta_phi=2.*M_PI); + /// Constructor to be used when creating a new identified object with attribute initialization + Sphere(const std::string& name, double rmin, double rmax, double theta=0., double delta_theta=M_PI, double phi=0., double delta_phi=2.*M_PI); + /// Set the Sphere dimensions + Sphere& setDimensions(double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi); + }; + + /**@class Paraboloid Shapes.h + * + * @author M.Frank + * @version 1.0 + */ + struct Paraboloid : public Solid_type<TGeoParaboloid> { + /// Constructor to be used when reading the already parsed object + template <typename Q> Paraboloid(const Handle<Q>& e) : Solid_type<Implementation>(e) {} + + /// Constructor to be used when creating a new anonymous object + Paraboloid(); + /// Constructor to be used when creating a new identified object + Paraboloid(const std::string& name); + /// Constructor to be used when creating a new anonymous object with attribute initialization + Paraboloid(double r_low, double r_high, double delta_z); + /// Constructor to be used when creating a new identified object with attribute initialization + Paraboloid(const std::string& name, double r_low, double r_high, double delta_z); + /// Set the Paraboloid dimensions + Paraboloid& setDimensions(double r_low, double r_high, double delta_z); + }; + /**@class PolyhedraRegular Shapes.h * * @author M.Frank @@ -258,8 +383,11 @@ namespace DD4hep { /// Constructor to be used when reading the already parsed object template <typename Q> PolyhedraRegular(const Handle<Q>& e) : Solid_type<Implementation>(e) {} + /// Constructor to be used when creating a new object - PolyhedraRegular(LCDD& lcdd, const std::string& name, int nsides, double rmin, double rmax, double zlen); + PolyhedraRegular(int nsides, double rmin, double rmax, double zlen); + /// Constructor to be used when creating a new object + PolyhedraRegular(const std::string& name, int nsides, double rmin, double rmax, double zlen); }; /**@class BooleanSolid Shapes.h @@ -276,9 +404,6 @@ namespace DD4hep { /// Constructor to be used when reading the already parsed object template <typename Q> BooleanSolid(const Handle<Q>& e) : Solid_type<Implementation>(e) {} - - /// Constructor to be used when creating a new object - BooleanSolid(LCDD& lcdd, const std::string& type, const std::string& name, const std::string& expr); }; /**@class SubtractionSolid Shapes.h @@ -290,11 +415,37 @@ namespace DD4hep { /// Constructor to be used when reading the already parsed object template<typename Q> SubtractionSolid(const Handle<Q>& e) : BooleanSolid(e) {} /// Constructor to be used when creating a new object - SubtractionSolid(LCDD& lcdd, const std::string& name, const std::string& expr); + SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot); + /// Constructor to be used when creating a new object + SubtractionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot); + }; + + /**@class UnionSolid Shapes.h + * + * @author M.Frank + * @version 1.0 + */ + struct UnionSolid : public BooleanSolid { + /// Constructor to be used when reading the already parsed object + template<typename Q> UnionSolid(const Handle<Q>& e) : BooleanSolid(e) {} + /// Constructor to be used when creating a new object + UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot); + /// Constructor to be used when creating a new object + UnionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot); + }; + + /**@class IntersectionSolid Shapes.h + * + * @author M.Frank + * @version 1.0 + */ + struct IntersectionSolid : public BooleanSolid { + /// Constructor to be used when reading the already parsed object + template<typename Q> IntersectionSolid(const Handle<Q>& e) : BooleanSolid(e) {} /// Constructor to be used when creating a new object - SubtractionSolid(LCDD& lcdd, const std::string& name, const Solid& shape1, const Solid& shape2); + IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot); /// Constructor to be used when creating a new object - SubtractionSolid(LCDD& lcdd, const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot); + IntersectionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot); }; } /* End namespace Geometry */ diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 07dba2baa7e9c27503b87062f11be5c33a55ae96..0ce4a19c7d93c4631eaa0077f56a8f12f104018e 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -90,6 +90,11 @@ namespace DD4hep { * @version 1.0 */ struct Volume : public Handle<TGeoVolume> { + protected: + //void inc_ref(); + //void dec_ref(); + + public: typedef Handle<TGeoVolume> Base; struct Object { unsigned long magic; @@ -97,7 +102,8 @@ namespace DD4hep { LimitSet limits; VisAttr vis; Ref_t sens_det; - Object() : region(), limits(), vis(), sens_det() {} + int referenced; + Object() : region(), limits(), vis(), sens_det(), referenced(0) {} }; /// Default constructor Volume() : Base(0) {} @@ -109,10 +115,10 @@ namespace DD4hep { template <typename T> Volume(const Handle<T>& v) : Base(v) {} /// Constructor to be used when creating a new geometry tree. - Volume(LCDD& lcdd, const std::string& name); + Volume(const std::string& name); /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes - Volume(LCDD& lcddument, const std::string& name, const Solid& s, const Material& m); + Volume(const std::string& name, const Solid& s, const Material& m); /// Place daughter volume. The position and rotation are the identity PlacedVolume placeVolume(const Volume& vol) const @@ -189,7 +195,7 @@ namespace DD4hep { 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); + Assembly(const std::string& name); }; } /* End namespace Geometry */ diff --git a/DDCore/include/XML/XMLDetector.h b/DDCore/include/XML/XMLDetector.h index af41be26c337832989b4c14a88def441cbaa0bfa..ea5457988d9260a49ca38d74b6fdc0552572a485 100644 --- a/DDCore/include/XML/XMLDetector.h +++ b/DDCore/include/XML/XMLDetector.h @@ -6,8 +6,8 @@ // Author : M.Frank // //==================================================================== -#ifndef DD4hep_XMLDETECTOR_H -#define DD4hep_XMLDETECTOR_H +#ifndef DD4HEP_XMLDETECTOR_H +#define DD4HEP_XMLDETECTOR_H // Framework include files #include "XML/XMLTags.h" @@ -138,4 +138,4 @@ namespace DD4hep { }; } } /* End namespace DD4hep */ -#endif /* DD4hep_XMLDETECTOR_H */ +#endif /* DD4HEP_XMLDETECTOR_H */ diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index bc2c7913025770464d545f2a4d4f0de76d61b7de..e77e86ad1cdbba46754a3940c71293424ca470c5 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -47,11 +47,34 @@ static bool traverse_up(const DetElement& parent, const DetElement& child, vecto return true; } #include <iostream> +static string find_path(TGeoNode* top, TGeoNode* child) { + if ( top == child ) { + return child->GetName(); + } + TIter next(top->GetVolume()->GetNodes()); + for (TGeoNode *daughter=(TGeoNode*)next(); daughter; daughter=(TGeoNode*)next() ) { + if ( daughter == child ) { + return child->GetName(); + } + } + next.Reset(); + for (TGeoNode *daughter=(TGeoNode*)next(); daughter; daughter=(TGeoNode*)next() ) { + string res = find_path(daughter, child); + if ( !res.empty() ) { + return top->GetName() + ("/"+res); + } + } + return ""; +} + static string find_child(TGeoNode* top, TGeoNode* child, vector<TGeoNode*>& path) { + if ( top == child ) { + path.push_back(child); + return child->GetName(); + } TIter next(top->GetVolume()->GetNodes()); for (TGeoNode *daughter=(TGeoNode*)next(); daughter; daughter=(TGeoNode*)next() ) { if ( daughter == child ) { - cout << "Found child:" << child->GetName() << endl; path.push_back(daughter); return child->GetName(); } @@ -112,6 +135,16 @@ static TGeoHMatrix* create_trafo(const Ref_t& parent, const Ref_t& child) { throw runtime_error("DetElement cannot connect nonexisting parent to not-existing child!"); } +/// Top detector element +static DetElement _top(DetElement o) { + DetElement par = o, pp = o; + while(par.isValid()) { + if ( par.placement().isValid() ) pp = par; + par = par.parent(); + } + return pp; +} + /// Default constructor DetElement::Object::Object() : magic(magic_word()), id(0), combine_hits(0), readout(), @@ -149,18 +182,11 @@ void DetElement::Object::deepCopy(const Object& source, int new_id, int flag) { child._data().parent = self; } else { - throw runtime_error("DetElement::add: Element "+string(child.name())+" is already present [Double-Insert]"); + throw runtime_error("DetElement::copy: Element "+string(child.name())+" is already present [Double-Insert]"); } } } -/// Top detector element -Ref_t DetElement::Object::top() { - // This is an ugly staement. Need to rethink it a bit.....(MSF) - if ( !this->parent.isValid() ) return this->asRef(); - return DetElement(this->parent)._data().top(); -} - /// Conversion to reference object Ref_t DetElement::Object::asRef() { return Ref_t(dynamic_cast<Value<TNamed,DetElement::Object>*>(this)); @@ -174,7 +200,7 @@ DetElement::Object::operator Ref_t() { /// Create cached matrix to transform to world coordinates TGeoMatrix* DetElement::Object::worldTransformation() { if ( !worldTrafo ) { - DetElement top_det(this->top()); + DetElement top_det = _top(DetElement(asRef())); vector<TGeoMatrix*> trafos; TGeoHMatrix* mat = create_trafo(top_det,asRef()); // Now we got the point in the top-most detector element. We now have @@ -209,17 +235,35 @@ TGeoMatrix* DetElement::Object::referenceTransformation() { } /// Constructor for a new subdetector element -DetElement::DetElement(const LCDD& /* lcdd */, const string& name, const string& type, int id) -{ +DetElement::DetElement(const string& name, const string& type, int id) { assign(new Value<TNamed,Object>(),name,type); _data().id = id; } /// Constructor for a new subdetector element -DetElement::DetElement(const string& name, const string& type, int id) -{ - assign(new Value<TNamed,Object>(),name,type); +DetElement::DetElement(const string& name, int id) { + assign(new Value<TNamed,Object>(),name,""); + _data().id = id; +} + +/// Constructor for a new subdetector element +DetElement::DetElement(DetElement parent, const string& name, int id) { + assign(new Value<TNamed,Object>(),name,""); _data().id = id; + parent.add(*this); +} + +/// Access to the full path to the placed object +std::string DetElement::placementPath() const { + if ( isValid() ) { + Object& o = _data(); + if ( o.placementPath.empty() ) { + DetElement top =_top(*this); + o.placementPath = find_path(top.placement().ptr(),placement().ptr()); + } + return o.placementPath; + } + return ""; } string DetElement::type() const { @@ -261,9 +305,20 @@ const DetElement::Children& DetElement::children() const { /// Access to individual children by name DetElement DetElement::child(const std::string& name) const { - const Children& c = _data().children; - Children::const_iterator i = c.find(name); - return i == c.end() ? DetElement() : (*i).second; + if ( isValid() ) { + const Children& c = _data().children; + Children::const_iterator i = c.find(name); + return i == c.end() ? DetElement() : (*i).second; + } + return DetElement(); +} + +/// Access to the detector elements's parent +DetElement DetElement::parent() const { + if ( isValid() ) { + return _data().parent; + } + return DetElement(); } void DetElement::check(bool condition, const string& msg) const { @@ -272,7 +327,7 @@ void DetElement::check(bool condition, const string& msg) const { } } -DetElement& DetElement::add(const DetElement& sdet) { +DetElement& DetElement::add(DetElement sdet) { if ( isValid() ) { pair<Children::iterator,bool> r = _data().children.insert(make_pair(sdet.name(),sdet)); if ( r.second ) { @@ -316,45 +371,35 @@ DetElement& DetElement::setPlacement(const PlacedVolume& placement) { Object& o = _data(); o.placement = placement; o.volume = placement.volume(); - //placement.setDetElement(*this); return *this; } - throw runtime_error("DetElement::addPlacement: Placement is not defined [Invalid Handle]"); + throw runtime_error("DetElement::setPlacement: Placement is not defined [Invalid Handle]"); } - throw runtime_error("DetElement::addPlacement: Self is not defined [Invalid Handle]"); -} -#if 0 -DetElement::Placements DetElement::placements() const { - return _data().placements; + throw runtime_error("DetElement::setPlacement: Self is not defined [Invalid Handle]"); } -// OBSOLETE: to be replaced by setPlacement -DetElement& DetElement::addPlacement(const PlacedVolume& placement) { - if ( isValid() ) { - if ( placement.isValid() ) { - _data().placements.push_back(placement); - setPlacement(placement); - return *this; - } - throw runtime_error("DetElement::addPlacement: Placement is not defined [Invalid Handle]"); - } - throw runtime_error("DetElement::addPlacement: Self is not defined [Invalid Handle]"); -} -#endif /// Access to the logical volume of the placements (all daughters have the same!) -Volume DetElement::volume() const { +Volume DetElement::volume() const { if ( isValid() ) { return _data().volume; } throw runtime_error("DetElement::volume: Self is not defined [Invalid Handle]"); } - +#if 0 +/// Set the logical volume of the placements (all daughters have the same!) +void DetElement::setVolume(Volume vol) { + if ( isValid() ) { + _data().volume = vol; + } + throw runtime_error("DetElement::setVolume: Self is not defined [Invalid Handle]"); +} +#endif DetElement& DetElement::setVisAttributes(const LCDD& lcdd, const string& name, const Volume& volume) { if ( isValid() ) { volume.setVisAttributes(lcdd,name); return *this; } - throw runtime_error("DetElement::setRegion: Self is not defined [Invalid Handle]"); + throw runtime_error("DetElement::setVisAttributes: Self is not defined [Invalid Handle]"); } DetElement& DetElement::setRegion(const LCDD& lcdd, const string& name, const Volume& volume) { diff --git a/DDCore/src/Geant4Converter.cpp b/DDCore/src/Geant4Converter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f57928b91d1569e2a16b2646b0686a338e12b44d --- /dev/null +++ b/DDCore/src/Geant4Converter.cpp @@ -0,0 +1,313 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +#include "DD4hep/LCDD.h" +#include "Geant4Converter.h" +// ROOT includes +#include "TROOT.h" +#include "TColor.h" +#include "TGeoShape.h" +#include "TGeoCone.h" +#include "TGeoParaboloid.h" +#include "TGeoPcon.h" +#include "TGeoPgon.h" +#include "TGeoSphere.h" +#include "TGeoTorus.h" +#include "TGeoTube.h" +#include "TGeoTrd1.h" +#include "TGeoTrd2.h" +#include "TGeoArb8.h" +#include "TGeoMatrix.h" +#include "TGeoBoolNode.h" +#include "TGeoCompositeShape.h" +#include "TGeoNode.h" +#include "TClass.h" +#include "TMath.h" +#include <iostream> + +using namespace DD4hep::Geometry; +using namespace DD4hep; +using namespace std; + +namespace { + static string indent = ""; + struct MyTransform3D : public G4Transform3D { + MyTransform3D() : G4Transform3D() {} + // Set transformation matrix + void set(double XX, double XY, double XZ, double DX, + double YX, double YY, double YZ, double DY, + double ZX, double ZY, double ZZ, double DZ) {} + // { G4Transform3D::setTransform(XX,XY,XZ,DX,YX,YY,YZ,DY,ZX,ZY,ZZ,DZ); } + }; +} + +/// Dump element in GDML format to output stream +void* Geant4Converter::handleElement(const string& name, const TGeoElement* element) const { + G4Element* g4e = data().g4Elements[element]; + if ( !g4e ) { + g4e = G4Element::GetElement(name,false); + if ( !g4e ) { + if ( element->GetNisotopes() > 1 ) { + g4e = new G4Element(name,element->GetTitle(),element->GetNisotopes()); + for(int i=0, n=element->GetNisotopes(); i<n; ++i) { + TGeoIsotope* iso = element->GetIsotope(i); + G4Isotope* g4iso = G4Isotope::GetIsotope(iso->GetName(),false); + if ( !g4iso ) { + g4iso = new G4Isotope(iso->GetName(),iso->GetZ(),iso->GetN(),iso->GetA()); + } + g4e->AddIsotope(g4iso,element->GetRelativeAbundance(i)); + } + } + else { + g4e = new G4Element(name,element->GetTitle(),element->A(),element->Z()); + } + } + data().g4Elements[element] = g4e; + } + return g4e; +} + +/// Dump material in GDML format to output stream +void* Geant4Converter::handleMaterial(const std::string& name, const TGeoMedium* medium) const { + G4Material* mat = data().g4Materials[medium]; + if ( !mat ) { + mat = G4Material::GetMaterial(name,false); + if ( !mat ) { + TGeoMaterial* m = medium->GetMaterial(); + if ( m->IsMixture() ) { + TGeoMixture* mix = (TGeoMixture*)m; + mat = new G4Material(name,mix->GetDensity(),mix->GetNelements()); + for(int i=0, n=mix->GetNelements(); i<n; ++i) { + TGeoElement* e = mix->GetElement(i); + G4Element* g4e = (G4Element*)handleElement(e->GetName(),e); + mat->AddElement(g4e,(mix->GetWmixt())[i]); + } + } + else { + mat = new G4Material(name,m->GetZ(),m->GetA(),m->GetDensity()); + } + } + data().g4Materials[medium] = mat; + } + return mat; +} + +/// Dump solid in GDML format to output stream +void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) const { + G4VSolid* solid = data().g4Solids[shape]; + if ( !solid && shape ) { + if ( shape->IsA() == TGeoBBox::Class() ) { + const TGeoBBox* s = (const TGeoBBox*)shape; + solid = new G4Box(name,s->GetDX()*CM_2_MM,s->GetDY()*CM_2_MM,s->GetDZ()*CM_2_MM); + } + else if ( shape->IsA() == TGeoTube::Class() ) { + const TGeoTube* s = (const TGeoTube*)shape; + solid = new G4Tubs(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM,s->GetDz()*CM_2_MM,0,2.*M_PI); + } + else if ( shape->IsA() == TGeoTubeSeg::Class() ) { + const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape; + solid = new G4Tubs(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM,s->GetDz()*CM_2_MM,s->GetPhi1()*DEGREE_2_RAD,s->GetPhi2()*DEGREE_2_RAD); + } + else if ( shape->IsA() == TGeoTrd1::Class() ) { + const TGeoTrd1* s = (const TGeoTrd1*)shape; + solid = new G4Trd(name,s->GetDx1()*CM_2_MM,s->GetDx2()*CM_2_MM,s->GetDy()*CM_2_MM,s->GetDy()*CM_2_MM,s->GetDz()*CM_2_MM); + } + else if ( shape->IsA() == TGeoTrd2::Class() ) { + const TGeoTrd2* s = (const TGeoTrd2*)shape; + solid = new G4Trd(name,s->GetDx1()*CM_2_MM,s->GetDx2()*CM_2_MM,s->GetDy1()*CM_2_MM,s->GetDy2()*CM_2_MM,s->GetDz()*CM_2_MM); + } + else if ( shape->IsA() == TGeoPgon::Class() ) { +#if 0 + const TGeoPgon* s = (const TGeoPgon*)shape; +#endif + const TGeoPcon* s = (const TGeoPcon*)shape; + vector<double> rmin, rmax, z; + for( size_t i=0; i<s->GetNz(); ++i ) { + rmin.push_back(s->GetRmin(i)*CM_2_MM); + rmax.push_back(s->GetRmax(i)*CM_2_MM); + z.push_back(s->GetZ(i)*CM_2_MM); + } + solid = new G4Polycone(name,s->GetPhi1()*DEGREE_2_RAD,(s->GetDphi()+s->GetPhi1())*DEGREE_2_RAD,s->GetNz(), + &rmin[0], &rmax[0], &z[0]); + } + else if ( shape->IsA() == TGeoPcon::Class() ) { + const TGeoPcon* s = (const TGeoPcon*)shape; + vector<double> rmin, rmax, z; + for( size_t i=0; i<s->GetNz(); ++i ) { + rmin.push_back(s->GetRmin(i)*CM_2_MM); + rmax.push_back(s->GetRmax(i)*CM_2_MM); + z.push_back(s->GetZ(i)*CM_2_MM); + } + solid = new G4Polycone(name,s->GetPhi1()*DEGREE_2_RAD,(s->GetDphi()+s->GetPhi1())*DEGREE_2_RAD,s->GetNz(), + &rmin[0], &rmax[0], &z[0]); + } + else if ( shape->IsA() == TGeoParaboloid::Class() ) { + const TGeoParaboloid* s = (const TGeoParaboloid*)shape; + solid = new G4Paraboloid(name,s->GetDz()*CM_2_MM,s->GetRlo()*CM_2_MM,s->GetRhi()*CM_2_MM); + } + else if ( shape->IsA() == TGeoSphere::Class() ) { + const TGeoSphere* s = (const TGeoSphere*)shape; + solid = new G4Sphere(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM, + s->GetPhi1()*DEGREE_2_RAD,s->GetPhi2()*DEGREE_2_RAD, + s->GetTheta1()*DEGREE_2_RAD,s->GetTheta2()*DEGREE_2_RAD); + } + else if ( shape->IsA() == TGeoTorus::Class() ) { + const TGeoTorus* s = (const TGeoTorus*)shape; + solid = new G4Torus(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM, s->GetR()*CM_2_MM, + s->GetPhi1()*DEGREE_2_RAD,s->GetDphi()*DEGREE_2_RAD); + } + else if ( shape->IsA() == TGeoCompositeShape::Class() ) { + const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape; + const TGeoBoolNode* boolean = s->GetBoolNode(); + TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); + TGeoMatrix* m = boolean->GetRightMatrix(); + G4VSolid* left = (G4VSolid*)handleSolid(name+"_left", boolean->GetLeftShape()); + G4VSolid* right = (G4VSolid*)handleSolid(name+"_right",boolean->GetRightShape()); + const Double_t *t = m->GetTranslation(); + const Double_t *r = m->GetRotationMatrix(); + + if ( !left ) { + throw runtime_error("G4Converter: No left Geant4 Solid present for composite shape:"+name); + } + if ( !right ) { + throw runtime_error("G4Converter: No right Geant4 Solid present for composite shape:"+name); + } + + if ( m->IsRotation() ) { + MyTransform3D transform; + transform.set(r[0],r[1],r[2],t[0], + r[3],r[4],r[5],t[1], + r[6],r[7],r[8],t[3]); + if ( oper == TGeoBoolNode::kGeoSubtraction ) + solid = new G4SubtractionSolid(name,left,right,transform); + else if ( oper == TGeoBoolNode::kGeoUnion ) + solid = new G4UnionSolid(name,left,right,transform); + else if ( oper == TGeoBoolNode::kGeoIntersection ) + solid = new G4IntersectionSolid(name,left,right,transform); + } + else { + G4ThreeVector transform(t[0],t[1],t[2]); + if ( oper == TGeoBoolNode::kGeoSubtraction ) + solid = new G4SubtractionSolid(name,left,right,0,transform); + else if ( oper == TGeoBoolNode::kGeoUnion ) + solid = new G4UnionSolid(name,left,right,0,transform); + else if ( oper == TGeoBoolNode::kGeoIntersection ) + solid = new G4IntersectionSolid(name,left,right,0,transform); + } + } + + if ( !solid ) { + string err = "Failed to handle unknown solid shape:" + + name + " of type " + string(shape->IsA()->GetName()); + throw runtime_error(err); + } + data().g4Solids[shape] = solid; + } + return solid; +} + +/// Dump logical volume in GDML format to output stream +void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume) const { + const TGeoVolume* v = volume; + G4LogicalVolume* vol = data().g4Volumes[v]; + if ( !vol ) { + string n = v->GetName(); + TGeoMedium* m = v->GetMedium(); + TGeoShape* s = v->GetShape(); + G4VSolid* solid = (G4VSolid*)handleSolid(s->GetName(),s); + G4Material* medium = (G4Material*)handleMaterial(m->GetName(),m); + + if ( !solid ) { + throw runtime_error("G4Converter: No Geant4 Solid present for volume:"+n); + } + if ( !medium ) { + throw runtime_error("G4Converter: No Geant4 material present for volume:"+n); + } + vol = new G4LogicalVolume(solid, medium, n); + data().g4Volumes[v] = vol; + } + return vol; +} + +/// Dump volume placement in GDML format to output stream +void* Geant4Converter::handlePlacement(const std::string& name, const TGeoNode* node) const { + G4PVPlacement* g4pv = data().g4Placements[node]; + if ( !g4pv ) { + TGeoMatrix* trafo = node->GetMatrix(); + if ( trafo ) { + const Double_t* trans = trafo->GetTranslation(); + const Double_t* rot = trafo->GetRotationMatrix(); + int copy = node->GetNumber(); + G4LogicalVolume* g4vol = data().g4Volumes[node->GetVolume()]; + G4LogicalVolume* g4mot = data().g4Volumes[node->GetMotherVolume()]; + + if ( trafo->IsRotation() ) { + MyTransform3D transform; + transform.set(rot[0],rot[1],rot[2],trans[0], + rot[3],rot[4],rot[5],trans[1], + rot[6],rot[7],rot[8],trans[3]); + g4pv = new G4PVPlacement(transform, // no rotation + g4vol, // its logical volume + name, // its name + g4mot, // its mother (logical) volume + false, // no boolean operations + copy); // its copy number + } + else { + G4ThreeVector pos(trans[0],trans[1],trans[2]); + g4pv = new G4PVPlacement(0, // no rotation + pos, // translation position + g4vol, // its logical volume + name, // its name + g4mot, // its mother (logical) volume + false, // no boolean operations + copy); // its copy number + } + data().g4Placements[node] = g4pv; + // cout << "Created volume placement:" << name << " No:" << copy << endl; + } + } + else { + cout << "Attempt to DOUBLE-place physical volume:" << name << " No:" << node->GetNumber() << endl; + } + return g4pv; +} + +template <typename O, typename C, typename F> void handle(const O* o, const C& c, F pmf) { + for(typename C::const_iterator i=c.begin(); i != c.end(); ++i) { + (o->*pmf)((*i).first, (*i).second); + } +} + +static void handleName(const TGeoNode* n) { + TGeoVolume* v = n->GetVolume(); + TGeoMedium* m = v->GetMedium(); + TGeoShape* s = v->GetShape(); + string nam; + cout << "Node:'" << n->GetName() << "' Vol:'" << v->GetName() << "' Shape:'" << s->GetName() << "' Medium:'" << m->GetName() << "'" << endl; +} + +void Geant4Converter::create(DetElement top) { + G4GeometryInfo geo; + m_dataPtr = &geo; + m_data->clear(); + collect(top,geo); + + handle(this, geo.materials, &Geant4Converter::handleMaterial); + handle(this, geo.solids, &Geant4Converter::handleSolid); + handle(this, geo.volumes, &Geant4Converter::handleVolume); + + for(Data::const_reverse_iterator i=m_data->rbegin(); i != m_data->rend(); ++i) { + const Data::mapped_type& v = (*i).second; + for(Data::mapped_type::const_iterator j=v.begin(); j != v.end(); ++j) { + handlePlacement((*j)->GetName(),*j); + handleName(*j); + } + } +} diff --git a/DDCore/src/Geant4Converter.h b/DDCore/src/Geant4Converter.h new file mode 100644 index 0000000000000000000000000000000000000000..95fa5d8e159f0c0e37fa8aedcb084843a168ed32 --- /dev/null +++ b/DDCore/src/Geant4Converter.h @@ -0,0 +1,100 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_GEANT4CONVERTER_H +#define DD4HEP_GEANT4CONVERTER_H + +#include "DD4hep/GeoHandler.h" +#include "DD4hep/LCDD.h" +#include <set> +#include <map> +#include <vector> +class TGeoVolume; +class TGeoNode; + +struct G4VAny { virtual ~G4VAny() {} }; + +template <class T> class G4AnyThing : public T { + public: + G4AnyThing() : T() {} + template <class A> G4AnyThing(A) : T() {} + template <class A,class B> G4AnyThing(A,B) : T() {} + template <class A,class B,class C> G4AnyThing(A,B,C) : T() {} + template <class A, class B, class C, class D> G4AnyThing(A,B,C,D) : T() {} + template <class A, class B, class C, class D, class E> G4AnyThing(A,B,C,D,E) : T() {} + template <class A, class B, class C, class D, class E, class F> G4AnyThing(A,B,C,D,E,F) : T() {} + template <class A, class B, class C, class D, class E, class F, class G> G4AnyThing(A,B,C,D,E,F,G) : T() {} + template <class A, class B, class C, class D, class E, class F, class G, class H> G4AnyThing(A,B,C,D,E,F,G,H) : T() {} + template <class A, class B, class C, class D, class E, class F, class G, class H, class I> G4AnyThing(A,B,C,D,E,F,G,H,I) : T() {} + void AddIsotope(void*, double) {} + void AddElement(void*, double) {} + static G4AnyThing<G4VAny>* GetIsotope(const std::string&, bool) { return 0; } + static G4AnyThing<G4VAny>* GetElement(const std::string&, bool) { return 0; } + static G4AnyThing<G4VAny>* GetMaterial(const std::string&, bool) { return 0; } + int GetNelements() const { return 0; } + double GetDensity() const { return 0.0; } +}; + +typedef G4VAny G4VSolid; +typedef G4AnyThing<G4VSolid> G4Box; +typedef G4AnyThing<G4VSolid> G4Tubs; +typedef G4AnyThing<G4VSolid> G4Trd; +typedef G4AnyThing<G4VSolid> G4Paraboloid; +typedef G4AnyThing<G4VSolid> G4Polycone; +typedef G4AnyThing<G4VSolid> G4Sphere; +typedef G4AnyThing<G4VSolid> G4Torus; +typedef G4AnyThing<G4VSolid> G4UnionSolid; +typedef G4AnyThing<G4VSolid> G4SubtractionSolid; +typedef G4AnyThing<G4VSolid> G4IntersectionSolid; + +typedef G4AnyThing<G4VAny> G4LogicalVolume; +typedef G4AnyThing<G4VAny> G4Material; +typedef G4AnyThing<G4VAny> G4Element; +typedef G4AnyThing<G4VAny> G4Isotope; +typedef G4AnyThing<G4VAny> G4Transform3D; +typedef G4AnyThing<G4VAny> G4ThreeVector; +typedef G4AnyThing<G4VAny> G4PVPlacement; + + +namespace DD4hep { + namespace Geometry { + + struct Geant4Converter : public GeoHandler { + struct G4GeometryInfo : public GeometryInfo { + std::map<const TGeoElement*,G4Element*> g4Elements; + std::map<const TGeoMedium*, G4Material*> g4Materials; + std::map<const TGeoShape*, G4VSolid*> g4Solids; + std::map<const TGeoVolume*, G4LogicalVolume*> g4Volumes; + std::map<const TGeoNode*, G4PVPlacement*> g4Placements; + }; + G4GeometryInfo* m_dataPtr; + G4GeometryInfo& data() const { return *m_dataPtr; } + + /// Constructor + Geant4Converter() {} + /// Standard destructor + virtual ~Geant4Converter() {} + /// Create geometry dump + void create(DetElement top); + + /// Dump material in GDML format to output stream + virtual void* handleMaterial(const std::string& name, const TGeoMedium* medium) const; + /// Dump element in GDML format to output stream + virtual void* handleElement(const std::string& name, const TGeoElement* element) const; + /// Dump solid in GDML format to output stream + virtual void* handleSolid(const std::string& name, const TGeoShape* volume) const; + /// Dump logical volume in GDML format to output stream + virtual void* handleVolume(const std::string& name, const TGeoVolume* volume) const; + /// Dump volume placement in GDML format to output stream + virtual void* handlePlacement(const std::string& name, const TGeoNode* node) const; + }; + } // End namespace Geometry +} // End namespace DD4hep + +#endif // DD4HEP_GEANT4CONVERTER_H + diff --git a/DDCore/src/GeoHandler.cpp b/DDCore/src/GeoHandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4dc91c79622c3a3e7b48ee238a1317c5130bb8f5 --- /dev/null +++ b/DDCore/src/GeoHandler.cpp @@ -0,0 +1,116 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +#include "DD4hep/LCDD.h" +#include "DD4hep/GeoHandler.h" + +// ROOT includes +#include "TGeoManager.h" +#include "TGeoCompositeShape.h" +#include "TGeoBoolNode.h" + +// C/C++ include files +#include <iostream> + +using namespace DD4hep::Geometry; +using namespace DD4hep; +using namespace std; + +namespace { + void collectSolid(GeoHandler::GeometryInfo& geo, const string& name, const string& node, TGeoShape* shape, TGeoMatrix* matrix) { + if ( shape->IsA() == TGeoCompositeShape::Class() ) { + const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape; + const TGeoBoolNode* boolean = s->GetBoolNode(); + collectSolid(geo, name+"_left", name+"_left", boolean->GetLeftShape(), boolean->GetLeftMatrix()); + collectSolid(geo, name+"_right", name+"_right", boolean->GetRightShape(), boolean->GetRightMatrix()); + } + geo.solids.insert(make_pair(name,shape)); + geo.trafos.push_back(make_pair(node,matrix)); + } +} + +/// Default constructor +GeoHandler::GeoHandler() { + m_data = new Data(); +} + +/// Initializing constructor +GeoHandler::GeoHandler(Data* ptr) : m_data(ptr) { +} + +/// Default destructor +GeoHandler::~GeoHandler() { + if ( m_data ) delete m_data; + m_data = 0; +} + +GeoHandler::Data* GeoHandler::release() { + Data* d = m_data; + m_data = 0; + return d; +} + +GeoHandler& GeoHandler::collect(DetElement element) { + m_data->clear(); + return i_collect(element.placement().ptr(),0); +} + +GeoHandler& GeoHandler::collect(DetElement element, GeometryInfo& info) { + m_data->clear(); + i_collect(element.placement().ptr(),0); + for(Data::const_reverse_iterator i=m_data->rbegin(); i != m_data->rend(); ++i) { + int level = (*i).first; + const Data::mapped_type& v = (*i).second; + for(Data::mapped_type::const_iterator j=v.begin(); j != v.end(); ++j) { + const TGeoNode* n = *j; + TGeoVolume* v = n->GetVolume(); + TGeoMedium* m = v->GetMedium(); + Volume vol = Handle<>(v); + VisAttr vis = vol.visAttributes(); + + info.volumes.insert(make_pair(v->GetName(),v)); + info.materials[m->GetName()] = m; + if ( vis.isValid() ) info.vis[v->GetName()] = vis; + collectSolid(info,v->GetName(),n->GetName(),v->GetShape(),n->GetMatrix()); + } + } + return *this; +} + +GeoHandler& GeoHandler::i_collect(const TGeoNode* current, int level) { + TGeoVolume* volume = current->GetVolume(); + TObjArray* nodes = volume->GetNodes(); + int num_children = nodes ? nodes->GetEntriesFast() : 0; + + (*m_data)[level].insert(current); + if ( num_children > 0 ) { + for(int i=0; i<num_children; ++i) { + TGeoNode* node = (TGeoNode*)nodes->At(i); + i_collect(node,level+1); + } + } + return *this; +} + +/// Initializing constructor +GeoScan::GeoScan(DetElement e) { + m_data = GeoHandler().collect(e).release(); +} + +/// Default destructor +GeoScan::~GeoScan() { + if ( m_data ) delete m_data; + m_data = 0; +} + +/// Work callback +GeoScan& GeoScan::operator()() { + return *this; +} + diff --git a/DDCore/src/GeometryTreeDump.cpp b/DDCore/src/GeometryTreeDump.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e4214b7870b43a18ff5e158315db0ade54b2194e --- /dev/null +++ b/DDCore/src/GeometryTreeDump.cpp @@ -0,0 +1,324 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +#include "DD4hep/LCDD.h" +#include "GeometryTreeDump.h" +// ROOT includes +#include "TROOT.h" +#include "TColor.h" +#include "TGeoShape.h" +#include "TGeoCone.h" +#include "TGeoParaboloid.h" +#include "TGeoPcon.h" +#include "TGeoPgon.h" +#include "TGeoSphere.h" +#include "TGeoTorus.h" +#include "TGeoTube.h" +#include "TGeoTrd1.h" +#include "TGeoTrd2.h" +#include "TGeoArb8.h" +#include "TGeoMatrix.h" +#include "TGeoBoolNode.h" +#include "TGeoCompositeShape.h" +#include "TClass.h" +#include "TGeoManager.h" +#include "TMath.h" +#include <iostream> + +using namespace DD4hep::Geometry; +using namespace DD4hep; +using namespace std; + +namespace { + string indent = ""; + + /// Reference to output stream + std::ostream& m_output = cout; + + + void getAngles(const Double_t* m, Double_t &phi, Double_t &theta, Double_t &psi) { + // Retreive Euler angles. + // Check if theta is 0 or 180. + if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) { + theta = TMath::ACos(m[8])*RAD_2_DEGREE; + phi = TMath::ATan2(-m[8]*m[1],m[0])*RAD_2_DEGREE; + psi = 0.; // convention, phi+psi matters + return; + } + // sin(theta) != 0 + phi = TMath::ATan2(m[2],-m[5]); + Double_t sphi = TMath::Sin(phi); + if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*RAD_2_DEGREE; + else theta = TMath::ASin(m[2]/sphi)*RAD_2_DEGREE; + phi *= RAD_2_DEGREE; + psi = TMath::ATan2(m[6],m[7])*RAD_2_DEGREE; + } +} + +/// Dump logical volume in GDML format to output stream +void* GeometryTreeDump::handleVolume(const string& name, const TGeoVolume* volume) const { + Volume vol = Handle<>(volume); + VisAttr vis = vol.visAttributes(); + TGeoShape* shape = volume->GetShape(); + TGeoMedium* medium = volume->GetMedium(); + int num = volume->GetNdaughters(); + + m_output << "\t\t<volume name=\"" << name << "\">" << endl; + m_output << "\t\t\t<solidref ref=\"" << shape->GetName() << "\"/>" << endl; + m_output << "\t\t\t<materialref ref=\"" << medium->GetName() << "\"/>" << endl; + if ( vis.isValid() ) { + m_output << "\t\t\t<visref ref=\"" << vis.name() << "\"/>" << endl; + } + if ( num > 0 ) { + for(int i=0; i<num; ++i) { + TGeoNode* n = volume->GetNode(i); + TGeoVolume* v = n->GetVolume(); + TGeoMatrix* m = n->GetMatrix(); + m_output << "\t\t\t<physvol>" << endl; + m_output << "\t\t\t\t<volumeref ref=\"" << v->GetName() << "\"/>" << endl; + if ( m ) { + if ( m->IsTranslation() ) { + m_output << "\t\t\t\t<positionref ref=\"" << n->GetName() << "_pos\"/>" << endl; + } + if ( m->IsRotation() ) { + m_output << "\t\t\t\t<rotationref ref=\"" << n->GetName() << "_rot\"/>" << endl; + } + } + m_output << "\t\t\t</physvol>" << endl; + } + } + m_output << "\t\t</volume>" << endl; + return 0; +} + +/// Dump solid in GDML format to output stream +void* GeometryTreeDump::handleSolid(const string& name, const TGeoShape* shape) const { + if ( shape ) { + if ( shape->IsA() == TGeoBBox::Class() ) { + const TGeoBBox* s = (const TGeoBBox*)shape; + m_output << "\t\t<box name=\"" << name << "_shape\" x=\"" + << s->GetDX() << "\" y=\"" + << s->GetDY() << "\" z=\"" + << s->GetDZ() << "\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTube::Class() ) { + const TGeoTube* s = (const TGeoTube*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" + << s->GetRmin() << "\" rmax=\"" + << s->GetRmax() << "\" z=\"" + << s->GetDz() << "\" startphi=\"0.0\" deltaphi=\"360.0\" aunit=\"deg\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTubeSeg::Class() ) { + const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" + << s->GetRmin() << "\" rmax=\"" + << s->GetRmax() << "\" z=\"" + << s->GetDz() << "\" startphi=\"" + << s->GetPhi1() << "\" deltaphi=\"" + << s->GetPhi2() << "\" aunit=\"deg\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTrd1::Class() ) { + const TGeoTrd1* s = (const TGeoTrd1*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\"" + << s->GetDx1() << "\" x2=\"" + << s->GetDx2() << "\" y1=\"" + << s->GetDy() << "\" y2=\"" + << s->GetDy() << "\" z=\"" + << s->GetDz() << "\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTrd2::Class() ) { + const TGeoTrd2* s = (const TGeoTrd2*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\"" + << s->GetDx1() << "\" x2=\"" + << s->GetDx2() << "\" y1=\"" + << s->GetDy1() << "\" y2=\"" + << s->GetDy2() << "\" z=\"" + << s->GetDz() << "\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoPgon::Class() ) { + const TGeoPgon* s = (const TGeoPgon*)shape; + m_output << "\t\t<polyhedra name=\"" << name << "_shape\" startphi=\"" + << s->GetPhi1() << "\" deltaphi=\"" + << s->GetDphi() << "\" numsides=\"" + << s->GetNedges() << "\" aunit=\"deg\" lunit=\"cm\">" << endl; + for(int i=0; i<s->GetNz(); ++i) { + m_output << "\t\t\t<zplane z=\"" << s->GetZ(i) + << "\" rmin=\"" << s->GetRmin(i) + << "\" rmax=\"" << s->GetRmax(i) + << "\" lunit=\"cm\"/>" << endl; + } + m_output << "\t\t</polyhedra>" << endl; + } + else if ( shape->IsA() == TGeoPcon::Class() ) { + const TGeoPcon* s = (const TGeoPcon*)shape; + m_output << "\t\t<polycone name=\"" << name << "_shape\" startphi=\"" + << s->GetPhi1() << "\" deltaphi=\"" + << s->GetDphi() << "\" aunit=\"deg\" lunit=\"cm\">" << endl; + for(int i=0; i<s->GetNz(); ++i) { + m_output << "\t\t\t<zplane z=\"" << s->GetZ(i) + << "\" rmin=\"" << s->GetRmin(i) + << "\" rmax=\"" << s->GetRmax(i) + << "\" lunit=\"cm\"/>" << endl; + } + m_output << "\t\t</polycone>" << endl; + } + else if ( shape->IsA() == TGeoCompositeShape::Class() ) { + string nn = name; + const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape; + const TGeoBoolNode* boolean = s->GetBoolNode(); + TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); + + handleSolid(name+"_left", boolean->GetLeftShape()); + handleSolid(name+"_right",boolean->GetRightShape()); + + if ( oper == TGeoBoolNode::kGeoSubtraction ) + m_output << "\t\t<subtraction name=\"" << nn << "\">" << endl; + else if ( oper == TGeoBoolNode::kGeoUnion ) + m_output << "\t\t<union name=\"" << nn << "\">" << endl; + else if ( oper == TGeoBoolNode::kGeoIntersection ) + m_output << "\t\t<intersection name=\"" << nn << "\">" << endl; + + m_output << "\t\t\t<first ref=\"" << nn << "_left\"/>" << endl; + m_output << "\t\t\t<second ref=\"" << nn << "_right\"/>" << endl; + indent = "\t"; + handleTransformation("", boolean->GetRightMatrix()); + indent = ""; + + if ( oper == TGeoBoolNode::kGeoSubtraction ) + m_output << "\t\t</subtraction>" << endl; + else if ( oper == TGeoBoolNode::kGeoUnion ) + m_output << "\t\t</union>" << endl; + else if ( oper == TGeoBoolNode::kGeoIntersection ) + m_output << "\t\t</intersection>" << endl; + } + else { + cerr << "Failed to handle unknwon solid shape:" + << shape->IsA()->GetName() << endl; + } + } + return 0; +} + +/// Dump structure information in GDML format to output stream +void GeometryTreeDump::handleStructure(const VolumeSet& volset) const { + m_output << "\t<structure>" << endl; + for(VolumeSet::const_iterator i=volset.begin(); i != volset.end(); ++i) + handleVolume((*i).first,(*i).second); + m_output << "\t</structure>" << endl; +} + +/// Dump single volume transformation in GDML format to output stream +void* GeometryTreeDump::handleTransformation(const string& name, const TGeoMatrix* m) const { + if ( m ) { + if ( m->IsTranslation() ) { + const Double_t* f = m->GetTranslation(); + m_output << indent << "\t\t<position "; + if ( !name.empty() ) m_output << "name=\"" << name << "_pos\" "; + m_output << "x=\"" << f[0] << "\" " + << "y=\"" << f[1] << "\" " + << "z=\"" << f[2] << "\" unit=\"cm\"/>" << endl; + } + if ( m->IsRotation() ) { + const Double_t* mat = m->GetRotationMatrix(); + Double_t theta=0.0, phi=0.0, psi=0.0; + getAngles(mat, theta, phi, psi); + m_output << indent << "\t\t<rotation "; + if ( !name.empty() ) m_output << "name=\"" << name << "_rot\" "; + m_output << "x=\"" << theta << "\" " + << "y=\"" << psi << "\" " + << "z=\"" << phi << "\" unit=\"deg\"/>" << endl; + } + } + return 0; +} + +/// Dump Transformations in GDML format to output stream +void GeometryTreeDump::handleTransformations(const TransformSet& trafos) const { + m_output << "\t<define>" << endl; + for(TransformSet::const_iterator i=trafos.begin(); i != trafos.end(); ++i) + handleTransformation((*i).first, (*i).second); + m_output << "\t</define>" << endl; +} + +/// Dump all solids in GDML format to output stream +void GeometryTreeDump::handleSolids(const SolidSet& solids) const { + m_output << "\t<solids>" << endl; + for(SolidSet::const_iterator i=solids.begin(); i != solids.end(); ++i) + handleSolid((*i).first, (*i).second); + m_output << "\t</solids>" << endl; +} + +/// Dump all constants in GDML format to output stream +void GeometryTreeDump::handleDefines(const LCDD::HandleMap& defs) const { + m_output << "\t<define>" << endl; + for(LCDD::HandleMap::const_iterator i=defs.begin(); i != defs.end(); ++i) + m_output << "\t\t<constant name=\"" << (*i).second->GetName() << "\" value=\"" << (*i).second->GetTitle() << "\" />" << endl; + m_output << "\t</define>" << endl; +} + +/// Dump all visualisation specs in LCDD format to output stream +void GeometryTreeDump::handleVisualisation(const LCDD::HandleMap& ) const { +} + +static string _path = ""; +static void dumpStructure(PlacedVolume pv, int level) { + TGeoNode* current = pv.ptr(); + TGeoVolume* volume = current->GetVolume(); + TObjArray* nodes = volume->GetNodes(); + int num_children = nodes ? nodes->GetEntriesFast() : 0; + char fmt[128]; + + _path += "/"; + _path += current->GetName(); + ::sprintf(fmt, "%%4d %%%ds %%7s %%s\n",level*2+5); + ::printf(fmt,level,"","->LV: ",volume->GetName()); + ::printf(fmt,level,"","->PV: ",current->GetName()); + ::printf(fmt,level,"","->path:",_path.c_str()); + if ( num_children > 0 ) { + for(int i=0; i<num_children; ++i) { + TGeoNode* node = (TGeoNode*)nodes->At(i); + dumpStructure(PlacedVolume(node),level+1); + } + } + _path = _path.substr(0,_path.length()-1-strlen(current->GetName())); +} + +static void dumpDetectors(DetElement parent,int level) { + const DetElement::Children& children = parent.children(); + PlacedVolume pl = parent.placement(); + char fmt[128]; + + _path += "/"; + _path += parent.name(); + ::sprintf(fmt, "%%4d %%%ds %%7s %%s\n",level*2+5); + ::printf(fmt,level,"","->path:",_path.c_str()); + if ( pl.isValid() ) { + ::printf(fmt,level,""," ->placement:",parent.placementPath().c_str()); + ::printf(fmt,level,""," ->logvol: ",pl->GetVolume()->GetName()); + ::printf(fmt,level,""," ->shape: ",pl->GetVolume()->GetShape()->GetName()); + } + for(DetElement::Children::const_iterator i=children.begin(); i!=children.end();++i) { + dumpDetectors((*i).second,level+1); + } + _path = _path.substr(0,_path.length()-1-strlen(parent.name())); +} + +void GeometryTreeDump::create(DetElement top) { + //PlacedVolume pv = top.placement(); + dumpDetectors(top,0); + dumpStructure(top.placement(),0); + //GeometryInfo geo; + //collect(top,geo); + //handleSetup(LCDD::getInstance().header()); + //handleDefines(LCDD::getInstance().constants()); + //handleVisualisation(geo.vis); + //handleTransformations(geo.trafos); + //handleSolids(geo.solids); + //handleStructure(geo.volumes); +} diff --git a/DDCore/src/GeometryTreeDump.h b/DDCore/src/GeometryTreeDump.h new file mode 100644 index 0000000000000000000000000000000000000000..955fbf42ba6d75eede8c2734a02e46f892b238e5 --- /dev/null +++ b/DDCore/src/GeometryTreeDump.h @@ -0,0 +1,64 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_GeometryTreeDump_H +#define DD4HEP_GeometryTreeDump_H + +#include "DD4hep/LCDD.h" +#include "DD4hep/GeoHandler.h" +#include <set> +#include <map> +#include <vector> +class TGeoVolume; +class TGeoNode; + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /* + * Geometry namespace declaration + */ + namespace Geometry { + + /** @class GeometryTreeDump GeometryTreeDump.h + * + * @author M.Frank + * @version 1.0 + */ + struct GeometryTreeDump : public GeoHandler { + GeometryTreeDump() {} + /// Standard destructor + virtual ~GeometryTreeDump() {} + /// Main entry point: create required object(s) + void create(DetElement top); + + /// Dump logical volume in GDML format to output stream + virtual void* handleVolume(const std::string& name, const TGeoVolume* volume) const; + /// Dump single volume transformation in GDML format to output stream + virtual void* handleTransformation(const std::string& name, const TGeoMatrix* matrix) const; + /// Dump solid in GDML format to output stream + virtual void* handleSolid(const std::string& name, const TGeoShape* volume) const; + + /// Dump all constants in GDML format to output stream + virtual void handleDefines(const LCDD::HandleMap& defs) const; + /// Dump all visualisation specs in LCDD format to output stream + void handleVisualisation(const LCDD::HandleMap& vis) const; + /// Dump all solids in GDML format to output stream + virtual void handleSolids(const SolidSet& solids) const; + /// Dump Transformations in GDML format to output stream + virtual void handleTransformations(const TransformSet& trafos) const; + /// Dump structure information in GDML format to output stream + virtual void handleStructure(const VolumeSet& volset) const; + }; + } // End namespace Geometry +} // End namespace DD4hep + +#endif // DD4HEP_GeometryTreeDump_H + diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index 4634570c8aa5945b5970df8531ee3ca28403fdda..f11a672d6d80952178dba7b764afc3a29adb3128 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -171,6 +171,7 @@ INSTANTIATE(TGeoNodeOffset); #include "TGeoCone.h" #include "TGeoArb8.h" #include "TGeoTrd2.h" +#include "TGeoParaboloid.h" #include "TGeoSphere.h" #include "TGeoTorus.h" #include "TGeoBoolNode.h" @@ -178,13 +179,14 @@ INSTANTIATE(TGeoNodeOffset); #include "TGeoCompositeShape.h" INSTANTIATE(TGeoVolume); INSTANTIATE(TGeoBBox); +INSTANTIATE(TGeoCone); +INSTANTIATE(TGeoParaboloid); INSTANTIATE(TGeoPcon); INSTANTIATE(TGeoPgon); INSTANTIATE(TGeoTube); INSTANTIATE(TGeoTubeSeg); INSTANTIATE(TGeoTrap); INSTANTIATE(TGeoTrd2); -INSTANTIATE(TGeoCone); INSTANTIATE(TGeoSphere); INSTANTIATE(TGeoTorus); INSTANTIATE(TGeoShape); diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index a61ac1d1fe7d7f9155efeebf3042e6e9de5d2b1f..3e0796bd5a7383f18ab6da5c813b39704efe8efc 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -7,14 +7,20 @@ // //==================================================================== +#include "DD4hep/GeoHandler.h" #include "LCDDImp.h" // C/C++ include files #include <iostream> #include <stdexcept> +#include "TGeoCompositeShape.h" +#include "TGeoBoolNode.h" #include "TGeoManager.h" #include "TGeoMatrix.h" +#include "TGeoVolume.h" +#include "TGeoShape.h" +#include "TClass.h" #if DD4HEP_USE_PYROOT #include "TPython.h" @@ -27,26 +33,27 @@ namespace DD4hep { namespace Geometry { struct Compact; }} using namespace DD4hep::Geometry; using namespace DD4hep; using namespace std; +namespace { + struct TopDetElement : public DetElement { + TopDetElement(const std::string& nam, Volume vol) : DetElement(nam,0) { _data().volume = vol; } + }; +} LCDD& LCDD::getInstance() { static LCDD* s_lcdd = new LCDDImp(); return *s_lcdd; } -LCDDImp::LCDDImp() : m_worldVol(), m_trackingVol() { +LCDDImp::LCDDImp() : m_world(), m_trackers(), m_worldVol(), m_trackingVol() { } Volume LCDDImp::pickMotherVolume(const DetElement&) const { // throw if not existing return m_worldVol; } -LCDD& LCDDImp::addVolume(const Ref_t& x) { - m_structure.append<TGeoVolume>(x,false); - return *this; -} - -LCDD& LCDDImp::addSolid(const Ref_t& x) { - m_structure.append<TGeoShape>(x,false); +LCDD& LCDDImp::addDetector(const Ref_t& x) { + m_detectors.append_noCheck(x); + m_world.add(DetElement(x)); return *this; } @@ -54,10 +61,6 @@ void LCDDImp::convertMaterials(const string& fname) { //convertMaterials(XML::DocumentHandler().load(fname).root()); } -//void LCDDImp::convertMaterials(XML::Handle_t materials) { -// Converter<Materials>(*this)(materials); -//} - void LCDDImp::addStdMaterials() { convertMaterials("file:../cmt/elements.xml"); convertMaterials("file:../cmt/materials.xml"); @@ -74,33 +77,79 @@ Handle<TObject> LCDDImp::getRefChild(const HandleMap& e, const std::string& name } return 0; } +namespace { + struct ShapePatcher : public GeoScan { + ShapePatcher(DetElement e) : GeoScan(e) {} + GeoScan& operator()() { + GeoHandler::Data& data = *m_data; + string nam; + for(GeoHandler::Data::const_reverse_iterator i=data.rbegin(); i != data.rend(); ++i) { + const GeoHandler::Data::mapped_type& v = (*i).second; + for(GeoHandler::Data::mapped_type::const_iterator j=v.begin(); j != v.end(); ++j) { + const TGeoNode* n = *j; + TGeoVolume* v = n->GetVolume(); + TGeoShape* s = v->GetShape(); + if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) { + nam = v->GetName(); + nam += "_shape"; + s->SetName(nam.c_str()); + } + else { + nam = s->GetName(); + } + if ( s->IsA()->Class() == TGeoCompositeShape::Class() ) { + TGeoCompositeShape* c = (TGeoCompositeShape*)s; + const TGeoBoolNode* boolean = c->GetBoolNode(); + s = boolean->GetLeftShape(); + if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) { + nam = v->GetName(); + nam += "_left"; + s->SetName(nam.c_str()); + } + s = boolean->GetRightShape(); + if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) { + nam = v->GetName(); + nam += "_right"; + s->SetName(nam.c_str()); + } + } + } + } + } + }; +} void LCDDImp::endDocument() { LCDD& lcdd = *this; - Volume world = volume("world_volume"); - Volume trkVol = volume("tracking_volume"); Material air = material("Air"); - world.setMaterial(air); - trkVol.setMaterial(air); + m_worldVol.setMaterial(air); + m_trackingVol.setMaterial(air); Region trackingRegion(lcdd,"TrackingRegion"); trackingRegion.setThreshold(1); trackingRegion.setStoreSecondaries(true); add(trackingRegion); - trkVol.setRegion(trackingRegion); + m_trackingVol.setRegion(trackingRegion); // Set the world volume to invisible. VisAttr worldVis(lcdd,"WorldVis"); worldVis.setVisible(false); - world.setVisAttributes(worldVis); + m_worldVol.setVisAttributes(worldVis); add(worldVis); // Set the tracking volume to invisible. VisAttr trackingVis(lcdd,"TrackingVis"); trackingVis.setVisible(false); - trkVol.setVisAttributes(trackingVis); + m_trackingVol.setVisAttributes(trackingVis); add(trackingVis); + + /// Since we allow now for anonymous shapes, + /// we will rename them to use the name of the volume they are assigned to + TGeoManager* mgr = gGeoManager; + mgr->CloseGeometry(); + m_world.setPlacement(PlacedVolume(mgr->GetTopNode())); + ShapePatcher(m_world)(); } void LCDDImp::create() { @@ -109,23 +158,22 @@ void LCDDImp::create() { void LCDDImp::init() { LCDD& lcdd = *this; - Box worldSolid(lcdd,"world_box","world_x","world_y","world_z"); + Box worldSolid("world_box","world_x","world_y","world_z"); Material vacuum = material("Vacuum"); - Volume world(lcdd,"world_volume",worldSolid,vacuum); - - Tube trackingSolid(lcdd,"tracking_cylinder", + Volume world("world_volume",worldSolid,vacuum); + Tube trackingSolid("tracking_cylinder", 0., _toDouble("tracking_region_radius"), _toDouble("2*tracking_region_zmax"),2*M_PI); - Volume tracking(lcdd,"tracking_volume",trackingSolid, vacuum); - //-->world.placeVolume(tracking); - - //Ref_t ref_world(lcdd,"world",world.refName()); - //m_setup.append(ref_world); + Volume tracking("tracking_volume",trackingSolid, vacuum); + m_world = TopDetElement("world",world); + m_trackers = TopDetElement("tracking",tracking); m_worldVol = world; m_trackingVol = tracking; m_materialAir = material("Air"); m_materialVacuum = material("Vacuum"); + m_detectors.append_noCheck(m_world); + m_world.add(m_trackers); gGeoManager->SetTopVolume(m_worldVol); } @@ -155,164 +203,18 @@ void LCDDImp::fromCompact(const std::string& xmlfile) { void LCDDImp::applyAlignment() { } -static void dumpChildren(const DetElement& e, int level) { -#if 0 - cout << "[" << level << " , " << e.placements().size() << "] "; - for(int j=0; j<level; ++j) cout << "..."; - cout << e.path() << endl; -#endif - for(DetElement::Children::const_iterator i=e.children().begin(); i != e.children().end(); ++i) - dumpChildren(DetElement((*i).second),level+1); -} - -#if 0 -#include "TGeoNode.h" +#include "SimpleGDMLWriter.h" +#include "Geant4Converter.h" +#include "GeometryTreeDump.h" -static void dumpGeometry(vector<TGeoNode*>& globals, vector<TGeoNode*>& locals, TGeoNode* current) { - typedef Value<TGeoNodeMatrix,PlacedVolume::Object> _P; - TGeoMatrix* matrix = current->GetMatrix(); - TGeoVolume* volume = current->GetVolume(); - TObjArray* nodes = volume->GetNodes(); - int num_children = nodes ? nodes->GetEntriesFast() : 0; - _P* val = dynamic_cast<_P*>(current); - static vector<DetElement> det_cache; - vector<TGeoNode*> loc_cache; - vector<TGeoNode*>* ptrloc_cache = &locals; - const char* tag = val ? "Yes" : "No "; - bool valid_det = false; - bool prt = false; - for(size_t i=0; i<globals.size(); ++i) { - if(strncmp(globals[i]->GetName(),"Muon",4)==0) { prt = true; break;} - } - - if ( val ) { - DetElement d = val->detector; - if ( d.isValid() ) { - valid_det = true; - det_cache.push_back(d); - ptrloc_cache = &loc_cache; - } - } - if ( prt ) { - cout << "[" << int(globals.size()) << " , " << tag << "] \t" << (void*)current << "\t" - << char(valid_det ? '*' : ' ') - << current->GetName(); - if ( num_children > 0 ) - cout << " #Children:" << num_children << "."; - else - cout << " No Children."; - cout << "\t Vol:" << volume->GetName(); - if ( valid_det ) { - DetElement d = val->detector; - cout << " DetElement:" << d->GetName(); - //cout << " Vol:" << d.volume().name(); - cout << " DetTrafos:" << locals.size(); - } - else { - cout << " Trafos:" << locals.size(); - for(size_t i=0; i<locals.size(); ++i) - cout << " " << (void*)locals[i]; - } - cout << endl; - } - if ( num_children > 0 ) { - globals.push_back(current); - for(int i=0; i<num_children; ++i) { - TGeoNode* node = (TGeoNode*)nodes->At(i); - ptrloc_cache->push_back(node); - dumpGeometry(globals,*ptrloc_cache,node); - ptrloc_cache->pop_back(); - } - globals.pop_back(); - } - if ( valid_det ) det_cache.pop_back(); -} - -vector<TGeoMatrix*> Transformations; -vector<TGeoSolid*> Volumes; -map<int, vector<TGeoNode*> > Placements; - - -static void dumpGeo(TGeoNode* current) { - - typedef Value<TGeoNodeMatrix,PlacedVolume::Object> _P; - TGeoMatrix* matrix = current->GetMatrix(); - TGeoVolume* volume = current->GetVolume(); - TObjArray* nodes = volume->GetNodes(); - int num_children = nodes ? nodes->GetEntriesFast() : 0; - _P* val = dynamic_cast<_P*>(current); - static vector<DetElement> det_cache; - vector<TGeoNode*> loc_cache; - vector<TGeoNode*>* ptrloc_cache = &locals; - const char* tag = val ? "Yes" : "No "; - bool valid_det = false; - bool prt = false; - for(size_t i=0; i<globals.size(); ++i) { - if(strncmp(globals[i]->GetName(),"Muon",4)==0) { prt = true; break;} - } - - if ( val ) { - DetElement d = val->detector; - if ( d.isValid() ) { - valid_det = true; - det_cache.push_back(d); - ptrloc_cache = &loc_cache; - } - } - if ( prt ) { - cout << "[" << int(globals.size()) << " , " << tag << "] \t" << (void*)current << "\t" - << char(valid_det ? '*' : ' ') - << current->GetName(); - if ( num_children > 0 ) - cout << " #Children:" << num_children << "."; - else - cout << " No Children."; - cout << "\t Vol:" << volume->GetName(); - if ( valid_det ) { - DetElement d = val->detector; - cout << " DetElement:" << d->GetName(); - //cout << " Vol:" << d.volume().name(); - cout << " DetTrafos:" << locals.size(); - } - else { - cout << " Trafos:" << locals.size(); - for(size_t i=0; i<locals.size(); ++i) - cout << " " << (void*)locals[i]; - } - cout << endl; - } - if ( num_children > 0 ) { - globals.push_back(current); - for(int i=0; i<num_children; ++i) { - TGeoNode* node = (TGeoNode*)nodes->At(i); - ptrloc_cache->push_back(node); - dumpGeometry(globals,*ptrloc_cache,node); - ptrloc_cache->pop_back(); - } - globals.pop_back(); - } - if ( valid_det ) det_cache.pop_back(); -} -#endif void LCDDImp::dump() const { TGeoManager* mgr = gGeoManager; - mgr->CloseGeometry(); mgr->SetVisLevel(4); mgr->SetVisOption(1); m_worldVol->Draw("ogl"); - cout << "Total number of object verifications:" << num_object_validations() << endl; - //Printer<const LCDD*>(*this,cout)(this); - for(HandleMap::const_iterator i=detectors().begin(); i != detectors().end(); ++i) { - DetElement e((*i).second); - dumpChildren(e,0); - //cout << "Detector: " << (*i).first << " : " << e.name() << endl; - } -#if 0 - TGeoNode* top = mgr->GetTopNode(); - vector<TGeoNode*> globals; - vector<TGeoNode*> locals; - //dumpGeometry(globals,locals,top); - //dumpGeo(top); -#endif -} + // SimpleGDMLWriter handler(cout); + // Geant4Converter handler; + //GeometryTreeDump handler; + //handler.create(m_world); +} diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h index 1c87cdb58afc19afb5e5da5f91b087dfad94067d..58775a4e4252af68e990e17d1f3ed01c1d64e7c7 100644 --- a/DDCore/src/LCDDImp.h +++ b/DDCore/src/LCDDImp.h @@ -26,9 +26,7 @@ namespace DD4hep { * XML namespace declaration */ namespace Geometry { - - struct Materials {}; - + class LCDDImp : public LCDD { public: struct InvalidObjectError : public std::runtime_error { @@ -79,26 +77,23 @@ namespace DD4hep { ObjectHandleMap m_fields; // GDML fields - ObjectHandleMap m_gdml; ObjectHandleMap m_define; - ObjectHandleMap m_structure; ObjectHandleMap m_materials; - ObjectHandleMap m_solids; - + DetElement m_world; + DetElement m_trackers; Volume m_worldVol; Volume m_trackingVol; Material m_materialAir; Material m_materialVacuum; - Ref_t m_setup; + Ref_t m_setup; void convertMaterials(const std::string& uri); - //void convertMaterials(XML::Handle_t doc_element); - LCDDImp(); + /// Read compact geometry description or alignment file virtual void fromCompact(const std::string& fname); /// Apply & lock realigments @@ -110,13 +105,15 @@ namespace DD4hep { virtual void endDocument(); void dump() const; - - virtual Handle<TObject> getRefChild(const HandleMap& e, const std::string& name, bool throw_if_not=true) const; - virtual Volume pickMotherVolume(const DetElement& sd) const; - virtual Volume worldVolume() const { return m_worldVol; } - virtual Volume trackingVolume() const { return m_trackingVol; } - virtual Material air() const { return m_materialVacuum; } - virtual Material vacuum() const { return m_materialAir; } + + virtual Handle<TObject> getRefChild(const HandleMap& e, const std::string& name, bool throw_if_not=true) const; + virtual Volume pickMotherVolume(const DetElement& sd) const; + virtual DetElement world() const { return m_world; } + virtual DetElement trackers() const { return m_trackers; } + virtual Volume worldVolume() const { return m_worldVol; } + virtual Volume trackingVolume() const { return m_trackingVol; } + virtual Material air() const { return m_materialVacuum; } + virtual Material vacuum() const { return m_materialAir; } virtual LimitSet limitSet(const std::string& name) const { return getRefChild(m_limits,name); } @@ -128,10 +125,6 @@ namespace DD4hep { { return getRefChild(m_regions,name); } virtual Ref_t idSpec(const std::string& name) const { return getRefChild(m_idDict,name); } - virtual Volume volume(const std::string& name) const - { return getRefChild(m_structure,name); } - virtual Solid solid(const std::string& name) const - { return getRefChild(solids(),name); } virtual Constant constant(const std::string& name) const { return getRefChild(m_define,name); } virtual Readout readout(const std::string& name) const @@ -144,8 +137,6 @@ namespace DD4hep { virtual const HandleMap& header() const { return m_header; } virtual const HandleMap& constants() const { return m_define; } virtual const HandleMap& visAttributes() const { return m_display; } - virtual const HandleMap& structure() const { return m_structure; } - virtual const HandleMap& solids() const { return m_solids; } virtual const HandleMap& limitsets() const { return m_limits; } virtual const HandleMap& regions() const { return m_regions; } virtual const HandleMap& materials() const { return m_materials; } @@ -154,8 +145,6 @@ namespace DD4hep { 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); } - virtual LCDD& add(const Volume& x) { return addVolume(x); } virtual LCDD& add(const Material& x) { return addMaterial(x); } virtual LCDD& add(const LimitSet& x) { return addLimitSet(x); } virtual LCDD& add(const Region& x) { return addRegion(x); } @@ -165,10 +154,6 @@ namespace DD4hep { virtual LCDD& add(const DetElement& x) { return addDetector(x); } #define __R return *this - // These are manager by the TGeoManager - virtual LCDD& addSolid(const Ref_t& x); // { m_solids.append(x); __R;} - virtual LCDD& addVolume(const Ref_t& x); // { m_structure.append(x); __R;} - // These not: virtual LCDD& addConstant(const Ref_t& x) { m_define.append(x,false); __R;} virtual LCDD& addMaterial(const Ref_t& x) { m_materials.append(x); __R;} @@ -178,7 +163,7 @@ namespace DD4hep { virtual LCDD& addReadout(const Ref_t& x) { m_readouts.append(x); __R;} 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& 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 59b6a22f1d2f75fa521ba7363752041c979fa1a3..b879c72d96a6cc07e3d7c32d8d1314d007c93f8a 100644 --- a/DDCore/src/Objects.cpp +++ b/DDCore/src/Objects.cpp @@ -114,35 +114,81 @@ VisAttr::VisAttr(LCDD& /* lcdd */, const string& name) { setAlpha(0.1f); } +/// Get Flag to show/hide daughter elements +bool VisAttr::showDaughters() const { + return _data().showDaughters; +} + /// Set Flag to show/hide daughter elements void VisAttr::setShowDaughters(bool value) { _data().showDaughters = value; } +/// Get visibility flag +bool VisAttr::visible() const { + return _data().visible; +} + /// Set visibility flag void VisAttr::setVisible(bool value) { _data().visible = value; } +/// Get line style +int VisAttr::lineStyle() const { + return _data().lineStyle; +} + /// Set line style void VisAttr::setLineStyle(LineStyle value) { _data().lineStyle = value; } +/// Get drawing style +int VisAttr::drawingStyle() const { + return _data().drawingStyle; +} + /// Set drawing style void VisAttr::setDrawingStyle(DrawingStyle value) { _data().drawingStyle = value; } +/// Get alpha value +float VisAttr::alpha() const { + //TNamed* obj = first_value<TNamed>(*this); + //obj->SetAlpha(value); + return _data().alpha; +} + /// Set alpha value -void VisAttr::setAlpha(float /* value */) { +void VisAttr::setAlpha(float value) { + _data().alpha = value; //TNamed* obj = first_value<TNamed>(*this); //obj->SetAlpha(value); } +/// Get object color +int VisAttr::color() const { + return _data().color; +} + /// Set object color void VisAttr::setColor(float red, float green, float blue) { - _data().color = TColor::GetColor(red,green,blue); + Object& o = _data(); + o.color = TColor::GetColor(red,green,blue); + o.col = gROOT->GetColor(o.color); +} + +/// Get RGB values of the color (if valid) +bool VisAttr::rgb(float& red, float& green, float& blue) const { + Object& o = _data(); + if ( o.col ) { + TColor* c = (TColor*)o.col; + c->GetRGB(red,green,blue); + return true; + } + return false; } /// String representation of this object diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 44988ab11eae82469afa4c374da41e599d4550b4..2ca533179acd7a94bafc444cbec67603d83987ef 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -21,6 +21,9 @@ #include "TGeoTube.h" #include "TGeoTrd2.h" #include "TGeoArb8.h" +#include "TGeoParaboloid.h" +#include "TGeoSphere.h" +#include "TGeoTorus.h" #include "TGeoMatrix.h" #include "TGeoBoolNode.h" #include "TGeoCompositeShape.h" @@ -35,10 +38,10 @@ template<typename T> void Solid_type<T>::_setDimensions(double* param) { /// Assign pointrs and register solid to geometry template<typename T> -void Solid_type<T>::_assign(LCDD& lcdd, T* n, const string& nam, const string& tit, bool cbbox) { +void Solid_type<T>::_assign(T* n, const string& nam, const string& tit, bool cbbox) { this->assign(n,nam,tit); if ( cbbox ) n->ComputeBBox(); - lcdd.addSolid(Solid(this->ptr())); + //lcdd.addSolid(Solid(this->ptr())); } /// Access to shape name @@ -46,8 +49,8 @@ template<typename T> const char* Solid_type<T>::name() const { return this->ptr()->GetName(); } -void Box::make(LCDD& lcdd, const string& name, double x, double y, double z) { - _assign(lcdd,new TGeoBBox(x,y,z),name,"box"); +void Box::make(const string& name, double x, double y, double z) { + _assign(new TGeoBBox(x,y,z),name,"box"); } /// Set the box dimensions @@ -57,18 +60,23 @@ Box& Box::setDimensions(double x, double y, double z) { return *this; } -/// Constructor to be used when creating a new DOM tree -Polycone::Polycone(LCDD& lcdd, const string& name) { - _assign(lcdd,new TGeoPcon(0,RAD_2_DEGREE * (2.*M_PI),0),name,"polycone",false); +/// Constructor to be used when creating a new object +Polycone::Polycone(const string& name) { + _assign(new TGeoPcon(0,RAD_2_DEGREE * (2.*M_PI),0),name,"polycone",false); +} + +/// Constructor to be used when creating a new object +Polycone::Polycone(double start, double delta) { + _assign(new TGeoPcon(RAD_2_DEGREE*start,RAD_2_DEGREE*delta,0),"","polycone",false); } -/// Constructor to be used when creating a new DOM tree -Polycone::Polycone(LCDD& lcdd, const string& name, double start, double delta) { - _assign(lcdd,new TGeoPcon(RAD_2_DEGREE*start,RAD_2_DEGREE*delta,0),name,"polycone",false); +/// Constructor to be used when creating a new object +Polycone::Polycone(const string& name, double start, double delta) { + _assign(new TGeoPcon(RAD_2_DEGREE*start,RAD_2_DEGREE*delta,0),name,"polycone",false); } /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes -Polycone::Polycone(LCDD& lcdd, const string& name, double start, double delta, const vector<double>& rmin, const vector<double>& rmax, const vector<double>& z) +Polycone::Polycone(double start, double delta, const vector<double>& rmin, const vector<double>& rmax, const vector<double>& z) { vector<double> params; if ( rmin.size() < 2 ) { @@ -82,7 +90,25 @@ Polycone::Polycone(LCDD& lcdd, const string& name, double start, double delta, c params.push_back(rmin[i]); params.push_back(rmax[i]); } - _assign(lcdd, new TGeoPcon(¶ms[0]),name,"polycone"); + _assign( new TGeoPcon(¶ms[0]),"","polycone"); +} + +/// Constructor to be used when creating a new polycone object. Add at the same time all Z planes +Polycone::Polycone(const string& name, double start, double delta, const vector<double>& rmin, const vector<double>& rmax, const vector<double>& z) +{ + vector<double> params; + if ( rmin.size() < 2 ) { + throw runtime_error("PolyCone::addZPlanes> Not enough Z planes. minimum is 2!"); + } + params.push_back(RAD_2_DEGREE * start); + params.push_back(RAD_2_DEGREE * delta); + params.push_back(rmin.size()); + for( size_t i=0; i<rmin.size(); ++i ) { + params.push_back(z[i]); + params.push_back(rmin[i]); + params.push_back(rmax[i]); + } + _assign( new TGeoPcon(¶ms[0]),name,"polycone"); } /// Add Z-planes to the Polycone @@ -109,10 +135,10 @@ void Polycone::addZPlanes(const vector<double>& rmin, const vector<double>& rmax _setDimensions(¶ms[0]); } -/// Constructor to be used when creating a new DOM tree with attribute initialization -void Tube::make(LCDD& lcdd, const string& name, double rmin, double rmax, double z, double deltaPhi) +/// Constructor to be used when creating a new object with attribute initialization +void Tube::make(const string& name, double rmin, double rmax, double z, double deltaPhi) { - _assign(lcdd,new TGeoTubeSeg(rmin,rmax,z,0.,RAD_2_DEGREE*deltaPhi),name,"tube"); + _assign(new TGeoTubeSeg(rmin,rmax,z,0.,RAD_2_DEGREE*deltaPhi),name,"tube"); } /// Set the tube dimensions @@ -123,15 +149,15 @@ Tube& Tube::setDimensions(double rmin, double rmax, double z, double deltaPhi) return *this; } -/// Constructor to be used when creating a new DOM tree with attribute initialization -void Cone::make(LCDD& lcdd, const string& name, +/// Constructor to be used when creating a new object with attribute initialization +void Cone::make(const string& name, double z, double rmin1, double rmax1, double rmin2, double rmax2) { - _assign(lcdd,new TGeoCone(z,rmin1,rmax1,rmin2,rmax2),name,"cone"); + _assign(new TGeoCone(z,rmin1,rmax1,rmin2,rmax2),name,"cone"); } Cone& Cone::setDimensions(double z,double rmin1,double rmax1,double rmin2,double rmax2) { @@ -140,25 +166,106 @@ Cone& Cone::setDimensions(double z,double rmin1,double rmax1,double rmin2,double return *this; } -/// Constructor to be used when creating a new DOM tree -Trapezoid::Trapezoid(LCDD& lcdd, const string& name) { - _assign(lcdd,new TGeoTrd2(0,0,0,0,0),name,"trd2"); +/// Constructor to be used when creating a new object +Trapezoid::Trapezoid(const string& name) { + _assign(new TGeoTrd2(0,0,0,0,0),name,"trd2"); } -/// Constructor to be used when creating a new DOM tree with attribute initialization -Trapezoid::Trapezoid(LCDD& lcdd, const string& name, double x1, double x2, double y1, double y2, double z) { - _assign(lcdd,new TGeoTrd2(x1,x2,y1,y2,z),name,"trd2"); +/// Constructor to be used when creating a new object with attribute initialization +Trapezoid::Trapezoid(const string& name, double x1, double x2, double y1, double y2, double z) { + _assign(new TGeoTrd2(x1,x2,y1,y2,z),name,"trd2"); +} + +/// Constructor to be used when creating a new object with attribute initialization +Trapezoid::Trapezoid(double x1, double x2, double y1, double y2, double z) { + _assign(new TGeoTrd2(x1,x2,y1,y2,z),"","trd2"); } /// Set the Trapezoid dimensions -Trapezoid& Trapezoid::setDimensions(double x1, double x2, double y1, double y2, double z) -{ +Trapezoid& Trapezoid::setDimensions(double x1, double x2, double y1, double y2, double z) { double params[] = {x1,x2,y1,y2,z}; _setDimensions(params); return *this; } -Trap::Trap( LCDD& lcdd, const string& name, +/// Constructor to be used when creating a new object +Paraboloid::Paraboloid(const string& name) { + _assign(new TGeoParaboloid(0,0,0),name,"paraboloid"); +} + +/// Constructor to be used when creating a new identified object with attribute initialization +Paraboloid::Paraboloid(const string& name, double r_low, double r_high, double delta_z) { + _assign(new TGeoParaboloid(r_low,r_high,delta_z),name,"paraboloid"); +} + +/// Constructor to be used when creating a new object with attribute initialization +Paraboloid::Paraboloid(double r_low, double r_high, double delta_z) { + _assign(new TGeoParaboloid(r_low,r_high,delta_z),"","paraboloid"); +} + +/// Set the Paraboloid dimensions +Paraboloid& Paraboloid::setDimensions(double r_low, double r_high, double delta_z) { + double params[] = {r_low,r_high,delta_z}; + _setDimensions(params); + return *this; +} + +/// Constructor to be used when creating a new anonymous object +Sphere::Sphere() { + _assign(new TGeoSphere(0,0),"","sphere"); +} + +/// Constructor to be used when creating a new identified object +Sphere::Sphere(const string& name) { + _assign(new TGeoSphere(0,0),name,"sphere"); +} + +/// Constructor to be used when creating a new identified object with attribute initialization +Sphere::Sphere(const string& name, double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi) { + _assign(new TGeoSphere(rmin,rmax,theta,delta_theta,phi,delta_phi),name,"sphere"); +} + +/// Constructor to be used when creating a new object with attribute initialization +Sphere::Sphere(double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi) { + _assign(new TGeoSphere(rmin,rmax,theta,delta_theta,phi,delta_phi),"","sphere"); +} + +/// Set the Sphere dimensions +Sphere& Sphere::setDimensions(double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi) { + double params[] = {rmin,rmax,theta,delta_theta,phi,delta_phi}; + _setDimensions(params); + return *this; +} + +/// Constructor to be used when creating a new object +Torus::Torus() { + _assign(new TGeoTorus(0,0,0),"","torus"); +} + +/// Constructor to be used when creating a new object +Torus::Torus(const string& name) { + _assign(new TGeoTorus(0,0,0),name,"torus"); +} + +/// Constructor to be used when creating a new identified object with attribute initialization +Torus::Torus(const string& name, double r, double rmin, double rmax, double phi, double delta_phi) { + _assign(new TGeoTorus(r,rmin,rmax,phi,delta_phi),name,"torus"); +} + +/// Constructor to be used when creating a new object with attribute initialization +Torus::Torus(double r, double rmin, double rmax, double phi, double delta_phi) { + _assign(new TGeoTorus(r,rmin,rmax,phi,delta_phi),"","torus"); +} + +/// Set the Torus dimensions +Torus& Torus::setDimensions(double r, double rmin, double rmax, double phi, double delta_phi) { + double params[] = {r,rmin,rmax,phi,delta_phi}; + _setDimensions(params); + return *this; +} + +/// Constructor to be used when creating a new identified object with attribute initialization +Trap::Trap( const string& name, double z, double theta, double phi, @@ -171,7 +278,23 @@ Trap::Trap( LCDD& lcdd, const string& name, double x4, double alpha2) { - _assign(lcdd,new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2),name,"trap"); + _assign(new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2),name,"trap"); +} + +/// Constructor to be used when creating a new anonymous object with attribute initialization +Trap::Trap( double z, + double theta, + double phi, + double y1, + double x1, + double x2, + double alpha1, + double y2, + double x3, + double x4, + double alpha2) +{ + _assign(new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2),"","trap"); } /// Set the trap dimensions @@ -183,14 +306,14 @@ Trap& Trap::setDimensions(double z,double theta,double phi, return *this; } -/// Constructor to be used when creating a new DOM tree -PolyhedraRegular::PolyhedraRegular(LCDD& lcdd, const string& name, int nsides, double rmin, double rmax, double zlen) +/// Constructor to be used when creating a new object +PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin, double rmax, double zlen) { if ( rmin<0e0 || rmin>rmax ) throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!"); else if ( rmax<0e0 ) throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!"); - _assign(lcdd,new TGeoPgon(),name,"polyhedra",false); + _assign(new TGeoPgon(),name,"polyhedra",false); double params[] = { RAD_2_DEGREE * 2 * M_PI, RAD_2_DEGREE * 2 * M_PI, @@ -202,26 +325,72 @@ PolyhedraRegular::PolyhedraRegular(LCDD& lcdd, const string& name, int nsides, d _setDimensions(¶ms[0]); } -/// Constructor to be used when creating a new DOM tree -BooleanSolid::BooleanSolid(LCDD& lcdd, const string& name, const string& type, const string& expr) +/// Constructor to be used when creating a new object +PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double zlen) { - _assign(lcdd,new TGeoCompositeShape(expr.c_str()),name,type); + if ( rmin<0e0 || rmin>rmax ) + throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!"); + else if ( rmax<0e0 ) + throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!"); + _assign(new TGeoPgon(),"","polyhedra",false); + double params[] = { + RAD_2_DEGREE * 2 * M_PI, + RAD_2_DEGREE * 2 * M_PI, + double(nsides), + 2e0, + zlen/2e0,rmin,rmax, + -zlen/2e0,rmin,rmax + }; + _setDimensions(¶ms[0]); } /// Constructor to be used when creating a new object -SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const string& expr) - : BooleanSolid(lcdd, name, "subtraction", expr) +SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) { + static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse()); + TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + TGeoCombiTrans* first = new TGeoCombiTrans("_first",0,0,0,&inverse_identity_rot); + TGeoCombiTrans* second = new TGeoCombiTrans("_secnd",pos.x,pos.y,pos.z,0); + second->SetRotation(rotation.Inverse()); + + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,first,second); + TGeoCompositeShape* comp = new TGeoCompositeShape("",sub); + comp->ComputeBBox(); + _assign( comp, "", "subtraction"); } -/// Constructor to be used when creating a new DOM tree -SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const Solid& shape1, const Solid& shape2) - : BooleanSolid(lcdd, name, "subtraction", shape1.name()+string("-")+shape2.name()) +/// Constructor to be used when creating a new object +SubtractionSolid::SubtractionSolid(const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) { + static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse()); + TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + TGeoCombiTrans* first = new TGeoCombiTrans((name+"_first").c_str(),0,0,0,&inverse_identity_rot); + TGeoCombiTrans* second = new TGeoCombiTrans((name+"_secnd").c_str(),pos.x,pos.y,pos.z,0); + second->SetRotation(rotation.Inverse()); + + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,first,second); + TGeoCompositeShape* comp = new TGeoCompositeShape(name.c_str(),sub); + comp->ComputeBBox(); + _assign( comp, "", "subtraction"); } /// Constructor to be used when creating a new object -SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) +UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) +{ + static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse()); + TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + TGeoCombiTrans* first = new TGeoCombiTrans("_first",0,0,0,&inverse_identity_rot); + TGeoCombiTrans* second = new TGeoCombiTrans("_secnd",pos.x,pos.y,pos.z,0); + second->SetRotation(rotation.Inverse()); + + TGeoUnion* sub = new TGeoUnion(shape1,shape2,first,second); + TGeoCompositeShape* comp = new TGeoCompositeShape("",sub); + comp->ComputeBBox(); + _assign( comp, "", "union"); +} + +/// Constructor to be used when creating a new object +UnionSolid::UnionSolid(const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) { static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse()); TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); @@ -229,25 +398,54 @@ SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const Solid& TGeoCombiTrans* second = new TGeoCombiTrans((name+"_secnd").c_str(),pos.x,pos.y,pos.z,0); second->SetRotation(rotation.Inverse()); - TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,first,second); + TGeoUnion* sub = new TGeoUnion(shape1,shape2,first,second); + TGeoCompositeShape* comp = new TGeoCompositeShape(name.c_str(),sub); + comp->ComputeBBox(); + _assign( comp, "", "union"); +} + +/// Constructor to be used when creating a new object +IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) +{ + static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse()); + TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + TGeoCombiTrans* first = new TGeoCombiTrans("_first",0,0,0,&inverse_identity_rot); + TGeoCombiTrans* second = new TGeoCombiTrans("_secnd",pos.x,pos.y,pos.z,0); + second->SetRotation(rotation.Inverse()); + + TGeoIntersection* sub = new TGeoIntersection(shape1,shape2,first,second); + TGeoCompositeShape* comp = new TGeoCompositeShape("",sub); + comp->ComputeBBox(); + _assign( comp, "", "intersection"); +} + +/// Constructor to be used when creating a new object +IntersectionSolid::IntersectionSolid(const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) +{ + static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse()); + TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + TGeoCombiTrans* first = new TGeoCombiTrans((name+"_first").c_str(),0,0,0,&inverse_identity_rot); + TGeoCombiTrans* second = new TGeoCombiTrans((name+"_secnd").c_str(),pos.x,pos.y,pos.z,0); + second->SetRotation(rotation.Inverse()); + + TGeoIntersection* sub = new TGeoIntersection(shape1,shape2,first,second); TGeoCompositeShape* comp = new TGeoCompositeShape(name.c_str(),sub); comp->ComputeBBox(); - _assign(lcdd, comp, "", "subtraction"); + _assign( comp, "", "intersection"); } #define INSTANTIATE(X) template class DD4hep::Geometry::Solid_type<X> -#include "TGeoSphere.h" -#include "TGeoTorus.h" INSTANTIATE(TGeoShape); INSTANTIATE(TGeoBBox); +INSTANTIATE(TGeoCone); +INSTANTIATE(TGeoParaboloid); INSTANTIATE(TGeoPcon); INSTANTIATE(TGeoPgon); +INSTANTIATE(TGeoSphere); +INSTANTIATE(TGeoTorus); INSTANTIATE(TGeoTube); INSTANTIATE(TGeoTubeSeg); INSTANTIATE(TGeoTrap); INSTANTIATE(TGeoTrd2); -INSTANTIATE(TGeoCone); INSTANTIATE(TGeoCompositeShape); -INSTANTIATE(TGeoSphere); -INSTANTIATE(TGeoTorus); diff --git a/DDCore/src/SimpleGDMLWriter.cpp b/DDCore/src/SimpleGDMLWriter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb2f5f5f4d45c5709ed07b8c43cfb54b8e64c0b8 --- /dev/null +++ b/DDCore/src/SimpleGDMLWriter.cpp @@ -0,0 +1,311 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +#include "DD4hep/LCDD.h" +#include "SimpleGDMLWriter.h" +// ROOT includes +#include "TROOT.h" +#include "TColor.h" +#include "TGeoShape.h" +#include "TGeoCone.h" +#include "TGeoParaboloid.h" +#include "TGeoPcon.h" +#include "TGeoPgon.h" +#include "TGeoSphere.h" +#include "TGeoTorus.h" +#include "TGeoTube.h" +#include "TGeoTrd1.h" +#include "TGeoTrd2.h" +#include "TGeoArb8.h" +#include "TGeoMatrix.h" +#include "TGeoBoolNode.h" +#include "TGeoCompositeShape.h" +#include "TClass.h" +#include "TMath.h" +#include <iostream> + +using namespace DD4hep::Geometry; +using namespace DD4hep; +using namespace std; + +namespace { + string indent = ""; + + void getAngles(const Double_t* m, Double_t &phi, Double_t &theta, Double_t &psi) { + // Retreive Euler angles. + // Check if theta is 0 or 180. + if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) { + theta = TMath::ACos(m[8])*RAD_2_DEGREE; + phi = TMath::ATan2(-m[8]*m[1],m[0])*RAD_2_DEGREE; + psi = 0.; // convention, phi+psi matters + return; + } + // sin(theta) != 0 + phi = TMath::ATan2(m[2],-m[5]); + Double_t sphi = TMath::Sin(phi); + if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*RAD_2_DEGREE; + else theta = TMath::ASin(m[2]/sphi)*RAD_2_DEGREE; + phi *= RAD_2_DEGREE; + psi = TMath::ATan2(m[6],m[7])*RAD_2_DEGREE; + } +} + +/// Dump logical volume in GDML format to output stream +void* SimpleGDMLWriter::handleVolume(const string& name, const TGeoVolume* volume) const { + Volume vol = Handle<>(volume); + VisAttr vis = vol.visAttributes(); + TGeoShape* shape = volume->GetShape(); + TGeoMedium* medium = volume->GetMedium(); + int num = volume->GetNdaughters(); + + m_output << "\t\t<volume name=\"" << name << "\">" << endl; + m_output << "\t\t\t<solidref ref=\"" << shape->GetName() << "\"/>" << endl; + m_output << "\t\t\t<materialref ref=\"" << medium->GetName() << "\"/>" << endl; + if ( vis.isValid() ) { + m_output << "\t\t\t<visref ref=\"" << vis.name() << "\"/>" << endl; + } + if ( num > 0 ) { + for(int i=0; i<num; ++i) { + TGeoNode* n = volume->GetNode(i); + TGeoVolume* v = n->GetVolume(); + TGeoMatrix* m = n->GetMatrix(); + m_output << "\t\t\t<physvol>" << endl; + m_output << "\t\t\t\t<volumeref ref=\"" << v->GetName() << "\"/>" << endl; + if ( m ) { + if ( m->IsTranslation() ) { + m_output << "\t\t\t\t<positionref ref=\"" << n->GetName() << "_pos\"/>" << endl; + } + if ( m->IsRotation() ) { + m_output << "\t\t\t\t<rotationref ref=\"" << n->GetName() << "_rot\"/>" << endl; + } + } + m_output << "\t\t\t</physvol>" << endl; + } + } + m_output << "\t\t</volume>" << endl; + return 0; +} + +/// Dump solid in GDML format to output stream +void* SimpleGDMLWriter::handleSolid(const string& name, const TGeoShape* shape) const { + if ( shape ) { + if ( shape->IsA() == TGeoBBox::Class() ) { + const TGeoBBox* s = (const TGeoBBox*)shape; + m_output << "\t\t<box name=\"" << name << "_shape\" x=\"" + << s->GetDX() << "\" y=\"" + << s->GetDY() << "\" z=\"" + << s->GetDZ() << "\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTube::Class() ) { + const TGeoTube* s = (const TGeoTube*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" + << s->GetRmin() << "\" rmax=\"" + << s->GetRmax() << "\" z=\"" + << s->GetDz() << "\" startphi=\"0.0\" deltaphi=\"360.0\" aunit=\"deg\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTubeSeg::Class() ) { + const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" + << s->GetRmin() << "\" rmax=\"" + << s->GetRmax() << "\" z=\"" + << s->GetDz() << "\" startphi=\"" + << s->GetPhi1() << "\" deltaphi=\"" + << s->GetPhi2() << "\" aunit=\"deg\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTrd1::Class() ) { + const TGeoTrd1* s = (const TGeoTrd1*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\"" + << s->GetDx1() << "\" x2=\"" + << s->GetDx2() << "\" y1=\"" + << s->GetDy() << "\" y2=\"" + << s->GetDy() << "\" z=\"" + << s->GetDz() << "\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoTrd2::Class() ) { + const TGeoTrd2* s = (const TGeoTrd2*)shape; + m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\"" + << s->GetDx1() << "\" x2=\"" + << s->GetDx2() << "\" y1=\"" + << s->GetDy1() << "\" y2=\"" + << s->GetDy2() << "\" z=\"" + << s->GetDz() << "\" lunit=\"cm\"/>" << endl; + } + else if ( shape->IsA() == TGeoPgon::Class() ) { + const TGeoPgon* s = (const TGeoPgon*)shape; + m_output << "\t\t<polyhedra name=\"" << name << "_shape\" startphi=\"" + << s->GetPhi1() << "\" deltaphi=\"" + << s->GetDphi() << "\" numsides=\"" + << s->GetNedges() << "\" aunit=\"deg\" lunit=\"cm\">" << endl; + for(int i=0; i<s->GetNz(); ++i) { + m_output << "\t\t\t<zplane z=\"" << s->GetZ(i) + << "\" rmin=\"" << s->GetRmin(i) + << "\" rmax=\"" << s->GetRmax(i) + << "\" lunit=\"cm\"/>" << endl; + } + m_output << "\t\t</polyhedra>" << endl; + } + else if ( shape->IsA() == TGeoPcon::Class() ) { + const TGeoPcon* s = (const TGeoPcon*)shape; + m_output << "\t\t<polycone name=\"" << name << "_shape\" startphi=\"" + << s->GetPhi1() << "\" deltaphi=\"" + << s->GetDphi() << "\" aunit=\"deg\" lunit=\"cm\">" << endl; + for(int i=0; i<s->GetNz(); ++i) { + m_output << "\t\t\t<zplane z=\"" << s->GetZ(i) + << "\" rmin=\"" << s->GetRmin(i) + << "\" rmax=\"" << s->GetRmax(i) + << "\" lunit=\"cm\"/>" << endl; + } + m_output << "\t\t</polycone>" << endl; + } + else if ( shape->IsA() == TGeoCompositeShape::Class() ) { + string nn = name; + const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape; + const TGeoBoolNode* boolean = s->GetBoolNode(); + TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); + + handleSolid(name+"_left", boolean->GetLeftShape()); + handleSolid(name+"_right",boolean->GetRightShape()); + + if ( oper == TGeoBoolNode::kGeoSubtraction ) + m_output << "\t\t<subtraction name=\"" << nn << "\">" << endl; + else if ( oper == TGeoBoolNode::kGeoUnion ) + m_output << "\t\t<union name=\"" << nn << "\">" << endl; + else if ( oper == TGeoBoolNode::kGeoIntersection ) + m_output << "\t\t<intersection name=\"" << nn << "\">" << endl; + + m_output << "\t\t\t<first ref=\"" << nn << "_left\"/>" << endl; + m_output << "\t\t\t<second ref=\"" << nn << "_right\"/>" << endl; + indent = "\t"; + handleTransformation("", boolean->GetRightMatrix()); + indent = ""; + + if ( oper == TGeoBoolNode::kGeoSubtraction ) + m_output << "\t\t</subtraction>" << endl; + else if ( oper == TGeoBoolNode::kGeoUnion ) + m_output << "\t\t</union>" << endl; + else if ( oper == TGeoBoolNode::kGeoIntersection ) + m_output << "\t\t</intersection>" << endl; + } + else { + cerr << "Failed to handle unknwon solid shape:" + << shape->IsA()->GetName() << endl; + } + } + return 0; +} + +/// Dump structure information in GDML format to output stream +void SimpleGDMLWriter::handleStructure(const VolumeSet& volset) const { + m_output << "\t<structure>" << endl; + for(VolumeSet::const_iterator i=volset.begin(); i != volset.end(); ++i) + handleVolume((*i).first,(*i).second); + m_output << "\t</structure>" << endl; +} + +/// Dump single volume transformation in GDML format to output stream +void* SimpleGDMLWriter::handleTransformation(const string& name, const TGeoMatrix* m) const { + if ( m ) { + if ( m->IsTranslation() ) { + const Double_t* f = m->GetTranslation(); + m_output << indent << "\t\t<position "; + if ( !name.empty() ) m_output << "name=\"" << name << "_pos\" "; + m_output << "x=\"" << f[0] << "\" " + << "y=\"" << f[1] << "\" " + << "z=\"" << f[2] << "\" unit=\"cm\"/>" << endl; + } + if ( m->IsRotation() ) { + const Double_t* mat = m->GetRotationMatrix(); + Double_t theta=0.0, phi=0.0, psi=0.0; + getAngles(mat, theta, phi, psi); + m_output << indent << "\t\t<rotation "; + if ( !name.empty() ) m_output << "name=\"" << name << "_rot\" "; + m_output << "x=\"" << theta << "\" " + << "y=\"" << psi << "\" " + << "z=\"" << phi << "\" unit=\"deg\"/>" << endl; + } + } + return 0; +} + +/// Dump Transformations in GDML format to output stream +void SimpleGDMLWriter::handleTransformations(const TransformSet& trafos) const { + m_output << "\t<define>" << endl; + for(TransformSet::const_iterator i=trafos.begin(); i != trafos.end(); ++i) + handleTransformation((*i).first, (*i).second); + m_output << "\t</define>" << endl; +} + +/// Dump all solids in GDML format to output stream +void SimpleGDMLWriter::handleSolids(const SolidSet& solids) const { + m_output << "\t<solids>" << endl; + for(SolidSet::const_iterator i=solids.begin(); i != solids.end(); ++i) + handleSolid((*i).first, (*i).second); + m_output << "\t</solids>" << endl; +} + +/// Dump all constants in GDML format to output stream +void SimpleGDMLWriter::handleDefines(const LCDD::HandleMap& defs) const { + m_output << "\t<define>" << endl; + for(LCDD::HandleMap::const_iterator i=defs.begin(); i != defs.end(); ++i) + m_output << "\t\t<constant name=\"" << (*i).second->GetName() << "\" value=\"" << (*i).second->GetTitle() << "\" />" << endl; + m_output << "\t</define>" << endl; +} + +/// Dump all visualisation specs in LCDD format to output stream +void SimpleGDMLWriter::handleVisualisation(const LCDD::HandleMap& vis) const { + m_output << "\t<display>" << endl; + for(LCDD::HandleMap::const_iterator i=vis.begin(); i != vis.end(); ++i) { + VisAttr v = (*i).second; + if ( v.isValid() ) { + float r=1., g=1., b=1., alpha=1.; + TColor *color = gROOT->GetColor(v.color()); + if ( color ) { + color->GetRGB(r,g,b); + alpha = color->GetAlpha(); + } + const char* line_style=0, *draw_style=0; + switch(v.lineStyle()) { + case VisAttr::DASHED: + line_style = "broken"; + break; + case VisAttr::SOLID: + default: + line_style = "unbroken"; + break; + } + switch(v.drawingStyle()) { + case VisAttr::WIREFRAME: + draw_style = "wireframe"; + break; + default: + break; + } + + m_output << "\t\t<vis name=\"" << v.name() << "\" "; + if ( line_style ) m_output << "linestyle=\"" << line_style << "\" "; + if ( draw_style ) m_output << "drawingStyle=\"" << draw_style << "\" "; + m_output << "show_daughters=\"" << (const char*)(v.showDaughters() ? "true" : "false") << "\" " + << "visible=\"" << (const char*)(v.visible() ? "true" : "false") << "\" >" << endl + << "\t\t\t<color R=\"" << r << "\" G=\"" << g << "\" B=\"" << b << "\" alpha=\"" << alpha << "\" />" << endl + << "\t\t</vis>" << endl; + } + } + m_output << "\t</display>" << endl; +} + +void SimpleGDMLWriter::create(DetElement top) { + GeometryInfo geo; + collect(top,geo); + //handleSetup(LCDD::getInstance().header()); + //handleDefines(LCDD::getInstance().constants()); + handleVisualisation(geo.vis); + //handleTransformations(geo.trafos); + //handleSolids(geo.solids); + //handleStructure(geo.volumes); +} diff --git a/DDCore/src/SimpleGDMLWriter.h b/DDCore/src/SimpleGDMLWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..1f1635c32596603f5f0535995d7f17294f28fbbf --- /dev/null +++ b/DDCore/src/SimpleGDMLWriter.h @@ -0,0 +1,68 @@ +// $Id:$ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_SIMPLEGDMLWRITER_H +#define DD4HEP_SIMPLEGDMLWRITER_H + +#include "DD4hep/LCDD.h" +#include "DD4hep/GeoHandler.h" +#include <set> +#include <map> +#include <vector> +class TGeoVolume; +class TGeoNode; + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /* + * Geometry namespace declaration + */ + namespace Geometry { + + /** @class SimpleGDMLWriter SimpleGDMLWriter.h + * + * @author M.Frank + * @version 1.0 + */ + struct SimpleGDMLWriter : public GeoHandler { + + /// Reference to output stream + std::ostream& m_output; + + SimpleGDMLWriter(std::ostream& os) : m_output(os) {} + /// Standard destructor + virtual ~SimpleGDMLWriter() {} + /// Main entry point: create required object(s) + void create(DetElement top); + + /// Dump logical volume in GDML format to output stream + virtual void* handleVolume(const std::string& name, const TGeoVolume* volume) const; + /// Dump single volume transformation in GDML format to output stream + virtual void* handleTransformation(const std::string& name, const TGeoMatrix* matrix) const; + /// Dump solid in GDML format to output stream + virtual void* handleSolid(const std::string& name, const TGeoShape* volume) const; + + /// Dump all constants in GDML format to output stream + virtual void handleDefines(const LCDD::HandleMap& defs) const; + /// Dump all visualisation specs in LCDD format to output stream + void handleVisualisation(const LCDD::HandleMap& vis) const; + /// Dump all solids in GDML format to output stream + virtual void handleSolids(const SolidSet& solids) const; + /// Dump Transformations in GDML format to output stream + virtual void handleTransformations(const TransformSet& trafos) const; + /// Dump structure information in GDML format to output stream + virtual void handleStructure(const VolumeSet& volset) const; + }; + } // End namespace Geometry +} // End namespace DD4hep + +#endif // DD4HEP_SIMPLEGDMLWRITER_H + diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index ad18e0d0619f22f535593e1bf04e5eefe9a697a6..36df53df14d92e68a6cc81aaa8e9383303a69b64 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -239,16 +239,14 @@ string PlacedVolume::toString() const { } /// Constructor to be used when creating a new geometry tree. -Volume::Volume(LCDD& lcdd, const string& name) { +Volume::Volume(const string& name) { m_element = new Value<TGeoVolume,Volume::Object>(name.c_str()); - lcdd.addVolume(*this); } /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes -Volume::Volume(LCDD& lcdd, const string& name, const Solid& s, const Material& m) { +Volume::Volume(const string& name, const Solid& s, const Material& m) { m_element = new Value<TGeoVolume,Volume::Object>(name.c_str(),s); setMaterial(m); - lcdd.addVolume(*this); } /// Set the volume's material @@ -413,8 +411,7 @@ LimitSet Volume::limitSet() const { return data<Object>()->limits; } /// Constructor to be used when creating a new geometry tree. -Assembly::Assembly(LCDD& lcdd, const std::string& name) { +Assembly::Assembly(const std::string& name) { m_element = new Value<TGeoVolumeAssembly,Volume::Object>(name.c_str()); - lcdd.addVolume(*this); } diff --git a/DDCore/src/compact/Compact2Objects.cpp b/DDCore/src/compact/Compact2Objects.cpp index 3df518b4e4600cded6cebf441daac09f2ddfe9fc..3687af7ff94d4d47e32b3d310d20f4e952716f5d 100644 --- a/DDCore/src/compact/Compact2Objects.cpp +++ b/DDCore/src/compact/Compact2Objects.cpp @@ -359,6 +359,17 @@ namespace DD4hep { namespace Geometry { template <> void Converter<LimitSet>::operator()(const xml_h& element) const { lcdd.addLimitSet(toRefObject<to_type>(lcdd,element)); } + void setChildTitles(const pair<string,DetElement>& e) { + DetElement parent = e.second.parent(); + const DetElement::Children& children = e.second.children(); + if ( strlen(e.second->GetTitle()) == 0 ) { + e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str()); + } + else { + cout << "Title present: " << e.second->GetTitle() << endl; + } + for_each(children.begin(),children.end(),setChildTitles); + } template <> void Converter<DetElement>::operator()(const xml_h& element) const { static const char* req_dets = ::getenv("REQUIRED_DETECTORS"); static const char* req_typs = ::getenv("REQUIRED_DETECTOR_TYPES"); @@ -376,12 +387,15 @@ namespace DD4hep { namespace Geometry { SensitiveDetector sd = toRefObject<SensitiveDetector>(lcdd,element); DetElement det(Handle<TNamed>(ROOT::Reflex::PluginService::Create<TNamed*>(type,&lcdd,&element,&sd))); - if ( det.isValid() && element.hasAttr(_A(readout)) ) { - string rdo = element.attr<string>(_A(readout)); - det.setReadout(lcdd.readout(rdo)); + if ( det.isValid() ) { + setChildTitles(make_pair(name,det)); + if ( element.hasAttr(_A(readout)) ) { + string rdo = element.attr<string>(_A(readout)); + det.setReadout(lcdd.readout(rdo)); + } } cout << (det.isValid() ? "Converted" : "FAILED ") - << " subdetector:" << name << " of type " << type << endl; + << " subdetector:" << name << " of type " << type << endl; lcdd.addDetector(det); } catch(const exception& e) { diff --git a/DDExamples/AlignDet/src/BoxDetector_geo.cpp b/DDExamples/AlignDet/src/BoxDetector_geo.cpp index 6aa54616ebde58d33886cda376e27174a9b24fb1..d8d82dfa170d789727ccd9bcd11d71c157e828c2 100644 --- a/DDExamples/AlignDet/src/BoxDetector_geo.cpp +++ b/DDExamples/AlignDet/src/BoxDetector_geo.cpp @@ -15,19 +15,18 @@ 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))); + xml_comp_t box (x_det.child(_X(box))); + xml_dim_t pos (x_det.child(_X(position))); + xml_dim_t 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,x_box.x(),x_box.y(),x_box.z()); - Volume det_vol(lcdd,name+"_vol",det_box, mat); + DetElement det (name,x_det.id()); + Volume det_vol(name+"_vol",Box(box.x(),box.y(),box.z()), 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()); + PlacedVolume phv = mother.placeVolume(det_vol,Position(pos.x(),pos.y(),pos.z()), + Rotation(rot.x(),rot.y(),rot.z())); + phv.addPhysVolID("id",x_det.id()); det.setPlacement(phv); return det; } diff --git a/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp b/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp index 71cd5d47e2e56a6e6bea16be238e19c80404617e..ab498b7030970923a85f4f95b40417177ef15035 100644 --- a/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp +++ b/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp @@ -18,8 +18,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens Material air = lcdd.air(); string det_name = x_det.nameStr(); string det_type = x_det.typeStr(); - Tube envelope (lcdd,det_name); - Volume envelopeVol(lcdd,det_name,envelope,air); + Tube envelope; + Volume envelopeVol(det_name,envelope,air); DetElement sdet (det_name,det_type,x_det.id()); double z = dim.outer_z(); double rmin = dim.inner_r(); @@ -30,20 +30,19 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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,layer_tub,air); + Tube layer_tub; + Volume layer_vol(layer_name,layer_tub,air); double rlayer = r; for(xml_coll_t l(x_layer,_X(slice)); l; ++l, ++m) { xml_comp_t x_slice = l; + double router = r + x_slice.thickness(); 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,slice_tube,slice_mat); - double router = r + x_slice.thickness(); + Tube slice_tube(r,router,z * 2); + Volume slice_vol (slice_name,slice_tube,slice_mat); 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 diff --git a/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp b/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp index a05c968acf403dd3cd0f6cda063de8dbfa8c720a..9282af5095cc36babbe1e31aaa6c09cd45869305 100644 --- a/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp +++ b/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp @@ -18,9 +18,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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); - Volume envelopeVol(lcdd,det_name,envelope,air); + Tube envelope; + Volume envelopeVol(det_name,envelope,air); bool reflect = dim.reflect(); double zmin = dim.inner_z(); double rmin = dim.inner_r(); @@ -37,16 +36,14 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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,layer_tub,air); + Volume layer_vol(layer_name,Tube(rmin,rmax,layerWidth),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, slice_tube, slice_mat); + Volume slice_vol (slice_name,Tube(rmin,rmax,w),slice_mat); if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens); @@ -66,10 +63,10 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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(det_name,det_type,x_det.id()); + + DetElement sdet(det_name,x_det.id()); Volume motherVol = lcdd.pickMotherVolume(sdet); - PlacedVolume phv=motherVol.placeVolume(envelopeVol,Position(0,0,zmin+totWidth/2)); + PlacedVolume phv = motherVol.placeVolume(envelopeVol,Position(0,0,zmin+totWidth/2)); phv.addPhysVolID(_A(system),sdet.id()) .addPhysVolID(_A(barrel),1); sdet.setPlacement(phv); diff --git a/DDExamples/CLICSiD/src/DiskTracker_geo.cpp b/DDExamples/CLICSiD/src/DiskTracker_geo.cpp index d1756bb4fc2628e7527d2bee51622005126355a3..388504eeef633af9b114f765029aec720643b5da 100644 --- a/DDExamples/CLICSiD/src/DiskTracker_geo.cpp +++ b/DDExamples/CLICSiD/src/DiskTracker_geo.cpp @@ -16,9 +16,8 @@ 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(det_name,det_type,x_det.id()); + DetElement sdet(det_name,x_det.id()); Volume motherVol = lcdd.pickMotherVolume(sdet); int l_num = 0; @@ -35,16 +34,15 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens double thickness = xml_comp_t(j).thickness(); layerWidth += thickness; } - Tube l_tub(lcdd,l_nam,rmin,rmax,layerWidth,2*M_PI); - Volume l_vol(lcdd,l_nam,l_tub,air); + Tube l_tub(rmin,rmax,layerWidth,2*M_PI); + Volume l_vol(l_nam,l_tub,air); 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,thick); - Volume s_vol(lcdd,s_nam, s_tub, mat); + Volume s_vol(s_nam, Tube(rmin,rmax,thick), mat); if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); s_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); @@ -57,8 +55,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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(l_nam,det_type+"/Layer",l_num); - sdet.add(layer.setPlacement(lpv)); + DetElement layer(sdet,l_nam,l_num); + layer.setPlacement(lpv); if ( reflect ) { PlacedVolume lpvR = motherVol.placeVolume(l_vol,Position(0,0,-zmin-layerWidth/2),ReflectRot()); lpvR.addPhysVolID(_X(system),sdet.id()); diff --git a/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp b/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp index 58ddd23511e0167a174f026864f8f5159b9f699f..0987eb3fff6521ca77beaf99c9fba52f29493f86 100644 --- a/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp +++ b/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp @@ -22,7 +22,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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(); @@ -32,17 +31,17 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens double mod_z = layering.totalThickness(); double outer_r = inner_r + mod_z; double totThick = mod_z; - DetElement sdet (det_name,det_type,det_id); + DetElement sdet (det_name,det_id); Volume motherVol = lcdd.pickMotherVolume(sdet); - PolyhedraRegular hedra(lcdd,det_name,nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z()); - Volume envelope (lcdd,det_name,hedra,air); + PolyhedraRegular hedra(nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z()); + Volume envelope (det_name,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.setPlacement(env_phv); - DetElement stave_det(det_name+"_stave0",det_type,det_id); + DetElement stave_det("stave0",det_id); double dx = mod_z / std::sin(dphi); // dx per layer dx = 0; @@ -54,14 +53,13 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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. + Trapezoid 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); + Volume mod_vol(det_name+"_module",trd,air); { // ===== buildBarrelStave(lcdd, sens, module_volume) ===== // Parameters for computing the layer X dimension: @@ -80,54 +78,51 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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"); + string l_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,l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance); - Volume l_vol(lcdd,l_name,l_box,air); - DetElement layer(l_name,det_type+"/Layer",det_id); + Box l_box(l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance); + Volume l_vol(det_name+"_"+l_name,l_box,air); + DetElement layer(stave_det, l_name, det_id); - stave_det.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"); + string s_name = _toString(s_num,"slice%d"); double s_thick = x_slice.thickness(); - Box s_box(lcdd,s_name,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(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.setPlacement(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.setPlacement(layer_phv); - // Increment to next layer Z position. - l_pos_z += l_thickness; - ++l_num; + Box s_box(l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance); + Volume s_vol(det_name+"_"+l_name+"_"+s_name,s_box,lcdd.material(x_slice.materialStr())); + DetElement slice(layer,s_name,det_id); + + 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.setPlacement(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.setPlacement(layer_phv); + // Increment to next layer Z position. + l_pos_z += l_thickness; + ++l_num; } } } @@ -143,18 +138,18 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens // Create nsides staves. for (int i = 0; i < nsides; i++, phi -= dphi) { // i is module number - DetElement stave_det(det_name+_toString(i,"_stave%d"),det_type,x_det.id()); // 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)); + 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); - sdet.add(i==0 ? stave_det : stave_det.clone(det_name+_toString(i,"_stave%d"))); - stave_det.setPlacement(pv); + DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d")); + sd.setPlacement(pv); + sdet.add(sd); } // Set envelope volume attributes. diff --git a/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp b/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp index 3d49bea23620eb2f6505f955ed8e8b3cdba34be6..8c7699e65721a32f05e7d0c651248daf2977dec2 100644 --- a/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp +++ b/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp @@ -19,10 +19,9 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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 (det_name,det_type,id); + DetElement sdet (det_name,id); Layering layering(x_det); Volume motherVol = lcdd.pickMotherVolume(sdet); @@ -36,16 +35,15 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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,rmin,rmax,thickness); + Tube envelopeTube(rmin,rmax,thickness); // First envelope bool subtracion of outgoing beampipe. // Incoming beampipe solid. - Tube beamInTube(lcdd,det_name + "_beampipe_incoming",0,outgoingR,thickness * 2); + Tube beamInTube(0,outgoingR,thickness * 2); // Position of incoming beampipe. Position beamInPos(beamPosX,0,0); /// Rotation of incoming beampipe. @@ -53,20 +51,18 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens // Second envelope bool subtracion of outgoing beampipe. // Outgoing beampipe solid. - Tube beamOutTube(lcdd,det_name + "_beampipe_outgoing",0,incomingR,thickness * 2); + Tube beamOutTube(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); + SubtractionSolid envelopeSubtraction1(envelopeTube,beamInTube,beamInPos,beamInRot); + SubtractionSolid envelopeSubtraction2(envelopeSubtraction1,beamOutTube,beamOutPos,beamOutRot); // Final envelope bool volume. - Volume envelopeVol(lcdd,det_name, envelopeSubtraction2, air); + Volume envelopeVol(det_name, envelopeSubtraction2, air); // Process each layer element. double layerPosZ = -thickness / 2; @@ -77,28 +73,26 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens // Create tube envelope for this layer, which can be reused in bool definition // in the repeat loop below. - Tube layerTube(lcdd, det_name + "_layer",rmin,rmax,layerThickness); + Tube layerTube(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"); + string layer_nam = _toString(i,"layer%d"); // Increment to new layer position. layerDisplZ += layerThickness / 2; layerPosZ += layerThickness / 2; // First layer subtraction solid. - DetElement layer(layer_nam,"ForwardDetector/Layer",sdet.id()); + DetElement layer(sdet,layer_nam,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); + SubtractionSolid layerSubtraction1(layerTube,beamInTube,layerSubtraction1Pos,beamInRot); // Second layer subtraction solid. - SubtractionSolid layerSubtraction2(lcdd,layer_nam + "_subtraction2", - layerSubtraction1,beamOutTube,layerSubtraction2Pos,beamOutRot); + SubtractionSolid layerSubtraction2(layerSubtraction1,beamOutTube,layerSubtraction2Pos,beamOutRot); // Layer LV. - Volume layerVol(lcdd,layer_nam, layerSubtraction2, air); + Volume layerVol(det_name+"_"+layer_nam,layerSubtraction2,air); // Slice loop. int sliceCount = 0; @@ -106,7 +100,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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"); + string slice_nam = _toString(sliceCount,"slice%d"); /** Get slice parameters. */ double sliceThickness = x_slice.thickness(); Material slice_mat = lcdd.material(x_slice.materialStr()); @@ -116,27 +110,24 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens slicePosZ += sliceThickness / 2; // Slice's basic tube. - Tube sliceTube(lcdd, slice_nam + "_tube", rmin,rmax,sliceThickness); - DetElement slice(slice_nam,"ForwardDetector/Layer/Slice",sdet.id()); + Tube sliceTube(rmin,rmax,sliceThickness); + DetElement slice(layer,slice_nam,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); + SubtractionSolid sliceSubtraction1(sliceTube,beamInTube,Position(slicePosX,0,0),beamInRot); // Second slice subtraction solid. - SubtractionSolid sliceSubtraction2(lcdd,slice_nam + "_subtraction2", - sliceSubtraction1,beamOutTube,Position(-slicePosX,0,0),beamOutRot); + SubtractionSolid sliceSubtraction2(sliceSubtraction1,beamOutTube,Position(-slicePosX,0,0),beamOutRot); // Slice LV. - Volume sliceVol(lcdd,slice_nam, sliceSubtraction2, slice_mat); - + Volume sliceVol(det_name+"_"+layer_nam+"_"+slice_nam, sliceSubtraction2, slice_mat); + if ( x_slice.isSensitive() ) sliceVol.setSensitiveDetector(sens); // Set attributes of slice slice.setAttributes(lcdd, sliceVol, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); // Place volume in layer slice.setPlacement(layerVol.placeVolume(sliceVol,Position(0,0,slicePosZ))); - layer.add(slice); // Start of next slice. sliceDisplZ += sliceThickness / 2; @@ -150,7 +141,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens PlacedVolume layerPV = envelopeVol.placeVolume(layerVol,Position(0,0,layerPosZ)); layerPV.addPhysVolID(_X(layer), i); layer.setPlacement(layerPV); - sdet.add(layer); // Increment to start of next layer. layerDisplZ += layerThickness / 2; @@ -168,7 +158,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens env_phv = motherVol.placeVolume(envelopeVol,Position(0,0,-zpos),ReflectRot()); env_phv.addPhysVolID(_X(system), id); env_phv.addPhysVolID(_X(barrel), 2); - DetElement rdet(det_name+"_reflect",det_type,x_det.id()); + DetElement rdet(det_name+"_reflect",x_det.id()); rdet.setPlacement(env_phv); } return sdet; diff --git a/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp b/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp index 9c3420612056996e5ca7106247d2ca10fc0cc96d..72c70e76ba8a264b4346f0952d7c4811dbf70a2c 100644 --- a/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp +++ b/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp @@ -17,16 +17,16 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens string det_name = x_det.nameStr(); string det_type = x_det.typeStr(); Material air = lcdd.air(); - DetElement sdet(det_name,det_type,x_det.id()); + DetElement sdet(det_name,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(l_name,"MultiLayerTracker/Layer",x_layer.id()); - Tube l_tub(lcdd,l_name); - Volume l_vol(lcdd,l_name,l_tub,air); + DetElement layer(sdet,_toString(n,"layer%d"),x_layer.id()); + Tube l_tub; + Volume l_vol(l_name,l_tub,air); double z = x_layer.outer_z(); double rmin = x_layer.inner_r(); double r = rmin; @@ -36,8 +36,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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, s_tub, mat); + Tube s_tub; + Volume s_vol(s_name, s_tub, mat); r += x_slice.thickness(); s_tub.setDimensions(r,r,2*z,2*M_PI); @@ -53,7 +53,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens PlacedVolume lpv = motherVol.placeVolume(l_vol,IdentityPos()); lpv.addPhysVolID(_X(system),sdet.id()).addPhysVolID(_X(barrel),0); - sdet.add(layer.setPlacement(lpv)); + layer.setPlacement(lpv); } sdet.setCombineHits(x_det.attr<bool>(_A(combineHits)),sens); return sdet; diff --git a/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp b/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp index 103f41475c58029a816445a36953cd11bafff145..63cb370003821a2caa1461136cffe011cdc641d5 100644 --- a/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp +++ b/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp @@ -15,10 +15,8 @@ using namespace DD4hep::Geometry; 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 (name,x_det.typeStr(),x_det.id()); - Polycone cone (lcdd,name); + DetElement sdet (name,x_det.id()); Material mat (lcdd.material(x_det.materialStr())); - Volume volume (lcdd,name, cone, mat); vector<double> rmin,rmax,z; int num = 0; @@ -31,7 +29,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector&) { if ( num < 2 ) { throw runtime_error("PolyCone["+name+"]> Not enough Z planes. minimum is 2!"); } - cone.addZPlanes(rmin,rmax,z); + Polycone cone (0.,2.*M_PI,rmin,rmax,z); + Volume volume (name, cone, mat); volume.setVisAttributes(lcdd, x_det.visStr()); sdet.setPlacement(lcdd.pickMotherVolume(sdet).placeVolume(volume)); return sdet; diff --git a/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp b/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp index c886f4f2caad3857e195491c6178c071a8276378..2768393193b34f0531eb1da6688a62e28baa43b8 100644 --- a/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp +++ b/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp @@ -30,10 +30,8 @@ static void placeStaves(DetElement& parent, double posX = -sectCenterRadius * std::sin(rotY); double posY = sectCenterRadius * std::cos(rotY); for (int module = 0; module < numsides; ++module) { - string nam = stave.name(); - nam = nam.substr(0,nam.length()-1)+_toString(module,"%d"); - DetElement det = module>0 ? stave.clone(nam) : stave; - PlacedVolume pv=envelopeVolume.placeVolume(sectVolume,Position(-posX,-posY,0),Rotation(rotX,rotY,0)); + DetElement det = module>0 ? stave.clone(_toString(module,"stave%d")) : stave; + PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,Position(-posX,-posY,0),Rotation(rotX,rotY,0)); pv.addPhysVolID(_X(stave), 0); pv.addPhysVolID(_X(module),module); det.setPlacement(pv); @@ -60,11 +58,11 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens int numSides = dim.numsides(); double detZ = dim.z(); double rmin = dim.rmin(); - DetElement sdet(det_name,det_type,x_det.id()); - DetElement stave(det_name+"_stave0",det_type,x_det.id()); + DetElement sdet(det_name,x_det.id()); + DetElement stave("stave0",x_det.id()); Volume motherVol = lcdd.pickMotherVolume(sdet); - cout << det_name << " Gap:" << gap << endl; + //cout << det_name << " Gap:" << gap << endl; for(xml_coll_t c(x_det,_X(layer)); c; ++c) { xml_comp_t x_layer = c; @@ -73,8 +71,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens totalSlices += x_layer.numChildren(_X(slice)); } - PolyhedraRegular polyhedra(lcdd,det_name,numSides,rmin,rmin+totalThickness,detZ); - Volume envelopeVol(lcdd,det_name,polyhedra,air); + PolyhedraRegular polyhedra(numSides,rmin,rmin+totalThickness,detZ); + Volume envelopeVol(det_name,polyhedra,air); // Add the subdetector envelope to the structure. double innerAngle = 2*M_PI/numSides; @@ -84,13 +82,11 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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",staveTrdOuter,air); + Trapezoid staveTrdOuter(innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2); + Volume staveOuterVol(det_name+"_stave",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+"_inner",staveTrdInner,air); + Trapezoid staveTrdInner(innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2); + Volume staveInnerVol(det_name+"_inner",staveTrdInner,air); double layerOuterAngle = (M_PI-innerAngle)/2; double layerInnerAngle = (M_PI/2 - layerOuterAngle); @@ -107,34 +103,30 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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"); - string layer_name = _toString(layer_num,"stave_layer%d"); + string layer_name = det_name+_toString(layer_num,"_layer%d"); double layer_thickness = lay->thickness(); - DetElement layer(layer_name,det_name+"/Layer",x_det.id()); + DetElement layer(stave,_toString(layer_num,"layer%d"),x_det.id()); // Layer position in Z within the stave. layer_pos_z += layer_thickness / 2; // Layer box & volume - Box layer_box(lcdd,"layer", layer_dim_x, detZ/2, layer_thickness); - Volume layer_vol(lcdd,"layer", layer_box, air); + Volume layer_vol(layer_name, Box(layer_dim_x,detZ/2,layer_thickness), 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"); - string slice_name = _toString(slice_number,"slice%d"); + 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(slice_name,det_name+"/Layer/Slice",x_det.id()); + DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id()); slice_pos_z += slice_thickness / 2; - // Slice box. - Box slice_box(lcdd,"slice",layer_dim_x,detZ/2,slice_thickness); - // Slice volume. - Volume slice_vol(lcdd,"slice",slice_box,slice_material); + // Slice volume & box + Volume slice_vol(slice_name,Box(layer_dim_x,detZ/2,slice_thickness),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()); @@ -142,7 +134,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z)); slice_phv.addPhysVolID(_X(slice),slice_number); - layer.add(slice); + slice.setPlacement(slice_phv); // Increment Z position for next slice. slice_pos_z += slice_thickness / 2; // Increment slice number. @@ -154,8 +146,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens // Layer physical volume. PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol,Position(0,0,layer_pos_z)); layer_phv.addPhysVolID(_X(layer),layer_num); - - stave.add(layer); + layer.setPlacement(layer_phv); // Increment the layer X dimension. layer_dim_x += layer_thickness * std::tan(layerInnerAngle);// * 2; @@ -168,10 +159,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens // Add stave inner physical volume to outer stave volume. staveOuterVol.placeVolume(staveInnerVol,IdentityPos()); - // Set the vis attributes of the outer stave section. stave.setVisAttributes(lcdd,staves.visStr(),staveOuterVol); - // Place the staves. placeStaves(sdet,stave,rmin,numSides,totalThickness,envelopeVol,innerAngle,staveOuterVol); diff --git a/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp b/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp index de179d778db72a22ff768dba583bada7f7fcf631..260aa2731b68be7788228e7cdae46e51e2c6ed53 100644 --- a/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp +++ b/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp @@ -18,7 +18,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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(); @@ -27,9 +26,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens double zmin = dim.zmin(); Layering layering(x_det); double totalThickness = layering.totalThickness(); - - PolyhedraRegular polyhedra(lcdd,det_name,numsides,rmin,rmax,totalThickness); - Volume envelopeVol(lcdd,det_name,polyhedra,air); + Volume envelopeVol(det_name,PolyhedraRegular(numsides,rmin,rmax,totalThickness),air); int l_num = 0; int layerType = 0; @@ -40,8 +37,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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,numsides,rmin,rmax,l_thick); - Volume l_vol (lcdd,l_name, l_solid, air); + Volume l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air); int s_num = 0; double sliceZ = -l_thick/2; @@ -50,8 +46,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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,numsides,rmin,rmax,s_thick); - Volume s_vol (lcdd,s_name,s_solid,s_mat); + Volume s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat); if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens); s_vol.setVisAttributes(lcdd.visAttributes(x_slice.visStr())); @@ -74,7 +69,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens } envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); - DetElement sdet (det_name,det_type,x_det.id()); + DetElement sdet (det_name,x_det.id()); Volume motherVol = lcdd.pickMotherVolume(sdet); PlacedVolume physvol = motherVol.placeVolume(envelopeVol, Position(0,0,zmin+totalThickness/2), @@ -89,7 +84,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens Rotation(M_PI,0,M_PI/numsides)); physvol.addPhysVolID("system",det_id); physvol.addPhysVolID("barrel",2); - DetElement rdet(det_name+"_reflect",det_type,x_det.id()); + DetElement rdet(det_name+"_reflect",x_det.id()); rdet.setPlacement(physvol); } return sdet; diff --git a/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp b/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp index 3834c51790aa69e6819b670226c0db326e599cbb..ba5d58fb3401b4a951ca8b170f2718e8989083fe 100644 --- a/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp +++ b/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp @@ -17,28 +17,28 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens Material air = lcdd.air(); int det_id = x_det.id(); string det_name = x_det.nameStr(); - string det_type = x_det.typeStr(); - DetElement sdet (det_name,det_type,det_id); + DetElement sdet (det_name,det_id); Volume motherVol = lcdd.pickMotherVolume(sdet); - + map<string, Volume> volumes; + 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 (m_nam,det_type+"/Module",det_id); + string m_nam = x_mod.nameStr(); + Volume m_vol(m_nam,Box(m_env.width(),m_env.length(),m_env.thickness()),air); + DetElement m_elt(sdet, m_nam, det_id); int ncomponents = 0, sensor_number = 0; + + volumes[m_nam] = m_vol; 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,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 (c_nam,det_type+"/Module/Component",det_id); + string c_nam = _toString(ncomponents,"component%d"); + Box c_box (x_comp.width(),x_comp.length(),x_comp.thickness()); + Volume c_vol (c_nam,c_box,lcdd.material(x_comp.materialStr())); 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)); @@ -57,11 +57,11 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens c_phv.addPhysVolID(_X(sensor),sensor_number++); c_vol.setSensitiveDetector(sens); } + DetElement c_elt(m_elt,c_nam,det_id); c_elt.setAttributes(lcdd,c_vol,x_comp.regionStr(),x_comp.limitsStr(),x_comp.visStr()); - m_elt.add(c_elt); + c_elt.setPlacement(c_phv); } 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; @@ -69,23 +69,23 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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(); + string m_nam = x_layer.moduleStr(); DetElement m_elt = sdet.child(m_nam); - Volume m_env = lcdd.volume(m_nam); + Volume m_env = volumes[m_nam]; string lay_nam = det_name+_toString(lay_id,"_layer%d"); - Tube lay_tub (lcdd,lay_nam,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. - + Tube lay_tub (x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()); + Volume lay_vol (lay_nam,lay_tub,air); // Create the layer envelope volume. + double phi0 = x_layout.phi0(); // Starting phi of first module. + double phi_tilt = x_layout.phi_tilt(); // Phi tilt of a module. + double rc = x_layout.rc(); // Radius of the module center. + int nphi = x_layout.nphi(); // Number of modules in phi. + double rphi_dr = x_layout.dr(); // The delta radius of every other module. + double phi_incr = (M_PI * 2) / nphi; // Phi increment for one module. + double phic = phi0; // Phi of the module center. + double z0 = z_layout.z0(); // Z position of first module in phi. + double nz = z_layout.nz(); // Number of modules to place in z. + double z_dr = z_layout.dr(); // Radial displacement parameter, of every other module. + // Z increment for module placement along Z axis. // Adjust for z0 at center of module rather than // the end of cylindrical envelope. @@ -103,8 +103,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens // 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"); // Module PhysicalVolume. PlacedVolume m_physvol = lay_vol.placeVolume(m_env,Position(x,y,module_z), @@ -124,12 +122,13 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens rphi_dr *= -1; // Flip sign of dr parameter. module_z = -z0; // Reset the Z placement parameter for module. } - m_elt.setAttributes(lcdd,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),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. + m_elt.setAttributes(lcdd,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + m_elt.setPlacement(lpv); } return sdet; } diff --git a/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp b/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp index 8e1d3e520328dee236ba6a5350fdf26d2055579f..8d3d712dc62a2afbcdf5218a3beee53baa1f1b6d 100644 --- a/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp +++ b/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp @@ -20,9 +20,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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 (det_name,det_type,det_id); + DetElement sdet (det_name,det_id); Volume motherVol = lcdd.trackingVolume(); int m_id=0, c_id=0, n_sensor=0; double posY; @@ -31,7 +30,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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(); @@ -42,21 +40,17 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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); - + Volume m_volume(det_name+"_"+m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum); 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, x1, x2, c_thick/2e0, c_thick/2e0, z); - Volume vol(lcdd, c_name, trd, c_mat); - + string c_name = m_volume.name() + _toString(c_id,"_component%d"); + Volume vol(c_name, Trapezoid(x1,x2,c_thick/2e0,c_thick/2e0,z), c_mat); + 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() ) { @@ -70,8 +64,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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(); + 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; @@ -82,33 +76,30 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens 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; + 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"); + string m_base = _toString(l_id,"layer%d") + _toString(mod_num,"_module%d"); double x = r*std::cos(phi); double y = r*std::sin(phi); + DetElement module(sdet,m_base,det_id); 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 (m_base,det_type+"/Module",det_id); module.setPlacement(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 (m_base+"_reflect",det_type+"/Module",det_id); + DetElement r_module(sdet,m_base+"_reflect",det_id); r_module.setPlacement(pv); - sdet.add(r_module); } - dz = -dz; + dz = -dz; phi += iphi; ++mod_num; } diff --git a/DDExamples/CLICSiD/src/TubeSegment_geo.cpp b/DDExamples/CLICSiD/src/TubeSegment_geo.cpp index b8e17308af4b173013f746795e9df56f483b9a4c..28e94d1aa30187ca34289ef441dc84ca92e8c1d3 100644 --- a/DDExamples/CLICSiD/src/TubeSegment_geo.cpp +++ b/DDExamples/CLICSiD/src/TubeSegment_geo.cpp @@ -15,19 +15,19 @@ using namespace DD4hep::Geometry; 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,x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); - Volume vol (lcdd,name,tub,lcdd.material(x_det.materialStr())); - + xml_dim_t pos (x_det.child(_X(position))); + xml_dim_t rot (x_det.child(_X(rotation))); + string name = x_det.nameStr(); + Tube tub (x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); + Volume vol (name,tub,lcdd.material(x_det.materialStr())); + vol.setVisAttributes(lcdd, x_det.visStr()); - DetElement sdet(name,x_det.typeStr(),x_det.id()); + DetElement sdet(name,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())); + mother.placeVolume(vol,Position(pos.x(),pos.y(),pos.z()), + Rotation(rot.x(),rot.y(),rot.z())); phv.addPhysVolID(_A(id),x_det.id()); sdet.setPlacement(phv); return sdet; diff --git a/DDExamples/ILDExDet/include/ILDExTPC.h b/DDExamples/ILDExDet/include/ILDExTPC.h index 071fab2f296ea595a4385334ad15e86976380dd0..b914d6da54aa7db8d45e103a3676e09b03e30c45 100644 --- a/DDExamples/ILDExDet/include/ILDExTPC.h +++ b/DDExamples/ILDExDet/include/ILDExTPC.h @@ -15,7 +15,7 @@ namespace DD4hep { struct ILDExTPC : public Geometry::DetElement { typedef Geometry::Ref_t Ref_t; ILDExTPC(const Ref_t& e) : Geometry::DetElement(e) {} - ILDExTPC(const Geometry::LCDD& lcdd, const std::string& name, const std::string& type, int id); + ILDExTPC(const std::string& name, const std::string& type, int id); void setInnerWall(Ref_t obj); void setOuterWall(Ref_t obj); void setGasVolume(Ref_t obj); diff --git a/DDExamples/ILDExDet/include/ILDExVXD.h b/DDExamples/ILDExDet/include/ILDExVXD.h index 3fdf50a6cbeebaafc71d6cf4d879e82ce4cd6437..133745ac671682aef044bbc6074118678bfff005 100644 --- a/DDExamples/ILDExDet/include/ILDExVXD.h +++ b/DDExamples/ILDExDet/include/ILDExVXD.h @@ -13,8 +13,9 @@ namespace DD4hep { struct ILDExVXD : public Geometry::DetElement { - ILDExVXD(const Geometry::LCDD& lcdd, const std::string& name, const std::string& type, int id) - : Geometry::DetElement(lcdd,name,type,id) {} + ILDExVXD(const Geometry::Ref_t& e) : Geometry::DetElement(e) {} + ILDExVXD(const std::string& name, const std::string& type, int id) + : Geometry::DetElement(name,type,id) {} }; } #endif // DD4hep_ILDEXVXD_H diff --git a/DDExamples/ILDExDet/include/TPCModule.h b/DDExamples/ILDExDet/include/TPCModule.h index 9926b8536affcde02e9b690995b49278340325ce..8eff9bef46c345a964daa56234902c65ac36cfe4 100644 --- a/DDExamples/ILDExDet/include/TPCModule.h +++ b/DDExamples/ILDExDet/include/TPCModule.h @@ -21,7 +21,7 @@ namespace DD4hep { TPCModule() {} TPCModule(const Ref_t& e) : Geometry::DetElement(e) {} TPCModule(const Geometry::DetElement& e) : Geometry::DetElement(e) {} - TPCModule(const Geometry::LCDD& lcdd, const std::string& name, const std::string& type, int id); + TPCModule(const std::string& name, const std::string& type, int id); /** ID of this module. */ int getID() const; diff --git a/DDExamples/ILDExDet/src/ILDExTPC.cpp b/DDExamples/ILDExDet/src/ILDExTPC.cpp index 8a66d39066791b6781fe0788f5515d9780ba535e..6d4e3468b754bd6bdbe8fd176e4527f2b1e80cae 100644 --- a/DDExamples/ILDExDet/src/ILDExTPC.cpp +++ b/DDExamples/ILDExDet/src/ILDExTPC.cpp @@ -8,7 +8,7 @@ namespace DD4hep { using namespace Geometry; - ILDExTPC::ILDExTPC(const LCDD&, const string& name, const string& type, int id) + ILDExTPC::ILDExTPC(const string& name, const string& type, int id) { Value<TNamed,TPCData>* p = new Value<TNamed,TPCData>(); assign(p,name, type); diff --git a/DDExamples/ILDExDet/src/TPCModule.cpp b/DDExamples/ILDExDet/src/TPCModule.cpp index 3bb15632f4762ec54a60c5485e86e8dddac8549a..f484351a53d81ad42f15de6b63dae0ad1697ea79 100644 --- a/DDExamples/ILDExDet/src/TPCModule.cpp +++ b/DDExamples/ILDExDet/src/TPCModule.cpp @@ -25,7 +25,7 @@ namespace DD4hep { using namespace Geometry; - TPCModule::TPCModule(const LCDD&, const string& name, const string& type, int id) + TPCModule::TPCModule(const string& name, const string& type, int id) { Value<TNamed,TPCModuleData>* p = new Value<TNamed,TPCModuleData>(); assign(p,name, type); diff --git a/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp b/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp index a824ab9fb2258de7b994f12c5d165542d375be3a..27e5e7aa6b5fc7cf751e524219401ff1e4ed231f 100644 --- a/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp +++ b/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp @@ -25,9 +25,9 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) // DetElement tpc(tpcData, name, x_det.typeStr()); // tpcData->id = x_det.id(); //else do this - DetElement tpc (lcdd,name,x_det.typeStr(),x_det.id()); - Tube tpc_tub(lcdd,name+"_envelope",x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); - Volume tpc_vol(lcdd,name+"_envelope_volume", tpc_tub, mat); + DetElement tpc (name,x_det.typeStr(),x_det.id()); + Tube tpc_tub(x_tube.rmin(),x_tube.rmax(),x_tube.zhalf()); + Volume tpc_vol(name+"_envelope_volume", tpc_tub, mat); for(xml_coll_t c(e,_X(detector)); c; ++c) { xml_comp_t px_det (c); @@ -37,9 +37,9 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) xml_comp_t px_mat (px_det.child(_X(material))); string part_nam(px_det.nameStr()); Material part_mat(lcdd.material(px_mat.nameStr())); - DetElement part_det(lcdd,part_nam,px_det.typeStr(),px_det.id()); - Tube part_tub(lcdd,part_nam+"_tube",px_tube.rmin(),px_tube.rmax(),px_tube.zhalf()); - Volume part_vol(lcdd,part_nam,part_tub,part_mat); + DetElement part_det(part_nam,px_det.typeStr(),px_det.id()); + Tube part_tub(px_tube.rmin(),px_tube.rmax(),px_tube.zhalf()); + Volume part_vol(part_nam,part_tub,part_mat); Position part_pos(px_pos.x(),px_pos.y(),px_pos.z()); Rotation part_rot(px_rot.x(),px_rot.y(),px_rot.z()); bool reflect = px_det.reflect(); @@ -63,15 +63,14 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens) double DeltaPhi=(2*M_PI-nmodules*(row.modulePitch()/(rmin+(rmax-rmin)/2)))/nmodules; double zhalf=px_tube.zhalf(); string mr_nam=m_name+_toString(rowID,"_Row%d"); - Tube mr_tub(lcdd,mr_nam+"_tube",rmin,rmax,zhalf,DeltaPhi); - Volume mr_vol(lcdd,mr_nam,mr_tub,part_mat); + Volume mr_vol(mr_nam,Tube(rmin,rmax,zhalf,DeltaPhi),part_mat); Material mr_mat(lcdd.material(px_mat.nameStr())); Readout xml_pads(lcdd.readout(row.padType())); //placing modules for(int md=0;md<nmodules;md++){ string m_nam=m_name+_toString(rowID,"_Row%d")+_toString(md,"_M%d"); - DetElement module (lcdd,m_nam,row.typeStr(),mdcount); + DetElement module(m_nam,row.typeStr(),mdcount); //data of module, e.g. Readout // Value<TNamed,TPCModuleData>* tpcModData = new Value<TNamed,TPCModuleData>(); // tpcModData->id = mdcount; diff --git a/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp b/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp index 82be5eba2258533f8e70c7e31b2272567ac752ac..b7f2b67e285f7e0544ce7ead1e3bcf594c7b4557 100644 --- a/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp +++ b/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp @@ -18,7 +18,7 @@ namespace DD4hep { namespace Geometry { template <> Ref_t DetElementFactory<ILDExVXD>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector&) { xml_det_t x_det = e; string name = x_det.nameStr(); - ILDExVXD vxd (lcdd,name,x_det.typeStr(),x_det.id()); + ILDExVXD vxd (name,x_det.typeStr(),x_det.id()); Volume mother= lcdd.pickMotherVolume(vxd); for(xml_coll_t c(e,_X(layer)); c; ++c) { @@ -37,12 +37,12 @@ namespace DD4hep { namespace Geometry { double width = 2.*tan(dphi/2.)*(sens_radius-sens_thick/2.); Material sens_mat = lcdd.material(x_ladder.materialStr()); Material supp_mat = lcdd.material(x_support.materialStr()); - Box ladderbox (lcdd,layername+"_ladder_solid", (sens_thick+supp_thick)/2.,width/2.,zhalf); - Volume laddervol (lcdd,layername+"_ladder_volume", ladderbox,sens_mat); - Box sensbox (lcdd,layername+"_sens_solid", sens_thick/2.,width/2.,zhalf); - Volume sensvol (lcdd,layername+"_sens_volume", sensbox,sens_mat); - Box suppbox (lcdd,layername+"_supp_solid", supp_thick/2.,width/2.,zhalf); - Volume suppvol (lcdd,layername+"_supp_volume", suppbox,supp_mat); + Box ladderbox ((sens_thick+supp_thick)/2.,width/2.,zhalf); + Volume laddervol (layername+"_ladder_volume", ladderbox,sens_mat); + Box sensbox (sens_thick/2.,width/2.,zhalf); + Volume sensvol (layername+"_sens_volume", sensbox,sens_mat); + Box suppbox (supp_thick/2.,width/2.,zhalf); + Volume suppvol (layername+"_supp_volume", suppbox,supp_mat); Position senspos (-(sens_thick+supp_thick)/2.+sens_thick/2.,0,0); Position supppos (-(sens_thick+supp_thick)/2.+sens_thick/2.+supp_thick/2.,0,0);