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