Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:16:44

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/DetElement.h>
0018 #include <DD4hep/MatrixHelpers.h>
0019 #include <DD4hep/DD4hepUnits.h>
0020 #include <DD4hep/Printout.h>
0021 #include <DD4hep/Path.h>
0022 #include <DD4hep/detail/ObjectsInterna.h>
0023 #include <DD4hep/detail/DetectorInterna.h>
0024 
0025 // C/C++ include files
0026 #include <stdexcept>
0027 #include <iostream>
0028 #include <iomanip>
0029 #include <fstream>
0030 
0031 // ROOT includes
0032 #include <TClass.h>
0033 #include <TGeoMatrix.h>
0034 #include <TGeoBoolNode.h>
0035 #include <TGeoCompositeShape.h>
0036 
0037 using namespace dd4hep;
0038 
0039 namespace {
0040   
0041   std::string prefix = "\t";
0042   std::string sep(",");
0043 
0044   struct Actor   {
0045     std::map<const TGeoNode*,std::string>     placements;
0046     std::map<const TGeoVolume*,std::string>   volumes;
0047     std::map<const TGeoShape*,std::string>    shapes;
0048     std::map<const TGeoMatrix*,std::string>   matrices;
0049     std::map<const TGeoMedium*,std::string>   materials;
0050     std::map<DetElement,std::string>          detelements;
0051 
0052     std::string function {"run_geometry"};
0053     bool dump_vis = false;
0054     bool dump_structure = false;
0055     Detector& detector;
0056     Actor(Detector& d) : detector(d) {}
0057     ~Actor() = default;
0058     std::ostream& handleHeader   (std::ostream& log);
0059     std::ostream& handleTrailer  (std::ostream& log);
0060     std::ostream& handleSolid    (std::ostream& log, const TGeoShape*  sh);
0061     std::ostream& handleMatrix   (std::ostream& log, TGeoMatrix* mat);
0062     std::ostream& handleMaterial (std::ostream& log, TGeoMedium* mat);
0063     std::ostream& handlePlacement(std::ostream& log, TGeoNode*   parent, TGeoNode* node);
0064     std::ostream& handleStructure(std::ostream& log, DetElement parent, DetElement de);
0065   };
0066   typedef void* pvoid_t;
0067 
0068   std::ostream& newline(std::ostream& log)    {
0069     return log << std::endl << prefix;
0070   }
0071   template <typename T> const void* pointer(const Handle<T>& h)   {
0072     return h.ptr();
0073   }
0074   template <typename T> const void* pointer(const T* h)   {
0075     return h;
0076   }
0077   template <typename T> inline std::string obj_name(const std::string& pref, const T* ptr)  {
0078     std::stringstream name;
0079     name << pref << "_" << pointer(ptr);
0080     return name.str();
0081   }
0082 
0083 
0084   std::ostream& Actor::handleHeader   (std::ostream& log)    {
0085     log << "#include \"TClass.h\"" << std::endl
0086         << "#include \"TGeoNode.h\"" << std::endl
0087         << "#include \"TGeoExtension.h\"" << std::endl
0088         << "#include \"TGeoShapeAssembly.h\"" << std::endl
0089         << "#include \"TGeoMedium.h\"" << std::endl
0090         << "#include \"TGeoVolume.h\"" << std::endl
0091         << "#include \"TGeoShape.h\"" << std::endl
0092         << "#include \"TGeoPhysicalNode.h\"" << std::endl
0093         << "#include \"TGeoCone.h\"" << std::endl
0094         << "#include \"TGeoParaboloid.h\"" << std::endl
0095         << "#include \"TGeoPgon.h\"" << std::endl
0096         << "#include \"TGeoPcon.h\"" << std::endl
0097         << "#include \"TGeoSphere.h\"" << std::endl
0098         << "#include \"TGeoArb8.h\"" << std::endl
0099         << "#include \"TGeoTrd1.h\"" << std::endl
0100         << "#include \"TGeoTrd2.h\"" << std::endl
0101         << "#include \"TGeoTube.h\"" << std::endl
0102         << "#include \"TGeoEltu.h\"" << std::endl
0103         << "#include \"TGeoXtru.h\"" << std::endl
0104         << "#include \"TGeoHype.h\"" << std::endl
0105         << "#include \"TGeoTorus.h\"" << std::endl
0106         << "#include \"TGeoHalfSpace.h\"" << std::endl
0107         << "#include \"TGeoCompositeShape.h\"" << std::endl
0108         << "#include \"TGeoShapeAssembly.h\"" << std::endl
0109         << "#include \"TGeoMatrix.h\"" << std::endl
0110         << "#include \"TGeoBoolNode.h\"" << std::endl
0111         << "#include \"TGeoCompositeShape.h\"" << std::endl
0112         << "#include \"TGeoManager.h\"" << std::endl << std::endl
0113         << "#include \"DD4hep/Factories.h\"" << std::endl
0114         << "#include \"DD4hep/Shapes.h\"" << std::endl
0115         << "#include \"DD4hep/Volumes.h\"" << std::endl
0116         << "#include \"DD4hep/Detector.h\"" << std::endl
0117         << "#include \"DD4hep/DetElement.h\"" << std::endl
0118         << "#include \"DD4hep/MatrixHelpers.h\"" << std::endl
0119         << "#include \"DD4hep/DD4hepUnits.h\"" << std::endl
0120         << "#include \"DD4hep/Printout.h\"" << std::endl
0121         << "#include \"DD4hep/Path.h\"" << std::endl
0122         << "#include \"DD4hep/detail/ObjectsInterna.h\"" << std::endl
0123         << "#include \"DD4hep/detail/DetectorInterna.h\"" << std::endl
0124         << "#include <vector>" << std::endl
0125         << "#include <map>" << std::endl
0126         << "#include <set>" << std::endl << std::endl << std::endl;
0127     log << "using namespace std;" << std::endl;
0128     log << "using namespace dd4hep;" << std::endl;
0129     log << "extern PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix* transform);" << std::endl;
0130 
0131     log << "namespace  {" << newline
0132         << "\t struct CodeGeo  {" << newline
0133         << "\t\t map<unsigned long, TGeoNode*>     placements;" << newline
0134         << "\t\t map<unsigned long, TGeoVolume*>   volumes;" << newline
0135         << "\t\t map<unsigned long, TGeoShape*>    shapes;" << newline
0136         << "\t\t map<unsigned long, TGeoMatrix*>   matrices;" << newline
0137         << "\t\t map<unsigned long, TGeoMedium*>   materials;" << newline
0138         << "\t\t map<unsigned long, DetElement>    structure;" << newline
0139         << "\t\t Detector& detector;" << newline
0140         << "\t\t CodeGeo(Detector& d) : detector(d) {}" << newline
0141         << "\t\t TGeoVolume* load_geometry();" << newline
0142         << "\t\t DetElement  load_structure();" << newline
0143         << "\t\t void add_vis(Detector& d, VisAttr& v)  {" << newline
0144         << "\t\t  try { d.add(v); } catch(...) {}" << newline
0145         << "\t\t }" << newline
0146         << "\t };" << std::endl
0147         << "}" << std::endl << std::endl << std::endl;
0148     log << "TGeoVolume* CodeGeo::load_geometry()   {" << newline;
0149 
0150     const auto& constants = detector.constants();
0151     log << "/// Handling " << constants.size() << " Constants" << newline;
0152     for(const auto& o : constants)    {
0153       const Constant& c = o.second;
0154       log << "detector.add(Constant(\"" << c.name() << "\",\""
0155           << c->type << "\",\"" << c->dataType << "\")); " << newline; 
0156     }
0157 
0158     // Copy visualization attributes and register them to the detector object
0159     const auto& vis = detector.visAttributes();
0160     log << "/// Handling " << vis.size() << " Visualization attributes" << newline;
0161     for(const auto& o : vis)    {
0162       float r, g, b;
0163       VisAttr v(o.second);
0164       v.rgb(r,g,b);
0165       log << "{ VisAttr v(\"" << o.first << "\"); "
0166           << "v.setColor(" << r << sep << g << sep << b << "); "
0167           << "v.setShowDaughters(" << v.showDaughters() << "); "
0168           << "v.setVisible(" << v.visible() << "); " << newline
0169           << "  v.setLineStyle(" << v.lineStyle() << "); "
0170           << "v.setDrawingStyle(" << v.drawingStyle() << "); "
0171           << "v.setAlpha(" << v.alpha() << "); "
0172           << "add_vis(detector,v);  }" << newline;
0173     }
0174 
0175     const auto& limits = detector.limitsets();
0176     log << "/// Handling " << limits.size() << " Limit Sets" << newline;
0177     for(const auto& o : limits)    {
0178       LimitSet ls = o.second;
0179       log << "{ LimitSet ls(string(\"" << ls.name() << "\")); " << newline;
0180       const std::set<Limit>& lims = ls.limits();
0181       const std::set<Limit>& cuts = ls.cuts();
0182       for(const auto& l : lims)   {
0183         log << "  { Limit l; l.particles = \"" << l.particles << "\";"
0184             << " l.name = \""    << l.name << "\";"
0185             << " l.unit = \""    << l.unit << "\";"
0186             << " l.content = \"" << l.content << "\";"
0187             << " l.value = " << l.value << ";"
0188             << " ls.addLimit(l); } " << newline;
0189       }
0190       for(const auto& l : cuts)   {
0191         log << "  { Limit l; l.particles = \"" << l.particles << "\";"
0192             << " l.name = \""    << l.name << "\";"
0193             << " l.unit = \""    << l.unit << "\";"
0194             << " l.content = \"" << l.content << "\";"
0195             << " l.value = " << l.value << ";"
0196             << " ls.addLimit(l); } " << newline;
0197       }
0198       log << "  detector.addLimitSet(ls); } " << newline;
0199     }
0200 
0201     const auto& regions = detector.regions();
0202     log << "/// Handling " << regions.size() << " Region settings " << newline;
0203     for(const auto& o : regions)    {
0204       Region r = o.second;
0205       log << "{ Region r(\"" << r.name() << "\")"
0206           << "; r->store_secondaries = " << r->store_secondaries
0207           << "; r->was_threshold_set = " << r->was_threshold_set
0208           << "; r->use_default_cut = " << r->use_default_cut
0209           << "; r->threshold = " << r->threshold
0210           << "; r->cut = " << r->cut << ";" << newline;
0211       if ( !r->user_limits.empty() )   {
0212         log << " vector<string> user_limits = {";
0213         for(size_t i=0, n=r->user_limits.size(); i<n; ++i)
0214           log << "r->user_limits.emplace_back(\"" << r->user_limits[i] << "\");" << newline;
0215       }
0216     }
0217 
0218     const auto& ids = detector.idSpecifications();
0219     log << "/// Handling " << ids.size() << " Id Specifications " << newline;
0220     for(const auto& o : ids)    {
0221       IDDescriptor i = o.second;
0222       log << "{ IDDescriptor i(\"" << i.name() << "\", \"" << i->description << "\");"
0223           << " detector.add(i); }" << newline;
0224     }
0225 
0226     const auto& segments = detector.readouts();
0227     log << "/// Handling " << segments.size() << " Segmentations " << newline
0228         << "list<Segmentation> segs; " << newline;
0229     for(const auto& o : segments)    {
0230       Readout      r = o.second;
0231       Segmentation s = r->segmentation;
0232       if ( s.isValid() )   {
0233         log << "{ Segmentation s(\"" << s.name() << "\");"
0234             << " segs.emplace_back(s); }" << newline;
0235       }
0236     }
0237 
0238     const auto& readouts = detector.readouts();
0239     log << "/// Handling " << readouts.size() << " Readout settings " << newline;
0240     for(const auto& o : readouts)    {
0241       Readout r = o.second;
0242       log << "{ Readout r(string(\"" << r.name() << "\"));"
0243           << " r->SetTitle(\"" << r->GetTitle() << "\"); ";
0244       if ( r->segmentation.isValid() )
0245         log << " r->segmentation = segs.front(); segs.pop_front(); ";
0246       if ( r->id.isValid() )
0247         log << " r->id = detector.idSpecification(\"" << r->id.name() << "\"); ";
0248       for(const auto& c : r->hits)   {
0249         log << newline;
0250         log << "{ HitCollection c(\"" << c.name << "\",\"" << c.key << "\", "
0251             << c.key_min << sep << c.key_max << "); "
0252             << "  r->hits.emplace_back(c); } ";
0253       }
0254       if ( !r->hits.empty() ) log << newline;
0255       log << " detector.add(r); }" << newline;
0256     }
0257     return log;
0258   }
0259 
0260   std::ostream& Actor::handleTrailer   (std::ostream& log)    {
0261     log << "static long generate_dd4hep(Detector& detector, int, char**)   {" << newline
0262         << "CodeGeo gen(detector);"                     << newline
0263         << "TGeoVolume* vol_top = gen.load_geometry();" << newline
0264         << "detector.manager().SetTopVolume(vol_top);"  << newline
0265         << "detector.init();"                           << newline;
0266     if ( dump_structure )  {
0267       TGeoManager& mgr = detector.manager();
0268       handleMaterial(log, mgr.GetMedium("Air"));
0269       handleMaterial(log, mgr.GetMedium("Vacuum"));
0270       log << "gen.structure[" << pointer(detector.world()) << "] = detector.world(); " << newline
0271           << "gen.load_structure();" << newline;
0272     }
0273     log << "return 1;"
0274         << std::endl << "}"  << std::endl     << std::endl
0275         << "DECLARE_APPLY(DD4hep_Run_" << function << ", generate_dd4hep)"
0276         << std::endl;
0277     return log;
0278   }
0279   
0280   std::ostream& Actor::handleStructure(std::ostream& log, DetElement parent, DetElement de)   {
0281     if ( de.isValid() && detelements.find(de) == detelements.end() )  {
0282       std::string name = obj_name("de", de.ptr());
0283       detelements.emplace(de,name);
0284       if ( !parent.isValid() )   {
0285         std::cout << "No parent: " << de.path() << " " << pointer(de) << " " << pointer(detector.world()) << std::endl;
0286         log << std::endl
0287             << "DetElement  CodeGeo::load_structure()   {" << newline;
0288       }
0289       else  {
0290         log << "{" << newline
0291             << "\t DetElement par = structure[" << pointer(parent) << "];"          << newline
0292             << "\t DetElement de(par,\"" << de.name() << "\"," << de.id() << ");"   << newline
0293             << "\t de->SetTitle(\""             << de->GetTitle() << "\");"         << newline
0294             << "\t de->combineHits = "          << de->combineHits << ";"           << newline
0295             << "\t de.setTypeFlag("             << de.typeFlag() << ");"            << newline;
0296         if ( de.placement().isValid() )  {
0297           log << "\t de.setPlacement(placements[" << pointer(de.placement()) << "]);" << newline;
0298         }
0299         else  {
0300           std::cout << "Placement od DetElement " << de.path() << " Is not valid! [Ignored]" << std::endl;
0301         }
0302         log << "\t structure[" << pointer(de) << "] = de; " << newline
0303             << "}"   << newline;
0304       }
0305       for(const auto& d : de.children() )  {
0306         handleStructure(log, de, d.second);
0307       }
0308       if ( !parent.isValid() )   {
0309         log << "return structure[" << pointer(de) << "];" << std::endl
0310             << "}" << std::endl << std::endl;
0311       }
0312     }
0313     return log;
0314   }
0315 
0316   std::ostream& Actor::handlePlacement(std::ostream& log, TGeoNode* parent, TGeoNode* node)  {
0317     if ( node && placements.find(node) == placements.end() )  {
0318       PlacedVolume pv(node);
0319       TGeoVolume* vol = node->GetVolume();
0320       TGeoMatrix* mat = node->GetMatrix();
0321 
0322       std::string name = obj_name("vol", vol);
0323       placements.emplace(node,name);
0324 
0325       handleMatrix(log, mat);
0326 
0327       if ( vol && volumes.find(vol) == volumes.end() )  {
0328         volumes.emplace(vol,name);
0329         if ( vol->IsA() == TGeoVolumeAssembly::Class() )    {
0330           log << "{" << newline;
0331           log << "\t Assembly vol(\"" << vol->GetName() << "\");" << newline;
0332         }
0333         else   {
0334           Volume v(vol);
0335           TGeoMedium* med = vol->GetMedium();
0336           TGeoShape*  sh  = vol->GetShape();
0337           handleSolid(log, sh);
0338           handleMaterial(log, med);
0339           log << "{" << newline;
0340           log << "\t Volume vol(\"" << vol->GetName() << "\", "
0341               << "Solid(shapes[" << pointer(sh) << "]), "
0342               << "Material(materials[" << pointer(med) << "]));" << newline;
0343           if ( ::strlen(vol->GetTitle()) != 0 )
0344             log << "\t vol->SetTitle(\"" << vol->GetTitle() << "\");" << newline;
0345           if ( !v.option().empty() )
0346             log << "\t vol.setOption(\"" << v.option() << "\"); " << newline;
0347           if ( v.region().isValid() )
0348             log << "\t vol.setRegion(detector, \"" << v.region().name() << "\");" << newline;
0349           if ( v.limitSet().isValid() )
0350             log << "\t vol.setLimitSet(detector, \"" << v.limitSet().name() << "\");" << newline;
0351           if ( v.sensitiveDetector().isValid() )
0352             log << "\t vol.setSensitiveDetector(detector.sensitiveDetector(\""
0353                 << v.sensitiveDetector().name() << "\"));" << newline;
0354           if ( dump_vis && v.visAttributes().isValid() )
0355             log << "\t vol.setVisAttributes(detector, \"" << v.visAttributes().name() << "\");" << newline;
0356         }
0357         log << "\t volumes[" << pointer(vol) << "] = vol;" << newline;
0358       }
0359       else  {
0360         log << "{" << newline
0361             << "\t Volume vol = volumes[" << pointer(vol) << "];" << newline;
0362       }
0363       if ( parent )   {
0364         log << "\t PlacedVolume pv = _addNode(volumes[" << pointer(parent->GetVolume())
0365             << "],vol.ptr()," << pv.copyNumber() << sep
0366             << "matrices[" << pointer(mat) << "]);" << newline
0367             << "\t placements[" << pointer(node) << "] = pv.ptr(); " << newline;
0368         for(const auto& vid : pv.volIDs() )
0369           log << "\t pv.addPhysVolID(\"" << vid.first << "\", " << vid.second << ");" << newline;
0370       }
0371       log << "}" << newline;
0372       for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
0373         TGeoNode* daughter = node->GetDaughter(idau);
0374         handlePlacement(log, node, daughter);
0375       }
0376       if ( !parent )  {
0377         log << "return volumes[" << pointer(vol) << "];" << std::endl
0378             << "}" << std::endl << std::endl << std::endl;
0379       }
0380     }
0381     return log;
0382   }
0383 
0384   std::ostream& Actor::handleMaterial(std::ostream& log, TGeoMedium* medium)   {
0385     if ( medium && materials.find(medium) == materials.end() )  {
0386       std::string name = obj_name("material",medium);
0387       materials.emplace(medium,name);
0388       TGeoMaterial* material = medium->GetMaterial();
0389       log << "{" << newline
0390           << "\t TGeoManager& mgr = detector.manager();" << newline
0391           << "\t TGeoMedium* med = mgr.GetMedium(\""<< medium->GetName() << "\");" << newline
0392           << "\t if ( 0 == med )  {" << newline
0393           << "\t TGeoMaterial* mat = mgr.GetMaterial(\"" << material->GetName() << "\");" << newline
0394           << "\t if ( 0 == mat )  {" << newline
0395           << "\t   mat = new TGeoMaterial(\"" << material->GetName() << "\", "
0396           << material->GetA() << sep << material->GetZ() << sep << material->GetDensity() << sep
0397           << material->GetRadLen() << sep << material->GetIntLen() << ");" << newline
0398           << "\t }" << newline
0399           << "\t med = new TGeoMedium(\""<< medium->GetName() << "\"," << medium->GetId() << ", mat);" << newline
0400           << "\t }" << newline
0401           << "\t materials[" << pointer(medium) << "] = med;" << newline
0402           << "}" << newline;
0403     }
0404     return log;
0405   }
0406   
0407   std::ostream& Actor::handleMatrix(std::ostream& log, TGeoMatrix* mat)   {
0408     if ( mat && matrices.find(mat) == matrices.end() )  {
0409       std::string name = obj_name("matrix",mat);
0410       log << "{" << newline
0411           << "\t TGeoHMatrix* mat = new TGeoHMatrix(\"" << mat->GetName() << "\");" << newline
0412           << "\t matrices[" << pointer(mat) << "] = mat;" << newline;
0413       if ( mat->IsTranslation() )   {
0414         const Double_t* tra = mat->GetTranslation();
0415         log << "\t Double_t trans[] = {";
0416         for(size_t i=0; tra && i<3; ++i)  {
0417           log << tra[i];
0418           log << ((i<2) ? sep : "};");
0419         }
0420         log << newline << "\t mat->SetTranslation(trans);" << newline;
0421       }
0422       if ( mat->IsRotation() )   {
0423         const Double_t* rot = mat->GetRotationMatrix();
0424         if ( rot && (rot[0] != 1e0 || rot[4] != 1e0 || rot[8] != 1e0) )  {
0425           log << "\t Double_t rot[] = {";
0426           for(size_t i=0; rot && i<9; ++i)  {
0427             log << rot[i];
0428             log << ((i<8) ? sep : "};");
0429           }
0430           log << newline << "\t mat->SetRotation(rot);" << newline;
0431         }
0432       }
0433       if ( mat->IsScale() )   {
0434         const Double_t* sca = mat->GetScale();
0435         log << "\t Double_t scale[] = {";
0436         for(size_t i=0; sca && i<3; ++i)  {
0437           log << sca[i];
0438           log << ((i<2) ? sep : "};");
0439         }
0440         log << newline << "\t mat->SetScale(scale);" << newline;
0441       }
0442       log << "}" << newline;
0443     }
0444     return log;
0445   }
0446   
0447   /// Pretty print of solid attributes
0448   std::ostream& Actor::handleSolid(std::ostream& log,  const TGeoShape* shape)    {
0449     std::string name = obj_name("solid", shape);
0450 
0451     if ( shapes.find(shape) != shapes.end() )  {
0452       return log;
0453     }
0454     else if (shape->IsA() == TGeoShapeAssembly::Class()) {
0455       // Nothing to do here: All handled in the handling of TGeoVolumeAssembly
0456       return log;
0457     }
0458 
0459     shapes.emplace(shape,name);
0460 
0461     TClass* cl = shape->IsA();
0462     log << "{" << newline;
0463     if ( cl == TGeoBBox::Class() )   {
0464       TGeoBBox* sh = (TGeoBBox*) shape;
0465       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0466           << sep << sh->GetDX()
0467           << sep << sh->GetDY()
0468           << sep << sh->GetDZ() << "));" << newline;
0469     }
0470     else if (cl == TGeoHalfSpace::Class()) {
0471       TGeoHalfSpace* sh = (TGeoHalfSpace*)(const_cast<TGeoShape*>(shape));
0472       log << "\t Double_t* point = {"
0473           << sh->GetPoint()[0] << sep << sh->GetPoint()[1] << sep << sh->GetPoint()[2] << "}; " << newline
0474           << "\t Double_t* norm = {"
0475           << sh->GetNorm()[0] << sep << sh->GetNorm()[1] << sep << sh->GetNorm()[2] << "}; " << newline
0476           << "\t Solid " << name << " = Solid(new " << cl->GetName() << "(\""
0477           << sh->GetName() << "\", point, norm));" << newline;
0478     }
0479     else if (cl == TGeoTube::Class()) {
0480       const TGeoTube* sh = (const TGeoTube*) shape;
0481       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0482           << sep << sh->GetRmin()
0483           << sep << sh->GetRmax()
0484           << sep << sh->GetDz()
0485           << "));" << newline;
0486     }
0487     else if (cl == TGeoTubeSeg::Class()) {
0488       const TGeoTubeSeg* sh = (const TGeoTubeSeg*) shape;
0489       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0490           << sep << sh->GetRmin()
0491           << sep << sh->GetRmax()
0492           << sep << sh->GetDz()
0493           << sep << sh->GetPhi1()
0494           << sep << sh->GetPhi2()
0495           << "));" << newline;
0496     }
0497     else if (cl == TGeoCtub::Class()) {
0498       const TGeoCtub* sh = (const TGeoCtub*) shape;
0499       const Double_t*   hi = sh->GetNhigh();
0500       const Double_t*   lo = sh->GetNlow();
0501       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0502           << sep << sh->GetRmin()
0503           << sep << sh->GetRmax()
0504           << sep << sh->GetDz()
0505           << sep << sh->GetPhi1()
0506           << sep << sh->GetPhi2()
0507           << sep << lo[0]
0508           << sep << lo[1]
0509           << sep << lo[2]
0510           << sep << hi[0]
0511           << sep << hi[1]
0512           << sep << hi[2]
0513           << "));" << newline;
0514     }
0515     else if (cl == TGeoEltu::Class()) {
0516       const TGeoEltu* sh = (const TGeoEltu*) shape;
0517       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0518           << sep   << sh->GetA()
0519           << sep   << sh->GetB()
0520           << sep   << sh->GetDz()
0521           << "));"   << newline;
0522     }
0523     else if (cl == TGeoTrd1::Class()) {
0524       const TGeoTrd1* sh = (const TGeoTrd1*) shape;
0525       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0526           << sep     << sh->GetDx1()
0527           << sep     << sh->GetDx2()
0528           << sep     << sh->GetDy()
0529           << sep     << sh->GetDz()
0530           << "));"    << newline;
0531     }
0532     else if (cl == TGeoTrd2::Class()) {
0533       const TGeoTrd2* sh = (const TGeoTrd2*) shape;
0534       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0535           << sep     << sh->GetDx1()
0536           << sep     << sh->GetDx2()
0537           << sep     << sh->GetDy1()
0538           << sep     << sh->GetDy2()
0539           << sep     << sh->GetDz()
0540           << "));"    << newline;
0541     }
0542     else if (cl == TGeoTrap::Class()) {
0543       const TGeoTrap* sh = (const TGeoTrap*) shape;
0544       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0545           << sep     << sh->GetDz() << sep << sh->GetTheta() << sep << sh->GetPhi()
0546           << sep     << sh->GetH1() << sep << sh->GetBl1()   << sep << sh->GetTl1() << sep << sh->GetAlpha1()
0547           << sep     << sh->GetH2() << sep << sh->GetBl2()   << sep << sh->GetTl2() << sep << sh->GetAlpha2()
0548           << "));"    << newline;
0549     }
0550     else if (cl == TGeoHype::Class()) {
0551       const TGeoHype* sh = (const TGeoHype*) shape;
0552       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0553           << sep     << sh->GetRmin() << sep  << sh->GetRmax() << sep << sh->GetDz()
0554           << sep     << sh->GetStIn() << sep << sh->GetStOut()
0555           << "));"    << newline;
0556     }
0557     else if (cl == TGeoPgon::Class()) {
0558       const TGeoPgon* sh = (const TGeoPgon*) shape;
0559       log << "double params[] = {" << sh->GetPhi1() << sep << sh->GetDphi() << sep
0560           << sh->GetNedges() << sep << sh->GetNz();
0561       for(int i=0, n=sh->GetNz(); i<n; ++i)
0562         log << sep << sh->GetZ(i) << sep << sh->GetRmin(i) << sep << sh->GetRmax(i);
0563       log << "};" << newline
0564           << "\t Solid " << name << " = Solid(new "    << cl->GetName() << "(params));" << newline
0565           << name << "->SetName(\"" << sh->GetName() << "\");" << newline;
0566     }
0567     else if (cl == TGeoPcon::Class()) {
0568       const TGeoPcon* sh = (const TGeoPcon*) shape;
0569       log << "double params[] = {" << sh->GetPhi1() << sep << sh->GetDphi() << sep << sh->GetNz();
0570       for(int i=0, n=sh->GetNz(); i<n; ++i)
0571         log << sep << sh->GetZ(i) << sep << sh->GetRmin(i) << sep << sh->GetRmax(i);
0572       log << "};" << newline
0573           << "\t Solid " << name << " = Solid(new "    << cl->GetName() << "(params));" << newline
0574           << name << "->SetName(\""     << sh->GetName() << "\");" << newline;
0575     }
0576     else if (cl == TGeoCone::Class()) {
0577       const TGeoCone* sh = (const TGeoCone*) shape;
0578       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0579           << sep << sh->GetDz()
0580           << sep << sh->GetRmin1() << sep << sh->GetRmax1()
0581           << sep << sh->GetRmin2() << sep << sh->GetRmax2()
0582           << "));"   << newline;
0583     }
0584     else if (cl == TGeoConeSeg::Class()) {
0585       const TGeoConeSeg* sh = (const TGeoConeSeg*) shape;
0586       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0587           << sep << sh->GetDz()
0588           << sep << sh->GetRmin1() << sep << sh->GetRmax1()
0589           << sep << sh->GetRmin2() << sep << sh->GetRmax2()
0590           << sep   << sh->GetPhi1()  << sep << sh->GetPhi2()
0591           << "));"   << newline;
0592     }
0593     else if (cl == TGeoParaboloid::Class()) {
0594       const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
0595       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0596           << sep   << sh->GetRlo() << sep << sh->GetRhi() << sep << sh->GetDz() << "));" << newline;
0597     }
0598     else if (cl == TGeoSphere::Class()) {
0599       const TGeoSphere* sh = (const TGeoSphere*) shape;
0600       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0601           << sep << sh->GetRmin()   << sep << sh->GetRmax()
0602           << sep << sh->GetPhi1()   << sep << sh->GetPhi2()
0603           << sep << sh->GetTheta1() << sep << sh->GetTheta2()
0604           << "));" << newline;
0605     }
0606     else if (cl == TGeoTorus::Class()) {
0607       const TGeoTorus* sh = (const TGeoTorus*) shape;
0608       log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
0609           << sep << sh->GetRmin()  << sep << sh->GetRmax() << sep << sh->GetR()
0610           << sep << sh->GetPhi1()  << sep << sh->GetDphi()
0611           << "));" << newline;
0612     }
0613     else if (cl == TGeoArb8::Class()) {
0614       TGeoArb8* sh = (TGeoArb8*) shape;
0615       const Double_t* v = sh->GetVertices();
0616       log << "double vertices[] = {";
0617       for(int i=0; i<8; ++i, v+=2)
0618         log << v[0] << sep << v[1] << ((i<7) ? ',' : ' ');
0619       log << "};" << newline
0620           << "\t Solid " << name << " = Solid(new " << cl->GetName()
0621           << "(\"" << sh->GetName() << "\"" << sep << sh->GetDz()  << sep << "vertices);" << newline;
0622     }
0623     else if (cl == TGeoXtru::Class()) {
0624       Solid sol(shape);
0625       const TGeoXtru* sh = (const TGeoXtru*) shape;
0626       std::vector<double> pars = sol.dimensions();
0627       log << "double param[] = {" << newline;
0628       for( size_t i=0; i < pars.size(); ++i )
0629         log << pars[i] << ((i+1<pars.size()) ? ',' : ' ');
0630       log << "};" << newline
0631           << "\t Solid " << name << " = Solid(new " << cl->GetName() << "(param));" << newline
0632           << "\t " << name << "->SetName(\"" << sh->GetName() << "\");" << newline;
0633     }
0634     else if (shape->IsA() == TGeoCompositeShape::Class()) {
0635       const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape;
0636       const TGeoBoolNode* boolean = sh->GetBoolNode();
0637       const TGeoShape* left  = boolean->GetLeftShape();
0638       const TGeoShape* right = boolean->GetRightShape();
0639       TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
0640       handleSolid(log, left);
0641       handleSolid(log, right);
0642       handleMatrix(log, boolean->GetRightMatrix());
0643       if (oper == TGeoBoolNode::kGeoSubtraction)
0644         log << "\t TGeoSubtraction* boolean" << pointer(shape) << " = new TGeoSubtraction";
0645       else if (oper == TGeoBoolNode::kGeoUnion)
0646         log << "\t TGeoUnion* boolean" << pointer(shape) << " = new TGeoUnion";
0647       else if (oper == TGeoBoolNode::kGeoIntersection)
0648         log << "\t TGeoIntersection* boolean" << pointer(shape) << " = new TGeoIntersection";
0649       log << "(shapes[" << pointer(left)  << "], "
0650           << " shapes[" << pointer(right) << "], 0, ";
0651       log << " matrices[" << pointer(boolean->GetRightMatrix()) << "]);" << newline;
0652       log << "\t Solid " << name << " = Solid(new TGeoCompositeShape(\""
0653           << sh->GetName() << "\", boolean" << pointer(shape) << "));" << newline;
0654     }
0655     else   {
0656       except("CxxRootGenerator","++ Unknown shape transformation request: %s", shape->IsA()->GetName());
0657     }
0658     log << "\t shapes[" << pointer(shape) << "] = " << name << ";" << newline
0659         << "}" << newline;
0660     return log;
0661   }
0662 }
0663 
0664 static long generate_cxx(Detector& description, int argc, char** argv) {
0665   std::string output;
0666   Actor actor(description);
0667 
0668   for(int i=0; i<argc; ++i)  {
0669     char c = ::tolower(argv[i][0]);
0670     if ( c == '-' ) { c = ::tolower(argv[i][1]); }
0671     if ( c == '-' ) { c = ::tolower(argv[i][1]); }
0672     if ( c == 'o' && i+1<argc )
0673       output = argv[++i];
0674     else if ( c == 'f' && i+1<argc )
0675       actor.function = argv[++i];
0676     else if ( c == 'v' )
0677       actor.dump_vis = true;
0678     else if ( c == 's' )
0679       actor.dump_structure = true;
0680     else   {
0681       std::cout <<
0682         "Usage: -plugin DD4hep_CxxRootGenerator -arg [-arg]                                  \n"
0683         "     -output   <string> Set output file for generated code. Default: stdout         \n"
0684         "     -help              Show thi help message                                       \n"
0685         "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
0686       ::exit(EINVAL);
0687     }
0688   }
0689   std::unique_ptr<std::ofstream> out;
0690   std::ostream* os = &std::cout;
0691   if ( !output.empty() )   {
0692     Path path(output);
0693     out.reset(new std::ofstream(path.c_str()));
0694     if ( !out->good() )   {
0695       out.reset();
0696       except("CxxRootGenerator",
0697              "++ Failed to open output files: %s [%s]",
0698              path.c_str(), ::strerror(errno));
0699     }
0700     os = out.get();
0701     actor.function = path.filename();
0702     if ( actor.function.rfind('.') != std::string::npos )
0703       actor.function = actor.function.substr(0, actor.function.rfind('.'));
0704     printout(INFO, "CxxRootGenerator",
0705              "++ Dump generated code to output files: %s [function: %s()]",
0706              path.c_str(), actor.function.c_str());
0707   }
0708   else if ( actor.function.empty() )   {
0709     actor.function = "run_geometry";
0710   }
0711   DetElement de = description.world();
0712   PlacedVolume pv = de.placement();
0713   actor.handleHeader(*os);
0714   actor.handlePlacement(*os, 0, pv.ptr());
0715   actor.handleStructure(*os, DetElement(), de);
0716   actor.handleTrailer(*os);
0717   out.reset();
0718   return 1;
0719 }
0720 
0721 DECLARE_APPLY(DD4hep_CxxGenerator,generate_cxx)