diff --git a/DDCore/include/DD4hep/DetFactoryHelper.h b/DDCore/include/DD4hep/DetFactoryHelper.h index f6641e078106dc38f79dc6f1b2c4f46bd08a04a8..e0f8ec400a5114291ef19e973bcd5b7e269be6c5 100644 --- a/DDCore/include/DD4hep/DetFactoryHelper.h +++ b/DDCore/include/DD4hep/DetFactoryHelper.h @@ -16,6 +16,7 @@ // Helpers to access tags and attributes quickly without specifying explicitly namespaces #define _X(a) DD4hep::XML::Tag_##a #define _A(a) DD4hep::XML::Attr_##a +#define _U(a) DD4hep::XML::Strng_t(#a) // Shortcuts to elements of the XML namespace typedef DD4hep::XML::Tag_t xml_tag_t; @@ -25,7 +26,7 @@ typedef DD4hep::XML::Handle_t xml_h; typedef DD4hep::XML::Element xml_elt_t; typedef DD4hep::XML::RefElement xml_ref_t; typedef DD4hep::XML::DetElement xml_det_t; -typedef xml_det_t::Component xml_comp_t; +typedef DD4hep::XML::Component xml_comp_t; typedef DD4hep::XML::Dimension xml_dim_t; typedef DD4hep::Geometry::LCDD lcdd_t; typedef DD4hep::XML::Strng_t Unicode; diff --git a/DDCore/include/DD4hep/Fields.h b/DDCore/include/DD4hep/Fields.h index e859078829b00064616b70e207c36897ea2c0c5c..2c522349f14bd0424b45fad37d01735bef61d1a3 100644 --- a/DDCore/include/DD4hep/Fields.h +++ b/DDCore/include/DD4hep/Fields.h @@ -27,6 +27,9 @@ namespace DD4hep { */ namespace Geometry { + // Forward declarations + typedef Position Direction; + /** @class CartesianField Fields.h * * Generic structure describing any field type (electric or magnetic) @@ -74,10 +77,10 @@ namespace DD4hep { bool changesEnergy() const; /// Returns the 3 field components (x, y, z). - void value(const Position& pos, Direction& field) const { value(pos,&field.x); } + void value(const Position& pos, Direction& field) const;// { value(pos,&field.x); } /// Returns the 3 field components (x, y, z). - void value(const Position& pos, double* val) const { value(&pos.x,val); } + void value(const Position& pos, double* val) const;// { value(&pos.x,val); } /// Returns the 3 field components (x, y, z). void value(const double* pos, double* val) const; @@ -138,7 +141,7 @@ namespace DD4hep { /// Returns the 3 electric field components (x, y, z) if many components are present void combinedElectric(const Position& pos, double* field) const { - combinedElectric(&pos.x,field); + combinedElectric((const double*)&pos,field); } /// Returns the 3 electric field components (x, y, z) if many components are present @@ -146,7 +149,7 @@ namespace DD4hep { /// Returns the 3 magnetic field components (x, y, z) if many components are present void combinedMagnetic(const Position& pos, double* field) const { - combinedMagnetic(&pos.x,field); + combinedMagnetic((const double*)&pos,field); } /// Returns the 3 magnetic field components (x, y, z) if many components are present @@ -154,12 +157,12 @@ namespace DD4hep { /// Returns the 3 electric field components (x, y, z). void electricField(const Position& pos, Direction& field) const { - electricField(&pos.x, &field.x); + electricField((const double*)&pos, (double*)&field); } /// Returns the 3 electric field components (x, y, z). void electricField(const Position& pos, double* field) const { - electricField(&pos.x, field); + electricField((double*)&pos, field); } /// Returns the 3 electric field components (x, y, z). @@ -170,12 +173,12 @@ namespace DD4hep { /// Returns the 3 magnetic field components (x, y, z). void magneticField(const Position& pos, Direction& field) const { - magneticField(&pos.x, &field.x); + magneticField((double*)&pos, (double*)&field); } /// Returns the 3 magnetic field components (x, y, z). void magneticField(const Position& pos, double* field) const { - magneticField(&pos.x, field); + magneticField((double*)&pos, field); } /// Returns the 3 magnetic field components (x, y, z). @@ -186,7 +189,7 @@ namespace DD4hep { /// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]). void electromagneticField(const Position& pos, double* val) const { - electromagneticField(&pos.x,val); + electromagneticField((double*)&pos,val); } /// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]). diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h index 584bb086fe416485d43b8ce03bf97b608766726a..4b15a2678a0f8b5860392f9953549d505ffac82e 100644 --- a/DDCore/include/DD4hep/LCDD.h +++ b/DDCore/include/DD4hep/LCDD.h @@ -33,7 +33,21 @@ namespace DD4hep { */ namespace Geometry { - /** @class LCDD LCDD.h + /** @enum LCDDBuildType LCDD.h DD4hep/LCDD.h + * Detector description build types. + * The corresponding flag is ONLY valid while parsing the + * compact description. If no eometry, ie. at all other times + * the accessor to the flag returns BUILD_NONE. + */ + enum LCDDBuildType { + BUILD_NONE = 0, + BUILD_DEFAULT = 1, + BUILD_SIMU = BUILD_DEFAULT, + BUILD_RECO, + BUILD_DISPLAY + }; + + /** @class LCDD LCDD.h DD4hep/LCDD.h * * @author M.Frank * @version 1.0 @@ -47,6 +61,8 @@ namespace DD4hep { /// Destructor virtual ~LCDD() {} + /// Access flag to steer the detail of building of the geometry/detector description + virtual LCDDBuildType buildType() const = 0; /// Initialize geometry virtual void init() = 0; /// Finalize the geometry @@ -178,9 +194,9 @@ namespace DD4hep { virtual LCDD& addField(const Ref_t& field) = 0; /// Read compact geometry description or alignment file - virtual void fromCompact(const std::string& fname) = 0; + virtual void fromCompact(const std::string& fname, LCDDBuildType type=BUILD_DEFAULT) = 0; /// Read any geometry description or alignment file - virtual void fromXML(const std::string& fname) = 0; + virtual void fromXML(const std::string& fname, LCDDBuildType type=BUILD_DEFAULT) = 0; /// virtual void dump() const = 0; /// Manipulate geometry using facroy converter diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h index 9d12b606085fc54b11c5097765b6a0fd8cf299b4..5249ae05902b5423bcc7c53f95adf3e16ed8d809 100644 --- a/DDCore/include/DD4hep/Objects.h +++ b/DDCore/include/DD4hep/Objects.h @@ -22,6 +22,13 @@ class TGeoTranslation; class TGeoPhysicalNode; class TGeoIdentity; #include "TGeoPhysicalNode.h" +#include "Math/Vector3D.h" +#include "Math/Transform3D.h" +#include "Math/RotationX.h" +#include "Math/RotationY.h" +#include "Math/RotationZ.h" +#include "Math/RotationZYX.h" +#include "Math/VectorUtil.h" // C/C++ include files #include <set> @@ -137,147 +144,16 @@ namespace DD4hep { std::string toString() const; }; - // We want the 3 coordinates ass-to-ass, so that they can be interpreted as "double*" -#ifdef _WIN32 -#pragma pack(push,DD4Hep_Objects_Position,1) -#define DD4HEP_BYTE_ALIGN(x) x -#elif defined(__CINT__) -#define DD4HEP_BYTE_ALIGN(x) x -#else -#define DD4HEP_BYTE_ALIGN(x) x __attribute__((__packed__)) -#endif - /** @class Position Objects.h - * - * @author M.Frank - * @version 1.0 - */ - DD4HEP_BYTE_ALIGN(struct) Position { - /// 3-dimensional cartesian coordinates - double x, y, z; - /// Default constructor - Position() : x(0), y(0), z(0) {} - /// Initializing constructor - Position(double xval, double yval, double zval) : x(xval), y(yval), z(zval) { } - /// Is it a identity rotation ? - bool isNull() const { return x==0 && y==0 && z==0; } - /// Ceck 2 positions for equality - bool operator==(const Position& c) const { return x==c.x && y==c.y && z==c.z; } - /// Ceck 2 positions for in-equality - bool operator!=(const Position& c) const { return x!=c.x || y!=c.y || x!=c.z; } - /// Negation of the direction - Position operator - () const { return Position(-x,-y,-z); } - /// Scalar multiplication - Position& operator *=(double a) { x *= a;y *= a;z *= a;return *this; } - /// Addition operator - Position& operator +=(const Position& p) { x+=p.x;y+=p.y;z+=p.z;return *this; } - /// Subtraction operator - Position& operator -= (const Position& p) { x-=p.x;y-=p.y;z-=p.z;return *this; } - - /// Position length - double length() const { return sqrt(x*x + y*y + z*z); } - Position& setLength(double new_length) { - double len=length(); - if ( len>std::numeric_limits<double>::epsilon() ) { - len = new_length/len; - x *= len; - y *= len; - z *= len; - } - else { - x = 0; - y = 0; - z = 0; - } - return *this; - } - /// Rho - radius in cylindrical coordinates - double rho() const { return std::sqrt(x*x+y*y); } - /// Phi - rotation angle around z in cylindrical coordinates - double phi() const - { return x == 0.0 && y == 0.0 ? 0.0 : std::atan2(x,y); } - /// Theta - rotation angle around x in cylindrical coordinates - double theta() const - { return x == 0.0 && y == 0.0 && z == 0.0 ? 0.0 : std::atan2(std::sqrt(x*x+y*y),y); } - /// cos(Theta angle): optimisation for std::cos(pos.theta()) - double cosTheta() const - { return x == 0.0 && y == 0.0 && z == 0.0 ? 1.0 : z/std::sqrt(x*x+y*y*z*z); } - /// Rotates the position vector around the x-axis. - Position& rotateX(double angle_in_rad); - /// Rotates the position vector around the y-axis. - Position& rotateY(double angle_in_rad); - /// Rotates the position vector around the z-axis. - Position& rotateZ(double angle_in_rad); - - /// Access to array like coordinates - const double* coordinates() const { return &x; } - /// Initializer for all member variables - Position& set(double xv, double yv, double zv) { x=xv; y=yv; z=zv; return *this; } - }; -#ifdef _WIN32 -#pragma pack(pop,DD4Hep_Objects_Position) -#pragma pack(push,DD4Hep_Objects_Rotation,1) -#endif - /// Addition of 2 positions - inline Position operator + (const Position& l, const Position& r) - { return Position(l.x+r.x,l.y+r.y,l.z+r.z); } - /// Subtraction of to positions - inline Position operator - (const Position& l, const Position& r) - { return Position(l.x-r.x,l.y-r.y,l.z-r.z); } - /// Dot product of 3-vectors. - inline double operator * (const Position& l, const Position& r) - { return sqrt(l.x*r.x + l.y*r.y + l.z*r.z); } - /// Positions scaling from left - inline Position operator * (double l, const Position& r) - { return Position(r.x*l,r.y*l,r.z*l); } - /// Positions scaling from right - inline Position operator * (const Position& l, double r) - { return Position(l.x*r,l.y*r,l.z*r); } - /// Positions scaling from right - inline Position operator / (const Position& l, double r) - { return Position(l.x/r,l.y/r,l.z/r); } - /// Calculate the mean length of two vectors - inline double mean_length(const Position& p1, const Position& p2) - { return 0.5* (p1.length() + p2.length()) / 2.0; } - /// Calculate the mean direction of two vectors - inline Position mean_direction(const Position& p1, const Position& p2) - { return 0.5 * (p1 + p2); } - - typedef Position Direction; - typedef Position Momentum; - - /** @class Rotation Objects.h - * - * @author M.Frank - * @version 1.0 - */ - DD4HEP_BYTE_ALIGN(struct) Rotation { - double theta, phi, psi; - /// Default constructor - Rotation() : theta(0), phi(0), psi(0) {} - /// Initializing constructor - Rotation(double thetaval, double phival, double psival) : theta(thetaval), phi(phival), psi(psival) {} - /// Is it a identity rotation ? - bool isNull() const { return theta==0 && phi==0 && psi==0; } - /// Ceck 2 rotations for equality - bool operator==(const Rotation& c) const { return theta==c.theta && phi==c.phi && psi==c.psi;} - /// Ceck 2 rotations for in-equality - bool operator!=(const Rotation& c) const { return theta!=c.theta || phi!=c.phi || psi!=c.psi;} - /// Access to array like coordinates - const double* angles() const { return θ } - /// Initializer for all member variables - Rotation& set(double th, double ph, double ps) { theta=th; phi=ph; psi=ps;return *this; } - /// Rotates the rotation vector around the x-axis. - Rotation& rotateX(double angle_in_rad); - /// Rotates the rotation vector around the y-axis. - Rotation& rotateY(double angle_in_rad); - /// Rotates the rotation vector around the z-axis. - Rotation& rotateZ(double angle_in_rad); - }; - -#ifdef _WIN32 -#pragma pack(pop,DD4Hep_Objects_Rotation,1) -#endif -#undef DD4HEP_BYTE_ALIGN + typedef ROOT::Math::XYZVector Position; + template <class V> V RotateX(const V& v, double a) { return ROOT::Math::VectorUtil::RotateX(v,a); } + template <class V> V RotateY(const V& v, double a) { return ROOT::Math::VectorUtil::RotateY(v,a); } + template <class V> V RotateZ(const V& v, double a) { return ROOT::Math::VectorUtil::RotateZ(v,a); } + + typedef ROOT::Math::RotationZYX Rotation; + typedef ROOT::Math::RotationZ RotationZ; + typedef ROOT::Math::RotationY RotationY; + typedef ROOT::Math::RotationX RotationX; + typedef ROOT::Math::Transform3D Transform3D; /** @class IdentityPos Objects.h * @@ -559,4 +435,36 @@ namespace DD4hep { } /* End namespace Geometry */ } /* End namespace DD4hep */ + + +namespace ROOT { namespace Math { + typedef DD4hep::Geometry::Position Position; + + /// Addition of 2 positions + inline Position operator + (const Position& l, const Position& r) + { return Position(l.X()+r.X(),l.Y()+r.Y(),l.Z()+r.Z()); } + /// Subtraction of to positions + inline Position operator - (const Position& l, const Position& r) + { return Position(l.X()-r.X(),l.Y()-r.Y(),l.Z()-r.Z()); } + /// Dot product of 3-vectors. + inline double operator * (const Position& l, const Position& r) + { return sqrt(l.X()*r.X() + l.Y()*r.Y() + l.Z()*r.Z()); } + /// Positions scaling from left + inline Position operator * (double l, const Position& r) + { return Position(r.X()*l,r.Y()*l,r.Z()*l); } + /// Positions scaling from right + inline Position operator * (const Position& l, double r) + { return Position(l.X()*r,l.Y()*r,l.Z()*r); } + /// Positions scaling from right + inline Position operator / (const Position& l, double r) + { return Position(l.X()/r,l.Y()/r,l.Z()/r); } + /// Calculate the mean length of two vectors + inline double mean_length(const Position& p1, const Position& p2) + { return 0.5* (p1.R() + p2.R()) / 2.0; } + /// Calculate the mean direction of two vectors + inline Position mean_direction(const Position& p1, const Position& p2) + { return 0.5 * (p1 + p2); } + +}} + #endif /* DD4HEP_GEOMETRY_OBJECTS_H */ diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index 711eb4b1f8deda3a2a91175328f5255ea9577ac3..ede1603ce17e46d62aa6e9659050b807bcde9004 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -12,6 +12,7 @@ // Framework include files #include "DD4hep/Handle.h" +#include "DD4hep/Objects.h" // C/C++ include files #include <vector> @@ -44,8 +45,6 @@ namespace DD4hep { namespace Geometry { // Forward declarations - struct Position; - struct Rotation; /**@class Solid_type Shapes.h * @@ -59,6 +58,8 @@ namespace DD4hep { typedef T Implementation; void _setDimensions(double* param); /// Assign pointrs and register solid to geometry + void _assign(Implementation* n, const std::string& tit, bool cbbox=true); + /// Assign pointrs and register solid to geometry void _assign(Implementation* n, const std::string& nam, const std::string& tit, bool cbbox=true); public: @@ -490,6 +491,8 @@ namespace DD4hep { template<typename Q> SubtractionSolid(const Handle<Q>& e) : BooleanSolid(e) {} /// Constructor to be used when creating a new object. Position is identity, Rotation is identity-rotation! SubtractionSolid(const Solid& shape1, const Solid& shape2); + /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother + SubtractionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& pos); /// Constructor to be used when creating a new object. Rotation is identity-rotation! SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos); /// Constructor to be used when creating a new object @@ -510,6 +513,8 @@ namespace DD4hep { template<typename Q> UnionSolid(const Handle<Q>& e) : BooleanSolid(e) {} /// Constructor to be used when creating a new object. Position is identity, Rotation is identity-rotation! UnionSolid(const Solid& shape1, const Solid& shape2); + /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother + UnionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& pos); /// Constructor to be used when creating a new object. Rotation is identity-rotation! UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos); /// Constructor to be used when creating a new object @@ -530,6 +535,8 @@ namespace DD4hep { template<typename Q> IntersectionSolid(const Handle<Q>& e) : BooleanSolid(e) {} /// Constructor to be used when creating a new object. Position is identity, Rotation is identity-rotation! IntersectionSolid(const Solid& shape1, const Solid& shape2); + /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother + IntersectionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& pos); /// Constructor to be used when creating a new object. Rotation is identity-rotation! IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos); /// Constructor to be used when creating a new object diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 231a457d72432767bcdbcbdfcdb82fba1e64bdf6..8458ce041a22a113c4b4a9dd70df0d90e0cfab65 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -37,11 +37,9 @@ namespace DD4hep { struct Region; struct LimitSet; struct Material; + struct VisAttr; struct Volume; struct PlacedVolume; - struct Position; - struct Rotation; - struct VisAttr; struct SensitiveDetector; /** @class PlacedVolume Volume.h DD4hep/lcdd/Volume.h @@ -124,6 +122,8 @@ namespace DD4hep { /// Place daughter volume. The position and rotation are the identity PlacedVolume placeVolume(const Volume& vol) const { return placeVolume(vol,IdentityPos()); } + /// Place daughter volume according to generic Transform3D + PlacedVolume placeVolume(const Volume& volume, const Transform3D& tr) const; /// Place un-rotated daughter volume at the given position. PlacedVolume placeVolume(const Volume& vol, const Position& pos) const; /// Place rotated daughter volume. The position is automatically the identity position @@ -131,7 +131,7 @@ namespace DD4hep { /// Place rotated and then translated daughter volume PlacedVolume placeVolume(const Volume& vol, const Position& pos, const Rotation& rot) const; /// Place daughter volume in rotated and then translated mother coordinate system - PlacedVolume placeVolumeEx(const Volume& vol, const Position& pos, const Rotation& rot) const; + PlacedVolume placeVolume(const Volume& vol, const Rotation& rot, const Position& pos) const; /// Place daughter volume. The position and rotation are the identity PlacedVolume placeVolume(const Volume& vol, const IdentityPos& pos) const; diff --git a/DDCore/include/XML/XMLDetector.h b/DDCore/include/XML/XMLDetector.h index 3c02bfadf31f327cbee9138e00c8cf85e9a64adb..aa52a910f74c632f5847c28b8b87977e6198bf65 100644 --- a/DDCore/include/XML/XMLDetector.h +++ b/DDCore/include/XML/XMLDetector.h @@ -276,6 +276,54 @@ namespace DD4hep { /// Access attribute values: outer_field double outer_field() const; + /// Access child element with tag "dimensions" as Dimension object + Dimension dimensions(bool throw_if_not_present=true) const; + /// Child access: position + Dimension position(bool throw_if_not_present=true) const; + /// Child access: rotation + Dimension rotation(bool throw_if_not_present=true) const; + /// Child access: trd + Dimension trd(bool throw_if_not_present=true) const; + /// Child access: tubs + Dimension tubs(bool throw_if_not_present=true) const; + /// Child access: staves + Dimension staves(bool throw_if_not_present=true) const; + /// Child access: beampipe + Dimension beampipe(bool throw_if_not_present=true) const; + + /// Access name attribute as STL string + std::string nameStr() const; + /// Access type attribute as STL string + std::string typeStr() const; + /// Access module attribute as STL string + std::string moduleStr() const; + /// Access readout attribute as STL string + std::string readoutStr() const; + /// Access vis attribute as STL string. If not present empty return empty string + std::string visStr() const; + /// Access region attribute as STL string. If not present empty return empty string + std::string regionStr() const; + /// Access limits attribute as STL string. If not present empty return empty string + std::string limitsStr() const; + }; + + /** @class DetElement::Component XMLDetector.h XML/XMLDetector.h + * + * Helper class to access any field in a xml tag. + * Specialized for attributes of a detector sub-element. + * + * @author M.Frank + * @version 1.0 + */ + struct Component : public Dimension { + /// Constructor from Handle + Component(Handle_t e) : Dimension(e) {} + /// Constructor from Element + Component(const Element& e) : Dimension(e) {} + /// Check if component is sensitive + bool isSensitive() const; + /// Access material attribute as STL string + std::string materialStr() const; }; /** @class DetElement XMLDetector.h XML/XMLDetector.h @@ -287,40 +335,6 @@ namespace DD4hep { * @version 1.0 */ struct DetElement : public Dimension { - /** @class DetElement::Component XMLDetector.h XML/XMLDetector.h - * - * Helper class to access any field in a xml tag. - * Specialized for attributes of a detector sub-element. - * - * @author M.Frank - * @version 1.0 - */ - struct Component : public Dimension { - /// Constructor from Handle - Component(Handle_t e) : Dimension(e) {} - /// Constructor from Element - Component(const Element& e) : Dimension(e) {} - /// Check if component is sensitive - bool isSensitive() const; - /// Access name attribute as STL string - std::string nameStr() const; - /// Access type attribute as STL string - std::string typeStr() const; - /// Access module attribute as STL string - std::string moduleStr() const; - /// Access readout attribute as STL string - std::string readoutStr() const; - /// Access material attribute as STL string - std::string materialStr() const; - /// Access vis attribute as STL string. If not present empty return empty string - std::string visStr() const; - /// Access region attribute as STL string. If not present empty return empty string - std::string regionStr() const; - /// Access limits attribute as STL string. If not present empty return empty string - std::string limitsStr() const; - /// Access child element with tag "dimensions" as Dimension object - Dimension dimensions() const; - }; /// Constructor from Handle DetElement(Handle_t e) : Dimension(e) {} /// Access undrlying XML handle object @@ -328,20 +342,8 @@ namespace DD4hep { /// Access parameters: id int id() const; - /// Access name attribute as STL string - std::string nameStr() const; - /// Access type attribute as STL string - std::string typeStr() const; /// Access material attribute as STL string. If not present empty return empty string std::string materialStr() const; - /// Access vis attribute as STL string. - std::string visStr() const; - /// Access region attribute as STL string. If not present empty return empty string - std::string regionStr() const; - /// Access limits attribute as STL string. If not present empty return empty string - std::string limitsStr() const; - /// Access child element with tag "dimensions" as Dimension object - Dimension dimensions() const; /// Check if element describes a tracking detector bool isTracker() const; /// Check if element describes a calorimetric detector diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index 25db7e42479cb7e1f7802ba7e0bfb9f9541c715f..7f29db32d8d708fc26430bb0f8ea739f69541ecf 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -504,45 +504,55 @@ DetElement& DetElement::setReference(DetElement reference) { /// Transformation from local coordinates of the placed volume to the world system bool DetElement::localToWorld(const Position& local, Position& global) const { - Double_t master_point[3]={0,0,0}, local_point[3] = {local.x,local.y,local.z}; + Double_t master_point[3]={0,0,0}, local_point[3] = {local.X(),local.Y(),local.Z()}; // If the path is unknown an exception will be thrown inside worldTransformation() ! _data().worldTransformation()->LocalToMaster(local_point,master_point); - global.set(master_point[0],master_point[1],master_point[2]); + global.SetCoordinates(master_point); return true; } /// Transformation from local coordinates of the placed volume to the parent system bool DetElement::localToParent(const Position& local, Position& global) const { // If the path is unknown an exception will be thrown inside parentTransformation() ! - _data().parentTransformation()->LocalToMaster(&local.x,&global.x); + Double_t master_point[3]={0,0,0}, local_point[3] = {local.X(),local.Y(),local.Z()}; + _data().parentTransformation()->LocalToMaster(local_point,master_point); + global.SetCoordinates(master_point); return true; } /// Transformation from local coordinates of the placed volume to arbitrary parent system set as reference bool DetElement::localToReference(const Position& local, Position& global) const { // If the path is unknown an exception will be thrown inside referenceTransformation() ! - _data().referenceTransformation()->LocalToMaster(&local.x,&global.x); + Double_t master_point[3]={0,0,0}, local_point[3] = {local.X(),local.Y(),local.Z()}; + _data().referenceTransformation()->LocalToMaster(local_point,master_point); + global.SetCoordinates(master_point); return true; } /// Transformation from world coordinates of the local placed volume coordinates bool DetElement::worldToLocal(const Position& global, Position& local) const { // If the path is unknown an exception will be thrown inside worldTransformation() ! - _data().worldTransformation()->MasterToLocal(&global.x,&local.x); + Double_t master_point[3]={global.X(),global.Y(),global.Z()}, local_point[3] = {0,0,0}; + _data().worldTransformation()->MasterToLocal(master_point,local_point); + local.SetCoordinates(local_point); return true; } /// Transformation from parent coordinates of the local placed volume coordinates bool DetElement::parentToLocal(const Position& global, Position& local) const { // If the path is unknown an exception will be thrown inside parentTransformation() ! - _data().parentTransformation()->MasterToLocal(&global.x,&local.x); + Double_t master_point[3]={global.X(),global.Y(),global.Z()}, local_point[3] = {0,0,0}; + _data().parentTransformation()->MasterToLocal(master_point,local_point); + local.SetCoordinates(local_point); return true; } /// Transformation from arbitrary parent system coordinates of the local placed volume coordinates bool DetElement::referenceToLocal(const Position& global, Position& local) const { // If the path is unknown an exception will be thrown inside referenceTransformation() ! - _data().referenceTransformation()->MasterToLocal(&global.x,&local.x); + Double_t master_point[3]={global.X(),global.Y(),global.Z()}, local_point[3] = {0,0,0}; + _data().referenceTransformation()->MasterToLocal(master_point,local_point); + local.SetCoordinates(local_point); return true; } diff --git a/DDCore/src/FieldTypes.cpp b/DDCore/src/FieldTypes.cpp index 40767bb438948fbda7198724f57289a511620f1b..1d80cc6cd56beaaa568602373a5b98096cf7404f 100644 --- a/DDCore/src/FieldTypes.cpp +++ b/DDCore/src/FieldTypes.cpp @@ -19,9 +19,9 @@ using namespace DD4hep::Geometry; /// Call to access the field components at a given location void ConstantField::fieldComponents(const double* /* pos */, double* field) { - field[0] += direction.x; - field[1] += direction.y; - field[2] += direction.z; + field[0] += direction.X(); + field[1] += direction.Y(); + field[2] += direction.Z(); } /// Initializing constructor diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index d9ae4534a37aaea67c591206e855c6d39e969112..e777392d30cfdc3c7371868a8699920029e5cd93 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -36,6 +36,11 @@ namespace { struct TopDetElement : public DetElement { TopDetElement(const string& nam, Volume vol) : DetElement(nam,/* "structure", */0) { _data().volume = vol; } }; + struct TypePreserve { + LCDDBuildType& m_t; + TypePreserve(LCDDBuildType& t) : m_t(t) { } + ~TypePreserve() { m_t = BUILD_NONE; } + }; } LCDD& LCDD::getInstance() { @@ -44,15 +49,22 @@ LCDD& LCDD::getInstance() { } /// Default constructor -LCDDImp::LCDDImp() : m_world(), m_trackers(), m_worldVol(), m_trackingVol(), m_field("global") +LCDDImp::LCDDImp() + : m_world(), m_trackers(), m_worldVol(), m_trackingVol(), m_field("global"), + m_buildType(BUILD_NONE) { m_properties = new Properties(); - if ( 0 == gGeoManager ) { + //if ( 0 == gGeoManager ) + { gGeoManager = new TGeoManager(); gGeoManager->AddNavigator(); gGeoManager->SetCurrentNavigator(0); cout << "Navigator:" << (void*)gGeoManager->GetCurrentNavigator() << endl; } + //if ( 0 == gGeoIdentity ) + { + gGeoIdentity = new TGeoIdentity(); + } VisAttr attr("invisible"); attr.setColor(0.5,0.5,0.5); attr.setAlpha(1); @@ -215,7 +227,8 @@ void LCDDImp::init() { } } -void LCDDImp::fromXML(const string& xmlfile) { +void LCDDImp::fromXML(const string& xmlfile, LCDDBuildType build_type) { + TypePreserve build_type_preserve(m_buildType=build_type); #if DD4HEP_USE_PYROOT string cmd; TPython::Exec("import lcdd"); diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h index cc9d0f976cbd07075c6d3f5ab426812ef4f09de6..6e20d0458ac785f89398a9fa554f98700e1396e6 100644 --- a/DDCore/src/LCDDImp.h +++ b/DDCore/src/LCDDImp.h @@ -84,18 +84,23 @@ namespace DD4hep { OverlayedField m_field; Ref_t m_header; Properties* m_properties; - + LCDDBuildType m_buildType; + /// Default constructor LCDDImp(); /// Standard destructor virtual ~LCDDImp(); + /// Access flag to steer the detail of building of the geometry/detector description + virtual LCDDBuildType buildType() const { return m_buildType; } /// Read compact geometry description or alignment file - virtual void fromCompact(const std::string& fname) { fromXML(fname); } + virtual void fromCompact(const std::string& fname, LCDDBuildType type=BUILD_DEFAULT) + { fromXML(fname,type); } + /// Read any XML file - virtual void fromXML(const std::string& fname); + virtual void fromXML(const std::string& fname,LCDDBuildType type=BUILD_DEFAULT); virtual void dump() const; diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp index 219d18240f20e48799f9be485f23ac0ded11ec79..9a506f65bbc299278be2c3fa66584633e2a3e346 100644 --- a/DDCore/src/Objects.cpp +++ b/DDCore/src/Objects.cpp @@ -125,54 +125,6 @@ string Constant::toString() const { return os.str(); } -/// Rotates the position vector around the x-axis. -Position& Position::rotateX(double angle_in_rad) { - double s = std::sin(angle_in_rad); - double c = std::cos(angle_in_rad); - double t = y * c - z * s; - z = z * c + y * s; - y = t; - return *this; -} - -/// Rotates the position vector around the y-axis. -Position& Position::rotateY(double angle_in_rad) { - double s = std::sin(angle_in_rad); - double c = std::cos(angle_in_rad); - double t = z * c - x * s; - x = x * c + z * s; - z = t; - return *this; -} - -/// Rotates the position vector around the z-axis. -Position& Position::rotateZ(double angle_in_rad) { - double s = std::sin(angle_in_rad); - double c = std::cos(angle_in_rad); - double t = x * c - y * s; - y = y * c + x * s; - x = t; - return *this; -} - -/// Rotates the rotation vector around the x-axis. -Rotation& Rotation::rotateX(double angle_in_rad) { - theta += angle_in_rad; - return *this; -} - -/// Rotates the rotation vector around the y-axis. -Rotation& Rotation::rotateY(double angle_in_rad) { - psi += angle_in_rad; - return *this; -} - -/// Rotates the rotation vector around the z-axis. -Rotation& Rotation::rotateZ(double angle_in_rad) { - phi += angle_in_rad; - return *this; -} - /// Constructor to be used when creating a new DOM tree Atom::Atom(const string& name, const string& formula, int Z, int N, double density) { TGeoElementTable* t = TGeoElement::GetElementTable(); @@ -329,24 +281,13 @@ int AlignmentEntry::align(const Rotation& rot, bool check, double overlap) { /// Align the PhysicalNode (translation + rotation) int AlignmentEntry::align(const Position& pos, const Rotation& rot, bool check, double overlap) { + if ( isValid() ) { - if ( pos.isNull() && rot.isNull() ) - return 0; TGeoHMatrix* new_matrix = dynamic_cast<TGeoHMatrix*>(m_element->GetOriginalMatrix()->MakeClone()); - if ( rot.isNull() ) { - TGeoTranslation m(pos.x,pos.y,pos.z); - new_matrix->Multiply(&m); - } - else if ( pos.isNull() ) { - TGeoRotation m("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - new_matrix->Multiply(&m); - } - else { - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans m(pos.x,pos.y,pos.z,0); - m.SetRotation(rotation); - new_matrix->Multiply(&m); - } + TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); + TGeoCombiTrans m(pos.X(),pos.Y(),pos.Z(),0); + m.SetRotation(rotation); + new_matrix->Multiply(&m); m_element->Align(new_matrix,0,check,overlap); return 1; } @@ -371,8 +312,8 @@ bool Limit::operator==(const Limit& c) const { /// operator less bool Limit::operator< (const Limit& c) const { - if ( value < c.value ) return true; - if ( name < c.name ) return true; + if ( value < c.value ) return true; + if ( name < c.name ) return true; if ( particles < c.particles ) return true; return false; } diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 90a44471e2c0a8fffafc4f26b596eee82eea59a1..caecf029c7aaf9b5f5f2d5d61894a59294327031 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -31,9 +31,7 @@ using namespace std; using namespace DD4hep::Geometry; - TGeoIdentity* DD4hep::Geometry::identityTransform() { - if ( 0 == gGeoIdentity ) gGeoIdentity = new TGeoIdentity(); return gGeoIdentity; } @@ -47,7 +45,13 @@ template<typename T> 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())); +} + +/// Assign pointrs and register solid to geometry +template<typename T> +void Solid_type<T>::_assign(T* n, const string& tit, bool cbbox) { + this->assign(n,"",tit); + if ( cbbox ) n->ComputeBBox(); } /// Access to shape name @@ -83,12 +87,12 @@ double Box::z() const { /// 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); + _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); + _assign(new TGeoPcon(RAD_2_DEGREE*start,RAD_2_DEGREE*delta,0),"polycone",false); } /// Constructor to be used when creating a new object @@ -111,7 +115,7 @@ Polycone::Polycone(double start, double delta, const vector<double>& rmin, const params.push_back(rmin[i]); params.push_back(rmax[i]); } - _assign( new TGeoPcon(¶ms[0]),"","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 @@ -163,17 +167,17 @@ ConeSegment::ConeSegment(const string& name) { /// Constructor to be used when creating a new cone segment object ConeSegment::ConeSegment(double dz, double rmin1, double rmax1, double rmin2, double rmax2, double phi1, double phi2) { - _assign(new TGeoConeSeg(dz,rmin1,rmax1,rmin2,rmax2,RAD_2_DEGREE * phi1,RAD_2_DEGREE * phi2),"","cone_segment"); + _assign(new TGeoConeSeg(dz,rmin1,rmax1,rmin2,rmax2,RAD_2_DEGREE*phi1,RAD_2_DEGREE*phi2),"cone_segment"); } /// Constructor to be used when creating a new cone segment object ConeSegment::ConeSegment(const string& name, double dz, double rmin1, double rmax1, double rmin2, double rmax2, double phi1, double phi2) { - _assign(new TGeoConeSeg(dz,rmin1,rmax1,rmin2,rmax2,RAD_2_DEGREE * phi1,RAD_2_DEGREE * phi2),name,"cone_segment"); + _assign(new TGeoConeSeg(dz,rmin1,rmax1,rmin2,rmax2,RAD_2_DEGREE*phi1,RAD_2_DEGREE*phi2),name,"cone_segment"); } /// Set the cone segment dimensions ConeSegment& ConeSegment::setDimensions(double dz, double rmin1, double rmax1, double rmin2, double rmax2, double phi1, double phi2) { - double params[] = {dz,rmin1,rmax1,rmin2,rmax2,RAD_2_DEGREE * phi1,RAD_2_DEGREE * phi2}; + double params[] = {dz,rmin1,rmax1,rmin2,rmax2,RAD_2_DEGREE*phi1,RAD_2_DEGREE*phi2}; _setDimensions(params); return *this; } @@ -216,7 +220,7 @@ Cone& Cone::setDimensions(double z,double rmin1,double rmax1,double rmin2,double /// Constructor to be used when creating a new object Trapezoid::Trapezoid() { - _assign(new TGeoTrd2(0,0,0,0,0),"","trd2"); + _assign(new TGeoTrd2(0,0,0,0,0),"trd2"); } /// Constructor to be used when creating a new object @@ -231,7 +235,7 @@ Trapezoid::Trapezoid(const string& name, double x1, double x2, double y1, double /// 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"); + _assign(new TGeoTrd2(x1,x2,y1,y2,z),"trd2"); } /// Set the Trapezoid dimensions @@ -265,7 +269,7 @@ Paraboloid& Paraboloid::setDimensions(double r_low, double r_high, double delta_ /// Constructor to be used when creating a new anonymous object Sphere::Sphere() { - _assign(new TGeoSphere(0,0),"","sphere"); + _assign(new TGeoSphere(0,0),"sphere"); } /// Constructor to be used when creating a new identified object @@ -280,7 +284,7 @@ Sphere::Sphere(const string& name, double rmin, double rmax, double theta, doubl /// 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"); + _assign(new TGeoSphere(rmin,rmax,theta,delta_theta,phi,delta_phi),"sphere"); } /// Set the Sphere dimensions @@ -292,7 +296,7 @@ Sphere& Sphere::setDimensions(double rmin, double rmax, double theta, double del /// Constructor to be used when creating a new object Torus::Torus() { - _assign(new TGeoTorus(0,0,0),"","torus"); + _assign(new TGeoTorus(0,0,0),"torus"); } /// Constructor to be used when creating a new object @@ -307,7 +311,7 @@ Torus::Torus(const string& name, double r, double rmin, double rmax, double phi, /// 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"); + _assign(new TGeoTorus(r,rmin,rmax,phi,delta_phi),"torus"); } /// Set the Torus dimensions @@ -347,7 +351,7 @@ Trap::Trap( double z, 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"); + _assign(new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2),"trap"); } /// Constructor to be used when creating a new anonymous object with attribute initialization @@ -359,7 +363,7 @@ Trap::Trap( double pz, double py, double px, double pLTX) { double x1 = px/2e0; double x2 = pLTX/2e0; double alpha1 = (pLTX-px)/py; - _assign(new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y1,x1,x2,alpha1),"","trap"); + _assign(new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y1,x1,x2,alpha1),"trap"); } /// Set the trap dimensions @@ -397,7 +401,7 @@ PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double 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); + _assign(new TGeoPgon(),"polyhedra",false); double params[] = { RAD_2_DEGREE * 2 * M_PI, RAD_2_DEGREE * 2 * M_PI, @@ -416,9 +420,9 @@ PolyhedraRegular::PolyhedraRegular(int nsides, double phistart, double rmin, dou 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); + _assign(new TGeoPgon(),"polyhedra",false); double params[] = { - phistart, + RAD_2_DEGREE * phistart, RAD_2_DEGREE * 2 * M_PI, double(nsides), 2e0, @@ -435,7 +439,7 @@ PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double 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); + _assign(new TGeoPgon(),"polyhedra",false); double params[] = { RAD_2_DEGREE * 2 * M_PI, RAD_2_DEGREE * 2 * M_PI, @@ -448,35 +452,43 @@ PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double } /// Constructor to be used when creating a new object. Position is identity, Rotation is the identity rotation -SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2) -{ +SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2) { TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),identityTransform()); - _assign(new TGeoCompositeShape("",sub), "", "subtraction"); + _assign(new TGeoCompositeShape("",sub),"subtraction"); +} + +/// Constructor to be used when creating a new object. Placement by a generic transformation within the mother +SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans) { + TGeoHMatrix* tr = new TGeoHMatrix(); + Double_t* t = tr->GetTranslation(); + Double_t* r = tr->GetRotationMatrix(); + trans.GetComponents(r[0],r[1],r[2],t[0],r[3],r[4],r[5],t[1],r[6],r[7],r[8],t[2]); + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),tr); + _assign(new TGeoCompositeShape("",sub),"subtraction"); } /// Constructor to be used when creating a new object. Rotation is the identity rotation -SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) -{ - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); - TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),trans); - _assign(new TGeoCompositeShape("",sub), "", "subtraction"); +SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) { + TGeoTranslation* tr = new TGeoTranslation(pos.X(),pos.Y(),pos.Z()); + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),tr); + _assign(new TGeoCompositeShape("",sub),"subtraction"); } /// Constructor to be used when creating a new object SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) { - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); + TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); trans->SetRotation(rotation.Inverse()); TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),trans); - _assign(new TGeoCompositeShape("",sub), "", "subtraction"); + _assign(new TGeoCompositeShape("",sub),"subtraction"); } /// 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) { - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); + TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); trans->SetRotation(rotation.Inverse()); TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape(name.c_str(),sub), name, "subtraction"); @@ -486,65 +498,85 @@ SubtractionSolid::SubtractionSolid(const string& name, const Solid& shape1, cons UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2) { TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),identityTransform()); - _assign(new TGeoCompositeShape("",uni), "", "union"); + _assign(new TGeoCompositeShape("",uni),"union"); +} + +/// Constructor to be used when creating a new object. Placement by a generic transformation within the mother +UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans) { + TGeoHMatrix* tr = new TGeoHMatrix(); + Double_t* t = tr->GetTranslation(); + Double_t* r = tr->GetRotationMatrix(); + trans.GetComponents(r[0],r[1],r[2],t[0],r[3],r[4],r[5],t[1],r[6],r[7],r[8],t[2]); + TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),tr); + _assign(new TGeoCompositeShape("",uni),"union"); } /// Constructor to be used when creating a new object. Rotation is identity rotation UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) { - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),trans); - _assign(new TGeoCompositeShape("",uni), "", "union"); + _assign(new TGeoCompositeShape("",uni),"union"); } /// Constructor to be used when creating a new object UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) { - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); - trans->SetRotation(rotation.Inverse()); - TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),trans); - _assign(new TGeoCompositeShape("",uni), "", "union"); + TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); + TGeoCombiTrans* tr = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); + tr->SetRotation(rotation.Inverse()); + TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),tr); + _assign(new TGeoCompositeShape("",uni),"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) { - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); + TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); trans->SetRotation(rotation.Inverse()); TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape(name.c_str(),uni), name, "union"); } -/// Constructor to be used when creating a new object. Position is identity. -IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) { - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); - TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); - _assign(new TGeoCompositeShape("",inter), "", "intersection"); -} - /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2) { TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),identityTransform()); - _assign(new TGeoCompositeShape("",inter), "", "intersection"); + _assign(new TGeoCompositeShape("",inter),"intersection"); +} + +/// Constructor to be used when creating a new object. Placement by a generic transformation within the mother +IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans) { + TGeoHMatrix* tr = new TGeoHMatrix(); + Double_t* t = tr->GetTranslation(); + Double_t* r = tr->GetRotationMatrix(); + trans.GetComponents(r[0],r[1],r[2],t[0],r[3],r[4],r[5],t[1],r[6],r[7],r[8],t[2]); + TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),tr); + _assign(new TGeoCompositeShape("",inter),"intersection"); +} + +/// Constructor to be used when creating a new object. Position is identity. +IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) { + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); + TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); + _assign(new TGeoCompositeShape("",inter),"intersection"); } /// Constructor to be used when creating a new object IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) { - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); + TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); trans->SetRotation(rotation.Inverse()); TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); - _assign(new TGeoCompositeShape("",inter), "", "intersection"); + _assign(new TGeoCompositeShape("",inter),"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) { - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); + TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); trans->SetRotation(rotation.Inverse()); TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape(name.c_str(),inter),name,"intersection"); diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 95a8728f7d49ac5dff055cece5caba2bd17fe368..f2ee7b3f7a72825ff38d96f5b7e54299575cf184 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -288,30 +288,66 @@ static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* } static TGeoTranslation* _translation(const Position& pos) { - return new TGeoTranslation("",pos.x,pos.y,pos.z); + return new TGeoTranslation("",pos.X(),pos.Y(),pos.Z()); } static TGeoRotation* _rotation(const Rotation& rot) { - return new TGeoRotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); + return new TGeoRotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); +} + +/// Place daughter volume according to generic Transform3D +PlacedVolume Volume::placeVolume(const Volume& volume, const Transform3D& tr) const { + Rotation rot; + Position pos; + tr.GetDecomposition(rot,pos); + return placeVolume(volume,rot,pos); +#if 0 + if ( volume.isValid() ) { + TGeoHMatrix *trans = new TGeoHMatrix(); + double v[12], t[3], r[9]; + tr.GetComponents(v); + t[0] = v[3]; + t[1] = v[7]; + t[2] = v[11]; + r[0] = v[0]; + r[1] = v[1]; + r[2] = v[2]; + r[3] = v[4]; + r[4] = v[5]; + r[5] = v[6]; + r[6] = v[8]; + r[7] = v[9]; + r[8] = v[10]; + trans->SetRotation(r); + trans->SetTranslation(t); + return _addNode(m_element,volume,trans); + } + throw runtime_error("Volume: Attempt to assign an invalid physical volume."); +#endif } /// Place translated and rotated daughter volume PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos, const Rotation& rot) const { if ( volume.isValid() ) { - TGeoCombiTrans* transform = new TGeoCombiTrans("",pos.x,pos.y,pos.z,_rotation(rot)); + TGeoCombiTrans* transform = new TGeoCombiTrans("",pos.X(),pos.Y(),pos.Z(),_rotation(rot)); return _addNode(m_element,volume,transform); } throw runtime_error("Volume: Attempt to assign an invalid physical volume."); } -/// Place translated and rotated daughter volume -PlacedVolume Volume::placeVolumeEx(const Volume& volume, const Position& pos, const Rotation& rot) const { +/// Place daughter volume in rotated and then translated mother coordinate system +PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation& rot, const Position& pos) const { if ( volume.isValid() ) { - TGeoHMatrix *transform = new TGeoHMatrix(TGeoTranslation(pos.x,pos.y,pos.z)); - transform->RotateZ(rot.phi*RAD_2_DEGREE); - transform->RotateX(rot.theta*RAD_2_DEGREE); - transform->RotateY(rot.psi*RAD_2_DEGREE); - return _addNode(m_element,volume,transform); + TGeoHMatrix *trans = new TGeoHMatrix(); + double t[3]; + trans->RotateZ(rot.Phi()*RAD_2_DEGREE); + trans->RotateY(rot.Theta()*RAD_2_DEGREE); + trans->RotateX(rot.Psi()*RAD_2_DEGREE); + pos.GetCoordinates(t); + trans->SetDx(t[0]); + trans->SetDy(t[1]); + trans->SetDz(t[2]); + return _addNode(m_element,volume,trans); } throw runtime_error("Volume: Attempt to assign an invalid physical volume."); } diff --git a/DDCore/src/XML/LCDDConverter.cpp b/DDCore/src/XML/LCDDConverter.cpp index 3a9ed9c4f1f9e1ff098ef09eb65c0ddff1e22b67..d258e1eeda466b1f0473c83cadfe980824373dc2 100644 --- a/DDCore/src/XML/LCDDConverter.cpp +++ b/DDCore/src/XML/LCDDConverter.cpp @@ -56,8 +56,6 @@ typedef Geometry::LimitSet LimitSet; typedef Geometry::IDDescriptor IDDescriptor; typedef Geometry::PlacedVolume PlacedVolume; -#define _U(x) Unicode(#x) - #define TAG(x) extern const Tag_t Tag_##x (#x) #define ATTR(x) extern const Tag_t Attr_##x (#x) @@ -407,11 +405,11 @@ Handle_t LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) obj.setAttr(_A(y),tr[1]*CM_2_MM); obj.setAttr(_A(z),tr[2]*CM_2_MM); } - if ((rot.x != 0.0) || (rot.y != 0.0) || (rot.z != 0.0)) { + if ((rot.X() != 0.0) || (rot.Y() != 0.0) || (rot.Z() != 0.0)) { first.append(obj=Element(geo.doc,_X(firstrotation))); - obj.setAttr(_A(x),rot.x); - obj.setAttr(_A(y),rot.y); - obj.setAttr(_A(z),rot.z); + obj.setAttr(_A(x),rot.X()); + obj.setAttr(_A(y),rot.Y()); + obj.setAttr(_A(z),rot.Z()); } rot = getXYZangles(boolean->GetRightMatrix()->Inverse().GetRotationMatrix()); @@ -424,11 +422,11 @@ Handle_t LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) obj.setAttr(_A(y),tr[1]*CM_2_MM); obj.setAttr(_A(z),tr[2]*CM_2_MM); } - if ((rot.x != 0.0) || (rot.y != 0.0) || (rot.z != 0.0)) { + if ((rot.X() != 0.0) || (rot.Y() != 0.0) || (rot.Z() != 0.0)) { first.append(obj=Element(geo.doc,_X(rotation))); - obj.setAttr(_A(x),rot.x); - obj.setAttr(_A(y),rot.y); - obj.setAttr(_A(z),rot.z); + obj.setAttr(_A(x),rot.X()); + obj.setAttr(_A(y),rot.Y()); + obj.setAttr(_A(z),rot.Z()); } } if ( !solid ) { @@ -478,12 +476,12 @@ Handle_t LCDDConverter::handleRotation(const std::string& name, const TGeoMatrix if ( !rot ) { static Handle_t identity; XYZRotation r = getXYZangles(trafo->Inverse().GetRotationMatrix()); - if ( r.x != 0 || r.y != 0 || r.z != 0 ) { + if ( r.X() != 0 || r.Y() != 0 || r.Z() != 0 ) { geo.doc_define.append(rot=Element(geo.doc,_X(rotation))); rot.setAttr(_A(name),name); - rot.setAttr(_A(x),r.x); - rot.setAttr(_A(y),r.y); - rot.setAttr(_A(z),r.z); + rot.setAttr(_A(x),r.X()); + rot.setAttr(_A(y),r.Y()); + rot.setAttr(_A(z),r.Z()); } else if ( identity ) { rot = identity; diff --git a/DDCore/src/XML/Layering.cpp b/DDCore/src/XML/Layering.cpp index 7317026e88349e00469d3016182f507963de0a66..376c24c530bb99410776bc49645028d54f8d8a05 100644 --- a/DDCore/src/XML/Layering.cpp +++ b/DDCore/src/XML/Layering.cpp @@ -81,11 +81,11 @@ void LayeringCnv::fromCompact(Layering& layering) const { for_each(layers.begin(),layers.end(),deletePtr<Layer>); for(Collection_t c(m_element,Tag_layer); c; ++c) { Layer lay; - DetElement::Component layer = c; + Component layer = c; int repeat = layer.hasAttr(Attr_repeat) ? layer.repeat() : 1; ++count; for(Collection_t s(c,Tag_slice); s; ++s) { - DetElement::Component slice = s; + Component slice = s; string mat = slice.materialStr(); LayerSlice lslice(slice.isSensitive(), slice.thickness(), mat); lay.add(lslice); @@ -101,12 +101,11 @@ void LayeringCnv::fromCompact(Layering& layering) const { } double Layering::singleLayerThickness(XML::Element e) const { - DetElement::Component layer = e; + Component layer = e; double thickness = 0e0; for(Collection_t s(layer,Tag_slice); s; ++s) { - DetElement::Component slice = s; + Component slice = s; thickness += slice.thickness(); } return thickness; } - diff --git a/DDCore/src/XML/XMLDetector.cpp b/DDCore/src/XML/XMLDetector.cpp index 37a8eaac99821fb01285d71e662749c737a26634..bcc0c7b356a5d9abb39abbfa1c33df037b4db2c9 100644 --- a/DDCore/src/XML/XMLDetector.cpp +++ b/DDCore/src/XML/XMLDetector.cpp @@ -17,6 +17,10 @@ using namespace DD4hep::XML; const XmlChar* val = m_element.attr_value_nothrow(Attr_##name); \ return val ? _toBool(val) : default_val; } +#define XML_CHILD_ACCESSOR_XML_DIM(name) \ + Dimension Dimension::name(bool throw_if_not_present) const { \ + return m_element.child(Tag_##name,throw_if_not_present); } + XML_ATTR_ACCESSOR(int,id) XML_ATTR_ACCESSOR_INT(id) @@ -132,72 +136,61 @@ XML_ATTR_ACCESSOR(int,id) XML_ATTR_ACCESSOR(double,) #endif + XML_CHILD_ACCESSOR_XML_DIM(dimensions) + XML_CHILD_ACCESSOR_XML_DIM(position) + XML_CHILD_ACCESSOR_XML_DIM(rotation) + XML_CHILD_ACCESSOR_XML_DIM(trd) + XML_CHILD_ACCESSOR_XML_DIM(tubs) + XML_CHILD_ACCESSOR_XML_DIM(staves) + XML_CHILD_ACCESSOR_XML_DIM(beampipe) + + string Dimension::padType() const { return m_element.attr<string>(Attr_pads); } -string DetElement::Component::nameStr() const { +string Dimension::nameStr() const { return m_element.attr<string>(Attr_name); } -string DetElement::Component::materialStr() const { - return m_element.attr<string>(Attr_material); -} - -string DetElement::Component::moduleStr() const { - return m_element.hasAttr(Attr_module) ? m_element.attr<string>(Attr_module) : string(); +string Dimension::typeStr() const { + return m_element.attr<string>(Attr_type); } -string DetElement::Component::typeStr() const { - return m_element.attr<string>(Attr_type); +string Dimension::regionStr() const { + return m_element.hasAttr(Attr_region) ? m_element.attr<string>(Attr_region) : string(); } -bool DetElement::Component::isSensitive() const { - char val = m_element.hasAttr(Attr_sensitive) ? m_element.attr<string>(Attr_sensitive)[0] : 'f'; - val = ::toupper(val); - return val == 'T' || val == 'Y'; +string Dimension::limitsStr() const { + return m_element.hasAttr(Attr_limits) ? m_element.attr<string>(Attr_limits) : string(); } -string DetElement::Component::visStr() const { +string Dimension::visStr() const { return m_element.hasAttr(Attr_vis) ? m_element.attr<string>(Attr_vis) : string(); } -string DetElement::Component::readoutStr() const { +string Dimension::readoutStr() const { return m_element.hasAttr(Attr_readout) ? m_element.attr<string>(Attr_readout) : string(); } -string DetElement::Component::regionStr() const { - return m_element.hasAttr(Attr_region) ? m_element.attr<string>(Attr_region) : string(); +string Dimension::moduleStr() const { + return m_element.hasAttr(Attr_module) ? m_element.attr<string>(Attr_module) : string(); } -string DetElement::Component::limitsStr() const { - return m_element.hasAttr(Attr_limits) ? m_element.attr<string>(Attr_limits) : string(); +string Component::materialStr() const { + return m_element.attr<string>(Attr_material); } -Dimension DetElement::Component::dimensions() const { - return Dimension(m_element.child(Tag_dimensions)); +bool Component::isSensitive() const { + char val = m_element.hasAttr(Attr_sensitive) ? m_element.attr<string>(Attr_sensitive)[0] : 'f'; + val = ::toupper(val); + return val == 'T' || val == 'Y'; } int DetElement::id() const { return m_element.hasAttr(Attr_id) ? m_element.attr<int>(Attr_id) : -1; } -string DetElement::nameStr() const { - return m_element.attr<string>(Attr_name); -} - -string DetElement::typeStr() const { - return m_element.attr<string>(Attr_type); -} - -string DetElement::visStr() const { - return m_element.attr<string>(Attr_vis); -} - -Dimension DetElement::dimensions() const { - return Dimension(m_element.child(Tag_dimensions)); -} - string DetElement::materialStr() const { Handle_t h = m_element.child(Tag_material); if ( h && h.hasAttr(Attr_name) ) { @@ -206,14 +199,6 @@ string DetElement::materialStr() const { return ""; } -string DetElement::regionStr() const { - return m_element.hasAttr(Attr_region) ? m_element.attr<string>(Attr_region) : string(); -} - -string DetElement::limitsStr() const { - return m_element.hasAttr(Attr_limits) ? m_element.attr<string>(Attr_limits) : string(); -} - void DetElement::check(bool condition, const string& msg) const { if ( condition ) { throw runtime_error(msg); diff --git a/DDCore/src/compact/Compact2Objects.cpp b/DDCore/src/compact/Compact2Objects.cpp index abbd0e94645201b6ac44aa609b074db14d88ed66..a5711d60f4afce9332ee58cc608586f1363efa5f 100644 --- a/DDCore/src/compact/Compact2Objects.cpp +++ b/DDCore/src/compact/Compact2Objects.cpp @@ -122,7 +122,9 @@ static Ref_t create_ConstantField(lcdd_t& /* lcdd */, const xml_h& e) { string t = e.attr<string>(_A(field)); Value<TNamed,ConstantField>* ptr = new Value<TNamed,ConstantField>(); ptr->type = ::toupper(t[0])=='E' ? CartesianField::ELECTRIC : CartesianField::MAGNETIC; - ptr->direction.set(strength.x(),strength.y(),strength.z()); + ptr->direction.SetX(strength.x()); + ptr->direction.SetY(strength.y()); + ptr->direction.SetZ(strength.z()); obj.assign(ptr,field.nameStr(),field.typeStr()); return obj; } @@ -406,14 +408,10 @@ template <> void Converter<AlignmentEntry>::operator()(const xml_h& e) const { Position pos; Rotation rot; if ( (child=e.child(_X(position),false)) ) { // Position is not mandatory! - pos.x = child.x(); - pos.y = child.y(); - pos.z = child.z(); + pos.SetXYZ(child.x(),child.y(),child.z()); } if ( (child=e.child(_X(rotation),false)) ) { // Rotation is not mandatory - rot.theta = child.x(); // child.theta(); - rot.phi = child.y(); // child.phi(); - rot.psi = child.z(); // child.psi(); + rot.SetComponents(child.z(),child.y(),child.x()); } if ( overlap ) { double ovl = e.attr<double>(_A(overlap));