DD4hep  1.31.0
Detector Description Toolkit for High Energy Physics
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Compact2Objects.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 // Main conversion operations for the compact notation.
15 // - Create elements, materials, etc.
16 // - Calls detector construction factories.
17 //
18 //==========================================================================
19 //
20 // Framework includes
22 #include <DD4hep/DetectorTools.h>
23 #include <DD4hep/MatrixHelpers.h>
24 #include <DD4hep/PropertyTable.h>
25 #include <DD4hep/OpticalSurfaces.h>
27 #include <DD4hep/IDDescriptor.h>
28 #include <DD4hep/DD4hepUnits.h>
29 #include <DD4hep/FieldTypes.h>
30 #include <DD4hep/Printout.h>
31 #include <DD4hep/Factories.h>
32 #include <DD4hep/Path.h>
33 #include <DD4hep/Plugins.h>
37 
38 #include <XML/DocumentHandler.h>
39 #include <XML/Utilities.h>
40 
41 // Root/TGeo include files
42 #include <TGeoManager.h>
43 #include <TGeoMaterial.h>
44 #include <TGeoPhysicalConstants.h>
45 #include <TGDMLMatrix.h>
46 #include <TMath.h>
47 
48 // C/C++ include files
49 #include <filesystem>
50 #include <iostream>
51 #include <climits>
52 #include <set>
53 
54 using namespace dd4hep;
55 
57 namespace dd4hep {
58 
59  class Debug;
60  class World;
61  class Isotope;
62  class Plugin;
63  class Compact;
64  class Includes;
65  class IncludeFile;
66  class Property;
67  class XMLFile;
68  class JsonFile;
69  class PropertyConstant;
70  class Parallelworld_Volume;
71  class DetElementInclude;
72  class STD_Conditions;
73 
75  template <> void Converter<Debug>::operator()(xml_h element) const;
76  template <> void Converter<World>::operator()(xml_h element) const;
77  template <> void Converter<Plugin>::operator()(xml_h element) const;
78  template <> void Converter<Constant>::operator()(xml_h element) const;
79  template <> void Converter<Material>::operator()(xml_h element) const;
80  template <> void Converter<Atom>::operator()(xml_h element) const;
81  template <> void Converter<Isotope>::operator()(xml_h element) const;
82  template <> void Converter<VisAttr>::operator()(xml_h element) const;
83  template <> void Converter<Region>::operator()(xml_h element) const;
84  template <> void Converter<Readout>::operator()(xml_h element) const;
85  template <> void Converter<Segmentation>::operator()(xml_h element) const;
86  template <> void Converter<LimitSet>::operator()(xml_h element) const;
87  template <> void Converter<Property>::operator()(xml_h element) const;
88  template <> void Converter<CartesianField>::operator()(xml_h element) const;
89  template <> void Converter<SensitiveDetector>::operator()(xml_h element) const;
90  template <> void Converter<OpticalSurface>::operator()(xml_h element) const;
91  template <> void Converter<PropertyTable>::operator()(xml_h element) const;
92  template <> void Converter<PropertyConstant>::operator()(xml_h element) const;
93  template <> void Converter<DetElement>::operator()(xml_h element) const;
94  template <> void Converter<STD_Conditions>::operator()(xml_h element) const;
95  template <> void Converter<IncludeFile>::operator()(xml_h element) const;
96  template <> void Converter<JsonFile>::operator()(xml_h element) const;
97  template <> void Converter<XMLFile>::operator()(xml_h element) const;
98  template <> void Converter<Header>::operator()(xml_h element) const;
99  template <> void Converter<DetElementInclude>::operator()(xml_h element) const;
100  template <> void Converter<Parallelworld_Volume>::operator()(xml_h element) const;
101  template <> void Converter<Compact>::operator()(xml_h element) const;
102 }
103 
104 namespace {
105  static UInt_t unique_mat_id = 0xAFFEFEED;
106  void throw_print(const std::string& msg) {
107  printout(ERROR, "Compact", msg.c_str());
108  throw std::runtime_error(msg);
109  }
110  class DebugOptions {
111  public:
112  bool readout = false;
113  bool regions = false;
114  bool limits = false;
115  bool visattr = false;
116  bool isotopes = false;
117  bool elements = false;
118  bool materials = false;
119  bool segmentation = false;
120  bool constants = false;
121  bool includes = false;
122  bool matrix = false;
123  bool surface = false;
124  bool include_guard= true;
125  } s_debug;
126 }
127 
128 static Ref_t create_ConstantField(Detector& /* description */, xml_h e) {
129  CartesianField obj;
130  xml_comp_t field(e), strength(e.child(_U(strength)));
131  std::string t = e.attr<std::string>(_U(field));
132  ConstantField* ptr = new ConstantField();
133  ptr->field_type = ::toupper(t[0]) == 'E' ? CartesianField::ELECTRIC : CartesianField::MAGNETIC;
134  ptr->direction.SetX(strength.x());
135  ptr->direction.SetY(strength.y());
136  ptr->direction.SetZ(strength.z());
137  obj.assign(ptr, field.nameStr(), field.typeStr());
138  return obj;
139 }
140 DECLARE_XMLELEMENT(ConstantField,create_ConstantField)
141 
142 static Ref_t create_SolenoidField(Detector& description, xml_h e) {
143  xml_comp_t c(e);
144  bool has_inner_radius = c.hasAttr(_U(inner_radius));
145  bool has_outer_radius = c.hasAttr(_U(outer_radius));
146 
147  if (!has_inner_radius && !has_outer_radius) {
148  throw_print("Compact2Objects[ERROR]: For a solenoidal field at least one of the "
149  " xml attributes inner_radius of outer_radius MUST be set.");
150  }
151  CartesianField obj;
152  SolenoidField* ptr = new SolenoidField();
153  //
154  // This logic is a bit weird, but has its origin in the compact syntax:
155  // If no "inner_radius" is given, the "outer_radius" IS the "inner_radius"
156  // and the "outer_radius" is given by one side of the world volume's box
157  //
158  if (has_inner_radius && has_outer_radius) {
159  ptr->innerRadius = c.attr<double>(_U(inner_radius));
160  ptr->outerRadius = c.attr<double>(_U(outer_radius));
161  }
162  else if (has_inner_radius) {
163  Box box = description.worldVolume().solid();
164  ptr->innerRadius = c.attr<double>(_U(inner_radius));
165  ptr->outerRadius = box.x();
166  }
167  else if (has_outer_radius) {
168  Box box = description.worldVolume().solid();
169  ptr->innerRadius = c.attr<double>(_U(outer_radius));
170  ptr->outerRadius = box.x();
171  }
172  if (c.hasAttr(_U(inner_field)))
173  ptr->innerField = c.attr<double>(_U(inner_field));
174  if (c.hasAttr(_U(outer_field)))
175  ptr->outerField = c.attr<double>(_U(outer_field));
176  if (c.hasAttr(_U(zmax)))
177  ptr->maxZ = c.attr<double>(_U(zmax));
178  else
179  ptr->maxZ = description.constant<double>("world_side");
180  if (c.hasAttr(_U(zmin)))
181  ptr->minZ = c.attr<double>(_U(zmin));
182  else
183  ptr->minZ = -ptr->maxZ;
185  obj.assign(ptr, c.nameStr(), c.typeStr());
186  return obj;
187 }
188 DECLARE_XMLELEMENT(SolenoidMagnet,create_SolenoidField)
189 // This is the plugin required for slic: note the different name
190 DECLARE_XMLELEMENT(solenoid,create_SolenoidField)
191 
192 static Ref_t create_DipoleField(Detector& /* description */, xml_h e) {
193  xml_comp_t c(e);
194  CartesianField obj;
195  DipoleField* ptr = new DipoleField();
196  double lunit = c.hasAttr(_U(lunit)) ? c.attr<double>(_U(lunit)) : 1.0;
197  double funit = c.hasAttr(_U(funit)) ? c.attr<double>(_U(funit)) : 1.0;
198  double val, mult = funit;
199 
200  if (c.hasAttr(_U(zmin)))
201  ptr->zmin = _multiply<double>(c.attr<std::string>(_U(zmin)), lunit);
202  if (c.hasAttr(_U(zmax)))
203  ptr->zmax = _multiply<double>(c.attr<std::string>(_U(zmax)), lunit);
204  if (c.hasAttr(_U(rmax)))
205  ptr->rmax = _multiply<double>(c.attr<std::string>(_U(rmax)), lunit);
206  for (xml_coll_t coll(c, _U(dipole_coeff)); coll; ++coll, mult /= lunit) {
207  xml_dim_t coeff = coll;
208  if ( coeff.hasAttr(_U(value)) )
209  val = coll.attr<double>(_U(value)) * mult;
210  else if ( coeff.hasAttr(_U(coefficient)) )
211  val = coeff.coefficient() * mult;
212  else
213  val = _multiply<double>(coll.text(), mult);
214  ptr->coefficents.emplace_back(val);
215  }
217  obj.assign(ptr, c.nameStr(), c.typeStr());
218  return obj;
219 }
220 DECLARE_XMLELEMENT(DipoleMagnet,create_DipoleField)
221 
222 static Ref_t create_MultipoleField(Detector& description, xml_h e) {
223  xml_dim_t c(e), child;
224  CartesianField obj;
225  MultipoleField* ptr = new MultipoleField();
226  double lunit = c.hasAttr(_U(lunit)) ? c.attr<double>(_U(lunit)) : 1.0;
227  double funit = c.hasAttr(_U(funit)) ? c.attr<double>(_U(funit)) : 1.0;
228  double val, mult = funit, bz = 0.0;
229  RotationZYX rot;
230  Position pos;
231 
232  if (c.hasAttr(_U(Z))) bz = c.Z() * funit;
233  if ((child = c.child(_U(position), false))) { // Position is not mandatory!
234  pos.SetXYZ(child.x(), child.y(), child.z());
235  }
236  if ((child = c.child(_U(rotation), false))) { // Rotation is not mandatory
237  rot.SetComponents(child.z(), child.y(), child.x());
238  }
239  if ((child = c.child(_U(shape), false))) { // Shape is not mandatory
240  std::string type = child.typeStr();
241  ptr->volume = xml::createShape(description, type, child);
242  }
243  ptr->B_z = bz;
244  ptr->transform = Transform3D(rot,pos);
245  for (xml_coll_t coll(c, _U(coefficient)); coll; ++coll, mult /= lunit) {
246  xml_dim_t coeff = coll;
247  if ( coll.hasAttr(_U(value)) )
248  val = coll.attr<double>(_U(value)) * mult;
249  else
250  val = coeff.coefficient(0.0) * mult;
251  ptr->coefficents.emplace_back(val);
252  val = coeff.skew(0.0) * mult;
253  ptr->skews.emplace_back(val);
254  }
256  obj.assign(ptr, c.nameStr(), c.typeStr());
257  return obj;
258 }
259 DECLARE_XMLELEMENT(MultipoleMagnet,create_MultipoleField)
260 
261 static long load_Compact(Detector& description, xml_h element) {
262  Converter<Compact>converter(description);
263  converter(element);
264  return 1;
265 }
266 DECLARE_XML_DOC_READER(lccdd,load_Compact)
267 DECLARE_XML_DOC_READER(compact,load_Compact)
268 
269 // We create out own type to avoid a class over the extension types
270 // attached to the Detector as a set of std::string is common.
271 class ProcessedFilesSet: public std::set<std::string> {};
272 
274 bool check_process_file(Detector& description, std::string filename) {
275 
276  // In order to have a global compact that is kept across plugin invocations
277  // we add it as an extension to the the detector description.
278  auto already_processed = description.extension<ProcessedFilesSet>( false );
279  if ( !already_processed ) {
280  already_processed = new ProcessedFilesSet( );
281  description.addExtension<ProcessedFilesSet>(already_processed );
282  }
283  std::string npath = dd4hep::Path{filename}.normalize();
284  if (already_processed->find(npath) != already_processed->end() ) {
285  printout(INFO, "Compact","++ Already processed xml document %s.", npath.c_str());
286  return true;
287  }
288  already_processed->insert(npath);
289  return false;
290 }
291 
294 template <> void Converter<Debug>::operator()(xml_h e) const {
295  for (xml_coll_t coll(e, _U(type)); coll; ++coll) {
296  int val = coll.attr<int>(_U(value));
297  std::string nam = coll.attr<std::string>(_U(name));
298  if ( nam.substr(0,6) == "isotop" ) s_debug.isotopes = (0 != val);
299  else if ( nam.substr(0,6) == "elemen" ) s_debug.elements = (0 != val);
300  else if ( nam.substr(0,6) == "materi" ) s_debug.materials = (0 != val);
301  else if ( nam.substr(0,6) == "visatt" ) s_debug.visattr = (0 != val);
302  else if ( nam.substr(0,6) == "region" ) s_debug.regions = (0 != val);
303  else if ( nam.substr(0,6) == "readou" ) s_debug.readout = (0 != val);
304  else if ( nam.substr(0,6) == "limits" ) s_debug.limits = (0 != val);
305  else if ( nam.substr(0,6) == "segmen" ) s_debug.segmentation = (0 != val);
306  else if ( nam.substr(0,6) == "consta" ) s_debug.constants = (0 != val);
307  else if ( nam.substr(0,6) == "define" ) s_debug.constants = (0 != val);
308  else if ( nam.substr(0,6) == "includ" ) s_debug.includes = (0 != val);
309  else if ( nam.substr(0,6) == "matrix" ) s_debug.matrix = (0 != val);
310  else if ( nam.substr(0,6) == "surfac" ) s_debug.surface = (0 != val);
311  else if ( nam.substr(0,6) == "incgua" ) s_debug.include_guard= (0 != val);
312 
313  }
314 }
315 
320 template <> void Converter<Plugin>::operator()(xml_h e) const {
321  xml_comp_t plugin(e);
322  std::string name = plugin.nameStr();
323  std::string type = "default";
324 
325  if ( xml_attr_t typ_attr = e.attr_nothrow(_U(type)) ) {
326  type = e.attr<std::string>(typ_attr);
327  }
328  if ( type == "default" ) {
329  std::vector<char*> argv;
330  std::vector<std::string> arguments;
331  for (xml_coll_t coll(e, _U(arg)); coll; ++coll) {
332  std::string val = coll.attr<std::string>(_U(value));
333  arguments.emplace_back(val);
334  }
335  for (xml_coll_t coll(e, _U(argument)); coll; ++coll) {
336  std::string val = coll.attr<std::string>(_U(value));
337  arguments.emplace_back(val);
338  }
339  for(std::vector<std::string>::iterator i=arguments.begin(); i!=arguments.end(); ++i)
340  argv.emplace_back(&((*i)[0]));
341  description.apply(name.c_str(),int(argv.size()), &argv[0]);
342  return;
343  }
344  // Call a custom plugin taking the xml element as an argument
345  long result = PluginService::Create<long>(name, &description, &e);
346  if (0 == result) {
347  PluginDebug dbg;
348  result = PluginService::Create<long>(name, &description, &e);
349  if ( 0 == result ) {
350  except("Compact","++ Failed to locate plugin %s - no factory: %s",
351  name.c_str(), dbg.missingFactory(name).c_str());
352  }
353  }
354  result = *(long*) result;
355  if (result != 1) {
356  except("Compact","++ Failed to execute plugin %s", name.c_str());
357  }
358 }
359 
364 template <> void Converter<Constant>::operator()(xml_h e) const {
365  if ( e.tag() != "include" ) {
366  xml_ref_t constant(e);
367  std::string nam = constant.attr<std::string>(_U(name));
368  std::string val = constant.attr<std::string>(_U(value));
369  std::string typ = constant.hasAttr(_U(type)) ? constant.attr<std::string>(_U(type)) : "number";
370  Constant c(nam, val, typ);
371  _toDictionary(nam, val, typ);
372  description.addConstant(c);
373  if ( s_debug.constants ) {
374  printout(ALWAYS, "Compact",
375  "++ Converting constant %-16s = %-32s [%s]", nam.c_str(), val.c_str(), typ.c_str());
376  }
377  return;
378  }
379  xml::DocumentHolder doc(xml::DocumentHandler().load(e, e.attr_value(_U(ref))));
380  if ( s_debug.includes ) {
381  printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
382  }
383  xml_h root = doc.root();
384  xml_coll_t(root, _U(define)).for_each(_U(constant), Converter<Constant>(description));
385  xml_coll_t(root, _U(constant)).for_each(Converter<Constant>(description));
386 }
387 
392 template <> void Converter<Header>::operator()(xml_h e) const {
393  xml_comp_t c(e);
394  Header h(e.attr<std::string>(_U(name)), e.attr<std::string>(_U(title), "Undefined"));
395  h.setUrl(e.attr<std::string>(_U(url), "Undefined"));
396  h.setAuthor(e.attr<std::string>(_U(author), "Undefined"));
397  h.setStatus(e.attr<std::string>(_U(status), "development"));
398  h.setVersion(e.attr<std::string>(_U(version), "Undefined"));
399  h.setComment(e.hasChild(_U(comment)) ? e.child(_U(comment)).text() : "No Comment");
400  description.setHeader(h);
401 }
402 
419 template <> void Converter<Material>::operator()(xml_h e) const {
420  xml_ref_t x_mat(e);
421  TGeoManager& mgr = description.manager();
422  xml_tag_t mname = x_mat.name();
423  const char* matname = mname.c_str();
424  TGeoElementTable* table = mgr.GetElementTable();
425  TGeoMaterial* mat = mgr.GetMaterial(matname);
426  TGeoMixture* mix = dynamic_cast<TGeoMixture*>(mat);
427  xml_coll_t fractions (x_mat, _U(fraction));
428  xml_coll_t composites(x_mat, _U(composite));
429 
430  if (0 == mat) {
431  TGeoMaterial* comp_mat;
432  TGeoElement* comp_elt;
433  xml_h density = x_mat.child(_U(D), false);
434  double dens_val = density.ptr() ? density.attr<double>(_U(value)) : 0.0;
435  double dens_unit = 1.0;
436 
437  if ( !density.ptr() ) {
438  throw_print("Compact2Objects[ERROR]: material without density tag ( <D unit=\"g/cm3\" value=\"..\"/> ) provided: "
439  + std::string( matname ) ) ;
440  }
441  if ( density.hasAttr(_U(unit)) ) {
442  dens_unit = density.attr<double>(_U(unit))/xml::_toDouble(_Unicode(gram/cm3));
443  }
444  if ( dens_unit != 1.0 ) {
445  dens_val *= dens_unit;
446  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact","Density unit: %.3f [%s] raw: %.3f normalized: %.3f ",
447  dens_unit, density.attr<std::string>(_U(unit)).c_str(), dens_val, (dens_val*dens_unit));
448  }
449  mat = mix = new TGeoMixture(matname, composites.size(), dens_val);
450  std::size_t ifrac = 0;
451  std::vector<double> composite_fractions;
452  double composite_fractions_total = 0.0;
453  for (composites.reset(); composites; ++composites) {
454  std::string nam = composites.attr<std::string>(_U(ref));
455  double fraction = composites.attr<double>(_U(n));
456  if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
457  fraction *= comp_mat->GetA();
458  else if (0 != (comp_elt = table->FindElement(nam.c_str())))
459  fraction *= comp_elt->A();
460  else
461  except("Compact2Objects","Converting material: %s Element missing: %s",mname.c_str(),nam.c_str());
462  composite_fractions_total += fraction;
463  composite_fractions.emplace_back(fraction);
464  }
465  for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) {
466  std::string nam = composites.attr<std::string>(_U(ref));
467  double fraction = composite_fractions[ifrac]/composite_fractions_total;
468  if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
469  mix->AddElement(comp_mat, fraction);
470  else if (0 != (comp_elt = table->FindElement(nam.c_str())))
471  mix->AddElement(comp_elt, fraction);
472  }
473  for (fractions.reset(); fractions; ++fractions) {
474  std::string nam = fractions.attr<std::string>(_U(ref));
475  double fraction = fractions.attr<double>(_U(n));
476  if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
477  mix->AddElement(comp_mat, fraction);
478  else if (0 != (comp_elt = table->FindElement(nam.c_str())))
479  mix->AddElement(comp_elt, fraction);
480  else
481  throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " Element missing: " + nam);
482  }
483  xml_h temperature = x_mat.child(_U(T), false);
484  double temp_val = description.stdConditions().temperature;
485  if ( temperature.ptr() ) {
486  double temp_unit = _toDouble("kelvin");
487  if ( temperature.hasAttr(_U(unit)) )
488  temp_unit = temperature.attr<double>(_U(unit));
489  temp_val = temperature.attr<double>(_U(value)) * temp_unit;
490  }
491  xml_h pressure = x_mat.child(_U(P), false);
492  double pressure_val = description.stdConditions().pressure;
493  if ( pressure.ptr() ) {
494  double pressure_unit = _toDouble("pascal");
495  if ( pressure.hasAttr(_U(unit)) )
496  pressure_unit = pressure.attr<double>(_U(unit));
497  pressure_val = pressure.attr<double>(_U(value)) * pressure_unit;
498  }
499 #if 0
500  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
501  "++ ROOT raw temperature and pressure: %.3g %.3g",
502  mat->GetTemperature(),mat->GetPressure());
503 #endif
504  mat->SetTemperature(temp_val);
505  mat->SetPressure(pressure_val);
506  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
507  "++ Converting material %-16s Density: %9.7g Temperature:%9.7g [K] Pressure:%9.7g [hPa].",
508  matname, dens_val, temp_val/dd4hep::kelvin, pressure_val/dd4hep::pascal/100.0);
509 
510  mix->SetRadLen(0e0);
511  mix->ComputeDerivedQuantities();
514  for(xml_coll_t properties(x_mat, _U(constant)); properties; ++properties) {
515  xml_elt_t p = properties;
516  if ( p.hasAttr(_U(ref)) ) {
517  bool err = kFALSE;
518  std::string ref = p.attr<std::string>(_U(ref));
519  mgr.GetProperty(ref.c_str(), &err);
520  if ( err == kFALSE ) {
521  std::string prop_nam = p.attr<std::string>(_U(name));
522  mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
523  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
524  "++ material %-16s add constant property: %s -> %s.",
525  mat->GetName(), prop_nam.c_str(), ref.c_str());
526  continue;
527  }
528  // ERROR
529  throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " ConstProperty missing in TGeoManager: " + ref);
530  }
531  else if ( p.hasAttr(_U(value)) ) {
532  std::stringstream str;
533  std::string ref, prop_nam = p.attr<std::string>(_U(name));
534  str << prop_nam << "_" << (void*)mat;
535  ref = str.str();
536  mgr.AddProperty(ref.c_str(), p.attr<double>(_U(value)));
537  mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
538  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
539  "++ material %-16s add constant property: %s -> %s.",
540  mat->GetName(), prop_nam.c_str(), ref.c_str());
541  }
542  else if ( p.hasAttr(_U(option)) ) {
543  std::string prop_nam = p.attr<std::string>(_U(name));
544  std::string prop_typ = p.attr<std::string>(_U(option));
545  mat->AddConstProperty(prop_nam.c_str(), prop_typ.c_str());
546  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
547  "++ material %-16s add constant property: %s -> %s.",
548  mat->GetName(), prop_nam.c_str(), prop_typ.c_str());
549  }
550  }
552  for(xml_coll_t properties(x_mat, _U(property)); properties; ++properties) {
553  xml_elt_t p = properties;
554  if ( p.hasAttr(_U(ref)) ) {
555  std::string ref = p.attr<std::string>(_U(ref));
556  TGDMLMatrix* gdmlMat = mgr.GetGDMLMatrix(ref.c_str());
557  if ( gdmlMat ) {
558  std::string prop_nam = p.attr<std::string>(_U(name));
559  mat->AddProperty(prop_nam.c_str(), ref.c_str());
560  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
561  "++ material %-16s add property: %s -> %s.",
562  mat->GetName(), prop_nam.c_str(), ref.c_str());
563  continue;
564  }
565  // ERROR
566  throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " Property missing: " + ref);
567  }
568  }
569  }
570  TGeoMedium* medium = mgr.GetMedium(matname);
571  if (0 == medium) {
572  --unique_mat_id;
573  medium = new TGeoMedium(matname, unique_mat_id, mat);
574  medium->SetTitle("material");
575  medium->SetUniqueID(unique_mat_id);
576  }
577  // TGeo has no notion of a material "formula"
578  // Hence, treat the formula the same way as the material itself
579  if (x_mat.hasAttr(_U(formula))) {
580  std::string form = x_mat.attr<std::string>(_U(formula));
581  if (form != matname) {
582  medium = mgr.GetMedium(form.c_str());
583  if (0 == medium) {
584  --unique_mat_id;
585  medium = new TGeoMedium(form.c_str(), unique_mat_id, mat);
586  medium->SetTitle("material");
587  medium->SetUniqueID(unique_mat_id);
588  }
589  }
590  }
591 }
592 
599 template <> void Converter<Isotope>::operator()(xml_h e) const {
600  xml_dim_t isotope(e);
601  TGeoManager& mgr = description.manager();
602  std::string nam = isotope.nameStr();
603  TGeoElementTable* tab = mgr.GetElementTable();
604  TGeoIsotope* iso = tab->FindIsotope(nam.c_str());
605 
606  // Create the isotope object in the event it is not yet present from the XML data
607  if ( !iso ) {
608  xml_ref_t atom(isotope.child(_U(atom)));
609  std::string unit = atom.attr<std::string>(_U(unit));
610  double value = atom.attr<double>(_U(value));
611  double a = value * _multiply<double>(unit,"mol/g");
612  int n = isotope.attr<int>(_U(N));
613  int z = isotope.attr<int>(_U(Z));
614  iso = new TGeoIsotope(nam.c_str(), z, n, a);
615  printout(s_debug.isotopes ? ALWAYS : DEBUG, "Compact",
616  "++ Converting isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol]",
617  iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
618  }
619  else {
620  printout(s_debug.isotopes ? WARNING : DEBUG, "Compact",
621  "++ Isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
622  iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
623  }
624 }
625 
640 template <> void Converter<Atom>::operator()(xml_h e) const {
641  xml_ref_t elem(e);
642  xml_tag_t name = elem.name();
643  TGeoManager& mgr = description.manager();
644  TGeoElementTable* tab = mgr.GetElementTable();
645  TGeoElement* elt = tab->FindElement(name.c_str());
646  if ( !elt ) {
647  if ( elem.hasChild(_U(atom)) ) {
648  xml_ref_t atom(elem.child(_U(atom)));
649  std::string formula = elem.attr<std::string>(_U(formula));
650  double value = atom.attr<double>(_U(value));
651  std::string unit = atom.attr<std::string>(_U(unit));
652  int z = elem.attr<int>(_U(Z));
653  double a = value*_multiply<double>(unit,"mol/g");
654  printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
655  "++ Converting element %-16s [%-3s] Z:%3d A:%8.4f [g/mol]",
656  name.c_str(), formula.c_str(), z, a);
657  tab->AddElement(name.c_str(), formula.c_str(), z, a);
658  }
659  else {
660  int num_isotopes = 0;
661  std::string formula = elem.hasAttr(_U(formula)) ? elem.attr<std::string>(_U(formula)) : name.str();
662  for( xml_coll_t i(elem,_U(fraction)); i; ++i)
663  ++num_isotopes;
664  elt = new TGeoElement(name.c_str(), formula.c_str(), num_isotopes);
665  tab->AddElement(elt);
666  for( xml_coll_t i(elem,_U(fraction)); i; ++i) {
667  double frac = i.attr<double>(_U(n));
668  std::string ref = i.attr<std::string>(_U(ref));
669  TGeoIsotope* iso = tab->FindIsotope(ref.c_str());
670  if ( !iso ) {
671  except("Compact","Element %s cannot be constructed. Isotope '%s' (fraction: %.3f) missing!",
672  name.c_str(), ref.c_str(), frac);
673  }
674  printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
675  "++ Converting element %-16s Add isotope: %-16s fraction:%.4f.",
676  name.c_str(), ref.c_str(), frac);
677  elt->AddIsotope(iso, frac);
678  }
679  printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
680  "++ Converted element %-16s [%-3s] Z:%3d A:%8.4f [g/mol] with %d isotopes.",
681  name.c_str(), formula.c_str(), elt->Z(), elt->A(), num_isotopes);
682  }
683  elt = tab->FindElement(name.c_str());
684  if (!elt) {
685  throw_print("Failed to properly insert the Element:"+name+" into the element table!");
686  }
687  }
688  else {
689  printout(s_debug.elements ? WARNING : DEBUG, "Compact",
690  "++ Element %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
691  elt->GetName(), elt->Z(), elt->N(), elt->A());
692  }
693 }
694 
702 template <> void Converter<STD_Conditions>::operator()(xml_h e) const {
703  xml_dim_t cond(e);
704  // Create the isotope object in the event it is not yet present from the XML data
705  if ( cond.ptr() ) {
706  if ( cond.hasAttr(_U(type)) ) {
707  description.setStdConditions(cond.typeStr());
708  }
709  xml_h temperature = cond.child(_U(T), false);
710  double temp_val = description.stdConditions().temperature;
711  if ( temperature.ptr() ) {
712  double temp_unit = _toDouble("kelvin");
713  if ( temperature.hasAttr(_U(unit)) )
714  temp_unit = temperature.attr<double>(_U(unit));
715  temp_val = temperature.attr<double>(_U(value)) * temp_unit;
716  }
717  xml_h pressure = cond.child(_U(P), false);
718  double pressure_val = description.stdConditions().pressure;
719  if ( pressure.ptr() ) {
720  double pressure_unit = _toDouble("pascal");
721  if ( pressure.hasAttr(_U(unit)) )
722  pressure_unit = pressure.attr<double>(_U(unit));
723  pressure_val = pressure.attr<double>(_U(value)) * pressure_unit;
724  }
725  description.setStdConditions(temp_val, pressure_val);
726  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
727  "+++ Material standard conditions: Temperature: %.3f Kelvin Pressure: %.3f hPa",
728  temp_val/_toDouble("kelvin"), pressure_val/_toDouble("hPa"));
729  }
730 }
731 
736 template <> void Converter<OpticalSurface>::operator()(xml_h element) const {
737  xml_elt_t e = element;
738  TGeoManager& mgr = description.manager();
739  std::string sname = e.attr<std::string>(_U(name));
740  std::string ref, pname;
741 
742  // Defaults from Geant4
743  OpticalSurface::EModel model = OpticalSurface::Model::kMglisur;
744  OpticalSurface::EFinish finish = OpticalSurface::Finish::kFpolished;
745  OpticalSurface::EType type = OpticalSurface::Type::kTdielectric_metal;
746  Double_t value = 1.0;
747  if ( e.hasAttr(_U(type)) ) type = OpticalSurface::stringToType(e.attr<std::string>(_U(type)));
748  if ( e.hasAttr(_U(model)) ) model = OpticalSurface::stringToModel(e.attr<std::string>(_U(model)));
749  if ( e.hasAttr(_U(finish)) ) finish = OpticalSurface::stringToFinish(e.attr<std::string>(_U(finish)));
750  if ( e.hasAttr(_U(value)) ) value = e.attr<double>(_U(value));
751  OpticalSurface surf(description, sname, model, finish, type, value);
752  if ( s_debug.surface ) {
753  printout(ALWAYS,"Compact","+++ Reading optical surface %s Typ:%d model:%d finish:%d value: %.3f",
754  sname.c_str(), int(type), int(model), int(finish), value);
755  }
756  for (xml_coll_t props(e, _U(property)); props; ++props) {
757  pname = props.attr<std::string>(_U(name));
758  if ( props.hasAttr(_U(ref)) ) {
759  bool err = kFALSE;
760  ref = props.attr<std::string>(_U(ref));
761  mgr.GetProperty(ref.c_str(), &err);
762  surf->AddProperty(pname.c_str(), ref.c_str());
763  if ( s_debug.surface ) {
764  printout(ALWAYS,"Compact","+++ \t\t Property: %s -> %s", pname.c_str(), ref.c_str());
765  }
766  continue;
767  }
768  std::size_t cols = props.attr<long>(_U(coldim));
769  xml_attr_t opt = props.attr_nothrow(_U(option));
770  std::stringstream str(props.attr<std::string>(_U(values))), str_nam;
771  std::string val;
772  std::vector<double> values;
773  while ( !str.eof() ) {
774  val = "";
775  str >> val;
776  if ( val.empty() && !str.good() ) break;
777  values.emplace_back(_toDouble(val));
778  }
780  TGDMLMatrix* table = new TGDMLMatrix("",values.size()/cols, cols);
781  if ( opt ) {
782  std::string tit = e.attr<std::string>(opt);
783  str_nam << tit << "|";
784  }
785  str_nam << pname << "__" << (void*)table;
786  table->SetName(str_nam.str().c_str());
787  table->SetTitle(pname.c_str());
788  for (std::size_t i=0, n=values.size(); i<n; ++i)
789  table->Set(i/cols, i%cols, values[i]);
790  surf->AddProperty(pname.c_str(), table->GetName());
791  description.manager().AddGDMLMatrix(table);
792  }
793 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
794  //
795  // In case there were constant surface properties specified: convert them here
796  for(xml_coll_t properties(e, _U(constant)); properties; ++properties) {
797  xml_elt_t p = properties;
798  pname = p.attr<std::string>(_U(name));
799  if ( p.hasAttr(_U(ref)) ) {
800  bool err = kFALSE;
801  ref = p.attr<std::string>(_U(ref));
802  mgr.GetProperty(ref.c_str(), &err);
803  if ( err == kFALSE ) {
804  surf->AddConstProperty(pname.c_str(), ref.c_str());
805  printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
806  "++ surface %-16s add constant property: %s -> %s.",
807  surf->GetName(), pname.c_str(), ref.c_str());
808  continue;
809  }
810  // ERROR
811  throw_print("Compact2Objects[ERROR]: Converting surface: " + sname +
812  " ConstProperty missing in TGeoManager: " + ref);
813  }
814  else if ( p.hasAttr(_U(value)) ) {
815  std::stringstream str;
816  str << pname << "_" << (void*)surf.ptr();
817  ref = str.str();
818  mgr.AddProperty(ref.c_str(), p.attr<double>(_U(value)));
819  surf->AddConstProperty(pname.c_str(), ref.c_str());
820  printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
821  "++ surface %-16s add constant property: %s -> %s.",
822  surf->GetName(), pname.c_str(), ref.c_str());
823  }
824  else if ( p.hasAttr(_U(option)) ) {
825  std::string ptyp = p.attr<std::string>(_U(option));
826  surf->AddConstProperty(pname.c_str(), ptyp.c_str());
827  printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
828  "++ surface %-16s add constant property: %s -> %s.",
829  surf->GetName(), pname.c_str(), ptyp.c_str());
830  }
831  }
832 #endif
833 }
834 
840 template <> void Converter<PropertyConstant>::operator()(xml_h e) const {
841  double value = e.attr<double>(_U(value));
842  std::string name = e.attr<std::string>(_U(name));
843  description.manager().AddProperty(name.c_str(), value);
844  if ( s_debug.matrix ) {
845  printout(ALWAYS,"Compact","+++ Reading property %s : %f",name.c_str(), value);
846  }
847 #if 0
848  xml_attr_t opt = e.attr_nothrow(_U(title));
849  if ( opt ) {
850  std::string val = e.attr<std::string>(opt);
851  TNamed* nam = description.manager().GetProperty(name.c_str());
852  if ( !nam ) {
853  except("Compact","Failed to access just added manager property: %s",name.c_str());
854  }
855  nam->SetTitle(val.c_str());
856  }
857 #endif
858 }
859 
865 template <> void Converter<PropertyTable>::operator()(xml_h e) const {
866  std::vector<double> vals;
867  std::size_t cols = e.attr<unsigned long>(_U(coldim));
868  std::stringstream str(e.attr<std::string>(_U(values)));
869 
870  if ( s_debug.matrix ) {
871  printout(ALWAYS,"Compact","+++ Reading property table %s with %d columns.",
872  e.attr<std::string>(_U(name)).c_str(), cols);
873  }
874  vals.reserve(1024);
875  while ( !str.eof() ) {
876  std::string item;
877  str >> item;
878  if ( item.empty() && !str.good() ) break;
879  vals.emplace_back(_toDouble(item));
880  if ( s_debug.matrix ) {
881  std::cout << " state:" << (str.good() ? "OK " : "BAD") << " '" << item << "'";
882  if ( 0 == (vals.size()%cols) ) std::cout << std::endl;
883  }
884  }
885  if ( s_debug.matrix ) {
886  std::cout << std::endl;
887  }
889  xml_attr_t opt = e.attr_nothrow(_U(option));
890  PropertyTable tab(description,
891  e.attr<std::string>(_U(name)),
892  opt ? e.attr<std::string>(opt).c_str() : "",
893  vals.size()/cols, cols);
894  for( std::size_t i=0, n=vals.size(); i < n; ++i )
895  tab->Set(i/cols, i%cols, vals[i]);
896  //if ( s_debug.matrix ) tab->Print();
897 }
898 
913 template <> void Converter<VisAttr>::operator()(xml_h e) const {
914  VisAttr attr(e.attr<std::string>(_U(name)));
915  float alpha = 1.0;
916  float red = 1.0;
917  float green = 1.0;
918  float blue = 1.0;
919  bool use_ref = false;
920  if(e.hasAttr(_U(ref))) {
921  use_ref = true;
922  auto refName = e.attr<std::string>(_U(ref));
923  const auto refAttr = description.visAttributes(refName);
924  if(!refAttr.isValid() ) {
925  except("Compact","+++ Reference VisAttr %s does not exist", refName.c_str());
926  }
927  // Just copying things manually.
928  // I think a handle's copy constructor/assignment would reuse the underlying pointer... maybe?
929  refAttr.argb(alpha,red,green,blue);
930  attr.setColor(alpha,red,green,blue);
931  attr.setDrawingStyle( refAttr.drawingStyle());
932  attr.setLineStyle( refAttr.lineStyle());
933  attr.setShowDaughters(refAttr.showDaughters());
934  attr.setVisible(refAttr.visible());
935  }
936  xml_dim_t dim(e);
937  alpha = dim.alpha(alpha);
938  red = dim.r(red );
939  green = dim.g(green);
940  blue = dim.b(blue );
941 
942  printout(s_debug.visattr ? ALWAYS : DEBUG, "Compact",
943  "++ Converting VisAttr structure: %-16s. Alpha=%.2f R=%.3f G=%.3f B=%.3f",
944  attr.name(), alpha, red, green, blue);
945  attr.setColor(alpha, red, green, blue);
946  if (e.hasAttr(_U(visible)))
947  attr.setVisible(e.attr<bool>(_U(visible)));
948  if (e.hasAttr(_U(lineStyle))) {
949  std::string ls = e.attr<std::string>(_U(lineStyle));
950  if (ls == "unbroken")
951  attr.setLineStyle(VisAttr::SOLID);
952  else if (ls == "broken")
953  attr.setLineStyle(VisAttr::DASHED);
954  }
955  else {
956  if (!use_ref)
957  attr.setLineStyle(VisAttr::SOLID);
958  }
959  if (e.hasAttr(_U(drawingStyle))) {
960  std::string ds = e.attr<std::string>(_U(drawingStyle));
961  if (ds == "wireframe")
962  attr.setDrawingStyle(VisAttr::WIREFRAME);
963  else if (ds == "solid")
964  attr.setDrawingStyle(VisAttr::SOLID);
965  }
966  else {
967  if (!use_ref)
968  attr.setDrawingStyle(VisAttr::SOLID);
969  }
970  if (e.hasAttr(_U(showDaughters)))
971  attr.setShowDaughters(e.attr<bool>(_U(showDaughters)));
972  else {
973  if (!use_ref)
974  attr.setShowDaughters(true);
975  }
976  description.addVisAttribute(attr);
977 }
978 
982 template <> void Converter<Region>::operator()(xml_h elt) const {
983  xml_dim_t e = elt;
984  Region region(e.nameStr());
985  auto& limits = region.limits();
986  xml_attr_t cut = elt.attr_nothrow(_U(cut));
987  xml_attr_t threshold = elt.attr_nothrow(_U(threshold));
988  xml_attr_t store_secondaries = elt.attr_nothrow(_U(store_secondaries));
989  double ene = e.eunit(1.0), len = e.lunit(1.0);
990 
991  printout(s_debug.regions ? ALWAYS : DEBUG, "Compact",
992  "++ Converting region structure: %s.",region.name());
993  if ( cut ) {
994  region.setCut(elt.attr<double>(cut)*len);
995  }
996  if ( threshold ) {
997  region.setThreshold(elt.attr<double>(threshold)*ene);
998  }
999  if ( store_secondaries ) {
1000  region.setStoreSecondaries(elt.attr<bool>(store_secondaries));
1001  }
1002  for (xml_coll_t user_limits(e, _U(limitsetref)); user_limits; ++user_limits)
1003  limits.emplace_back(user_limits.attr<std::string>(_U(name)));
1004  description.addRegion(region);
1005 }
1006 
1007 
1015 template <> void Converter<Segmentation>::operator()(xml_h seg) const {
1016  std::string type = seg.attr<std::string>(_U(type));
1017  std::string name = seg.hasAttr(_U(name)) ? seg.attr<std::string>(_U(name)) : std::string();
1018  std::pair<Segmentation,IDDescriptor>* opt = _option<std::pair<Segmentation,IDDescriptor> >();
1019 
1020  const BitFieldCoder* bitfield = &opt->second->decoder;
1021  Segmentation segment(type, name, bitfield);
1022  if ( segment.isValid() ) {
1023  const DDSegmentation::Parameters& pars = segment.parameters();
1024  printout(s_debug.segmentation ? ALWAYS : DEBUG, "Compact",
1025  "++ Converting segmentation structure: %s of type %s.",name.c_str(),type.c_str());
1026  for(const auto p : pars ) {
1027  xml::Strng_t pNam(p->name());
1028  if ( seg.hasAttr(pNam) ) {
1029  std::string pType = p->type();
1030  if ( pType.compare("int") == 0 ) {
1032  static_cast<ParInt*>(p)->setTypedValue(seg.attr<int>(pNam));
1033  } else if ( pType.compare("float") == 0 ) {
1035  static_cast<ParFloat*>(p)->setTypedValue(seg.attr<float>(pNam));
1036  } else if ( pType.compare("doublevec") == 0 ) {
1037  std::vector<double> valueVector;
1038  std::string par = seg.attr<std::string>(pNam);
1039  printout(s_debug.segmentation ? ALWAYS : DEBUG, "Compact",
1040  "++ Converting this std::string structure: %s.",par.c_str());
1041  std::vector<std::string> elts = DDSegmentation::splitString(par);
1042  for (const std::string& spar : elts ) {
1043  if ( spar.empty() ) continue;
1044  valueVector.emplace_back(_toDouble(spar));
1045  }
1047  static_cast<ParDouVec*>(p)->setTypedValue(valueVector);
1048  } else if ( pType.compare("double" ) == 0) {
1050  static_cast<ParDouble*>(p)->setTypedValue(seg.attr<double>(pNam));
1051  } else {
1052  p->setValue(seg.attr<std::string>(pNam));
1053  }
1054  } else if (not p->isOptional()) {
1055  throw_print("FAILED to create segmentation: " + type +
1056  ". Missing mandatory parameter: " + p->name() + "!");
1057  }
1058  }
1059  long key_min = 0, key_max = 0;
1060  DDSegmentation::Segmentation* base = segment->segmentation;
1061  for(xml_coll_t sub(seg,_U(segmentation)); sub; ++sub) {
1062  std::pair<Segmentation,IDDescriptor> sub_object(Segmentation(),opt->second);
1063  Converter<Segmentation> sub_conv(description,param,&sub_object);
1064  sub_conv(sub);
1065  if ( sub_object.first.isValid() ) {
1066  Segmentation sub_seg = sub_object.first;
1067  xml_dim_t x_seg(sub);
1068  if ( sub.hasAttr(_U(key_value)) ) {
1069  key_min = key_max = x_seg.key_value();
1070  }
1071  else if ( sub.hasAttr(_U(key_min)) && sub.hasAttr(_U(key_max)) ) {
1072  key_min = x_seg.key_min();
1073  key_max = x_seg.key_max();
1074  }
1075  else {
1076  std::stringstream tree;
1077  xml::dump_tree(sub,tree);
1078  throw_print("Nested segmentations: Invalid key specification:"+tree.str());
1079  }
1080  printout(s_debug.segmentation ? ALWAYS : DEBUG,"Compact",
1081  "++ Segmentation [%s/%s]: Add sub-segmentation %s [%s]",
1082  name.c_str(), type.c_str(),
1083  sub_seg->segmentation->name().c_str(),
1084  sub_seg->segmentation->type().c_str());
1085  base->addSubsegmentation(key_min, key_max, sub_seg->segmentation);
1086  sub_seg->segmentation = 0;
1087  delete sub_seg.ptr();
1088  }
1089  }
1090  }
1091  opt->first = segment;
1092 }
1093 
1101 template <> void Converter<Readout>::operator()(xml_h e) const {
1102  xml_h seg = e.child(_U(segmentation), false);
1103  xml_h id = e.child(_U(id));
1104  std::string name = e.attr<std::string>(_U(name));
1105  std::pair<Segmentation,IDDescriptor> opt;
1106  Readout ro(name);
1107 
1108  if (id) {
1109  // <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id>
1110  opt.second = IDDescriptor(name,id.text());
1111  description.addIDSpecification(opt.second);
1112  }
1113  if (seg) { // Segmentation is not mandatory!
1114  Converter<Segmentation>(description,param,&opt)(seg);
1115  opt.first->setName(name);
1116  }
1120  if ( opt.first.isValid() ) {
1121  ro.setSegmentation(opt.first);
1122  }
1123  if ( opt.second.isValid() ) {
1124  ro.setIDDescriptor(opt.second);
1125  }
1126 
1127  printout(s_debug.readout ? ALWAYS : DEBUG,
1128  "Compact", "++ Converting readout structure: %-16s. %s%s",
1129  ro.name(), id ? "ID: " : "", id ? id.text().c_str() : "");
1130 
1131  for(xml_coll_t colls(e,_U(hits_collections)); colls; ++colls) {
1132  std::string hits_key;
1133  if ( colls.hasAttr(_U(key)) ) hits_key = colls.attr<std::string>(_U(key));
1134  for(xml_coll_t coll(colls,_U(hits_collection)); coll; ++coll) {
1135  xml_dim_t c(coll);
1136  std::string coll_name = c.nameStr();
1137  std::string coll_key = hits_key;
1138  long key_min = 0, key_max = 0;
1139 
1140  if ( c.hasAttr(_U(key)) ) {
1141  coll_key = c.attr<std::string>(_U(key));
1142  }
1143  if ( c.hasAttr(_U(key_value)) ) {
1144  key_max = key_min = c.key_value();
1145  }
1146  else if ( c.hasAttr(_U(key_min)) && c.hasAttr(_U(key_max)) ) {
1147  key_min = c.key_min();
1148  key_max = c.key_max();
1149  }
1150  else {
1151  std::stringstream tree;
1152  xml::dump_tree(e,tree);
1153  throw_print("Readout: Invalid specification for multiple hit collections."+tree.str());
1154  }
1155  printout(s_debug.readout ? ALWAYS : DEBUG,"Compact",
1156  "++ Readout[%s]: Add hit collection %s [%s] %d-%d",
1157  ro.name(), coll_name.c_str(), coll_key.c_str(), key_min, key_max);
1158  HitCollection hits(coll_name, coll_key, key_min, key_max);
1159  ro->hits.emplace_back(hits);
1160  }
1161  }
1162  description.addReadout(ro);
1163 }
1164 
1165 static long load_readout(Detector& description, xml_h element) {
1166  Converter<Readout> converter(description);
1167  converter(element);
1168  return 1;
1169 }
1170 DECLARE_XML_DOC_READER(readout,load_readout)
1171 
1172 
1173 
1179 template <> void Converter<LimitSet>::operator()(xml_h e) const {
1180  Limit limit;
1181  LimitSet ls(e.attr<std::string>(_U(name)));
1182  printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1183  "++ Converting LimitSet structure: %s.",ls.name());
1184  for (xml_coll_t c(e, _U(limit)); c; ++c) {
1185  limit.name = c.attr<std::string>(_U(name));
1186  limit.particles = c.attr<std::string>(_U(particles));
1187  limit.content = c.attr<std::string>(_U(value));
1188  limit.unit = c.attr<std::string>(_U(unit));
1189  limit.value = _multiply<double>(limit.content, limit.unit);
1190  ls.addLimit(limit);
1191  printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1192  "++ %s: add %-6s: [%s] = %s [%s] = %f",
1193  ls.name(), limit.name.c_str(), limit.particles.c_str(),
1194  limit.content.c_str(), limit.unit.c_str(), limit.value);
1195  }
1196  limit.name = "cut";
1197  for (xml_coll_t c(e, _U(cut)); c; ++c) {
1198  limit.particles = c.attr<std::string>(_U(particles));
1199  limit.content = c.attr<std::string>(_U(value));
1200  limit.unit = c.attr<std::string>(_U(unit));
1201  limit.value = _multiply<double>(limit.content, limit.unit);
1202  ls.addCut(limit);
1203  printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1204  "++ %s: add %-6s: [%s] = %s [%s] = %f",
1205  ls.name(), limit.name.c_str(), limit.particles.c_str(),
1206  limit.content.c_str(), limit.unit.c_str(), limit.value);
1207  }
1208  description.addLimitSet(ls);
1209 }
1210 
1217 template <> void Converter<Property>::operator()(xml_h e) const {
1218  std::string name = e.attr<std::string>(_U(name));
1219  Detector::Properties& prp = description.properties();
1220  if ( name.empty() )
1221  throw_print("Failed to convert properties. No name given!");
1222 
1223  std::vector<xml_attr_t> a = e.attributes();
1224  if ( prp.find(name) == prp.end() )
1225  prp.emplace(name, Detector::PropertyValues());
1226 
1227  for (xml_attr_t i : a )
1228  prp[name].emplace(xml_tag_t(e.attr_name(i)).str(),e.attr<std::string>(i));
1229 }
1230 
1239 template <> void Converter<CartesianField>::operator()(xml_h e) const {
1240  std::string msg = "updated";
1241  std::string name = e.attr<std::string>(_U(name));
1242  std::string type = e.attr<std::string>(_U(type));
1243  CartesianField field = description.field(name);
1244  if ( !field.isValid() ) {
1245  // The field is not present: We create it and add it to Detector
1246  field = Ref_t(PluginService::Create<NamedObject*>(type, &description, &e));
1247  if ( !field.isValid() ) {
1248  PluginDebug dbg;
1249  PluginService::Create<NamedObject*>(type, &description, &e);
1250  throw_print("Failed to create field object of type "+type + ". "+dbg.missingFactory(type));
1251  }
1252  description.addField(field);
1253  msg = "created";
1254  }
1255  type = field.type();
1256  // Now update the field structure with the generic part ie. set its properties
1257  CartesianField::Properties& prp = field.properties();
1258  for ( xml_coll_t c(e, _U(properties)); c; ++c ) {
1259  std::string props_name = c.attr<std::string>(_U(name));
1260  std::vector<xml_attr_t>a = c.attributes();
1261  if ( prp.find(props_name) == prp.end() ) {
1262  prp.emplace(props_name, Detector::PropertyValues());
1263  }
1264  for ( xml_attr_t i : a )
1265  prp[props_name].emplace(xml_tag_t(c.attr_name(i)).str(), c.attr<std::string>(i));
1266 
1267  if (c.hasAttr(_U(global)) && c.attr<bool>(_U(global))) {
1268  description.field().properties() = prp;
1269  }
1270  }
1271  printout(INFO, "Compact", "++ Converted field: Successfully %s field %s [%s]", msg.c_str(), name.c_str(), type.c_str());
1272 }
1273 
1287 template <> void Converter<SensitiveDetector>::operator()(xml_h element) const {
1288  std::string name = element.attr<std::string>(_U(name));
1289  try {
1290  SensitiveDetector sd = description.sensitiveDetector(name);
1291  xml_attr_t type = element.attr_nothrow(_U(type));
1292  if ( type ) {
1293  sd.setType(element.attr<std::string>(type));
1294  }
1296  if ( verbose ) {
1297  sd.setVerbose(element.attr<bool>(verbose));
1298  }
1299  xml_attr_t combine = element.attr_nothrow(_U(combine_hits));
1300  if ( combine ) {
1301  sd.setCombineHits(element.attr<bool>(combine));
1302  }
1303  xml_attr_t limits = element.attr_nothrow(_U(limits));
1304  if ( limits ) {
1305  std::string l = element.attr<std::string>(limits);
1306  LimitSet ls = description.limitSet(l);
1307  if (!ls.isValid()) {
1308  throw_print("Converter<SensitiveDetector>: Request for non-existing limitset:" + l);
1309  }
1310  sd.setLimitSet(ls);
1311  }
1312  xml_attr_t region = element.attr_nothrow(_U(region));
1313  if ( region ) {
1314  std::string r = element.attr<std::string>(region);
1315  Region reg = description.region(r);
1316  if (!reg.isValid()) {
1317  throw_print("Converter<SensitiveDetector>: Request for non-existing region:" + r);
1318  }
1319  sd.setRegion(reg);
1320  }
1321  xml_attr_t hits = element.attr_nothrow(_U(hits_collection));
1322  if (hits) {
1323  sd.setHitsCollection(element.attr<std::string>(hits));
1324  }
1325  xml_attr_t ecut = element.attr_nothrow(_U(ecut));
1326  xml_attr_t eunit = element.attr_nothrow(_U(eunit));
1327  if (ecut && eunit) {
1328  double value = _multiply<double>(_toString(ecut), _toString(eunit));
1329  sd.setEnergyCutoff(value);
1330  }
1331  else if (ecut) { // If no unit is given , we assume the correct Geant4 unit is used!
1332  sd.setEnergyCutoff(element.attr<double>(ecut));
1333  }
1334  printout(DEBUG, "Compact", "SensitiveDetector-update: %-18s %-24s Hits:%-24s Cutoff:%7.3f", sd.name(),
1335  (" [" + sd.type() + "]").c_str(), sd.hitsCollection().c_str(), sd.energyCutoff());
1336  xml_attr_t sequence = element.attr_nothrow(_U(sequence));
1337  if (sequence) {
1338  }
1339  }
1340  catch (const std::exception& e) {
1341  printout(ERROR, "Compact", "++ FAILED to convert sensitive detector: %s: %s", name.c_str(), e.what());
1342  }
1343  catch (...) {
1344  printout(ERROR, "Compact", "++ FAILED to convert sensitive detector: %s: %s", name.c_str(), "UNKNONW Exception");
1345  }
1346 }
1347 
1348 static void setChildTitles(const std::pair<std::string, DetElement>& e) {
1349  DetElement parent = e.second.parent();
1350  const DetElement::Children& children = e.second.children();
1351  if (::strlen(e.second->GetTitle()) == 0) {
1352  e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
1353  }
1354  for_each(children.begin(), children.end(), setChildTitles);
1355 }
1356 
1357 template <> void Converter<DetElement>::operator()(xml_h element) const {
1358  static const char* req_dets = ::getenv("REQUIRED_DETECTORS");
1359  static const char* req_typs = ::getenv("REQUIRED_DETECTOR_TYPES");
1360  static const char* ign_dets = ::getenv("IGNORED_DETECTORS");
1361  static const char* ign_typs = ::getenv("IGNORED_DETECTOR_TYPES");
1362  std::string type = element.attr<std::string>(_U(type));
1363  std::string name = element.attr<std::string>(_U(name));
1364  std::string name_match = ":" + name + ":";
1365  std::string type_match = ":" + type + ":";
1366 
1367  if (req_dets && !strstr(req_dets, name_match.c_str()))
1368  return;
1369  if (req_typs && !strstr(req_typs, type_match.c_str()))
1370  return;
1371  if (ign_dets && strstr(ign_dets, name_match.c_str()))
1372  return;
1373  if (ign_typs && strstr(ign_typs, type_match.c_str()))
1374  return;
1375  xml_attr_t attr_ignore = element.attr_nothrow(_U(ignore));
1376  if ( attr_ignore ) {
1377  bool ignore_det = element.attr<bool>(_U(ignore));
1378  if ( ignore_det ) {
1379  printout(INFO, "Compact",
1380  "+++ Do not build subdetector:%s [ignore flag set]",
1381  name.c_str());
1382  return;
1383  }
1384  }
1385  try {
1386  std::string par_name;
1387  xml_attr_t attr_par = element.attr_nothrow(_U(parent));
1388  xml_elt_t elt_par(0);
1389  if (attr_par)
1390  par_name = element.attr<std::string>(attr_par);
1391  else if ( (elt_par=element.child(_U(parent),false)) )
1392  par_name = elt_par.attr<std::string>(_U(name));
1393  if ( !par_name.empty() ) {
1394  // We have here a nested detector. If the mother volume is not yet registered
1395  // it must be done here, so that the detector constructor gets the correct answer from
1396  // the call to Detector::pickMotherVolume(DetElement).
1397  if ( par_name[0] == '$' ) par_name = xml::getEnviron(par_name);
1398  DetElement parent = description.detector(par_name);
1399  if ( !parent.isValid() ) {
1400  except("Compact","Failed to access valid parent detector of %s",name.c_str());
1401  }
1402  description.declareParent(name, parent);
1403  }
1404  xml_attr_t attr_ro = element.attr_nothrow(_U(readout));
1405  SensitiveDetector sd;
1406  Segmentation seg;
1407  if ( attr_ro ) {
1408  Readout ro = description.readout(element.attr<std::string>(attr_ro));
1409  if (!ro.isValid()) {
1410  except("Compact","No Readout structure present for detector:" + name);
1411  }
1412  seg = ro.segmentation();
1413  sd = SensitiveDetector(name, "sensitive");
1414  sd.setHitsCollection(ro.name());
1415  sd.setReadout(ro);
1416  description.addSensitiveDetector(sd);
1417  }
1418  Ref_t sens = sd;
1419  DetElement det(Ref_t(PluginService::Create<NamedObject*>(type, &description, &element, &sens)));
1420  if (det.isValid()) {
1421  setChildTitles(std::make_pair(name, det));
1422  if ( sd.isValid() ) {
1424  }
1425  if ( seg.isValid() ) {
1426  seg->sensitive = sd;
1427  seg->detector = det;
1428  }
1429  }
1430  printout(det.isValid() ? INFO : ERROR, "Compact", "%s subdetector:%s of type %s %s",
1431  (det.isValid() ? "++ Converted" : "FAILED "), name.c_str(), type.c_str(),
1432  (sd.isValid() ? ("[" + sd.type() + "]").c_str() : ""));
1433 
1434  if (!det.isValid()) {
1435  PluginDebug dbg;
1436  PluginService::Create<NamedObject*>(type, &description, &element, &sens);
1437  except("Compact","Failed to execute subdetector creation plugin. %s", dbg.missingFactory(type).c_str());
1438  }
1439  description.addDetector(det);
1440  description.surfaceManager().registerSurfaces(det);
1441  return;
1442  }
1443  catch (const std::exception& e) {
1444  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
1445  std::terminate();
1446  }
1447  catch (...) {
1448  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
1449  std::terminate();
1450  }
1451 }
1452 
1454 template <> void Converter<IncludeFile>::operator()(xml_h element) const {
1455  xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
1456  if ( s_debug.include_guard) {
1457  // Include guard, we check whether this file was already processed
1458  if (check_process_file(description, doc.uri()))
1459  return;
1460  }
1461  xml_h root = doc.root();
1462  if ( s_debug.includes ) {
1463  printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
1464  }
1465  if ( root.tag() == "materials" || root.tag() == "elements" ) {
1466  xml_coll_t(root, _U(isotope)).for_each(Converter<Isotope>(this->description,0,0));
1467  xml_coll_t(root, _U(element)).for_each(Converter<Atom>(this->description));
1468  xml_coll_t(root, _U(material)).for_each(Converter<Material>(this->description));
1469  return;
1470  }
1471  this->description.fromXML(doc.uri(), this->description.buildType());
1472 }
1473 
1475 template <> void Converter<JsonFile>::operator()(xml_h element) const {
1476  std::string base = xml::DocumentHandler::system_directory(element);
1477  std::string file = element.attr<std::string>(_U(ref));
1478  std::vector<char*> argv{&file[0], &base[0]};
1479  description.apply("DD4hep_JsonProcessor",int(argv.size()), &argv[0]);
1480 }
1481 
1483 template <> void Converter<XMLFile>::operator()(xml_h element) const {
1484  PrintLevel level = s_debug.includes ? ALWAYS : DEBUG;
1485  std::string fname = element.attr<std::string>(_U(ref));
1486  std::size_t idx = fname.find("://");
1487  std::error_code ec;
1488 
1489  if ( idx == std::string::npos && std::filesystem::exists(fname, ec) ) {
1490  // Regular file without protocol specification
1491  printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1492  this->description.fromXML(fname, this->description.buildType());
1493  }
1494  else if ( idx == std::string::npos ) {
1495  // File relative to location of xml tag (protocol specification not possible)
1496  std::string location = xml::DocumentHandler::system_path(element, fname);
1497  printout(level, "Compact","++ Processing xml document %s.", location.c_str());
1498  this->description.fromXML(location, this->description.buildType());
1499  }
1500  else if ( idx > 0 ) {
1501  // File with protocol specification: must trust the location and the parser capabilities
1502  printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1503  this->description.fromXML(fname, this->description.buildType());
1504  }
1505  else {
1506  // Are there any other possibilities ?
1507  printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1508  this->description.fromXML(fname, this->description.buildType());
1509  }
1510 }
1511 
1513 template <> void Converter<World>::operator()(xml_h element) const {
1514  xml_elt_t x_world(element);
1515  xml_comp_t x_shape = x_world.child(_U(shape), false);
1516  xml_attr_t att = x_world.getAttr(_U(material));
1517  Material mat = att ? description.material(x_world.attr<std::string>(att)) : description.air();
1518  Volume world_vol;
1519 
1521  if ( x_shape ) {
1522  Solid sol(x_shape.createShape());
1523  world_vol = Volume("world_volume", sol, mat);
1524  printout(INFO, "Compact", "++ Created successfully world volume '%s'. shape: %s material:%s.",
1525  world_vol.name(), sol.type(), mat.name());
1526  description.manager().SetTopVolume(world_vol.ptr());
1527  }
1528  else {
1529  world_vol = description.worldVolume();
1530  if ( !world_vol && att ) {
1533  Box sol("world_x", "world_y", "world_z");
1534  world_vol = Volume("world_volume", sol, mat);
1535  printout(INFO, "Compact", "++ Created world volume '%s' as %s (%.2f, %.2f %.2f [cm]) material:%s.",
1536  world_vol.name(), sol.type(),
1537  sol.x()/dd4hep::cm, sol.y()/dd4hep::cm, sol.z()/dd4hep::cm,
1538  mat.name());
1539  description.manager().SetTopVolume(world_vol.ptr());
1540  }
1541  else if ( !world_vol ) {
1542  except("Compact", "++ Logical error: "
1543  "You cannot configure the world volume before it is created and not giving creation instructions.");
1544  }
1545  }
1546  // Delegate further configuration o0f the world volume to the xml utilities:
1547  if ( world_vol.isValid() ) {
1548  xml::configVolume(description, x_world, world_vol, false, true);
1549  auto vis = world_vol.visAttributes();
1550  if ( !vis.isValid() ) {
1551  vis = description.visAttributes("WorldVis");
1552  world_vol.setVisAttributes(vis);
1553  }
1554  }
1555 }
1556 
1558 template <> void Converter<Parallelworld_Volume>::operator()(xml_h element) const {
1559  xml_det_t parallel(element);
1560  xml_comp_t shape = parallel.child(_U(shape));
1561  xml_dim_t pos = element.child(_U(position),false);
1562  xml_dim_t rot = element.child(_U(rotation),false);
1563  std::string name = element.attr<std::string>(_U(name));
1564  std::string path = element.attr<std::string>(_U(anchor));
1565  bool conn = element.attr<bool>(_U(connected),false);
1566  DetElement anchor(detail::tools::findElement(description, path));
1567  Position position = pos ? Position(pos.x(), pos.y(), pos.z()) : Position();
1568  RotationZYX rotation = rot ? RotationZYX(rot.z(), rot.y(), rot.x()) : RotationZYX();
1569 
1570  Material mat = parallel.hasAttr(_U(material))
1571  ? description.material(parallel.attr<std::string>(_U(material)))
1572  : description.air();
1573  VisAttr vis = parallel.hasAttr(_U(vis))
1574  ? description.invisible()
1575  : description.visAttributes(parallel.visStr());
1576 
1577  if ( !anchor.isValid() ) {
1578  except("Parallelworld_Volume",
1579  "++ FAILED Cannot identify the anchor of the tracking volume: '%s'",
1580  path.c_str());
1581  }
1582 
1584  Transform3D tr_volume(detail::matrix::_transform(anchor.nominal().worldTransformation().Inverse()));
1585  Solid sol(shape.createShape());
1586  Volume vol(name, sol, mat);
1587  Volume par = conn ? description.worldVolume() : description.parallelWorldVolume();
1588  PlacedVolume pv;
1589 
1591  vol.setVisAttributes(vis);
1593  vol.setFlagBit(Volume::VETO_SIMU);
1594 
1596  Transform3D trafo = tr_volume * Transform3D(rotation,position); // Is this the correct order ?
1597  pv = par.placeVolume(vol, trafo);
1598  if ( !pv.isValid() ) {
1599  except("Parallelworld_Volume",
1600  "++ FAILED to place the tracking volume inside the anchor '%s'",path.c_str());
1601  }
1602  if ( name == "tracking_volume" ) {
1603  description.setTrackingVolume(vol);
1604  }
1605  printout(INFO, "Compact", "++ Converted successfully parallelworld_volume %s. anchor: %s vis:%s.",
1606  vol.name(), anchor.path().c_str(), vis.name());
1607 }
1608 
1610 template <> void Converter<DetElementInclude>::operator()(xml_h element) const {
1611  std::string type = element.hasAttr(_U(type)) ? element.attr<std::string>(_U(type)) : std::string("xml");
1612  if ( type == "xml" ) {
1613  xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
1614  if ( s_debug.include_guard ) {
1615  // Include guard, we check whether this file was already processed
1616  if (check_process_file(description, doc.uri()))
1617  return;
1618  }
1619  if ( s_debug.includes ) {
1620  printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
1621  }
1622  xml_h node = doc.root();
1623  std::string tag = node.tag();
1624  if ( tag == "lccdd" )
1625  Converter<Compact>(this->description)(node);
1626  else if ( tag == "define" )
1627  xml_coll_t(node, _U(constant)).for_each(Converter<Constant>(this->description));
1628  else if ( tag == "readout" )
1629  Converter<Readout>(this->description)(node);
1630  else if ( tag == "readouts" )
1631  xml_coll_t(node, _U(readout)).for_each(Converter<Readout>(this->description));
1632  else if ( tag == "region" )
1633  Converter<Region>(this->description)(node);
1634  else if ( tag == "regions" )
1635  xml_coll_t(node, _U(region)).for_each(Converter<Region>(this->description));
1636  else if ( tag == "limits" || tag == "limitsets" )
1637  xml_coll_t(node, _U(limitset)).for_each(Converter<LimitSet>(this->description));
1638  else if ( tag == "display" )
1639  xml_coll_t(node,_U(vis)).for_each(Converter<VisAttr>(this->description));
1640  else if ( tag == "detector" )
1641  Converter<DetElement>(this->description)(node);
1642  else if ( tag == "detectors" )
1643  xml_coll_t(node,_U(detector)).for_each(Converter<DetElement>(this->description));
1644  }
1645  else if ( type == "json" ) {
1646  Converter<JsonFile>(this->description)(element);
1647  }
1648  else if ( type == "gdml" ) {
1649  Converter<IncludeFile>(this->description)(element);
1650  }
1651  else if ( type == "include" ) {
1652  Converter<IncludeFile>(this->description)(element);
1653  }
1654  else if ( type == "xml-extended" ) {
1655  Converter<XMLFile>(this->description)(element);
1656  }
1657  else {
1658  except("Compact","++ FAILED Invalid file type:%s. This cannot be processed!",type.c_str());
1659  }
1660 }
1661 
1663 template <> void Converter<Compact>::operator()(xml_h element) const {
1664  static int num_calls = 0;
1665  char text[32];
1666 
1667  ++num_calls;
1668  xml_elt_t compact(element);
1669  bool steer_geometry = compact.hasChild(_U(geometry));
1670  bool open_geometry = true;
1671  bool close_document = true;
1672  bool close_geometry = true;
1673  bool build_reflections = false;
1674  xml_dim_t world = element.child(_U(world), false);
1675 
1676 
1677  if (element.hasChild(_U(debug)))
1678  (Converter<Debug>(description))(xml_h(compact.child(_U(debug))));
1679 
1680  if ( steer_geometry ) {
1681  xml_elt_t steer = compact.child(_U(geometry));
1682  if ( steer.hasAttr(_U(open)) )
1683  open_geometry = steer.attr<bool>(_U(open));
1684  if ( steer.hasAttr(_U(close)) )
1685  close_document = steer.attr<bool>(_U(close));
1686  if ( steer.hasAttr(_U(reflect)) )
1687  build_reflections = steer.attr<bool>(_U(reflect));
1688  for (xml_coll_t clr(steer, _U(clear)); clr; ++clr) {
1689  std::string nam = clr.hasAttr(_U(name)) ? clr.attr<std::string>(_U(name)) : std::string();
1690  if ( nam.substr(0,6) == "elemen" ) {
1691  TGeoElementTable* table = description.manager().GetElementTable();
1692  table->TGeoElementTable::~TGeoElementTable();
1693  new(table) TGeoElementTable();
1694  // This will initialize the table without filling:
1695  table->AddElement("VACUUM","VACUUM" ,0, 0, 0.0);
1696  printout(INFO,"Compact",
1697  "++ Cleared default ROOT TGeoElementTable contents. "
1698  "Must now be filled from XML!");
1699  }
1700  }
1701  }
1702 
1703  if ( s_debug.materials || s_debug.elements ) {
1704  printout(INFO,"Compact","+++ UNIT System:");
1705  printout(INFO,"Compact","+++ Density: %8.3g Units:%8.3g",
1706  xml::_toDouble(_Unicode(gram/cm3)), dd4hep::gram/dd4hep::cm3);
1707  printout(INFO,"Compact","+++ GeV: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(GeV)),dd4hep::GeV);
1708  printout(INFO,"Compact","+++ sec: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(second)),dd4hep::second);
1709  printout(INFO,"Compact","+++ nanosecond: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(nanosecond)),dd4hep::nanosecond);
1710  printout(INFO,"Compact","+++ kilo: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(kilogram)),dd4hep::kilogram);
1711  printout(INFO,"Compact","+++ kilo: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(joule*s*s/(m*m))),
1712  dd4hep::joule*dd4hep::s*dd4hep::s/(dd4hep::meter*dd4hep::meter));
1713  printout(INFO,"Compact","+++ meter: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(meter)),dd4hep::meter);
1714  printout(INFO,"Compact","+++ ampere: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(ampere)),dd4hep::ampere);
1715  printout(INFO,"Compact","+++ degree: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(degree)),dd4hep::degree);
1716  }
1717 
1718  xml_coll_t(compact, _U(define)).for_each(_U(include), Converter<DetElementInclude>(description));
1719  xml_coll_t(compact, _U(define)).for_each(_U(constant), Converter<Constant>(description));
1720  xml_coll_t(compact, _U(std_conditions)).for_each( Converter<STD_Conditions>(description));
1721  xml_coll_t(compact, _U(includes)).for_each(_U(gdmlFile), Converter<IncludeFile>(description));
1722  xml_coll_t(compact, _U(includes)).for_each(_U(file), Converter<IncludeFile>(description));
1723 
1724  if (element.hasChild(_U(info)))
1725  (Converter<Header>(description))(xml_h(compact.child(_U(info))));
1726 
1728  xml_coll_t(compact, _U(properties)).for_each(_U(attributes), Converter<Property>(description));
1729  xml_coll_t(compact, _U(properties)).for_each(_U(constant), Converter<PropertyConstant>(description));
1730  xml_coll_t(compact, _U(properties)).for_each(_U(matrix), Converter<PropertyTable>(description));
1731  xml_coll_t(compact, _U(properties)).for_each(_U(plugin), Converter<Plugin> (description));
1732  xml_coll_t(compact, _U(surfaces)).for_each(_U(opticalsurface), Converter<OpticalSurface>(description));
1733 
1734  xml_coll_t(compact, _U(materials)).for_each(_U(element), Converter<Atom>(description));
1735  xml_coll_t(compact, _U(materials)).for_each(_U(material), Converter<Material>(description));
1736  xml_coll_t(compact, _U(materials)).for_each(_U(plugin), Converter<Plugin> (description));
1737 
1738  printout(DEBUG, "Compact", "++ Converting visualization attributes...");
1739  xml_coll_t(compact, _U(display)).for_each(_U(include), Converter<DetElementInclude>(description));
1740  xml_coll_t(compact, _U(display)).for_each(_U(vis), Converter<VisAttr>(description));
1741 
1742  printout(DEBUG, "Compact", "++ Converting limitset structures...");
1743  xml_coll_t(compact, _U(limits)).for_each(_U(include), Converter<DetElementInclude>(description));
1744  xml_coll_t(compact, _U(limits)).for_each(_U(limitset), Converter<LimitSet>(description));
1745 
1746  printout(DEBUG, "Compact", "++ Converting region structures...");
1747  xml_coll_t(compact, _U(regions)).for_each(_U(include), Converter<DetElementInclude>(description));
1748  xml_coll_t(compact, _U(regions)).for_each(_U(region), Converter<Region>(description));
1749 
1750  if ( world ) {
1751  (Converter<World>(description))(world);
1752  }
1753  if ( open_geometry ) description.init();
1754  printout(DEBUG, "Compact", "++ Converting readout structures...");
1755  xml_coll_t(compact, _U(readouts)).for_each(_U(include), Converter<DetElementInclude>(description));
1756  xml_coll_t(compact, _U(readouts)).for_each(_U(readout), Converter<Readout>(description));
1757 
1758  printout(DEBUG, "Compact", "++ Converting included files with subdetector structures...");
1759  xml_coll_t(compact, _U(detectors)).for_each(_U(include), Converter<DetElementInclude>(description));
1760  printout(DEBUG, "Compact", "++ Converting detector structures...");
1761  xml_coll_t(compact, _U(detectors)).for_each(_U(detector), Converter<DetElement>(description));
1762  xml_coll_t(compact, _U(include)).for_each(Converter<DetElementInclude>(this->description));
1763 
1764  xml_coll_t(compact, _U(includes)).for_each(_U(xml), Converter<XMLFile>(description));
1765  xml_coll_t(compact, _U(fields)).for_each(_U(field), Converter<CartesianField>(description));
1766  xml_coll_t(compact, _U(sensitive_detectors)).for_each(_U(sd), Converter<SensitiveDetector>(description));
1767  xml_coll_t(compact, _U(parallelworld_volume)).for_each(Converter<Parallelworld_Volume>(description));
1768 
1769  if ( --num_calls == 0 && close_document ) {
1770  ::snprintf(text, sizeof(text), "%u", xml_h(element).checksum(0));
1771  description.addConstant(Constant("compact_checksum", text));
1772  description.endDocument(close_geometry);
1773  }
1774  if ( build_reflections ) {
1775  ReflectionBuilder rb(description);
1776  rb.execute();
1777  }
1779  xml_coll_t(compact, _U(plugins)).for_each(_U(plugin), Converter<Plugin> (description));
1780  xml_coll_t(compact, _U(plugins)).for_each(_U(include), Converter<XMLFile> (description));
1781  xml_coll_t(compact, _U(plugins)).for_each(_U(xml), Converter<XMLFile> (description));
1782 }
1783 
1784 #ifdef _WIN32
1785 template Converter<Plugin>;
1786 template Converter<Constant>;
1787 template Converter<Material>;
1788 template Converter<Atom>;
1789 template Converter<VisAttr>;
1790 template Converter<Region>;
1791 template Converter<Readout>;
1792 template Converter<Segmentation>;
1793 template Converter<LimitSet>;
1794 template Converter<Property>;
1795 template Converter<CartesianField>;
1796 template Converter<SensitiveDetector>;
1797 template Converter<DetElement>;
1798 template Converter<GdmlFile>;
1799 template Converter<XMLFile>;
1800 template Converter<Header>;
1801 template Converter<DetElementInclude>;
1802 template Converter<Compact>;
1803 
1804 #endif
dd4hep::World
Handle class to hold the information of the top DetElement object 'world'.
Definition: World.h:31
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::xml::configVolume
std::size_t configVolume(dd4hep::Detector &detector, dd4hep::xml::Handle_t element, dd4hep::Volume volume, bool propagate, bool ignore_unknown_attr=false)
Configure volume properties from XML element.
Definition: Utilities.cpp:331
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::Collection_t
Class to support the access to collections of XmlNodes (or XmlElements)
Definition: XMLElements.h:636
dd4hep::Detector::setHeader
virtual void setHeader(Header h)=0
Accessor to the header entry.
dd4hep::OpticalSurface::stringToType
static EType stringToType(const std::string &type)
Convenience function forwarding to TGeoOpticalSurface.
Definition: OpticalSurfaces.h:83
dd4hep::DipoleField::zmin
double zmin
Definition: FieldTypes.h:80
cond
AlignmentCondition::Object * cond
Definition: AlignmentsCalculator.cpp:68
dd4hep::SensitiveDetector::setEnergyCutoff
SensitiveDetector & setEnergyCutoff(double value)
Set energy cut off.
Definition: DetElement.cpp:430
dd4hep::Detector::addIDSpecification
virtual Detector & addIDSpecification(const Handle< NamedObject > &element)=0
Add a new id descriptor by named reference to the detector description.
dd4hep::xml::Handle_t::tag
std::string tag() const
Text access to the element's tag.
Definition: XMLElements.h:414
dd4hep::Property
The property class to assign options to actions.
Definition: ComponentProperties.h:45
dd4hep::xml::_toDouble
double _toDouble(const XmlChar *value)
Conversion function from raw unicode string to double.
Definition: XMLElements.cpp:360
dd4hep::Detector::detector
virtual DetElement detector(const std::string &name) const =0
Retrieve a subdetector element by its name from the detector description.
dd4hep::DipoleField::rmax
double rmax
Definition: FieldTypes.h:81
OpticalSurfaces.h
Path.h
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
MatrixHelpers.h
dd4hep::Limit::particles
std::string particles
Particle the limit should be applied to.
Definition: Objects.h:391
dd4hep::HitCollection
Definition of the HitCollection parameters used by the Readout.
Definition: ObjectsInterna.h:157
dd4hep::info
std::size_t info(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:65
dd4hep::Detector::Properties
std::map< std::string, PropertyValues > Properties
Definition: Detector.h:95
dd4hep::DDSegmentation::BitFieldCoder
Helper class for decoding and encoding a bit field of 64bits for convenient declaration.
Definition: BitFieldCoder.h:113
dd4hep::exception
void exception(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:69
dd4hep::DetElement::type
std::string type() const
Access detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:97
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::Box::x
double x() const
Access half "length" of the box.
Definition: Shapes.cpp:155
dd4hep::MultipoleField
Implementation object of a Multipole magnetic field.
Definition: FieldTypes.h:152
dd4hep::_toDictionary
void _toDictionary(const std::string &name, const std::string &value)
Enter name value pair to the dictionary. "value" must be a numerical expression, which is evaluated.
Definition: Handle.cpp:240
dd4hep::SensitiveDetector::setHitsCollection
SensitiveDetector & setHitsCollection(const std::string &spec)
Assign the name of the hits collection.
Definition: DetElement.cpp:441
dd4hep::PropertyTable
Class to support the handling of optical surfaces.
Definition: PropertyTable.h:32
dd4hep::SensitiveDetector::setVerbose
SensitiveDetector & setVerbose(bool value)
Set flag to handle hits collection.
Definition: DetElement.cpp:452
dd4hep::debug
std::size_t debug(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:64
dd4hep::Limit
Small object describing a limit structure acting on a particle type.
Definition: Objects.h:388
dd4hep::Segmentation::sensitive
Handle< SensitiveDetectorObject > sensitive() const
Access the sensitive detector using this segmentation object.
Definition: Segmentations.cpp:125
dd4hep::Volume::solid
Solid solid() const
Access to Solid (Shape)
Definition: Volumes.cpp:1252
dd4hep::Detector::PropertyValues
std::map< std::string, std::string > PropertyValues
Definition: Detector.h:94
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
dd4hep::Handle< NamedObject >
dd4hep::Segmentation::detector
Handle< DetElementObject > detector() const
Access the main detector element using this segmentation object.
Definition: Segmentations.cpp:120
dd4hep::CartesianField::MAGNETIC
@ MAGNETIC
Definition: Fields.h:43
DetectorInterna.h
dd4hep::Detector::region
virtual Region region(const std::string &name) const =0
Retrieve a region object by its name from the detector description.
dd4hep::detail::matrix::_transform
TGeoHMatrix * _transform(const Transform3D &trans)
Convert a Transform3D object to a newly created TGeoHMatrix.
Definition: MatrixHelpers.cpp:140
dd4hep::_toString
std::string _toString(bool value)
String conversions: boolean value to string.
Definition: Handle.cpp:332
dd4hep::Solid_type< TGeoShape >
dd4hep::xml::Tag_t::c_str
const char * c_str() const
Access data buffer of STL string.
Definition: XMLElements.h:308
dd4hep::xml::Handle_t
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:380
dd4hep::Detector::worldVolume
virtual Volume worldVolume() const =0
Return handle to the world volume containing everything.
check_process_file
bool check_process_file(Detector &description, std::string filename)
Check whether a XML file was already processed.
Definition: Compact2Objects.cpp:274
Factories.h
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::OverlayedField::properties
Properties & properties() const
Access to properties container.
Definition: Fields.cpp:99
dd4hep::DipoleField
Implementation object of a dipole magnetic field.
Definition: FieldTypes.h:77
dd4hep::Volume::placeVolume
PlacedVolume placeVolume(const Volume &volume) const
Place daughter volume. The position and rotation are the identity.
Definition: Volumes.cpp:859
xml_coll_t
dd4hep::xml::Collection_t xml_coll_t
Definition: ConditionsRepository.cpp:35
dd4hep::Detector::addVisAttribute
virtual Detector & addVisAttribute(const Handle< NamedObject > &element)=0
Add a new visualisation attribute by named reference to the detector description.
dd4hep::SolenoidField::maxZ
double maxZ
Definition: FieldTypes.h:58
xml_attr_t
dd4hep::xml::Attribute xml_attr_t
Definition: XML.h:27
xml_comp_t
dd4hep::xml::Component xml_comp_t
Definition: XML.h:33
dd4hep::DDSegmentation::Segmentation::name
virtual const std::string & name() const
Access the segmentation name.
Definition: Segmentation.h:95
_Unicode
#define _Unicode(a)
Definition: Tags.h:24
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
dd4hep::Detector::addField
virtual Detector & addField(const Handle< NamedObject > &field)=0
Add a field component by named reference to the detector description.
dd4hep::xml::Element::setValue
void setValue(const T &val) const
Set element value.
Definition: XMLElements.h:904
DocumentHandler.h
dd4hep::Detector::addLimitSet
virtual Detector & addLimitSet(const Handle< NamedObject > &limset)=0
Add a new limit set by named reference to the detector description.
dd4hep::Material
Handle class describing a material.
Definition: Objects.h:271
dd4hep::ConstantField
Implementation object of a field with constant strength.
Definition: FieldTypes.h:34
dd4hep::xml::Handle_t::attr_name
const XmlChar * attr_name(const Attribute attr) const
Access attribute name (throws exception if not present)
Definition: XMLElements.cpp:854
dd4hep::xml::Tag_t
Class to support both way translation between C++ and XML strings.
Definition: XMLElements.h:254
dd4hep::xml::Handle_t::hasChild
bool hasChild(const XmlChar *tag) const
Check the existence of a child with a given tag name.
Definition: XMLElements.cpp:767
dd4hep::Detector::addConstant
virtual Detector & addConstant(const Handle< NamedObject > &element)=0
Add a new constant by named reference to the detector description.
dd4hep::STD_Conditions::temperature
double temperature
Definition: Detector.h:69
dd4hep::Detector::material
virtual Material material(const std::string &name) const =0
Retrieve a matrial by its name from the detector description.
dd4hep::DipoleField::zmax
double zmax
Definition: FieldTypes.h:79
dd4hep::SolenoidField::innerRadius
double innerRadius
Definition: FieldTypes.h:59
dd4hep::Detector::setTrackingVolume
virtual void setTrackingVolume(Volume vol)=0
Set the tracking volume of the detector.
dd4hep::STD_Conditions
Helper class to access default temperature and pressure.
Definition: Detector.h:58
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::Detector::air
virtual Material air() const =0
Return handle to material describing air.
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::Detector::addSensitiveDetector
virtual Detector & addSensitiveDetector(const Handle< NamedObject > &element)=0
Add a new sensitive detector by named reference to the detector description.
dd4hep::DipoleField::coefficents
Coefficents coefficents
Definition: FieldTypes.h:82
dd4hep::Handle::assign
void assign(Object *n, const std::string &nam, const std::string &title)
Assign a new named object. Note: object references must be managed by the user.
mix
#define mix(a, b, c)
Definition: Geant4EventSeed.h:113
dd4hep::Detector::apply
virtual long apply(const char *factory, int argc, char **argv) const =0
Manipulate geometry using factory converter.
dd4hep::xml::Handle_t::attr_value
const XmlChar * attr_value(const Attribute attr) const
Access attribute value by the attribute (throws exception if not present)
Definition: XMLElements.cpp:867
dd4hep::Detector::field
virtual OverlayedField field() const =0
Return handle to the combined electromagentic field description.
dd4hep::xml::Collection_t::for_each
void for_each(T oper) const
Loop processor using function object.
Definition: XMLElements.h:667
dd4hep::Detector::init
virtual void init()=0
Initialize geometry.
dd4hep::OpticalSurface::EFinish
Object::ESurfaceFinish EFinish
Definition: OpticalSurfaces.h:49
dd4hep::xml::Element::child
Handle_t child(const Strng_t &tag_value, bool except=true) const
Access child by tag name. Thow an exception if required in case the child is not present.
Definition: XMLElements.h:914
dd4hep::MultipoleField::B_z
double B_z
Constant Z field overlay.
Definition: FieldTypes.h:167
dd4hep::LimitSet
Handle class describing a set of limits as they are used for simulation.
Definition: Objects.h:424
dd4hep::SensitiveDetector::hitsCollection
const std::string & hitsCollection() const
Access the hits collection name.
Definition: DetElement.cpp:447
dd4hep::SolenoidField::minZ
double minZ
Definition: FieldTypes.h:57
OpticalSurfaceManager.h
dd4hep::xml::createShape
Solid createShape(Detector &description, const std::string &shape_type, xml::Element element)
Create a solid shape using the plugin mechanism from the attributes of the XML element.
Definition: Utilities.cpp:84
dd4hep::Limit::name
std::string name
Limit name.
Definition: Objects.h:393
dd4hep::OpticalSurfaceManager::registerSurfaces
void registerSurfaces(DetElement subdetector)
Register the temporary surface objects with the TGeoManager.
Definition: OpticalSurfaceManager.cpp:119
dd4hep::DetElementObject::flag
unsigned int flag
Flag to remember internally calculated quatities.
Definition: DetectorInterna.h:100
dd4hep::VisAttr::DASHED
@ DASHED
Definition: Objects.h:326
DetectorTools.h
dd4hep::Detector::sensitiveDetector
virtual SensitiveDetector sensitiveDetector(const std::string &name) const =0
Retrieve a sensitive detector by its name from the detector description.
dd4hep::DDSegmentation::Parameters
std::vector< Parameter > Parameters
Definition: SegmentationsInterna.h:35
dd4hep::Volume::VETO_SIMU
@ VETO_SIMU
Definition: Volumes.h:376
dd4hep::xml
Namespace for the AIDA detector description toolkit supporting XML utilities.
Definition: ConditionsTags.h:27
xml_det_t
dd4hep::xml::DetElement xml_det_t
Definition: XML.h:32
dd4hep::CartesianField::Properties
std::map< std::string, std::map< std::string, std::string > > Properties
Definition: Fields.h:45
_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::Detector::surfaceManager
virtual OpticalSurfaceManager surfaceManager() const =0
Access the optical surface manager.
Plugins.h
dd4hep::Detector::endDocument
virtual void endDocument(bool close_geometry=true)=0
Finalize the geometry.
dd4hep::Detector::stdConditions
virtual const STD_Conditions & stdConditions() const =0
Access default conditions (temperature and pressure.
dd4hep::Region
Handle class describing a region as used in simulation.
Definition: Objects.h:461
dd4hep::PluginDebug
Helper to debug plugin manager calls.
Definition: Plugins.h:73
dd4hep::MultipoleField::transform
Transform3D transform
Position transformation of the field. Only stored here for reference.
Definition: FieldTypes.h:161
dd4hep::Header
Handle class describing the basic information about geometry objects as it is defined in Detector.
Definition: Objects.h:157
dd4hep::Limit::content
std::string content
Content.
Definition: Objects.h:397
dd4hep::Path::normalize
Path normalize() const
Normalize path name.
Definition: Path.cpp:114
dd4hep::SensitiveDetector::setReadout
SensitiveDetector & setReadout(Readout readout)
Assign the IDDescriptor reference.
Definition: DetElement.cpp:414
dd4hep::Readout::segmentation
Segmentation segmentation() const
Access segmentation structure.
Definition: Readout.cpp:134
dd4hep::Limit::unit
std::string unit
Units.
Definition: Objects.h:395
dd4hep::xml::Strng_t
Helper class to encapsulate a unicode string.
Definition: XMLElements.h:170
dd4hep::Detector::limitSet
virtual LimitSet limitSet(const std::string &name) const =0
Retrieve a limitset by its name from the detector description.
dd4hep::DDSegmentation::splitString
std::vector< std::string > splitString(const std::string &s, char delimiter=' ')
Helper method to split string into tokens.
Definition: SegmentationParameter.h:33
dd4hep::PluginDebug::missingFactory
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
Definition: Plugins.cpp:147
dd4hep::ReflectionBuilder
Scan geometry and create reflected volumes.
Definition: Volumes.h:60
dd4hep::sim::IDDescriptor
IDDescriptor IDDescriptor
Definition: LCIOConversions.cpp:69
dd4hep::verbose
std::size_t verbose(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:63
dd4hep::xml::DocumentHolder
Class supporting the basic functionality of an XML document including ownership.
Definition: XMLElements.h:741
dd4hep::Limit::value
double value
Double value.
Definition: Objects.h:399
dd4hep::xml::Handle_t::child
Handle_t child(const XmlChar *tag, bool throw_exception=true) const
Access a single child by its tag name (unicode)
Definition: XMLElements.cpp:713
DECLARE_XML_DOC_READER
#define DECLARE_XML_DOC_READER(name, func)
Definition: Factories.h:316
dd4hep::Detector::invisible
virtual VisAttr invisible() const =0
Return handle to "invisible" visualization attributes.
dd4hep::xml::Element::hasAttr
bool hasAttr(const XmlChar *name) const
Check for the existence of a named attribute.
Definition: XMLElements.h:847
detectors
DetectorMap detectors
Definition: AlignmentsCalculator.cpp:79
dd4hep::Detector::visAttributes
virtual const HandleMap & visAttributes() const =0
Accessor to the map of visualisation attributes.
dd4hep::Transform3D
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:116
dd4hep::SensitiveDetector::type
std::string type() const
Access the type of the sensitive detector.
Definition: DetElement.cpp:409
xml_tag_t
dd4hep::xml::Tag_t xml_tag_t
Definition: XML.h:26
xml_h
dd4hep::xml::Handle_t xml_h
Definition: ConditionsRepository.cpp:32
DECLARE_XMLELEMENT
#define DECLARE_XMLELEMENT(name, func)
Definition: Factories.h:301
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:80
dd4hep::xml::RefElement
User abstraction class to manipulate named XML elements (references) within a document.
Definition: XMLElements.h:953
dd4hep::CartesianField::TypedObject::field_type
int field_type
Field type.
Definition: Fields.h:56
ProcessedFilesSet
Definition: Compact2Objects.cpp:271
dd4hep::Ref_t
Handle< NamedObject > Ref_t
Default Ref_t definition describing named objects.
Definition: Handle.h:180
DetFactoryHelper.h
SegmentationsInterna.h
dd4hep::SolenoidField::outerField
double outerField
Definition: FieldTypes.h:56
dd4hep::_toDouble
double _toDouble(const std::string &value)
String conversions: string to double value.
Definition: Handle.cpp:116
key
unsigned char key
Definition: AlignmentsCalculator.cpp:69
dd4hep::Segmentation::segmentation
DDSegmentation::Segmentation * segmentation() const
Access to the base DDSegmentation object. WARNING: Deprecated call!
Definition: Segmentations.cpp:105
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
IDDescriptor.h
dd4hep::xml::DocumentHandler
Class supporting to read and parse XML documents.
Definition: DocumentHandler.h:39
dd4hep::OpticalSurface::stringToModel
static EModel stringToModel(const std::string &model)
Definition: OpticalSurfaces.h:90
std
Definition: Plugins.h:29
dd4hep::MultipoleField::skews
Coefficents skews
Multi-pole skews.
Definition: FieldTypes.h:157
dd4hep::VisAttr::SOLID
@ SOLID
Definition: Objects.h:326
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:151
ObjectsInterna.h
PropertyTable.h
dd4hep::_multiply< double >
double _multiply< double >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:236
dd4hep::Detector::constant
virtual Constant constant(const std::string &name) const =0
Retrieve a constant by its name from the detector description.
dd4hep::xml::Element
User abstraction class to manipulate XML elements within a document.
Definition: XMLElements.h:769
dd4hep::xml::dump_tree
void dump_tree(Handle_t elt)
Dump partial or full XML trees to stdout.
Definition: DocumentHandler.cpp:698
dd4hep::MultipoleField::volume
Solid volume
Boundary volume (optional)
Definition: FieldTypes.h:159
dd4hep::SensitiveDetector::energyCutoff
double energyCutoff() const
Access energy cut off.
Definition: DetElement.cpp:436
dd4hep::Volume::setVisAttributes
const Volume & setVisAttributes(const VisAttr &obj) const
Set Visualization attributes to the volume.
Definition: Volumes.cpp:1156
dd4hep::Detector::extension
IFACE * extension(bool alert=true) const
Access extension element by the type.
Definition: Detector.h:342
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::xml::Tag_t::str
const std::string & str() const
Access writable STL string.
Definition: XMLElements.h:304
dd4hep::DDSegmentation::TypedSegmentationParameter
Concrete class to hold a segmentation parameter of a given type with its description.
Definition: SegmentationParameter.h:166
dd4hep::VisAttr::WIREFRAME
@ WIREFRAME
Definition: Objects.h:326
dd4hep::xml::Handle_t::attributes
std::vector< Attribute > attributes() const
Retrieve a collection of all attributes of this DOM element.
Definition: XMLElements.cpp:681
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::MultipoleField::coefficents
Coefficents coefficents
Multi-pole coefficients.
Definition: FieldTypes.h:155
dd4hep::OpticalSurface::EModel
Object::ESurfaceModel EModel
Definition: OpticalSurfaces.h:48
dd4hep::STD_Conditions::pressure
double pressure
Definition: Detector.h:68
dd4hep::xml::getEnviron
std::string getEnviron(const std::string &env)
Helper function to lookup environment from the expression evaluator.
Definition: XMLElements.cpp:406
dd4hep::Detector::fromXML
virtual void fromXML(const std::string &fname, DetectorBuildType type=BUILD_DEFAULT)=0
Read any geometry description or alignment file.
dd4hep::Detector::addDetector
virtual Detector & addDetector(const Handle< NamedObject > &detector)=0
Add a new subdetector by named reference to the detector description.
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
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::xml::DocumentHandler::system_directory
static std::string system_directory(Handle_t base)
System directory of a given XML entity.
Definition: DocumentHandler.cpp:673
dd4hep::CartesianField::ELECTRIC
@ ELECTRIC
Definition: Fields.h:43
dd4hep::OpticalSurface::stringToFinish
static EFinish stringToFinish(const std::string &finish)
Definition: OpticalSurfaces.h:96
dd4hep::SensitiveDetector::setRegion
SensitiveDetector & setRegion(Region reg)
Set the regional attributes to the sensitive detector.
Definition: DetElement.cpp:476
dd4hep::Detector::setStdConditions
virtual void setStdConditions(double temp, double pressure)=0
Set the STD temperature and pressure.
dd4hep::SensitiveDetector::setCombineHits
SensitiveDetector & setCombineHits(bool value)
Set flag to handle hits collection.
Definition: DetElement.cpp:464
dd4hep::RotationZYX
ROOT::Math::RotationZYX RotationZYX
Definition: Objects.h:104
dd4hep::SolenoidField::outerRadius
double outerRadius
Definition: FieldTypes.h:60
dd4hep::DDSegmentation::Segmentation::addSubsegmentation
virtual void addSubsegmentation(long key_min, long key_max, Segmentation *entry)
Add subsegmentation. Call only valid for Multi-segmentations. Default implementation throws an except...
Definition: Segmentation.cpp:61
dd4hep::DetElementObject::HAVE_SENSITIVE_DETECTOR
@ HAVE_SENSITIVE_DETECTOR
Definition: DetectorInterna.h:92
dd4hep::xml::Handle_t::hasAttr
bool hasAttr(const XmlChar *t) const
Check for the existence of a named attribute.
Definition: XMLElements.cpp:676
dd4hep::Detector::readout
virtual Readout readout(const std::string &name) const =0
Retrieve a readout object by its name from the detector description.
dd4hep::SensitiveDetector::setLimitSet
SensitiveDetector & setLimitSet(LimitSet limits)
Set the limits to the sensitive detector.
Definition: DetElement.cpp:487
dd4hep::Detector::declareParent
virtual void declareParent(const std::string &detector_name, const DetElement &det)=0
Register new parent detector using the detector name.
dd4hep::xml::DocumentHandler::system_path
static std::string system_path(Handle_t base)
System ID of a given XML entity.
Definition: DocumentHandler.cpp:276
dd4hep::Detector::addReadout
virtual Detector & addReadout(const Handle< NamedObject > &readout)=0
Add a new detector readout by named reference to the detector description.
dd4hep::Detector::parallelWorldVolume
virtual Volume parallelWorldVolume() const =0
Return handle to the parallel world volume.
dd4hep::Volume::visAttributes
VisAttr visAttributes() const
Access the visualisation attributes.
Definition: Volumes.cpp:1239
DD4hepUnits.h
dd4hep::OpticalSurface::EType
Object::ESurfaceType EType
Definition: OpticalSurfaces.h:50
FieldTypes.h
dd4hep::DDSegmentation::Segmentation
Base class for all segmentations.
Definition: Segmentation.h:74
dd4hep::xml::Handle_t::attr
T attr(const Attribute a) const
Access typed attribute value by the XmlAttr.
Definition: XMLElements.h:454
Printout.h
xml_dim_t
dd4hep::xml::Dimension xml_dim_t
Definition: XML.h:31
dd4hep::OpticalSurface
Class to support the handling of optical surfaces.
Definition: OpticalSurfaces.h:42
Utilities.h
dd4hep::xml::Element::attr
T attr(const XmlAttr *att) const
Access attribute with implicit return type conversion.
Definition: XMLElements.h:851
dd4hep::xml::Handle_t::ptr
Elt_t ptr() const
Direct access to the XmlElement by function.
Definition: XMLElements.h:401
dd4hep::SolenoidField::innerField
double innerField
Definition: FieldTypes.h:55
dd4hep::Path
Path handling class.
Definition: Path.h:45
dd4hep::SensitiveDetector::setType
SensitiveDetector & setType(const std::string &typ)
Set detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:403
dd4hep::SolenoidField
Implementation object of a solenoidal magnetic field.
Definition: FieldTypes.h:53
Gaudi::PluginService::v1::Debug
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
Definition: PluginServiceV1.cpp:340
dd4hep::Detector::addRegion
virtual Detector & addRegion(const Handle< NamedObject > &region)=0
Add a new detector region by named reference to the detector description.
dd4hep::Detector::properties
virtual Properties & properties() const =0
Access to properties map.
dd4hep::CartesianField
Base class describing any field with 3D cartesian vectors for the field strength.
Definition: Fields.h:40
dd4hep::xml::Handle_t::attr_nothrow
Attribute attr_nothrow(const XmlChar *tag) const
Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
Definition: XMLElements.cpp:671
dd4hep::DDSegmentation::Segmentation::type
virtual const std::string & type() const
Access the segmentation type.
Definition: Segmentation.h:103