From 3b98f89dd04cd9cb70f3d1f26e799532217f519e Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Tue, 20 Nov 2012 19:43:17 +0000 Subject: [PATCH] Add second placement option --- DDCore/include/DD4hep/Objects.h | 4 +++ DDCore/include/DD4hep/Volumes.h | 4 ++- DDCore/src/Segementations.cpp | 12 ++++----- DDCore/src/Shapes.cpp | 32 ++++++++++++------------ DDCore/src/Volumes.cpp | 43 ++++++++++++++++++++++----------- 5 files changed, 59 insertions(+), 36 deletions(-) diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h index ec60a9a05..c7491033e 100644 --- a/DDCore/include/DD4hep/Objects.h +++ b/DDCore/include/DD4hep/Objects.h @@ -20,6 +20,7 @@ class TGeoMatrix; class TGeoRotation; class TGeoTranslation; class TGeoPhysicalNode; +class TGeoIdentity; #include "TGeoPhysicalNode.h" // C/C++ include files @@ -48,6 +49,9 @@ namespace DD4hep { class IDDescriptor; + /** Access to identity transformation */ + TGeoIdentity* identityTransform(); + /** @class Author Objects.h * * @author M.Frank diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 1c2f6aea1..161ec033d 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -129,8 +129,10 @@ namespace DD4hep { PlacedVolume placeVolume(const Volume& vol, const Position& pos) const; /// Place rotated daughter volume. The position is automatically the identity position PlacedVolume placeVolume(const Volume& vol, const Rotation& rot) const; - /// Place translated and rotated daughter volume + /// 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; /// Place daughter volume. The position and rotation are the identity PlacedVolume placeVolume(const Volume& vol, const IdentityPos& pos) const; diff --git a/DDCore/src/Segementations.cpp b/DDCore/src/Segementations.cpp index 87f305cb9..01a235f03 100644 --- a/DDCore/src/Segementations.cpp +++ b/DDCore/src/Segementations.cpp @@ -71,22 +71,22 @@ ProjectiveCylinder::ProjectiveCylinder() : Segmentation("projective_cylinder") {} /// Accessors: get number of bins in theta -int ProjectiveCylinder::thetaBins() const { +int ProjectiveCylinder::thetaBins() const { return _data().data.cylindrical_binning.ntheta; } /// Accessors: get number of bins in phi -int ProjectiveCylinder::phiBins() const { +int ProjectiveCylinder::phiBins() const { return _data().data.cylindrical_binning.nphi; } /// Accessors: set number of bins in theta -void ProjectiveCylinder::setThetaBins(int value) { +void ProjectiveCylinder::setThetaBins(int value) { _data().data.cylindrical_binning.ntheta = value; } /// Accessors: set grid size in Y -void ProjectiveCylinder::setPhiBins(int value) { +void ProjectiveCylinder::setPhiBins(int value) { _data().data.cylindrical_binning.nphi = value; } @@ -95,11 +95,11 @@ NonProjectiveCylinder::NonProjectiveCylinder() { } -double NonProjectiveCylinder::gridSizeZ() const { +double NonProjectiveCylinder::gridSizeZ() const { return _data().data.cylindrical_grid.grid_size_z; } -double NonProjectiveCylinder::gridSizePhi() const { +double NonProjectiveCylinder::gridSizePhi() const { return _data().data.cylindrical_grid.grid_size_phi; } diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 0d13630f7..627c51ccf 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -31,8 +31,10 @@ using namespace std; using namespace DD4hep::Geometry; -namespace { - static TGeoIdentity s_identity; + +TGeoIdentity* DD4hep::Geometry::identityTransform() { + if ( 0 == gGeoIdentity ) gGeoIdentity = new TGeoIdentity(); + return gGeoIdentity; } template<typename T> void Solid_type<T>::_setDimensions(double* param) { @@ -177,7 +179,7 @@ ConeSegment& ConeSegment::setDimensions(double dz, double rmin1, double rmax1, d } /// Constructor to be used when creating a new object with attribute initialization -void Tube::make(const string& name, double rmin, double rmax, double startPhi, double z, double deltaPhi) +void Tube::make(const string& name, double rmin, double rmax, double z, double startPhi, double deltaPhi) { _assign(new TGeoTubeSeg(rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi),name,"tube"); } @@ -443,7 +445,7 @@ 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) { - TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,&s_identity,&s_identity); + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),identityTransform()); _assign(new TGeoCompositeShape("",sub), "", "subtraction"); } @@ -451,7 +453,7 @@ SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2) 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,&s_identity,trans); + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape("",sub), "", "subtraction"); } @@ -461,7 +463,7 @@ SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, con 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,&s_identity,trans); + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape("",sub), "", "subtraction"); } @@ -471,14 +473,14 @@ SubtractionSolid::SubtractionSolid(const string& name, const Solid& shape1, cons 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,&s_identity,trans); + TGeoSubtraction* sub = new TGeoSubtraction(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape(name.c_str(),sub), name, "subtraction"); } /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2) { - TGeoUnion* uni = new TGeoUnion(shape1,shape2,&s_identity,&s_identity); + TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),identityTransform()); _assign(new TGeoCompositeShape("",uni), "", "union"); } @@ -486,7 +488,7 @@ UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2) UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) { TGeoCombiTrans* trans = new TGeoCombiTrans(pos.x,pos.y,pos.z,0); - TGeoUnion* uni = new TGeoUnion(shape1,shape2,&s_identity,trans); + TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape("",uni), "", "union"); } @@ -496,7 +498,7 @@ UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Position& 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,&s_identity,trans); + TGeoUnion* uni = new TGeoUnion(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape("",uni), "", "union"); } @@ -506,20 +508,20 @@ UnionSolid::UnionSolid(const string& name, const Solid& shape1, const Solid& sha 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,&s_identity,trans); + 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,&s_identity,trans); + 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,&s_identity,&s_identity); + TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),identityTransform()); _assign(new TGeoCompositeShape("",inter), "", "intersection"); } @@ -529,7 +531,7 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, c 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,&s_identity,trans); + TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape("",inter), "", "intersection"); } @@ -539,7 +541,7 @@ IntersectionSolid::IntersectionSolid(const string& name, const Solid& shape1, co 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,&s_identity,trans); + 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 09c7108d6..13376464c 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -273,18 +273,39 @@ static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* TGeoVolume* parent = par; TObjArray* a = parent->GetNodes(); Int_t id = a ? a->GetEntries() : 0; + if ( transform && transform != identityTransform() ) { + string nam = string(daughter->GetName())+"_placement"; + transform->SetName(nam.c_str()); + } parent->AddNode(daughter,id,transform); TGeoNodeMatrix* n = dynamic_cast<TGeoNodeMatrix*>(parent->GetNode(id)); return PlacedVolume(n); } +static TGeoTranslation* _translation(const Position& pos) { + 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); +} + /// Place translated and rotated daughter volume PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos, const Rotation& rot) const { if ( volume.isValid() ) { - string nam = string(volume.name())+"_placement"; - TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - TGeoCombiTrans* transform = new TGeoCombiTrans(nam.c_str(),pos.x,pos.y,pos.z,0); - transform->SetRotation(rotation); + 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 { + 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); } throw runtime_error("Volume: Attempt to assign an invalid physical volume."); @@ -293,9 +314,7 @@ PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos, cons /// Place un-rotated daughter volume at the given position. PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos) const { if ( volume.isValid() ) { - string nam = string(volume.name())+"_placement"; - TGeoTranslation* transform = new TGeoTranslation(nam.c_str(),pos.x,pos.y,pos.z); - return _addNode(m_element,volume,transform); + return _addNode(m_element,volume,_translation(pos)); } throw runtime_error("Volume: Attempt to assign an invalid physical volume."); } @@ -303,9 +322,7 @@ PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos) con /// Place rotated daughter volume. The position is automatically the identity position PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation& rot) const { if ( volume.isValid() ) { - string nam = string(volume.name())+"_placement"; - TGeoRotation* transform = new TGeoRotation(nam.c_str(),rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE); - return _addNode(m_element,volume,transform); + return _addNode(m_element,volume,_rotation(rot)); } throw runtime_error("Volume: Attempt to assign an invalid physical volume."); } @@ -313,8 +330,7 @@ PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation& rot) con /// Place daughter volume. The position and rotation are the identity PlacedVolume Volume::placeVolume(const Volume& volume, const IdentityPos& /* pos */) const { if ( volume.isValid() ) { - string nam = string(volume.name())+"_placement"; - return _addNode(m_element,volume,new TGeoIdentity(nam.c_str())); + return _addNode(m_element,volume,identityTransform()); } throw runtime_error("Volume: Attempt to assign an invalid physical volume."); } @@ -322,8 +338,7 @@ PlacedVolume Volume::placeVolume(const Volume& volume, const IdentityPos& /* pos /// Place daughter volume. The position and rotation are the identity PlacedVolume Volume::placeVolume(const Volume& volume, const IdentityRot& /* rot */) const { if ( volume.isValid() ) { - string nam = string(volume.name())+"_placement"; - return _addNode(m_element,volume,new TGeoIdentity(nam.c_str())); + return _addNode(m_element,volume,identityTransform()); } throw runtime_error("Volume: Attempt to assign an invalid physical volume."); } -- GitLab