Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:59

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 #define _USE_MATH_DEFINES
0015 
0016 // Framework include files
0017 #include <DD4hep/Detector.h>
0018 #include <DD4hep/MatrixHelpers.h>
0019 #include <DD4hep/DD4hepUnits.h>
0020 #include <DD4hep/ShapeTags.h>
0021 #include <DD4hep/Printout.h>
0022 #include <DD4hep/detail/ShapesInterna.h>
0023 
0024 // C/C++ include files
0025 #include <stdexcept>
0026 #include <iomanip>
0027 #include <sstream>
0028 
0029 // ROOT includes
0030 #include <TClass.h>
0031 #include <TGeoMatrix.h>
0032 #include <TGeoBoolNode.h>
0033 #include <TGeoScaledShape.h>
0034 #include <TGeoCompositeShape.h>
0035 
0036 using namespace dd4hep;
0037 namespace units = dd4hep;
0038 
0039 template <typename T> void Solid_type<T>::_setDimensions(double* param)   const {
0040   auto p = this->access(); // Ensure we have a valid handle!
0041   p->SetDimensions(param);
0042   p->ComputeBBox();
0043 }
0044 
0045 /// Assign pointrs and register solid to geometry
0046 template <typename T>
0047 void Solid_type<T>::_assign(T* n, const std::string& nam, const std::string& tit, bool cbbox) {
0048   this->assign(n, nam, tit);
0049   if (cbbox)
0050     n->ComputeBBox();
0051 }
0052 
0053 /// Access to shape name
0054 template <typename T> const char* Solid_type<T>::name() const {
0055   if ( this->ptr() )  {
0056     return this->ptr()->GetName();
0057   }
0058   return this->access()->GetName();   // Trigger an exception if object is invalid
0059 }
0060 
0061 /// Access to shape name
0062 template <typename T> const char* Solid_type<T>::title() const {
0063   if ( this->ptr() )  {
0064     return this->ptr()->GetTitle();
0065   }
0066   return this->access()->GetTitle();   // Trigger an exception if object is invalid
0067 }
0068 
0069 /// Set new shape name
0070 template <typename T> Solid_type<T>& Solid_type<T>::setName(const char* value)    {
0071   this->access()->SetName(value);
0072   return *this;
0073 }
0074 
0075 /// Set new shape name
0076 template <typename T> Solid_type<T>& Solid_type<T>::setName(const std::string& value)    {
0077   this->access()->SetName(value.c_str());
0078   return *this;
0079 }
0080 
0081 /// Access to shape type (The TClass name of the ROOT implementation)
0082 template <typename T> const char* Solid_type<T>::type() const  {
0083   if ( this->ptr() )  {
0084     return this->ptr()->IsA()->GetName();
0085   }
0086   return this->access()->GetName();  // Trigger an exception on invalid handle
0087 }
0088 
0089 /// Access the dimensions of the shape: inverse of the setDimensions member function
0090 template <typename T> std::vector<double> Solid_type<T>::dimensions()  {
0091   return get_shape_dimensions(this->access());
0092 }
0093 
0094 /// Set the shape dimensions. As for the TGeo shape, but angles in rad rather than degrees.
0095 template <typename T> Solid_type<T>& Solid_type<T>::setDimensions(const std::vector<double>& params)  {
0096   set_shape_dimensions(this->access(), params);
0097   return *this;
0098 }
0099 
0100 /// Divide volume into subsections (See the ROOT manuloa for details)
0101 template <typename T> TGeoVolume*
0102 Solid_type<T>::divide(const Volume& voldiv, const std::string& divname,
0103                       int iaxis, int ndiv, double start, double step)   const {
0104   T* p = this->ptr();
0105   if ( p )  {
0106     auto* pdiv = p->Divide(voldiv.ptr(), divname.c_str(), iaxis, ndiv, start, step);
0107     if ( pdiv )   {
0108       VolumeMulti mv(pdiv);
0109       return mv.ptr();
0110     }
0111     except("dd4hep","Volume: Failed to divide volume %s -> %s [Invalid result]",
0112        voldiv.name(), divname.c_str());
0113   }
0114   except("dd4hep","Volume: Attempt to divide an invalid logical volume to %s.", divname.c_str());
0115   return 0;
0116 }
0117 
0118 /// Constructor to create an anonymous new box object (retrieves name from volume)
0119 ShapelessSolid::ShapelessSolid(const std::string& nam)  {
0120   _assign(new TGeoShapeAssembly(), nam, SHAPELESS_TAG, true);
0121 }
0122 
0123 void Scale::make(const std::string& nam, Solid base, double x_scale, double y_scale, double z_scale)   {
0124   auto scale = std::make_unique<TGeoScale>(x_scale, y_scale, z_scale);
0125   _assign(new TGeoScaledShape(nam.c_str(), base.access(), scale.release()), "", SCALE_TAG, true);
0126 }
0127 
0128 /// Access x-scale factor
0129 double Scale::scale_x() const {
0130   return this->access()->GetScale()->GetScale()[0];
0131 }
0132 
0133 /// Access y-scale factor
0134 double Scale::scale_y() const {
0135   return this->access()->GetScale()->GetScale()[1];
0136 }
0137 
0138 /// Access z-scale factor
0139 double Scale::scale_z() const {
0140   return this->access()->GetScale()->GetScale()[2];
0141 }
0142 
0143 void Box::make(const std::string& nam, double x_val, double y_val, double z_val)   {
0144   _assign(new TGeoBBox(nam.c_str(), x_val, y_val, z_val), "", BOX_TAG, true);
0145 }
0146 
0147 /// Set the box dimensionsy
0148 Box& Box::setDimensions(double x_val, double y_val, double z_val)   {
0149   double params[] = { x_val, y_val, z_val};
0150   _setDimensions(params);
0151   return *this;
0152 }
0153 
0154 /// Access half "length" of the box
0155 double Box::x() const {
0156   return this->ptr()->GetDX();
0157 }
0158 
0159 /// Access half "width" of the box
0160 double Box::y() const {
0161   return this->ptr()->GetDY();
0162 }
0163 
0164 /// Access half "depth" of the box
0165 double Box::z() const {
0166   return this->ptr()->GetDZ();
0167 }
0168 
0169 /// Internal helper method to support object construction
0170 void HalfSpace::make(const std::string& nam, const double* const point, const double* const normal)   {
0171   _assign(new TGeoHalfSpace(nam.c_str(),(Double_t*)point, (Double_t*)normal), "", HALFSPACE_TAG,true);
0172 }
0173 
0174 /// Constructor to be used when creating a new object
0175 Polycone::Polycone(double startPhi, double deltaPhi) {
0176   _assign(new TGeoPcon(startPhi/units::deg, deltaPhi/units::deg, 0), "", POLYCONE_TAG, false);
0177 }
0178 
0179 /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
0180 Polycone::Polycone(double startPhi, double deltaPhi,
0181                    const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z) {
0182   std::vector<double> params;
0183   if (rmin.size() < 2) {
0184     throw std::runtime_error("dd4hep: PolyCone Not enough Z planes. minimum is 2!");
0185   }
0186   if((z.size()!=rmin.size()) || (z.size()!=rmax.size()) )    {
0187     throw std::runtime_error("dd4hep: Polycone: vectors z,rmin,rmax not of same length");
0188   }
0189   params.emplace_back(startPhi/units::deg);
0190   params.emplace_back(deltaPhi/units::deg);
0191   params.emplace_back(rmin.size());
0192   for (std::size_t i = 0; i < rmin.size(); ++i) {
0193     params.emplace_back(z[i] );
0194     params.emplace_back(rmin[i] );
0195     params.emplace_back(rmax[i] );
0196   }
0197   _assign(new TGeoPcon(&params[0]), "", POLYCONE_TAG, true);
0198 }
0199 
0200 /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
0201 Polycone::Polycone(double startPhi, double deltaPhi, const std::vector<double>& r, const std::vector<double>& z) {
0202   std::vector<double> params;
0203   if (r.size() < 2) {
0204     throw std::runtime_error("dd4hep: PolyCone Not enough Z planes. minimum is 2!");
0205   }
0206   if((z.size()!=r.size()) )    {
0207     throw std::runtime_error("dd4hep: Polycone: vectors z,r not of same length");
0208   } 
0209   params.emplace_back(startPhi/units::deg);
0210   params.emplace_back(deltaPhi/units::deg);
0211   params.emplace_back(r.size());
0212   for (std::size_t i = 0; i < r.size(); ++i) {
0213     params.emplace_back(z[i] );
0214     params.emplace_back(0.0  );
0215     params.emplace_back(r[i] );
0216   }
0217   _assign(new TGeoPcon(&params[0]), "", POLYCONE_TAG, true);
0218 }
0219 
0220 /// Constructor to be used when creating a new object
0221 Polycone::Polycone(const std::string& nam, double startPhi, double deltaPhi) {
0222   _assign(new TGeoPcon(nam.c_str(), startPhi/units::deg, deltaPhi/units::deg, 0), "", POLYCONE_TAG, false);
0223 }
0224 
0225 /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
0226 Polycone::Polycone(const std::string& nam, double startPhi, double deltaPhi,
0227                    const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z) {
0228   std::vector<double> params;
0229   if (rmin.size() < 2) {
0230     throw std::runtime_error("dd4hep: PolyCone Not enough Z planes. minimum is 2!");
0231   }
0232   if((z.size()!=rmin.size()) || (z.size()!=rmax.size()) )    {
0233     throw std::runtime_error("dd4hep: Polycone: vectors z,rmin,rmax not of same length");
0234   }
0235   params.emplace_back(startPhi/units::deg);
0236   params.emplace_back(deltaPhi/units::deg);
0237   params.emplace_back(rmin.size());
0238   for (std::size_t i = 0; i < rmin.size(); ++i) {
0239     params.emplace_back(z[i] );
0240     params.emplace_back(rmin[i] );
0241     params.emplace_back(rmax[i] );
0242   }
0243   _assign(new TGeoPcon(&params[0]), nam, POLYCONE_TAG, true);
0244 }
0245 
0246 /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
0247 Polycone::Polycone(const std::string& nam, double startPhi, double deltaPhi, const std::vector<double>& r, const std::vector<double>& z) {
0248   std::vector<double> params;
0249   if (r.size() < 2) {
0250     throw std::runtime_error("dd4hep: PolyCone Not enough Z planes. minimum is 2!");
0251   }
0252   if((z.size()!=r.size()) )    {
0253     throw std::runtime_error("dd4hep: Polycone: vectors z,r not of same length");
0254   } 
0255   params.emplace_back(startPhi/units::deg);
0256   params.emplace_back(deltaPhi/units::deg);
0257   params.emplace_back(r.size());
0258   for (std::size_t i = 0; i < r.size(); ++i) {
0259     params.emplace_back(z[i] );
0260     params.emplace_back(0.0  );
0261     params.emplace_back(r[i] );
0262   }
0263   _assign(new TGeoPcon(&params[0]), nam, POLYCONE_TAG, true);
0264 }
0265 
0266 /// Add Z-planes to the Polycone
0267 void Polycone::addZPlanes(const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z) {
0268   TGeoPcon* sh = *this;
0269   std::vector<double> params;
0270   std::size_t num = sh->GetNz();
0271   if (num + rmin.size() < 2)   {
0272     except("PolyCone","++ addZPlanes: Not enough Z planes. minimum is 2!");
0273   }
0274   params.emplace_back(sh->GetPhi1());
0275   params.emplace_back(sh->GetDphi());
0276   params.emplace_back(num + rmin.size());
0277   for (std::size_t i = 0; i < num; ++i) {
0278     params.emplace_back(sh->GetZ(i));
0279     params.emplace_back(sh->GetRmin(i));
0280     params.emplace_back(sh->GetRmax(i));
0281   }
0282   for (std::size_t i = 0; i < rmin.size(); ++i) {
0283     params.emplace_back(z[i] );
0284     params.emplace_back(rmin[i] );
0285     params.emplace_back(rmax[i] );
0286   }
0287   _setDimensions(&params[0]);
0288 }
0289 
0290 /// Constructor to be used when creating a new cone segment object
0291 void ConeSegment::make(const std::string& nam,
0292                        double dz, 
0293                        double rmin1,     double rmax1,
0294                        double rmin2,     double rmax2,
0295                        double startPhi,  double endPhi)
0296 {
0297   _assign(new TGeoConeSeg(nam.c_str(), dz, rmin1, rmax1, rmin2, rmax2,
0298                           startPhi/units::deg, endPhi/units::deg), "", CONESEGMENT_TAG, true);
0299 }
0300 
0301 /// Set the cone segment dimensions
0302 ConeSegment& ConeSegment::setDimensions(double dz, 
0303                                         double rmin1, double rmax1,
0304                                         double rmin2, double rmax2,
0305                                         double startPhi,  double endPhi) {
0306   double params[] = { dz, rmin1, rmax1, rmin2, rmax2, startPhi/units::deg, endPhi/units::deg };
0307   _setDimensions(params);
0308   return *this;
0309 }
0310 
0311 /// Constructor to be used when creating a new object with attribute initialization
0312 void Cone::make(const std::string& nam, double z, double rmin1, double rmax1, double rmin2, double rmax2) {
0313   _assign(new TGeoCone(nam.c_str(), z, rmin1, rmax1, rmin2, rmax2 ), "", CONE_TAG, true);
0314 }
0315 
0316 /// Set the box dimensions (startPhi=0.0, endPhi=2*pi)
0317 Cone& Cone::setDimensions(double z, double rmin1, double rmax1, double rmin2, double rmax2) {
0318   double params[] = { z, rmin1, rmax1, rmin2, rmax2  };
0319   _setDimensions(params);
0320   return *this;
0321 }
0322 
0323 /// Constructor to be used when creating a new object with attribute initialization
0324 void Tube::make(const std::string& nam, double rmin, double rmax, double z, double start_phi, double end_phi) {
0325   // Check if it is a full tube
0326   if(fabs(end_phi-start_phi-2*M_PI)<10e-6){
0327     _assign(new TGeoTubeSeg(nam.c_str(), rmin, rmax, z, start_phi/units::deg, start_phi/units::deg+360.),nam,TUBE_TAG,true);
0328   }else{
0329     _assign(new TGeoTubeSeg(nam.c_str(), rmin, rmax, z, start_phi/units::deg, end_phi/units::deg),nam,TUBE_TAG,true);
0330   }
0331 }
0332 
0333 /// Set the tube dimensions
0334 Tube& Tube::setDimensions(double rmin, double rmax, double z, double start_phi, double end_phi) {
0335   double params[] = {rmin,rmax,z,start_phi/units::deg,end_phi/units::deg};
0336   _setDimensions(params);
0337   return *this;
0338 }
0339 
0340 /// Constructor to be used when creating a new object with attribute initialization
0341 CutTube::CutTube(double rmin, double rmax, double dz, double start_phi, double end_phi,
0342                  double lx, double ly, double lz, double tx, double ty, double tz)  {
0343   make("", rmin,rmax,dz,start_phi/units::deg,end_phi/units::deg,lx,ly,lz,tx,ty,tz);
0344 }
0345 
0346 /// Constructor to be used when creating a new object with attribute initialization
0347 CutTube::CutTube(const std::string& nam,
0348                  double rmin, double rmax, double dz, double start_phi, double end_phi,
0349                  double lx, double ly, double lz, double tx, double ty, double tz)  {
0350   make(nam, rmin,rmax,dz,start_phi/units::deg,end_phi/units::deg,lx,ly,lz,tx,ty,tz);
0351 }
0352 
0353 /// Constructor to be used when creating a new object with attribute initialization
0354 void CutTube::make(const std::string& nam, double rmin, double rmax, double dz, double start_phi, double end_phi,
0355                    double lx, double ly, double lz, double tx, double ty, double tz)  {
0356   _assign(new TGeoCtub(nam.c_str(), rmin,rmax,dz,start_phi,end_phi,lx,ly,lz,tx,ty,tz),"",CUTTUBE_TAG,true);
0357 }
0358 
0359 /// Constructor to create a truncated tube object with attribute initialization
0360 TruncatedTube::TruncatedTube(double dz, double rmin, double rmax, double start_phi, double delta_phi,
0361                              double cut_atStart, double cut_atDelta, bool cut_inside)
0362 {  make("", dz, rmin, rmax, start_phi/units::deg, delta_phi/units::deg, cut_atStart, cut_atDelta, cut_inside);    }
0363 
0364 /// Constructor to create a truncated tube object with attribute initialization
0365 TruncatedTube::TruncatedTube(const std::string& nam,
0366                              double dz, double rmin, double rmax, double start_phi, double delta_phi,
0367                              double cut_atStart, double cut_atDelta, bool cut_inside)
0368 {  make(nam, dz, rmin, rmax, start_phi/units::deg, delta_phi/units::deg, cut_atStart, cut_atDelta, cut_inside);    }
0369 
0370 /// Internal helper method to support object construction
0371 void TruncatedTube::make(const std::string& nam,
0372                          double dz, double rmin, double rmax, double start_phi, double delta_phi,
0373                          double cut_atStart, double cut_atDelta, bool cut_inside)   {
0374   // check the parameters
0375   if( rmin <= 0 || rmax <= 0 || cut_atStart <= 0 || cut_atDelta <= 0 )
0376     except(TRUNCATEDTUBE_TAG,"++ 0 <= rIn,cut_atStart,rOut,cut_atDelta,rOut violated!");
0377   else if( rmin >= rmax )
0378     except(TRUNCATEDTUBE_TAG,"++ rIn<rOut violated!");
0379   else if( start_phi != 0. )
0380     except(TRUNCATEDTUBE_TAG,"++ start_phi != 0 not supported!");
0381 
0382   double r         = cut_atStart;
0383   double R         = cut_atDelta;
0384   // angle of the box w.r.t. tubs
0385   double cath      = r - R * std::cos( delta_phi*units::deg );
0386   double hypo      = std::sqrt( r*r + R*R - 2.*r*R * std::cos( delta_phi*units::deg ));
0387   double cos_alpha = cath / hypo;
0388   double alpha     = std::acos( cos_alpha );
0389   double sin_alpha = std::sin( std::fabs(alpha) );
0390   
0391   // exaggerate dimensions - does not matter, it's subtracted!
0392   // If we don't, the **edge** of the box would cut into the tube segment
0393   // for larger delta-phi values
0394   double boxX      = 1.1*rmax + rmax/sin_alpha; // Need to adjust for move!
0395   double boxY      = rmax;
0396   // width of the box > width of the tubs
0397   double boxZ      = 1.1 * dz;
0398   double xBox;      // center point of the box
0399   if( cut_inside )
0400     xBox = r - boxY / sin_alpha;
0401   else
0402     xBox = r + boxY / sin_alpha;
0403 
0404   // rotationmatrix of box w.r.t. tubs
0405   TGeoRotation rot;
0406   rot.RotateZ( -alpha/dd4hep::deg );
0407   TGeoTranslation trans(xBox, 0., 0.);  
0408   TGeoBBox*        box   = new TGeoBBox((nam+"Box").c_str(), boxX, boxY, boxZ);
0409   TGeoTubeSeg*     tubs  = new TGeoTubeSeg((nam+"Tubs").c_str(), rmin, rmax, dz, start_phi, delta_phi);
0410   TGeoCombiTrans*  combi = new TGeoCombiTrans(trans, rot);
0411   TGeoSubtraction* sub   = new TGeoSubtraction(tubs, box, nullptr, combi);
0412   _assign(new TGeoCompositeShape(nam.c_str(), sub),"",TRUNCATEDTUBE_TAG,true);
0413   std::stringstream params;
0414   params << dz                  << " " << std::endl
0415          << rmin                << " " << std::endl
0416          << rmax                << " " << std::endl
0417          << start_phi*units::deg << " " << std::endl
0418          << delta_phi*units::deg << " " << std::endl
0419          << cut_atStart          << " " << std::endl
0420          << cut_atDelta          << " " << std::endl
0421          << char(cut_inside ? '1' : '0') << std::endl;
0422   combi->SetTitle(params.str().c_str());
0423   //cout << "Params: " << params.str() << std::endl;
0424 #if 0
0425   params << TRUNCATEDTUBE_TAG << ":" << std::endl
0426          << "\t dz:          " << dz << " " << std::endl
0427          << "\t rmin:        " << rmin << " " << std::endl
0428          << "\t rmax:        " << rmax << " " << std::endl
0429          << "\t startPhi:    " << start_phi << " " << std::endl
0430          << "\t deltaPhi:    " << delta_phi << " " << std::endl
0431          << "\t r/cutAtStart:" << cut_atStart << " " << std::endl
0432          << "\t R/cutAtDelta:" << cut_atDelta << " " << std::endl
0433          << "\t cutInside:   " << char(cut_inside ? '1' : '0') << std::endl
0434          << "\t\t alpha:     " << alpha << std::endl
0435          << "\t\t sin_alpha: " << sin_alpha << std::endl
0436          << "\t\t boxY:      " << boxY << std::endl
0437          << "\t\t xBox:      " << xBox << std::endl;
0438 #endif
0439 #if 0
0440   cout << "Trans:";  trans.Print(); cout << std::endl;
0441   cout << "Rot:  ";  rot.Print();   cout << std::endl;
0442   cout << " Dz:           " << dz
0443        << " rmin:         " << rmin
0444        << " rmax:         " << rmax
0445        << " r/cutAtStart: " << r
0446        << " R/cutAtDelta: " << R
0447        << " cutInside:    " << (cut_inside ? "YES" : "NO ")
0448        << std::endl;
0449   cout << " cath:      " << cath
0450        << " hypo:      " << hypo
0451        << " cos_alpha: " << cos_alpha
0452        << " alpha:     " << alpha
0453        << " alpha(deg):" << alpha/dd4hep::deg
0454        << std::endl;
0455   cout << " Deg:       " << dd4hep::deg
0456        << " cm:        " << dd4hep::cm
0457        << " xBox:      " << xBox
0458        << std::endl;
0459   cout << "Box:" << "x:" << box->GetDX() << " y:" << box->GetDY() << " z:" << box->GetDZ() << std::endl;
0460   cout << "Tubs:" << " rmin:" << rmin << " rmax" << rmax << "dZ" << dZ
0461        << " startPhi:" <<  start_phi << " deltaPhi:" << delta_phi << std::endl;
0462 #endif
0463 }
0464 
0465 /// Accessor: dZ value
0466 double TruncatedTube::dZ() const    {
0467   return dd4hep::dimensions<TruncatedTube>(*this)[0];
0468 }
0469 
0470 /// Accessor: r-min value
0471 double TruncatedTube::rMin() const   {
0472   return dd4hep::dimensions<TruncatedTube>(*this)[1];
0473 }
0474 
0475 /// Accessor: r-max value
0476 double TruncatedTube::rMax() const   {
0477   return dd4hep::dimensions<TruncatedTube>(*this)[2];
0478 }
0479 
0480 /// Accessor: start-phi value
0481 double TruncatedTube::startPhi() const    {
0482   return dd4hep::dimensions<TruncatedTube>(*this)[3];
0483 }
0484 
0485 /// Accessor: delta-phi value
0486 double TruncatedTube::deltaPhi() const    {
0487   return dd4hep::dimensions<TruncatedTube>(*this)[4];
0488 }
0489 
0490 /// Accessor: cut at start value
0491 double TruncatedTube::cutAtStart() const   {
0492   return dd4hep::dimensions<TruncatedTube>(*this)[5];
0493 }
0494 
0495 /// Accessor: cut at delta value
0496 double TruncatedTube::cutAtDelta() const   {
0497   return dd4hep::dimensions<TruncatedTube>(*this)[6];
0498 }
0499 
0500 /// Accessor: cut-inside value
0501 bool TruncatedTube::cutInside() const   {
0502   return std::abs(dd4hep::dimensions<TruncatedTube>(*this)[7]) > std::numeric_limits<double>::epsilon();
0503 }
0504 
0505 /// Constructor to be used when creating a new object with attribute initialization
0506 void EllipticalTube::make(const std::string& nam, double a, double b, double dz) {
0507   _assign(new TGeoEltu(nam.c_str(), a, b, dz), "", ELLIPTICALTUBE_TAG, true);
0508 }
0509 
0510 /// Internal helper method to support TwistedTube object construction
0511 void TwistedTube::make(const std::string& nam, double twist_angle, double rmin, double rmax,
0512                        double zneg, double zpos, int nsegments, double totphi)   {
0513   _assign(new TwistedTubeObject(nam.c_str(), twist_angle/units::deg, rmin, rmax, zneg, zpos, nsegments, totphi/units::deg),
0514           "", TWISTEDTUBE_TAG, true);
0515 }
0516 
0517 /// Constructor to be used when creating a new object with attribute initialization
0518 void Trd1::make(const std::string& nam, double x1, double x2, double y, double z) {
0519   _assign(new TGeoTrd1(nam.c_str(), x1, x2, y, z ), "", TRD1_TAG, true);
0520 }
0521 
0522 /// Set the Trd1 dimensions
0523 Trd1& Trd1::setDimensions(double x1, double x2, double y, double z) {
0524   double params[] = { x1, x2, y, z  };
0525   _setDimensions(params);
0526   return *this;
0527 }
0528 
0529 /// Constructor to be used when creating a new object with attribute initialization
0530 void Trd2::make(const std::string& nam, double x1, double x2, double y1, double y2, double z) {
0531   _assign(new TGeoTrd2(nam.c_str(), x1, x2, y1, y2, z ), "", TRD2_TAG, true);
0532 }
0533 
0534 /// Set the Trd2 dimensions
0535 Trd2& Trd2::setDimensions(double x1, double x2, double y1, double y2, double z) {
0536   double params[] = { x1, x2, y1, y2, z  };
0537   _setDimensions(params);
0538   return *this;
0539 }
0540 
0541 /// Constructor to be used when creating a new object with attribute initialization
0542 void Paraboloid::make(const std::string& nam, double r_low, double r_high, double delta_z) {
0543   _assign(new TGeoParaboloid(nam.c_str(), r_low, r_high, delta_z ), "", PARABOLOID_TAG, true);
0544 }
0545 
0546 /// Set the Paraboloid dimensions
0547 Paraboloid& Paraboloid::setDimensions(double r_low, double r_high, double delta_z) {
0548   double params[] = { r_low, r_high, delta_z  };
0549   _setDimensions(params);
0550   return *this;
0551 }
0552 
0553 /// Constructor to create a new anonymous object with attribute initialization
0554 void Hyperboloid::make(const std::string& nam, double rin, double stin, double rout, double stout, double dz) {
0555   _assign(new TGeoHype(nam.c_str(), rin, stin/units::deg, rout, stout/units::deg, dz), "", HYPERBOLOID_TAG, true);
0556 }
0557 
0558 /// Set the Hyperboloid dimensions
0559 Hyperboloid& Hyperboloid::setDimensions(double rin, double stin, double rout, double stout, double dz)  {
0560   double params[] = { rin, stin/units::deg, rout, stout/units::deg, dz};
0561   _setDimensions(params);
0562   return *this;
0563 }
0564 
0565 /// Constructor function to be used when creating a new object with attribute initialization
0566 void Sphere::make(const std::string& nam, double rmin, double rmax, double startTheta, double endTheta, double startPhi, double endPhi) {
0567   _assign(new TGeoSphere(nam.c_str(), rmin, rmax,
0568                          startTheta/units::deg, endTheta/units::deg,
0569                          startPhi/units::deg,   endPhi/units::deg), "", SPHERE_TAG, true);
0570 }
0571 
0572 /// Set the Sphere dimensions
0573 Sphere& Sphere::setDimensions(double rmin, double rmax, double startTheta, double endTheta, double startPhi, double endPhi) {
0574   double params[] = { rmin, rmax, startTheta/units::deg, endTheta/units::deg, startPhi/units::deg, endPhi/units::deg };
0575   _setDimensions(params);
0576   return *this;
0577 }
0578 
0579 /// Constructor to be used when creating a new object with attribute initialization
0580 void Torus::make(const std::string& nam, double r, double rmin, double rmax, double startPhi, double deltaPhi) {
0581   _assign(new TGeoTorus(nam.c_str(), r, rmin, rmax, startPhi/units::deg, deltaPhi/units::deg), "", TORUS_TAG, true);
0582 }
0583 
0584 /// Set the Torus dimensions
0585 Torus& Torus::setDimensions(double r, double rmin, double rmax, double startPhi, double deltaPhi) {
0586   double params[] = { r, rmin, rmax, startPhi/units::deg, deltaPhi/units::deg };
0587   _setDimensions(params);
0588   return *this;
0589 }
0590 
0591 /// Constructor to be used when creating a new anonymous object with attribute initialization
0592 Trap::Trap(double z, double theta, double phi,
0593            double h1, double bl1, double tl1, double alpha1,
0594            double h2, double bl2, double tl2, double alpha2) {
0595   _assign(new TGeoTrap(z, theta/units::deg, phi/units::deg,
0596                        h1, bl1, tl1, alpha1/units::deg,
0597                        h2, bl2, tl2, alpha2/units::deg), "", TRAP_TAG, true);
0598 }
0599 
0600 /// Constructor to be used when creating a new anonymous object with attribute initialization
0601 Trap::Trap(const std::string& nam,
0602            double z, double theta, double phi,
0603            double h1, double bl1, double tl1, double alpha1,
0604            double h2, double bl2, double tl2, double alpha2) {
0605   _assign(new TGeoTrap(nam.c_str(), z, theta/units::deg, phi/units::deg,
0606                        h1, bl1, tl1, alpha1/units::deg,
0607                        h2, bl2, tl2, alpha2/units::deg), "", TRAP_TAG, true);
0608 }
0609 
0610 /// Constructor to be used when creating a new anonymous object with attribute initialization
0611 void Trap::make(const std::string& nam, double pZ, double pY, double pX, double pLTX) {
0612   double fDz  = 0.5*pZ;
0613   double fTheta = 0;
0614   double fPhi = 0;
0615   double fDy1 = 0.5*pY;
0616   double fDx1 = 0.5*pX;
0617   double fDx2 = 0.5*pLTX;
0618   double fAlpha1 = atan(0.5*(pLTX - pX)/pY);
0619   double fDy2 = fDy1;
0620   double fDx3 = fDx1;
0621   double fDx4 = fDx2;
0622   double fAlpha2 = fAlpha1;
0623 
0624   _assign(new TGeoTrap(nam.c_str(),
0625                fDz,  fTheta /* = 0 */,  fPhi /* = 0 */,
0626                        fDy1, fDx1, fDx2, fAlpha1/units::deg,
0627                        fDy2, fDx3, fDx4, fAlpha2/units::deg), "", TRAP_TAG, true);
0628 }
0629 
0630 /// Set the trap dimensions
0631 Trap& Trap::setDimensions(double z, double theta, double phi,
0632                           double h1, double bl1, double tl1, double alpha1,
0633                           double h2, double bl2, double tl2, double alpha2) {
0634   double params[] = { z,  theta/units::deg, phi/units::deg,
0635                       h1, bl1, tl1, alpha1/units::deg,
0636                       h2, bl2, tl2, alpha2/units::deg };
0637   _setDimensions(params);
0638   return *this;
0639 }
0640 
0641 /// Internal helper method to support object construction
0642 void PseudoTrap::make(const std::string& nam, double x1, double x2, double y1, double y2, double z, double r, bool atMinusZ)    {
0643   double x            = atMinusZ ? x1 : x2;
0644   double h            = 0;
0645   bool   intersec     = false; // union or intersection solid
0646   double displacement = 0;
0647   double startPhi     = 0;
0648   double halfZ        = z;
0649   double halfOpeningAngle = std::asin( x / std::abs( r ))/units::deg;
0650 
0651   /// calculate the displacement of the tubs w.r.t. to the trap, determine the opening angle of the tubs
0652   double delta        = std::sqrt( r * r - x * x );
0653  
0654 #if 0
0655   // Implementation from : (Crappy)
0656   // https://cmssdt.cern.ch/lxr/source/SimG4Core/Geometry/src/DDG4SolidConverter.cc#0362
0657   if( r < 0 && std::abs(r) >= x )  {
0658     intersec = true;       // intersection solid
0659     h = y1 < y2 ? y2 : y1; // tubs half height
0660     h += h/20.;            // enlarge a bit - for subtraction solid
0661     if( atMinusZ )    {
0662       displacement = -halfZ - delta; 
0663       startPhi     =  270.0 - halfOpeningAngle;
0664     }
0665     else    {
0666       displacement =  halfZ + delta;
0667       startPhi     =  90.0  - halfOpeningAngle;
0668     }
0669   }
0670   else if( r > 0 && std::abs(r) >= x )  {
0671     if( atMinusZ )    {
0672       displacement = -halfZ + delta;
0673       startPhi     =  90.0  - halfOpeningAngle;
0674       h = y1;
0675     }
0676     else
0677     {
0678       displacement =  halfZ - delta; 
0679       startPhi     =  270.0 - halfOpeningAngle;
0680       h = y2;
0681     }    
0682   }
0683   else  {
0684     except(PSEUDOTRAP_TAG,"Check parameters of the PseudoTrap!");   
0685   }
0686 #endif
0687 
0688   // Implementation from :
0689   // https://cmssdt.cern.ch/lxr/source/Fireworks/Geometry/src/TGeoMgrFromDdd.cc#0538
0690   if( r < 0 && std::abs(r) >= x )  {
0691     intersec = true;       // intersection solid
0692     h = y1 < y2 ? y2 : y1; // tubs half height
0693     h += h/20.;            // enlarge a bit - for subtraction solid
0694     if( atMinusZ )    {
0695       displacement = - halfZ - delta; 
0696       startPhi     =  90.0 - halfOpeningAngle;
0697     }
0698     else    {
0699       displacement =   halfZ + delta;
0700       startPhi     = -90.0 - halfOpeningAngle;
0701     }
0702   }
0703   else if( r > 0 && std::abs(r) >= x )  {
0704     if( atMinusZ )    {
0705       displacement = - halfZ + delta;
0706       startPhi     = 270.0 - halfOpeningAngle;
0707       h = y1;
0708     }
0709     else
0710     {
0711       displacement =   halfZ - delta; 
0712       startPhi     =  90.0 - halfOpeningAngle;
0713       h = y2;
0714     }    
0715   }
0716   else  {
0717     except(PSEUDOTRAP_TAG,"Check parameters of the PseudoTrap!");   
0718   }
0719   printout(DEBUG,"PseudoTrap","++ Trd2(%s): x1=%.3g x2=%.3g y1=%.3g y2=%.3g halfZ=%.3g",
0720        (nam+"Trd2").c_str(), x1, x2, y1, y2, halfZ);
0721   printout(DEBUG,"PseudoTrap","++ Tubs(%s): r=%.3g h=%.3g startPhi=%.3g endPhi=%.3g",
0722        (nam+"Tubs").c_str(), std::abs(r),h,startPhi,startPhi + halfOpeningAngle*2.);
0723 
0724   Solid trap(new TGeoTrd2((nam+"Trd2").c_str(), x1, x2, y1, y2, halfZ));
0725   Solid tubs(new TGeoTubeSeg((nam+"Tubs").c_str(), 0.,std::abs(r),h,startPhi,startPhi + halfOpeningAngle*2.));
0726   std::stringstream params;
0727   params << x1 << " " << x2 << " " << y1 << " " << y2 << " " << z << " "
0728          << r << " " << char(atMinusZ ? '1' : '0') << " ";
0729   TGeoCompositeShape* solid = 0;
0730   if( intersec )  {
0731     printout(DEBUG,"PseudoTrap","++ Intersection displacement=%.3g", displacement);
0732     solid = SubtractionSolid(nam, trap, tubs, Transform3D(RotationX(M_PI/2.), Position(0.,0.,displacement))).ptr();
0733   }
0734   else  {
0735     printout(DEBUG,"PseudoTrap","++ Union displacement=%.3g sqrt(r*r-x*x)=%.3g", displacement, std::sqrt(r*r-x*x));
0736     SubtractionSolid sub((nam+"Subs").c_str(), tubs, Box(1.1*x, 1.1*h, std::sqrt(r*r-x*x)), Transform3D(RotationX(M_PI/2.)));
0737     solid = UnionSolid(nam, trap, sub, Transform3D(RotationX(M_PI/2.), Position(0,0,displacement))).ptr();
0738   }
0739   solid->GetBoolNode()->GetRightMatrix()->SetTitle(params.str().c_str());
0740   _assign(solid,"",PSEUDOTRAP_TAG, true);
0741 }
0742 
0743 /// Helper function to create poly hedron
0744 void PolyhedraRegular::make(const std::string& nam, int nsides, double rmin, double rmax,
0745                             double zpos, double zneg, double start, double delta) {
0746   if (rmin < 0e0 || rmin > rmax)
0747     throw std::runtime_error("dd4hep: PolyhedraRegular: Illegal argument rmin:<" + _toString(rmin) + "> is invalid!");
0748   else if (rmax < 0e0)
0749     throw std::runtime_error("dd4hep: PolyhedraRegular: Illegal argument rmax:<" + _toString(rmax) + "> is invalid!");
0750   double params[] = { start/units::deg, delta/units::deg, double(nsides), 2e0, zpos, rmin, rmax, zneg, rmin, rmax };
0751   _assign(new TGeoPgon(params), nam, POLYHEDRA_TAG, false);
0752   //_setDimensions(&params[0]);
0753 }
0754 
0755 /// Helper function to create poly hedron
0756 void Polyhedra::make(const std::string& nam, int nsides, double start, double delta,
0757                      const std::vector<double>& z, const std::vector<double>& rmin, const std::vector<double>& rmax)  {
0758   std::vector<double> temp;
0759   if ( rmin.size() != z.size() || rmax.size() != z.size() )  {
0760     except("Polyhedra",
0761            "Number of values to define zplanes are incorrect: z:%ld rmin:%ld rmax:%ld",
0762            z.size(), rmin.size(), rmax.size());
0763   }
0764   // No need to transform coordinates to cm. We are in the dd4hep world: all is already in cm.
0765   temp.reserve(4+z.size()*2);
0766   temp.emplace_back(start/units::deg);
0767   temp.emplace_back(delta/units::deg);
0768   temp.emplace_back(double(nsides));
0769   temp.emplace_back(double(z.size()));
0770   for(std::size_t i=0; i<z.size(); ++i)   {
0771     temp.emplace_back(z[i]);
0772     temp.emplace_back(rmin[i]);
0773     temp.emplace_back(rmax[i]);
0774   }
0775   _assign(new TGeoPgon(&temp[0]), nam, POLYHEDRA_TAG, false);
0776 }
0777 
0778 /// Helper function to create the polyhedron
0779 void ExtrudedPolygon::make(const std::string&         nam,
0780                            const std::vector<double>& pt_x,
0781                            const std::vector<double>& pt_y,
0782                            const std::vector<double>& sec_z,
0783                            const std::vector<double>& sec_x,
0784                            const std::vector<double>& sec_y,
0785                            const std::vector<double>& sec_scale)
0786 {
0787   TGeoXtru* solid = new TGeoXtru(sec_z.size());
0788   _assign(solid, nam, EXTRUDEDPOLYGON_TAG, false);
0789   // No need to transform coordinates to cm. We are in the dd4hep world: all is already in cm.
0790   solid->DefinePolygon(pt_x.size(), &(*pt_x.begin()), &(*pt_y.begin()));
0791   for( std::size_t i = 0; i < sec_z.size(); ++i )
0792     solid->DefineSection(i, sec_z[i], sec_x[i], sec_y[i], sec_scale[i]);
0793 }
0794 
0795 /// Creator method for arbitrary eight point solids
0796 void EightPointSolid::make(const std::string& nam, double dz, const double* vtx)   {
0797   _assign(new TGeoArb8(nam.c_str(), dz, (double*)vtx), "", EIGHTPOINTSOLID_TAG, true);
0798 }
0799 
0800 /// Internal helper method to support object construction
0801 void TessellatedSolid::make(const std::string& nam, int num_facets)   {
0802   _assign(new TGeoTessellated(nam.c_str(), num_facets), nam, TESSELLATEDSOLID_TAG, false);
0803 }
0804 
0805 /// Internal helper method to support object construction
0806 void TessellatedSolid::make(const std::string& nam, const std::vector<Vertex>& vertices)   {
0807   _assign(new TGeoTessellated(nam.c_str(), vertices), nam, TESSELLATEDSOLID_TAG, false);
0808 }
0809 
0810 /// Add new facet to the shape
0811 bool TessellatedSolid::addFacet(const Vertex& pt0, const Vertex& pt1, const Vertex& pt2)  const {
0812   return access()->AddFacet(pt0, pt1, pt2);
0813 }
0814 
0815 /// Add new facet to the shape
0816 bool TessellatedSolid::addFacet(const Vertex& pt0, const Vertex& pt1, const Vertex& pt2, const Vertex& pt3)  const {
0817   return access()->AddFacet(pt0, pt1, pt2, pt3);
0818 }
0819 
0820 /// Add new facet to the shape. Call only if the tessellated shape was constructed with vertices
0821 bool TessellatedSolid::addFacet(const int pt0, const int pt1, const int pt2)  const    {
0822   return access()->AddFacet(pt0, pt1, pt2);
0823 }
0824 
0825 /// Add new facet to the shape. Call only if the tessellated shape was constructed with vertices
0826 bool TessellatedSolid::addFacet(const int pt0, const int pt1, const int pt2, const int pt3)  const   {
0827   return access()->AddFacet(pt0, pt1, pt2, pt3);
0828 }
0829 
0830 /// Access the number of facets in the shape
0831 int TessellatedSolid::num_facet()   const   {
0832   return access()->GetNvertices();
0833 }
0834 
0835 /// Access a facet from the built shape
0836 const TessellatedSolid::Facet& TessellatedSolid::facet(int index)    const   {
0837   return ptr()->GetFacet(index);
0838 }
0839 
0840 /// Access the number of vertices in the shape
0841 int TessellatedSolid::num_vertex()   const   {
0842   return access()->GetNvertices();
0843 }
0844 
0845 /// Access a single vertex from the shape
0846 const TessellatedSolid::Vertex& TessellatedSolid::vertex(int index)    const    {
0847   return ptr()->GetVertex(index);
0848 }
0849 
0850 /// Access right solid of the boolean
0851 Solid BooleanSolid::rightShape()  const    {
0852   return access()->GetBoolNode()->GetRightShape();
0853 }
0854 
0855 /// Access left solid of the boolean
0856 Solid BooleanSolid::leftShape()  const   {
0857   return access()->GetBoolNode()->GetLeftShape();
0858 }
0859 
0860 /// Access right positioning matrix of the boolean
0861 const TGeoMatrix* BooleanSolid::rightMatrix()  const   {
0862   return access()->GetBoolNode()->GetRightMatrix();
0863 }
0864 
0865 /// Access left positioning matrix of the boolean
0866 const TGeoMatrix* BooleanSolid::leftMatrix()  const   {
0867   return access()->GetBoolNode()->GetLeftMatrix();
0868 }
0869 
0870 /// Constructor to be used when creating a new object. Position is identity, Rotation is the identity rotation
0871 SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2) {
0872   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity());
0873   _assign(new TGeoCompositeShape("", sub), "", SUBTRACTION_TAG, true);
0874 }
0875 
0876 /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother
0877 SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans) {
0878   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans));
0879   _assign(new TGeoCompositeShape("", sub), "", SUBTRACTION_TAG, true);
0880 }
0881 
0882 /// Constructor to be used when creating a new object. Rotation is the identity rotation
0883 SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) {
0884   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos));
0885   _assign(new TGeoCompositeShape("", sub), "", SUBTRACTION_TAG, true);
0886 }
0887 
0888 /// Constructor to be used when creating a new object
0889 SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const RotationZYX& rot) {
0890   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot));
0891   _assign(new TGeoCompositeShape("", sub), "", SUBTRACTION_TAG, true);
0892 }
0893 
0894 /// Constructor to be used when creating a new object
0895 SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Rotation3D& rot) {
0896   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot));
0897   _assign(new TGeoCompositeShape("", sub), "", SUBTRACTION_TAG, true);
0898 }
0899 
0900 /// Constructor to be used when creating a new object. Position is identity, Rotation is the identity rotation
0901 SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2) {
0902   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity());
0903   _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true);
0904 }
0905 
0906 /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother
0907 SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) {
0908   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans));
0909   _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true);
0910 }
0911 
0912 /// Constructor to be used when creating a new object. Rotation is the identity rotation
0913 SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) {
0914   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos));
0915   _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true);
0916 }
0917 
0918 /// Constructor to be used when creating a new object
0919 SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) {
0920   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot));
0921   _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true);
0922 }
0923 
0924 /// Constructor to be used when creating a new object
0925 SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) {
0926   TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot));
0927   _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true);
0928 }
0929 
0930 /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation
0931 UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2) {
0932   TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity());
0933   _assign(new TGeoCompositeShape("", uni), "", UNION_TAG, true);
0934 }
0935 
0936 /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother
0937 UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans) {
0938   TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans));
0939   _assign(new TGeoCompositeShape("", uni), "", UNION_TAG, true);
0940 }
0941 
0942 /// Constructor to be used when creating a new object. Rotation is identity rotation
0943 UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) {
0944   TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos));
0945   _assign(new TGeoCompositeShape("", uni), "", UNION_TAG, true);
0946 }
0947 
0948 /// Constructor to be used when creating a new object
0949 UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const RotationZYX& rot) {
0950   TGeoUnion *uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot));
0951   _assign(new TGeoCompositeShape("", uni), "", UNION_TAG, true);
0952 }
0953 
0954 /// Constructor to be used when creating a new object
0955 UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Rotation3D& rot) {
0956   TGeoUnion *uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot));
0957   _assign(new TGeoCompositeShape("", uni), "", UNION_TAG, true);
0958 }
0959 
0960 /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation
0961 UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2) {
0962   TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity());
0963   _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true);
0964 }
0965 
0966 /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother
0967 UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) {
0968   TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans));
0969   _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true);
0970 }
0971 
0972 /// Constructor to be used when creating a new object. Rotation is identity rotation
0973 UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) {
0974   TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos));
0975   _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true);
0976 }
0977 
0978 /// Constructor to be used when creating a new object
0979 UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) {
0980   TGeoUnion *uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot));
0981   _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true);
0982 }
0983 
0984 /// Constructor to be used when creating a new object
0985 UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) {
0986   TGeoUnion *uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot));
0987   _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true);
0988 }
0989 
0990 /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation
0991 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2) {
0992   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity());
0993   _assign(new TGeoCompositeShape("", inter), "", INTERSECTION_TAG, true);
0994 }
0995 
0996 /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother
0997 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans) {
0998   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans));
0999   _assign(new TGeoCompositeShape("", inter), "", INTERSECTION_TAG, true);
1000 }
1001 
1002 /// Constructor to be used when creating a new object. Position is identity.
1003 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) {
1004   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos));
1005   _assign(new TGeoCompositeShape("", inter), "", INTERSECTION_TAG, true);
1006 }
1007 
1008 /// Constructor to be used when creating a new object
1009 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const RotationZYX& rot) {
1010   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot));
1011   _assign(new TGeoCompositeShape("", inter), "", INTERSECTION_TAG, true);
1012 }
1013 
1014 /// Constructor to be used when creating a new object
1015 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Rotation3D& rot) {
1016   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot));
1017   _assign(new TGeoCompositeShape("", inter), "", INTERSECTION_TAG, true);
1018 }
1019 
1020 /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation
1021 IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2) {
1022   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity());
1023   _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true);
1024 }
1025 
1026 /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother
1027 IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) {
1028   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans));
1029   _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true);
1030 }
1031 
1032 /// Constructor to be used when creating a new object. Position is identity.
1033 IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) {
1034   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos));
1035   _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true);
1036 }
1037 
1038 /// Constructor to be used when creating a new object
1039 IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) {
1040   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot));
1041   _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true);
1042 }
1043 
1044 /// Constructor to be used when creating a new object
1045 IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) {
1046   TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot));
1047   _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true);
1048 }
1049 
1050 
1051 #define INSTANTIATE(X) template class dd4hep::Solid_type<X>
1052 
1053 INSTANTIATE(TGeoShape);
1054 INSTANTIATE(TGeoBBox);
1055 INSTANTIATE(TGeoHalfSpace);
1056 INSTANTIATE(TGeoCone);
1057 INSTANTIATE(TGeoConeSeg);
1058 INSTANTIATE(TGeoParaboloid);
1059 INSTANTIATE(TGeoPcon);
1060 INSTANTIATE(TGeoPgon);
1061 INSTANTIATE(TGeoSphere);
1062 INSTANTIATE(TGeoTorus);
1063 INSTANTIATE(TGeoTube);
1064 INSTANTIATE(TGeoTubeSeg);
1065 INSTANTIATE(TGeoEltu);
1066 INSTANTIATE(TGeoXtru);
1067 INSTANTIATE(TGeoGtra);
1068 INSTANTIATE(TGeoHype);
1069 INSTANTIATE(TGeoTrap);
1070 INSTANTIATE(TGeoTrd1);
1071 INSTANTIATE(TGeoTrd2);
1072 INSTANTIATE(TGeoCtub);
1073 INSTANTIATE(TGeoScaledShape);
1074 INSTANTIATE(TGeoCompositeShape);
1075 INSTANTIATE(TGeoTessellated);