DD4hep  1.32.1
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 <climits>
52 #include <set>
53 
54 using namespace dd4hep;
55 
57 namespace dd4hep {
58 
59  class Debug;
60  class World;
61  class Isotope;
62  class Plugin;
63  class Compact;
64  class Includes;
65  class IncludeFile;
66  class Property;
67  class XMLFile;
68  class JsonFile;
69  class PropertyConstant;
70  class Parallelworld_Volume;
71  class DetElementInclude;
72  class STD_Conditions;
73 
75  template <> void Converter<Debug>::operator()(xml_h element) const;
76  template <> void Converter<World>::operator()(xml_h element) const;
77  template <> void Converter<Plugin>::operator()(xml_h element) const;
78  template <> void Converter<Constant>::operator()(xml_h element) const;
79  template <> void Converter<Material>::operator()(xml_h element) const;
80  template <> void Converter<Atom>::operator()(xml_h element) const;
81  template <> void Converter<Isotope>::operator()(xml_h element) const;
82  template <> void Converter<VisAttr>::operator()(xml_h element) const;
83  template <> void Converter<Region>::operator()(xml_h element) const;
84  template <> void Converter<Readout>::operator()(xml_h element) const;
85  template <> void Converter<Segmentation>::operator()(xml_h element) const;
86  template <> void Converter<LimitSet>::operator()(xml_h element) const;
87  template <> void Converter<Property>::operator()(xml_h element) const;
88  template <> void Converter<CartesianField>::operator()(xml_h element) const;
89  template <> void Converter<SensitiveDetector>::operator()(xml_h element) const;
90  template <> void Converter<OpticalSurface>::operator()(xml_h element) const;
91  template <> void Converter<PropertyTable>::operator()(xml_h element) const;
92  template <> void Converter<PropertyConstant>::operator()(xml_h element) const;
93  template <> void Converter<DetElement>::operator()(xml_h element) const;
94  template <> void Converter<STD_Conditions>::operator()(xml_h element) const;
95  template <> void Converter<IncludeFile>::operator()(xml_h element) const;
96  template <> void Converter<JsonFile>::operator()(xml_h element) const;
97  template <> void Converter<XMLFile>::operator()(xml_h element) const;
98  template <> void Converter<Header>::operator()(xml_h element) const;
99  template <> void Converter<DetElementInclude>::operator()(xml_h element) const;
100  template <> void Converter<Parallelworld_Volume>::operator()(xml_h element) const;
101  template <> void Converter<Compact>::operator()(xml_h element) const;
102 }
103 
104 namespace {
105  static UInt_t unique_mat_id = 0xAFFEFEED;
106  void throw_print(const std::string& msg) {
107  printout(ERROR, "Compact", msg.c_str());
108  throw std::runtime_error(msg);
109  }
110  class DebugOptions {
111  public:
112  bool readout = false;
113  bool regions = false;
114  bool limits = false;
115  bool visattr = false;
116  bool isotopes = false;
117  bool elements = false;
118  bool materials = false;
119  bool segmentation = false;
120  bool constants = false;
121  bool includes = false;
122  bool matrix = false;
123  bool surface = false;
124  bool detelements = 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  else if ( nam.substr(0,6) == "detele" ) s_debug.detelements = (0 != val);
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.empty() ? nullptr : &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 = description.header();
396  if( !h.isValid() ) {
397  h = Header(e.attr<std::string>(_U(name)), e.attr<std::string>(_U(title), "Undefined"));
398  h.setUrl(e.attr<std::string>(_U(url), "Undefined"));
399  h.setAuthor(e.attr<std::string>(_U(author), "Undefined"));
400  h.setStatus(e.attr<std::string>(_U(status), "development"));
401  h.setVersion(e.attr<std::string>(_U(version), "Undefined"));
402  h.setComment(e.hasChild(_U(comment)) ? e.child(_U(comment)).text() : "No Comment");
403  description.setHeader(h);
404  return;
405  }
406  printout(WARNING, "Compact","++ Overwriting/updating Header structure is very dangerous. Try to avoid this.");
407  printout(WARNING, "Compact","++ Header definition in: %s", xml::DocumentHandler::system_path(e).c_str());
408  if( e.hasAttr(_U(comment)) ) h.setComment(e.attr<std::string>(_U(comment)).c_str());
409  if( e.hasAttr(_U(version)) ) h.setVersion(e.attr<std::string>(_U(version)).c_str());
410  if( e.hasAttr(_U(author)) ) h.setAuthor(e.attr<std::string>(_U(author)).c_str());
411  if( e.hasAttr(_U(status)) ) h.setStatus(e.attr<std::string>(_U(status)).c_str());
412  if( e.hasAttr(_U(title)) ) h.setTitle(e.attr<std::string>(_U(title)).c_str());
413  if( e.hasAttr(_U(name)) ) h.setName(e.attr<std::string>(_U(name)).c_str());
414  if( e.hasAttr(_U(url)) ) h.setUrl(e.attr<std::string>(_U(url)).c_str());
415 }
416 
433 template <> void Converter<Material>::operator()(xml_h e) const {
434  xml_ref_t x_mat(e);
435  TGeoManager& mgr = description.manager();
436  xml_tag_t mname = x_mat.name();
437  const char* matname = mname.c_str();
438  TGeoElementTable* table = mgr.GetElementTable();
439  TGeoMaterial* mat = mgr.GetMaterial(matname);
440  TGeoMixture* mix = dynamic_cast<TGeoMixture*>(mat);
441  xml_coll_t fractions (x_mat, _U(fraction));
442  xml_coll_t composites(x_mat, _U(composite));
443 
444  if (0 == mat) {
445  TGeoMaterial* comp_mat;
446  TGeoElement* comp_elt;
447  xml_h density = x_mat.child(_U(D), false);
448  double dens_val = density.ptr() ? density.attr<double>(_U(value)) : 0.0;
449  double dens_unit = 1.0;
450 
451  if ( !density.ptr() ) {
452  throw_print("Compact2Objects[ERROR]: material without density tag ( <D unit=\"g/cm3\" value=\"..\"/> ) provided: "
453  + std::string( matname ) ) ;
454  }
455  if ( density.hasAttr(_U(unit)) ) {
456  dens_unit = density.attr<double>(_U(unit))/xml::_toDouble(_Unicode(gram/cm3));
457  }
458  if ( dens_unit != 1.0 ) {
459  dens_val *= dens_unit;
460  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact","Density unit: %.3f [%s] raw: %.3f normalized: %.3f ",
461  dens_unit, density.attr<std::string>(_U(unit)).c_str(), dens_val, (dens_val*dens_unit));
462  }
463  mat = mix = new TGeoMixture(matname, composites.size(), dens_val);
464  std::size_t ifrac = 0;
465  std::vector<double> composite_fractions;
466  double composite_fractions_total = 0.0;
467  for (composites.reset(); composites; ++composites) {
468  std::string nam = composites.attr<std::string>(_U(ref));
469  double fraction = composites.attr<double>(_U(n));
470  if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
471  fraction *= comp_mat->GetA();
472  else if (0 != (comp_elt = table->FindElement(nam.c_str())))
473  fraction *= comp_elt->A();
474  else
475  except("Compact2Objects","Converting material: %s Element missing: %s",mname.c_str(),nam.c_str());
476  composite_fractions_total += fraction;
477  composite_fractions.emplace_back(fraction);
478  }
479  for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) {
480  std::string nam = composites.attr<std::string>(_U(ref));
481  double fraction = composite_fractions[ifrac]/composite_fractions_total;
482  if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
483  mix->AddElement(comp_mat, fraction);
484  else if (0 != (comp_elt = table->FindElement(nam.c_str())))
485  mix->AddElement(comp_elt, fraction);
486  }
487  for (fractions.reset(); fractions; ++fractions) {
488  std::string nam = fractions.attr<std::string>(_U(ref));
489  double fraction = fractions.attr<double>(_U(n));
490  if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
491  mix->AddElement(comp_mat, fraction);
492  else if (0 != (comp_elt = table->FindElement(nam.c_str())))
493  mix->AddElement(comp_elt, fraction);
494  else
495  throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " Element missing: " + nam);
496  }
497  xml_h temperature = x_mat.child(_U(T), false);
498  double temp_val = description.stdConditions().temperature;
499  if ( temperature.ptr() ) {
500  double temp_unit = _toDouble("kelvin");
501  if ( temperature.hasAttr(_U(unit)) )
502  temp_unit = temperature.attr<double>(_U(unit));
503  temp_val = temperature.attr<double>(_U(value)) * temp_unit;
504  }
505  xml_h pressure = x_mat.child(_U(P), false);
506  double pressure_val = description.stdConditions().pressure;
507  if ( pressure.ptr() ) {
508  double pressure_unit = _toDouble("pascal");
509  if ( pressure.hasAttr(_U(unit)) )
510  pressure_unit = pressure.attr<double>(_U(unit));
511  pressure_val = pressure.attr<double>(_U(value)) * pressure_unit;
512  }
513 #if 0
514  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
515  "++ ROOT raw temperature and pressure: %.3g %.3g",
516  mat->GetTemperature(),mat->GetPressure());
517 #endif
518  mat->SetTemperature(temp_val);
519  mat->SetPressure(pressure_val);
520  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
521  "++ Converting material %-16s Density: %9.7g Temperature:%9.7g [K] Pressure:%9.7g [hPa].",
522  matname, dens_val, temp_val/dd4hep::kelvin, pressure_val/dd4hep::pascal/100.0);
523 
524  mix->SetRadLen(0e0);
525  mix->ComputeDerivedQuantities();
528  for(xml_coll_t properties(x_mat, _U(constant)); properties; ++properties) {
529  xml_elt_t p = properties;
530  if ( p.hasAttr(_U(ref)) ) {
531  bool err = kFALSE;
532  std::string ref = p.attr<std::string>(_U(ref));
533  mgr.GetProperty(ref.c_str(), &err);
534  if ( err == kFALSE ) {
535  std::string prop_nam = p.attr<std::string>(_U(name));
536  mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
537  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
538  "++ material %-16s add constant property: %s -> %s.",
539  mat->GetName(), prop_nam.c_str(), ref.c_str());
540  continue;
541  }
542  // ERROR
543  throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " ConstProperty missing in TGeoManager: " + ref);
544  }
545  else if ( p.hasAttr(_U(value)) ) {
546  std::stringstream str;
547  std::string ref, prop_nam = p.attr<std::string>(_U(name));
548  str << prop_nam << "_" << (void*)mat;
549  ref = str.str();
550  mgr.AddProperty(ref.c_str(), p.attr<double>(_U(value)));
551  mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
552  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
553  "++ material %-16s add constant property: %s -> %s.",
554  mat->GetName(), prop_nam.c_str(), ref.c_str());
555  }
556  else if ( p.hasAttr(_U(option)) ) {
557  std::string prop_nam = p.attr<std::string>(_U(name));
558  std::string prop_typ = p.attr<std::string>(_U(option));
559  mat->AddConstProperty(prop_nam.c_str(), prop_typ.c_str());
560  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
561  "++ material %-16s add constant property: %s -> %s.",
562  mat->GetName(), prop_nam.c_str(), prop_typ.c_str());
563  }
564  }
566  for(xml_coll_t properties(x_mat, _U(property)); properties; ++properties) {
567  xml_elt_t p = properties;
568  if ( p.hasAttr(_U(ref)) ) {
569  std::string ref = p.attr<std::string>(_U(ref));
570  TGDMLMatrix* gdmlMat = mgr.GetGDMLMatrix(ref.c_str());
571  if ( gdmlMat ) {
572  std::string prop_nam = p.attr<std::string>(_U(name));
573  mat->AddProperty(prop_nam.c_str(), ref.c_str());
574  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
575  "++ material %-16s add property: %s -> %s.",
576  mat->GetName(), prop_nam.c_str(), ref.c_str());
577  continue;
578  }
579  // ERROR
580  throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " Property missing: " + ref);
581  }
582  }
583  }
584  TGeoMedium* medium = mgr.GetMedium(matname);
585  if (0 == medium) {
586  --unique_mat_id;
587  medium = new TGeoMedium(matname, unique_mat_id, mat);
588  medium->SetTitle("material");
589  medium->SetUniqueID(unique_mat_id);
590  }
591  // TGeo has no notion of a material "formula"
592  // Hence, treat the formula the same way as the material itself
593  if (x_mat.hasAttr(_U(formula))) {
594  std::string form = x_mat.attr<std::string>(_U(formula));
595  if (form != matname) {
596  medium = mgr.GetMedium(form.c_str());
597  if (0 == medium) {
598  --unique_mat_id;
599  medium = new TGeoMedium(form.c_str(), unique_mat_id, mat);
600  medium->SetTitle("material");
601  medium->SetUniqueID(unique_mat_id);
602  }
603  }
604  }
605 }
606 
613 template <> void Converter<Isotope>::operator()(xml_h e) const {
614  xml_dim_t isotope(e);
615  TGeoManager& mgr = description.manager();
616  std::string nam = isotope.nameStr();
617  TGeoElementTable* tab = mgr.GetElementTable();
618  TGeoIsotope* iso = tab->FindIsotope(nam.c_str());
619 
620  // Create the isotope object in the event it is not yet present from the XML data
621  if ( !iso ) {
622  xml_ref_t atom(isotope.child(_U(atom)));
623  std::string unit = atom.attr<std::string>(_U(unit));
624  double value = atom.attr<double>(_U(value));
625  double a = value * _multiply<double>(unit,"mol/g");
626  int n = isotope.attr<int>(_U(N));
627  int z = isotope.attr<int>(_U(Z));
628  iso = new TGeoIsotope(nam.c_str(), z, n, a);
629  printout(s_debug.isotopes ? ALWAYS : DEBUG, "Compact",
630  "++ Converting isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol]",
631  iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
632  }
633  else {
634  printout(s_debug.isotopes ? WARNING : DEBUG, "Compact",
635  "++ Isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
636  iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
637  }
638 }
639 
654 template <> void Converter<Atom>::operator()(xml_h e) const {
655  xml_ref_t elem(e);
656  xml_tag_t name = elem.name();
657  TGeoManager& mgr = description.manager();
658  TGeoElementTable* tab = mgr.GetElementTable();
659  TGeoElement* elt = tab->FindElement(name.c_str());
660  if ( !elt ) {
661  if ( elem.hasChild(_U(atom)) ) {
662  xml_ref_t atom(elem.child(_U(atom)));
663  std::string formula = elem.attr<std::string>(_U(formula));
664  double value = atom.attr<double>(_U(value));
665  std::string unit = atom.attr<std::string>(_U(unit));
666  int z = elem.attr<int>(_U(Z));
667  double a = value*_multiply<double>(unit,"mol/g");
668  printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
669  "++ Converting element %-16s [%-3s] Z:%3d A:%8.4f [g/mol]",
670  name.c_str(), formula.c_str(), z, a);
671  tab->AddElement(name.c_str(), formula.c_str(), z, a);
672  }
673  else {
674  int num_isotopes = 0;
675  std::string formula = elem.hasAttr(_U(formula)) ? elem.attr<std::string>(_U(formula)) : name.str();
676  for( xml_coll_t i(elem,_U(fraction)); i; ++i)
677  ++num_isotopes;
678  elt = new TGeoElement(name.c_str(), formula.c_str(), num_isotopes);
679  tab->AddElement(elt);
680  for( xml_coll_t i(elem,_U(fraction)); i; ++i) {
681  double frac = i.attr<double>(_U(n));
682  std::string ref = i.attr<std::string>(_U(ref));
683  TGeoIsotope* iso = tab->FindIsotope(ref.c_str());
684  if ( !iso ) {
685  except("Compact","Element %s cannot be constructed. Isotope '%s' (fraction: %.3f) missing!",
686  name.c_str(), ref.c_str(), frac);
687  }
688  printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
689  "++ Converting element %-16s Add isotope: %-16s fraction:%.4f.",
690  name.c_str(), ref.c_str(), frac);
691  elt->AddIsotope(iso, frac);
692  }
693  printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
694  "++ Converted element %-16s [%-3s] Z:%3d A:%8.4f [g/mol] with %d isotopes.",
695  name.c_str(), formula.c_str(), elt->Z(), elt->A(), num_isotopes);
696  }
697  elt = tab->FindElement(name.c_str());
698  if (!elt) {
699  throw_print("Failed to properly insert the Element:"+name+" into the element table!");
700  }
701  }
702  else {
703  printout(s_debug.elements ? WARNING : DEBUG, "Compact",
704  "++ Element %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
705  elt->GetName(), elt->Z(), elt->N(), elt->A());
706  }
707 }
708 
716 template <> void Converter<STD_Conditions>::operator()(xml_h e) const {
717  xml_dim_t cond(e);
718  // Create the isotope object in the event it is not yet present from the XML data
719  if ( cond.ptr() ) {
720  if ( cond.hasAttr(_U(type)) ) {
721  description.setStdConditions(cond.typeStr());
722  }
723  xml_h temperature = cond.child(_U(T), false);
724  double temp_val = description.stdConditions().temperature;
725  if ( temperature.ptr() ) {
726  double temp_unit = _toDouble("kelvin");
727  if ( temperature.hasAttr(_U(unit)) )
728  temp_unit = temperature.attr<double>(_U(unit));
729  temp_val = temperature.attr<double>(_U(value)) * temp_unit;
730  }
731  xml_h pressure = cond.child(_U(P), false);
732  double pressure_val = description.stdConditions().pressure;
733  if ( pressure.ptr() ) {
734  double pressure_unit = _toDouble("pascal");
735  if ( pressure.hasAttr(_U(unit)) )
736  pressure_unit = pressure.attr<double>(_U(unit));
737  pressure_val = pressure.attr<double>(_U(value)) * pressure_unit;
738  }
739  description.setStdConditions(temp_val, pressure_val);
740  printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
741  "+++ Material standard conditions: Temperature: %.3f Kelvin Pressure: %.3f hPa",
742  temp_val/_toDouble("kelvin"), pressure_val/_toDouble("hPa"));
743  }
744 }
745 
750 template <> void Converter<OpticalSurface>::operator()(xml_h element) const {
751  xml_elt_t e = element;
752  TGeoManager& mgr = description.manager();
753  std::string sname = e.attr<std::string>(_U(name));
754  std::string ref, pname;
755 
756  // Defaults from Geant4
757  OpticalSurface::EModel model = OpticalSurface::Model::kMglisur;
758  OpticalSurface::EFinish finish = OpticalSurface::Finish::kFpolished;
759  OpticalSurface::EType type = OpticalSurface::Type::kTdielectric_metal;
760  Double_t value = 1.0;
761  if ( e.hasAttr(_U(type)) ) type = OpticalSurface::stringToType(e.attr<std::string>(_U(type)));
762  if ( e.hasAttr(_U(model)) ) model = OpticalSurface::stringToModel(e.attr<std::string>(_U(model)));
763  if ( e.hasAttr(_U(finish)) ) finish = OpticalSurface::stringToFinish(e.attr<std::string>(_U(finish)));
764  if ( e.hasAttr(_U(value)) ) value = e.attr<double>(_U(value));
765  OpticalSurface surf(description, sname, model, finish, type, value);
766  if ( s_debug.surface ) {
767  printout(ALWAYS,"Compact","+++ Reading optical surface %s Typ:%d model:%d finish:%d value: %.3f",
768  sname.c_str(), int(type), int(model), int(finish), value);
769  }
770  for (xml_coll_t props(e, _U(property)); props; ++props) {
771  pname = props.attr<std::string>(_U(name));
772  if ( props.hasAttr(_U(ref)) ) {
773  bool err = kFALSE;
774  ref = props.attr<std::string>(_U(ref));
775  mgr.GetProperty(ref.c_str(), &err);
776  surf->AddProperty(pname.c_str(), ref.c_str());
777  if ( s_debug.surface ) {
778  printout(ALWAYS,"Compact","+++ \t\t Property: %s -> %s", pname.c_str(), ref.c_str());
779  }
780  continue;
781  }
782  std::size_t cols = props.attr<long>(_U(coldim));
783  xml_attr_t opt = props.attr_nothrow(_U(option));
784  std::stringstream str(props.attr<std::string>(_U(values))), str_nam;
785  std::string val;
786  std::vector<double> values;
787  while ( !str.eof() ) {
788  val = "";
789  str >> val;
790  if ( val.empty() && !str.good() ) break;
791  values.emplace_back(_toDouble(val));
792  }
794  TGDMLMatrix* table = new TGDMLMatrix("",values.size()/cols, cols);
795  if ( opt ) {
796  std::string tit = e.attr<std::string>(opt);
797  str_nam << tit << "|";
798  }
799  str_nam << pname << "__" << (void*)table;
800  table->SetName(str_nam.str().c_str());
801  table->SetTitle(pname.c_str());
802  for (std::size_t i=0, n=values.size(); i<n; ++i)
803  table->Set(i/cols, i%cols, values[i]);
804  surf->AddProperty(pname.c_str(), table->GetName());
805  description.manager().AddGDMLMatrix(table);
806  }
807 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
808  //
809  // In case there were constant surface properties specified: convert them here
810  for(xml_coll_t properties(e, _U(constant)); properties; ++properties) {
811  xml_elt_t p = properties;
812  pname = p.attr<std::string>(_U(name));
813  if ( p.hasAttr(_U(ref)) ) {
814  bool err = kFALSE;
815  ref = p.attr<std::string>(_U(ref));
816  mgr.GetProperty(ref.c_str(), &err);
817  if ( err == kFALSE ) {
818  surf->AddConstProperty(pname.c_str(), ref.c_str());
819  printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
820  "++ surface %-16s add constant property: %s -> %s.",
821  surf->GetName(), pname.c_str(), ref.c_str());
822  continue;
823  }
824  // ERROR
825  throw_print("Compact2Objects[ERROR]: Converting surface: " + sname +
826  " ConstProperty missing in TGeoManager: " + ref);
827  }
828  else if ( p.hasAttr(_U(value)) ) {
829  std::stringstream str;
830  str << pname << "_" << (void*)surf.ptr();
831  ref = str.str();
832  mgr.AddProperty(ref.c_str(), p.attr<double>(_U(value)));
833  surf->AddConstProperty(pname.c_str(), ref.c_str());
834  printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
835  "++ surface %-16s add constant property: %s -> %s.",
836  surf->GetName(), pname.c_str(), ref.c_str());
837  }
838  else if ( p.hasAttr(_U(option)) ) {
839  std::string ptyp = p.attr<std::string>(_U(option));
840  surf->AddConstProperty(pname.c_str(), ptyp.c_str());
841  printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
842  "++ surface %-16s add constant property: %s -> %s.",
843  surf->GetName(), pname.c_str(), ptyp.c_str());
844  }
845  }
846 #endif
847 }
848 
854 template <> void Converter<PropertyConstant>::operator()(xml_h e) const {
855  double value = e.attr<double>(_U(value));
856  std::string name = e.attr<std::string>(_U(name));
857  description.manager().AddProperty(name.c_str(), value);
858  if ( s_debug.matrix ) {
859  printout(ALWAYS,"Compact","+++ Reading property %s : %f",name.c_str(), value);
860  }
861 #if 0
862  xml_attr_t opt = e.attr_nothrow(_U(title));
863  if ( opt ) {
864  std::string val = e.attr<std::string>(opt);
865  TNamed* nam = description.manager().GetProperty(name.c_str());
866  if ( !nam ) {
867  except("Compact","Failed to access just added manager property: %s",name.c_str());
868  }
869  nam->SetTitle(val.c_str());
870  }
871 #endif
872 }
873 
879 template <> void Converter<PropertyTable>::operator()(xml_h e) const {
880  std::vector<double> vals;
881  std::size_t cols = e.attr<unsigned long>(_U(coldim));
882  std::stringstream str(e.attr<std::string>(_U(values)));
883 
884  if ( s_debug.matrix ) {
885  printout(ALWAYS,"Compact","+++ Reading property table %s with %d columns.",
886  e.attr<std::string>(_U(name)).c_str(), cols);
887  }
888  vals.reserve(1024);
889  while ( !str.eof() ) {
890  std::string item;
891  str >> item;
892  if ( item.empty() && !str.good() ) break;
893  vals.emplace_back(_toDouble(item));
894  if ( s_debug.matrix ) {
895  std::cout << " state:" << (str.good() ? "OK " : "BAD") << " '" << item << "'";
896  if ( 0 == (vals.size()%cols) ) std::cout << std::endl;
897  }
898  }
899  if ( s_debug.matrix ) {
900  std::cout << std::endl;
901  }
903  xml_attr_t opt = e.attr_nothrow(_U(option));
904  PropertyTable tab(description,
905  e.attr<std::string>(_U(name)),
906  opt ? e.attr<std::string>(opt).c_str() : "",
907  vals.size()/cols, cols);
908  for( std::size_t i=0, n=vals.size(); i < n; ++i )
909  tab->Set(i/cols, i%cols, vals[i]);
910  //if ( s_debug.matrix ) tab->Print();
911 }
912 
927 template <> void Converter<VisAttr>::operator()(xml_h e) const {
928  VisAttr attr(e.attr<std::string>(_U(name)));
929  float alpha = 1.0;
930  float red = 1.0;
931  float green = 1.0;
932  float blue = 1.0;
933  bool use_ref = false;
934  if(e.hasAttr(_U(ref))) {
935  use_ref = true;
936  auto refName = e.attr<std::string>(_U(ref));
937  const auto refAttr = description.visAttributes(refName);
938  if(!refAttr.isValid() ) {
939  except("Compact","+++ Reference VisAttr %s does not exist", refName.c_str());
940  }
941  // Just copying things manually.
942  // I think a handle's copy constructor/assignment would reuse the underlying pointer... maybe?
943  refAttr.argb(alpha,red,green,blue);
944  attr.setColor(alpha,red,green,blue);
945  attr.setDrawingStyle( refAttr.drawingStyle());
946  attr.setLineStyle( refAttr.lineStyle());
947  attr.setShowDaughters(refAttr.showDaughters());
948  attr.setVisible(refAttr.visible());
949  }
950  xml_dim_t dim(e);
951  alpha = dim.alpha(alpha);
952  red = dim.r(red );
953  green = dim.g(green);
954  blue = dim.b(blue );
955 
956  printout(s_debug.visattr ? ALWAYS : DEBUG, "Compact",
957  "++ Converting VisAttr structure: %-16s. Alpha=%.2f R=%.3f G=%.3f B=%.3f",
958  attr.name(), alpha, red, green, blue);
959  attr.setColor(alpha, red, green, blue);
960  if (e.hasAttr(_U(visible)))
961  attr.setVisible(e.attr<bool>(_U(visible)));
962  if (e.hasAttr(_U(lineStyle))) {
963  std::string ls = e.attr<std::string>(_U(lineStyle));
964  if (ls == "unbroken")
965  attr.setLineStyle(VisAttr::SOLID);
966  else if (ls == "broken")
967  attr.setLineStyle(VisAttr::DASHED);
968  }
969  else {
970  if (!use_ref)
971  attr.setLineStyle(VisAttr::SOLID);
972  }
973  if (e.hasAttr(_U(drawingStyle))) {
974  std::string ds = e.attr<std::string>(_U(drawingStyle));
975  if (ds == "wireframe")
976  attr.setDrawingStyle(VisAttr::WIREFRAME);
977  else if (ds == "solid")
978  attr.setDrawingStyle(VisAttr::SOLID);
979  }
980  else {
981  if (!use_ref)
982  attr.setDrawingStyle(VisAttr::SOLID);
983  }
984  if (e.hasAttr(_U(showDaughters)))
985  attr.setShowDaughters(e.attr<bool>(_U(showDaughters)));
986  else {
987  if (!use_ref)
988  attr.setShowDaughters(true);
989  }
990  description.addVisAttribute(attr);
991 }
992 
996 template <> void Converter<Region>::operator()(xml_h elt) const {
997  xml_dim_t e = elt;
998  Region region(e.nameStr());
999  auto& limits = region.limits();
1000  xml_attr_t cut = elt.attr_nothrow(_U(cut));
1001  xml_attr_t threshold = elt.attr_nothrow(_U(threshold));
1002  xml_attr_t store_secondaries = elt.attr_nothrow(_U(store_secondaries));
1003  double ene = e.eunit(1.0), len = e.lunit(1.0);
1004 
1005  printout(s_debug.regions ? ALWAYS : DEBUG, "Compact",
1006  "++ Converting region structure: %s.",region.name());
1007  if ( cut ) {
1008  region.setCut(elt.attr<double>(cut)*len);
1009  }
1010  if ( threshold ) {
1011  region.setThreshold(elt.attr<double>(threshold)*ene);
1012  }
1013  if ( store_secondaries ) {
1014  region.setStoreSecondaries(elt.attr<bool>(store_secondaries));
1015  }
1016  for (xml_coll_t user_limits(e, _U(limitsetref)); user_limits; ++user_limits)
1017  limits.emplace_back(user_limits.attr<std::string>(_U(name)));
1018  description.addRegion(region);
1019 }
1020 
1021 
1029 template <> void Converter<Segmentation>::operator()(xml_h seg) const {
1030  std::string type = seg.attr<std::string>(_U(type));
1031  std::string name = seg.hasAttr(_U(name)) ? seg.attr<std::string>(_U(name)) : std::string();
1032  std::pair<Segmentation,IDDescriptor>* opt = _option<std::pair<Segmentation,IDDescriptor> >();
1033 
1034  const BitFieldCoder* bitfield = &opt->second->decoder;
1035  Segmentation segment(type, name, bitfield);
1036  if ( segment.isValid() ) {
1037  const DDSegmentation::Parameters& pars = segment.parameters();
1038  printout(s_debug.segmentation ? ALWAYS : DEBUG, "Compact",
1039  "++ Converting segmentation structure: %s of type %s.",name.c_str(),type.c_str());
1040  for(const auto p : pars ) {
1041  xml::Strng_t pNam(p->name());
1042  if ( seg.hasAttr(pNam) ) {
1043  std::string pType = p->type();
1044  if ( pType.compare("int") == 0 ) {
1046  static_cast<ParInt*>(p)->setTypedValue(seg.attr<int>(pNam));
1047  } else if ( pType.compare("float") == 0 ) {
1049  static_cast<ParFloat*>(p)->setTypedValue(seg.attr<float>(pNam));
1050  } else if ( pType.compare("doublevec") == 0 ) {
1051  std::vector<double> valueVector;
1052  std::string par = seg.attr<std::string>(pNam);
1053  printout(s_debug.segmentation ? ALWAYS : DEBUG, "Compact",
1054  "++ Converting this std::string structure: %s.",par.c_str());
1055  std::vector<std::string> elts = DDSegmentation::splitString(par);
1056  for (const std::string& spar : elts ) {
1057  if ( spar.empty() ) continue;
1058  valueVector.emplace_back(_toDouble(spar));
1059  }
1061  static_cast<ParDouVec*>(p)->setTypedValue(valueVector);
1062  } else if ( pType.compare("double" ) == 0) {
1064  static_cast<ParDouble*>(p)->setTypedValue(seg.attr<double>(pNam));
1065  } else {
1066  p->setValue(seg.attr<std::string>(pNam));
1067  }
1068  } else if (not p->isOptional()) {
1069  throw_print("FAILED to create segmentation: " + type +
1070  ". Missing mandatory parameter: " + p->name() + "!");
1071  }
1072  }
1073  long key_min = 0, key_max = 0;
1074  DDSegmentation::Segmentation* base = segment->segmentation;
1075  for(xml_coll_t sub(seg,_U(segmentation)); sub; ++sub) {
1076  std::pair<Segmentation,IDDescriptor> sub_object(Segmentation(),opt->second);
1077  Converter<Segmentation> sub_conv(description,param,&sub_object);
1078  sub_conv(sub);
1079  if ( sub_object.first.isValid() ) {
1080  Segmentation sub_seg = sub_object.first;
1081  xml_dim_t x_seg(sub);
1082  if ( sub.hasAttr(_U(key_value)) ) {
1083  key_min = key_max = x_seg.key_value();
1084  }
1085  else if ( sub.hasAttr(_U(key_min)) && sub.hasAttr(_U(key_max)) ) {
1086  key_min = x_seg.key_min();
1087  key_max = x_seg.key_max();
1088  }
1089  else {
1090  std::stringstream tree;
1091  xml::dump_tree(sub,tree);
1092  throw_print("Nested segmentations: Invalid key specification:"+tree.str());
1093  }
1094  printout(s_debug.segmentation ? ALWAYS : DEBUG,"Compact",
1095  "++ Segmentation [%s/%s]: Add sub-segmentation %s [%s]",
1096  name.c_str(), type.c_str(),
1097  sub_seg->segmentation->name().c_str(),
1098  sub_seg->segmentation->type().c_str());
1099  base->addSubsegmentation(key_min, key_max, sub_seg->segmentation);
1100  sub_seg->segmentation = 0;
1101  delete sub_seg.ptr();
1102  }
1103  }
1104  }
1105  opt->first = segment;
1106 }
1107 
1115 template <> void Converter<Readout>::operator()(xml_h e) const {
1116  xml_h seg = e.child(_U(segmentation), false);
1117  xml_h id = e.child(_U(id));
1118  std::string name = e.attr<std::string>(_U(name));
1119  std::pair<Segmentation,IDDescriptor> opt;
1120  Readout ro(name);
1121 
1122  if (id) {
1123  // <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id>
1124  opt.second = IDDescriptor(name,id.text());
1125  description.addIDSpecification(opt.second);
1126  }
1127  if (seg) { // Segmentation is not mandatory!
1128  Converter<Segmentation>(description,param,&opt)(seg);
1129  opt.first->setName(name);
1130  }
1134  if ( opt.first.isValid() ) {
1135  ro.setSegmentation(opt.first);
1136  }
1137  if ( opt.second.isValid() ) {
1138  ro.setIDDescriptor(opt.second);
1139  }
1140 
1141  printout(s_debug.readout ? ALWAYS : DEBUG,
1142  "Compact", "++ Converting readout structure: %-16s. %s%s",
1143  ro.name(), id ? "ID: " : "", id ? id.text().c_str() : "");
1144 
1145  for(xml_coll_t colls(e,_U(hits_collections)); colls; ++colls) {
1146  std::string hits_key;
1147  if ( colls.hasAttr(_U(key)) ) hits_key = colls.attr<std::string>(_U(key));
1148  for(xml_coll_t coll(colls,_U(hits_collection)); coll; ++coll) {
1149  xml_dim_t c(coll);
1150  std::string coll_name = c.nameStr();
1151  std::string coll_key = hits_key;
1152  long key_min = 0, key_max = 0;
1153 
1154  if ( c.hasAttr(_U(key)) ) {
1155  coll_key = c.attr<std::string>(_U(key));
1156  }
1157  if ( c.hasAttr(_U(key_value)) ) {
1158  key_max = key_min = c.key_value();
1159  }
1160  else if ( c.hasAttr(_U(key_min)) && c.hasAttr(_U(key_max)) ) {
1161  key_min = c.key_min();
1162  key_max = c.key_max();
1163  }
1164  else {
1165  std::stringstream tree;
1166  xml::dump_tree(e,tree);
1167  throw_print("Readout: Invalid specification for multiple hit collections."+tree.str());
1168  }
1169  printout(s_debug.readout ? ALWAYS : DEBUG,"Compact",
1170  "++ Readout[%s]: Add hit collection %s [%s] %d-%d",
1171  ro.name(), coll_name.c_str(), coll_key.c_str(), key_min, key_max);
1172  HitCollection hits(coll_name, coll_key, key_min, key_max);
1173  ro->hits.emplace_back(hits);
1174  }
1175  }
1176  description.addReadout(ro);
1177 }
1178 
1179 static long load_readout(Detector& description, xml_h element) {
1180  Converter<Readout> converter(description);
1181  converter(element);
1182  return 1;
1183 }
1184 DECLARE_XML_DOC_READER(readout,load_readout)
1185 
1186 
1187 
1193 template <> void Converter<LimitSet>::operator()(xml_h e) const {
1194  Limit limit;
1195  LimitSet ls(e.attr<std::string>(_U(name)));
1196  printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1197  "++ Converting LimitSet structure: %s.",ls.name());
1198  for (xml_coll_t c(e, _U(limit)); c; ++c) {
1199  limit.name = c.attr<std::string>(_U(name));
1200  limit.particles = c.attr<std::string>(_U(particles));
1201  limit.content = c.attr<std::string>(_U(value));
1202  limit.unit = c.attr<std::string>(_U(unit));
1203  limit.value = _multiply<double>(limit.content, limit.unit);
1204  ls.addLimit(limit);
1205  printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1206  "++ %s: add %-6s: [%s] = %s [%s] = %f",
1207  ls.name(), limit.name.c_str(), limit.particles.c_str(),
1208  limit.content.c_str(), limit.unit.c_str(), limit.value);
1209  }
1210  limit.name = "cut";
1211  for (xml_coll_t c(e, _U(cut)); c; ++c) {
1212  limit.particles = c.attr<std::string>(_U(particles));
1213  limit.content = c.attr<std::string>(_U(value));
1214  limit.unit = c.attr<std::string>(_U(unit));
1215  limit.value = _multiply<double>(limit.content, limit.unit);
1216  ls.addCut(limit);
1217  printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1218  "++ %s: add %-6s: [%s] = %s [%s] = %f",
1219  ls.name(), limit.name.c_str(), limit.particles.c_str(),
1220  limit.content.c_str(), limit.unit.c_str(), limit.value);
1221  }
1222  description.addLimitSet(ls);
1223 }
1224 
1231 template <> void Converter<Property>::operator()(xml_h e) const {
1232  std::string name = e.attr<std::string>(_U(name));
1233  Detector::Properties& prp = description.properties();
1234  if ( name.empty() )
1235  throw_print("Failed to convert properties. No name given!");
1236 
1237  std::vector<xml_attr_t> a = e.attributes();
1238  if ( prp.find(name) == prp.end() )
1239  prp.emplace(name, Detector::PropertyValues());
1240 
1241  for (xml_attr_t i : a )
1242  prp[name].emplace(xml_tag_t(e.attr_name(i)).str(),e.attr<std::string>(i));
1243 }
1244 
1253 template <> void Converter<CartesianField>::operator()(xml_h e) const {
1254  std::string msg = "updated";
1255  std::string name = e.attr<std::string>(_U(name));
1256  std::string type = e.attr<std::string>(_U(type));
1257  CartesianField field = description.field(name);
1258  if ( !field.isValid() ) {
1259  // The field is not present: We create it and add it to Detector
1260  field = Ref_t(PluginService::Create<NamedObject*>(type, &description, &e));
1261  if ( !field.isValid() ) {
1262  PluginDebug dbg;
1263  PluginService::Create<NamedObject*>(type, &description, &e);
1264  throw_print("Failed to create field object of type "+type + ". "+dbg.missingFactory(type));
1265  }
1266  description.addField(field);
1267  msg = "created";
1268  }
1269  type = field.type();
1270  // Now update the field structure with the generic part ie. set its properties
1271  CartesianField::Properties& prp = field.properties();
1272  for ( xml_coll_t c(e, _U(properties)); c; ++c ) {
1273  std::string props_name = c.attr<std::string>(_U(name));
1274  std::vector<xml_attr_t>a = c.attributes();
1275  if ( prp.find(props_name) == prp.end() ) {
1276  prp.emplace(props_name, Detector::PropertyValues());
1277  }
1278  for ( xml_attr_t i : a )
1279  prp[props_name].emplace(xml_tag_t(c.attr_name(i)).str(), c.attr<std::string>(i));
1280 
1281  if (c.hasAttr(_U(global)) && c.attr<bool>(_U(global))) {
1282  description.field().properties() = prp;
1283  }
1284  }
1285  printout(INFO, "Compact", "++ Converted field: Successfully %s field %s [%s]", msg.c_str(), name.c_str(), type.c_str());
1286 }
1287 
1301 template <> void Converter<SensitiveDetector>::operator()(xml_h element) const {
1302  std::string name = element.attr<std::string>(_U(name));
1303  try {
1304  SensitiveDetector sd = description.sensitiveDetector(name);
1305  xml_attr_t type = element.attr_nothrow(_U(type));
1306  if ( type ) {
1307  sd.setType(element.attr<std::string>(type));
1308  }
1310  if ( verbose ) {
1311  sd.setVerbose(element.attr<bool>(verbose));
1312  }
1313  xml_attr_t combine = element.attr_nothrow(_U(combine_hits));
1314  if ( combine ) {
1315  sd.setCombineHits(element.attr<bool>(combine));
1316  }
1317  xml_attr_t limits = element.attr_nothrow(_U(limits));
1318  if ( limits ) {
1319  std::string l = element.attr<std::string>(limits);
1320  LimitSet ls = description.limitSet(l);
1321  if (!ls.isValid()) {
1322  throw_print("Converter<SensitiveDetector>: Request for non-existing limitset:" + l);
1323  }
1324  sd.setLimitSet(ls);
1325  }
1326  xml_attr_t region = element.attr_nothrow(_U(region));
1327  if ( region ) {
1328  std::string r = element.attr<std::string>(region);
1329  Region reg = description.region(r);
1330  if (!reg.isValid()) {
1331  throw_print("Converter<SensitiveDetector>: Request for non-existing region:" + r);
1332  }
1333  sd.setRegion(reg);
1334  }
1335  xml_attr_t hits = element.attr_nothrow(_U(hits_collection));
1336  if (hits) {
1337  sd.setHitsCollection(element.attr<std::string>(hits));
1338  }
1339  xml_attr_t ecut = element.attr_nothrow(_U(ecut));
1340  xml_attr_t eunit = element.attr_nothrow(_U(eunit));
1341  if (ecut && eunit) {
1342  double value = _multiply<double>(_toString(ecut), _toString(eunit));
1343  sd.setEnergyCutoff(value);
1344  }
1345  else if (ecut) { // If no unit is given , we assume the correct Geant4 unit is used!
1346  sd.setEnergyCutoff(element.attr<double>(ecut));
1347  }
1348  printout(DEBUG, "Compact", "SensitiveDetector-update: %-18s %-24s Hits:%-24s Cutoff:%7.3f", sd.name(),
1349  (" [" + sd.type() + "]").c_str(), sd.hitsCollection().c_str(), sd.energyCutoff());
1350  xml_attr_t sequence = element.attr_nothrow(_U(sequence));
1351  if (sequence) {
1352  }
1353  }
1354  catch (const std::exception& e) {
1355  printout(ERROR, "Compact", "++ FAILED to convert sensitive detector: %s: %s", name.c_str(), e.what());
1356  }
1357  catch (...) {
1358  printout(ERROR, "Compact", "++ FAILED to convert sensitive detector: %s: %s", name.c_str(), "UNKNONW Exception");
1359  }
1360 }
1361 
1362 static void setChildTitles(const std::pair<std::string, DetElement>& e) {
1363  DetElement parent = e.second.parent();
1364  const DetElement::Children& children = e.second.children();
1365  if (::strlen(e.second->GetTitle()) == 0) {
1366  e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
1367  }
1368  for_each(children.begin(), children.end(), setChildTitles);
1369 }
1370 
1371 template <> void Converter<DetElement>::operator()(xml_h element) const {
1372  static const char* req_dets = ::getenv("REQUIRED_DETECTORS");
1373  static const char* req_typs = ::getenv("REQUIRED_DETECTOR_TYPES");
1374  static const char* ign_dets = ::getenv("IGNORED_DETECTORS");
1375  static const char* ign_typs = ::getenv("IGNORED_DETECTOR_TYPES");
1376  std::string type = element.attr<std::string>(_U(type));
1377  std::string name = element.attr<std::string>(_U(name));
1378  std::string name_match = ":" + name + ":";
1379  std::string type_match = ":" + type + ":";
1380 
1381  if (req_dets && !strstr(req_dets, name_match.c_str()))
1382  return;
1383  if (req_typs && !strstr(req_typs, type_match.c_str()))
1384  return;
1385  if (ign_dets && strstr(ign_dets, name_match.c_str()))
1386  return;
1387  if (ign_typs && strstr(ign_typs, type_match.c_str()))
1388  return;
1389  xml_attr_t attr_ignore = element.attr_nothrow(_U(ignore));
1390  if ( attr_ignore ) {
1391  bool ignore_det = element.attr<bool>(_U(ignore));
1392  if ( ignore_det ) {
1393  printout(INFO, "Compact",
1394  "+++ Do not build subdetector:%s [ignore flag set]",
1395  name.c_str());
1396  return;
1397  }
1398  }
1399  try {
1400  std::string par_name;
1401  xml_attr_t attr_par = element.attr_nothrow(_U(parent));
1402  xml_elt_t elt_par(0);
1403  if (attr_par)
1404  par_name = element.attr<std::string>(attr_par);
1405  else if ( (elt_par=element.child(_U(parent),false)) )
1406  par_name = elt_par.attr<std::string>(_U(name));
1407  if ( !par_name.empty() ) {
1408  // We have here a nested detector. If the mother volume is not yet registered
1409  // it must be done here, so that the detector constructor gets the correct answer from
1410  // the call to Detector::pickMotherVolume(DetElement).
1411  if ( par_name[0] == '$' ) par_name = xml::getEnviron(par_name);
1412  DetElement parent = description.detector(par_name);
1413  if ( !parent.isValid() ) {
1414  except("Compact","Failed to access valid parent detector of %s",name.c_str());
1415  }
1416  description.declareParent(name, parent);
1417  }
1418  if( s_debug.detelements ) {
1419  printout(ALWAYS, "Compact","++ Building DetElement %s of type: %s. Parent: %s",
1420  name.c_str(), type.c_str(), par_name.c_str());
1421  }
1422 
1423  xml_attr_t attr_ro = element.attr_nothrow(_U(readout));
1424  SensitiveDetector sd;
1425  Segmentation seg;
1426  if ( attr_ro ) {
1427  Readout ro = description.readout(element.attr<std::string>(attr_ro));
1428  if (!ro.isValid()) {
1429  except("Compact","No Readout structure present for detector:" + name);
1430  }
1431  seg = ro.segmentation();
1432  sd = SensitiveDetector(name, "sensitive");
1433  sd.setHitsCollection(ro.name());
1434  sd.setReadout(ro);
1435  description.addSensitiveDetector(sd);
1436  }
1437  Ref_t sens = sd;
1438  DetElement det(Ref_t(PluginService::Create<NamedObject*>(type, &description, &element, &sens)));
1439  if (det.isValid()) {
1440  setChildTitles(std::make_pair(name, det));
1441  if ( sd.isValid() ) {
1443  }
1444  if ( seg.isValid() ) {
1445  seg->sensitive = sd;
1446  seg->detector = det;
1447  }
1448  }
1449  printout(det.isValid() ? INFO : ERROR, "Compact", "%s subdetector:%s of type %s %s",
1450  (det.isValid() ? "++ Converted" : "FAILED "), name.c_str(), type.c_str(),
1451  (sd.isValid() ? ("[" + sd.type() + "]").c_str() : ""));
1452 
1453  if (!det.isValid()) {
1454  PluginDebug dbg;
1455  PluginService::Create<NamedObject*>(type, &description, &element, &sens);
1456  except("Compact","Failed to execute subdetector creation plugin. %s", dbg.missingFactory(type).c_str());
1457  }
1458  description.addDetector(det);
1459  description.surfaceManager().registerSurfaces(det);
1460  return;
1461  }
1462  catch (const std::exception& e) {
1463  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
1464  std::terminate();
1465  }
1466  catch (...) {
1467  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
1468  std::terminate();
1469  }
1470 }
1471 
1473 template <> void Converter<IncludeFile>::operator()(xml_h element) const {
1474  xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
1475  if ( s_debug.include_guard) {
1476  // Include guard, we check whether this file was already processed
1477  if (check_process_file(description, doc.uri()))
1478  return;
1479  }
1480  xml_h root = doc.root();
1481  if ( s_debug.includes ) {
1482  printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
1483  }
1484  if ( root.tag() == "materials" || root.tag() == "elements" ) {
1485  xml_coll_t(root, _U(isotope)).for_each(Converter<Isotope>(this->description,0,0));
1486  xml_coll_t(root, _U(element)).for_each(Converter<Atom>(this->description));
1487  xml_coll_t(root, _U(material)).for_each(Converter<Material>(this->description));
1488  return;
1489  }
1490  this->description.fromXML(doc.uri(), this->description.buildType());
1491 }
1492 
1494 template <> void Converter<JsonFile>::operator()(xml_h element) const {
1495  std::string base = xml::DocumentHandler::system_directory(element);
1496  std::string file = element.attr<std::string>(_U(ref));
1497  std::vector<char*> argv{&file[0], &base[0]};
1498  description.apply("DD4hep_JsonProcessor",int(argv.size()), &argv[0]);
1499 }
1500 
1502 template <> void Converter<XMLFile>::operator()(xml_h element) const {
1503  PrintLevel level = s_debug.includes ? ALWAYS : DEBUG;
1504  std::string fname = element.attr<std::string>(_U(ref));
1505  std::size_t idx = fname.find("://");
1506  std::error_code ec;
1507 
1508  if ( idx == std::string::npos && std::filesystem::exists(fname, ec) ) {
1509  // Regular file without protocol specification
1510  printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1511  this->description.fromXML(fname, this->description.buildType());
1512  }
1513  else if ( idx == std::string::npos ) {
1514  // File relative to location of xml tag (protocol specification not possible)
1515  std::string location = xml::DocumentHandler::system_path(element, fname);
1516  printout(level, "Compact","++ Processing xml document %s.", location.c_str());
1517  this->description.fromXML(location, this->description.buildType());
1518  }
1519  else if ( idx > 0 ) {
1520  // File with protocol specification: must trust the location and the parser capabilities
1521  printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1522  this->description.fromXML(fname, this->description.buildType());
1523  }
1524  else {
1525  // Are there any other possibilities ?
1526  printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1527  this->description.fromXML(fname, this->description.buildType());
1528  }
1529 }
1530 
1532 template <> void Converter<World>::operator()(xml_h element) const {
1533  xml_elt_t x_world(element);
1534  xml_comp_t x_shape = x_world.child(_U(shape), false);
1535  xml_attr_t att = x_world.getAttr(_U(material));
1536  Material mat = att ? description.material(x_world.attr<std::string>(att)) : description.air();
1537  Volume world_vol;
1538 
1540  if ( x_shape ) {
1541  Solid sol(x_shape.createShape());
1542  world_vol = Volume("world_volume", sol, mat);
1543  printout(INFO, "Compact", "++ Created successfully world volume '%s'. shape: %s material:%s.",
1544  world_vol.name(), sol.type(), mat.name());
1545  description.manager().SetTopVolume(world_vol.ptr());
1546  }
1547  else {
1548  world_vol = description.worldVolume();
1549  if ( !world_vol && att ) {
1552  Box sol("world_x", "world_y", "world_z");
1553  world_vol = Volume("world_volume", sol, mat);
1554  printout(INFO, "Compact", "++ Created world volume '%s' as %s (%.2f, %.2f %.2f [cm]) material:%s.",
1555  world_vol.name(), sol.type(),
1556  sol.x()/dd4hep::cm, sol.y()/dd4hep::cm, sol.z()/dd4hep::cm,
1557  mat.name());
1558  description.manager().SetTopVolume(world_vol.ptr());
1559  }
1560  else if ( !world_vol ) {
1561  except("Compact", "++ Logical error: "
1562  "You cannot configure the world volume before it is created and not giving creation instructions.");
1563  }
1564  }
1565  // Delegate further configuration o0f the world volume to the xml utilities:
1566  if ( world_vol.isValid() ) {
1567  xml::configVolume(description, x_world, world_vol, false, true);
1568  auto vis = world_vol.visAttributes();
1569  if ( !vis.isValid() ) {
1570  vis = description.visAttributes("WorldVis");
1571  world_vol.setVisAttributes(vis);
1572  }
1573  }
1574 }
1575 
1577 template <> void Converter<Parallelworld_Volume>::operator()(xml_h element) const {
1578  xml_det_t parallel(element);
1579  xml_comp_t shape = parallel.child(_U(shape));
1580  xml_dim_t pos = element.child(_U(position),false);
1581  xml_dim_t rot = element.child(_U(rotation),false);
1582  std::string name = element.attr<std::string>(_U(name));
1583  std::string path = element.attr<std::string>(_U(anchor));
1584  bool conn = element.attr<bool>(_U(connected),false);
1585  DetElement anchor(detail::tools::findElement(description, path));
1586  Position position = pos ? Position(pos.x(), pos.y(), pos.z()) : Position();
1587  RotationZYX rotation = rot ? RotationZYX(rot.z(), rot.y(), rot.x()) : RotationZYX();
1588 
1589  Material mat = parallel.hasAttr(_U(material))
1590  ? description.material(parallel.attr<std::string>(_U(material)))
1591  : description.air();
1592  VisAttr vis = parallel.hasAttr(_U(vis))
1593  ? description.invisible()
1594  : description.visAttributes(parallel.visStr());
1595 
1596  if ( !anchor.isValid() ) {
1597  except("Parallelworld_Volume",
1598  "++ FAILED Cannot identify the anchor of the tracking volume: '%s'",
1599  path.c_str());
1600  }
1601 
1603  Transform3D tr_volume(detail::matrix::_transform(anchor.nominal().worldTransformation().Inverse()));
1604  Solid sol(shape.createShape());
1605  Volume vol(name, sol, mat);
1606  Volume par = conn ? description.worldVolume() : description.parallelWorldVolume();
1607  PlacedVolume pv;
1608 
1610  vol.setVisAttributes(vis);
1612  vol.setFlagBit(Volume::VETO_SIMU);
1613 
1615  Transform3D trafo = tr_volume * Transform3D(rotation,position); // Is this the correct order ?
1616  pv = par.placeVolume(vol, trafo);
1617  if ( !pv.isValid() ) {
1618  except("Parallelworld_Volume",
1619  "++ FAILED to place the tracking volume inside the anchor '%s'",path.c_str());
1620  }
1621  if ( name == "tracking_volume" ) {
1622  description.setTrackingVolume(vol);
1623  }
1624  printout(INFO, "Compact", "++ Converted successfully parallelworld_volume %s. anchor: %s vis:%s.",
1625  vol.name(), anchor.path().c_str(), vis.name());
1626 }
1627 
1629 template <> void Converter<DetElementInclude>::operator()(xml_h element) const {
1630  std::string type = element.hasAttr(_U(type)) ? element.attr<std::string>(_U(type)) : std::string("xml");
1631  if ( type == "xml" ) {
1632  xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
1633  if ( s_debug.include_guard ) {
1634  // Include guard, we check whether this file was already processed
1635  if (check_process_file(description, doc.uri()))
1636  return;
1637  }
1638  if ( s_debug.includes ) {
1639  printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
1640  }
1641  xml_h node = doc.root();
1642  std::string tag = node.tag();
1643  if ( tag == "lccdd" )
1644  Converter<Compact>(this->description)(node);
1645  else if ( tag == "define" )
1646  xml_coll_t(node, _U(constant)).for_each(Converter<Constant>(this->description));
1647  else if ( tag == "readout" )
1648  Converter<Readout>(this->description)(node);
1649  else if ( tag == "readouts" )
1650  xml_coll_t(node, _U(readout)).for_each(Converter<Readout>(this->description));
1651  else if ( tag == "region" )
1652  Converter<Region>(this->description)(node);
1653  else if ( tag == "regions" )
1654  xml_coll_t(node, _U(region)).for_each(Converter<Region>(this->description));
1655  else if ( tag == "limits" || tag == "limitsets" )
1656  xml_coll_t(node, _U(limitset)).for_each(Converter<LimitSet>(this->description));
1657  else if ( tag == "display" )
1658  xml_coll_t(node,_U(vis)).for_each(Converter<VisAttr>(this->description));
1659  else if ( tag == "detector" )
1660  Converter<DetElement>(this->description)(node);
1661  else if ( tag == "detectors" )
1662  xml_coll_t(node,_U(detector)).for_each(Converter<DetElement>(this->description));
1663  }
1664  else if ( type == "json" ) {
1665  Converter<JsonFile>(this->description)(element);
1666  }
1667  else if ( type == "gdml" ) {
1668  Converter<IncludeFile>(this->description)(element);
1669  }
1670  else if ( type == "include" ) {
1671  Converter<IncludeFile>(this->description)(element);
1672  }
1673  else if ( type == "xml-extended" ) {
1674  Converter<XMLFile>(this->description)(element);
1675  }
1676  else {
1677  except("Compact","++ FAILED Invalid file type:%s. This cannot be processed!",type.c_str());
1678  }
1679 }
1680 
1682 template <> void Converter<Compact>::operator()(xml_h element) const {
1683  static int num_calls = 0;
1684  char text[32];
1685 
1686  ++num_calls;
1687  xml_elt_t compact(element);
1688  bool steer_geometry = compact.hasChild(_U(geometry));
1689  bool open_geometry = true;
1690  bool close_document = true;
1691  bool close_geometry = true;
1692  bool build_reflections = false;
1693  xml_dim_t world = element.child(_U(world), false);
1694 
1695 
1696  if (element.hasChild(_U(debug)))
1697  (Converter<Debug>(description))(xml_h(compact.child(_U(debug))));
1698 
1699  if ( steer_geometry ) {
1700  xml_elt_t steer = compact.child(_U(geometry));
1701  if ( steer.hasAttr(_U(open)) )
1702  open_geometry = steer.attr<bool>(_U(open));
1703  if ( steer.hasAttr(_U(close)) )
1704  close_document = steer.attr<bool>(_U(close));
1705  if ( steer.hasAttr(_U(reflect)) )
1706  build_reflections = steer.attr<bool>(_U(reflect));
1707  for (xml_coll_t clr(steer, _U(clear)); clr; ++clr) {
1708  std::string nam = clr.hasAttr(_U(name)) ? clr.attr<std::string>(_U(name)) : std::string();
1709  if ( nam.substr(0,6) == "elemen" ) {
1710  TGeoElementTable* table = description.manager().GetElementTable();
1711  table->TGeoElementTable::~TGeoElementTable();
1712  new(table) TGeoElementTable();
1713  // This will initialize the table without filling:
1714  table->AddElement("VACUUM","VACUUM" ,0, 0, 0.0);
1715  printout(INFO,"Compact",
1716  "++ Cleared default ROOT TGeoElementTable contents. "
1717  "Must now be filled from XML!");
1718  }
1719  }
1720  }
1721 
1722  if ( s_debug.materials || s_debug.elements ) {
1723  printout(INFO,"Compact","+++ UNIT System:");
1724  printout(INFO,"Compact","+++ Density: %8.3g Units:%8.3g",
1725  xml::_toDouble(_Unicode(gram/cm3)), dd4hep::gram/dd4hep::cm3);
1726  printout(INFO,"Compact","+++ GeV: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(GeV)),dd4hep::GeV);
1727  printout(INFO,"Compact","+++ sec: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(second)),dd4hep::second);
1728  printout(INFO,"Compact","+++ nanosecond: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(nanosecond)),dd4hep::nanosecond);
1729  printout(INFO,"Compact","+++ kilo: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(kilogram)),dd4hep::kilogram);
1730  printout(INFO,"Compact","+++ kilo: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(joule*s*s/(m*m))),
1731  dd4hep::joule*dd4hep::s*dd4hep::s/(dd4hep::meter*dd4hep::meter));
1732  printout(INFO,"Compact","+++ meter: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(meter)),dd4hep::meter);
1733  printout(INFO,"Compact","+++ ampere: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(ampere)),dd4hep::ampere);
1734  printout(INFO,"Compact","+++ degree: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(degree)),dd4hep::degree);
1735  }
1736 
1737  xml_coll_t(compact, _U(define)).for_each(_U(include), Converter<DetElementInclude>(description));
1738  xml_coll_t(compact, _U(define)).for_each(_U(constant), Converter<Constant>(description));
1739  xml_coll_t(compact, _U(std_conditions)).for_each( Converter<STD_Conditions>(description));
1740  xml_coll_t(compact, _U(includes)).for_each(_U(gdmlFile), Converter<IncludeFile>(description));
1741  xml_coll_t(compact, _U(includes)).for_each(_U(file), Converter<IncludeFile>(description));
1742 
1743  if (element.hasChild(_U(info)))
1744  (Converter<Header>(description))(xml_h(compact.child(_U(info))));
1745 
1747  xml_coll_t(compact, _U(properties)).for_each(_U(attributes), Converter<Property>(description));
1748  xml_coll_t(compact, _U(properties)).for_each(_U(constant), Converter<PropertyConstant>(description));
1749  xml_coll_t(compact, _U(properties)).for_each(_U(matrix), Converter<PropertyTable>(description));
1750  xml_coll_t(compact, _U(properties)).for_each(_U(plugin), Converter<Plugin> (description));
1751  xml_coll_t(compact, _U(surfaces)).for_each(_U(opticalsurface), Converter<OpticalSurface>(description));
1752 
1753  xml_coll_t(compact, _U(materials)).for_each(_U(element), Converter<Atom>(description));
1754  xml_coll_t(compact, _U(materials)).for_each(_U(material), Converter<Material>(description));
1755  xml_coll_t(compact, _U(materials)).for_each(_U(plugin), Converter<Plugin> (description));
1756 
1757  printout(DEBUG, "Compact", "++ Converting visualization attributes...");
1758  xml_coll_t(compact, _U(display)).for_each(_U(include), Converter<DetElementInclude>(description));
1759  xml_coll_t(compact, _U(display)).for_each(_U(vis), Converter<VisAttr>(description));
1760 
1761  printout(DEBUG, "Compact", "++ Converting limitset structures...");
1762  xml_coll_t(compact, _U(limits)).for_each(_U(include), Converter<DetElementInclude>(description));
1763  xml_coll_t(compact, _U(limits)).for_each(_U(limitset), Converter<LimitSet>(description));
1764 
1765  printout(DEBUG, "Compact", "++ Converting region structures...");
1766  xml_coll_t(compact, _U(regions)).for_each(_U(include), Converter<DetElementInclude>(description));
1767  xml_coll_t(compact, _U(regions)).for_each(_U(region), Converter<Region>(description));
1768 
1769  if ( world ) {
1770  (Converter<World>(description))(world);
1771  }
1772  if ( open_geometry ) description.init();
1773  printout(DEBUG, "Compact", "++ Converting readout structures...");
1774  xml_coll_t(compact, _U(readouts)).for_each(_U(include), Converter<DetElementInclude>(description));
1775  xml_coll_t(compact, _U(readouts)).for_each(_U(readout), Converter<Readout>(description));
1776 
1777  printout(DEBUG, "Compact", "++ Converting included files with subdetector structures...");
1778  xml_coll_t(compact, _U(detectors)).for_each(_U(include), Converter<DetElementInclude>(description));
1779  printout(DEBUG, "Compact", "++ Converting detector structures...");
1780  xml_coll_t(compact, _U(detectors)).for_each(_U(detector), Converter<DetElement>(description));
1781  xml_coll_t(compact, _U(include)).for_each(Converter<DetElementInclude>(this->description));
1782 
1783  xml_coll_t(compact, _U(includes)).for_each(_U(xml), Converter<XMLFile>(description));
1784  xml_coll_t(compact, _U(fields)).for_each(_U(field), Converter<CartesianField>(description));
1785  xml_coll_t(compact, _U(sensitive_detectors)).for_each(_U(sd), Converter<SensitiveDetector>(description));
1786  xml_coll_t(compact, _U(parallelworld_volume)).for_each(Converter<Parallelworld_Volume>(description));
1787 
1788  if ( --num_calls == 0 && close_document ) {
1789  ::snprintf(text, sizeof(text), "%u", xml_h(element).checksum(0));
1790  description.addConstant(Constant("compact_checksum", text));
1791  description.endDocument(close_geometry);
1792  }
1793  if ( build_reflections ) {
1794  ReflectionBuilder rb(description);
1795  rb.execute();
1796  }
1798  xml_coll_t(compact, _U(plugins)).for_each(_U(plugin), Converter<Plugin> (description));
1799  xml_coll_t(compact, _U(plugins)).for_each(_U(include), Converter<XMLFile> (description));
1800  xml_coll_t(compact, _U(plugins)).for_each(_U(xml), Converter<XMLFile> (description));
1801 }
1802 
1803 #ifdef _WIN32
1804 template Converter<Plugin>;
1805 template Converter<Constant>;
1806 template Converter<Material>;
1807 template Converter<Atom>;
1808 template Converter<VisAttr>;
1809 template Converter<Region>;
1810 template Converter<Readout>;
1811 template Converter<Segmentation>;
1812 template Converter<LimitSet>;
1813 template Converter<Property>;
1814 template Converter<CartesianField>;
1815 template Converter<SensitiveDetector>;
1816 template Converter<DetElement>;
1817 template Converter<GdmlFile>;
1818 template Converter<XMLFile>;
1819 template Converter<Header>;
1820 template Converter<DetElementInclude>;
1821 template Converter<Compact>;
1822 
1823 #endif
dd4hep::Header::setAuthor
void setAuthor(const std::string &new_author)
Accessor: set object author.
Definition: Objects.cpp:102
dd4hep::World
Handle class to hold the information of the top DetElement object 'world'.
Definition: World.h:30
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::Header::setStatus
void setStatus(const std::string &new_status)
Accessor: set object status.
Definition: Objects.cpp:112
dd4hep::Detector::addIDSpecification
virtual Detector & addIDSpecification(const Handle< NamedObject > &element)=0
Add a new id descriptor by named reference to the detector description.
dd4hep::xml::Handle_t::tag
std::string tag() const
Text access to the element's tag.
Definition: XMLElements.h:414
dd4hep::Property
The property class to assign options to actions.
Definition: ComponentProperties.h:45
dd4hep::xml::_toDouble
double _toDouble(const XmlChar *value)
Conversion function from raw unicode string to double.
Definition: XMLElements.cpp:360
dd4hep::Detector::detector
virtual DetElement detector(const std::string &name) const =0
Retrieve a subdetector element by its name from the detector description.
dd4hep::DipoleField::rmax
double rmax
Definition: FieldTypes.h:81
OpticalSurfaces.h
Path.h
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:43
dd4hep::DetElement::parent
DetElement parent() const
Access to the detector elements's parent.
Definition: DetElement.cpp:239
MatrixHelpers.h
dd4hep::Limit::particles
std::string particles
Particle the limit should be applied to.
Definition: Objects.h:391
dd4hep::HitCollection
Definition of the HitCollection parameters used by the Readout.
Definition: ObjectsInterna.h:157
dd4hep::info
std::size_t info(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:65
dd4hep::Detector::Properties
std::map< std::string, PropertyValues > Properties
Definition: Detector.h:95
dd4hep::DDSegmentation::BitFieldCoder
Helper class for decoding and encoding a bit field of 64bits for convenient declaration.
Definition: BitFieldCoder.h:113
dd4hep::exception
void exception(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:69
dd4hep::DetElement::type
std::string type() const
Access detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:97
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:164
dd4hep::VisAttr
Handle class describing visualization attributes.
Definition: Objects.h:323
dd4hep::Box::x
double x() const
Access half "length" of the box.
Definition: Shapes.cpp:155
dd4hep::MultipoleField
Implementation object of a Multipole magnetic field.
Definition: FieldTypes.h:152
dd4hep::_toDictionary
void _toDictionary(const std::string &name, const std::string &value)
Enter name value pair to the dictionary. "value" must be a numerical expression, which is evaluated.
Definition: Handle.cpp:240
dd4hep::SensitiveDetector::setHitsCollection
SensitiveDetector & setHitsCollection(const std::string &spec)
Assign the name of the hits collection.
Definition: DetElement.cpp:441
dd4hep::PropertyTable
Class to support the handling of optical surfaces.
Definition: PropertyTable.h:32
dd4hep::SensitiveDetector::setVerbose
SensitiveDetector & setVerbose(bool value)
Set flag to handle hits collection.
Definition: DetElement.cpp:452
dd4hep::debug
std::size_t debug(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:64
dd4hep::Header::setComment
void setComment(const std::string &new_comment)
Accessor: set object comment.
Definition: Objects.cpp:132
dd4hep::Limit
Small object describing a limit structure acting on a particle type.
Definition: Objects.h:388
dd4hep::Segmentation::sensitive
Handle< SensitiveDetectorObject > sensitive() const
Access the sensitive detector using this segmentation object.
Definition: Segmentations.cpp:125
dd4hep::Volume::solid
Solid solid() const
Access to Solid (Shape)
Definition: Volumes.cpp:1252
dd4hep::Detector::PropertyValues
std::map< std::string, std::string > PropertyValues
Definition: Detector.h:94
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
dd4hep::Handle< NamedObject >
dd4hep::Segmentation::detector
Handle< DetElementObject > detector() const
Access the main detector element using this segmentation object.
Definition: Segmentations.cpp:120
dd4hep::CartesianField::MAGNETIC
@ MAGNETIC
Definition: Fields.h:43
DetectorInterna.h
dd4hep::Detector::region
virtual Region region(const std::string &name) const =0
Retrieve a region object by its name from the detector description.
dd4hep::detail::matrix::_transform
TGeoHMatrix * _transform(const Transform3D &trans)
Convert a Transform3D object to a newly created TGeoHMatrix.
Definition: MatrixHelpers.cpp:140
dd4hep::_toString
std::string _toString(bool value)
String conversions: boolean value to string.
Definition: Handle.cpp:332
dd4hep::Solid_type< TGeoShape >
dd4hep::xml::Tag_t::c_str
const char * c_str() const
Access data buffer of STL string.
Definition: XMLElements.h:308
dd4hep::xml::Handle_t
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:380
dd4hep::Detector::worldVolume
virtual Volume worldVolume() const =0
Return handle to the world volume containing everything.
check_process_file
bool check_process_file(Detector &description, std::string filename)
Check whether a XML file was already processed.
Definition: Compact2Objects.cpp:275
Factories.h
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::Header::setUrl
void setUrl(const std::string &new_url)
Accessor: set object url.
Definition: Objects.cpp:92
dd4hep::OverlayedField::properties
Properties & properties() const
Access to properties container.
Definition: Fields.cpp:99
dd4hep::DipoleField
Implementation object of a dipole magnetic field.
Definition: FieldTypes.h:77
dd4hep::Volume::placeVolume
PlacedVolume placeVolume(const Volume &volume) const
Place daughter volume. The position and rotation are the identity.
Definition: Volumes.cpp:859
xml_coll_t
dd4hep::xml::Collection_t xml_coll_t
Definition: ConditionsRepository.cpp:35
dd4hep::Detector::addVisAttribute
virtual Detector & addVisAttribute(const Handle< NamedObject > &element)=0
Add a new visualisation attribute by named reference to the detector description.
dd4hep::SolenoidField::maxZ
double maxZ
Definition: FieldTypes.h:58
xml_attr_t
dd4hep::xml::Attribute xml_attr_t
Definition: XML.h:27
xml_comp_t
dd4hep::xml::Component xml_comp_t
Definition: XML.h:33
dd4hep::DDSegmentation::Segmentation::name
virtual const std::string & name() const
Access the segmentation name.
Definition: Segmentation.h:95
_Unicode
#define _Unicode(a)
Definition: Tags.h:24
dd4hep::detail::tools::findElement
DetElement findElement(const Detector &description, const std::string &path)
Find DetElement as child of the top level volume by its absolute path.
Definition: DetectorTools.cpp:215
dd4hep::Detector::addField
virtual Detector & addField(const Handle< NamedObject > &field)=0
Add a field component by named reference to the detector description.
dd4hep::xml::Element::setValue
void setValue(const T &val) const
Set element value.
Definition: XMLElements.h:904
DocumentHandler.h
dd4hep::Detector::addLimitSet
virtual Detector & addLimitSet(const Handle< NamedObject > &limset)=0
Add a new limit set by named reference to the detector description.
dd4hep::Material
Handle class describing a material.
Definition: Objects.h:271
dd4hep::ConstantField
Implementation object of a field with constant strength.
Definition: FieldTypes.h:34
dd4hep::xml::Handle_t::attr_name
const XmlChar * attr_name(const Attribute attr) const
Access attribute name (throws exception if not present)
Definition: XMLElements.cpp:854
dd4hep::xml::Tag_t
Class to support both way translation between C++ and XML strings.
Definition: XMLElements.h:254
dd4hep::xml::Handle_t::hasChild
bool hasChild(const XmlChar *tag) const
Check the existence of a child with a given tag name.
Definition: XMLElements.cpp:767
dd4hep::Detector::addConstant
virtual Detector & addConstant(const Handle< NamedObject > &element)=0
Add a new constant by named reference to the detector description.
dd4hep::STD_Conditions::temperature
double temperature
Definition: Detector.h:69
dd4hep::Detector::material
virtual Material material(const std::string &name) const =0
Retrieve a matrial by its name from the detector description.
dd4hep::DipoleField::zmax
double zmax
Definition: FieldTypes.h:79
dd4hep::SolenoidField::innerRadius
double innerRadius
Definition: FieldTypes.h:59
dd4hep::Detector::setTrackingVolume
virtual void setTrackingVolume(Volume vol)=0
Set the tracking volume of the detector.
dd4hep::STD_Conditions
Helper class to access default temperature and pressure.
Definition: Detector.h:58
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::Detector::air
virtual Material air() const =0
Return handle to material describing air.
dd4hep::Constant
Handle class describing a constant (define) object in description.
Definition: Objects.h:208
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:371
dd4hep::Detector::addSensitiveDetector
virtual Detector & addSensitiveDetector(const Handle< NamedObject > &element)=0
Add a new sensitive detector by named reference to the detector description.
dd4hep::DipoleField::coefficents
Coefficents coefficents
Definition: FieldTypes.h:82
dd4hep::Handle::assign
void assign(Object *n, const std::string &nam, const std::string &title)
Assign a new named object. Note: object references must be managed by the user.
mix
#define mix(a, b, c)
Definition: Geant4EventSeed.h:113
dd4hep::Detector::apply
virtual long apply(const char *factory, int argc, char **argv) const =0
Manipulate geometry using factory converter.
dd4hep::xml::Handle_t::attr_value
const XmlChar * attr_value(const Attribute attr) const
Access attribute value by the attribute (throws exception if not present)
Definition: XMLElements.cpp:867
dd4hep::Detector::field
virtual OverlayedField field() const =0
Return handle to the combined electromagentic field description.
dd4hep::xml::Collection_t::for_each
void for_each(T oper) const
Loop processor using function object.
Definition: XMLElements.h:667
dd4hep::Detector::init
virtual void init()=0
Initialize geometry.
dd4hep::Header::setTitle
void setTitle(const std::string &new_title)
Accessor: set object title.
Definition: Objects.cpp:82
dd4hep::OpticalSurface::EFinish
Object::ESurfaceFinish EFinish
Definition: OpticalSurfaces.h:49
dd4hep::xml::Element::child
Handle_t child(const Strng_t &tag_value, bool except=true) const
Access child by tag name. Thow an exception if required in case the child is not present.
Definition: XMLElements.h:914
dd4hep::MultipoleField::B_z
double B_z
Constant Z field overlay.
Definition: FieldTypes.h:167
dd4hep::LimitSet
Handle class describing a set of limits as they are used for simulation.
Definition: Objects.h:424
dd4hep::SensitiveDetector::hitsCollection
const std::string & hitsCollection() const
Access the hits collection name.
Definition: DetElement.cpp:447
dd4hep::SolenoidField::minZ
double minZ
Definition: FieldTypes.h:57
OpticalSurfaceManager.h
dd4hep::xml::createShape
Solid createShape(Detector &description, const std::string &shape_type, xml::Element element)
Create a solid shape using the plugin mechanism from the attributes of the XML element.
Definition: Utilities.cpp:84
dd4hep::Limit::name
std::string name
Limit name.
Definition: Objects.h:393
dd4hep::OpticalSurfaceManager::registerSurfaces
void registerSurfaces(DetElement subdetector)
Register the temporary surface objects with the TGeoManager.
Definition: OpticalSurfaceManager.cpp:119
dd4hep::DetElementObject::flag
unsigned int flag
Flag to remember internally calculated quatities.
Definition: DetectorInterna.h:100
dd4hep::VisAttr::DASHED
@ DASHED
Definition: Objects.h:326
DetectorTools.h
dd4hep::Detector::sensitiveDetector
virtual SensitiveDetector sensitiveDetector(const std::string &name) const =0
Retrieve a sensitive detector by its name from the detector description.
dd4hep::DDSegmentation::Parameters
std::vector< Parameter > Parameters
Definition: SegmentationsInterna.h:35
dd4hep::Volume::VETO_SIMU
@ VETO_SIMU
Definition: Volumes.h:376
dd4hep::xml
Namespace for the AIDA detector description toolkit supporting XML utilities.
Definition: ConditionsTags.h:27
xml_det_t
dd4hep::xml::DetElement xml_det_t
Definition: XML.h:32
dd4hep::CartesianField::Properties
std::map< std::string, std::map< std::string, std::string > > Properties
Definition: Fields.h:45
_U
#define _U(a)
Definition: Tags.h:23
TNamed
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:37
dd4hep::Detector::surfaceManager
virtual OpticalSurfaceManager surfaceManager() const =0
Access the optical surface manager.
Plugins.h
dd4hep::Detector::endDocument
virtual void endDocument(bool close_geometry=true)=0
Finalize the geometry.
dd4hep::Detector::stdConditions
virtual const STD_Conditions & stdConditions() const =0
Access default conditions (temperature and pressure.
dd4hep::Region
Handle class describing a region as used in simulation.
Definition: Objects.h:461
dd4hep::PluginDebug
Helper to debug plugin manager calls.
Definition: Plugins.h:73
dd4hep::MultipoleField::transform
Transform3D transform
Position transformation of the field. Only stored here for reference.
Definition: FieldTypes.h:161
dd4hep::Header::setName
void setName(const std::string &new_name)
Accessor: set object name.
Definition: Objects.cpp:72
dd4hep::Header
Handle class describing the basic information about geometry objects as it is defined in Detector.
Definition: Objects.h:157
dd4hep::Limit::content
std::string content
Content.
Definition: Objects.h:397
dd4hep::Path::normalize
Path normalize() const
Normalize path name.
Definition: Path.cpp:114
dd4hep::SensitiveDetector::setReadout
SensitiveDetector & setReadout(Readout readout)
Assign the IDDescriptor reference.
Definition: DetElement.cpp:414
dd4hep::Readout::segmentation
Segmentation segmentation() const
Access segmentation structure.
Definition: Readout.cpp:134
dd4hep::Limit::unit
std::string unit
Units.
Definition: Objects.h:395
dd4hep::xml::Strng_t
Helper class to encapsulate a unicode string.
Definition: XMLElements.h:170
dd4hep::Detector::limitSet
virtual LimitSet limitSet(const std::string &name) const =0
Retrieve a limitset by its name from the detector description.
dd4hep::DDSegmentation::splitString
std::vector< std::string > splitString(const std::string &s, char delimiter=' ')
Helper method to split string into tokens.
Definition: SegmentationParameter.h:33
dd4hep::PluginDebug::missingFactory
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
Definition: Plugins.cpp:147
dd4hep::ReflectionBuilder
Scan geometry and create reflected volumes.
Definition: Volumes.h:60
dd4hep::sim::IDDescriptor
IDDescriptor IDDescriptor
Definition: LCIOConversions.cpp:69
dd4hep::verbose
std::size_t verbose(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:63
dd4hep::xml::DocumentHolder
Class supporting the basic functionality of an XML document including ownership.
Definition: XMLElements.h:741
dd4hep::Limit::value
double value
Double value.
Definition: Objects.h:399
dd4hep::xml::Handle_t::child
Handle_t child(const XmlChar *tag, bool throw_exception=true) const
Access a single child by its tag name (unicode)
Definition: XMLElements.cpp:713
DECLARE_XML_DOC_READER
#define DECLARE_XML_DOC_READER(name, func)
Definition: Factories.h:316
dd4hep::Detector::invisible
virtual VisAttr invisible() const =0
Return handle to "invisible" visualization attributes.
dd4hep::xml::Element::hasAttr
bool hasAttr(const XmlChar *name) const
Check for the existence of a named attribute.
Definition: XMLElements.h:847
detectors
DetectorMap detectors
Definition: AlignmentsCalculator.cpp:79
dd4hep::Detector::visAttributes
virtual const HandleMap & visAttributes() const =0
Accessor to the map of visualisation attributes.
dd4hep::Transform3D
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:116
dd4hep::SensitiveDetector::type
std::string type() const
Access the type of the sensitive detector.
Definition: DetElement.cpp:409
xml_tag_t
dd4hep::xml::Tag_t xml_tag_t
Definition: XML.h:26
xml_h
dd4hep::xml::Handle_t xml_h
Definition: ConditionsRepository.cpp:32
DECLARE_XMLELEMENT
#define DECLARE_XMLELEMENT(name, func)
Definition: Factories.h:301
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:80
dd4hep::xml::RefElement
User abstraction class to manipulate named XML elements (references) within a document.
Definition: XMLElements.h:953
dd4hep::CartesianField::TypedObject::field_type
int field_type
Field type.
Definition: Fields.h:56
ProcessedFilesSet
Definition: Compact2Objects.cpp:272
dd4hep::Ref_t
Handle< NamedObject > Ref_t
Default Ref_t definition describing named objects.
Definition: Handle.h:180
DetFactoryHelper.h
SegmentationsInterna.h
dd4hep::SolenoidField::outerField
double outerField
Definition: FieldTypes.h:56
dd4hep::_toDouble
double _toDouble(const std::string &value)
String conversions: string to double value.
Definition: Handle.cpp:116
key
unsigned char key
Definition: AlignmentsCalculator.cpp:69
dd4hep::Segmentation::segmentation
DDSegmentation::Segmentation * segmentation() const
Access to the base DDSegmentation object. WARNING: Deprecated call!
Definition: Segmentations.cpp:105
dd4hep::DetElement::Children
std::map< std::string, DetElement > Children
Definition: DetElement.h:205
dd4hep::Detector::buildType
virtual DetectorBuildType buildType() const =0
Access flag to steer the detail of building of the geometry/detector description.
dd4hep::Box
Class describing a box shape.
Definition: Shapes.h:295
IDDescriptor.h
dd4hep::xml::DocumentHandler
Class supporting to read and parse XML documents.
Definition: DocumentHandler.h:39
dd4hep::OpticalSurface::stringToModel
static EModel stringToModel(const std::string &model)
Definition: OpticalSurfaces.h:90
std
Definition: Plugins.h:29
dd4hep::MultipoleField::skews
Coefficents skews
Multi-pole skews.
Definition: FieldTypes.h:157
dd4hep::VisAttr::SOLID
@ SOLID
Definition: Objects.h:326
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:151
ObjectsInterna.h
PropertyTable.h
dd4hep::_multiply< double >
double _multiply< double >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:236
dd4hep::Detector::constant
virtual Constant constant(const std::string &name) const =0
Retrieve a constant by its name from the detector description.
dd4hep::xml::Element
User abstraction class to manipulate XML elements within a document.
Definition: XMLElements.h:769
dd4hep::xml::dump_tree
void dump_tree(Handle_t elt)
Dump partial or full XML trees to stdout.
Definition: DocumentHandler.cpp:698
dd4hep::MultipoleField::volume
Solid volume
Boundary volume (optional)
Definition: FieldTypes.h:159
dd4hep::SensitiveDetector::energyCutoff
double energyCutoff() const
Access energy cut off.
Definition: DetElement.cpp:436
dd4hep::Volume::setVisAttributes
const Volume & setVisAttributes(const VisAttr &obj) const
Set Visualization attributes to the volume.
Definition: Volumes.cpp:1156
dd4hep::Detector::extension
IFACE * extension(bool alert=true) const
Access extension element by the type.
Definition: Detector.h:342
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::xml::Tag_t::str
const std::string & str() const
Access writable STL string.
Definition: XMLElements.h:304
dd4hep::DDSegmentation::TypedSegmentationParameter
Concrete class to hold a segmentation parameter of a given type with its description.
Definition: SegmentationParameter.h:166
dd4hep::VisAttr::WIREFRAME
@ WIREFRAME
Definition: Objects.h:326
dd4hep::xml::Handle_t::attributes
std::vector< Attribute > attributes() const
Retrieve a collection of all attributes of this DOM element.
Definition: XMLElements.cpp:681
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::MultipoleField::coefficents
Coefficents coefficents
Multi-pole coefficients.
Definition: FieldTypes.h:155
dd4hep::OpticalSurface::EModel
Object::ESurfaceModel EModel
Definition: OpticalSurfaces.h:48
dd4hep::STD_Conditions::pressure
double pressure
Definition: Detector.h:68
dd4hep::xml::getEnviron
std::string getEnviron(const std::string &env)
Helper function to lookup environment from the expression evaluator.
Definition: XMLElements.cpp:406
dd4hep::Detector::fromXML
virtual void fromXML(const std::string &fname, DetectorBuildType type=BUILD_DEFAULT)=0
Read any geometry description or alignment file.
dd4hep::Detector::addDetector
virtual Detector & addDetector(const Handle< NamedObject > &detector)=0
Add a new subdetector by named reference to the detector description.
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::Readout
Handle to the implementation of the readout structure of a subdetector.
Definition: Readout.h:38
dd4hep::Segmentation
Handle class supporting generic Segmentations of sensitive detectors.
Definition: Segmentations.h:41
dd4hep::xml::DocumentHandler::system_directory
static std::string system_directory(Handle_t base)
System directory of a given XML entity.
Definition: DocumentHandler.cpp:673
dd4hep::CartesianField::ELECTRIC
@ ELECTRIC
Definition: Fields.h:43
dd4hep::OpticalSurface::stringToFinish
static EFinish stringToFinish(const std::string &finish)
Definition: OpticalSurfaces.h:96
dd4hep::SensitiveDetector::setRegion
SensitiveDetector & setRegion(Region reg)
Set the regional attributes to the sensitive detector.
Definition: DetElement.cpp:476
dd4hep::Detector::setStdConditions
virtual void setStdConditions(double temp, double pressure)=0
Set the STD temperature and pressure.
dd4hep::SensitiveDetector::setCombineHits
SensitiveDetector & setCombineHits(bool value)
Set flag to handle hits collection.
Definition: DetElement.cpp:464
dd4hep::RotationZYX
ROOT::Math::RotationZYX RotationZYX
Definition: Objects.h:104
dd4hep::SolenoidField::outerRadius
double outerRadius
Definition: FieldTypes.h:60
dd4hep::DDSegmentation::Segmentation::addSubsegmentation
virtual void addSubsegmentation(long key_min, long key_max, Segmentation *entry)
Add subsegmentation. Call only valid for Multi-segmentations. Default implementation throws an except...
Definition: Segmentation.cpp:61
dd4hep::DetElementObject::HAVE_SENSITIVE_DETECTOR
@ HAVE_SENSITIVE_DETECTOR
Definition: DetectorInterna.h:92
dd4hep::xml::Handle_t::hasAttr
bool hasAttr(const XmlChar *t) const
Check for the existence of a named attribute.
Definition: XMLElements.cpp:676
dd4hep::Detector::readout
virtual Readout readout(const std::string &name) const =0
Retrieve a readout object by its name from the detector description.
dd4hep::SensitiveDetector::setLimitSet
SensitiveDetector & setLimitSet(LimitSet limits)
Set the limits to the sensitive detector.
Definition: DetElement.cpp:487
dd4hep::Detector::declareParent
virtual void declareParent(const std::string &detector_name, const DetElement &det)=0
Register new parent detector using the detector name.
dd4hep::xml::DocumentHandler::system_path
static std::string system_path(Handle_t base)
System ID of a given XML entity.
Definition: DocumentHandler.cpp:276
dd4hep::Detector::addReadout
virtual Detector & addReadout(const Handle< NamedObject > &readout)=0
Add a new detector readout by named reference to the detector description.
dd4hep::Detector::parallelWorldVolume
virtual Volume parallelWorldVolume() const =0
Return handle to the parallel world volume.
dd4hep::Volume::visAttributes
VisAttr visAttributes() const
Access the visualisation attributes.
Definition: Volumes.cpp:1239
DD4hepUnits.h
dd4hep::OpticalSurface::EType
Object::ESurfaceType EType
Definition: OpticalSurfaces.h:50
FieldTypes.h
dd4hep::DDSegmentation::Segmentation
Base class for all segmentations.
Definition: Segmentation.h:74
dd4hep::Header::setVersion
void setVersion(const std::string &new_version)
Accessor: set object version.
Definition: Objects.cpp:122
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::Detector::header
virtual Header header() const =0
Accessor to the map of header entries.
dd4hep::SolenoidField::innerField
double innerField
Definition: FieldTypes.h:55
dd4hep::Path
Path handling class.
Definition: Path.h:45
dd4hep::SensitiveDetector::setType
SensitiveDetector & setType(const std::string &typ)
Set detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:403
dd4hep::SolenoidField
Implementation object of a solenoidal magnetic field.
Definition: FieldTypes.h:53
Gaudi::PluginService::v1::Debug
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
Definition: PluginServiceV1.cpp:340
dd4hep::Detector::addRegion
virtual Detector & addRegion(const Handle< NamedObject > &region)=0
Add a new detector region by named reference to the detector description.
dd4hep::Detector::properties
virtual Properties & properties() const =0
Access to properties map.
dd4hep::CartesianField
Base class describing any field with 3D cartesian vectors for the field strength.
Definition: Fields.h:40
dd4hep::xml::Handle_t::attr_nothrow
Attribute attr_nothrow(const XmlChar *tag) const
Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
Definition: XMLElements.cpp:671
dd4hep::DDSegmentation::Segmentation::type
virtual const std::string & type() const
Access the segmentation type.
Definition: Segmentation.h:103