DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
CodeGenerator.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 #include <DD4hep/Factories.h>
14 #include <DD4hep/Shapes.h>
15 #include <DD4hep/Volumes.h>
16 #include <DD4hep/Detector.h>
17 #include <DD4hep/DetElement.h>
18 #include <DD4hep/MatrixHelpers.h>
19 #include <DD4hep/DD4hepUnits.h>
20 #include <DD4hep/Printout.h>
21 #include <DD4hep/Path.h>
24 
25 // C/C++ include files
26 #include <stdexcept>
27 #include <iostream>
28 #include <iomanip>
29 #include <fstream>
30 
31 // ROOT includes
32 #include <TClass.h>
33 #include <TGeoMatrix.h>
34 #include <TGeoBoolNode.h>
35 #include <TGeoCompositeShape.h>
36 
37 using namespace dd4hep;
38 
39 namespace {
40 
41  std::string prefix = "\t";
42  std::string sep(",");
43 
44  struct Actor {
45  std::map<const TGeoNode*,std::string> placements;
46  std::map<const TGeoVolume*,std::string> volumes;
47  std::map<const TGeoShape*,std::string> shapes;
48  std::map<const TGeoMatrix*,std::string> matrices;
49  std::map<const TGeoMedium*,std::string> materials;
50  std::map<DetElement,std::string> detelements;
51 
52  std::string function {"run_geometry"};
53  bool dump_vis = false;
54  bool dump_structure = false;
55  Detector& detector;
56  Actor(Detector& d) : detector(d) {}
57  ~Actor() = default;
58  std::ostream& handleHeader (std::ostream& log);
59  std::ostream& handleTrailer (std::ostream& log);
60  std::ostream& handleSolid (std::ostream& log, const TGeoShape* sh);
61  std::ostream& handleMatrix (std::ostream& log, TGeoMatrix* mat);
62  std::ostream& handleMaterial (std::ostream& log, TGeoMedium* mat);
63  std::ostream& handlePlacement(std::ostream& log, TGeoNode* parent, TGeoNode* node);
64  std::ostream& handleStructure(std::ostream& log, DetElement parent, DetElement de);
65  };
66  typedef void* pvoid_t;
67 
68  std::ostream& newline(std::ostream& log) {
69  return log << std::endl << prefix;
70  }
71  template <typename T> const void* pointer(const Handle<T>& h) {
72  return h.ptr();
73  }
74  template <typename T> const void* pointer(const T* h) {
75  return h;
76  }
77  template <typename T> inline std::string obj_name(const std::string& pref, const T* ptr) {
78  std::stringstream name;
79  name << pref << "_" << pointer(ptr);
80  return name.str();
81  }
82 
83 
84  std::ostream& Actor::handleHeader (std::ostream& log) {
85  log << "#include \"TClass.h\"" << std::endl
86  << "#include \"TGeoNode.h\"" << std::endl
87  << "#include \"TGeoExtension.h\"" << std::endl
88  << "#include \"TGeoShapeAssembly.h\"" << std::endl
89  << "#include \"TGeoMedium.h\"" << std::endl
90  << "#include \"TGeoVolume.h\"" << std::endl
91  << "#include \"TGeoShape.h\"" << std::endl
92  << "#include \"TGeoPhysicalNode.h\"" << std::endl
93  << "#include \"TGeoCone.h\"" << std::endl
94  << "#include \"TGeoParaboloid.h\"" << std::endl
95  << "#include \"TGeoPgon.h\"" << std::endl
96  << "#include \"TGeoPcon.h\"" << std::endl
97  << "#include \"TGeoSphere.h\"" << std::endl
98  << "#include \"TGeoArb8.h\"" << std::endl
99  << "#include \"TGeoTrd1.h\"" << std::endl
100  << "#include \"TGeoTrd2.h\"" << std::endl
101  << "#include \"TGeoTube.h\"" << std::endl
102  << "#include \"TGeoEltu.h\"" << std::endl
103  << "#include \"TGeoXtru.h\"" << std::endl
104  << "#include \"TGeoHype.h\"" << std::endl
105  << "#include \"TGeoTorus.h\"" << std::endl
106  << "#include \"TGeoHalfSpace.h\"" << std::endl
107  << "#include \"TGeoCompositeShape.h\"" << std::endl
108  << "#include \"TGeoShapeAssembly.h\"" << std::endl
109  << "#include \"TGeoMatrix.h\"" << std::endl
110  << "#include \"TGeoBoolNode.h\"" << std::endl
111  << "#include \"TGeoCompositeShape.h\"" << std::endl
112  << "#include \"TGeoManager.h\"" << std::endl << std::endl
113  << "#include \"DD4hep/Factories.h\"" << std::endl
114  << "#include \"DD4hep/Shapes.h\"" << std::endl
115  << "#include \"DD4hep/Volumes.h\"" << std::endl
116  << "#include \"DD4hep/Detector.h\"" << std::endl
117  << "#include \"DD4hep/DetElement.h\"" << std::endl
118  << "#include \"DD4hep/MatrixHelpers.h\"" << std::endl
119  << "#include \"DD4hep/DD4hepUnits.h\"" << std::endl
120  << "#include \"DD4hep/Printout.h\"" << std::endl
121  << "#include \"DD4hep/Path.h\"" << std::endl
122  << "#include \"DD4hep/detail/ObjectsInterna.h\"" << std::endl
123  << "#include \"DD4hep/detail/DetectorInterna.h\"" << std::endl
124  << "#include <vector>" << std::endl
125  << "#include <map>" << std::endl
126  << "#include <set>" << std::endl << std::endl << std::endl;
127  log << "using namespace std;" << std::endl;
128  log << "using namespace dd4hep;" << std::endl;
129  log << "extern PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix* transform);" << std::endl;
130 
131  log << "namespace {" << newline
132  << "\t struct CodeGeo {" << newline
133  << "\t\t map<unsigned long, TGeoNode*> placements;" << newline
134  << "\t\t map<unsigned long, TGeoVolume*> volumes;" << newline
135  << "\t\t map<unsigned long, TGeoShape*> shapes;" << newline
136  << "\t\t map<unsigned long, TGeoMatrix*> matrices;" << newline
137  << "\t\t map<unsigned long, TGeoMedium*> materials;" << newline
138  << "\t\t map<unsigned long, DetElement> structure;" << newline
139  << "\t\t Detector& detector;" << newline
140  << "\t\t CodeGeo(Detector& d) : detector(d) {}" << newline
141  << "\t\t TGeoVolume* load_geometry();" << newline
142  << "\t\t DetElement load_structure();" << newline
143  << "\t\t void add_vis(Detector& d, VisAttr& v) {" << newline
144  << "\t\t try { d.add(v); } catch(...) {}" << newline
145  << "\t\t }" << newline
146  << "\t };" << std::endl
147  << "}" << std::endl << std::endl << std::endl;
148  log << "TGeoVolume* CodeGeo::load_geometry() {" << newline;
149 
150  const auto& constants = detector.constants();
151  log << "/// Handling " << constants.size() << " Constants" << newline;
152  for(const auto& o : constants) {
153  const Constant& c = o.second;
154  log << "detector.add(Constant(\"" << c.name() << "\",\""
155  << c->type << "\",\"" << c->dataType << "\")); " << newline;
156  }
157 
158  // Copy visualization attributes and register them to the detector object
159  const auto& vis = detector.visAttributes();
160  log << "/// Handling " << vis.size() << " Visualization attributes" << newline;
161  for(const auto& o : vis) {
162  float r, g, b;
163  VisAttr v(o.second);
164  v.rgb(r,g,b);
165  log << "{ VisAttr v(\"" << o.first << "\"); "
166  << "v.setColor(" << r << sep << g << sep << b << "); "
167  << "v.setShowDaughters(" << v.showDaughters() << "); "
168  << "v.setVisible(" << v.visible() << "); " << newline
169  << " v.setLineStyle(" << v.lineStyle() << "); "
170  << "v.setDrawingStyle(" << v.drawingStyle() << "); "
171  << "v.setAlpha(" << v.alpha() << "); "
172  << "add_vis(detector,v); }" << newline;
173  }
174 
175  const auto& limits = detector.limitsets();
176  log << "/// Handling " << limits.size() << " Limit Sets" << newline;
177  for(const auto& o : limits) {
178  LimitSet ls = o.second;
179  log << "{ LimitSet ls(string(\"" << ls.name() << "\")); " << newline;
180  const std::set<Limit>& lims = ls.limits();
181  const std::set<Limit>& cuts = ls.cuts();
182  for(const auto& l : lims) {
183  log << " { Limit l; l.particles = \"" << l.particles << "\";"
184  << " l.name = \"" << l.name << "\";"
185  << " l.unit = \"" << l.unit << "\";"
186  << " l.content = \"" << l.content << "\";"
187  << " l.value = " << l.value << ";"
188  << " ls.addLimit(l); } " << newline;
189  }
190  for(const auto& l : cuts) {
191  log << " { Limit l; l.particles = \"" << l.particles << "\";"
192  << " l.name = \"" << l.name << "\";"
193  << " l.unit = \"" << l.unit << "\";"
194  << " l.content = \"" << l.content << "\";"
195  << " l.value = " << l.value << ";"
196  << " ls.addLimit(l); } " << newline;
197  }
198  log << " detector.addLimitSet(ls); } " << newline;
199  }
200 
201  const auto& regions = detector.regions();
202  log << "/// Handling " << regions.size() << " Region settings " << newline;
203  for(const auto& o : regions) {
204  Region r = o.second;
205  log << "{ Region r(\"" << r.name() << "\")"
206  << "; r->store_secondaries = " << r->store_secondaries
207  << "; r->was_threshold_set = " << r->was_threshold_set
208  << "; r->use_default_cut = " << r->use_default_cut
209  << "; r->threshold = " << r->threshold
210  << "; r->cut = " << r->cut << ";" << newline;
211  if ( !r->user_limits.empty() ) {
212  log << " vector<string> user_limits = {";
213  for(size_t i=0, n=r->user_limits.size(); i<n; ++i)
214  log << "r->user_limits.emplace_back(\"" << r->user_limits[i] << "\");" << newline;
215  }
216  }
217 
218  const auto& ids = detector.idSpecifications();
219  log << "/// Handling " << ids.size() << " Id Specifications " << newline;
220  for(const auto& o : ids) {
221  IDDescriptor i = o.second;
222  log << "{ IDDescriptor i(\"" << i.name() << "\", \"" << i->description << "\");"
223  << " detector.add(i); }" << newline;
224  }
225 
226  const auto& segments = detector.readouts();
227  log << "/// Handling " << segments.size() << " Segmentations " << newline
228  << "list<Segmentation> segs; " << newline;
229  for(const auto& o : segments) {
230  Readout r = o.second;
231  Segmentation s = r->segmentation;
232  if ( s.isValid() ) {
233  log << "{ Segmentation s(\"" << s.name() << "\");"
234  << " segs.emplace_back(s); }" << newline;
235  }
236  }
237 
238  const auto& readouts = detector.readouts();
239  log << "/// Handling " << readouts.size() << " Readout settings " << newline;
240  for(const auto& o : readouts) {
241  Readout r = o.second;
242  log << "{ Readout r(string(\"" << r.name() << "\"));"
243  << " r->SetTitle(\"" << r->GetTitle() << "\"); ";
244  if ( r->segmentation.isValid() )
245  log << " r->segmentation = segs.front(); segs.pop_front(); ";
246  if ( r->id.isValid() )
247  log << " r->id = detector.idSpecification(\"" << r->id.name() << "\"); ";
248  for(const auto& c : r->hits) {
249  log << newline;
250  log << "{ HitCollection c(\"" << c.name << "\",\"" << c.key << "\", "
251  << c.key_min << sep << c.key_max << "); "
252  << " r->hits.emplace_back(c); } ";
253  }
254  if ( !r->hits.empty() ) log << newline;
255  log << " detector.add(r); }" << newline;
256  }
257  return log;
258  }
259 
260  std::ostream& Actor::handleTrailer (std::ostream& log) {
261  log << "static long generate_dd4hep(Detector& detector, int, char**) {" << newline
262  << "CodeGeo gen(detector);" << newline
263  << "TGeoVolume* vol_top = gen.load_geometry();" << newline
264  << "detector.manager().SetTopVolume(vol_top);" << newline
265  << "detector.init();" << newline;
266  if ( dump_structure ) {
267  TGeoManager& mgr = detector.manager();
268  handleMaterial(log, mgr.GetMedium("Air"));
269  handleMaterial(log, mgr.GetMedium("Vacuum"));
270  log << "gen.structure[" << pointer(detector.world()) << "] = detector.world(); " << newline
271  << "gen.load_structure();" << newline;
272  }
273  log << "return 1;"
274  << std::endl << "}" << std::endl << std::endl
275  << "DECLARE_APPLY(DD4hep_Run_" << function << ", generate_dd4hep)"
276  << std::endl;
277  return log;
278  }
279 
280  std::ostream& Actor::handleStructure(std::ostream& log, DetElement parent, DetElement de) {
281  if ( de.isValid() && detelements.find(de) == detelements.end() ) {
282  std::string name = obj_name("de", de.ptr());
283  detelements.emplace(de,name);
284  if ( !parent.isValid() ) {
285  std::cout << "No parent: " << de.path() << " " << pointer(de) << " " << pointer(detector.world()) << std::endl;
286  log << std::endl
287  << "DetElement CodeGeo::load_structure() {" << newline;
288  }
289  else {
290  log << "{" << newline
291  << "\t DetElement par = structure[" << pointer(parent) << "];" << newline
292  << "\t DetElement de(par,\"" << de.name() << "\"," << de.id() << ");" << newline
293  << "\t de->SetTitle(\"" << de->GetTitle() << "\");" << newline
294  << "\t de->combineHits = " << de->combineHits << ";" << newline
295  << "\t de.setTypeFlag(" << de.typeFlag() << ");" << newline;
296  if ( de.placement().isValid() ) {
297  log << "\t de.setPlacement(placements[" << pointer(de.placement()) << "]);" << newline;
298  }
299  else {
300  std::cout << "Placement od DetElement " << de.path() << " Is not valid! [Ignored]" << std::endl;
301  }
302  log << "\t structure[" << pointer(de) << "] = de; " << newline
303  << "}" << newline;
304  }
305  for(const auto& d : de.children() ) {
306  handleStructure(log, de, d.second);
307  }
308  if ( !parent.isValid() ) {
309  log << "return structure[" << pointer(de) << "];" << std::endl
310  << "}" << std::endl << std::endl;
311  }
312  }
313  return log;
314  }
315 
316  std::ostream& Actor::handlePlacement(std::ostream& log, TGeoNode* parent, TGeoNode* node) {
317  if ( node && placements.find(node) == placements.end() ) {
318  PlacedVolume pv(node);
319  TGeoVolume* vol = node->GetVolume();
320  TGeoMatrix* mat = node->GetMatrix();
321 
322  std::string name = obj_name("vol", vol);
323  placements.emplace(node,name);
324 
325  handleMatrix(log, mat);
326 
327  if ( vol && volumes.find(vol) == volumes.end() ) {
328  volumes.emplace(vol,name);
329  if ( vol->IsA() == TGeoVolumeAssembly::Class() ) {
330  log << "{" << newline;
331  log << "\t Assembly vol(\"" << vol->GetName() << "\");" << newline;
332  }
333  else {
334  Volume v(vol);
335  TGeoMedium* med = vol->GetMedium();
336  TGeoShape* sh = vol->GetShape();
337  handleSolid(log, sh);
338  handleMaterial(log, med);
339  log << "{" << newline;
340  log << "\t Volume vol(\"" << vol->GetName() << "\", "
341  << "Solid(shapes[" << pointer(sh) << "]), "
342  << "Material(materials[" << pointer(med) << "]));" << newline;
343  if ( ::strlen(vol->GetTitle()) != 0 )
344  log << "\t vol->SetTitle(\"" << vol->GetTitle() << "\");" << newline;
345  if ( !v.option().empty() )
346  log << "\t vol.setOption(\"" << v.option() << "\"); " << newline;
347  if ( v.region().isValid() )
348  log << "\t vol.setRegion(detector, \"" << v.region().name() << "\");" << newline;
349  if ( v.limitSet().isValid() )
350  log << "\t vol.setLimitSet(detector, \"" << v.limitSet().name() << "\");" << newline;
351  if ( v.sensitiveDetector().isValid() )
352  log << "\t vol.setSensitiveDetector(detector.sensitiveDetector(\""
353  << v.sensitiveDetector().name() << "\"));" << newline;
354  if ( dump_vis && v.visAttributes().isValid() )
355  log << "\t vol.setVisAttributes(detector, \"" << v.visAttributes().name() << "\");" << newline;
356  }
357  log << "\t volumes[" << pointer(vol) << "] = vol;" << newline;
358  }
359  else {
360  log << "{" << newline
361  << "\t Volume vol = volumes[" << pointer(vol) << "];" << newline;
362  }
363  if ( parent ) {
364  log << "\t PlacedVolume pv = _addNode(volumes[" << pointer(parent->GetVolume())
365  << "],vol.ptr()," << pv.copyNumber() << sep
366  << "matrices[" << pointer(mat) << "]);" << newline
367  << "\t placements[" << pointer(node) << "] = pv.ptr(); " << newline;
368  for(const auto& vid : pv.volIDs() )
369  log << "\t pv.addPhysVolID(\"" << vid.first << "\", " << vid.second << ");" << newline;
370  }
371  log << "}" << newline;
372  for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
373  TGeoNode* daughter = node->GetDaughter(idau);
374  handlePlacement(log, node, daughter);
375  }
376  if ( !parent ) {
377  log << "return volumes[" << pointer(vol) << "];" << std::endl
378  << "}" << std::endl << std::endl << std::endl;
379  }
380  }
381  return log;
382  }
383 
384  std::ostream& Actor::handleMaterial(std::ostream& log, TGeoMedium* medium) {
385  if ( medium && materials.find(medium) == materials.end() ) {
386  std::string name = obj_name("material",medium);
387  materials.emplace(medium,name);
388  TGeoMaterial* material = medium->GetMaterial();
389  log << "{" << newline
390  << "\t TGeoManager& mgr = detector.manager();" << newline
391  << "\t TGeoMedium* med = mgr.GetMedium(\""<< medium->GetName() << "\");" << newline
392  << "\t if ( 0 == med ) {" << newline
393  << "\t TGeoMaterial* mat = mgr.GetMaterial(\"" << material->GetName() << "\");" << newline
394  << "\t if ( 0 == mat ) {" << newline
395  << "\t mat = new TGeoMaterial(\"" << material->GetName() << "\", "
396  << material->GetA() << sep << material->GetZ() << sep << material->GetDensity() << sep
397  << material->GetRadLen() << sep << material->GetIntLen() << ");" << newline
398  << "\t }" << newline
399  << "\t med = new TGeoMedium(\""<< medium->GetName() << "\"," << medium->GetId() << ", mat);" << newline
400  << "\t }" << newline
401  << "\t materials[" << pointer(medium) << "] = med;" << newline
402  << "}" << newline;
403  }
404  return log;
405  }
406 
407  std::ostream& Actor::handleMatrix(std::ostream& log, TGeoMatrix* mat) {
408  if ( mat && matrices.find(mat) == matrices.end() ) {
409  std::string name = obj_name("matrix",mat);
410  log << "{" << newline
411  << "\t TGeoHMatrix* mat = new TGeoHMatrix(\"" << mat->GetName() << "\");" << newline
412  << "\t matrices[" << pointer(mat) << "] = mat;" << newline;
413  if ( mat->IsTranslation() ) {
414  const Double_t* tra = mat->GetTranslation();
415  log << "\t Double_t trans[] = {";
416  for(size_t i=0; tra && i<3; ++i) {
417  log << tra[i];
418  log << ((i<2) ? sep : "};");
419  }
420  log << newline << "\t mat->SetTranslation(trans);" << newline;
421  }
422  if ( mat->IsRotation() ) {
423  const Double_t* rot = mat->GetRotationMatrix();
424  if ( rot && (rot[0] != 1e0 || rot[4] != 1e0 || rot[8] != 1e0) ) {
425  log << "\t Double_t rot[] = {";
426  for(size_t i=0; rot && i<9; ++i) {
427  log << rot[i];
428  log << ((i<8) ? sep : "};");
429  }
430  log << newline << "\t mat->SetRotation(rot);" << newline;
431  }
432  }
433  if ( mat->IsScale() ) {
434  const Double_t* sca = mat->GetScale();
435  log << "\t Double_t scale[] = {";
436  for(size_t i=0; sca && i<3; ++i) {
437  log << sca[i];
438  log << ((i<2) ? sep : "};");
439  }
440  log << newline << "\t mat->SetScale(scale);" << newline;
441  }
442  log << "}" << newline;
443  }
444  return log;
445  }
446 
448  std::ostream& Actor::handleSolid(std::ostream& log, const TGeoShape* shape) {
449  std::string name = obj_name("solid", shape);
450 
451  if ( shapes.find(shape) != shapes.end() ) {
452  return log;
453  }
454  else if (shape->IsA() == TGeoShapeAssembly::Class()) {
455  // Nothing to do here: All handled in the handling of TGeoVolumeAssembly
456  return log;
457  }
458 
459  shapes.emplace(shape,name);
460 
461  TClass* cl = shape->IsA();
462  log << "{" << newline;
463  if ( cl == TGeoBBox::Class() ) {
464  TGeoBBox* sh = (TGeoBBox*) shape;
465  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
466  << sep << sh->GetDX()
467  << sep << sh->GetDY()
468  << sep << sh->GetDZ() << "));" << newline;
469  }
470  else if (cl == TGeoHalfSpace::Class()) {
471  TGeoHalfSpace* sh = (TGeoHalfSpace*)(const_cast<TGeoShape*>(shape));
472  log << "\t Double_t* point = {"
473  << sh->GetPoint()[0] << sep << sh->GetPoint()[1] << sep << sh->GetPoint()[2] << "}; " << newline
474  << "\t Double_t* norm = {"
475  << sh->GetNorm()[0] << sep << sh->GetNorm()[1] << sep << sh->GetNorm()[2] << "}; " << newline
476  << "\t Solid " << name << " = Solid(new " << cl->GetName() << "(\""
477  << sh->GetName() << "\", point, norm));" << newline;
478  }
479  else if (cl == TGeoTube::Class()) {
480  const TGeoTube* sh = (const TGeoTube*) shape;
481  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
482  << sep << sh->GetRmin()
483  << sep << sh->GetRmax()
484  << sep << sh->GetDz()
485  << "));" << newline;
486  }
487  else if (cl == TGeoTubeSeg::Class()) {
488  const TGeoTubeSeg* sh = (const TGeoTubeSeg*) shape;
489  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
490  << sep << sh->GetRmin()
491  << sep << sh->GetRmax()
492  << sep << sh->GetDz()
493  << sep << sh->GetPhi1()
494  << sep << sh->GetPhi2()
495  << "));" << newline;
496  }
497  else if (cl == TGeoCtub::Class()) {
498  const TGeoCtub* sh = (const TGeoCtub*) shape;
499  const Double_t* hi = sh->GetNhigh();
500  const Double_t* lo = sh->GetNlow();
501  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
502  << sep << sh->GetRmin()
503  << sep << sh->GetRmax()
504  << sep << sh->GetDz()
505  << sep << sh->GetPhi1()
506  << sep << sh->GetPhi2()
507  << sep << lo[0]
508  << sep << lo[1]
509  << sep << lo[2]
510  << sep << hi[0]
511  << sep << hi[1]
512  << sep << hi[2]
513  << "));" << newline;
514  }
515  else if (cl == TGeoEltu::Class()) {
516  const TGeoEltu* sh = (const TGeoEltu*) shape;
517  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
518  << sep << sh->GetA()
519  << sep << sh->GetB()
520  << sep << sh->GetDz()
521  << "));" << newline;
522  }
523  else if (cl == TGeoTrd1::Class()) {
524  const TGeoTrd1* sh = (const TGeoTrd1*) shape;
525  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
526  << sep << sh->GetDx1()
527  << sep << sh->GetDx2()
528  << sep << sh->GetDy()
529  << sep << sh->GetDz()
530  << "));" << newline;
531  }
532  else if (cl == TGeoTrd2::Class()) {
533  const TGeoTrd2* sh = (const TGeoTrd2*) shape;
534  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
535  << sep << sh->GetDx1()
536  << sep << sh->GetDx2()
537  << sep << sh->GetDy1()
538  << sep << sh->GetDy2()
539  << sep << sh->GetDz()
540  << "));" << newline;
541  }
542  else if (cl == TGeoTrap::Class()) {
543  const TGeoTrap* sh = (const TGeoTrap*) shape;
544  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
545  << sep << sh->GetDz() << sep << sh->GetTheta() << sep << sh->GetPhi()
546  << sep << sh->GetH1() << sep << sh->GetBl1() << sep << sh->GetTl1() << sep << sh->GetAlpha1()
547  << sep << sh->GetH2() << sep << sh->GetBl2() << sep << sh->GetTl2() << sep << sh->GetAlpha2()
548  << "));" << newline;
549  }
550  else if (cl == TGeoHype::Class()) {
551  const TGeoHype* sh = (const TGeoHype*) shape;
552  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
553  << sep << sh->GetRmin() << sep << sh->GetRmax() << sep << sh->GetDz()
554  << sep << sh->GetStIn() << sep << sh->GetStOut()
555  << "));" << newline;
556  }
557  else if (cl == TGeoPgon::Class()) {
558  const TGeoPgon* sh = (const TGeoPgon*) shape;
559  log << "double params[] = {" << sh->GetPhi1() << sep << sh->GetDphi() << sep
560  << sh->GetNedges() << sep << sh->GetNz();
561  for(int i=0, n=sh->GetNz(); i<n; ++i)
562  log << sep << sh->GetZ(i) << sep << sh->GetRmin(i) << sep << sh->GetRmax(i);
563  log << "};" << newline
564  << "\t Solid " << name << " = Solid(new " << cl->GetName() << "(params));" << newline
565  << name << "->SetName(\"" << sh->GetName() << "\");" << newline;
566  }
567  else if (cl == TGeoPcon::Class()) {
568  const TGeoPcon* sh = (const TGeoPcon*) shape;
569  log << "double params[] = {" << sh->GetPhi1() << sep << sh->GetDphi() << sep << sh->GetNz();
570  for(int i=0, n=sh->GetNz(); i<n; ++i)
571  log << sep << sh->GetZ(i) << sep << sh->GetRmin(i) << sep << sh->GetRmax(i);
572  log << "};" << newline
573  << "\t Solid " << name << " = Solid(new " << cl->GetName() << "(params));" << newline
574  << name << "->SetName(\"" << sh->GetName() << "\");" << newline;
575  }
576  else if (cl == TGeoCone::Class()) {
577  const TGeoCone* sh = (const TGeoCone*) shape;
578  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
579  << sep << sh->GetDz()
580  << sep << sh->GetRmin1() << sep << sh->GetRmax1()
581  << sep << sh->GetRmin2() << sep << sh->GetRmax2()
582  << "));" << newline;
583  }
584  else if (cl == TGeoConeSeg::Class()) {
585  const TGeoConeSeg* sh = (const TGeoConeSeg*) shape;
586  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
587  << sep << sh->GetDz()
588  << sep << sh->GetRmin1() << sep << sh->GetRmax1()
589  << sep << sh->GetRmin2() << sep << sh->GetRmax2()
590  << sep << sh->GetPhi1() << sep << sh->GetPhi2()
591  << "));" << newline;
592  }
593  else if (cl == TGeoParaboloid::Class()) {
594  const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
595  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
596  << sep << sh->GetRlo() << sep << sh->GetRhi() << sep << sh->GetDz() << "));" << newline;
597  }
598  else if (cl == TGeoSphere::Class()) {
599  const TGeoSphere* sh = (const TGeoSphere*) shape;
600  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
601  << sep << sh->GetRmin() << sep << sh->GetRmax()
602  << sep << sh->GetPhi1() << sep << sh->GetPhi2()
603  << sep << sh->GetTheta1() << sep << sh->GetTheta2()
604  << "));" << newline;
605  }
606  else if (cl == TGeoTorus::Class()) {
607  const TGeoTorus* sh = (const TGeoTorus*) shape;
608  log << "\t Solid " << name << "(new " << cl->GetName() << "(\"" << sh->GetName() << '"'
609  << sep << sh->GetRmin() << sep << sh->GetRmax() << sep << sh->GetR()
610  << sep << sh->GetPhi1() << sep << sh->GetDphi()
611  << "));" << newline;
612  }
613  else if (cl == TGeoArb8::Class()) {
614  TGeoArb8* sh = (TGeoArb8*) shape;
615  const Double_t* v = sh->GetVertices();
616  log << "double vertices[] = {";
617  for(int i=0; i<8; ++i, v+=2)
618  log << v[0] << sep << v[1] << ((i<7) ? ',' : ' ');
619  log << "};" << newline
620  << "\t Solid " << name << " = Solid(new " << cl->GetName()
621  << "(\"" << sh->GetName() << "\"" << sep << sh->GetDz() << sep << "vertices);" << newline;
622  }
623  else if (cl == TGeoXtru::Class()) {
624  Solid sol(shape);
625  const TGeoXtru* sh = (const TGeoXtru*) shape;
626  std::vector<double> pars = sol.dimensions();
627  log << "double param[] = {" << newline;
628  for( size_t i=0; i < pars.size(); ++i )
629  log << pars[i] << ((i+1<pars.size()) ? ',' : ' ');
630  log << "};" << newline
631  << "\t Solid " << name << " = Solid(new " << cl->GetName() << "(param));" << newline
632  << "\t " << name << "->SetName(\"" << sh->GetName() << "\");" << newline;
633  }
634  else if (shape->IsA() == TGeoCompositeShape::Class()) {
635  const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape;
636  const TGeoBoolNode* boolean = sh->GetBoolNode();
637  const TGeoShape* left = boolean->GetLeftShape();
638  const TGeoShape* right = boolean->GetRightShape();
639  TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
640  handleSolid(log, left);
641  handleSolid(log, right);
642  handleMatrix(log, boolean->GetRightMatrix());
643  if (oper == TGeoBoolNode::kGeoSubtraction)
644  log << "\t TGeoSubtraction* boolean" << pointer(shape) << " = new TGeoSubtraction";
645  else if (oper == TGeoBoolNode::kGeoUnion)
646  log << "\t TGeoUnion* boolean" << pointer(shape) << " = new TGeoUnion";
647  else if (oper == TGeoBoolNode::kGeoIntersection)
648  log << "\t TGeoIntersection* boolean" << pointer(shape) << " = new TGeoIntersection";
649  log << "(shapes[" << pointer(left) << "], "
650  << " shapes[" << pointer(right) << "], 0, ";
651  log << " matrices[" << pointer(boolean->GetRightMatrix()) << "]);" << newline;
652  log << "\t Solid " << name << " = Solid(new TGeoCompositeShape(\""
653  << sh->GetName() << "\", boolean" << pointer(shape) << "));" << newline;
654  }
655  else {
656  except("CxxRootGenerator","++ Unknown shape transformation request: %s", shape->IsA()->GetName());
657  }
658  log << "\t shapes[" << pointer(shape) << "] = " << name << ";" << newline
659  << "}" << newline;
660  return log;
661  }
662 }
663 
664 static long generate_cxx(Detector& description, int argc, char** argv) {
665  std::string output;
666  Actor actor(description);
667 
668  for(int i=0; i<argc; ++i) {
669  char c = ::tolower(argv[i][0]);
670  if ( c == '-' ) { c = ::tolower(argv[i][1]); }
671  if ( c == '-' ) { c = ::tolower(argv[i][1]); }
672  if ( c == 'o' && i+1<argc )
673  output = argv[++i];
674  else if ( c == 'f' && i+1<argc )
675  actor.function = argv[++i];
676  else if ( c == 'v' )
677  actor.dump_vis = true;
678  else if ( c == 's' )
679  actor.dump_structure = true;
680  else {
681  std::cout <<
682  "Usage: -plugin DD4hep_CxxRootGenerator -arg [-arg] \n"
683  " -output <string> Set output file for generated code. Default: stdout \n"
684  " -help Show thi help message \n"
685  "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
686  ::exit(EINVAL);
687  }
688  }
689  std::unique_ptr<std::ofstream> out;
690  std::ostream* os = &std::cout;
691  if ( !output.empty() ) {
692  Path path(output);
693  out.reset(new std::ofstream(path.c_str()));
694  if ( !out->good() ) {
695  out.reset();
696  except("CxxRootGenerator",
697  "++ Failed to open output files: %s [%s]",
698  path.c_str(), ::strerror(errno));
699  }
700  os = out.get();
701  actor.function = path.filename();
702  if ( actor.function.rfind('.') != std::string::npos )
703  actor.function = actor.function.substr(0, actor.function.rfind('.'));
704  printout(INFO, "CxxRootGenerator",
705  "++ Dump generated code to output files: %s [function: %s()]",
706  path.c_str(), actor.function.c_str());
707  }
708  else if ( actor.function.empty() ) {
709  actor.function = "run_geometry";
710  }
711  DetElement de = description.world();
712  PlacedVolume pv = de.placement();
713  actor.handleHeader(*os);
714  actor.handlePlacement(*os, 0, pv.ptr());
715  actor.handleStructure(*os, DetElement(), de);
716  actor.handleTrailer(*os);
717  out.reset();
718  return 1;
719 }
720 
721 DECLARE_APPLY(DD4hep_CxxGenerator,generate_cxx)
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:207
dd4hep::DetElement::path
const std::string & path() const
Path of the detector element (not necessarily identical to placement path!)
Definition: DetElement.cpp:158
dd4hep::Detector::world
virtual DetElement world() const =0
Return reference to the top-most (world) detector element.
dd4hep::LimitSet::cuts
const std::set< Limit > & cuts() const
Accessor to limits container.
Definition: Objects.cpp:476
Volumes.h
v
View * v
Definition: MultiView.cpp:28
Path.h
MatrixHelpers.h
Detector.h
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:173
dd4hep::VisAttr
Handle class describing visualization attributes.
Definition: Objects.h:324
dd4hep::DetElement::placement
PlacedVolume placement() const
Access to the physical volume of this detector element.
Definition: DetElement.cpp:321
dd4hep::LimitSet::limits
const std::set< Limit > & limits() const
Accessor to limits container.
Definition: Objects.cpp:464
dd4hep::IDDescriptor
Class implementing the ID encoding of the detector response.
Definition: IDDescriptor.h:37
DECLARE_APPLY
#define DECLARE_APPLY(name, func)
Definition: Factories.h:281
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:128
dd4hep::Handle
Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects...
Definition: Handle.h:84
DetectorInterna.h
dd4hep::Solid_type< TGeoShape >
Factories.h
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::Constant::dataType
std::string dataType() const
Access the constant.
Definition: Objects.cpp:148
dd4hep::DetElement::typeFlag
unsigned int typeFlag() const
Access the type of the sensitive detector.
Definition: DetElement.cpp:108
dd4hep::Region::threshold
double threshold() const
Access production threshold.
Definition: Objects.cpp:520
dd4hep::View::name
const std::string & name() const
Access to the view name/title.
Definition: View.h:81
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::Constant
Handle class describing a constant (define) object in description.
Definition: Objects.h:209
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:378
dd4hep::LimitSet
Handle class describing a set of limits as they are used for simulation.
Definition: Objects.h:425
dd4hep::Region
Handle class describing a region as used in simulation.
Definition: Objects.h:462
Shapes.h
dd4hep::Readout::segmentation
Segmentation segmentation() const
Access segmentation structure.
Definition: Readout.cpp:134
dd4hep::DetElement::combineHits
bool combineHits() const
Getter: Combine hits attribute.
Definition: DetElement.cpp:173
dd4hep::Region::cut
double cut() const
Access cut value.
Definition: Objects.cpp:515
dd4hep::Segmentation::name
const char * name() const
Accessor: Segmentation type.
Definition: Segmentations.cpp:45
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:153
DetElement.h
ObjectsInterna.h
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
TGeoConeSeg
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:17
dd4hep::Readout
Handle to the implementation of the readout structure of a subdetector.
Definition: Readout.h:38
dd4hep::Segmentation
Handle class supporting generic Segmentations of sensitive detectors.
Definition: Segmentations.h:41
dd4hep::DetElement::id
int id() const
Get the detector identifier.
Definition: DetElement.cpp:169
DD4hepUnits.h
Printout.h
dd4hep::Path
Path handling class.
Definition: Path.h:45