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