Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:14:35

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 #include <DD4hep/Factories.h>
0014 #include <DD4hep/Shapes.h>
0015 #include <DD4hep/Volumes.h>
0016 #include <DD4hep/Detector.h>
0017 #include <DD4hep/MatrixHelpers.h>
0018 #include <DD4hep/DD4hepUnits.h>
0019 #include <DD4hep/Printout.h>
0020 #include <DD4hep/Path.h>
0021 
0022 // C/C++ include files
0023 #include <iostream>
0024 #include <fstream>
0025 
0026 // ROOT includes
0027 #include <TClass.h>
0028 #include <TGeoMatrix.h>
0029 #include <TGeoBoolNode.h>
0030 #include <TGeoCompositeShape.h>
0031 
0032 using namespace dd4hep;
0033 
0034 namespace {
0035   std::string prefix = "\t";
0036 
0037   /// Debug utility to generate pure TGeo code from DD4hep detector setups.
0038   /** 
0039    *  This utility can be used to reproduce problems with TGeo ONLY.
0040    * 
0041    *  \author  M.Frank
0042    *  \version 1.0
0043    */
0044   struct Actor   {
0045     std::set<const TGeoNode*>     nodes;
0046     std::set<const TGeoVolume*>   volumes;
0047     std::set<const TGeoShape*>    solids;
0048     std::set<const TGeoMatrix*>   matrices;
0049     std::set<const TGeoMedium*>   materials;
0050     std::set<const TGeoElement*>  elements;
0051     std::string function {"run_geometry"};
0052     bool dump_vis = false;
0053     bool dump_mat = false;
0054 
0055     Actor() = default;
0056     ~Actor() = default;
0057     std::ostream& handleHeader   (std::ostream& log);
0058     std::ostream& handleTrailer  (std::ostream& log);
0059     std::ostream& handleSolid    (std::ostream& log, const TGeoShape*  sh);
0060     std::ostream& handleMatrix   (std::ostream& log, TGeoMatrix* mat);
0061     std::ostream& handleElement  (std::ostream& log, TGeoElement* elt);
0062     std::ostream& handleMaterial (std::ostream& log, TGeoMedium* mat);
0063     std::ostream& handlePlacement(std::ostream& log, TGeoNode*   parent, TGeoNode* node);
0064   };
0065   typedef void* pvoid_t;
0066 
0067   std::ostream& newline(std::ostream& log)    {
0068     return log << std::endl << prefix;
0069   }
0070 
0071   std::ostream& Actor::handleHeader   (std::ostream& log)    {
0072     log << "#include \"TClass.h\"" << std::endl
0073         << "#include \"TGeoNode.h\"" << std::endl
0074         << "#include \"TGeoExtension.h\"" << std::endl
0075         << "#include \"TGeoShapeAssembly.h\"" << std::endl
0076         << "#include \"TGeoMedium.h\"" << std::endl
0077         << "#include \"TGeoVolume.h\"" << std::endl
0078         << "#include \"TGeoShape.h\"" << std::endl
0079         << "#include \"TGeoPhysicalNode.h\"" << std::endl
0080         << "#include \"TGeoCone.h\"" << std::endl
0081         << "#include \"TGeoParaboloid.h\"" << std::endl
0082         << "#include \"TGeoPgon.h\"" << std::endl
0083         << "#include \"TGeoPcon.h\"" << std::endl
0084         << "#include \"TGeoSphere.h\"" << std::endl
0085         << "#include \"TGeoArb8.h\"" << std::endl
0086         << "#include \"TGeoTrd1.h\"" << std::endl
0087         << "#include \"TGeoTrd2.h\"" << std::endl
0088         << "#include \"TGeoTube.h\"" << std::endl
0089         << "#include \"TGeoEltu.h\"" << std::endl
0090         << "#include \"TGeoXtru.h\"" << std::endl
0091         << "#include \"TGeoHype.h\"" << std::endl
0092         << "#include \"TGeoTorus.h\"" << std::endl
0093         << "#include \"TGeoHalfSpace.h\"" << std::endl
0094         << "#include \"TGeoCompositeShape.h\"" << std::endl
0095         << "#include \"TGeoShapeAssembly.h\"" << std::endl
0096         << "#include \"TGeoMatrix.h\"" << std::endl
0097         << "#include \"TGeoBoolNode.h\"" << std::endl
0098         << "#include \"TGeoCompositeShape.h\"" << std::endl
0099         << "#include \"TGeoManager.h\"" << std::endl
0100         << "#include <vector>" << std::endl
0101         << "#include <map>" << std::endl
0102         << "#include <set>" << std::endl << std::endl << std::endl;
0103     log << "TGeoVolume* generate_geometry()   {" << newline;
0104     return log;
0105   }
0106 
0107   std::ostream& Actor::handleTrailer   (std::ostream& log)    {
0108     log << std::endl << "}" << std::endl << std::endl;
0109     log << "void " << function << "() {" << newline
0110         << "if ( !gGeoManager ) gGeoManager = new TGeoManager();" << newline
0111         << "TGeoVolume* vol_top = generate_geometry();" << newline
0112         << "gGeoManager->SetTopVolume(vol_top);" << newline
0113         << "vol_top->Draw(\"ogl\");" << newline
0114         << std::endl << "}" << std::endl;
0115     return log;
0116   }
0117 
0118   std::ostream& Actor::handlePlacement(std::ostream& log, TGeoNode* parent, TGeoNode* node)  {
0119     if ( node && nodes.find(node) == nodes.end() )  {
0120       TGeoVolume* vol = node->GetVolume();
0121       TGeoMatrix* mat = node->GetMatrix();
0122       nodes.insert(node);
0123       handleMatrix(log, mat);
0124 
0125       if ( vol && volumes.find(vol) == volumes.end() )  {
0126         volumes.insert(vol);
0127         if ( vol->IsA() == TGeoVolumeAssembly::Class() )    {
0128           log << "TGeoVolume* vol_" << pvoid_t(vol)
0129               << " = new TGeoVolumeAssembly(\"" << vol->GetName() << "\");" << newline;          
0130         }
0131         else   {
0132           TGeoMedium* med = vol->GetMedium();
0133           TGeoShape*  sh  = vol->GetShape();
0134           handleSolid(log, sh);
0135           handleMaterial(log, med);
0136           log << "TGeoVolume* vol_" << pvoid_t(vol) << " = new TGeoVolume(\"" << vol->GetName() << "\", "
0137               << "shape_" << pvoid_t(sh) << ", material_" << pvoid_t(med) << ");" << newline;
0138           if ( dump_vis )    {
0139             log << "vol_" << pvoid_t(vol) << "->SetLineColor(Color_t(" << int(vol->GetLineColor()) << "));" << newline;
0140             log << "vol_" << pvoid_t(vol) << "->SetLineStyle(" << vol->GetLineStyle() << ");" << newline;
0141             log << "vol_" << pvoid_t(vol) << "->SetLineWidth(" << vol->GetLineWidth() << ");" << newline;
0142             log << "vol_" << pvoid_t(vol) << "->SetFillColor(Color_t(" << int(vol->GetFillColor()) << "));" << newline;
0143             log << "vol_" << pvoid_t(vol) << "->SetFillStyle(" << vol->GetFillStyle() << ");" << newline;
0144           }
0145         }
0146       }
0147 
0148       for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
0149         TGeoNode* daughter = node->GetDaughter(idau);
0150         handlePlacement(log, node, daughter);
0151       }
0152 
0153       if ( parent )   {
0154         Int_t ndau       = parent->GetNdaughters();
0155         TGeoVolume* pvol = parent->GetVolume();
0156         log << "vol_" << pvoid_t(pvol)
0157             << "->AddNode(vol_" << pvoid_t(vol) << ", " << ndau << ", matrix_" << pvoid_t(mat)
0158             << ");" << newline;
0159         log << "TGeoNode* node_" << pvoid_t(node) << " = vol_" << pvoid_t(pvol)
0160             << "->GetNode(" << ndau << ");" << newline;
0161       }
0162       else   {
0163         log << "return vol_" << pvoid_t(vol) << ";" << std::endl;
0164       }
0165     }
0166     return log;
0167   }
0168 
0169   std::ostream& Actor::handleElement  (std::ostream& log, TGeoElement* elt)   {
0170     if ( elt && elements.find(elt) == elements.end() )  {
0171       elements.insert(elt);
0172       log << "TGeoElement* elt_" << pvoid_t(elt) << " = new TGeoElement(\""
0173           << elt->GetName() << "\", \"" << elt->GetTitle() << "\", ";
0174       if ( elt->GetNisotopes() > 0 )   {
0175         log << elt->GetNisotopes() << ");" << newline;
0176         for(Int_t i=0; i<elt->GetNisotopes(); ++i)   {
0177           TGeoIsotope* iso = elt->GetIsotope(i);
0178           log << "elt_" << pvoid_t(elt) << "->AddIsotope("
0179               << "new TGeoIsotope(\"" << elt->GetName() << "_" << iso->GetN()
0180               << "\", " << iso->GetZ() << ", " << iso->GetN() << ", " << iso->GetA() << "));"
0181               << newline;
0182         }
0183       }
0184       else   {
0185         log << elt->Z() << ", " << elt->N() << ", " << elt->A() << ");" << newline;
0186       }
0187     }
0188     return log;
0189   }
0190 
0191   std::ostream& Actor::handleMaterial(std::ostream& log, TGeoMedium* medium)   {
0192     if ( medium && materials.find(medium) == materials.end() )  {
0193       materials.insert(medium);
0194       if ( !dump_mat )    {
0195         log << "TGeoMedium* material_" << pvoid_t(medium) << " = gGeoManager->GetMedium(\"IRON\");"
0196             << newline;
0197         return log;
0198       }
0199       TGeoMaterial* mat = medium->GetMaterial();
0200       if ( mat->IsMixture() )  {
0201         TGeoMixture* mix = (TGeoMixture*) mat;
0202         int nElements = mix->GetNelements();
0203         double W_total = 0.0;
0204         for (int i = 0; i < nElements; ++i)   {
0205           handleElement(log, mix->GetElement(i));
0206           W_total += (mix->GetWmixt())[i];
0207         }
0208         log << "TGeoMixture* mat_" << pvoid_t(mat) << " = new TGeoMixture(\""
0209             << mix->GetName() << "\", " << nElements << ", " << mix->GetDensity() << ");"
0210             << newline;
0211         for (int i = 0; i < nElements; ++i)   {
0212           TGeoElement* e = mix->GetElement(i);
0213           log << "mat_" << pvoid_t(mat) << "->AddElement(elt_" << pvoid_t(e)
0214               << ", " << ((mix->GetWmixt())[i]/W_total) << ");"
0215               << newline;
0216         }
0217         mix->SetRadLen(0e0);
0218         mix->ComputeDerivedQuantities();
0219       }
0220       else {
0221         double z = mat->GetZ(), a = mat->GetA();
0222         if ( z < 1.0000001 ) z = 1.0;
0223         if ( a < 0.5000001 ) a = 1.0;
0224         log << "TGeoMaterial* mat_" << pvoid_t(mat) << " = new TGeoMaterial(\""
0225             << mat->GetName() << "\", " << a << ", " << z
0226             << ", " << mat->GetDensity()
0227             << ", " << mat->GetRadLen()
0228             << ", " << mat->GetIntLen() << ");"
0229             << newline;
0230       }
0231       log << "mat_" << pvoid_t(mat) << "->SetState(TGeoMaterial::EGeoMaterialState("
0232           << mat->GetState() << "));" << newline
0233           << "mat_" << pvoid_t(mat) << "->SetPressure(" << mat->GetPressure() << ");" << newline
0234           << "mat_" << pvoid_t(mat) << "->SetTemperature(" << mat->GetTemperature() << ");" << newline
0235           << "mat_" << pvoid_t(mat) << "->SetTransparency(" << int(mat->GetTransparency()) << ");" << newline;
0236       log << "TGeoMedium* material_" << pvoid_t(medium) << " = new TGeoMedium(\""
0237           << medium->GetName() << "\", " << medium->GetId()
0238           << ", mat_" << pvoid_t(mat) << ");" << newline;
0239     }
0240     return log;
0241   }
0242   
0243   std::ostream& Actor::handleMatrix(std::ostream& log, TGeoMatrix* mat)   {
0244     if ( mat && matrices.find(mat) == matrices.end() )  {
0245       const Double_t*   rot = mat->GetRotationMatrix();
0246       const Double_t*   tra = mat->GetTranslation();
0247       const Double_t*   sca = mat->GetScale();
0248       log << "TGeoHMatrix* matrix_" << pvoid_t(mat) << " = new TGeoHMatrix(\"" << mat->GetName() << "\");"
0249           << newline << "{" << newline;
0250       if ( mat->IsTranslation() )   {
0251         log << "\t Double_t trans[] = {";
0252         for(size_t i=0; tra && i<3; ++i)  {
0253           log << tra[i];
0254           log << ((i<2) ? ", " : "};");
0255         }
0256         log << newline << "\t matrix_" << pvoid_t(mat) << "->SetTranslation(trans);" << newline;
0257       }
0258       if ( mat->IsRotation() )   {
0259         log << "\t Double_t rot[] = {";
0260         for(size_t i=0; rot && i<9; ++i)  {
0261           log << rot[i];
0262           log << ((i<8) ? ", " : "};");
0263         }
0264         log << newline << "\t matrix_" << pvoid_t(mat) << "->SetRotation(rot);" << newline;
0265       }
0266       if ( mat->IsScale() )   {
0267         log << "\t Double_t scale[] = {";
0268         for(size_t i=0; sca && i<3; ++i)  {
0269           log << sca[i];
0270           log << ((i<2) ? ", " : "};");
0271         }
0272         log << newline << "\t matrix_" << pvoid_t(mat) << "->SetScale(scale);" << newline;
0273       }
0274       log << "}" << newline;
0275     }
0276     return log;
0277   }
0278   
0279   /// Pretty print of solid attributes
0280   std::ostream& Actor::handleSolid(std::ostream& log,  const TGeoShape* shape)    {
0281     if ( !shape || solids.find(shape) != solids.end() )  {
0282       return log;
0283     }
0284     solids.insert(shape);
0285     
0286     TClass* cl = shape->IsA();
0287     void* pvoid = (void*)shape;
0288     if ( cl == TGeoBBox::Class() )   {
0289       TGeoBBox* sh = (TGeoBBox*) shape;
0290       log << cl->GetName() << "* shape_" << pvoid << " = "
0291           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0292           << ", " << sh->GetDX()
0293           << ", " << sh->GetDY()
0294           << ", " << sh->GetDZ() << ");" << newline;
0295     }
0296     else if (cl == TGeoHalfSpace::Class()) {
0297       TGeoHalfSpace* sh = (TGeoHalfSpace*)(const_cast<TGeoShape*>(shape));
0298       log << cl->GetName() << "* shape_" << (void*)shape << " = 0;" << newline
0299           << "{" << newline
0300           << "\t Double_t* point_ << " << pvoid << " = {"
0301           << sh->GetPoint()[0] << ", " << sh->GetPoint()[1] << ", " << sh->GetPoint()[2] << "}; " << newline
0302           << "\t Double_t* norm_ << " << pvoid << " = {"
0303           << sh->GetNorm()[0] << ", " << sh->GetNorm()[1] << ", " << sh->GetNorm()[2] << "}; " << newline
0304           << "shape_" << pvoid << " = "
0305           << "new " << cl->GetName() << "(\"" << sh->GetName() << "\" "
0306           << ", point_" << pvoid << ", norm_" << pvoid << ");" << newline
0307           << "}" << newline;
0308     }
0309     else if (cl == TGeoTube::Class()) {
0310       const TGeoTube* sh = (const TGeoTube*) shape;
0311       log << cl->GetName() << "* shape_" << pvoid << " = "
0312           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0313           << ", " << sh->GetRmin()
0314           << ", " << sh->GetRmax()
0315           << ", " << sh->GetDz()
0316           << ");" << newline;
0317     }
0318     else if (cl == TGeoTubeSeg::Class()) {
0319       const TGeoTubeSeg* sh = (const TGeoTubeSeg*) shape;
0320       log << cl->GetName() << "* shape_" << pvoid << " = "
0321           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0322           << ", " << sh->GetRmin()
0323           << ", " << sh->GetRmax()
0324           << ", " << sh->GetDz()
0325           << ", " << sh->GetPhi1()
0326           << ", " << sh->GetPhi2()
0327           << ");" << newline;
0328     }
0329     else if (cl == TGeoCtub::Class()) {
0330       const TGeoCtub* sh = (const TGeoCtub*) shape;
0331       const Double_t*   hi = sh->GetNhigh();
0332       const Double_t*   lo = sh->GetNlow();
0333       log << cl->GetName() << "* shape_" << pvoid << " = "
0334           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0335           << ", " << sh->GetRmin()
0336           << ", " << sh->GetRmax()
0337           << ", " << sh->GetDz()
0338           << ", " << sh->GetPhi1()
0339           << ", " << sh->GetPhi2()
0340           << ", " << lo[0]
0341           << ", " << lo[1]
0342           << ", " << lo[2]
0343           << ", " << hi[0]
0344           << ", " << hi[1]
0345           << ", " << hi[2]
0346           << ");" << newline;
0347     }
0348     else if (cl == TGeoEltu::Class()) {
0349       const TGeoEltu* sh = (const TGeoEltu*) shape;
0350       log << cl->GetName() << "* shape_" << pvoid << " = "
0351           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0352           << ", "   << sh->GetA()
0353           << ", "   << sh->GetB()
0354           << ", "   << sh->GetDz()
0355           << ");"   << newline;
0356     }
0357     else if (cl == TGeoTrd1::Class()) {
0358       const TGeoTrd1* sh = (const TGeoTrd1*) shape;
0359       log << cl->GetName() << "* shape_" << pvoid << " = "
0360           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0361           << ", "   << sh->GetDx1()
0362           << ", "   << sh->GetDx2()
0363           << ", "   << sh->GetDy()
0364           << ", "   << sh->GetDz()
0365           << ");"   << newline;
0366     }
0367     else if (cl == TGeoTrd2::Class()) {
0368       const TGeoTrd2* sh = (const TGeoTrd2*) shape;
0369       log << cl->GetName() << "* shape_" << pvoid << " = "
0370           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0371           << ", "   << sh->GetDx1()
0372           << ", "   << sh->GetDx2()
0373           << ", "   << sh->GetDy1()
0374           << ", "   << sh->GetDy2()
0375           << ", "   << sh->GetDz()
0376           << ");"   << newline;
0377     }
0378     else if (cl == TGeoTrap::Class()) {
0379       const TGeoTrap* sh = (const TGeoTrap*) shape;
0380       log << cl->GetName() << "* shape_" << pvoid << " = "
0381           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0382           << ", "   << sh->GetDz() << ", " << sh->GetTheta() << ", " << sh->GetPhi()
0383           << ", "   << sh->GetH1() << ", " << sh->GetBl1()   << ", " << sh->GetTl1() << ", " << sh->GetAlpha1()
0384           << ", "   << sh->GetH2() << ", " << sh->GetBl2()   << ", " << sh->GetTl2() << ", " << sh->GetAlpha2()
0385           << ");"   << newline;
0386     }
0387     else if (cl == TGeoHype::Class()) {
0388       const TGeoHype* sh = (const TGeoHype*) shape;
0389       log << cl->GetName() << "* shape_" << pvoid << " = "
0390           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0391           << ", "   << sh->GetRmin() << ", "  << sh->GetRmax() << ", " << sh->GetDz()
0392           << ", "   << sh->GetStIn() << ", " << sh->GetStOut()
0393           << ");"   << newline;
0394     }
0395     else if (cl == TGeoPgon::Class()) {
0396       const TGeoPgon* sh = (const TGeoPgon*) shape;
0397       std::vector<double> params;
0398       params.emplace_back(sh->GetPhi1());
0399       params.emplace_back(sh->GetDphi());
0400       params.emplace_back(double(sh->GetNedges()));
0401       params.emplace_back(double(sh->GetNz()));
0402       for(int i=0, n=sh->GetNz(); i<n; ++i)  {
0403         params.emplace_back(sh->GetZ(i));
0404         params.emplace_back(sh->GetRmin(i));
0405         params.emplace_back(sh->GetRmax(i));
0406       }
0407       log << cl->GetName() << "* shape_" << pvoid << " = "
0408           << "new " << cl->GetName() << "(" << &params[0] << ");" << newline;
0409       log << "shape_" << pvoid << "->SetName(\"" << sh->GetName() << "\");" << newline;
0410     }
0411     else if (cl == TGeoPcon::Class()) {
0412       const TGeoPcon* sh = (const TGeoPcon*) shape;
0413       std::vector<double> params;
0414       params.emplace_back(sh->GetPhi1());
0415       params.emplace_back(sh->GetDphi());
0416       params.emplace_back(double(sh->GetNz()));
0417       for(int i=0, n=sh->GetNz(); i<n; ++i)  {
0418         params.emplace_back(sh->GetZ(i));
0419         params.emplace_back(sh->GetRmin(i));
0420         params.emplace_back(sh->GetRmax(i));
0421       }
0422       log << cl->GetName() << "* shape_" << pvoid << " = "
0423           << "new " << cl->GetName() << "(" << &params[0] << ");" << newline;
0424       log << "shape_" << pvoid << "->SetName(\"" << sh->GetName() << "\");" << newline;
0425     }
0426     else if (cl == TGeoCone::Class()) {
0427       const TGeoCone* sh = (const TGeoCone*) shape;
0428       log << cl->GetName() << "* shape_" << pvoid << " = "
0429           << "new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0430           << ", "   << sh->GetRmin1() << ", " << sh->GetRmin2() << ", "
0431           << ", "   << sh->GetRmax1() << ", " << sh->GetRmax2()
0432           << ", " << sh->GetDz()
0433           << ");"   << newline;
0434     }
0435     else if (cl == TGeoConeSeg::Class()) {
0436       const TGeoConeSeg* sh = (const TGeoConeSeg*) shape;
0437       log << cl->GetName() << "* shape_" << pvoid << " = "
0438           << "new " << cl->GetName()  << "(\"" << sh->GetName() << '"'
0439           << ", "   << sh->GetRmin1() << ", " << sh->GetRmin2() << ", "
0440           << ", "   << sh->GetRmax1() << ", " << sh->GetRmax2()
0441           << ", "   << sh->GetDz()
0442           << ", "   << sh->GetPhi1()  << ", " << sh->GetPhi2()
0443           << ");"   << newline;
0444     }
0445     else if (cl == TGeoParaboloid::Class()) {
0446       const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
0447       log << cl->GetName() << "* shape_" << pvoid << " = "
0448           << "new " << cl->GetName()  << "(\"" << sh->GetName() << '"'
0449           << ", "   << sh->GetRlo() << ", " << sh->GetRhi() << ", " << sh->GetDz() << ");" << newline;
0450     }
0451     else if (cl == TGeoSphere::Class()) {
0452       const TGeoSphere* sh = (const TGeoSphere*) shape;
0453       log << cl->GetName() << "* shape_" << pvoid << " = "
0454           << "new " << cl->GetName()  << "(\"" << sh->GetName() << '"'
0455           << ", "   << sh->GetRmin() << ", " << sh->GetRmax()
0456           << ", "   << sh->GetPhi1()  << ", " << sh->GetPhi2()
0457           << ", "   << sh->GetTheta1()  << ", " << sh->GetTheta2()
0458           << ");" << newline;
0459     }
0460     else if (cl == TGeoTorus::Class()) {
0461       const TGeoTorus* sh = (const TGeoTorus*) shape;
0462       log << cl->GetName() << "* shape_" << pvoid << " = "
0463           << "new " << cl->GetName()  << "(\"" << sh->GetName() << '"'
0464           << ", "   << sh->GetRmin()  << ", " << sh->GetRmax() << ", " << sh->GetR()
0465           << ", "   << sh->GetPhi1()  << ", " << sh->GetDphi()
0466           << ");" << newline;
0467     }
0468     else if (cl == TGeoArb8::Class()) {
0469       TGeoArb8* sh = (TGeoArb8*) shape;
0470       const Double_t* v = sh->GetVertices();
0471       log << cl->GetName() << "* shape_" << pvoid << " = 0;" << newline
0472           << "{" << newline
0473           << "\tstd::vector<double> vertices_" << pvoid << ";" << newline;
0474       for(int i=0; i<8; ++i) {
0475         log << "\tvertices_" << pvoid << ".emplace_back(" << *v << ");" << newline; ++v;
0476         log << "\tvertices_" << pvoid << ".emplace_back(" << *v << ");" << newline; ++v;
0477       }
0478       log << "\tshape_" << pvoid << " = new " << cl->GetName()
0479           << "(\"" << sh->GetName() << '"'
0480           << ", "  << sh->GetDz()  << ", &vertices_" << pvoid << "[0]);" << newline
0481           << "}" << newline;
0482     }
0483     else if (cl == TGeoXtru::Class()) {
0484       Solid sol(shape);
0485       const TGeoXtru* sh = (const TGeoXtru*) shape;
0486       std::vector<double> pars = sol.dimensions();
0487       log << cl->GetName() << "* shape_" << pvoid << " = 0;" << newline
0488           << "{" << newline
0489           << "\tstd::vector<double> param_" << pvoid << ";" << newline;
0490       for( auto p : pars)
0491         log << "\tparam_" << pvoid << ".emplace_back(" << p << ");" << newline;
0492       log << "\tshape_" << pvoid << " = new " << cl->GetName()
0493           << "( &param_" << pvoid << "[0]);" << newline;
0494       log << "shape_" << pvoid << "->SetName(\"" << sh->GetName() << "\");" << newline;
0495     }
0496     else if (shape->IsA() == TGeoCompositeShape::Class()) {
0497       const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape;
0498       const TGeoBoolNode* boolean = sh->GetBoolNode();
0499       const TGeoShape* left  = boolean->GetLeftShape();
0500       const TGeoShape* right = boolean->GetRightShape();
0501       TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
0502       handleSolid(log, left);
0503       handleSolid(log, right);
0504       handleMatrix(log, boolean->GetRightMatrix());
0505       log << "TGeoCompositeShape* shape_" << pvoid_t(sh) << " = 0;" << newline;
0506       log << "{" << newline;
0507       if (oper == TGeoBoolNode::kGeoSubtraction)
0508         log << "\t TGeoSubtraction* boolean = new TGeoSubtraction";
0509       else if (oper == TGeoBoolNode::kGeoUnion)
0510         log << "\t TGeoUnion* boolean = new TGeoUnion";
0511       else if (oper == TGeoBoolNode::kGeoIntersection)
0512         log << "\t TGeoIntersection* boolean = new TGeoIntersection";
0513       log << "(shape_"   << pvoid_t(left) << ", shape_" << pvoid_t(right) << ", 0, ";
0514       log << "matrix_"   << pvoid_t(boolean->GetRightMatrix()) << ");" << newline;
0515       log << "\t shape_" << pvoid_t(sh)
0516           << " = new TGeoCompositeShape(\"" << sh->GetName() << "\", boolean);" << newline;
0517       log << "}" << newline;
0518     }
0519     else if (shape->IsA() == TGeoShapeAssembly::Class()) {
0520       //const TGeoShapeAssembly* sh = (const TGeoShapeAssembly*)shape;
0521       // Nothing to do here: All handled in the handling of TGeoVolumeAssembly
0522     }
0523     else   {
0524       except("CxxRootGenerator","++ Unknown shape transformation request: %s", shape->IsA()->GetName());
0525     }
0526     return log;
0527   }
0528 
0529 }
0530 
0531 static long generate_cxx(Detector& description, int argc, char** argv) {
0532   std::string output;
0533   Actor actor;
0534 
0535   for(int i=0; i<argc; ++i)  {
0536     char c = ::tolower(argv[i][0]);
0537     if ( c == '-' ) { c = ::tolower(argv[i][1]); }
0538     if ( c == '-' ) { c = ::tolower(argv[i][1]); }
0539     if ( c == 'o' && i+1<argc )
0540       output = argv[++i];
0541     else if ( c == 'f' && i+1<argc )
0542       actor.function = argv[++i];
0543     else if ( c == 'v' )
0544       actor.dump_vis = true;
0545     else if ( c == 'm' )
0546       actor.dump_mat = true;
0547     else   {
0548       std::cout <<
0549         "Usage: -plugin DD4hep_CxxRootGenerator -arg [-arg]                                  \n"
0550         "     -output   <string> Set output file for generated code. Default: stdout         \n"
0551         "     -visualization     Also dump visualization attributes of volumes               \n"
0552         "     -materials         Also dump proper materials. Default to IRON                 \n"
0553         "     -help              Show thi help message                                       \n"
0554         "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
0555       ::exit(EINVAL);
0556     }
0557   }
0558   std::unique_ptr<std::ofstream> out;
0559   std::ostream* os = &std::cout;
0560   if ( !output.empty() )   {
0561     Path path(output);
0562     out.reset(new std::ofstream(path.c_str()));
0563     if ( !out->good() )   {
0564       out.reset();
0565       except("CxxRootGenerator",
0566              "++ Failed to open output files: %s [%s]",
0567              path.c_str(), ::strerror(errno));
0568     }
0569     os = out.get();
0570     actor.function = path.filename();
0571     if ( actor.function.rfind('.') != std::string::npos )
0572       actor.function = actor.function.substr(0, actor.function.rfind('.'));
0573     printout(INFO, "CxxRootGenerator",
0574              "++ Dump generated code to output files: %s [function: %s()]",
0575              path.c_str(), actor.function.c_str());
0576   }
0577   else if ( actor.function.empty() )   {
0578     actor.function = "run_geometry";
0579   }
0580   DetElement de = description.world();
0581   PlacedVolume pv = de.placement();
0582   actor.handleHeader(*os);
0583   actor.handlePlacement(*os, 0, pv.ptr());
0584   actor.handleTrailer(*os);
0585   out.reset();
0586   return 1;
0587 }
0588 
0589 DECLARE_APPLY(DD4hep_TGeoCxxGenerator,generate_cxx)