Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /DD4hep/DDCore/src/plugins/TGeoCodeGenerator.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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