File indexing completed on 2025-07-02 07:53:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0026 #include <iostream>
0027 #include <fstream>
0028 #include <map>
0029 #include <memory>
0030 #include <sstream>
0031 #include <string>
0032
0033
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
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
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
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)