42 #include <TGeoManager.h>
43 #include <TGeoMaterial.h>
44 #include <TGeoPhysicalConstants.h>
45 #include <TGDMLMatrix.h>
70 class PropertyConstant;
71 class Parallelworld_Volume;
72 class DetElementInclude;
76 template <>
void Converter<Debug>::operator()(
xml_h element)
const;
77 template <>
void Converter<World>::operator()(
xml_h element)
const;
78 template <>
void Converter<Plugin>::operator()(
xml_h element)
const;
79 template <>
void Converter<Constant>::operator()(
xml_h element)
const;
80 template <>
void Converter<Material>::operator()(
xml_h element)
const;
81 template <>
void Converter<Atom>::operator()(
xml_h element)
const;
82 template <>
void Converter<Isotope>::operator()(
xml_h element)
const;
83 template <>
void Converter<VisAttr>::operator()(
xml_h element)
const;
84 template <>
void Converter<Region>::operator()(
xml_h element)
const;
85 template <>
void Converter<Readout>::operator()(
xml_h element)
const;
86 template <>
void Converter<Segmentation>::operator()(
xml_h element)
const;
87 template <>
void Converter<LimitSet>::operator()(
xml_h element)
const;
88 template <>
void Converter<Property>::operator()(
xml_h element)
const;
89 template <>
void Converter<CartesianField>::operator()(
xml_h element)
const;
90 template <>
void Converter<SensitiveDetector>::operator()(
xml_h element)
const;
91 template <>
void Converter<OpticalSurface>::operator()(
xml_h element)
const;
92 template <>
void Converter<PropertyTable>::operator()(
xml_h element)
const;
93 template <>
void Converter<PropertyConstant>::operator()(
xml_h element)
const;
94 template <>
void Converter<DetElement>::operator()(
xml_h element)
const;
95 template <>
void Converter<STD_Conditions>::operator()(
xml_h element)
const;
96 template <>
void Converter<IncludeFile>::operator()(
xml_h element)
const;
97 template <>
void Converter<JsonFile>::operator()(
xml_h element)
const;
98 template <>
void Converter<XMLFile>::operator()(
xml_h element)
const;
99 template <>
void Converter<Header>::operator()(
xml_h element)
const;
100 template <>
void Converter<DetElementInclude>::operator()(
xml_h element)
const;
101 template <>
void Converter<Parallelworld_Volume>::operator()(
xml_h element)
const;
102 template <>
void Converter<Compact>::operator()(
xml_h element)
const;
106 static UInt_t unique_mat_id = 0xAFFEFEED;
107 void throw_print(
const std::string& msg) {
108 printout(ERROR,
"Compact", msg.c_str());
109 throw std::runtime_error(msg);
113 bool readout =
false;
114 bool regions =
false;
116 bool visattr =
false;
117 bool isotopes =
false;
118 bool elements =
false;
119 bool materials =
false;
120 bool segmentation =
false;
121 bool constants =
false;
122 bool includes =
false;
124 bool surface =
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);
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[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 {
396 h.setUrl(e.
attr<std::string>(
_U(url),
"Undefined"));
397 h.setAuthor(e.
attr<std::string>(
_U(author),
"Undefined"));
398 h.setStatus(e.
attr<std::string>(
_U(status),
"development"));
399 h.setVersion(e.
attr<std::string>(
_U(version),
"Undefined"));
400 h.setComment(e.
hasChild(
_U(comment)) ? e.
child(
_U(comment)).text() :
"No Comment");
420 template <>
void Converter<Material>::operator()(
xml_h e)
const {
422 TGeoManager& mgr = description.
manager();
424 const char* matname = mname.
c_str();
425 TGeoElementTable* table = mgr.GetElementTable();
426 TGeoMaterial* mat = mgr.GetMaterial(matname);
427 TGeoMixture*
mix =
dynamic_cast<TGeoMixture*
>(mat);
432 TGeoMaterial* comp_mat;
433 TGeoElement* comp_elt;
435 double dens_val = density.
ptr() ? density.
attr<
double>(
_U(value)) : 0.0;
436 double dens_unit = 1.0;
438 if ( !density.
ptr() ) {
439 throw_print(
"Compact2Objects[ERROR]: material without density tag ( <D unit=\"g/cm3\" value=\"..\"/> ) provided: "
440 + std::string( matname ) ) ;
445 if ( dens_unit != 1.0 ) {
446 dens_val *= dens_unit;
447 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
"Density unit: %.3f [%s] raw: %.3f normalized: %.3f ",
448 dens_unit, density.
attr<std::string>(
_U(unit)).c_str(), dens_val, (dens_val*dens_unit));
450 mat =
mix =
new TGeoMixture(matname, composites.size(), dens_val);
451 std::size_t ifrac = 0;
452 std::vector<double> composite_fractions;
453 double composite_fractions_total = 0.0;
454 for (composites.reset(); composites; ++composites) {
455 std::string nam = composites.attr<std::string>(
_U(ref));
456 double fraction = composites.attr<
double>(
_U(n));
457 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
458 fraction *= comp_mat->GetA();
459 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
460 fraction *= comp_elt->A();
462 except(
"Compact2Objects",
"Converting material: %s Element missing: %s",mname.
c_str(),nam.c_str());
463 composite_fractions_total += fraction;
464 composite_fractions.emplace_back(fraction);
466 for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) {
467 std::string nam = composites.attr<std::string>(
_U(ref));
468 double fraction = composite_fractions[ifrac]/composite_fractions_total;
469 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
470 mix->AddElement(comp_mat, fraction);
471 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
472 mix->AddElement(comp_elt, fraction);
474 for (fractions.reset(); fractions; ++fractions) {
475 std::string nam = fractions.attr<std::string>(
_U(ref));
476 double fraction = fractions.attr<
double>(
_U(n));
477 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
478 mix->AddElement(comp_mat, fraction);
479 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
480 mix->AddElement(comp_elt, fraction);
482 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" Element missing: " + nam);
486 if ( temperature.
ptr() ) {
489 temp_unit = temperature.
attr<
double>(
_U(unit));
490 temp_val = temperature.
attr<
double>(
_U(value)) * temp_unit;
494 if ( pressure.
ptr() ) {
495 double pressure_unit =
_toDouble(
"pascal");
497 pressure_unit = pressure.
attr<
double>(
_U(unit));
498 pressure_val = pressure.
attr<
double>(
_U(value)) * pressure_unit;
501 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
502 "++ ROOT raw temperature and pressure: %.3g %.3g",
503 mat->GetTemperature(),mat->GetPressure());
505 mat->SetTemperature(temp_val);
506 mat->SetPressure(pressure_val);
507 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
508 "++ Converting material %-16s Density: %9.7g Temperature:%9.7g [K] Pressure:%9.7g [hPa].",
509 matname, dens_val, temp_val/dd4hep::kelvin, pressure_val/dd4hep::pascal/100.0);
512 mix->ComputeDerivedQuantities();
515 for(
xml_coll_t properties(x_mat,
_U(constant)); properties; ++properties) {
519 std::string ref = p.
attr<std::string>(
_U(ref));
520 mgr.GetProperty(ref.c_str(), &err);
521 if ( err == kFALSE ) {
522 std::string prop_nam = p.
attr<std::string>(
_U(name));
523 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
524 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
525 "++ material %-16s add constant property: %s -> %s.",
526 mat->GetName(), prop_nam.c_str(), ref.c_str());
530 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" ConstProperty missing in TGeoManager: " + ref);
533 std::stringstream str;
534 std::string ref, prop_nam = p.
attr<std::string>(
_U(name));
535 str << prop_nam <<
"_" << (
void*)mat;
537 mgr.AddProperty(ref.c_str(), p.
attr<
double>(
_U(value)));
538 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
539 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
540 "++ material %-16s add constant property: %s -> %s.",
541 mat->GetName(), prop_nam.c_str(), ref.c_str());
544 std::string prop_nam = p.
attr<std::string>(
_U(name));
545 std::string prop_typ = p.
attr<std::string>(
_U(option));
546 mat->AddConstProperty(prop_nam.c_str(), prop_typ.c_str());
547 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
548 "++ material %-16s add constant property: %s -> %s.",
549 mat->GetName(), prop_nam.c_str(), prop_typ.c_str());
553 for(
xml_coll_t properties(x_mat,
_U(property)); properties; ++properties) {
556 std::string ref = p.
attr<std::string>(
_U(ref));
557 TGDMLMatrix* gdmlMat = mgr.GetGDMLMatrix(ref.c_str());
559 std::string prop_nam = p.
attr<std::string>(
_U(name));
560 mat->AddProperty(prop_nam.c_str(), ref.c_str());
561 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
562 "++ material %-16s add property: %s -> %s.",
563 mat->GetName(), prop_nam.c_str(), ref.c_str());
567 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" Property missing: " + ref);
571 TGeoMedium* medium = mgr.GetMedium(matname);
574 medium =
new TGeoMedium(matname, unique_mat_id, mat);
575 medium->SetTitle(
"material");
576 medium->SetUniqueID(unique_mat_id);
580 if (x_mat.hasAttr(
_U(formula))) {
581 std::string form = x_mat.attr<std::string>(
_U(formula));
582 if (form != matname) {
583 medium = mgr.GetMedium(form.c_str());
586 medium =
new TGeoMedium(form.c_str(), unique_mat_id, mat);
587 medium->SetTitle(
"material");
588 medium->SetUniqueID(unique_mat_id);
600 template <>
void Converter<Isotope>::operator()(
xml_h e)
const {
602 TGeoManager& mgr = description.
manager();
603 std::string nam = isotope.nameStr();
604 TGeoElementTable* tab = mgr.GetElementTable();
605 TGeoIsotope* iso = tab->FindIsotope(nam.c_str());
610 std::string unit = atom.attr<std::string>(
_U(unit));
611 double value = atom.attr<
double>(
_U(value));
613 int n = isotope.attr<
int>(
_U(N));
614 int z = isotope.attr<
int>(
_U(Z));
615 iso =
new TGeoIsotope(nam.c_str(), z, n, a);
616 printout(s_debug.isotopes ? ALWAYS : DEBUG,
"Compact",
617 "++ Converting isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol]",
618 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
621 printout(s_debug.isotopes ? WARNING : DEBUG,
"Compact",
622 "++ Isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
623 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
641 template <>
void Converter<Atom>::operator()(
xml_h e)
const {
644 TGeoManager& mgr = description.
manager();
645 TGeoElementTable* tab = mgr.GetElementTable();
646 TGeoElement* elt = tab->FindElement(name.
c_str());
648 if ( elem.hasChild(
_U(atom)) ) {
650 std::string formula = elem.attr<std::string>(
_U(formula));
651 double value = atom.attr<
double>(
_U(value));
652 std::string unit = atom.attr<std::string>(
_U(unit));
653 int z = elem.attr<
int>(
_U(Z));
655 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
656 "++ Converting element %-16s [%-3s] Z:%3d A:%8.4f [g/mol]",
657 name.
c_str(), formula.c_str(), z, a);
658 tab->AddElement(name.
c_str(), formula.c_str(), z, a);
661 int num_isotopes = 0;
662 std::string formula = elem.hasAttr(
_U(formula)) ? elem.attr<std::string>(
_U(formula)) : name.
str();
665 elt =
new TGeoElement(name.
c_str(), formula.c_str(), num_isotopes);
666 tab->AddElement(elt);
668 double frac = i.attr<
double>(
_U(n));
669 std::string ref = i.attr<std::string>(
_U(ref));
670 TGeoIsotope* iso = tab->FindIsotope(ref.c_str());
672 except(
"Compact",
"Element %s cannot be constructed. Isotope '%s' (fraction: %.3f) missing!",
673 name.
c_str(), ref.c_str(), frac);
675 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
676 "++ Converting element %-16s Add isotope: %-16s fraction:%.4f.",
677 name.
c_str(), ref.c_str(), frac);
678 elt->AddIsotope(iso, frac);
680 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
681 "++ Converted element %-16s [%-3s] Z:%3d A:%8.4f [g/mol] with %d isotopes.",
682 name.
c_str(), formula.c_str(), elt->Z(), elt->A(), num_isotopes);
684 elt = tab->FindElement(name.
c_str());
686 throw_print(
"Failed to properly insert the Element:"+name+
" into the element table!");
690 printout(s_debug.elements ? WARNING : DEBUG,
"Compact",
691 "++ Element %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
692 elt->GetName(), elt->Z(), elt->N(), elt->A());
703 template <>
void Converter<STD_Conditions>::operator()(
xml_h e)
const {
707 if (
cond.hasAttr(
_U(type)) ) {
712 if ( temperature.
ptr() ) {
715 temp_unit = temperature.
attr<
double>(
_U(unit));
716 temp_val = temperature.
attr<
double>(
_U(value)) * temp_unit;
720 if ( pressure.
ptr() ) {
721 double pressure_unit =
_toDouble(
"pascal");
723 pressure_unit = pressure.
attr<
double>(
_U(unit));
724 pressure_val = pressure.
attr<
double>(
_U(value)) * pressure_unit;
727 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
728 "+++ Material standard conditions: Temperature: %.3f Kelvin Pressure: %.3f hPa",
737 template <>
void Converter<OpticalSurface>::operator()(
xml_h element)
const {
739 TGeoManager& mgr = description.
manager();
740 std::string sname = e.
attr<std::string>(
_U(name));
741 std::string ref, pname;
747 Double_t value = 1.0;
752 OpticalSurface surf(description, sname, model, finish, type, value);
753 if ( s_debug.surface ) {
754 printout(ALWAYS,
"Compact",
"+++ Reading optical surface %s Typ:%d model:%d finish:%d value: %.3f",
755 sname.c_str(),
int(type),
int(model),
int(finish), value);
757 for (
xml_coll_t props(e,
_U(property)); props; ++props) {
758 pname = props.attr<std::string>(
_U(name));
759 if ( props.hasAttr(
_U(ref)) ) {
761 ref = props.attr<std::string>(
_U(ref));
762 mgr.GetProperty(ref.c_str(), &err);
763 surf->AddProperty(pname.c_str(), ref.c_str());
764 if ( s_debug.surface ) {
765 printout(ALWAYS,
"Compact",
"+++ \t\t Property: %s -> %s", pname.c_str(), ref.c_str());
769 std::size_t cols = props.attr<
long>(
_U(coldim));
771 std::stringstream str(props.attr<std::string>(
_U(values))), str_nam;
773 std::vector<double> values;
774 while ( !str.eof() ) {
777 if ( val.empty() && !str.good() )
break;
781 TGDMLMatrix* table =
new TGDMLMatrix(
"",values.size()/cols, cols);
783 std::string tit = e.
attr<std::string>(opt);
784 str_nam << tit <<
"|";
786 str_nam << pname <<
"__" << (
void*)table;
787 table->SetName(str_nam.str().c_str());
788 table->SetTitle(pname.c_str());
789 for (std::size_t i=0, n=values.size(); i<n; ++i)
790 table->Set(i/cols, i%cols, values[i]);
791 surf->AddProperty(pname.c_str(), table->GetName());
792 description.
manager().AddGDMLMatrix(table);
794 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
797 for(
xml_coll_t properties(e,
_U(constant)); properties; ++properties) {
799 pname = p.
attr<std::string>(
_U(name));
802 ref = p.
attr<std::string>(
_U(ref));
803 mgr.GetProperty(ref.c_str(), &err);
804 if ( err == kFALSE ) {
805 surf->AddConstProperty(pname.c_str(), ref.c_str());
806 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
807 "++ surface %-16s add constant property: %s -> %s.",
808 surf->GetName(), pname.c_str(), ref.c_str());
812 throw_print(
"Compact2Objects[ERROR]: Converting surface: " + sname +
813 " ConstProperty missing in TGeoManager: " + ref);
816 std::stringstream str;
817 str << pname <<
"_" << (
void*)surf.ptr();
819 mgr.AddProperty(ref.c_str(), p.
attr<
double>(
_U(value)));
820 surf->AddConstProperty(pname.c_str(), ref.c_str());
821 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
822 "++ surface %-16s add constant property: %s -> %s.",
823 surf->GetName(), pname.c_str(), ref.c_str());
826 std::string ptyp = p.
attr<std::string>(
_U(option));
827 surf->AddConstProperty(pname.c_str(), ptyp.c_str());
828 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
829 "++ surface %-16s add constant property: %s -> %s.",
830 surf->GetName(), pname.c_str(), ptyp.c_str());
841 template <>
void Converter<PropertyConstant>::operator()(
xml_h e)
const {
842 double value = e.
attr<
double>(
_U(value));
843 std::string name = e.
attr<std::string>(
_U(name));
844 description.
manager().AddProperty(name.c_str(), value);
845 if ( s_debug.matrix ) {
846 printout(ALWAYS,
"Compact",
"+++ Reading property %s : %f",name.c_str(), value);
851 std::string val = e.
attr<std::string>(opt);
852 TNamed* nam = description.
manager().GetProperty(name.c_str());
854 except(
"Compact",
"Failed to access just added manager property: %s",name.c_str());
856 nam->SetTitle(val.c_str());
866 template <>
void Converter<PropertyTable>::operator()(
xml_h e)
const {
867 std::vector<double> vals;
868 std::size_t cols = e.
attr<
unsigned long>(
_U(coldim));
869 std::stringstream str(e.
attr<std::string>(
_U(values)));
871 if ( s_debug.matrix ) {
872 printout(ALWAYS,
"Compact",
"+++ Reading property table %s with %d columns.",
873 e.
attr<std::string>(
_U(name)).c_str(), cols);
876 while ( !str.eof() ) {
879 if ( item.empty() && !str.good() )
break;
881 if ( s_debug.matrix ) {
882 std::cout <<
" state:" << (str.good() ?
"OK " :
"BAD") <<
" '" << item <<
"'";
883 if ( 0 == (vals.size()%cols) ) std::cout << std::endl;
886 if ( s_debug.matrix ) {
887 std::cout << std::endl;
892 e.
attr<std::string>(
_U(name)),
893 opt ? e.
attr<std::string>(opt).c_str() :
"",
894 vals.size()/cols, cols);
895 for( std::size_t i=0, n=vals.size(); i < n; ++i )
896 tab->Set(i/cols, i%cols, vals[i]);
914 template <>
void Converter<VisAttr>::operator()(
xml_h e)
const {
920 bool use_ref =
false;
923 auto refName = e.
attr<std::string>(
_U(ref));
925 if(!refAttr.isValid() ) {
926 except(
"Compact",
"+++ Reference VisAttr %s does not exist", refName.c_str());
930 refAttr.argb(alpha,red,green,blue);
931 attr.setColor(alpha,red,green,blue);
932 attr.setDrawingStyle( refAttr.drawingStyle());
933 attr.setLineStyle( refAttr.lineStyle());
934 attr.setShowDaughters(refAttr.showDaughters());
935 attr.setVisible(refAttr.visible());
938 alpha = dim.alpha(alpha);
940 green = dim.g(green);
943 printout(s_debug.visattr ? ALWAYS : DEBUG,
"Compact",
944 "++ Converting VisAttr structure: %-16s. Alpha=%.2f R=%.3f G=%.3f B=%.3f",
945 attr.name(), alpha, red, green, blue);
946 attr.setColor(alpha, red, green, blue);
948 attr.setVisible(e.
attr<
bool>(
_U(visible)));
950 std::string ls = e.
attr<std::string>(
_U(lineStyle));
951 if (ls ==
"unbroken")
953 else if (ls ==
"broken")
961 std::string ds = e.
attr<std::string>(
_U(drawingStyle));
962 if (ds ==
"wireframe")
964 else if (ds ==
"solid")
972 attr.setShowDaughters(e.
attr<
bool>(
_U(showDaughters)));
975 attr.setShowDaughters(
true);
983 template <>
void Converter<Region>::operator()(
xml_h elt)
const {
985 Region region(e.nameStr());
986 auto& limits = region.limits();
990 double ene = e.eunit(1.0), len = e.lunit(1.0);
992 printout(s_debug.regions ? ALWAYS : DEBUG,
"Compact",
993 "++ Converting region structure: %s.",region.name());
995 region.setCut(elt.
attr<
double>(cut)*len);
998 region.setThreshold(elt.
attr<
double>(threshold)*ene);
1000 if ( store_secondaries ) {
1001 region.setStoreSecondaries(elt.
attr<
bool>(store_secondaries));
1003 for (
xml_coll_t user_limits(e,
_U(limitsetref)); user_limits; ++user_limits)
1004 limits.emplace_back(user_limits.attr<std::string>(
_U(name)));
1016 template <>
void Converter<Segmentation>::operator()(
xml_h seg)
const {
1017 std::string type = seg.
attr<std::string>(
_U(type));
1018 std::string name = seg.
hasAttr(
_U(name)) ? seg.
attr<std::string>(
_U(name)) : std::string();
1019 std::pair<Segmentation,IDDescriptor>* opt = _option<std::pair<Segmentation,IDDescriptor> >();
1023 if ( segment.isValid() ) {
1025 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1026 "++ Converting segmentation structure: %s of type %s.",name.c_str(),type.c_str());
1027 for(
const auto p : pars ) {
1030 std::string pType = p->type();
1031 if ( pType.compare(
"int") == 0 ) {
1033 static_cast<ParInt*
>(p)->setTypedValue(seg.
attr<
int>(pNam));
1034 }
else if ( pType.compare(
"float") == 0 ) {
1036 static_cast<ParFloat*
>(p)->setTypedValue(seg.
attr<
float>(pNam));
1037 }
else if ( pType.compare(
"doublevec") == 0 ) {
1038 std::vector<double> valueVector;
1039 std::string par = seg.
attr<std::string>(pNam);
1040 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1041 "++ Converting this std::string structure: %s.",par.c_str());
1043 for (
const std::string& spar : elts ) {
1044 if ( spar.empty() )
continue;
1045 valueVector.emplace_back(
_toDouble(spar));
1048 static_cast<ParDouVec*
>(p)->setTypedValue(valueVector);
1049 }
else if ( pType.compare(
"double" ) == 0) {
1051 static_cast<ParDouble*
>(p)->setTypedValue(seg.
attr<
double>(pNam));
1055 }
else if (not p->isOptional()) {
1056 throw_print(
"FAILED to create segmentation: " + type +
1057 ". Missing mandatory parameter: " + p->name() +
"!");
1060 long key_min = 0, key_max = 0;
1062 for(
xml_coll_t sub(seg,
_U(segmentation)); sub; ++sub) {
1063 std::pair<Segmentation,IDDescriptor> sub_object(
Segmentation(),opt->second);
1064 Converter<Segmentation> sub_conv(description,param,&sub_object);
1066 if ( sub_object.first.isValid() ) {
1069 if ( sub.hasAttr(
_U(key_value)) ) {
1070 key_min = key_max = x_seg.key_value();
1072 else if ( sub.hasAttr(
_U(key_min)) && sub.hasAttr(
_U(key_max)) ) {
1073 key_min = x_seg.key_min();
1074 key_max = x_seg.key_max();
1077 std::stringstream tree;
1079 throw_print(
"Nested segmentations: Invalid key specification:"+tree.str());
1081 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1082 "++ Segmentation [%s/%s]: Add sub-segmentation %s [%s]",
1083 name.c_str(), type.c_str(),
1088 delete sub_seg.
ptr();
1092 opt->first = segment;
1102 template <>
void Converter<Readout>::operator()(
xml_h e)
const {
1105 std::string name = e.
attr<std::string>(
_U(name));
1106 std::pair<Segmentation,IDDescriptor> opt;
1115 Converter<Segmentation>(description,param,&opt)(seg);
1116 opt.first->setName(name);
1121 if ( opt.first.isValid() ) {
1122 ro.setSegmentation(opt.first);
1124 if ( opt.second.isValid() ) {
1125 ro.setIDDescriptor(opt.second);
1128 printout(s_debug.readout ? ALWAYS : DEBUG,
1129 "Compact",
"++ Converting readout structure: %-16s. %s%s",
1130 ro.name(),
id ?
"ID: " :
"",
id ?
id.text().c_str() :
"");
1132 for(
xml_coll_t colls(e,
_U(hits_collections)); colls; ++colls) {
1133 std::string hits_key;
1134 if ( colls.hasAttr(
_U(
key)) ) hits_key = colls.attr<std::string>(
_U(
key));
1135 for(
xml_coll_t coll(colls,
_U(hits_collection)); coll; ++coll) {
1137 std::string coll_name = c.nameStr();
1138 std::string coll_key = hits_key;
1139 long key_min = 0, key_max = 0;
1141 if ( c.hasAttr(
_U(
key)) ) {
1142 coll_key = c.attr<std::string>(
_U(
key));
1144 if ( c.hasAttr(
_U(key_value)) ) {
1145 key_max = key_min = c.key_value();
1147 else if ( c.hasAttr(
_U(key_min)) && c.hasAttr(
_U(key_max)) ) {
1148 key_min = c.key_min();
1149 key_max = c.key_max();
1152 std::stringstream tree;
1154 throw_print(
"Readout: Invalid specification for multiple hit collections."+tree.str());
1156 printout(s_debug.readout ? ALWAYS : DEBUG,
"Compact",
1157 "++ Readout[%s]: Add hit collection %s [%s] %d-%d",
1158 ro.name(), coll_name.c_str(), coll_key.c_str(), key_min, key_max);
1160 ro->hits.emplace_back(hits);
1166 static long load_readout(
Detector& description,
xml_h element) {
1167 Converter<Readout> converter(description);
1180 template <>
void Converter<LimitSet>::operator()(
xml_h e)
const {
1183 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1184 "++ Converting LimitSet structure: %s.",ls.name());
1186 limit.
name = c.attr<std::string>(
_U(name));
1187 limit.
particles = c.attr<std::string>(
_U(particles));
1188 limit.
content = c.attr<std::string>(
_U(value));
1189 limit.
unit = c.attr<std::string>(
_U(unit));
1192 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1193 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1199 limit.
particles = c.attr<std::string>(
_U(particles));
1200 limit.
content = c.attr<std::string>(
_U(value));
1201 limit.
unit = c.attr<std::string>(
_U(unit));
1204 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1205 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1218 template <>
void Converter<Property>::operator()(
xml_h e)
const {
1219 std::string name = e.
attr<std::string>(
_U(name));
1222 throw_print(
"Failed to convert properties. No name given!");
1225 if ( prp.find(name) == prp.end() )
1240 template <>
void Converter<CartesianField>::operator()(
xml_h e)
const {
1241 std::string msg =
"updated";
1242 std::string name = e.
attr<std::string>(
_U(name));
1243 std::string type = e.
attr<std::string>(
_U(type));
1245 if ( !field.isValid() ) {
1247 field =
Ref_t(PluginService::Create<NamedObject*>(type, &description, &e));
1248 if ( !field.isValid() ) {
1250 PluginService::Create<NamedObject*>(type, &description, &e);
1251 throw_print(
"Failed to create field object of type "+type +
". "+dbg.
missingFactory(type));
1256 type = field.type();
1260 std::string props_name = c.attr<std::string>(
_U(name));
1261 std::vector<xml_attr_t>a = c.attributes();
1262 if ( prp.find(props_name) == prp.end() ) {
1266 prp[props_name].emplace(
xml_tag_t(c.attr_name(i)).
str(), c.attr<std::string>(i));
1268 if (c.hasAttr(
_U(global)) && c.attr<
bool>(
_U(global))) {
1272 printout(INFO,
"Compact",
"++ Converted field: Successfully %s field %s [%s]", msg.c_str(), name.c_str(), type.c_str());
1288 template <>
void Converter<SensitiveDetector>::operator()(
xml_h element)
const {
1289 std::string name = element.
attr<std::string>(
_U(name));
1306 std::string l = element.
attr<std::string>(limits);
1308 if (!ls.isValid()) {
1309 throw_print(
"Converter<SensitiveDetector>: Request for non-existing limitset:" + l);
1315 std::string r = element.
attr<std::string>(region);
1317 if (!reg.isValid()) {
1318 throw_print(
"Converter<SensitiveDetector>: Request for non-existing region:" + r);
1328 if (ecut && eunit) {
1335 printout(DEBUG,
"Compact",
"SensitiveDetector-update: %-18s %-24s Hits:%-24s Cutoff:%7.3f", sd.
name(),
1342 printout(ERROR,
"Compact",
"++ FAILED to convert sensitive detector: %s: %s", name.c_str(), e.what());
1345 printout(ERROR,
"Compact",
"++ FAILED to convert sensitive detector: %s: %s", name.c_str(),
"UNKNONW Exception");
1349 static void setChildTitles(
const std::pair<std::string, DetElement>& e) {
1352 if (::strlen(e.second->GetTitle()) == 0) {
1353 e.second->SetTitle(parent.
isValid() ? parent.
type().c_str() : e.first.c_str());
1355 for_each(children.begin(), children.end(), setChildTitles);
1358 template <>
void Converter<DetElement>::operator()(
xml_h element)
const {
1359 static const char* req_dets = ::getenv(
"REQUIRED_DETECTORS");
1360 static const char* req_typs = ::getenv(
"REQUIRED_DETECTOR_TYPES");
1361 static const char* ign_dets = ::getenv(
"IGNORED_DETECTORS");
1362 static const char* ign_typs = ::getenv(
"IGNORED_DETECTOR_TYPES");
1363 std::string type = element.
attr<std::string>(
_U(type));
1364 std::string name = element.
attr<std::string>(
_U(name));
1365 std::string name_match =
":" + name +
":";
1366 std::string type_match =
":" + type +
":";
1368 if (req_dets && !strstr(req_dets, name_match.c_str()))
1370 if (req_typs && !strstr(req_typs, type_match.c_str()))
1372 if (ign_dets && strstr(ign_dets, name_match.c_str()))
1374 if (ign_typs && strstr(ign_typs, type_match.c_str()))
1377 if ( attr_ignore ) {
1378 bool ignore_det = element.
attr<
bool>(
_U(ignore));
1380 printout(INFO,
"Compact",
1381 "+++ Do not build subdetector:%s [ignore flag set]",
1387 std::string par_name;
1391 par_name = element.
attr<std::string>(attr_par);
1392 else if ( (elt_par=element.
child(
_U(parent),
false)) )
1393 par_name = elt_par.attr<std::string>(
_U(name));
1394 if ( !par_name.empty() ) {
1401 except(
"Compact",
"Failed to access valid parent detector of %s",name.c_str());
1411 except(
"Compact",
"No Readout structure present for detector:" + name);
1420 DetElement det(
Ref_t(PluginService::Create<NamedObject*>(type, &description, &element, &sens)));
1421 if (
det.isValid()) {
1422 setChildTitles(std::make_pair(name,
det));
1431 printout(
det.isValid() ? INFO : ERROR,
"Compact",
"%s subdetector:%s of type %s %s",
1432 (
det.isValid() ?
"++ Converted" :
"FAILED "), name.c_str(), type.c_str(),
1433 (sd.
isValid() ? (
"[" + sd.
type() +
"]").c_str() :
""));
1435 if (!
det.isValid()) {
1437 PluginService::Create<NamedObject*>(type, &description, &element, &sens);
1438 except(
"Compact",
"Failed to execute subdetector creation plugin. %s", dbg.
missingFactory(type).c_str());
1445 printout(ERROR,
"Compact",
"++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
1449 printout(ERROR,
"Compact",
"++ FAILED to convert subdetector: %s: %s", name.c_str(),
"UNKNONW Exception");
1455 template <>
void Converter<IncludeFile>::operator()(
xml_h element)
const {
1457 if ( s_debug.include_guard) {
1462 xml_h root = doc.root();
1463 if ( s_debug.includes ) {
1464 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
1466 if ( root.
tag() ==
"materials" || root.
tag() ==
"elements" ) {
1472 this->description.
fromXML(doc.uri(), this->description.buildType());
1476 template <>
void Converter<JsonFile>::operator()(
xml_h element)
const {
1478 std::string file = element.
attr<std::string>(
_U(ref));
1479 std::vector<char*> argv{&file[0], &base[0]};
1480 description.
apply(
"DD4hep_JsonProcessor",
int(argv.size()), &argv[0]);
1484 template <>
void Converter<XMLFile>::operator()(
xml_h element)
const {
1485 PrintLevel level = s_debug.includes ? ALWAYS : DEBUG;
1486 std::string fname = element.
attr<std::string>(
_U(ref));
1487 std::size_t idx = fname.find(
"://");
1490 if ( idx == std::string::npos && std::filesystem::exists(fname, ec) ) {
1492 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1495 else if ( idx == std::string::npos ) {
1498 printout(level,
"Compact",
"++ Processing xml document %s.", location.c_str());
1501 else if ( idx > 0 ) {
1503 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1508 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1514 template <>
void Converter<World>::operator()(
xml_h element)
const {
1518 Material mat = att ? description.
material(x_world.attr<std::string>(att)) : description.
air();
1523 Solid sol(x_shape.createShape());
1524 world_vol =
Volume(
"world_volume", sol, mat);
1525 printout(INFO,
"Compact",
"++ Created successfully world volume '%s'. shape: %s material:%s.",
1526 world_vol.
name(), sol.type(), mat.
name());
1527 description.
manager().SetTopVolume(world_vol.
ptr());
1531 if ( !world_vol && att ) {
1534 Box sol(
"world_x",
"world_y",
"world_z");
1535 world_vol =
Volume(
"world_volume", sol, mat);
1536 printout(INFO,
"Compact",
"++ Created world volume '%s' as %s (%.2f, %.2f %.2f [cm]) material:%s.",
1537 world_vol.
name(), sol.type(),
1538 sol.x()/dd4hep::cm, sol.y()/dd4hep::cm, sol.z()/dd4hep::cm,
1540 description.
manager().SetTopVolume(world_vol.
ptr());
1542 else if ( !world_vol ) {
1543 except(
"Compact",
"++ Logical error: "
1544 "You cannot configure the world volume before it is created and not giving creation instructions.");
1551 if ( !vis.isValid() ) {
1559 template <>
void Converter<Parallelworld_Volume>::operator()(
xml_h element)
const {
1564 std::string name = element.
attr<std::string>(
_U(name));
1565 std::string path = element.
attr<std::string>(
_U(anchor));
1566 bool conn = element.
attr<
bool>(
_U(connected),
false);
1571 Material mat = parallel.hasAttr(
_U(material))
1572 ? description.
material(parallel.attr<std::string>(
_U(material)))
1573 : description.
air();
1578 if ( !anchor.isValid() ) {
1579 except(
"Parallelworld_Volume",
1580 "++ FAILED Cannot identify the anchor of the tracking volume: '%s'",
1586 Solid sol(shape.createShape());
1587 Volume vol(name, sol, mat);
1592 vol.setVisAttributes(vis);
1600 except(
"Parallelworld_Volume",
1601 "++ FAILED to place the tracking volume inside the anchor '%s'",path.c_str());
1603 if ( name ==
"tracking_volume" ) {
1606 printout(INFO,
"Compact",
"++ Converted successfully parallelworld_volume %s. anchor: %s vis:%s.",
1607 vol.name(), anchor.path().c_str(), vis.
name());
1611 template <>
void Converter<DetElementInclude>::operator()(
xml_h element)
const {
1612 std::string type = element.
hasAttr(
_U(type)) ? element.
attr<std::string>(
_U(type)) : std::string(
"xml");
1613 if ( type ==
"xml" ) {
1615 if ( s_debug.include_guard ) {
1620 if ( s_debug.includes ) {
1621 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
1623 xml_h node = doc.root();
1624 std::string tag = node.
tag();
1625 if ( tag ==
"lccdd" )
1626 Converter<Compact>(this->description)(node);
1627 else if ( tag ==
"define" )
1629 else if ( tag ==
"readout" )
1630 Converter<Readout>(this->description)(node);
1631 else if ( tag ==
"readouts" )
1633 else if ( tag ==
"region" )
1634 Converter<Region>(this->description)(node);
1635 else if ( tag ==
"regions" )
1637 else if ( tag ==
"limits" || tag ==
"limitsets" )
1639 else if ( tag ==
"display" )
1641 else if ( tag ==
"detector" )
1642 Converter<DetElement>(this->description)(node);
1643 else if ( tag ==
"detectors" )
1646 else if ( type ==
"json" ) {
1647 Converter<JsonFile>(this->description)(element);
1649 else if ( type ==
"gdml" ) {
1650 Converter<IncludeFile>(this->description)(element);
1652 else if ( type ==
"include" ) {
1653 Converter<IncludeFile>(this->description)(element);
1655 else if ( type ==
"xml-extended" ) {
1656 Converter<XMLFile>(this->description)(element);
1659 except(
"Compact",
"++ FAILED Invalid file type:%s. This cannot be processed!",type.c_str());
1664 template <>
void Converter<Compact>::operator()(
xml_h element)
const {
1665 static int num_calls = 0;
1670 bool steer_geometry = compact.hasChild(
_U(geometry));
1671 bool open_geometry =
true;
1672 bool close_document =
true;
1673 bool close_geometry =
true;
1674 bool build_reflections =
false;
1679 (Converter<Debug>(description))(
xml_h(compact.child(
_U(
debug))));
1681 if ( steer_geometry ) {
1684 open_geometry = steer.
attr<
bool>(
_U(open));
1686 close_document = steer.
attr<
bool>(
_U(close));
1688 build_reflections = steer.
attr<
bool>(
_U(reflect));
1690 std::string nam = clr.hasAttr(
_U(name)) ? clr.attr<std::string>(
_U(name)) : std::string();
1691 if ( nam.substr(0,6) ==
"elemen" ) {
1692 TGeoElementTable* table = description.
manager().GetElementTable();
1693 table->TGeoElementTable::~TGeoElementTable();
1694 new(table) TGeoElementTable();
1696 table->AddElement(
"VACUUM",
"VACUUM" ,0, 0, 0.0);
1697 printout(INFO,
"Compact",
1698 "++ Cleared default ROOT TGeoElementTable contents. "
1699 "Must now be filled from XML!");
1704 if ( s_debug.materials || s_debug.elements ) {
1705 printout(INFO,
"Compact",
"+++ UNIT System:");
1706 printout(INFO,
"Compact",
"+++ Density: %8.3g Units:%8.3g",
1710 printout(INFO,
"Compact",
"+++ nanosecond: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(nanosecond)),dd4hep::nanosecond);
1711 printout(INFO,
"Compact",
"+++ kilo: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(kilogram)),dd4hep::kilogram);
1713 dd4hep::joule*dd4hep::s*dd4hep::s/(dd4hep::meter*dd4hep::meter));
1715 printout(INFO,
"Compact",
"+++ ampere: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(ampere)),dd4hep::ampere);
1716 printout(INFO,
"Compact",
"+++ degree: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(degree)),dd4hep::degree);
1726 (Converter<Header>(description))(
xml_h(compact.child(
_U(
info))));
1739 printout(DEBUG,
"Compact",
"++ Converting visualization attributes...");
1743 printout(DEBUG,
"Compact",
"++ Converting limitset structures...");
1747 printout(DEBUG,
"Compact",
"++ Converting region structures...");
1752 (Converter<World>(description))(world);
1754 if ( open_geometry ) description.
init();
1755 printout(DEBUG,
"Compact",
"++ Converting readout structures...");
1759 printout(DEBUG,
"Compact",
"++ Converting included files with subdetector structures...");
1761 printout(DEBUG,
"Compact",
"++ Converting detector structures...");
1767 xml_coll_t(compact,
_U(sensitive_detectors)).
for_each(
_U(sd), Converter<SensitiveDetector>(description));
1768 xml_coll_t(compact,
_U(parallelworld_volume)).
for_each(Converter<Parallelworld_Volume>(description));
1770 if ( --num_calls == 0 && close_document ) {
1771 ::snprintf(text,
sizeof(text),
"%u",
xml_h(element).checksum(0));
1775 if ( build_reflections ) {
1786 template Converter<Plugin>;
1787 template Converter<Constant>;
1788 template Converter<Material>;
1789 template Converter<Atom>;
1790 template Converter<VisAttr>;
1791 template Converter<Region>;
1792 template Converter<Readout>;
1793 template Converter<Segmentation>;
1794 template Converter<LimitSet>;
1795 template Converter<Property>;
1796 template Converter<CartesianField>;
1797 template Converter<SensitiveDetector>;
1798 template Converter<DetElement>;
1799 template Converter<GdmlFile>;
1800 template Converter<XMLFile>;
1801 template Converter<Header>;
1802 template Converter<DetElementInclude>;
1803 template Converter<Compact>;