DD4hep  1.31.0
Detector Description Toolkit for High Energy Physics
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
StandardPlugins.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 
14 // Framework include files
15 #define DD4HEP_MUST_USE_DETECTORIMP_H
17 #include <DD4hep/DetectorImp.h>
18 #include <DD4hep/Memory.h>
19 #include <DD4hep/DD4hepUI.h>
20 #include <DD4hep/Factories.h>
21 #include <DD4hep/Printout.h>
22 #include <DD4hep/DD4hepUnits.h>
23 #include <DD4hep/DetectorTools.h>
24 #include <DD4hep/PluginCreators.h>
25 #include <DD4hep/VolumeProcessor.h>
28 #include <XML/DocumentHandler.h>
29 #include <XML/XMLElements.h>
30 #include <XML/XMLTags.h>
31 
32 // ROOT includes
33 #include <TInterpreter.h>
34 #include <TGeoElement.h>
35 #include <TGeoManager.h>
36 #include <TGeoVolume.h>
37 #include <TSystem.h>
38 #include <TClass.h>
39 #include <TRint.h>
40 #include <TGDMLMatrix.h>
41 
42 // C/C++ include files
43 #include <cerrno>
44 #include <cstdlib>
45 #include <sstream>
46 
47 using namespace dd4hep;
48 using namespace dd4hep::detail;
49 
50 namespace {
51 
52  struct ProcessorArgs {
53  bool use = false;
54  int start = 0, end = 0, argc = 0, count=0;
55  std::vector<char*> argv;
56  ProcessorArgs(int ac, char** av) {
57  for(int i=0; i<ac; ++i) {
58  if ( 0 == ::strncmp(av[i],"-processor",6) ) {
59  use = true;
60  start = i;
61  }
62  if ( use ) {
63  ++argc; ++count; end = i;
64  if ( 0 == ::strncmp(av[i],"-end-processor",6) ) {
65  argv.emplace_back(av[i]);
66  return;
67  }
68  else if ( 0 == ::strncmp(av[i],"-end-plugin",4) ) { // End of current plugin
69  argv.emplace_back((char*)"-end-processor");
70  return;
71  }
72  else if ( 0 == ::strncmp(av[i],"-plugin",4) ) { // Start of next plugin
73  argv.emplace_back((char*)"-end-processor");
74  return;
75  }
76  argv.emplace_back(av[i]);
77  }
78  }
79  }
80  };
81 }
82 
84 
91 static long dummy_plugin(Detector& , int, char**) {
92  return 1;
93 }
94 DECLARE_APPLY(DD4hep_DummyPlugin,dummy_plugin)
95 
96 
104 static void* create_description_instance(const char* /* name */) {
105  return &Detector::getInstance();
106 }
107 DECLARE_CONSTRUCTOR(Detector_constructor,create_description_instance)
108 
109 
118 static long display(Detector& description, int argc, char** argv) {
119  TGeoManager& mgr = description.manager();
120  int vislevel = 6, visopt = 1;
121  std::string detector = "/world";
122  const char* opt = "ogl";
123  for( int i = 0; i < argc && argv[i]; ++i ) {
124  if ( 0 == ::strncmp("-option",argv[i],4) )
125  opt = argv[++i];
126  else if ( 0 == ::strncmp("-level",argv[i],4) )
127  vislevel = ::atol(argv[++i]);
128  else if ( 0 == ::strncmp("-visopt",argv[i],4) )
129  visopt = ::atol(argv[++i]);
130  else if ( 0 == ::strncmp("-detector",argv[i],4) )
131  detector = argv[++i];
132  else {
133  std::cout <<
134  "Usage: -plugin DD4hep_GeometryDisplay -arg [-arg] \n\n"
135  " Invoke the ROOT geometry display using the factory mechanism. \n\n"
136  " -detector <string> Top level DetElement path. Default: '/world' \n"
137  " -option <string> ROOT Draw option. Default: 'ogl' \n"
138  " -level <number> Visualization level [TGeoManager::SetVisLevel] Default: 4 \n"
139  " -visopt <number> Visualization option [TGeoManager::SetVisOption] Default: 1\n"
140  " -load Only load the geometry. Do not invoke the display \n"
141  " -help Print this help output \n"
142  " Arguments given: " << arguments(argc,argv) << std::endl << std::flush;
143  ::exit(EINVAL);
144  }
145  }
146  mgr.SetVisLevel(vislevel);
147  mgr.SetVisOption(visopt);
148  TGeoVolume* vol = mgr.GetTopVolume();
149  if ( detector != "/world" ) {
150  DetElement elt = detail::tools::findElement(description,detector);
151  if ( !elt.isValid() ) {
152  except("DD4hep_GeometryDisplay","+++ Invalid DetElement path: %s",detector.c_str());
153  }
154  if ( !elt.placement().isValid() ) {
155  except("DD4hep_GeometryDisplay","+++ Invalid DetElement placement: %s",detector.c_str());
156  }
157  vol = elt.placement().volume();
158  }
159  if ( vol ) {
160  vol->Draw(opt);
161  return 1;
162  }
163  return 0;
164 }
165 DECLARE_APPLY(DD4hep_GeometryDisplay,display)
166 
167 
175 static long run_function(Detector&, int argc, char** argv) {
176  std::string lib, func;
177  std::vector<char*> args;
178  for(int i = 0; i < argc && argv[i]; ++i) {
179  if ( 0 == ::strncmp("-library",argv[i],4) )
180  lib = argv[++i];
181  else if ( 0 == ::strncmp("-function",argv[i],4) )
182  func = argv[++i];
183  else
184  args.emplace_back(argv[i]);
185  }
186  if ( lib.empty() || func.empty() ) {
187  std::cout <<
188  "Usage: -plugin DD4hep_Function -arg [-arg] \n\n"
189  " Execute a function without arguments inside a library. \n\n"
190  " -library <string> Library to be loaded \n"
191  " -function <string> name of the entry point to be executed. \n"
192  "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
193  ::exit(EINVAL);
194  }
195  Func_t f = gSystem->DynFindSymbol("*",func.c_str());
196  int ret;
197  if ( !f ) {
198  ret = gSystem->Load(lib.c_str());
199  if ( ret != 0 ) {
200  except("DD4hep_Function","+++ Failed to load library: %s",lib.c_str());
201  }
202  f = gSystem->DynFindSymbol("*",func.c_str());
203  if ( !f ) {
204  except("DD4hep_Function","+++ Failed to find function %s in library: %s",
205  func.c_str(),lib.c_str());
206  }
207  }
208  typedef int (*call_t)(int, char**);
209  call_t ff = (call_t)f;
210  ret = (*ff)(args.size(),&args[0]);
211  return ret;
212 }
213 DECLARE_APPLY(DD4hep_Function,run_function)
214 
215 
223 static long run_interpreter(Detector& /* description */, int argc, char** argv) {
224  if ( 0 == gApplication ) {
225  std::pair<int, char**> a(argc,argv);
226  gApplication = new TRint("DD4hepRint", &a.first, a.second);
227  printout(INFO,"DD4hepRint","++ Created ROOT interpreter instance for DD4hepUI.");
228  }
229  for(int i=0; i<argc; ++i) {
230  printout(INFO,"DD4hepRint","Excecute[%d]: %s", i, argv[i]);
231  gInterpreter->ProcessLine(argv[i]);
232  }
233  if ( !gApplication->IsRunning() ) {
234  gApplication->Run();
235  }
236  return 1;
237 }
238 DECLARE_APPLY(DD4hep_Rint,run_interpreter)
239 
240 
252 static long root_ui(Detector& description, int /* argc */, char** /* argv */) {
253  char cmd[256];
254  std::snprintf(cmd, sizeof(cmd),
255  "dd4hep::detail::DD4hepUI* gDD4hepUI = new "
256  "dd4hep::detail::DD4hepUI(*(dd4hep::Detector*)%p);",
257  (void*)&description);
258  gInterpreter->ProcessLine(cmd);
259  printout(ALWAYS,"DD4hepUI",
260  "Use the ROOT interpreter variable gDD4hepUI "
261  "to interact with the detector description.");
262  return 1;
263 }
264 DECLARE_APPLY(DD4hep_InteractiveUI,root_ui)
265 
266 
275 static long root_dump_gdml_tables(Detector& description, int /* argc */, char** /* argv */) {
276  size_t num_tables = 0;
277  size_t num_elements = 0;
278  const TObjArray* c = description.manager().GetListOfGDMLMatrices();
279  TObjArrayIter arr(c);
280  printout(INFO,"Dump_GDMLTables","+++ Dumping known GDML tables from TGeoManager.");
281  for(TObject* i = arr.Next(); i; i=arr.Next()) {
282  TGDMLMatrix* gdmlMat = (TGDMLMatrix*)i;
283  num_elements += (gdmlMat->GetRows()*gdmlMat->GetCols());
284  ++num_tables;
285  gdmlMat->Print();
286  }
287  printout(INFO,"Dump_GDMLTables",
288  "+++ Successfully dumped %ld GDML tables with %ld elements.",
289  num_tables, num_elements);
290  return 1;
291 }
292 DECLARE_APPLY(DD4hep_Dump_GDMLTables,root_dump_gdml_tables)
293 
294 
303 static long root_dump_optical_surfaces(Detector& description, int /* argc */, char** /* argv */) {
304  size_t num_surfaces = 0;
305  printout(ALWAYS,"","");
306  const TObjArray* c = description.manager().GetListOfOpticalSurfaces();
307  TObjArrayIter arr(c);
308  printout(ALWAYS,"Dump_OpticalSurfaces","+++ Dumping known Optical Surfaces from TGeoManager.");
309  for(TObject* i = arr.Next(); i; i=arr.Next()) {
310  TGeoOpticalSurface* optSurt = (TGeoOpticalSurface*)i;
311  ++num_surfaces;
312  optSurt->Print();
313  }
314  printout(ALWAYS,"Dump_OpticalSurfaces",
315  "+++ Successfully dumped %ld Optical surfaces.",num_surfaces);
316  return 1;
317 }
318 DECLARE_APPLY(DD4hep_Dump_OpticalSurfaces,root_dump_optical_surfaces)
319 
320 
329 static long root_dump_skin_surfaces(Detector& description, int /* argc */, char** /* argv */) {
330  size_t num_surfaces = 0;
331  printout(ALWAYS,"","");
332  const TObjArray* c = description.manager().GetListOfSkinSurfaces();
333  TObjArrayIter arr(c);
334  printout(ALWAYS,"Dump_SkinSurfaces","+++ Dumping known Skin Surfaces from TGeoManager.");
335  for(TObject* i = arr.Next(); i; i=arr.Next()) {
336  TGeoSkinSurface* skinSurf = (TGeoSkinSurface*)i;
337  ++num_surfaces;
338  skinSurf->Print();
339  }
340  printout(ALWAYS,"Dump_SkinSurfaces",
341  "+++ Successfully dumped %ld Skin surfaces.",num_surfaces);
342  return 1;
343 }
344 DECLARE_APPLY(DD4hep_Dump_SkinSurfaces,root_dump_skin_surfaces)
345 
346 
355 static long root_dump_border_surfaces(Detector& description, int /* argc */, char** /* argv */) {
356  size_t num_surfaces = 0;
357  printout(ALWAYS,"","");
358  const TObjArray* c = description.manager().GetListOfBorderSurfaces();
359  TObjArrayIter arr(c);
360  printout(ALWAYS,"Dump_BorderSurfaces","+++ Dumping known Border Surfaces from TGeoManager.");
361  for(TObject* i = arr.Next(); i; i=arr.Next()) {
362  TGeoBorderSurface* bordSurt = (TGeoBorderSurface*)i;
363  ++num_surfaces;
364  bordSurt->Print();
365  }
366  printout(ALWAYS,"Dump_BorderSurfaces",
367  "+++ Successfully dumped %ld Border surfaces.",num_surfaces);
368  return 1;
369 }
370 DECLARE_APPLY(DD4hep_Dump_BorderSurfaces,root_dump_border_surfaces)
371 
372 
382 static long root_elements(Detector& description, int argc, char** argv) {
383  using elt_h = xml::Element;
384 
386 
391  struct ElementPrint {
393  ElementPrint() = default;
395  virtual ~ElementPrint() = default;
397  virtual void operator()(TGeoElement* elt) { elt->Print(); }
399  virtual void operator()(TGeoIsotope* iso) { iso->Print(); }
400  };
401 
403 
408  struct ElementPrintXML : public ElementPrint {
410  elt_h root;
412  ElementPrintXML(elt_h r) : root(r) {}
414  virtual ~ElementPrintXML() {}
416  virtual void operator()(TGeoElement* element) {
417  elt_h elt = root.addChild(_U(element));
418  elt.setAttr(_U(Z),element->Z());
419  elt.setAttr(_U(N),element->N());
420  elt.setAttr(_U(formula),element->GetName());
421  elt.setAttr(_U(name),element->GetName());
422  elt_h atom = elt.addChild(_U(atom));
423  atom.setAttr(_U(type),"A");
424  atom.setAttr(_U(unit),"g/mole");
425  atom.setAttr(_U(value),element->A());
426  }
428  virtual void operator()(TGeoIsotope* isotope) {
429  elt_h iso = root.addChild(_U(isotope));
430  iso.setAttr(_U(Z),isotope->GetZ());
431  iso.setAttr(_U(N),isotope->GetN());
432  iso.setAttr(_U(formula),isotope->GetName());
433  iso.setAttr(_U(name),isotope->GetName());
434  elt_h atom = iso.addChild(_U(atom));
435  atom.setAttr(_U(type),"A");
436  atom.setAttr(_U(unit),"g/mole");
437  atom.setAttr(_U(value),isotope->GetA());
438  }
439  };
440 
441  std::string type = "text", output = "";
442  for(int i=0; i<argc; ++i) {
443  if ( argv[i][0] == '-' ) {
444  char c = ::tolower(argv[i][1]);
445  if ( c == 't' && i+1<argc ) type = argv[++i];
446  else if ( c == 'o' && i+1<argc ) output = argv[++i];
447  else {
448  ::printf("DD4hep_ElementTable -opt [-opt] \n"
449  " -type <string> Output format: text or xml \n"
450  " -output <file-name> Output file specifier (xml only) \n"
451  "\n");
452  exit(EINVAL);
453  }
454  }
455  }
456 
457  xml::Document doc(0);
459  xml::Element element(0);
460  if ( type == "xml" ) {
461  const char comment[] = "\n"
462  " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
463  " ++++ Generic detector description in C++ ++++\n"
464  " ++++ dd4hep Detector description generator. ++++\n"
465  " ++++ ++++\n"
466  " ++++ Parser:"
468  " ++++\n"
469  " ++++ ++++\n"
470  " ++++ Table of elements as defined in ROOT: " ROOT_RELEASE " ++++\n"
471  " ++++ ++++\n"
472  " ++++ M.Frank CERN/LHCb ++++\n"
473  " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n ";
474  doc = docH.create("materials", comment);
475  element = doc.root();
476  }
477  dd4hep_ptr<ElementPrint> printer(element
478  ? new ElementPrintXML(element)
479  : new ElementPrint());
480  TGeoElementTable* table = description.manager().GetElementTable();
481  for(Int_t i=0, n=table->GetNelements(); i < n; ++i)
482  (*printer)(table->GetElement(i));
483 
484  for(Int_t i=0, n=table->GetNelements(); i < n; ++i) {
485  TGeoElement* elt = table->GetElement(i);
486  Int_t niso = elt->GetNisotopes();
487  if ( niso > 0 ) {
488  for(Int_t j=0; j < niso; ++j)
489  (*printer)(elt->GetIsotope(j));
490  }
491  }
492  if ( element ) {
494  dH.output(doc, output);
495  }
496  return 1;
497 }
498 DECLARE_APPLY(DD4hep_ElementTable,root_elements)
499 
500 
510 static long root_materials(Detector& description, int argc, char** argv) {
511 
512  using elt_h = xml::Element;
513 
515 
520  struct MaterialPrint {
521  public:
523  Detector& description;
524 
525  public:
527  MaterialPrint(Detector& desc) : description(desc) {}
529  virtual ~MaterialPrint() = default;
531  virtual elt_h print(TGeoMaterial* mat) {
532  const char* st = "Undefined";
533  switch( mat->GetState() ) {
534  case TGeoMaterial::kMatStateSolid: st = "solid"; break;
535  case TGeoMaterial::kMatStateLiquid: st = "liquid"; break;
536  case TGeoMaterial::kMatStateGas: st = "gas"; break;
537  case TGeoMaterial::kMatStateUndefined:
538  default: st = "Undefined"; break;
539  }
540  ::printf("%-32s %-8s\n", mat->GetName(), mat->IsMixture() ? "Mixture" : "Material");
541  ::printf(" Aeff=%7.3f Zeff=%7.4f rho=%8.3f [g/mole] radlen=%8.3g [cm] intlen=%8.3g [cm] index=%3d\n",
542  mat->GetA(), mat->GetZ(), mat->GetDensity(),
543  mat->GetRadLen(), mat->GetIntLen(), mat->GetIndex());
544  ::printf(" Temp=%.3g [Kelvin] Pressure=%.5g [hPa] state=%s\n",
545  mat->GetTemperature(), mat->GetPressure()/dd4hep::pascal/100.0, st);
546  return elt_h(0);
547  }
549  virtual void print(elt_h, TGeoElement* elt, double frac) {
550  ::printf(" %-6s Fraction: %7.3f Z=%3d A=%6.2f N=%3d Neff=%6.2f\n",
551  elt->GetName(), frac, elt->Z(), elt->A(), elt->N(), elt->Neff());
552  }
554  virtual void printProperty(elt_h, TNamed* prop, TGDMLMatrix* matrix) {
555  if ( matrix )
556  ::printf(" Property: %-20s [%ld x %ld] --> %s\n",
557  prop->GetName(), long(matrix->GetRows()), long(matrix->GetCols()), prop->GetTitle());
558  else
559  ::printf(" Property: %-20s [ERROR: NO TABLE!] --> %s\n",
560  prop->GetName(), prop->GetTitle());
561  }
562  virtual void operator()(TGeoMaterial* mat) {
563  Double_t* mix = mat->IsMixture() ? ((TGeoMixture*)mat)->GetWmixt() : 0;
564  elt_h mh = print(mat);
565  for( int n=mat->GetNelements(), i=0; i<n; ++i ) {
566  TGeoElement* elt = mat->GetElement(i);
567  print(mh, elt, mix ? mix[i] : 1);
568  }
569  TListIter mat_iter(&mat->GetProperties());
570  for( TObject* i = mat_iter.Next(); i; i=mat_iter.Next() ) {
571  printProperty(mh, (TNamed*)i, description.manager().GetGDMLMatrix(i->GetTitle()));
572  }
573  }
574  };
576 
581  struct MaterialPrintXML : public MaterialPrint {
582  elt_h root;
583  MaterialPrintXML(elt_h elt, Detector& desc) : MaterialPrint(desc), root(elt) {}
584  virtual ~MaterialPrintXML() {}
585  virtual elt_h print(TGeoMaterial* mat) {
586  elt_h elt = root.addChild(_U(material));
587  elt.setAttr(_U(name),mat->GetName());
588  if ( ::strlen(mat->GetTitle())>0 ) {
589  elt.setAttr(_U(formula),mat->GetTitle());
590  }
591  else if ( mat->GetNelements() == 1 ) {
592  elt.setAttr(_U(formula),mat->GetElement(0)->GetName());
593 #if 0
594  // We do not need this. It shall be computed by TGeo using the Geant4 formula.
595  elt_h RL = elt.addChild(_U(RL));
596  RL.setAttr(_U(type), "X0");
597  RL.setAttr(_U(value), mat->GetRadLen());
598  RL.setAttr(_U(unit), "cm");
599  elt_h NIL = elt.addChild(_U(NIL));
600  NIL.setAttr(_U(type), "lambda");
601  NIL.setAttr(_U(value), mat->GetIntLen());
602  NIL.setAttr(_U(unit), "cm");
603 #endif
604  }
605  elt_h D = elt.addChild(_U(D));
606  D.setAttr(_U(type), "density");
607  D.setAttr(_U(value), mat->GetDensity());
608  D.setAttr(_U(unit), "g/cm3");
609  if ( mat->GetTemperature() != description.stdConditions().temperature ) {
610  elt_h T = elt.addChild(_U(T));
611  T.setAttr(_U(type), "temperature");
612  T.setAttr(_U(value), mat->GetTemperature());
613  T.setAttr(_U(unit), "kelvin");
614  }
615  if ( mat->GetPressure() != description.stdConditions().pressure ) {
616  elt_h P = elt.addChild(_U(P));
617  P.setAttr(_U(type), "pressure");
618  P.setAttr(_U(value), mat->GetPressure());
619  P.setAttr(_U(unit), "pascal");
620  }
621  return elt;
622  }
623  virtual void print(elt_h mat, TGeoElement* element, double frac) {
624  elt_h elt = mat.addChild(_U(composite));
625  elt.setAttr(_U(n),frac);
626  elt.setAttr(_U(ref),element->GetName());
627  }
628  virtual void printProperty(elt_h mat, TNamed* prop, TGDMLMatrix* /* matrix */) {
629  elt_h elt = mat.addChild(_U(property));
630  elt.setAttr(_U(name),prop->GetName());
631  elt.setAttr(_U(ref), prop->GetTitle());
632  }
633  };
634 
635  std::string type = "text", output = "", name = "";
636  for(int i=0; i<argc; ++i) {
637  if ( argv[i][0] == '-' ) {
638  char c = ::tolower(argv[i][1]);
639  if ( c == 't' && i+1<argc ) type = argv[++i];
640  else if ( c == 'n' && i+1<argc ) name = argv[++i];
641  else if ( c == 'o' && i+1<argc ) output = argv[++i];
642  else {
643  ::printf("DD4hep_MaterialTable -opt [-opt] \n"
644  " -type <string> Output format: text or xml \n"
645  " -output <file-name> Output file specifier (xml only) \n"
646  "\n");
647  exit(EINVAL);
648  }
649  }
650  }
651 
652  xml::Document doc(0);
654  xml::Element element(0);
655  if ( type == "xml" ) {
656  const char comment[] = "\n"
657  " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
658  " ++++ Generic detector description in C++ ++++\n"
659  " ++++ dd4hep Detector description generator. ++++\n"
660  " ++++ ++++\n"
661  " ++++ Parser:"
663  " ++++\n"
664  " ++++ ++++\n"
665  " ++++ Table of elements as defined in ROOT: " ROOT_RELEASE " ++++\n"
666  " ++++ ++++\n"
667  " ++++ M.Frank CERN/LHCb ++++\n"
668  " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n ";
669  doc = docH.create("materials", comment);
670  element = doc.root();
671  }
672  dd4hep_ptr<MaterialPrint> printer(element
673  ? new MaterialPrintXML(element, description)
674  : new MaterialPrint(description));
675  TObject* obj = 0;
676  TList* mats = description.manager().GetListOfMaterials();
677  dd4hep_ptr<TIterator> iter(mats->MakeIterator());
678  while( (obj=iter->Next()) != 0 ) {
679  TGeoMaterial* mat = (TGeoMaterial*)obj;
680  if ( name.empty() || name == mat->GetName() )
681  (*printer)(mat);
682  }
683  if ( element ) {
685  dH.output(doc, output);
686  }
687  return 1;
688 }
689 DECLARE_APPLY(DD4hep_MaterialTable,root_materials)
690 
691 
704 static long load_compact(Detector& description, int argc, char** argv) {
705  if ( argc > 0 ) {
707  std::string input = argv[0];
708  if ( argc > 1 ) {
709  type = buildType(argv[1]);
710  printout(INFO,"CompactLoader","+++ Processing compact file: %s with flag %s",
711  input.c_str(), argv[1]);
712  description.fromCompact(input,type);
713  return 1;
714  }
715  printout(INFO,"CompactLoader","+++ Processing compact file: %s",input.c_str());
716  description.fromCompact(input);
717  return 1;
718  }
719  return 0;
720 }
721 DECLARE_APPLY(DD4hep_CompactLoader,load_compact)
722 
723 
738 static long load_xml(Detector& description, int argc, char** argv) {
739  if ( argc > 0 ) {
741  std::string input = argv[0];
742  if ( argc > 1 ) {
743  type = buildType(argv[1]);
744  printout(INFO,"XMLLoader","+++ Processing XML file: %s with flag %s",
745  input.c_str(), argv[1]);
746  description.fromXML(input, type);
747  return 1;
748  }
749  printout(INFO,"XMLLoader","+++ Processing XML file: %s",input.c_str());
750  description.fromXML(input, description.buildType());
751  return 1;
752  }
753  return 0;
754 }
755 DECLARE_APPLY(DD4hep_XMLLoader,load_xml)
756 
757 
772 static long process_xml_doc(Detector& description, int argc, char** argv) {
773  if ( argc > 0 ) {
775  DetectorImp* imp = dynamic_cast<DetectorImp*>(&description);
776  if ( imp ) {
777  xml::XmlElement* h = (xml::XmlElement*)argv[0];
778  xml::Handle_t input(h);
779  if ( input.ptr() ) {
780  if ( argc > 1 ) {
781  type = buildType(argv[1]);
782  printout(INFO,"XMLLoader","+++ Processing XML element: %s with flag %s",
783  input.tag().c_str(), argv[1]);
784  }
785  imp->processXMLElement(input, type);
786  return 1;
787  }
788  except("DD4hepXMLProcessor",
789  "++ The passed reference to the parsed XML document is invalid.");
790  }
791  }
792  return 0;
793 }
794 DECLARE_APPLY(DD4hep_XMLProcessor,process_xml_doc)
795 
796 
804 static long load_volmgr(Detector& description, int, char**) {
805  printout(INFO,"DD4hepVolumeManager","**** running plugin DD4hepVolumeManager ! " );
806  try {
807  DetectorImp* imp = dynamic_cast<DetectorImp*>(&description);
808  if ( imp ) {
809  imp->imp_loadVolumeManager();
810  printout(INFO,"VolumeManager","+++ Volume manager populated and loaded.");
811  return 1;
812  }
813  }
814  catch (const std::exception& e) {
815  except("DD4hep_VolumeManager", "Exception: %s\n %s", e.what(),
816  "dd4hep: while programming VolumeManager. Are your volIDs correct?");
817  }
818  catch (...) {
819  except("DD4hep_VolumeManager",
820  "UNKNOWN exception while programming VolumeManager. Are your volIDs correct?");
821  }
822  return 0;
823 }
824 DECLARE_APPLY(DD4hep_VolumeManager,load_volmgr)
825 DECLARE_APPLY(DD4hepVolumeManager,load_volmgr)
826 
827 
835 static long dump_geometry2root(Detector& description, int argc, char** argv) {
836  if ( argc > 0 ) {
837  std::string output;
838  for(int i = 0; i < argc && argv[i]; ++i) {
839  if ( 0 == ::strncmp("-output",argv[i],4) )
840  output = argv[++i];
841  }
842  if ( output.empty() ) {
843  std::cout <<
844  "Usage: -plugin DD4hep_Geometry2ROOT -arg [-arg] \n\n"
845  " Output DD4hep detector description object to a ROOT file. \n\n"
846  " -output <string> Output file name. \n"
847  "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
848  ::exit(EINVAL);
849  }
850  printout(INFO,"Geometry2ROOT","+++ Dump geometry to root file:%s",output.c_str());
851  //description.manager().Export(output.c_str()+1);
852  if ( DD4hepRootPersistency::save(description,output.c_str(),"Geometry") > 1 ) {
853  return 1;
854  }
855  }
856  printout(ERROR,"Geometry2ROOT","+++ No output file name given.");
857  return 0;
858 }
859 DECLARE_APPLY(DD4hep_Geometry2ROOT,dump_geometry2root)
860 
861 
869 static long load_geometryFromroot(Detector& description, int argc, char** argv) {
870  if ( argc > 0 ) {
871  std::string input = argv[0]; // <-- for backwards compatibility
872  for(int i = 0; i < argc && argv[i]; ++i) {
873  if ( 0 == ::strncmp("-input",argv[i],4) )
874  input = argv[++i];
875  }
876  if ( input.empty() ) {
877  std::cout <<
878  "Usage: DD4hep_RootLoader -arg [-arg] \n\n"
879  " Load DD4hep detector description from ROOT file to memory. \n\n"
880  " -input <string> Input file name. \n"
881  "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
882  ::exit(EINVAL);
883  }
884  printout(INFO,"DD4hepRootLoader","+++ Read geometry from root file:%s",input.c_str());
885  if ( 1 == DD4hepRootPersistency::load(description,input.c_str(),"Geometry") ) {
886  return 1;
887  }
888  }
889  printout(ERROR,"DD4hep_RootLoader","+++ No input file name given.");
890  return 0;
891 }
892 DECLARE_APPLY(DD4hep_RootLoader,load_geometryFromroot)
893 
894 
902 static long dump_geometry2tgeo(Detector& description, int argc, char** argv) {
903  if ( argc > 0 ) {
904  std::string output( argc == 1 ? argv[0] : "" );
905  printout(INFO,"Geometry2TGeo","+++ output: %d %s", argc, output.c_str());
906  for(int i = 0; i < argc && argv[i]; ++i) {
907  if ( 0 == ::strncmp("-output",argv[i],4) )
908  output = argv[++i];
909  }
910  if ( output.empty() ) {
911  std::cout <<
912  "Usage: -plugin <name> -arg [-arg] \n"
913  " Output TGeo information to a ROOT file. \n\n"
914  " name: factory name DD4hepGeometry2TGeo \n"
915  " -output <string> Output file name. \n"
916  "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
917  ::exit(EINVAL);
918  }
919  printout(INFO,"Geometry2TGeo","+++ Dump geometry to root file:%s",output.c_str());
920  if ( description.manager().Export(output.c_str()) > 1 ) {
921  return 1;
922  }
923  }
924  printout(ERROR,"Geometry2TGeo","+++ No output file name given.");
925  return 0;
926 }
927 DECLARE_APPLY(DD4hep_Geometry2TGeo,dump_geometry2tgeo)
928 DECLARE_APPLY(DD4hepGeometry2TGeo,dump_geometry2tgeo)
929 
930 
938 static long check_detectors(Detector& description, int /* argc */, char** /* argv */) {
939  DD4hepRootCheck check(&description);
940  auto ret = check.checkDetectors();
941  return ret.first > 0 && ret.second == 0 ? 1 : 0;
942 }
943 DECLARE_APPLY(DD4hep_CheckDetectors,check_detectors)
944 
945 
953 static long check_sensitives(Detector& description, int /* argc */, char** /* argv */) {
954  DD4hepRootCheck check(&description);
955  auto ret = check.checkSensitives();
956  return ret.first > 0 && ret.second == 0 ? 1 : 0;
957 }
958 DECLARE_APPLY(DD4hep_CheckSensitives,check_sensitives)
959 
960 
968 static long check_segmentations(Detector& description, int /* argc */, char** /* argv */) {
969  DD4hepRootCheck check(&description);
970  auto ret = check.checkSegmentations();
971  return ret.first > 0 && ret.second == 0 ? 1 : 0;
972 }
973 DECLARE_APPLY(DD4hep_CheckSegmentations,check_segmentations)
974 
975 
983 static long check_readouts(Detector& description, int /* argc */, char** /* argv */) {
984  DD4hepRootCheck check(&description);
985  auto ret = check.checkReadouts();
986  return ret.first > 0 && ret.second == 0 ? 1 : 0;
987 }
988 DECLARE_APPLY(DD4hep_CheckReadouts,check_readouts)
989 
990 
998 static long check_idspecs(Detector& description, int /* argc */, char** /* argv */) {
999  DD4hepRootCheck check(&description);
1000  auto ret = check.checkIdSpecs();
1001  return ret.first > 0 && ret.second == 0 ? 1 : 0;
1002 }
1003 DECLARE_APPLY(DD4hep_CheckIdspecs,check_idspecs)
1004 
1005 
1013 static long check_volumemanager(Detector& description, int /* argc */, char** /* argv */) {
1014  DD4hepRootCheck check(&description);
1015  auto ret = check.checkVolManager();
1016  return ret.first > 0 && ret.second == 0 ? 1 : 0;
1017 }
1018 DECLARE_APPLY(DD4hep_CheckVolumeManager,check_volumemanager)
1019 
1020 
1028 static long check_nominals(Detector& description, int /* argc */, char** /* argv */) {
1029  DD4hepRootCheck check(&description);
1030  auto ret = check.checkNominals();
1031  return ret.first > 0 && ret.second == 0 ? 1 : 0;
1032 }
1033 DECLARE_APPLY(DD4hep_CheckNominals,check_nominals)
1034 
1035 
1043 static long dump_volume_tree(Detector& description, int argc, char** argv) {
1044  struct Actor {
1045  Detector& description;
1046  bool m_printPathes = false;
1047  bool m_printVolIDs = false;
1048  bool m_printShapes = false;
1049  bool m_printPointers = false;
1050  bool m_printPositions = false;
1051  bool m_printVis = false;
1052  bool m_printMaterials = false;
1053  bool m_printSensitivesOnly = false;
1054  long m_printMaxLevel = 999999;
1055  long m_numNodes = 0;
1056  long m_numShapes = 0;
1057  long m_numSensitive = 0;
1058  long m_numMaterial = 0;
1059  long m_numMaterialERR = 0;
1060  bool m_topStat = false;
1061  std::string m_detector;
1062  std::string currTop;
1063  std::map<std::string,long> top_counts;
1064 
1065  Actor(Detector& desc, int ac, char** av) : description(desc) {
1066  m_detector = "/world";
1067  for(int i=0; i<ac; ++i) {
1068  char c = ::tolower(av[i][0]);
1069  char* p = av[i];
1070  if ( c == '-' ) { ++p; c = ::tolower(av[i][1]); }
1071  if ( c == '-' ) { ++p; c = ::tolower(av[i][1]); }
1072  if ( ::strncmp(p,"volume_ids",3) == 0 ) m_printVolIDs = true;
1073  else if ( ::strncmp(p,"level",3) == 0 ) m_printMaxLevel = ::atol(av[++i]);
1074  else if ( ::strncmp(p,"materials",3) == 0 ) m_printMaterials = true;
1075  else if ( ::strncmp(p,"pathes",3) == 0 ) m_printPathes = true;
1076  else if ( ::strncmp(p,"positions",3) == 0 ) m_printPositions = true;
1077  else if ( ::strncmp(p,"pointers",3) == 0 ) m_printPointers = true;
1078  else if ( ::strncmp(p,"shapes",3) == 0 ) m_printShapes = true;
1079  else if ( ::strncmp(p,"sensitive",3) == 0 ) m_printSensitivesOnly = true;
1080  else if ( ::strncmp(p,"topstats",3) == 0 ) m_topStat = true;
1081  else if ( ::strncmp(p,"vis",3) == 0 ) m_printVis = true;
1082  else if ( ::strncmp(p,"detector",3) == 0 ) m_detector = av[++i];
1083  else if ( ::strncmp(p,"help",3) == 0 ) {
1084  std::cout <<
1085  "Usage: -plugin <name> -arg [-arg] \n"
1086  " -detector <string> Top level DetElement path. Default: '/world' \n"
1087  " -pathes Print DetElement pathes \n"
1088  " -level <number> Maximal depth to be explored by the scan \n"
1089  " -positions Print placement positions \n"
1090  " -volume_ids Print placement volume IDs \n"
1091  " -materials Print volume materials \n"
1092  " -pointers Debug: Print pointer values \n"
1093  " -shapes Print shape information \n"
1094  " -vis Print visualisation attribute name(s) if present \n"
1095  " -sensitive Only print information for sensitive volumes \n"
1096  " -topstats Print statistics about top level node \n"
1097  "\tArguments given: " << arguments(ac,av) << std::endl << std::flush;
1098  _exit(0);
1099  }
1100  }
1101  if ( m_printMaxLevel < 999999 )
1102  printout(ALWAYS,"VolumeDump","+++ Maximal print level: %ld",m_printMaxLevel);
1103  if ( !m_detector.empty() )
1104  printout(ALWAYS,"VolumeDump","+++ Subdetector path: %s",m_detector.c_str());
1105  printout(ALWAYS,"VolumeDump","+++ Printing positions: %s",yes_no(m_printPositions));
1106  printout(ALWAYS,"VolumeDump","+++ Printing shapes: %s",yes_no(m_printShapes));
1107  printout(ALWAYS,"VolumeDump","+++ Printing materials: %s",yes_no(m_printMaterials));
1108  printout(ALWAYS,"VolumeDump","+++ Printing volume ids: %s",yes_no(m_printVolIDs));
1109  printout(ALWAYS,"VolumeDump","+++ Printing visattrs: %s",yes_no(m_printVis));
1110  printout(ALWAYS,"VolumeDump","+++ Print only sensitives: %s",yes_no(m_printSensitivesOnly));
1111  }
1112  ~Actor() {
1113  printout(ALWAYS,"VolumeDump",
1114  "+++ Checked %ld physical volume placements. %3ld are sensitive.",
1115  m_numNodes, m_numSensitive);
1116  if ( m_printMaterials ) {
1117  printout(ALWAYS,"VolumeDump",
1118  "+++ Checked %ld materials in volume placements. %3ld are BAD.",
1119  m_numMaterial, m_numMaterialERR);
1120  }
1121  if ( m_printShapes ) {
1122  printout(ALWAYS,"VolumeDump","+++ Checked %ld shapes.", m_numShapes);
1123  }
1124  if ( m_topStat ) {
1125  for(const auto& t : top_counts) {
1126  if ( t.second > 1 )
1127  printout(ALWAYS,"VolumeDump",
1128  "+++ Top node: %-32s %8ld placements.",t.first.c_str(),t.second);
1129  }
1130  }
1131  }
1132 
1133  long dump(std::string prefix, TGeoNode* ideal, TGeoNode* aligned, int level, PlacedVolume::VolIDs volids) {
1134  char fmt[128];
1135  std::stringstream log;
1136  PlacedVolume pv(ideal);
1137  bool sensitive = false;
1138  std::string opt_info, pref = std::move(prefix);
1139 
1140  if ( level >= m_printMaxLevel ) {
1141  return 1;
1142  }
1143  ++m_numNodes;
1144  if ( level == 0 )
1145  currTop = "";
1146  else if ( level == 1 ) {
1147  currTop = ideal->GetVolume()->GetName();
1148  ++top_counts[currTop];
1149  }
1150  else if ( level > 1 ) {
1151  ++top_counts[currTop];
1152  }
1153 
1154  if ( m_printPathes ) {
1155  pref += "/";
1156  pref += aligned->GetName();
1157  }
1159  TGeoVolume* mother = ideal ? ideal->GetMotherVolume() : nullptr;
1160  if ( m_printPositions || m_printVolIDs ) {
1161  if ( m_printPointers ) {
1162  if ( ideal != aligned )
1163  std::snprintf(fmt,sizeof(fmt),"Ideal:%p Aligned:%p ",
1164  (void*)ideal,(void*)aligned);
1165  else
1166  std::snprintf(fmt,sizeof(fmt),"Ideal:%p MotherVol:%p",
1167  (void*)ideal, (void*)mother);
1168  log << fmt;
1169  }
1170  // Top level volume! have no volume ids
1171  if ( m_printVolIDs && ideal && ideal->GetMotherVolume() ) {
1172  PlacedVolume::VolIDs vid = pv.volIDs();
1173  if ( !vid.empty() ) {
1174  sensitive = true;
1175  log << " VolID: ";
1176  volids.insert(volids.end(),vid.begin(),vid.end());
1177  for( const auto& i : volids ) {
1178  std::snprintf(fmt, sizeof(fmt), "%s:%2d ",i.first.c_str(),i.second);
1179  log << fmt;
1180  }
1181  if ( !vid.empty() || pv.volume().isSensitive() ) {
1182  SensitiveDetector sd = pv.volume().sensitiveDetector();
1183  if ( sd.isValid() ) {
1184  IDDescriptor dsc = sd.readout().idSpec();
1185  if ( dsc.isValid() ) {
1186  log << std::hex << " (0x" << std::setfill('0') << std::setw(8)
1187  << dsc.encode(volids)
1188  << std::setfill(' ') << std::dec << ") ";
1189  }
1190  }
1191  }
1192  }
1193  }
1194  opt_info = log.str();
1195  log.str("");
1196  }
1198  if ( m_printVis && pv.volume().visAttributes().isValid() ) {
1199  log << " Vis:" << pv.volume().visAttributes().name();
1200  opt_info += log.str();
1201  log.str("");
1202  }
1203  TGeoVolume* volume = ideal ? ideal->GetVolume() : 0;
1204  if ( !m_printSensitivesOnly || (m_printSensitivesOnly && sensitive) ) {
1205  Volume vol = pv.volume();
1206  char sens = vol.isSensitive() ? 'S' : ' ';
1207  if ( m_printPointers ) {
1208  if ( ideal == aligned ) {
1209  std::snprintf(fmt,sizeof(fmt),"%03d %%s [Ideal:%p Vol:%p MotherVol:%p] %%-%ds %%-16s Vol:%%s shape:%%s \t %c %%s",
1210  level+1,(void*)ideal,(void*)vol, (void*)mother, 2*level+1, sens);
1211  }
1212  else {
1213  std::snprintf(fmt,sizeof(fmt),"%03d %%s Ideal:%p Aligned:%p %%-%ds %%-16s Vol:%%s shape:%%s %c %%s",
1214  level+1,(void*)ideal,(void*)aligned,2*level+1,sens);
1215  }
1216  }
1217  else {
1218  if ( ideal == aligned ) {
1219  std::snprintf(fmt,sizeof(fmt),"%03d %%s %%-%ds %%-16s Vol:%%s shape:%%s \t %c %%s",
1220  level+1,2*level+1,sens);
1221  }
1222  else {
1223  std::snprintf(fmt,sizeof(fmt),"%03d %%s Ideal:%p Aligned:%p %%-%ds %%-16s Vol:%%s shape:%%s %c %%s",
1224  level+1,(void*)ideal,(void*)aligned,2*level+1,sens);
1225  }
1226  }
1227  const auto* sh = volume ? volume->GetShape() : nullptr;
1228  printout(INFO,"VolumeDump",fmt,pref.c_str(),"",
1229  aligned->GetName(),
1230  vol.name(),
1231  sh ? sh->IsA()->GetName() : "[Invalid Shape]",
1232  opt_info.c_str());
1233  if ( sens == 'S' ) ++m_numSensitive;
1234  }
1235  if ( m_printMaterials ) {
1236  Volume vol = pv.volume();
1237  Material mat = vol.material();
1238  TGeoMaterial* mptr = mat->GetMaterial();
1239  bool ok = mat.A() == mptr->GetA() && mat.Z() == mptr->GetZ();
1240  std::snprintf(fmt,sizeof(fmt),"%03d %%s %%-%ds Material: %%-16s A:%%6.2f %%6.2f Z:%%6.2f %%6.2f",
1241  level+1,2*level+1);
1242  ++m_numMaterial;
1243  if ( !ok ) ++m_numMaterialERR;
1244  printout(ok ? INFO : ERROR, "VolumeDump", fmt,
1245  " ->", "", mat.name(), mat.A(), mptr->GetA(), mat.Z(), mptr->GetZ());
1246  }
1247  log.str("");
1248  if ( m_printShapes ) {
1249  log << "Shape: " << toStringSolid(pv.volume().solid()) << " \t";
1250  }
1251  if ( m_printPositions ) {
1252  if ( ideal ) {
1253  const double* trans = ideal->GetMatrix()->GetTranslation();
1254  std::snprintf(fmt, sizeof(fmt), "Pos: (%f,%f,%f) ",trans[0],trans[1],trans[2]);
1255  }
1256  else {
1257  std::snprintf(fmt, sizeof(fmt), " <ERROR: INVALID Translation matrix> ");
1258  }
1259  log << fmt << " \t";
1260  }
1261  if ( !log.str().empty() ) {
1262  std::snprintf(fmt,sizeof(fmt),"%03d %%s %%-%ds %%s",level+1,2*level+1);
1263  printout(INFO, "VolumeDump", fmt, " ->", "", log.str().c_str());
1264  }
1265  for (Int_t idau = 0, ndau = aligned->GetNdaughters(); idau < ndau; ++idau) {
1266  if ( ideal ) {
1267  TGeoNode* ideal_daughter = ideal->GetDaughter(idau);
1268  const char* daughter_name = ideal_daughter->GetName();
1269  TGeoNode* aligned_daughter = volume->GetNode(daughter_name);
1270  dump(pref, ideal_daughter, aligned_daughter, level+1, volids);
1271  }
1272  else {
1273  printout(ERROR,"VolumeDump"," <ERROR: INVALID IDEAL Translation matrix>: %s",aligned->GetName());
1274  }
1275  }
1276  return 1;
1277  }
1279  int operator()() {
1280  PlacedVolume pv;
1281  DetElement top = description.world();
1283 
1284  if ( m_detector != "/world" ) {
1285  top = detail::tools::findElement(description,m_detector);
1286  if ( !top.isValid() ) {
1287  except("VolumeDump","+++ Invalid DetElement path: %s",m_detector.c_str());
1288  }
1289  }
1290  if ( !top.placement().isValid() ) {
1291  except("VolumeDump","+++ Invalid DetElement placement: %s",m_detector.c_str());
1292  }
1293  std::string place = top.placementPath();
1294  detail::tools::placementPath(top, path);
1295  pv = detail::tools::findNode(description.world().placement(),place);
1296  if ( !pv.isValid() ) {
1297  except("VolumeDump","+++ Invalid placement verification for placement:%s",place.c_str());
1298  }
1299  return this->dump("", top.placement().ptr(), pv.ptr(), 0, PlacedVolume::VolIDs());
1300  }
1301  };
1302  Actor actor(description, argc, argv);
1303  return actor();
1304 }
1305 DECLARE_APPLY(DD4hep_VolumeDump,dump_volume_tree)
1306 
1307 // ======================================================================================
1309 
1320 static int detelement_processor(Detector& description, int argc, char** argv) {
1321  bool recursive = true;
1322  ProcessorArgs args(argc, argv);
1323  DetElement det = description.world();
1324  std::unique_ptr<DetectorProcessor>
1325  proc(dd4hep::createProcessor<DetectorProcessor>(description, args.argc, &args.argv[0]));
1326 
1327  for(int i=0; i<argc; ++i) {
1328  if ( i >= args.start && i <= args.end )
1329  continue;
1330  else if ( 0 == ::strncmp(argv[i],"-recursive",4) )
1331  recursive = true;
1332  else if ( 0 == ::strncmp(argv[i],"-no-recursive",7) )
1333  recursive = false;
1334  else if ( 0 == ::strncmp(argv[i],"-detector",4) ) {
1335  std::string path = argv[++i];
1336  det = detail::tools::findElement(description, path);
1337  if ( det.isValid() ) {
1338  continue;
1339  }
1340  except("DetElementProcessor",
1341  "++ The detector element path:%s is not part of this description!",
1342  path.c_str());
1343  }
1344  else {
1345  except("DetElementProcessor","++ Unknown plugin argument: %s",argv[i]);
1346  }
1347  }
1348  return DetectorScanner().scan(*proc, det, 0, recursive) > 0 ? 1 : 0;
1349 }
1350 DECLARE_APPLY(DD4hep_DetElementProcessor,detelement_processor)
1351 
1352 // ======================================================================================
1354 
1365 static int placed_volume_processor(Detector& description, int argc, char** argv) {
1366  bool recursive = true;
1367  PlacedVolume pv = description.world().placement();
1368  ProcessorArgs args(argc, argv);
1369  std::unique_ptr<PlacedVolumeProcessor>
1370  proc(dd4hep::createProcessor<PlacedVolumeProcessor>(description, args.argc, &args.argv[0]));
1371 
1372  std::string path = "/world";
1373  for(int i=0; i<argc; ++i) {
1374  if ( i >= args.start && i <= args.end )
1375  continue;
1376  else if ( 0 == ::strncmp(argv[i],"-recursive",4) )
1377  recursive = true;
1378  else if ( 0 == ::strncmp(argv[i],"--recursive",5) )
1379  recursive = true;
1380  else if ( 0 == ::strncmp(argv[i],"-no-recursive",7) )
1381  recursive = false;
1382  else if ( 0 == ::strncmp(argv[i],"--no-recursive",8) )
1383  recursive = false;
1384  else if ( 0 == ::strncmp(argv[i],"-detector",4) )
1385  path = argv[++i];
1386  else if ( 0 == ::strncmp(argv[i],"--detector",5) )
1387  path = argv[++i];
1388  else
1389  except("PlacedVolumeProcessor","++ Unknown plugin argument: %s",argv[i]);
1390  }
1391  DetElement det = detail::tools::findElement(description, path);
1392  if ( det.isValid() ) {
1393  pv = det.placement();
1394  if ( pv.isValid() ) {
1395  return PlacedVolumeScanner().scanPlacements(*proc, pv, 0, recursive) > 0 ? 1 : 0;
1396  }
1397  except("PlacedVolumeProcessor",
1398  "++ The detector element with path:%s has no valid placement!",
1399  path.c_str());
1400  }
1401  except("PlacedVolumeProcessor",
1402  "++ The detector element path:%s is not part of this description!",
1403  path.c_str());
1404  return 0;
1405 }
1406 DECLARE_APPLY(DD4hep_PlacedVolumeProcessor,placed_volume_processor)
1407 
1408 
1416 template <int flag> long dump_detelement_tree(Detector& description, int argc, char** argv) {
1417  using VolIDs = PlacedVolume::VolIDs;
1419  struct Actor {
1420  Detector& descr;
1421  std::string path { };
1422  DetElement det_world { };
1423  long count = 0;
1424  int have_match = -1;
1425  int analysis_level = 999999;
1426  bool dump_materials = false;
1427  bool dump_shapes = false;
1428  bool dump_positions = false;
1429  bool dump_volids = false;
1430  bool sensitive_only = false;
1431 
1433  Actor(Detector& det) : descr(det) {
1434  det_world = descr.world();
1435  }
1437  ~Actor() {
1438  printout(ALWAYS,"DetectorDump", "+++ Scanned a total of %ld elements.",count);
1439  }
1440  void parse_args(int ac, char** av) {
1441  for(int i=0; i<ac; ++i) {
1442  if ( ::strncmp(av[i],"--sensitive", 5)==0 ) { sensitive_only = true; }
1443  else if ( ::strncmp(av[i], "-sensitive", 5)==0 ) { sensitive_only = true; }
1444  else if ( ::strncmp(av[i], "--no-sensitive", 8)==0 ) { sensitive_only = false; }
1445  else if ( ::strncmp(av[i], "-materials", 4)==0 ) { dump_materials = true; }
1446  else if ( ::strncmp(av[i], "--materials", 5)==0 ) { dump_materials = true; }
1447  else if ( ::strncmp(av[i], "-shapes", 4)==0 ) { dump_shapes = true; }
1448  else if ( ::strncmp(av[i], "--shapes", 5)==0 ) { dump_shapes = true; }
1449  else if ( ::strncmp(av[i], "-positions", 4)==0 ) { dump_positions = true; }
1450  else if ( ::strncmp(av[i], "--positions", 5)==0 ) { dump_positions = true; }
1451  else if ( ::strncmp(av[i], "-no-sensitive", 7)==0 ) { sensitive_only = false; }
1452  else if ( ::strncmp(av[i], "--volids", 5)==0 ) { dump_volids = true; }
1453  else if ( ::strncmp(av[i], "-volids", 5)==0 ) { dump_volids = true; }
1454  else if ( ::strncmp(av[i], "--detector", 5)==0 ) { path = av[++i]; }
1455  else if ( ::strncmp(av[i], "-detector", 5)==0 ) { path = av[++i]; }
1456  else if ( ::strncmp(av[i], "--level", 5)==0 ) { analysis_level = ::atol(av[++i]); }
1457  else if ( ::strncmp(av[i], "-level", 5)==0 ) { analysis_level = ::atol(av[++i]); }
1458  else {
1459  std::cout << " "
1460  << (flag==0 ? "DD4hep_DetectorDump" : "DD4hep_DetectorVolumeDump") << " -arg [-arg] \n\n"
1461  << " Dump " << (flag==0 ? "DetElement" : "Detector volume") << " tree. \n"
1462  << " Configure produced output information using the following options: \n\n"
1463  " --sensitive Process only sensitive volumes. \n"
1464  " -sensitive dto. \n"
1465  " --no-sensitive Invert sensitive only flag. \n"
1466  " -no-sensitive dto. \n"
1467  " --shapes Print shape information. \n"
1468  " -shapes dto. \n"
1469  " --positions Print position information. \n"
1470  " -positions dto. \n"
1471  " --materials Print material information. \n"
1472  " -materials dto. \n"
1473  " --detector <path> Process elements only if <path> is part of the DetElement path.\n"
1474  " -detector <path> dto. \n"
1475  " -level <number> Maximal depth to be explored by the scan \n"
1476  " --level <number> dto. \n"
1477  " -volids Print volume identifiers of placements. \n"
1478  " --volids dto. \n"
1479  "\tArguments given: " << arguments(ac,av) << std::endl << std::flush;
1480  ::exit(EINVAL);
1481  }
1482  }
1483  }
1484  IDDescriptor get_id_descriptor(PlacedVolume pv) {
1485  if ( pv.isValid() ) {
1486  Volume v = pv.volume();
1487  SensitiveDetector sd = v.sensitiveDetector();
1488  if ( sd.isValid() ) {
1489  IDDescriptor dsc = sd.readout().idSpec();
1490  if ( dsc.isValid() ) return dsc;
1491  }
1492  for (Int_t idau = 0, ndau = v->GetNdaughters(); idau < ndau; ++idau) {
1493  IDDescriptor dsc = get_id_descriptor(v->GetNode(idau));
1494  if ( dsc.isValid() ) return dsc;
1495  }
1496  }
1497  return IDDescriptor();
1498  }
1499  void validate_id_descriptor(DetElement de, IDDescriptor& desc) {
1500  desc = (!de.parent() || de.parent() == det_world)
1501  ? IDDescriptor() : get_id_descriptor(de.placement());
1502  }
1503 
1504  long dump(DetElement de, int level, IDDescriptor& id_desc, VolIDs chain) {
1505  char fmt[256];
1506  PlacedVolume place = de.placement();
1507  const DetElement::Children& children = de.children();
1508  bool use_elt = path.empty() || de.path().find(path) != std::string::npos;
1509 
1510  if ( have_match < 0 && use_elt ) {
1511  have_match = level;
1512  }
1513 
1514  use_elt &= ((level-have_match) <= analysis_level);
1515  if ( !place.isValid() ) {
1516  std::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s DetElement with INVALID PLACEMENT!", level+1, 2*level+1);
1517  printout(ERROR,"DetectorDump", fmt, "", de.path().c_str());
1518  use_elt = false;
1519  }
1520 
1521  if ( place.isValid() && de != det_world ) {
1522  chain.insert(chain.end(), place.volIDs().begin(), place.volIDs().end());
1523  }
1524  if ( use_elt ) {
1525  if ( !sensitive_only || 0 != de.volumeID() ) {
1526  char sens = place.isValid() && place.volume().isSensitive() ? 'S' : ' ';
1527  switch( flag ) {
1528  case 0:
1529  ++count;
1530  if ( de.placement() == de.idealPlacement() ) {
1531  std::snprintf(fmt, sizeof(fmt), "%03d %%-%ds %%s NumDau:%%d VolID:%%08X Place:%%p %%c", level+1, 2*level+1);
1532  printout(INFO, "DetectorDump", fmt, "", de.path().c_str(), int(children.size()),
1533  (unsigned long)de.volumeID(), (void*)place.ptr(), sens);
1534  break;
1535  }
1536  std::snprintf(fmt, sizeof(fmt), "%03d %%-%ds %%s NumDau:%%d VolID:%%08X Place:%%p [ideal:%%p aligned:%%p] %%c",
1537  level+1, 2*level+1);
1538  printout(INFO, "DetectorDump", fmt, "", de.path().c_str(), int(children.size()),
1539  (unsigned long)de.volumeID(), (void*)de.idealPlacement().ptr(),
1540  (void*)place.ptr(), sens);
1541  break;
1542  case 1:
1543  ++count;
1544  std::snprintf(fmt, sizeof(fmt), "%03d %%-%ds Detector: %%s NumDau:%%d VolID:%%p", level+1, 2*level+1);
1545  printout(INFO, "DetectorDump", fmt, "", de.path().c_str(), int(children.size()), (void*)de.volumeID());
1546  if ( de.placement() == de.idealPlacement() ) {
1547  std::snprintf(fmt, sizeof(fmt), "%03d %%-%ds Placement: %%s %%c", level+1, 2*level+3);
1548  printout(INFO,"DetectorDump",fmt,"", de.placementPath().c_str(), sens);
1549  break;
1550  }
1551  std::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Placement: %%s [ideal:%%p aligned:%%p] %%c",
1552  level+1,2*level+3);
1553  printout(INFO,"DetectorDump",fmt,"", de.placementPath().c_str(),
1554  (void*)de.idealPlacement().ptr(), (void*)place.ptr(), sens);
1555  break;
1556  default:
1557  break;
1558  }
1559  if ( (dump_materials || dump_shapes) && place.isValid() ) {
1560  Volume vol = place.volume();
1561  Material mat = vol.material();
1562  std::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Material: %%-12s Shape: %%s", level+1,2*level+3);
1563  printout(INFO,"DetectorDump",fmt,"", mat.name(), toStringSolid(vol->GetShape()).c_str());
1564  }
1565  if ( dump_positions && place.isValid() ) {
1566  Position pos = place.position();
1567  Box box = place.volume().solid();
1568  double loc[3] = {0,0,0}, world[3] = {0,0,0};
1569  TGeoHMatrix tr = de.nominal().worldTransformation();
1570  tr.LocalToMaster(loc, world);
1571  std::snprintf(fmt,sizeof(fmt), "%03d %%-%ds BBox: (%%9.4f,%%9.4f,%%9.4f) [cm]", level+1,2*level+3);
1572  printout(INFO,"DetectorDump",fmt,"", box.x(), box.y(), box.z());
1573  std::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Position: (%%9.4f,%%9.4f,%%9.4f) [cm] w/r to mother", level+1,2*level+3);
1574  printout(INFO,"DetectorDump",fmt,"", pos.X(), pos.Y(), pos.Z());
1575  std::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Position: (%%9.4f,%%9.4f,%%9.4f) [cm] w/r to world", level+1,2*level+3);
1576  printout(INFO,"DetectorDump",fmt,"", world[0], world[1], world[2]);
1577  }
1578  if ( dump_volids && !place.volIDs().empty() ) {
1579  std::stringstream log;
1580  log << " VID:";
1581  for( const auto& i : chain )
1582  log << " " << i.first << ':' << std::dec << std::setw(2) << i.second;
1583  if ( id_desc.isValid() ) {
1584  log << " (encoded:0x" << std::setfill('0') << std::setw(8) << std::hex
1585  << id_desc.encode(chain)
1586  << std::setfill(' ') << std::dec << ") ";
1587  }
1588  std::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s", level+1, 2*level+1);
1589  printout(INFO,"DetectorDump", fmt, "", log.str().c_str());
1590  }
1591  }
1592  }
1593  for ( const auto& c : children ) {
1594  validate_id_descriptor(c.second, id_desc);
1595  dump(c.second, level+1, id_desc, chain);
1596  }
1597  return 1;
1598  }
1599  };
1600  VolIDs chain;
1601  IDDescriptor id_descriptor;
1602  Actor actor(description);
1603  actor.parse_args(argc, argv);
1604  return actor.dump(description.world(), 0, id_descriptor, std::move(chain));
1605 }
1606 DECLARE_APPLY(DD4hep_DetectorDump,dump_detelement_tree<0>)
1607 DECLARE_APPLY(DD4hep_DetectorVolumeDump,dump_detelement_tree<1>)
1608 
1609 
1617 static long detelement_cache(Detector& description, int argc, char** argv) {
1618  struct Actor {
1619  long cache(DetElement de) {
1620  const DetElement::Children& c = de.children();
1623  de.placementPath();
1624  de.path();
1625  for( const auto& i : c ) cache(i.second);
1626  return 1;
1627  }
1628  } actor;
1629  std::string detector = "/world";
1630  for(int i = 0; i < argc && argv[i]; ++i) {
1631  if ( 0 == ::strncmp("-detector",argv[i],4) )
1632  detector = argv[++i];
1633  else if ( 0 == ::strncmp("--detector",argv[i],5) )
1634  detector = argv[++i];
1635  else {
1636  std::cout <<
1637  "Usage: -plugin DD4hep_DetElementCache -arg [-arg] \n\n"
1638  " Fill cache with transformation information in DetElements. \n\n"
1639  " -detector <string> Top level DetElement path. Default: '/world'\n"
1640  " --detector <string> dto. \n"
1641  " -help Print this help. \n"
1642  " Arguments given: " << arguments(argc,argv) << std::endl << std::flush;
1643  ::exit(EINVAL);
1644  }
1645  }
1646  DetElement element = description.world();
1647  if ( detector != "/world" ) {
1648  element = detail::tools::findElement(description, detector);
1649  if ( !element.isValid() ) {
1650  except("VolumeDump","+++ Invalid DetElement path: %s", detector.c_str());
1651  }
1652  }
1653  return actor.cache(element);
1654 }
1655 DECLARE_APPLY(DD4hep_DetElementCache,detelement_cache)
1656 
1657 
1665 #include "../GeometryTreeDump.h"
1666 static long exec_GeometryTreeDump(Detector& description, int, char** ) {
1667  GeometryTreeDump dmp;
1668  dmp.create(description.world());
1669  return 1;
1670 }
1671 DECLARE_APPLY(DD4hep_GeometryTreeDump,exec_GeometryTreeDump)
1672 
1673 
1681 static long detectortype_cache(Detector& description, int argc, char** argv) {
1682  std::vector<std::string> types;
1683  for(int i = 0; i < argc && argv[i]; ++i) {
1684  if ( 0 == ::strncmp("-type",argv[i],4) )
1685  types.push_back(argv[++i]);
1686  else if ( 0 == ::strncmp("--type",argv[i],4) )
1687  types.push_back(argv[++i]);
1688  else {
1689  std::cout <<
1690  "Usage: DD4hep_DetectorTypes -type <type> -arg [-arg] \n"
1691  " Dump detector types from detector description. \n\n"
1692  " -type <string> Add new type to be listed. Multiple possible. \n"
1693  "\tArguments given: " << arguments(argc,argv) << std::endl << std::flush;
1694  ::exit(EINVAL);
1695  }
1696  }
1697  if ( types.empty() ) {
1698  types = description.detectorTypes();
1699  }
1700  printout(INFO,"DetectorTypes","Detector type dump: %ld types:", long(types.size()));
1701  for( const auto& type : types ) {
1702  const std::vector<DetElement>& detectors = description.detectors(type);
1703  printout(INFO,"DetectorTypes","\t --> %ld %s detectors:",long(detectors.size()), type.c_str());
1704  for( const auto& d : detectors ) {
1705  printout(INFO,"DetectorTypes","\t\t %-16s --> %s [%s]",type.c_str(),d.name(),d.type().c_str());
1706  }
1707  }
1708  return 1;
1709 }
1710 DECLARE_APPLY(DD4hep_DetectorTypes,detectortype_cache)
1711 
1712 
1720 #include <DD4hep/SurfaceInstaller.h>
1723 
1724 
1732 #include <DD4hep/PluginTester.h>
1733 static long install_plugin_tester(Detector& description, int , char** ) {
1734  PluginTester* test = description.extension<PluginTester>(false);
1735  if ( !test ) {
1736  description.addExtension<PluginTester>(new PluginTester());
1737  printout(INFO,"PluginTester",
1738  "+++ Successfully installed PluginTester instance to Detector.");
1739  }
1740  return 1;
1741 }
1742 DECLARE_APPLY(DD4hep_PluginTester,install_plugin_tester)
1743 
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:207
dd4hep::Detector::manager
virtual TGeoManager & manager() const =0
Access the geometry manager of this instance.
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::addExtension
IFACE * addExtension(CONCRETE *c)
Extend the sensitive detector element with an arbitrary structure accessible by the type.
Definition: Detector.h:331
dd4hep::xml::DocumentHandler::create
Document create(const char *tag, const char *comment=0) const
Create new XML document by parsing empty xml buffer.
Definition: DocumentHandler.cpp:680
dd4hep::run_interpreter
void run_interpreter(const std::string &name)
Definition: RootDictionary.h:53
DD4hepRootPersistency.h
dd4hep::Detector::world
virtual DetElement world() const =0
Return reference to the top-most (world) detector element.
dd4hep::DetectorScanner
Helper to run DetElement scans.
Definition: DetectorProcessor.h:173
DetectorProcessor.h
dd4hep::Alignment::detectorTransformation
const TGeoHMatrix & detectorTransformation() const
Access the alignment/placement matrix with respect to the world.
Definition: Alignments.cpp:73
v
View * v
Definition: MultiView.cpp:28
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:43
dd4hep::DetElement::parent
DetElement parent() const
Access to the detector elements's parent.
Definition: DetElement.cpp:239
DetectorImp.h
dd4hep::PlacedVolumeScanner::scanPlacements
int scanPlacements(PlacedVolumeProcessor &proc, PlacedVolume start, int level=0, bool recursive=true) const
PlacedVolume element tree scanner using wrapped PlacedVolumeProcessor objects.
Definition: VolumeProcessor.h:165
Detector.h
dd4hep::buildType
DetectorBuildType buildType(const char *value)
Translate string representation of the geometry build type to value.
Definition: BuildType.cpp:24
dd4hep::exception
void exception(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:69
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:164
dd4hep::Box::x
double x() const
Access half "length" of the box.
Definition: Shapes.cpp:155
dd4hep::Detector::detectors
virtual const HandleMap & detectors() const =0
Accessor to the map of sub-detectors.
dd4hep::DetElement::placement
PlacedVolume placement() const
Access to the physical volume of this detector element.
Definition: DetElement.cpp:321
DD4hepRootPersistency::load
static int load(dd4hep::Detector &description, const char *fname, const char *instance="Geometry")
Load an detector description from a ROOT file to memory.
Definition: DD4hepRootPersistency.cpp:113
dd4hep::detail::tools::placementPath
std::string placementPath(DetElement element)
Assemble the placement path from a given detector element to the world volume.
Definition: DetectorTools.cpp:277
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::Volume::solid
Solid solid() const
Access to Solid (Shape)
Definition: Volumes.cpp:1252
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
DD4hepRootPersistency::save
static int save(dd4hep::Detector &description, const char *fname, const char *instance="Geometry")
Save an existing detector description in memory to a ROOT file.
Definition: DD4hepRootPersistency.cpp:47
dd4hep::xml::Handle_t
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:380
dd4hep::Volume::isSensitive
bool isSensitive() const
Accessor if volume is sensitive (ie. is attached to a sensitive detector)
Definition: Volumes.cpp:1322
dd4hep::DetElement::volumeID
VolumeID volumeID() const
The cached VolumeID of this subdetector element.
Definition: DetElement.cpp:344
dd4hep::DetectorLoad::processXMLElement
virtual void processXMLElement(const std::string &msg_source, const xml::Handle_t &root)
Process a given DOM (sub-) tree.
Definition: DetectorLoad.cpp:129
Factories.h
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dump_detelement_tree
long dump_detelement_tree(Detector &description, int argc, char **argv)
Basic entry point to print out the detector element hierarchy.
Definition: StandardPlugins.cpp:1416
dd4hep::Material::A
double A() const
atomic number of the underlying material
Definition: Objects.cpp:187
dd4hep::Box::z
double z() const
Access half "depth" of the box.
Definition: Shapes.cpp:165
dd4hep::Box::y
double y() const
Access half "width" of the box.
Definition: Shapes.cpp:160
dd4hep::detail::printf
std::size_t printf(const char *fmt,...)
Definition: Printout.cpp:97
dd4hep::Volume::material
Material material() const
Access to the Volume material.
Definition: Volumes.cpp:1151
dd4hep::detail::tools::findElement
DetElement findElement(const Detector &description, const std::string &path)
Find DetElement as child of the top level volume by its absolute path.
Definition: DetectorTools.cpp:215
DocumentHandler.h
DD4hepRootCheck
Helper class to check various ingredients of the Detector object after loaded from ROOT.
Definition: DD4hepRootPersistency.h:100
dd4hep::Material
Handle class describing a material.
Definition: Objects.h:271
dd4hep::toStringSolid
std::string toStringSolid(const TGeoShape *shape, int precision=2)
Pretty print of solid attributes.
Definition: ShapeUtilities.cpp:1148
DECLARE_CONSTRUCTOR
#define DECLARE_CONSTRUCTOR(name, func)
Definition: Factories.h:286
dd4hep::STD_Conditions::temperature
double temperature
Definition: Detector.h:69
dd4hep::Detector::getInstance
static Detector & getInstance(const std::string &name="default")
—Factory method----—
Definition: DetectorImp.cpp:150
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::PlacedVolumeExtension::VolIDs
Volume ID container.
Definition: Volumes.h:89
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:371
dd4hep::detail
DD4hep internal namespace.
Definition: Alignments.h:32
mix
#define mix(a, b, c)
Definition: Geant4EventSeed.h:113
dd4hep::DetectorScanner::scan
int scan(Q &p, DetElement start, int level=0, bool recursive=true) const
Detector element tree scanner using wrapped DetectorProcessor objects.
Definition: DetectorProcessor.h:194
dd4hep::Alignment::worldTransformation
const TGeoHMatrix & worldTransformation() const
Create cached matrix to transform to world coordinates.
Definition: Alignments.cpp:68
dd4hep::IDDescriptor::encode
static VolumeID encode(const Field *fld, VolumeID value)
Encode partial volume identifiers to a volumeID.
Definition: IDDescriptor.cpp:148
VolumeProcessor.h
DetectorTools.h
dd4hep::Material::Z
double Z() const
proton number of the underlying material
Definition: Objects.cpp:175
_U
#define _U(a)
Definition: Tags.h:23
TNamed
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:37
dd4hep::DetElement::placementPath
const std::string & placementPath() const
Access to the full path to the placed object.
Definition: DetElement.cpp:85
dd4hep::Detector::stdConditions
virtual const STD_Conditions & stdConditions() const =0
Access default conditions (temperature and pressure.
dd4hep::PlacedVolumeScanner
Helper to run placement scan through volume hierarchies scans.
Definition: VolumeProcessor.h:135
dd4hep::Detector::detectorTypes
virtual std::vector< std::string > detectorTypes() const =0
Access the availible detector types.
dd4hep::DetElement::nominal
Alignment nominal() const
Access to the constant ideal (nominal) alignment information.
Definition: DetElement.cpp:185
TestSurfacesPlugin
SurfaceInstaller TestSurfacesPlugin
Basic entry point to print out detector type map.
Definition: StandardPlugins.cpp:1721
dd4hep::Detector::fromCompact
virtual void fromCompact(const std::string &fname, DetectorBuildType type=BUILD_DEFAULT)=0
Deprecated call (use fromXML): Read compact geometry description or alignment file.
dd4hep::PlacedVolume::VolIDs
PlacedVolumeExtension::VolIDs VolIDs
Definition: Volumes.h:167
dd4hep::sim::IDDescriptor
IDDescriptor IDDescriptor
Definition: LCIOConversions.cpp:69
dd4hep::detail::GeometryTreeDump::create
void create(DetElement top)
Main entry point: create required object(s)
Definition: GeometryTreeDump.cpp:294
XML_IMPLEMENTATION_TYPE
#define XML_IMPLEMENTATION_TYPE
Definition: config.h:63
DECLARE_SURFACE_INSTALLER
#define DECLARE_SURFACE_INSTALLER(name, class)
Definition: SurfaceInstaller.h:108
detectors
DetectorMap detectors
Definition: AlignmentsCalculator.cpp:79
dd4hep::xml::Document
Class supporting the basic functionality of an XML document.
Definition: XMLElements.h:697
dd4hep::detail::tools::findNode
PlacedVolume findNode(PlacedVolume top_place, const std::string &place)
Find a given node in the hierarchy starting from the top node (absolute placement!...
Definition: DetectorTools.cpp:329
Memory.h
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:80
dd4hep::xml::DocumentHandler::output
virtual int output(Document doc, const std::string &fname) const
Write xml document to output file (stdout if file name empty)
Definition: DocumentHandler.cpp:395
dd4hep::PluginTester
Helper class to ease testing of plugins: Effectively a container of object extensions.
Definition: PluginTester.h:30
dd4hep::DetElement::Children
std::map< std::string, DetElement > Children
Definition: DetElement.h:205
dd4hep::Detector::buildType
virtual DetectorBuildType buildType() const =0
Access flag to steer the detail of building of the geometry/detector description.
dd4hep::Box
Class describing a box shape.
Definition: Shapes.h:295
dd4hep::xml::DocumentHandler
Class supporting to read and parse XML documents.
Definition: DocumentHandler.h:39
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:151
dd4hep::DetElement::idealPlacement
PlacedVolume idealPlacement() const
Access to the ideal physical volume of this detector element.
Definition: DetElement.cpp:312
XMLElements.h
dd4hep::xml::Element
User abstraction class to manipulate XML elements within a document.
Definition: XMLElements.h:769
TObject
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:41
dd4hep::Detector::extension
IFACE * extension(bool alert=true) const
Access extension element by the type.
Definition: Detector.h:342
DD4hepUI.h
dd4hep::DetectorBuildType
DetectorBuildType
Detector description build types.
Definition: BuildType.h:34
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::SensitiveDetector::readout
Readout readout() const
Access readout structure of the sensitive detector.
Definition: DetElement.cpp:420
dd4hep::detail::tools::PlacementPath
std::vector< PlacedVolume > PlacementPath
Definition: DetectorTools.h:39
dd4hep::PlacedVolume::volume
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:468
dd4hep::STD_Conditions::pressure
double pressure
Definition: Detector.h:68
dd4hep::PlacedVolumeExtension::VolIDs::insert
std::pair< std::vector< VolID >::iterator, bool > insert(const std::string &name, int value)
Insert new entry.
Definition: Volumes.cpp:422
dd4hep::Detector::fromXML
virtual void fromXML(const std::string &fname, DetectorBuildType type=BUILD_DEFAULT)=0
Read any geometry description or alignment file.
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::SurfaceInstaller
Base class to implement surface installers for known detector patterns.
Definition: SurfaceInstaller.h:55
dd4hep::Readout::idSpec
IDDescriptor idSpec() const
Access IDDescription structure.
Definition: Readout.cpp:112
dd4hep::PlacedVolume::volIDs
const PlacedVolumeExtension::VolIDs & volIDs() const
Access to the volume IDs.
Definition: Volumes.cpp:496
dd4hep::BUILD_DEFAULT
@ BUILD_DEFAULT
Definition: BuildType.h:36
XMLTags.h
DD4hepUnits.h
dd4hep::PlacedVolume::position
Position position() const
Access the translation vector to the parent volume.
Definition: Volumes.cpp:534
dd4hep::detail::GeometryTreeDump
Geometry to screen dump action.
Definition: GeometryTreeDump.h:40
Printout.h
dd4hep::DetectorImp::imp_loadVolumeManager
void imp_loadVolumeManager()
Local method (no interface): Load volume manager.
Definition: DetectorImp.cpp:282
dd4hep::DetectorImp
Concrete implementation class of the Detector interface.
Definition: DetectorImp.h:59
PluginCreators.h
dd4hep::dd4hep_ptr
Out version of the std auto_ptr implementation base either on auto_ptr or unique_ptr.
Definition: Memory.h:46
dd4hep::xml::Document::root
Handle_t root() const
Access the ROOT eleemnt of the DOM document.
Definition: XMLElements.cpp:1043