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 include_guard=
true;
131 std::string t = e.
attr<std::string>(
_U(field));
134 ptr->direction.SetX(strength.x());
135 ptr->direction.SetY(strength.y());
136 ptr->direction.SetZ(strength.z());
137 obj.
assign(ptr, field.nameStr(), field.typeStr());
144 bool has_inner_radius = c.hasAttr(
_U(inner_radius));
145 bool has_outer_radius = c.hasAttr(
_U(outer_radius));
147 if (!has_inner_radius && !has_outer_radius) {
148 throw_print(
"Compact2Objects[ERROR]: For a solenoidal field at least one of the "
149 " xml attributes inner_radius of outer_radius MUST be set.");
158 if (has_inner_radius && has_outer_radius) {
162 else if (has_inner_radius) {
167 else if (has_outer_radius) {
172 if (c.hasAttr(
_U(inner_field)))
174 if (c.hasAttr(
_U(outer_field)))
176 if (c.hasAttr(
_U(zmax)))
177 ptr->
maxZ = c.attr<
double>(
_U(zmax));
180 if (c.hasAttr(
_U(zmin)))
181 ptr->
minZ = c.attr<
double>(
_U(zmin));
185 obj.
assign(ptr, c.nameStr(), c.typeStr());
196 double lunit = c.hasAttr(
_U(lunit)) ? c.attr<
double>(
_U(lunit)) : 1.0;
197 double funit = c.hasAttr(
_U(funit)) ? c.attr<
double>(
_U(funit)) : 1.0;
198 double val, mult = funit;
200 if (c.hasAttr(
_U(zmin)))
202 if (c.hasAttr(
_U(zmax)))
204 if (c.hasAttr(
_U(rmax)))
206 for (
xml_coll_t coll(c,
_U(dipole_coeff)); coll; ++coll, mult /= lunit) {
208 if ( coeff.hasAttr(
_U(value)) )
209 val = coll.attr<
double>(
_U(value)) * mult;
210 else if ( coeff.hasAttr(
_U(coefficient)) )
211 val = coeff.coefficient() * mult;
217 obj.
assign(ptr, c.nameStr(), c.typeStr());
226 double lunit = c.hasAttr(
_U(lunit)) ? c.attr<
double>(
_U(lunit)) : 1.0;
227 double funit = c.hasAttr(
_U(funit)) ? c.attr<
double>(
_U(funit)) : 1.0;
228 double val, mult = funit, bz = 0.0;
232 if (c.hasAttr(
_U(Z))) bz = c.Z() * funit;
233 if ((child = c.child(
_U(position),
false))) {
234 pos.SetXYZ(child.x(), child.y(), child.z());
236 if ((child = c.child(
_U(rotation),
false))) {
237 rot.SetComponents(child.z(), child.y(), child.x());
239 if ((child = c.child(
_U(shape),
false))) {
240 std::string type = child.typeStr();
245 for (
xml_coll_t coll(c,
_U(coefficient)); coll; ++coll, mult /= lunit) {
247 if ( coll.hasAttr(
_U(value)) )
248 val = coll.attr<
double>(
_U(value)) * mult;
250 val = coeff.coefficient(0.0) * mult;
252 val = coeff.skew(0.0) * mult;
253 ptr->
skews.emplace_back(val);
256 obj.
assign(ptr, c.nameStr(), c.typeStr());
261 static long load_Compact(
Detector& description,
xml_h element) {
262 Converter<Compact>converter(description);
279 if ( !already_processed ) {
284 if (already_processed->find(npath) != already_processed->end() ) {
285 printout(INFO,
"Compact",
"++ Already processed xml document %s.", npath.c_str());
288 already_processed->insert(npath);
294 template <>
void Converter<Debug>::operator()(
xml_h e)
const {
296 int val = coll.attr<
int>(
_U(value));
297 std::string nam = coll.attr<std::string>(
_U(name));
298 if ( nam.substr(0,6) ==
"isotop" ) s_debug.isotopes = (0 != val);
299 else if ( nam.substr(0,6) ==
"elemen" ) s_debug.elements = (0 != val);
300 else if ( nam.substr(0,6) ==
"materi" ) s_debug.materials = (0 != val);
301 else if ( nam.substr(0,6) ==
"visatt" ) s_debug.visattr = (0 != val);
302 else if ( nam.substr(0,6) ==
"region" ) s_debug.regions = (0 != val);
303 else if ( nam.substr(0,6) ==
"readou" ) s_debug.readout = (0 != val);
304 else if ( nam.substr(0,6) ==
"limits" ) s_debug.limits = (0 != val);
305 else if ( nam.substr(0,6) ==
"segmen" ) s_debug.segmentation = (0 != val);
306 else if ( nam.substr(0,6) ==
"consta" ) s_debug.constants = (0 != val);
307 else if ( nam.substr(0,6) ==
"define" ) s_debug.constants = (0 != val);
308 else if ( nam.substr(0,6) ==
"includ" ) s_debug.includes = (0 != val);
309 else if ( nam.substr(0,6) ==
"matrix" ) s_debug.matrix = (0 != val);
310 else if ( nam.substr(0,6) ==
"surfac" ) s_debug.surface = (0 != val);
311 else if ( nam.substr(0,6) ==
"incgua" ) s_debug.include_guard= (0 != val);
320 template <>
void Converter<Plugin>::operator()(
xml_h e)
const {
322 std::string name = plugin.nameStr();
323 std::string type =
"default";
326 type = e.
attr<std::string>(typ_attr);
328 if ( type ==
"default" ) {
329 std::vector<char*> argv;
330 std::vector<std::string> arguments;
332 std::string val = coll.attr<std::string>(
_U(value));
333 arguments.emplace_back(val);
336 std::string val = coll.attr<std::string>(
_U(value));
337 arguments.emplace_back(val);
339 for(std::vector<std::string>::iterator i=arguments.begin(); i!=arguments.end(); ++i)
340 argv.emplace_back(&((*i)[0]));
341 description.
apply(name.c_str(),int(argv.size()), &argv[0]);
345 long result = PluginService::Create<long>(name, &description, &e);
348 result = PluginService::Create<long>(name, &description, &e);
350 except(
"Compact",
"++ Failed to locate plugin %s - no factory: %s",
354 result = *(
long*) result;
356 except(
"Compact",
"++ Failed to execute plugin %s", name.c_str());
364 template <>
void Converter<Constant>::operator()(
xml_h e)
const {
365 if ( e.
tag() !=
"include" ) {
367 std::string nam = constant.attr<std::string>(
_U(name));
368 std::string val = constant.attr<std::string>(
_U(value));
369 std::string typ = constant.hasAttr(
_U(type)) ? constant.attr<std::string>(
_U(type)) :
"number";
373 if ( s_debug.constants ) {
374 printout(ALWAYS,
"Compact",
375 "++ Converting constant %-16s = %-32s [%s]", nam.c_str(), val.c_str(), typ.c_str());
380 if ( s_debug.includes ) {
381 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
383 xml_h root = doc.root();
392 template <>
void Converter<Header>::operator()(
xml_h e)
const {
395 h.setUrl(e.
attr<std::string>(
_U(url),
"Undefined"));
396 h.setAuthor(e.
attr<std::string>(
_U(author),
"Undefined"));
397 h.setStatus(e.
attr<std::string>(
_U(status),
"development"));
398 h.setVersion(e.
attr<std::string>(
_U(version),
"Undefined"));
399 h.setComment(e.
hasChild(
_U(comment)) ? e.
child(
_U(comment)).text() :
"No Comment");
419 template <>
void Converter<Material>::operator()(
xml_h e)
const {
421 TGeoManager& mgr = description.
manager();
423 const char* matname = mname.
c_str();
424 TGeoElementTable* table = mgr.GetElementTable();
425 TGeoMaterial* mat = mgr.GetMaterial(matname);
426 TGeoMixture*
mix =
dynamic_cast<TGeoMixture*
>(mat);
431 TGeoMaterial* comp_mat;
432 TGeoElement* comp_elt;
434 double dens_val = density.
ptr() ? density.
attr<
double>(
_U(value)) : 0.0;
435 double dens_unit = 1.0;
437 if ( !density.
ptr() ) {
438 throw_print(
"Compact2Objects[ERROR]: material without density tag ( <D unit=\"g/cm3\" value=\"..\"/> ) provided: "
439 + std::string( matname ) ) ;
444 if ( dens_unit != 1.0 ) {
445 dens_val *= dens_unit;
446 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
"Density unit: %.3f [%s] raw: %.3f normalized: %.3f ",
447 dens_unit, density.
attr<std::string>(
_U(unit)).c_str(), dens_val, (dens_val*dens_unit));
449 mat =
mix =
new TGeoMixture(matname, composites.size(), dens_val);
450 std::size_t ifrac = 0;
451 std::vector<double> composite_fractions;
452 double composite_fractions_total = 0.0;
453 for (composites.reset(); composites; ++composites) {
454 std::string nam = composites.attr<std::string>(
_U(ref));
455 double fraction = composites.attr<
double>(
_U(n));
456 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
457 fraction *= comp_mat->GetA();
458 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
459 fraction *= comp_elt->A();
461 except(
"Compact2Objects",
"Converting material: %s Element missing: %s",mname.
c_str(),nam.c_str());
462 composite_fractions_total += fraction;
463 composite_fractions.emplace_back(fraction);
465 for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) {
466 std::string nam = composites.attr<std::string>(
_U(ref));
467 double fraction = composite_fractions[ifrac]/composite_fractions_total;
468 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
469 mix->AddElement(comp_mat, fraction);
470 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
471 mix->AddElement(comp_elt, fraction);
473 for (fractions.reset(); fractions; ++fractions) {
474 std::string nam = fractions.attr<std::string>(
_U(ref));
475 double fraction = fractions.attr<
double>(
_U(n));
476 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
477 mix->AddElement(comp_mat, fraction);
478 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
479 mix->AddElement(comp_elt, fraction);
481 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" Element missing: " + nam);
485 if ( temperature.
ptr() ) {
488 temp_unit = temperature.
attr<
double>(
_U(unit));
489 temp_val = temperature.
attr<
double>(
_U(value)) * temp_unit;
493 if ( pressure.
ptr() ) {
494 double pressure_unit =
_toDouble(
"pascal");
496 pressure_unit = pressure.
attr<
double>(
_U(unit));
497 pressure_val = pressure.
attr<
double>(
_U(value)) * pressure_unit;
500 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
501 "++ ROOT raw temperature and pressure: %.3g %.3g",
502 mat->GetTemperature(),mat->GetPressure());
504 mat->SetTemperature(temp_val);
505 mat->SetPressure(pressure_val);
506 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
507 "++ Converting material %-16s Density: %9.7g Temperature:%9.7g [K] Pressure:%9.7g [hPa].",
508 matname, dens_val, temp_val/dd4hep::kelvin, pressure_val/dd4hep::pascal/100.0);
511 mix->ComputeDerivedQuantities();
514 for(
xml_coll_t properties(x_mat,
_U(constant)); properties; ++properties) {
518 std::string ref = p.
attr<std::string>(
_U(ref));
519 mgr.GetProperty(ref.c_str(), &err);
520 if ( err == kFALSE ) {
521 std::string prop_nam = p.
attr<std::string>(
_U(name));
522 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
523 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
524 "++ material %-16s add constant property: %s -> %s.",
525 mat->GetName(), prop_nam.c_str(), ref.c_str());
529 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" ConstProperty missing in TGeoManager: " + ref);
532 std::stringstream str;
533 std::string ref, prop_nam = p.
attr<std::string>(
_U(name));
534 str << prop_nam <<
"_" << (
void*)mat;
536 mgr.AddProperty(ref.c_str(), p.
attr<
double>(
_U(value)));
537 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
538 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
539 "++ material %-16s add constant property: %s -> %s.",
540 mat->GetName(), prop_nam.c_str(), ref.c_str());
543 std::string prop_nam = p.
attr<std::string>(
_U(name));
544 std::string prop_typ = p.
attr<std::string>(
_U(option));
545 mat->AddConstProperty(prop_nam.c_str(), prop_typ.c_str());
546 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
547 "++ material %-16s add constant property: %s -> %s.",
548 mat->GetName(), prop_nam.c_str(), prop_typ.c_str());
552 for(
xml_coll_t properties(x_mat,
_U(property)); properties; ++properties) {
555 std::string ref = p.
attr<std::string>(
_U(ref));
556 TGDMLMatrix* gdmlMat = mgr.GetGDMLMatrix(ref.c_str());
558 std::string prop_nam = p.
attr<std::string>(
_U(name));
559 mat->AddProperty(prop_nam.c_str(), ref.c_str());
560 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
561 "++ material %-16s add property: %s -> %s.",
562 mat->GetName(), prop_nam.c_str(), ref.c_str());
566 throw_print(
"Compact2Objects[ERROR]: Converting material:" + mname +
" Property missing: " + ref);
570 TGeoMedium* medium = mgr.GetMedium(matname);
573 medium =
new TGeoMedium(matname, unique_mat_id, mat);
574 medium->SetTitle(
"material");
575 medium->SetUniqueID(unique_mat_id);
579 if (x_mat.hasAttr(
_U(formula))) {
580 std::string form = x_mat.attr<std::string>(
_U(formula));
581 if (form != matname) {
582 medium = mgr.GetMedium(form.c_str());
585 medium =
new TGeoMedium(form.c_str(), unique_mat_id, mat);
586 medium->SetTitle(
"material");
587 medium->SetUniqueID(unique_mat_id);
599 template <>
void Converter<Isotope>::operator()(
xml_h e)
const {
601 TGeoManager& mgr = description.
manager();
602 std::string nam = isotope.nameStr();
603 TGeoElementTable* tab = mgr.GetElementTable();
604 TGeoIsotope* iso = tab->FindIsotope(nam.c_str());
609 std::string unit = atom.attr<std::string>(
_U(unit));
610 double value = atom.attr<
double>(
_U(value));
612 int n = isotope.attr<
int>(
_U(N));
613 int z = isotope.attr<
int>(
_U(Z));
614 iso =
new TGeoIsotope(nam.c_str(), z, n, a);
615 printout(s_debug.isotopes ? ALWAYS : DEBUG,
"Compact",
616 "++ Converting isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol]",
617 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
620 printout(s_debug.isotopes ? WARNING : DEBUG,
"Compact",
621 "++ Isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
622 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
640 template <>
void Converter<Atom>::operator()(
xml_h e)
const {
643 TGeoManager& mgr = description.
manager();
644 TGeoElementTable* tab = mgr.GetElementTable();
645 TGeoElement* elt = tab->FindElement(name.
c_str());
647 if ( elem.hasChild(
_U(atom)) ) {
649 std::string formula = elem.attr<std::string>(
_U(formula));
650 double value = atom.attr<
double>(
_U(value));
651 std::string unit = atom.attr<std::string>(
_U(unit));
652 int z = elem.attr<
int>(
_U(Z));
654 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
655 "++ Converting element %-16s [%-3s] Z:%3d A:%8.4f [g/mol]",
656 name.
c_str(), formula.c_str(), z, a);
657 tab->AddElement(name.
c_str(), formula.c_str(), z, a);
660 int num_isotopes = 0;
661 std::string formula = elem.hasAttr(
_U(formula)) ? elem.attr<std::string>(
_U(formula)) : name.
str();
664 elt =
new TGeoElement(name.
c_str(), formula.c_str(), num_isotopes);
665 tab->AddElement(elt);
667 double frac = i.attr<
double>(
_U(n));
668 std::string ref = i.attr<std::string>(
_U(ref));
669 TGeoIsotope* iso = tab->FindIsotope(ref.c_str());
671 except(
"Compact",
"Element %s cannot be constructed. Isotope '%s' (fraction: %.3f) missing!",
672 name.
c_str(), ref.c_str(), frac);
674 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
675 "++ Converting element %-16s Add isotope: %-16s fraction:%.4f.",
676 name.
c_str(), ref.c_str(), frac);
677 elt->AddIsotope(iso, frac);
679 printout(s_debug.elements ? ALWAYS : DEBUG,
"Compact",
680 "++ Converted element %-16s [%-3s] Z:%3d A:%8.4f [g/mol] with %d isotopes.",
681 name.
c_str(), formula.c_str(), elt->Z(), elt->A(), num_isotopes);
683 elt = tab->FindElement(name.
c_str());
685 throw_print(
"Failed to properly insert the Element:"+name+
" into the element table!");
689 printout(s_debug.elements ? WARNING : DEBUG,
"Compact",
690 "++ Element %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
691 elt->GetName(), elt->Z(), elt->N(), elt->A());
702 template <>
void Converter<STD_Conditions>::operator()(
xml_h e)
const {
706 if (
cond.hasAttr(
_U(type)) ) {
711 if ( temperature.
ptr() ) {
714 temp_unit = temperature.
attr<
double>(
_U(unit));
715 temp_val = temperature.
attr<
double>(
_U(value)) * temp_unit;
719 if ( pressure.
ptr() ) {
720 double pressure_unit =
_toDouble(
"pascal");
722 pressure_unit = pressure.
attr<
double>(
_U(unit));
723 pressure_val = pressure.
attr<
double>(
_U(value)) * pressure_unit;
726 printout(s_debug.materials ? ALWAYS : DEBUG,
"Compact",
727 "+++ Material standard conditions: Temperature: %.3f Kelvin Pressure: %.3f hPa",
736 template <>
void Converter<OpticalSurface>::operator()(
xml_h element)
const {
738 TGeoManager& mgr = description.
manager();
739 std::string sname = e.
attr<std::string>(
_U(name));
740 std::string ref, pname;
746 Double_t value = 1.0;
751 OpticalSurface surf(description, sname, model, finish, type, value);
752 if ( s_debug.surface ) {
753 printout(ALWAYS,
"Compact",
"+++ Reading optical surface %s Typ:%d model:%d finish:%d value: %.3f",
754 sname.c_str(),
int(type),
int(model),
int(finish), value);
756 for (
xml_coll_t props(e,
_U(property)); props; ++props) {
757 pname = props.attr<std::string>(
_U(name));
758 if ( props.hasAttr(
_U(ref)) ) {
760 ref = props.attr<std::string>(
_U(ref));
761 mgr.GetProperty(ref.c_str(), &err);
762 surf->AddProperty(pname.c_str(), ref.c_str());
763 if ( s_debug.surface ) {
764 printout(ALWAYS,
"Compact",
"+++ \t\t Property: %s -> %s", pname.c_str(), ref.c_str());
768 std::size_t cols = props.attr<
long>(
_U(coldim));
770 std::stringstream str(props.attr<std::string>(
_U(values))), str_nam;
772 std::vector<double> values;
773 while ( !str.eof() ) {
776 if ( val.empty() && !str.good() )
break;
780 TGDMLMatrix* table =
new TGDMLMatrix(
"",values.size()/cols, cols);
782 std::string tit = e.
attr<std::string>(opt);
783 str_nam << tit <<
"|";
785 str_nam << pname <<
"__" << (
void*)table;
786 table->SetName(str_nam.str().c_str());
787 table->SetTitle(pname.c_str());
788 for (std::size_t i=0, n=values.size(); i<n; ++i)
789 table->Set(i/cols, i%cols, values[i]);
790 surf->AddProperty(pname.c_str(), table->GetName());
791 description.
manager().AddGDMLMatrix(table);
793 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
796 for(
xml_coll_t properties(e,
_U(constant)); properties; ++properties) {
798 pname = p.
attr<std::string>(
_U(name));
801 ref = p.
attr<std::string>(
_U(ref));
802 mgr.GetProperty(ref.c_str(), &err);
803 if ( err == kFALSE ) {
804 surf->AddConstProperty(pname.c_str(), ref.c_str());
805 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
806 "++ surface %-16s add constant property: %s -> %s.",
807 surf->GetName(), pname.c_str(), ref.c_str());
811 throw_print(
"Compact2Objects[ERROR]: Converting surface: " + sname +
812 " ConstProperty missing in TGeoManager: " + ref);
815 std::stringstream str;
816 str << pname <<
"_" << (
void*)surf.ptr();
818 mgr.AddProperty(ref.c_str(), p.
attr<
double>(
_U(value)));
819 surf->AddConstProperty(pname.c_str(), ref.c_str());
820 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
821 "++ surface %-16s add constant property: %s -> %s.",
822 surf->GetName(), pname.c_str(), ref.c_str());
825 std::string ptyp = p.
attr<std::string>(
_U(option));
826 surf->AddConstProperty(pname.c_str(), ptyp.c_str());
827 printout(s_debug.surface ? ALWAYS : DEBUG,
"Compact",
828 "++ surface %-16s add constant property: %s -> %s.",
829 surf->GetName(), pname.c_str(), ptyp.c_str());
840 template <>
void Converter<PropertyConstant>::operator()(
xml_h e)
const {
841 double value = e.
attr<
double>(
_U(value));
842 std::string name = e.
attr<std::string>(
_U(name));
843 description.
manager().AddProperty(name.c_str(), value);
844 if ( s_debug.matrix ) {
845 printout(ALWAYS,
"Compact",
"+++ Reading property %s : %f",name.c_str(), value);
850 std::string val = e.
attr<std::string>(opt);
851 TNamed* nam = description.
manager().GetProperty(name.c_str());
853 except(
"Compact",
"Failed to access just added manager property: %s",name.c_str());
855 nam->SetTitle(val.c_str());
865 template <>
void Converter<PropertyTable>::operator()(
xml_h e)
const {
866 std::vector<double> vals;
867 std::size_t cols = e.
attr<
unsigned long>(
_U(coldim));
868 std::stringstream str(e.
attr<std::string>(
_U(values)));
870 if ( s_debug.matrix ) {
871 printout(ALWAYS,
"Compact",
"+++ Reading property table %s with %d columns.",
872 e.
attr<std::string>(
_U(name)).c_str(), cols);
875 while ( !str.eof() ) {
878 if ( item.empty() && !str.good() )
break;
880 if ( s_debug.matrix ) {
881 std::cout <<
" state:" << (str.good() ?
"OK " :
"BAD") <<
" '" << item <<
"'";
882 if ( 0 == (vals.size()%cols) ) std::cout << std::endl;
885 if ( s_debug.matrix ) {
886 std::cout << std::endl;
891 e.
attr<std::string>(
_U(name)),
892 opt ? e.
attr<std::string>(opt).c_str() :
"",
893 vals.size()/cols, cols);
894 for( std::size_t i=0, n=vals.size(); i < n; ++i )
895 tab->Set(i/cols, i%cols, vals[i]);
913 template <>
void Converter<VisAttr>::operator()(
xml_h e)
const {
919 bool use_ref =
false;
922 auto refName = e.
attr<std::string>(
_U(ref));
924 if(!refAttr.isValid() ) {
925 except(
"Compact",
"+++ Reference VisAttr %s does not exist", refName.c_str());
929 refAttr.argb(alpha,red,green,blue);
930 attr.setColor(alpha,red,green,blue);
931 attr.setDrawingStyle( refAttr.drawingStyle());
932 attr.setLineStyle( refAttr.lineStyle());
933 attr.setShowDaughters(refAttr.showDaughters());
934 attr.setVisible(refAttr.visible());
937 alpha = dim.alpha(alpha);
939 green = dim.g(green);
942 printout(s_debug.visattr ? ALWAYS : DEBUG,
"Compact",
943 "++ Converting VisAttr structure: %-16s. Alpha=%.2f R=%.3f G=%.3f B=%.3f",
944 attr.name(), alpha, red, green, blue);
945 attr.setColor(alpha, red, green, blue);
947 attr.setVisible(e.
attr<
bool>(
_U(visible)));
949 std::string ls = e.
attr<std::string>(
_U(lineStyle));
950 if (ls ==
"unbroken")
952 else if (ls ==
"broken")
960 std::string ds = e.
attr<std::string>(
_U(drawingStyle));
961 if (ds ==
"wireframe")
963 else if (ds ==
"solid")
971 attr.setShowDaughters(e.
attr<
bool>(
_U(showDaughters)));
974 attr.setShowDaughters(
true);
982 template <>
void Converter<Region>::operator()(
xml_h elt)
const {
984 Region region(e.nameStr());
985 auto& limits = region.limits();
989 double ene = e.eunit(1.0), len = e.lunit(1.0);
991 printout(s_debug.regions ? ALWAYS : DEBUG,
"Compact",
992 "++ Converting region structure: %s.",region.name());
994 region.setCut(elt.
attr<
double>(cut)*len);
997 region.setThreshold(elt.
attr<
double>(threshold)*ene);
999 if ( store_secondaries ) {
1000 region.setStoreSecondaries(elt.
attr<
bool>(store_secondaries));
1002 for (
xml_coll_t user_limits(e,
_U(limitsetref)); user_limits; ++user_limits)
1003 limits.emplace_back(user_limits.attr<std::string>(
_U(name)));
1015 template <>
void Converter<Segmentation>::operator()(
xml_h seg)
const {
1016 std::string type = seg.
attr<std::string>(
_U(type));
1017 std::string name = seg.
hasAttr(
_U(name)) ? seg.
attr<std::string>(
_U(name)) : std::string();
1018 std::pair<Segmentation,IDDescriptor>* opt = _option<std::pair<Segmentation,IDDescriptor> >();
1022 if ( segment.isValid() ) {
1024 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1025 "++ Converting segmentation structure: %s of type %s.",name.c_str(),type.c_str());
1026 for(
const auto p : pars ) {
1029 std::string pType = p->type();
1030 if ( pType.compare(
"int") == 0 ) {
1032 static_cast<ParInt*
>(p)->setTypedValue(seg.
attr<
int>(pNam));
1033 }
else if ( pType.compare(
"float") == 0 ) {
1035 static_cast<ParFloat*
>(p)->setTypedValue(seg.
attr<
float>(pNam));
1036 }
else if ( pType.compare(
"doublevec") == 0 ) {
1037 std::vector<double> valueVector;
1038 std::string par = seg.
attr<std::string>(pNam);
1039 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1040 "++ Converting this std::string structure: %s.",par.c_str());
1042 for (
const std::string& spar : elts ) {
1043 if ( spar.empty() )
continue;
1044 valueVector.emplace_back(
_toDouble(spar));
1047 static_cast<ParDouVec*
>(p)->setTypedValue(valueVector);
1048 }
else if ( pType.compare(
"double" ) == 0) {
1050 static_cast<ParDouble*
>(p)->setTypedValue(seg.
attr<
double>(pNam));
1054 }
else if (not p->isOptional()) {
1055 throw_print(
"FAILED to create segmentation: " + type +
1056 ". Missing mandatory parameter: " + p->name() +
"!");
1059 long key_min = 0, key_max = 0;
1061 for(
xml_coll_t sub(seg,
_U(segmentation)); sub; ++sub) {
1062 std::pair<Segmentation,IDDescriptor> sub_object(
Segmentation(),opt->second);
1063 Converter<Segmentation> sub_conv(description,param,&sub_object);
1065 if ( sub_object.first.isValid() ) {
1068 if ( sub.hasAttr(
_U(key_value)) ) {
1069 key_min = key_max = x_seg.key_value();
1071 else if ( sub.hasAttr(
_U(key_min)) && sub.hasAttr(
_U(key_max)) ) {
1072 key_min = x_seg.key_min();
1073 key_max = x_seg.key_max();
1076 std::stringstream tree;
1078 throw_print(
"Nested segmentations: Invalid key specification:"+tree.str());
1080 printout(s_debug.segmentation ? ALWAYS : DEBUG,
"Compact",
1081 "++ Segmentation [%s/%s]: Add sub-segmentation %s [%s]",
1082 name.c_str(), type.c_str(),
1087 delete sub_seg.
ptr();
1091 opt->first = segment;
1101 template <>
void Converter<Readout>::operator()(
xml_h e)
const {
1104 std::string name = e.
attr<std::string>(
_U(name));
1105 std::pair<Segmentation,IDDescriptor> opt;
1114 Converter<Segmentation>(description,param,&opt)(seg);
1115 opt.first->setName(name);
1120 if ( opt.first.isValid() ) {
1121 ro.setSegmentation(opt.first);
1123 if ( opt.second.isValid() ) {
1124 ro.setIDDescriptor(opt.second);
1127 printout(s_debug.readout ? ALWAYS : DEBUG,
1128 "Compact",
"++ Converting readout structure: %-16s. %s%s",
1129 ro.name(),
id ?
"ID: " :
"",
id ?
id.text().c_str() :
"");
1131 for(
xml_coll_t colls(e,
_U(hits_collections)); colls; ++colls) {
1132 std::string hits_key;
1133 if ( colls.hasAttr(
_U(
key)) ) hits_key = colls.attr<std::string>(
_U(
key));
1134 for(
xml_coll_t coll(colls,
_U(hits_collection)); coll; ++coll) {
1136 std::string coll_name = c.nameStr();
1137 std::string coll_key = hits_key;
1138 long key_min = 0, key_max = 0;
1140 if ( c.hasAttr(
_U(
key)) ) {
1141 coll_key = c.attr<std::string>(
_U(
key));
1143 if ( c.hasAttr(
_U(key_value)) ) {
1144 key_max = key_min = c.key_value();
1146 else if ( c.hasAttr(
_U(key_min)) && c.hasAttr(
_U(key_max)) ) {
1147 key_min = c.key_min();
1148 key_max = c.key_max();
1151 std::stringstream tree;
1153 throw_print(
"Readout: Invalid specification for multiple hit collections."+tree.str());
1155 printout(s_debug.readout ? ALWAYS : DEBUG,
"Compact",
1156 "++ Readout[%s]: Add hit collection %s [%s] %d-%d",
1157 ro.name(), coll_name.c_str(), coll_key.c_str(), key_min, key_max);
1159 ro->hits.emplace_back(hits);
1165 static long load_readout(
Detector& description,
xml_h element) {
1166 Converter<Readout> converter(description);
1179 template <>
void Converter<LimitSet>::operator()(
xml_h e)
const {
1182 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1183 "++ Converting LimitSet structure: %s.",ls.name());
1185 limit.
name = c.attr<std::string>(
_U(name));
1186 limit.
particles = c.attr<std::string>(
_U(particles));
1187 limit.
content = c.attr<std::string>(
_U(value));
1188 limit.
unit = c.attr<std::string>(
_U(unit));
1191 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1192 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1198 limit.
particles = c.attr<std::string>(
_U(particles));
1199 limit.
content = c.attr<std::string>(
_U(value));
1200 limit.
unit = c.attr<std::string>(
_U(unit));
1203 printout(s_debug.limits ? ALWAYS : DEBUG,
"Compact",
1204 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1217 template <>
void Converter<Property>::operator()(
xml_h e)
const {
1218 std::string name = e.
attr<std::string>(
_U(name));
1221 throw_print(
"Failed to convert properties. No name given!");
1224 if ( prp.find(name) == prp.end() )
1239 template <>
void Converter<CartesianField>::operator()(
xml_h e)
const {
1240 std::string msg =
"updated";
1241 std::string name = e.
attr<std::string>(
_U(name));
1242 std::string type = e.
attr<std::string>(
_U(type));
1244 if ( !field.isValid() ) {
1246 field =
Ref_t(PluginService::Create<NamedObject*>(type, &description, &e));
1247 if ( !field.isValid() ) {
1249 PluginService::Create<NamedObject*>(type, &description, &e);
1250 throw_print(
"Failed to create field object of type "+type +
". "+dbg.
missingFactory(type));
1255 type = field.type();
1259 std::string props_name = c.attr<std::string>(
_U(name));
1260 std::vector<xml_attr_t>a = c.attributes();
1261 if ( prp.find(props_name) == prp.end() ) {
1265 prp[props_name].emplace(
xml_tag_t(c.attr_name(i)).
str(), c.attr<std::string>(i));
1267 if (c.hasAttr(
_U(global)) && c.attr<
bool>(
_U(global))) {
1271 printout(INFO,
"Compact",
"++ Converted field: Successfully %s field %s [%s]", msg.c_str(), name.c_str(), type.c_str());
1287 template <>
void Converter<SensitiveDetector>::operator()(
xml_h element)
const {
1288 std::string name = element.
attr<std::string>(
_U(name));
1305 std::string l = element.
attr<std::string>(limits);
1307 if (!ls.isValid()) {
1308 throw_print(
"Converter<SensitiveDetector>: Request for non-existing limitset:" + l);
1314 std::string r = element.
attr<std::string>(region);
1316 if (!reg.isValid()) {
1317 throw_print(
"Converter<SensitiveDetector>: Request for non-existing region:" + r);
1327 if (ecut && eunit) {
1334 printout(DEBUG,
"Compact",
"SensitiveDetector-update: %-18s %-24s Hits:%-24s Cutoff:%7.3f", sd.
name(),
1341 printout(ERROR,
"Compact",
"++ FAILED to convert sensitive detector: %s: %s", name.c_str(), e.what());
1344 printout(ERROR,
"Compact",
"++ FAILED to convert sensitive detector: %s: %s", name.c_str(),
"UNKNONW Exception");
1348 static void setChildTitles(
const std::pair<std::string, DetElement>& e) {
1351 if (::strlen(e.second->GetTitle()) == 0) {
1352 e.second->SetTitle(parent.
isValid() ? parent.
type().c_str() : e.first.c_str());
1354 for_each(children.begin(), children.end(), setChildTitles);
1357 template <>
void Converter<DetElement>::operator()(
xml_h element)
const {
1358 static const char* req_dets = ::getenv(
"REQUIRED_DETECTORS");
1359 static const char* req_typs = ::getenv(
"REQUIRED_DETECTOR_TYPES");
1360 static const char* ign_dets = ::getenv(
"IGNORED_DETECTORS");
1361 static const char* ign_typs = ::getenv(
"IGNORED_DETECTOR_TYPES");
1362 std::string type = element.
attr<std::string>(
_U(type));
1363 std::string name = element.
attr<std::string>(
_U(name));
1364 std::string name_match =
":" + name +
":";
1365 std::string type_match =
":" + type +
":";
1367 if (req_dets && !strstr(req_dets, name_match.c_str()))
1369 if (req_typs && !strstr(req_typs, type_match.c_str()))
1371 if (ign_dets && strstr(ign_dets, name_match.c_str()))
1373 if (ign_typs && strstr(ign_typs, type_match.c_str()))
1376 if ( attr_ignore ) {
1377 bool ignore_det = element.
attr<
bool>(
_U(ignore));
1379 printout(INFO,
"Compact",
1380 "+++ Do not build subdetector:%s [ignore flag set]",
1386 std::string par_name;
1390 par_name = element.
attr<std::string>(attr_par);
1391 else if ( (elt_par=element.
child(
_U(parent),
false)) )
1392 par_name = elt_par.attr<std::string>(
_U(name));
1393 if ( !par_name.empty() ) {
1400 except(
"Compact",
"Failed to access valid parent detector of %s",name.c_str());
1410 except(
"Compact",
"No Readout structure present for detector:" + name);
1419 DetElement det(
Ref_t(PluginService::Create<NamedObject*>(type, &description, &element, &sens)));
1420 if (
det.isValid()) {
1421 setChildTitles(std::make_pair(name,
det));
1430 printout(
det.isValid() ? INFO : ERROR,
"Compact",
"%s subdetector:%s of type %s %s",
1431 (
det.isValid() ?
"++ Converted" :
"FAILED "), name.c_str(), type.c_str(),
1432 (sd.
isValid() ? (
"[" + sd.
type() +
"]").c_str() :
""));
1434 if (!
det.isValid()) {
1436 PluginService::Create<NamedObject*>(type, &description, &element, &sens);
1437 except(
"Compact",
"Failed to execute subdetector creation plugin. %s", dbg.
missingFactory(type).c_str());
1444 printout(ERROR,
"Compact",
"++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
1448 printout(ERROR,
"Compact",
"++ FAILED to convert subdetector: %s: %s", name.c_str(),
"UNKNONW Exception");
1454 template <>
void Converter<IncludeFile>::operator()(
xml_h element)
const {
1456 if ( s_debug.include_guard) {
1461 xml_h root = doc.root();
1462 if ( s_debug.includes ) {
1463 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
1465 if ( root.
tag() ==
"materials" || root.
tag() ==
"elements" ) {
1471 this->description.
fromXML(doc.uri(), this->description.buildType());
1475 template <>
void Converter<JsonFile>::operator()(
xml_h element)
const {
1477 std::string file = element.
attr<std::string>(
_U(ref));
1478 std::vector<char*> argv{&file[0], &base[0]};
1479 description.
apply(
"DD4hep_JsonProcessor",
int(argv.size()), &argv[0]);
1483 template <>
void Converter<XMLFile>::operator()(
xml_h element)
const {
1484 PrintLevel level = s_debug.includes ? ALWAYS : DEBUG;
1485 std::string fname = element.
attr<std::string>(
_U(ref));
1486 std::size_t idx = fname.find(
"://");
1489 if ( idx == std::string::npos && std::filesystem::exists(fname, ec) ) {
1491 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1494 else if ( idx == std::string::npos ) {
1497 printout(level,
"Compact",
"++ Processing xml document %s.", location.c_str());
1500 else if ( idx > 0 ) {
1502 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1507 printout(level,
"Compact",
"++ Processing xml document %s.", fname.c_str());
1513 template <>
void Converter<World>::operator()(
xml_h element)
const {
1517 Material mat = att ? description.
material(x_world.attr<std::string>(att)) : description.
air();
1522 Solid sol(x_shape.createShape());
1523 world_vol =
Volume(
"world_volume", sol, mat);
1524 printout(INFO,
"Compact",
"++ Created successfully world volume '%s'. shape: %s material:%s.",
1525 world_vol.
name(), sol.type(), mat.
name());
1526 description.
manager().SetTopVolume(world_vol.
ptr());
1530 if ( !world_vol && att ) {
1533 Box sol(
"world_x",
"world_y",
"world_z");
1534 world_vol =
Volume(
"world_volume", sol, mat);
1535 printout(INFO,
"Compact",
"++ Created world volume '%s' as %s (%.2f, %.2f %.2f [cm]) material:%s.",
1536 world_vol.
name(), sol.type(),
1537 sol.x()/dd4hep::cm, sol.y()/dd4hep::cm, sol.z()/dd4hep::cm,
1539 description.
manager().SetTopVolume(world_vol.
ptr());
1541 else if ( !world_vol ) {
1542 except(
"Compact",
"++ Logical error: "
1543 "You cannot configure the world volume before it is created and not giving creation instructions.");
1550 if ( !vis.isValid() ) {
1558 template <>
void Converter<Parallelworld_Volume>::operator()(
xml_h element)
const {
1563 std::string name = element.
attr<std::string>(
_U(name));
1564 std::string path = element.
attr<std::string>(
_U(anchor));
1565 bool conn = element.
attr<
bool>(
_U(connected),
false);
1570 Material mat = parallel.hasAttr(
_U(material))
1571 ? description.
material(parallel.attr<std::string>(
_U(material)))
1572 : description.
air();
1577 if ( !anchor.isValid() ) {
1578 except(
"Parallelworld_Volume",
1579 "++ FAILED Cannot identify the anchor of the tracking volume: '%s'",
1585 Solid sol(shape.createShape());
1586 Volume vol(name, sol, mat);
1591 vol.setVisAttributes(vis);
1599 except(
"Parallelworld_Volume",
1600 "++ FAILED to place the tracking volume inside the anchor '%s'",path.c_str());
1602 if ( name ==
"tracking_volume" ) {
1605 printout(INFO,
"Compact",
"++ Converted successfully parallelworld_volume %s. anchor: %s vis:%s.",
1606 vol.name(), anchor.path().c_str(), vis.
name());
1610 template <>
void Converter<DetElementInclude>::operator()(
xml_h element)
const {
1611 std::string type = element.
hasAttr(
_U(type)) ? element.
attr<std::string>(
_U(type)) : std::string(
"xml");
1612 if ( type ==
"xml" ) {
1614 if ( s_debug.include_guard ) {
1619 if ( s_debug.includes ) {
1620 printout(ALWAYS,
"Compact",
"++ Processing xml document %s.",doc.uri().c_str());
1622 xml_h node = doc.root();
1623 std::string tag = node.
tag();
1624 if ( tag ==
"lccdd" )
1625 Converter<Compact>(this->description)(node);
1626 else if ( tag ==
"define" )
1628 else if ( tag ==
"readout" )
1629 Converter<Readout>(this->description)(node);
1630 else if ( tag ==
"readouts" )
1632 else if ( tag ==
"region" )
1633 Converter<Region>(this->description)(node);
1634 else if ( tag ==
"regions" )
1636 else if ( tag ==
"limits" || tag ==
"limitsets" )
1638 else if ( tag ==
"display" )
1640 else if ( tag ==
"detector" )
1641 Converter<DetElement>(this->description)(node);
1642 else if ( tag ==
"detectors" )
1645 else if ( type ==
"json" ) {
1646 Converter<JsonFile>(this->description)(element);
1648 else if ( type ==
"gdml" ) {
1649 Converter<IncludeFile>(this->description)(element);
1651 else if ( type ==
"include" ) {
1652 Converter<IncludeFile>(this->description)(element);
1654 else if ( type ==
"xml-extended" ) {
1655 Converter<XMLFile>(this->description)(element);
1658 except(
"Compact",
"++ FAILED Invalid file type:%s. This cannot be processed!",type.c_str());
1663 template <>
void Converter<Compact>::operator()(
xml_h element)
const {
1664 static int num_calls = 0;
1669 bool steer_geometry = compact.hasChild(
_U(geometry));
1670 bool open_geometry =
true;
1671 bool close_document =
true;
1672 bool close_geometry =
true;
1673 bool build_reflections =
false;
1678 (Converter<Debug>(description))(
xml_h(compact.child(
_U(
debug))));
1680 if ( steer_geometry ) {
1683 open_geometry = steer.
attr<
bool>(
_U(open));
1685 close_document = steer.
attr<
bool>(
_U(close));
1687 build_reflections = steer.
attr<
bool>(
_U(reflect));
1689 std::string nam = clr.hasAttr(
_U(name)) ? clr.attr<std::string>(
_U(name)) : std::string();
1690 if ( nam.substr(0,6) ==
"elemen" ) {
1691 TGeoElementTable* table = description.
manager().GetElementTable();
1692 table->TGeoElementTable::~TGeoElementTable();
1693 new(table) TGeoElementTable();
1695 table->AddElement(
"VACUUM",
"VACUUM" ,0, 0, 0.0);
1696 printout(INFO,
"Compact",
1697 "++ Cleared default ROOT TGeoElementTable contents. "
1698 "Must now be filled from XML!");
1703 if ( s_debug.materials || s_debug.elements ) {
1704 printout(INFO,
"Compact",
"+++ UNIT System:");
1705 printout(INFO,
"Compact",
"+++ Density: %8.3g Units:%8.3g",
1709 printout(INFO,
"Compact",
"+++ nanosecond: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(nanosecond)),dd4hep::nanosecond);
1710 printout(INFO,
"Compact",
"+++ kilo: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(kilogram)),dd4hep::kilogram);
1712 dd4hep::joule*dd4hep::s*dd4hep::s/(dd4hep::meter*dd4hep::meter));
1714 printout(INFO,
"Compact",
"+++ ampere: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(ampere)),dd4hep::ampere);
1715 printout(INFO,
"Compact",
"+++ degree: %8.3g Units:%8.3g",
xml::_toDouble(
_Unicode(degree)),dd4hep::degree);
1725 (Converter<Header>(description))(
xml_h(compact.child(
_U(
info))));
1738 printout(DEBUG,
"Compact",
"++ Converting visualization attributes...");
1742 printout(DEBUG,
"Compact",
"++ Converting limitset structures...");
1746 printout(DEBUG,
"Compact",
"++ Converting region structures...");
1751 (Converter<World>(description))(world);
1753 if ( open_geometry ) description.
init();
1754 printout(DEBUG,
"Compact",
"++ Converting readout structures...");
1758 printout(DEBUG,
"Compact",
"++ Converting included files with subdetector structures...");
1760 printout(DEBUG,
"Compact",
"++ Converting detector structures...");
1766 xml_coll_t(compact,
_U(sensitive_detectors)).
for_each(
_U(sd), Converter<SensitiveDetector>(description));
1767 xml_coll_t(compact,
_U(parallelworld_volume)).
for_each(Converter<Parallelworld_Volume>(description));
1769 if ( --num_calls == 0 && close_document ) {
1770 ::snprintf(text,
sizeof(text),
"%u",
xml_h(element).checksum(0));
1774 if ( build_reflections ) {
1785 template Converter<Plugin>;
1786 template Converter<Constant>;
1787 template Converter<Material>;
1788 template Converter<Atom>;
1789 template Converter<VisAttr>;
1790 template Converter<Region>;
1791 template Converter<Readout>;
1792 template Converter<Segmentation>;
1793 template Converter<LimitSet>;
1794 template Converter<Property>;
1795 template Converter<CartesianField>;
1796 template Converter<SensitiveDetector>;
1797 template Converter<DetElement>;
1798 template Converter<GdmlFile>;
1799 template Converter<XMLFile>;
1800 template Converter<Header>;
1801 template Converter<DetElementInclude>;
1802 template Converter<Compact>;