Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-02 07:53:02

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