File indexing completed on 2025-01-30 09:16:44
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 <stdexcept>
0027 #include <iostream>
0028 #include <iomanip>
0029 #include <fstream>
0030
0031
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
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
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
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)