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