42 #include <TGeoManager.h>
43 #include <TGeoMaterial.h>
44 #include <TGeoPhysicalConstants.h>
45 #include <TGDMLMatrix.h>
69 class PropertyConstant;
70 class Parallelworld_Volume;
71 class DetElementInclude;
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;
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);
112 bool readout =
false;
113 bool regions =
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;
123 bool surface =
false;
124 bool detelements =
false;
125 bool include_guard=
true;
132 std::string t = e.
attr<std::string>(
_U(field));
135 ptr->direction.SetX(strength.x());
136 ptr->direction.SetY(strength.y());
137 ptr->direction.SetZ(strength.z());
138 obj.
assign(ptr, field.nameStr(), field.typeStr());
145 bool has_inner_radius = c.hasAttr(
_U(inner_radius));
146 bool has_outer_radius = c.hasAttr(
_U(outer_radius));
148 if (!has_inner_radius && !has_outer_radius) {
149 throw_print(
"Compact2Objects[ERROR]: For a solenoidal field at least one of the "
150 " xml attributes inner_radius of outer_radius MUST be set.");
159 if (has_inner_radius && has_outer_radius) {
163 else if (has_inner_radius) {
168 else if (has_outer_radius) {
173 if (c.hasAttr(
_U(inner_field)))
175 if (c.hasAttr(
_U(outer_field)))
177 if (c.hasAttr(
_U(zmax)))
178 ptr->
maxZ = c.attr<
double>(
_U(zmax));
181 if (c.hasAttr(
_U(zmin)))
182 ptr->
minZ = c.attr<
double>(
_U(zmin));
186 obj.
assign(ptr, c.nameStr(), c.typeStr());
197 double lunit = c.hasAttr(
_U(lunit)) ? c.attr<
double>(
_U(lunit)) : 1.0;
198 double funit = c.hasAttr(
_U(funit)) ? c.attr<
double>(
_U(funit)) : 1.0;
199 double val, mult = funit;
201 if (c.hasAttr(
_U(zmin)))
203 if (c.hasAttr(
_U(zmax)))
205 if (c.hasAttr(
_U(rmax)))
207 for (
xml_coll_t coll(c,
_U(dipole_coeff)); coll; ++coll, mult /= lunit) {
209 if ( coeff.hasAttr(
_U(value)) )
210 val = coll.attr<
double>(
_U(value)) * mult;
211 else if ( coeff.hasAttr(
_U(coefficient)) )
212 val = coeff.coefficient() * mult;
218 obj.
assign(ptr, c.nameStr(), c.typeStr());
227 double lunit = c.hasAttr(
_U(lunit)) ? c.attr<
double>(
_U(lunit)) : 1.0;
228 double funit = c.hasAttr(
_U(funit)) ? c.attr<
double>(
_U(funit)) : 1.0;
229 double val, mult = funit, bz = 0.0;
233 if (c.hasAttr(
_U(Z))) bz = c.Z() * funit;
234 if ((child = c.child(
_U(position),
false))) {
235 pos.SetXYZ(child.x(), child.y(), child.z());
237 if ((child = c.child(
_U(rotation),
false))) {
238 rot.SetComponents(child.z(), child.y(), child.x());
240 if ((child = c.child(
_U(shape),
false))) {
241 std::string type = child.typeStr();
246 for (
xml_coll_t coll(c,
_U(coefficient)); coll; ++coll, mult /= lunit) {
248 if ( coll.hasAttr(
_U(value)) )
249 val = coll.attr<
double>(
_U(value)) * mult;
251 val = coeff.coefficient(0.0) * mult;
253 val = coeff.skew(0.0) * mult;
254 ptr->
skews.emplace_back(val);
257 obj.
assign(ptr, c.nameStr(), c.typeStr());
262 static long load_Compact(
Detector& description,
xml_h element) {
263 Converter<Compact>converter(description);
280 if ( !already_processed ) {
285 if (already_processed->find(npath) != already_processed->end() ) {
286 printout(INFO,
"Compact",
"++ Already processed xml document %s.", npath.c_str());
289 already_processed->insert(npath);
295 template <>
void Converter<Debug>::operator()(
xml_h e)
const {
297 int val = coll.attr<
int>(
_U(value));
298 std::string nam = coll.attr<std::string>(
_U(name));
299 if ( nam.substr(0,6) ==
"isotop" ) s_debug.isotopes = (0 != val);
300 else if ( nam.substr(0,6) ==
"elemen" ) s_debug.elements = (0 != val);
301 else if ( nam.substr(0,6) ==
"materi" ) s_debug.materials = (0 != val);
302 else if ( nam.substr(0,6) ==
"visatt" ) s_debug.visattr = (0 != val);
303 else if ( nam.substr(0,6) ==
"region" ) s_debug.regions = (0 != val);
304 else if ( nam.substr(0,6) ==
"readou" ) s_debug.readout = (0 != val);
305 else if ( nam.substr(0,6) ==
"limits" ) s_debug.limits = (0 != val);
306 else if ( nam.substr(0,6) ==
"segmen" ) s_debug.segmentation = (0 != val);
307 else if ( nam.substr(0,6) ==
"consta" ) s_debug.constants = (0 != val);
308 else if ( nam.substr(0,6) ==
"define" ) s_debug.constants = (0 != val);
309 else if ( nam.substr(0,6) ==
"includ" ) s_debug.includes = (0 != val);
310 else if ( nam.substr(0,6) ==
"matrix" ) s_debug.matrix = (0 != val);
311 else if ( nam.substr(0,6) ==
"surfac" ) s_debug.surface = (0 != val);
312 else if ( nam.substr(0,6) ==
"incgua" ) s_debug.include_guard= (0 != val);
313 else if ( nam.substr(0,6) ==
"detele" ) s_debug.detelements = (0 != val);
321 template <>
void Converter<Plugin>::operator()(
xml_h e)
const {
323 std::string name = plugin.nameStr();
324 std::string type =
"default";
327 type = e.
attr<std::string>(typ_attr);
329 if ( type ==
"default" ) {
330 std::vector<char*> argv;
331 std::vector<std::string> arguments;
333 std::string val = coll.attr<std::string>(
_U(value));
334 arguments.emplace_back(val);
337 std::string val = coll.attr<std::string>(
_U(value));
338 arguments.emplace_back(val);
340 for(std::vector<std::string>::iterator i=arguments.begin(); i!=arguments.end(); ++i)
341 argv.emplace_back(&((*i)[0]));
342 description.
apply(name.c_str(),int(argv.size()), argv.empty() ? nullptr : &argv[0]);
346 long result = PluginService::Create<long>(name, &description, &e);
349 result = PluginService::Create<long>(name, &description, &e);
351 except(
"Compact",
"++ Failed to locate plugin %s - no factory: %s",
355 result = *(
long*) result;
357 except(
"Compact",
"++ Failed to execute plugin %s", name.c_str());
365 template <>
void Converter<Constant>::operator()(
xml_h e)
const {
366 if ( e.
tag() !=
"include" ) {
368 std::string nam = constant.attr<std::string>(
_U(name));
369 std::string val = constant.attr<std::string>(
_U(value));
370 std::string typ = constant.hasAttr(
_U(type)) ? constant.attr<std::string>(
_U(type)) :
"number";
374 if ( s_debug.constants ) {
375 printout(ALWAYS,
"Compact",
376 "++ Converting constant %-16s = %-32s [%s]", nam.c_str(), val.c_str(), typ.c_str());
381 if ( s_debug.includes ) {
382 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
384 xml_h root = doc.root();
393 template <>
void Converter<Header>::operator()(
xml_h e)
const {
397 h =
Header(e.
attr<std::string>(
_U(name)), e.
attr<std::string>(
_U(title),
"Undefined"));
406 printout(WARNING,
"Compact",
"++ Overwriting/updating Header structure is very dangerous. Try to avoid this.");
433 template <>
void Converter<Material>::operator()(
xml_h e)
const {
435 TGeoManager& mgr = description.
manager();
437 const char* matname = mname.
c_str();
438 TGeoElementTable* table = mgr.GetElementTable();
439 TGeoMaterial* mat = mgr.GetMaterial(matname);
440 TGeoMixture*
mix =
dynamic_cast<TGeoMixture*
>(mat);
445 TGeoMaterial* comp_mat;
446 TGeoElement* comp_elt;
448 double dens_val = density.
ptr() ? density.
attr<
double>(
_U(value)) : 0.0;
449 double dens_unit = 1.0;
451 if ( !density.
ptr() ) {
452 throw_print(
"Compact2Objects[ERROR]: material without density tag ( <D unit=\"g/cm3\" value=\"..\"/> ) provided: "
453 + std::string( matname ) ) ;
458 if ( dens_unit != 1.0 ) {
459 dens_val *= dens_unit;
460 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
"Density unit: %.3f [%s] raw: %.3f normalized: %.3f ",
461 dens_unit, density.
attr<std::string>(
_U(unit)).c_str(), dens_val, (dens_val*dens_unit));
463 mat =
mix =
new TGeoMixture(matname, composites.size(), dens_val);
464 std::size_t ifrac = 0;
465 std::vector<double> composite_fractions;
466 double composite_fractions_total = 0.0;
467 for (composites.reset(); composites; ++composites) {
468 std::string nam = composites.attr<std::string>(
_U(ref));
469 double fraction = composites.attr<
double>(
_U(n));
470 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
471 fraction *= comp_mat->GetA();
472 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
473 fraction *= comp_elt->A();
475 except(
"Compact2Objects",
"Converting material: %s Element missing: %s",mname.
c_str(),nam.c_str());
476 composite_fractions_total += fraction;
477 composite_fractions.emplace_back(fraction);
479 for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) {
480 std::string nam = composites.attr<std::string>(
_U(ref));
481 double fraction = composite_fractions[ifrac]/composite_fractions_total;
482 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
483 mix->AddElement(comp_mat, fraction);
484 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
485 mix->AddElement(comp_elt, fraction);
487 for (fractions.reset(); fractions; ++fractions) {
488 std::string nam = fractions.attr<std::string>(
_U(ref));
489 double fraction = fractions.attr<
double>(
_U(n));
490 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
491 mix->AddElement(comp_mat, fraction);
492 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
493 mix->AddElement(comp_elt, fraction);
495 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" Element missing: " + nam);
499 if ( temperature.
ptr() ) {
502 temp_unit = temperature.
attr<
double>(
_U(unit));
503 temp_val = temperature.
attr<
double>(
_U(value)) * temp_unit;
507 if ( pressure.
ptr() ) {
508 double pressure_unit =
_toDouble(
"pascal");
510 pressure_unit = pressure.
attr<
double>(
_U(unit));
511 pressure_val = pressure.
attr<
double>(
_U(value)) * pressure_unit;
514 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
515 "++ ROOT raw temperature and pressure: %.3g %.3g",
516 mat->GetTemperature(),mat->GetPressure());
518 mat->SetTemperature(temp_val);
519 mat->SetPressure(pressure_val);
520 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
521 "++ Converting material %-16s Density: %9.7g Temperature:%9.7g [K] Pressure:%9.7g [hPa].",
522 matname, dens_val, temp_val/dd4hep::kelvin, pressure_val/dd4hep::pascal/100.0);
525 mix->ComputeDerivedQuantities();
528 for(
xml_coll_t properties(x_mat,
_U(constant)); properties; ++properties) {
532 std::string ref = p.
attr<std::string>(
_U(ref));
533 mgr.GetProperty(ref.c_str(), &err);
534 if ( err == kFALSE ) {
535 std::string prop_nam = p.
attr<std::string>(
_U(name));
536 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
537 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
538 "++ material %-16s add constant property: %s -> %s.",
539 mat->GetName(), prop_nam.c_str(), ref.c_str());
543 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" ConstProperty missing in TGeoManager: " + ref);
546 std::stringstream str;
547 std::string ref, prop_nam = p.
attr<std::string>(
_U(name));
548 str << prop_nam <<
"_" << (
void*)mat;
550 mgr.AddProperty(ref.c_str(), p.
attr<
double>(
_U(value)));
551 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
552 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
553 "++ material %-16s add constant property: %s -> %s.",
554 mat->GetName(), prop_nam.c_str(), ref.c_str());
557 std::string prop_nam = p.
attr<std::string>(
_U(name));
558 std::string prop_typ = p.
attr<std::string>(
_U(option));
559 mat->AddConstProperty(prop_nam.c_str(), prop_typ.c_str());
560 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
561 "++ material %-16s add constant property: %s -> %s.",
562 mat->GetName(), prop_nam.c_str(), prop_typ.c_str());
566 for(
xml_coll_t properties(x_mat,
_U(property)); properties; ++properties) {
569 std::string ref = p.
attr<std::string>(
_U(ref));
570 TGDMLMatrix* gdmlMat = mgr.GetGDMLMatrix(ref.c_str());
572 std::string prop_nam = p.
attr<std::string>(
_U(name));
573 mat->AddProperty(prop_nam.c_str(), ref.c_str());
574 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
575 "++ material %-16s add property: %s -> %s.",
576 mat->GetName(), prop_nam.c_str(), ref.c_str());
580 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" Property missing: " + ref);
584 TGeoMedium* medium = mgr.GetMedium(matname);
587 medium =
new TGeoMedium(matname, unique_mat_id, mat);
588 medium->SetTitle(
"material");
589 medium->SetUniqueID(unique_mat_id);
593 if (x_mat.hasAttr(
_U(formula))) {
594 std::string form = x_mat.attr<std::string>(
_U(formula));
595 if (form != matname) {
596 medium = mgr.GetMedium(form.c_str());
599 medium =
new TGeoMedium(form.c_str(), unique_mat_id, mat);
600 medium->SetTitle(
"material");
601 medium->SetUniqueID(unique_mat_id);
613 template <>
void Converter<Isotope>::operator()(
xml_h e)
const {
615 TGeoManager& mgr = description.
manager();
616 std::string nam = isotope.nameStr();
617 TGeoElementTable* tab = mgr.GetElementTable();
618 TGeoIsotope* iso = tab->FindIsotope(nam.c_str());
623 std::string unit = atom.attr<std::string>(
_U(unit));
624 double value = atom.attr<
double>(
_U(value));
626 int n = isotope.attr<
int>(
_U(N));
627 int z = isotope.attr<
int>(
_U(Z));
628 iso =
new TGeoIsotope(nam.c_str(), z, n, a);
629 printout(s_debug.isotopes ? ALWAYS : DEBUG,
"Compact",
630 "++ Converting isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol]",
631 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
634 printout(s_debug.isotopes ? WARNING : DEBUG,
"Compact",
635 "++ Isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
636 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
654 template <>
void Converter<Atom>::operator()(
xml_h e)
const {
657 TGeoManager& mgr = description.
manager();
658 TGeoElementTable* tab = mgr.GetElementTable();
659 TGeoElement* elt = tab->FindElement(name.
c_str());
661 if ( elem.hasChild(
_U(atom)) ) {
663 std::string formula = elem.attr<std::string>(
_U(formula));
664 double value = atom.attr<
double>(
_U(value));
665 std::string unit = atom.attr<std::string>(
_U(unit));
666 int z = elem.attr<
int>(
_U(Z));
668 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
669 "++ Converting element %-16s [%-3s] Z:%3d A:%8.4f [g/mol]",
670 name.
c_str(), formula.c_str(), z, a);
671 tab->AddElement(name.
c_str(), formula.c_str(), z, a);
674 int num_isotopes = 0;
675 std::string formula = elem.hasAttr(
_U(formula)) ? elem.attr<std::string>(
_U(formula)) : name.
str();
678 elt =
new TGeoElement(name.
c_str(), formula.c_str(), num_isotopes);
679 tab->AddElement(elt);
681 double frac = i.attr<
double>(
_U(n));
682 std::string ref = i.attr<std::string>(
_U(ref));
683 TGeoIsotope* iso = tab->FindIsotope(ref.c_str());
685 except(
"Compact",
"Element %s cannot be constructed. Isotope '%s' (fraction: %.3f) missing!",
686 name.
c_str(), ref.c_str(), frac);
688 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
689 "++ Converting element %-16s Add isotope: %-16s fraction:%.4f.",
690 name.
c_str(), ref.c_str(), frac);
691 elt->AddIsotope(iso, frac);
693 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
694 "++ Converted element %-16s [%-3s] Z:%3d A:%8.4f [g/mol] with %d isotopes.",
695 name.
c_str(), formula.c_str(), elt->Z(), elt->A(), num_isotopes);
697 elt = tab->FindElement(name.
c_str());
699 throw_print(
"Failed to properly insert the Element:"+name+
" into the element table!");
703 printout(s_debug.elements ? WARNING : DEBUG,
"Compact",
704 "++ Element %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
705 elt->GetName(), elt->Z(), elt->N(), elt->A());
716 template <>
void Converter<STD_Conditions>::operator()(
xml_h e)
const {
720 if (
cond.hasAttr(
_U(type)) ) {
725 if ( temperature.
ptr() ) {
728 temp_unit = temperature.
attr<
double>(
_U(unit));
729 temp_val = temperature.
attr<
double>(
_U(value)) * temp_unit;
733 if ( pressure.
ptr() ) {
734 double pressure_unit =
_toDouble(
"pascal");
736 pressure_unit = pressure.
attr<
double>(
_U(unit));
737 pressure_val = pressure.
attr<
double>(
_U(value)) * pressure_unit;
740 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
741 "+++ Material standard conditions: Temperature: %.3f Kelvin Pressure: %.3f hPa",
750 template <>
void Converter<OpticalSurface>::operator()(
xml_h element)
const {
752 TGeoManager& mgr = description.
manager();
753 std::string sname = e.
attr<std::string>(
_U(name));
754 std::string ref, pname;
760 Double_t value = 1.0;
765 OpticalSurface surf(description, sname, model, finish, type, value);
766 if ( s_debug.surface ) {
767 printout(ALWAYS,
"Compact",
"+++ Reading optical surface %s Typ:%d model:%d finish:%d value: %.3f",
768 sname.c_str(),
int(type),
int(model),
int(finish), value);
770 for (
xml_coll_t props(e,
_U(property)); props; ++props) {
771 pname = props.attr<std::string>(
_U(name));
772 if ( props.hasAttr(
_U(ref)) ) {
774 ref = props.attr<std::string>(
_U(ref));
775 mgr.GetProperty(ref.c_str(), &err);
776 surf->AddProperty(pname.c_str(), ref.c_str());
777 if ( s_debug.surface ) {
778 printout(ALWAYS,
"Compact",
"+++ \t\t Property: %s -> %s", pname.c_str(), ref.c_str());
782 std::size_t cols = props.attr<
long>(
_U(coldim));
784 std::stringstream str(props.attr<std::string>(
_U(values))), str_nam;
786 std::vector<double> values;
787 while ( !str.eof() ) {
790 if ( val.empty() && !str.good() )
break;
794 TGDMLMatrix* table =
new TGDMLMatrix(
"",values.size()/cols, cols);
796 std::string tit = e.
attr<std::string>(opt);
797 str_nam << tit <<
"|";
799 str_nam << pname <<
"__" << (
void*)table;
800 table->SetName(str_nam.str().c_str());
801 table->SetTitle(pname.c_str());
802 for (std::size_t i=0, n=values.size(); i<n; ++i)
803 table->Set(i/cols, i%cols, values[i]);
804 surf->AddProperty(pname.c_str(), table->GetName());
805 description.
manager().AddGDMLMatrix(table);
807 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
810 for(
xml_coll_t properties(e,
_U(constant)); properties; ++properties) {
812 pname = p.
attr<std::string>(
_U(name));
815 ref = p.
attr<std::string>(
_U(ref));
816 mgr.GetProperty(ref.c_str(), &err);
817 if ( err == kFALSE ) {
818 surf->AddConstProperty(pname.c_str(), ref.c_str());
819 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
820 "++ surface %-16s add constant property: %s -> %s.",
821 surf->GetName(), pname.c_str(), ref.c_str());
825 throw_print(
"Compact2Objects[ERROR]: Converting surface: " + sname +
826 " ConstProperty missing in TGeoManager: " + ref);
829 std::stringstream str;
830 str << pname <<
"_" << (
void*)surf.ptr();
832 mgr.AddProperty(ref.c_str(), p.
attr<
double>(
_U(value)));
833 surf->AddConstProperty(pname.c_str(), ref.c_str());
834 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
835 "++ surface %-16s add constant property: %s -> %s.",
836 surf->GetName(), pname.c_str(), ref.c_str());
839 std::string ptyp = p.
attr<std::string>(
_U(option));
840 surf->AddConstProperty(pname.c_str(), ptyp.c_str());
841 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
842 "++ surface %-16s add constant property: %s -> %s.",
843 surf->GetName(), pname.c_str(), ptyp.c_str());
854 template <>
void Converter<PropertyConstant>::operator()(
xml_h e)
const {
855 double value = e.
attr<
double>(
_U(value));
856 std::string name = e.
attr<std::string>(
_U(name));
857 description.
manager().AddProperty(name.c_str(), value);
858 if ( s_debug.matrix ) {
859 printout(ALWAYS,
"Compact",
"+++ Reading property %s : %f",name.c_str(), value);
864 std::string val = e.
attr<std::string>(opt);
865 TNamed* nam = description.
manager().GetProperty(name.c_str());
867 except(
"Compact",
"Failed to access just added manager property: %s",name.c_str());
869 nam->SetTitle(val.c_str());
879 template <>
void Converter<PropertyTable>::operator()(
xml_h e)
const {
880 std::vector<double> vals;
881 std::size_t cols = e.
attr<
unsigned long>(
_U(coldim));
882 std::stringstream str(e.
attr<std::string>(
_U(values)));
884 if ( s_debug.matrix ) {
885 printout(ALWAYS,
"Compact",
"+++ Reading property table %s with %d columns.",
886 e.
attr<std::string>(
_U(name)).c_str(), cols);
889 while ( !str.eof() ) {
892 if ( item.empty() && !str.good() )
break;
894 if ( s_debug.matrix ) {
895 std::cout <<
" state:" << (str.good() ?
"OK " :
"BAD") <<
" '" << item <<
"'";
896 if ( 0 == (vals.size()%cols) ) std::cout << std::endl;
899 if ( s_debug.matrix ) {
900 std::cout << std::endl;
905 e.
attr<std::string>(
_U(name)),
906 opt ? e.
attr<std::string>(opt).c_str() :
"",
907 vals.size()/cols, cols);
908 for( std::size_t i=0, n=vals.size(); i < n; ++i )
909 tab->Set(i/cols, i%cols, vals[i]);
927 template <>
void Converter<VisAttr>::operator()(
xml_h e)
const {
933 bool use_ref =
false;
936 auto refName = e.
attr<std::string>(
_U(ref));
938 if(!refAttr.isValid() ) {
939 except(
"Compact",
"+++ Reference VisAttr %s does not exist", refName.c_str());
943 refAttr.argb(alpha,red,green,blue);
944 attr.setColor(alpha,red,green,blue);
945 attr.setDrawingStyle( refAttr.drawingStyle());
946 attr.setLineStyle( refAttr.lineStyle());
947 attr.setShowDaughters(refAttr.showDaughters());
948 attr.setVisible(refAttr.visible());
951 alpha = dim.alpha(alpha);
953 green = dim.g(green);
956 printout(s_debug.visattr ? ALWAYS : DEBUG,
"Compact",
957 "++ Converting VisAttr structure: %-16s. Alpha=%.2f R=%.3f G=%.3f B=%.3f",
958 attr.name(), alpha, red, green, blue);
959 attr.setColor(alpha, red, green, blue);
961 attr.setVisible(e.
attr<
bool>(
_U(visible)));
963 std::string ls = e.
attr<std::string>(
_U(lineStyle));
964 if (ls ==
"unbroken")
966 else if (ls ==
"broken")
974 std::string ds = e.
attr<std::string>(
_U(drawingStyle));
975 if (ds ==
"wireframe")
977 else if (ds ==
"solid")
985 attr.setShowDaughters(e.
attr<
bool>(
_U(showDaughters)));
988 attr.setShowDaughters(
true);
996 template <>
void Converter<Region>::operator()(
xml_h elt)
const {
998 Region region(e.nameStr());
999 auto& limits = region.limits();
1003 double ene = e.eunit(1.0), len = e.lunit(1.0);
1005 printout(s_debug.regions ? ALWAYS : DEBUG,
"Compact",
1006 "++ Converting region structure: %s.",region.name());
1008 region.setCut(elt.
attr<
double>(cut)*len);
1011 region.setThreshold(elt.
attr<
double>(threshold)*ene);
1013 if ( store_secondaries ) {
1014 region.setStoreSecondaries(elt.
attr<
bool>(store_secondaries));
1016 for (
xml_coll_t user_limits(e,
_U(limitsetref)); user_limits; ++user_limits)
1017 limits.emplace_back(user_limits.attr<std::string>(
_U(name)));
1029 template <>
void Converter<Segmentation>::operator()(
xml_h seg)
const {
1030 std::string type = seg.
attr<std::string>(
_U(type));
1031 std::string name = seg.
hasAttr(
_U(name)) ? seg.
attr<std::string>(
_U(name)) : std::string();
1032 std::pair<Segmentation,IDDescriptor>* opt = _option<std::pair<Segmentation,IDDescriptor> >();
1036 if ( segment.isValid() ) {
1038 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1039 "++ Converting segmentation structure: %s of type %s.",name.c_str(),type.c_str());
1040 for(
const auto p : pars ) {
1043 std::string pType = p->type();
1044 if ( pType.compare(
"int") == 0 ) {
1046 static_cast<ParInt*
>(p)->setTypedValue(seg.
attr<
int>(pNam));
1047 }
else if ( pType.compare(
"float") == 0 ) {
1049 static_cast<ParFloat*
>(p)->setTypedValue(seg.
attr<
float>(pNam));
1050 }
else if ( pType.compare(
"doublevec") == 0 ) {
1051 std::vector<double> valueVector;
1052 std::string par = seg.
attr<std::string>(pNam);
1053 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1054 "++ Converting this std::string structure: %s.",par.c_str());
1056 for (
const std::string& spar : elts ) {
1057 if ( spar.empty() )
continue;
1058 valueVector.emplace_back(
_toDouble(spar));
1061 static_cast<ParDouVec*
>(p)->setTypedValue(valueVector);
1062 }
else if ( pType.compare(
"double" ) == 0) {
1064 static_cast<ParDouble*
>(p)->setTypedValue(seg.
attr<
double>(pNam));
1068 }
else if (not p->isOptional()) {
1069 throw_print(
"FAILED to create segmentation: " + type +
1070 ". Missing mandatory parameter: " + p->name() +
"!");
1073 long key_min = 0, key_max = 0;
1075 for(
xml_coll_t sub(seg,
_U(segmentation)); sub; ++sub) {
1076 std::pair<Segmentation,IDDescriptor> sub_object(
Segmentation(),opt->second);
1077 Converter<Segmentation> sub_conv(description,param,&sub_object);
1079 if ( sub_object.first.isValid() ) {
1082 if ( sub.hasAttr(
_U(key_value)) ) {
1083 key_min = key_max = x_seg.key_value();
1085 else if ( sub.hasAttr(
_U(key_min)) && sub.hasAttr(
_U(key_max)) ) {
1086 key_min = x_seg.key_min();
1087 key_max = x_seg.key_max();
1090 std::stringstream tree;
1092 throw_print(
"Nested segmentations: Invalid key specification:"+tree.str());
1094 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1095 "++ Segmentation [%s/%s]: Add sub-segmentation %s [%s]",
1096 name.c_str(), type.c_str(),
1101 delete sub_seg.
ptr();
1105 opt->first = segment;
1115 template <>
void Converter<Readout>::operator()(
xml_h e)
const {
1118 std::string name = e.
attr<std::string>(
_U(name));
1119 std::pair<Segmentation,IDDescriptor> opt;
1128 Converter<Segmentation>(description,param,&opt)(seg);
1129 opt.first->setName(name);
1134 if ( opt.first.isValid() ) {
1135 ro.setSegmentation(opt.first);
1137 if ( opt.second.isValid() ) {
1138 ro.setIDDescriptor(opt.second);
1141 printout(s_debug.readout ? ALWAYS : DEBUG,
1142 "Compact",
"++ Converting readout structure: %-16s. %s%s",
1143 ro.name(),
id ?
"ID: " :
"",
id ?
id.text().c_str() :
"");
1145 for(
xml_coll_t colls(e,
_U(hits_collections)); colls; ++colls) {
1146 std::string hits_key;
1147 if ( colls.hasAttr(
_U(
key)) ) hits_key = colls.attr<std::string>(
_U(
key));
1148 for(
xml_coll_t coll(colls,
_U(hits_collection)); coll; ++coll) {
1150 std::string coll_name = c.nameStr();
1151 std::string coll_key = hits_key;
1152 long key_min = 0, key_max = 0;
1154 if ( c.hasAttr(
_U(
key)) ) {
1155 coll_key = c.attr<std::string>(
_U(
key));
1157 if ( c.hasAttr(
_U(key_value)) ) {
1158 key_max = key_min = c.key_value();
1160 else if ( c.hasAttr(
_U(key_min)) && c.hasAttr(
_U(key_max)) ) {
1161 key_min = c.key_min();
1162 key_max = c.key_max();
1165 std::stringstream tree;
1167 throw_print(
"Readout: Invalid specification for multiple hit collections."+tree.str());
1169 printout(s_debug.readout ? ALWAYS : DEBUG,
"Compact",
1170 "++ Readout[%s]: Add hit collection %s [%s] %d-%d",
1171 ro.name(), coll_name.c_str(), coll_key.c_str(), key_min, key_max);
1173 ro->hits.emplace_back(hits);
1179 static long load_readout(
Detector& description,
xml_h element) {
1180 Converter<Readout> converter(description);
1193 template <>
void Converter<LimitSet>::operator()(
xml_h e)
const {
1196 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1197 "++ Converting LimitSet structure: %s.",ls.name());
1199 limit.
name = c.attr<std::string>(
_U(name));
1200 limit.
particles = c.attr<std::string>(
_U(particles));
1201 limit.
content = c.attr<std::string>(
_U(value));
1202 limit.
unit = c.attr<std::string>(
_U(unit));
1205 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1206 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1212 limit.
particles = c.attr<std::string>(
_U(particles));
1213 limit.
content = c.attr<std::string>(
_U(value));
1214 limit.
unit = c.attr<std::string>(
_U(unit));
1217 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1218 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1231 template <>
void Converter<Property>::operator()(
xml_h e)
const {
1232 std::string name = e.
attr<std::string>(
_U(name));
1235 throw_print(
"Failed to convert properties. No name given!");
1238 if ( prp.find(name) == prp.end() )
1253 template <>
void Converter<CartesianField>::operator()(
xml_h e)
const {
1254 std::string msg =
"updated";
1255 std::string name = e.
attr<std::string>(
_U(name));
1256 std::string type = e.
attr<std::string>(
_U(type));
1258 if ( !field.isValid() ) {
1260 field =
Ref_t(PluginService::Create<NamedObject*>(type, &description, &e));
1261 if ( !field.isValid() ) {
1263 PluginService::Create<NamedObject*>(type, &description, &e);
1264 throw_print(
"Failed to create field object of type "+type +
". "+dbg.
missingFactory(type));
1269 type = field.type();
1273 std::string props_name = c.attr<std::string>(
_U(name));
1274 std::vector<xml_attr_t>a = c.attributes();
1275 if ( prp.find(props_name) == prp.end() ) {
1279 prp[props_name].emplace(
xml_tag_t(c.attr_name(i)).
str(), c.attr<std::string>(i));
1281 if (c.hasAttr(
_U(global)) && c.attr<
bool>(
_U(global))) {
1285 printout(INFO,
"Compact",
"++ Converted field: Successfully %s field %s [%s]", msg.c_str(), name.c_str(), type.c_str());
1301 template <>
void Converter<SensitiveDetector>::operator()(
xml_h element)
const {
1302 std::string name = element.
attr<std::string>(
_U(name));
1319 std::string l = element.
attr<std::string>(limits);
1321 if (!ls.isValid()) {
1322 throw_print(
"Converter<SensitiveDetector>: Request for non-existing limitset:" + l);
1328 std::string r = element.
attr<std::string>(region);
1330 if (!reg.isValid()) {
1331 throw_print(
"Converter<SensitiveDetector>: Request for non-existing region:" + r);
1341 if (ecut && eunit) {
1348 printout(DEBUG,
"Compact",
"SensitiveDetector-update: %-18s %-24s Hits:%-24s Cutoff:%7.3f", sd.
name(),
1355 printout(ERROR,
"Compact",
"++ FAILED to convert sensitive detector: %s: %s", name.c_str(), e.what());
1358 printout(ERROR,
"Compact",
"++ FAILED to convert sensitive detector: %s: %s", name.c_str(),
"UNKNONW Exception");
1362 static void setChildTitles(
const std::pair<std::string, DetElement>& e) {
1365 if (::strlen(e.second->GetTitle()) == 0) {
1366 e.second->SetTitle(parent.
isValid() ? parent.
type().c_str() : e.first.c_str());
1368 for_each(children.begin(), children.end(), setChildTitles);
1371 template <>
void Converter<DetElement>::operator()(
xml_h element)
const {
1372 static const char* req_dets = ::getenv(
"REQUIRED_DETECTORS");
1373 static const char* req_typs = ::getenv(
"REQUIRED_DETECTOR_TYPES");
1374 static const char* ign_dets = ::getenv(
"IGNORED_DETECTORS");
1375 static const char* ign_typs = ::getenv(
"IGNORED_DETECTOR_TYPES");
1376 std::string type = element.
attr<std::string>(
_U(type));
1377 std::string name = element.
attr<std::string>(
_U(name));
1378 std::string name_match =
":" + name +
":";
1379 std::string type_match =
":" + type +
":";
1381 if (req_dets && !strstr(req_dets, name_match.c_str()))
1383 if (req_typs && !strstr(req_typs, type_match.c_str()))
1385 if (ign_dets && strstr(ign_dets, name_match.c_str()))
1387 if (ign_typs && strstr(ign_typs, type_match.c_str()))
1390 if ( attr_ignore ) {
1391 bool ignore_det = element.
attr<
bool>(
_U(ignore));
1393 printout(INFO,
"Compact",
1394 "+++ Do not build subdetector:%s [ignore flag set]",
1400 std::string par_name;
1404 par_name = element.
attr<std::string>(attr_par);
1405 else if ( (elt_par=element.
child(
_U(parent),
false)) )
1406 par_name = elt_par.attr<std::string>(
_U(name));
1407 if ( !par_name.empty() ) {
1414 except(
"Compact",
"Failed to access valid parent detector of %s",name.c_str());
1418 if( s_debug.detelements ) {
1419 printout(ALWAYS,
"Compact",
"++ Building DetElement %s of type: %s. Parent: %s",
1420 name.c_str(), type.c_str(), par_name.c_str());
1429 except(
"Compact",
"No Readout structure present for detector:" + name);
1438 DetElement det(
Ref_t(PluginService::Create<NamedObject*>(type, &description, &element, &sens)));
1439 if (
det.isValid()) {
1440 setChildTitles(std::make_pair(name,
det));
1449 printout(
det.isValid() ? INFO : ERROR,
"Compact",
"%s subdetector:%s of type %s %s",
1450 (
det.isValid() ?
"++ Converted" :
"FAILED "), name.c_str(), type.c_str(),
1451 (sd.
isValid() ? (
"[" + sd.
type() +
"]").c_str() :
""));
1453 if (!
det.isValid()) {
1455 PluginService::Create<NamedObject*>(type, &description, &element, &sens);
1456 except(
"Compact",
"Failed to execute subdetector creation plugin. %s", dbg.
missingFactory(type).c_str());
1463 printout(ERROR,
"Compact",
"++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
1467 printout(ERROR,
"Compact",
"++ FAILED to convert subdetector: %s: %s", name.c_str(),
"UNKNONW Exception");
1473 template <>
void Converter<IncludeFile>::operator()(
xml_h element)
const {
1475 if ( s_debug.include_guard) {
1480 xml_h root = doc.root();
1481 if ( s_debug.includes ) {
1482 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
1484 if ( root.
tag() ==
"materials" || root.
tag() ==
"elements" ) {
1490 this->description.
fromXML(doc.uri(), this->description.buildType());
1494 template <>
void Converter<JsonFile>::operator()(
xml_h element)
const {
1496 std::string file = element.
attr<std::string>(
_U(ref));
1497 std::vector<char*> argv{&file[0], &base[0]};
1498 description.
apply(
"DD4hep_JsonProcessor",
int(argv.size()), &argv[0]);
1502 template <>
void Converter<XMLFile>::operator()(
xml_h element)
const {
1503 PrintLevel level = s_debug.includes ? ALWAYS : DEBUG;
1504 std::string fname = element.
attr<std::string>(
_U(ref));
1505 std::size_t idx = fname.find(
"://");
1508 if ( idx == std::string::npos && std::filesystem::exists(fname, ec) ) {
1510 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1513 else if ( idx == std::string::npos ) {
1516 printout(level,
"Compact",
"++ Processing xml document %s.", location.c_str());
1519 else if ( idx > 0 ) {
1521 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1526 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1532 template <>
void Converter<World>::operator()(
xml_h element)
const {
1536 Material mat = att ? description.
material(x_world.attr<std::string>(att)) : description.
air();
1541 Solid sol(x_shape.createShape());
1542 world_vol =
Volume(
"world_volume", sol, mat);
1543 printout(INFO,
"Compact",
"++ Created successfully world volume '%s'. shape: %s material:%s.",
1544 world_vol.
name(), sol.type(), mat.
name());
1545 description.
manager().SetTopVolume(world_vol.
ptr());
1549 if ( !world_vol && att ) {
1552 Box sol(
"world_x",
"world_y",
"world_z");
1553 world_vol =
Volume(
"world_volume", sol, mat);
1554 printout(INFO,
"Compact",
"++ Created world volume '%s' as %s (%.2f, %.2f %.2f [cm]) material:%s.",
1555 world_vol.
name(), sol.type(),
1556 sol.x()/dd4hep::cm, sol.y()/dd4hep::cm, sol.z()/dd4hep::cm,
1558 description.
manager().SetTopVolume(world_vol.
ptr());
1560 else if ( !world_vol ) {
1561 except(
"Compact",
"++ Logical error: "
1562 "You cannot configure the world volume before it is created and not giving creation instructions.");
1569 if ( !vis.isValid() ) {
1577 template <>
void Converter<Parallelworld_Volume>::operator()(
xml_h element)
const {
1582 std::string name = element.
attr<std::string>(
_U(name));
1583 std::string path = element.
attr<std::string>(
_U(anchor));
1584 bool conn = element.
attr<
bool>(
_U(connected),
false);
1589 Material mat = parallel.hasAttr(
_U(material))
1590 ? description.
material(parallel.attr<std::string>(
_U(material)))
1591 : description.
air();
1596 if ( !anchor.isValid() ) {
1597 except(
"Parallelworld_Volume",
1598 "++ FAILED Cannot identify the anchor of the tracking volume: '%s'",
1604 Solid sol(shape.createShape());
1605 Volume vol(name, sol, mat);
1610 vol.setVisAttributes(vis);
1618 except(
"Parallelworld_Volume",
1619 "++ FAILED to place the tracking volume inside the anchor '%s'",path.c_str());
1621 if ( name ==
"tracking_volume" ) {
1624 printout(INFO,
"Compact",
"++ Converted successfully parallelworld_volume %s. anchor: %s vis:%s.",
1625 vol.name(), anchor.path().c_str(), vis.
name());
1629 template <>
void Converter<DetElementInclude>::operator()(
xml_h element)
const {
1630 std::string type = element.
hasAttr(
_U(type)) ? element.
attr<std::string>(
_U(type)) : std::string(
"xml");
1631 if ( type ==
"xml" ) {
1633 if ( s_debug.include_guard ) {
1638 if ( s_debug.includes ) {
1639 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
1641 xml_h node = doc.root();
1642 std::string tag = node.
tag();
1643 if ( tag ==
"lccdd" )
1644 Converter<Compact>(this->description)(node);
1645 else if ( tag ==
"define" )
1647 else if ( tag ==
"readout" )
1648 Converter<Readout>(this->description)(node);
1649 else if ( tag ==
"readouts" )
1651 else if ( tag ==
"region" )
1652 Converter<Region>(this->description)(node);
1653 else if ( tag ==
"regions" )
1655 else if ( tag ==
"limits" || tag ==
"limitsets" )
1657 else if ( tag ==
"display" )
1659 else if ( tag ==
"detector" )
1660 Converter<DetElement>(this->description)(node);
1661 else if ( tag ==
"detectors" )
1664 else if ( type ==
"json" ) {
1665 Converter<JsonFile>(this->description)(element);
1667 else if ( type ==
"gdml" ) {
1668 Converter<IncludeFile>(this->description)(element);
1670 else if ( type ==
"include" ) {
1671 Converter<IncludeFile>(this->description)(element);
1673 else if ( type ==
"xml-extended" ) {
1674 Converter<XMLFile>(this->description)(element);
1677 except(
"Compact",
"++ FAILED Invalid file type:%s. This cannot be processed!",type.c_str());
1682 template <>
void Converter<Compact>::operator()(
xml_h element)
const {
1683 static int num_calls = 0;
1688 bool steer_geometry = compact.hasChild(
_U(geometry));
1689 bool open_geometry =
true;
1690 bool close_document =
true;
1691 bool close_geometry =
true;
1692 bool build_reflections =
false;
1697 (Converter<Debug>(description))(
xml_h(compact.child(
_U(
debug))));
1699 if ( steer_geometry ) {
1702 open_geometry = steer.
attr<
bool>(
_U(open));
1704 close_document = steer.
attr<
bool>(
_U(close));
1706 build_reflections = steer.
attr<
bool>(
_U(reflect));
1708 std::string nam = clr.hasAttr(
_U(name)) ? clr.attr<std::string>(
_U(name)) : std::string();
1709 if ( nam.substr(0,6) ==
"elemen" ) {
1710 TGeoElementTable* table = description.
manager().GetElementTable();
1711 table->TGeoElementTable::~TGeoElementTable();
1712 new(table) TGeoElementTable();
1714 table->AddElement(
"VACUUM",
"VACUUM" ,0, 0, 0.0);
1715 printout(INFO,
"Compact",
1716 "++ Cleared default ROOT TGeoElementTable contents. "
1717 "Must now be filled from XML!");
1722 if ( s_debug.materials || s_debug.elements ) {
1723 printout(INFO,
"Compact",
"+++ UNIT System:");
1724 printout(INFO,
"Compact",
"+++ Density: %8.3g Units:%8.3g",
1728 printout(INFO,
"Compact",
"+++ nanosecond: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(nanosecond)),dd4hep::nanosecond);
1729 printout(INFO,
"Compact",
"+++ kilo: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(kilogram)),dd4hep::kilogram);
1731 dd4hep::joule*dd4hep::s*dd4hep::s/(dd4hep::meter*dd4hep::meter));
1733 printout(INFO,
"Compact",
"+++ ampere: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(ampere)),dd4hep::ampere);
1734 printout(INFO,
"Compact",
"+++ degree: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(degree)),dd4hep::degree);
1744 (Converter<Header>(description))(
xml_h(compact.child(
_U(
info))));
1757 printout(DEBUG,
"Compact",
"++ Converting visualization attributes...");
1761 printout(DEBUG,
"Compact",
"++ Converting limitset structures...");
1765 printout(DEBUG,
"Compact",
"++ Converting region structures...");
1770 (Converter<World>(description))(world);
1772 if ( open_geometry ) description.
init();
1773 printout(DEBUG,
"Compact",
"++ Converting readout structures...");
1777 printout(DEBUG,
"Compact",
"++ Converting included files with subdetector structures...");
1779 printout(DEBUG,
"Compact",
"++ Converting detector structures...");
1785 xml_coll_t(compact,
_U(sensitive_detectors)).
for_each(
_U(sd), Converter<SensitiveDetector>(description));
1786 xml_coll_t(compact,
_U(parallelworld_volume)).
for_each(Converter<Parallelworld_Volume>(description));
1788 if ( --num_calls == 0 && close_document ) {
1789 ::snprintf(text,
sizeof(text),
"%u",
xml_h(element).checksum(0));
1793 if ( build_reflections ) {
1804 template Converter<Plugin>;
1805 template Converter<Constant>;
1806 template Converter<Material>;
1807 template Converter<Atom>;
1808 template Converter<VisAttr>;
1809 template Converter<Region>;
1810 template Converter<Readout>;
1811 template Converter<Segmentation>;
1812 template Converter<LimitSet>;
1813 template Converter<Property>;
1814 template Converter<CartesianField>;
1815 template Converter<SensitiveDetector>;
1816 template Converter<DetElement>;
1817 template Converter<GdmlFile>;
1818 template Converter<XMLFile>;
1819 template Converter<Header>;
1820 template Converter<DetElementInclude>;
1821 template Converter<Compact>;