Warning, file /DD4hep/DDCore/src/plugins/Compact2Objects.cpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <DD4hep/DetFactoryHelper.h>
0022 #include <DD4hep/DetectorTools.h>
0023 #include <DD4hep/MatrixHelpers.h>
0024 #include <DD4hep/PropertyTable.h>
0025 #include <DD4hep/OpticalSurfaces.h>
0026 #include <DD4hep/OpticalSurfaceManager.h>
0027 #include <DD4hep/IDDescriptor.h>
0028 #include <DD4hep/DD4hepUnits.h>
0029 #include <DD4hep/FieldTypes.h>
0030 #include <DD4hep/Printout.h>
0031 #include <DD4hep/Factories.h>
0032 #include <DD4hep/Path.h>
0033 #include <DD4hep/Plugins.h>
0034 #include <DD4hep/detail/SegmentationsInterna.h>
0035 #include <DD4hep/detail/DetectorInterna.h>
0036 #include <DD4hep/detail/ObjectsInterna.h>
0037
0038 #include <XML/DocumentHandler.h>
0039 #include <XML/Utilities.h>
0040
0041
0042 #include <TGeoManager.h>
0043 #include <TGeoMaterial.h>
0044 #include <TGeoPhysicalConstants.h>
0045 #include <TGDMLMatrix.h>
0046 #include <TMath.h>
0047
0048
0049 #include <filesystem>
0050 #include <iostream>
0051 #include <iomanip>
0052 #include <climits>
0053 #include <set>
0054
0055 using namespace dd4hep;
0056
0057
0058 namespace dd4hep {
0059
0060 class Debug;
0061 class World;
0062 class Isotope;
0063 class Plugin;
0064 class Compact;
0065 class Includes;
0066 class IncludeFile;
0067 class Property;
0068 class XMLFile;
0069 class JsonFile;
0070 class PropertyConstant;
0071 class Parallelworld_Volume;
0072 class DetElementInclude;
0073 class STD_Conditions;
0074
0075
0076 template <> void Converter<Debug>::operator()(xml_h element) const;
0077 template <> void Converter<World>::operator()(xml_h element) const;
0078 template <> void Converter<Plugin>::operator()(xml_h element) const;
0079 template <> void Converter<Constant>::operator()(xml_h element) const;
0080 template <> void Converter<Material>::operator()(xml_h element) const;
0081 template <> void Converter<Atom>::operator()(xml_h element) const;
0082 template <> void Converter<Isotope>::operator()(xml_h element) const;
0083 template <> void Converter<VisAttr>::operator()(xml_h element) const;
0084 template <> void Converter<Region>::operator()(xml_h element) const;
0085 template <> void Converter<Readout>::operator()(xml_h element) const;
0086 template <> void Converter<Segmentation>::operator()(xml_h element) const;
0087 template <> void Converter<LimitSet>::operator()(xml_h element) const;
0088 template <> void Converter<Property>::operator()(xml_h element) const;
0089 template <> void Converter<CartesianField>::operator()(xml_h element) const;
0090 template <> void Converter<SensitiveDetector>::operator()(xml_h element) const;
0091 template <> void Converter<OpticalSurface>::operator()(xml_h element) const;
0092 template <> void Converter<PropertyTable>::operator()(xml_h element) const;
0093 template <> void Converter<PropertyConstant>::operator()(xml_h element) const;
0094 template <> void Converter<DetElement>::operator()(xml_h element) const;
0095 template <> void Converter<STD_Conditions>::operator()(xml_h element) const;
0096 template <> void Converter<IncludeFile>::operator()(xml_h element) const;
0097 template <> void Converter<JsonFile>::operator()(xml_h element) const;
0098 template <> void Converter<XMLFile>::operator()(xml_h element) const;
0099 template <> void Converter<Header>::operator()(xml_h element) const;
0100 template <> void Converter<DetElementInclude>::operator()(xml_h element) const;
0101 template <> void Converter<Parallelworld_Volume>::operator()(xml_h element) const;
0102 template <> void Converter<Compact>::operator()(xml_h element) const;
0103 }
0104
0105 namespace {
0106 static UInt_t unique_mat_id = 0xAFFEFEED;
0107 void throw_print(const std::string& msg) {
0108 printout(ERROR, "Compact", msg.c_str());
0109 throw std::runtime_error(msg);
0110 }
0111 class DebugOptions {
0112 public:
0113 bool readout = false;
0114 bool regions = false;
0115 bool limits = false;
0116 bool visattr = false;
0117 bool isotopes = false;
0118 bool elements = false;
0119 bool materials = false;
0120 bool segmentation = false;
0121 bool constants = false;
0122 bool includes = false;
0123 bool matrix = false;
0124 bool surface = false;
0125 bool include_guard= true;
0126 } s_debug;
0127 }
0128
0129 static Ref_t create_ConstantField(Detector& , xml_h e) {
0130 CartesianField obj;
0131 xml_comp_t field(e), strength(e.child(_U(strength)));
0132 std::string t = e.attr<std::string>(_U(field));
0133 ConstantField* ptr = new ConstantField();
0134 ptr->field_type = ::toupper(t[0]) == 'E' ? CartesianField::ELECTRIC : CartesianField::MAGNETIC;
0135 ptr->direction.SetX(strength.x());
0136 ptr->direction.SetY(strength.y());
0137 ptr->direction.SetZ(strength.z());
0138 obj.assign(ptr, field.nameStr(), field.typeStr());
0139 return obj;
0140 }
0141 DECLARE_XMLELEMENT(ConstantField,create_ConstantField)
0142
0143 static Ref_t create_SolenoidField(Detector& description, xml_h e) {
0144 xml_comp_t c(e);
0145 bool has_inner_radius = c.hasAttr(_U(inner_radius));
0146 bool has_outer_radius = c.hasAttr(_U(outer_radius));
0147
0148 if (!has_inner_radius && !has_outer_radius) {
0149 throw_print("Compact2Objects[ERROR]: For a solenoidal field at least one of the "
0150 " xml attributes inner_radius of outer_radius MUST be set.");
0151 }
0152 CartesianField obj;
0153 SolenoidField* ptr = new SolenoidField();
0154
0155
0156
0157
0158
0159 if (has_inner_radius && has_outer_radius) {
0160 ptr->innerRadius = c.attr<double>(_U(inner_radius));
0161 ptr->outerRadius = c.attr<double>(_U(outer_radius));
0162 }
0163 else if (has_inner_radius) {
0164 Box box = description.worldVolume().solid();
0165 ptr->innerRadius = c.attr<double>(_U(inner_radius));
0166 ptr->outerRadius = box.x();
0167 }
0168 else if (has_outer_radius) {
0169 Box box = description.worldVolume().solid();
0170 ptr->innerRadius = c.attr<double>(_U(outer_radius));
0171 ptr->outerRadius = box.x();
0172 }
0173 if (c.hasAttr(_U(inner_field)))
0174 ptr->innerField = c.attr<double>(_U(inner_field));
0175 if (c.hasAttr(_U(outer_field)))
0176 ptr->outerField = c.attr<double>(_U(outer_field));
0177 if (c.hasAttr(_U(zmax)))
0178 ptr->maxZ = c.attr<double>(_U(zmax));
0179 else
0180 ptr->maxZ = description.constant<double>("world_side");
0181 if (c.hasAttr(_U(zmin)))
0182 ptr->minZ = c.attr<double>(_U(zmin));
0183 else
0184 ptr->minZ = -ptr->maxZ;
0185 ptr->field_type = CartesianField::MAGNETIC;
0186 obj.assign(ptr, c.nameStr(), c.typeStr());
0187 return obj;
0188 }
0189 DECLARE_XMLELEMENT(SolenoidMagnet,create_SolenoidField)
0190
0191 DECLARE_XMLELEMENT(solenoid,create_SolenoidField)
0192
0193 static Ref_t create_DipoleField(Detector& , xml_h e) {
0194 xml_comp_t c(e);
0195 CartesianField obj;
0196 DipoleField* ptr = new DipoleField();
0197 double lunit = c.hasAttr(_U(lunit)) ? c.attr<double>(_U(lunit)) : 1.0;
0198 double funit = c.hasAttr(_U(funit)) ? c.attr<double>(_U(funit)) : 1.0;
0199 double val, mult = funit;
0200
0201 if (c.hasAttr(_U(zmin)))
0202 ptr->zmin = _multiply<double>(c.attr<std::string>(_U(zmin)), lunit);
0203 if (c.hasAttr(_U(zmax)))
0204 ptr->zmax = _multiply<double>(c.attr<std::string>(_U(zmax)), lunit);
0205 if (c.hasAttr(_U(rmax)))
0206 ptr->rmax = _multiply<double>(c.attr<std::string>(_U(rmax)), lunit);
0207 for (xml_coll_t coll(c, _U(dipole_coeff)); coll; ++coll, mult /= lunit) {
0208 xml_dim_t coeff = coll;
0209 if ( coeff.hasAttr(_U(value)) )
0210 val = coll.attr<double>(_U(value)) * mult;
0211 else if ( coeff.hasAttr(_U(coefficient)) )
0212 val = coeff.coefficient() * mult;
0213 else
0214 val = _multiply<double>(coll.text(), mult);
0215 ptr->coefficents.emplace_back(val);
0216 }
0217 ptr->field_type = CartesianField::MAGNETIC;
0218 obj.assign(ptr, c.nameStr(), c.typeStr());
0219 return obj;
0220 }
0221 DECLARE_XMLELEMENT(DipoleMagnet,create_DipoleField)
0222
0223 static Ref_t create_MultipoleField(Detector& description, xml_h e) {
0224 xml_dim_t c(e), child;
0225 CartesianField obj;
0226 MultipoleField* ptr = new MultipoleField();
0227 double lunit = c.hasAttr(_U(lunit)) ? c.attr<double>(_U(lunit)) : 1.0;
0228 double funit = c.hasAttr(_U(funit)) ? c.attr<double>(_U(funit)) : 1.0;
0229 double val, mult = funit, bz = 0.0;
0230 RotationZYX rot;
0231 Position pos;
0232
0233 if (c.hasAttr(_U(Z))) bz = c.Z() * funit;
0234 if ((child = c.child(_U(position), false))) {
0235 pos.SetXYZ(child.x(), child.y(), child.z());
0236 }
0237 if ((child = c.child(_U(rotation), false))) {
0238 rot.SetComponents(child.z(), child.y(), child.x());
0239 }
0240 if ((child = c.child(_U(shape), false))) {
0241 std::string type = child.typeStr();
0242 ptr->volume = xml::createShape(description, type, child);
0243 }
0244 ptr->B_z = bz;
0245 ptr->transform = Transform3D(rot,pos);
0246 for (xml_coll_t coll(c, _U(coefficient)); coll; ++coll, mult /= lunit) {
0247 xml_dim_t coeff = coll;
0248 if ( coll.hasAttr(_U(value)) )
0249 val = coll.attr<double>(_U(value)) * mult;
0250 else
0251 val = coeff.coefficient(0.0) * mult;
0252 ptr->coefficents.emplace_back(val);
0253 val = coeff.skew(0.0) * mult;
0254 ptr->skews.emplace_back(val);
0255 }
0256 ptr->field_type = CartesianField::MAGNETIC;
0257 obj.assign(ptr, c.nameStr(), c.typeStr());
0258 return obj;
0259 }
0260 DECLARE_XMLELEMENT(MultipoleMagnet,create_MultipoleField)
0261
0262 static long load_Compact(Detector& description, xml_h element) {
0263 Converter<Compact>converter(description);
0264 converter(element);
0265 return 1;
0266 }
0267 DECLARE_XML_DOC_READER(lccdd,load_Compact)
0268 DECLARE_XML_DOC_READER(compact,load_Compact)
0269
0270
0271
0272 class ProcessedFilesSet: public std::set<std::string> {};
0273
0274
0275 bool check_process_file(Detector& description, std::string filename) {
0276
0277
0278
0279 auto already_processed = description.extension<ProcessedFilesSet>( false );
0280 if ( !already_processed ) {
0281 already_processed = new ProcessedFilesSet( );
0282 description.addExtension<ProcessedFilesSet>(already_processed );
0283 }
0284 std::string npath = dd4hep::Path{filename}.normalize();
0285 if (already_processed->find(npath) != already_processed->end() ) {
0286 printout(INFO, "Compact","++ Already processed xml document %s.", npath.c_str());
0287 return true;
0288 }
0289 already_processed->insert(npath);
0290 return false;
0291 }
0292
0293
0294
0295 template <> void Converter<Debug>::operator()(xml_h e) const {
0296 for (xml_coll_t coll(e, _U(type)); coll; ++coll) {
0297 int val = coll.attr<int>(_U(value));
0298 std::string nam = coll.attr<std::string>(_U(name));
0299 if ( nam.substr(0,6) == "isotop" ) s_debug.isotopes = (0 != val);
0300 else if ( nam.substr(0,6) == "elemen" ) s_debug.elements = (0 != val);
0301 else if ( nam.substr(0,6) == "materi" ) s_debug.materials = (0 != val);
0302 else if ( nam.substr(0,6) == "visatt" ) s_debug.visattr = (0 != val);
0303 else if ( nam.substr(0,6) == "region" ) s_debug.regions = (0 != val);
0304 else if ( nam.substr(0,6) == "readou" ) s_debug.readout = (0 != val);
0305 else if ( nam.substr(0,6) == "limits" ) s_debug.limits = (0 != val);
0306 else if ( nam.substr(0,6) == "segmen" ) s_debug.segmentation = (0 != val);
0307 else if ( nam.substr(0,6) == "consta" ) s_debug.constants = (0 != val);
0308 else if ( nam.substr(0,6) == "define" ) s_debug.constants = (0 != val);
0309 else if ( nam.substr(0,6) == "includ" ) s_debug.includes = (0 != val);
0310 else if ( nam.substr(0,6) == "matrix" ) s_debug.matrix = (0 != val);
0311 else if ( nam.substr(0,6) == "surfac" ) s_debug.surface = (0 != val);
0312 else if ( nam.substr(0,6) == "incgua" ) s_debug.include_guard= (0 != val);
0313
0314 }
0315 }
0316
0317
0318
0319
0320
0321 template <> void Converter<Plugin>::operator()(xml_h e) const {
0322 xml_comp_t plugin(e);
0323 std::string name = plugin.nameStr();
0324 std::string type = "default";
0325
0326 if ( xml_attr_t typ_attr = e.attr_nothrow(_U(type)) ) {
0327 type = e.attr<std::string>(typ_attr);
0328 }
0329 if ( type == "default" ) {
0330 std::vector<char*> argv;
0331 std::vector<std::string> arguments;
0332 for (xml_coll_t coll(e, _U(arg)); coll; ++coll) {
0333 std::string val = coll.attr<std::string>(_U(value));
0334 arguments.emplace_back(val);
0335 }
0336 for (xml_coll_t coll(e, _U(argument)); coll; ++coll) {
0337 std::string val = coll.attr<std::string>(_U(value));
0338 arguments.emplace_back(val);
0339 }
0340 for(std::vector<std::string>::iterator i=arguments.begin(); i!=arguments.end(); ++i)
0341 argv.emplace_back(&((*i)[0]));
0342 description.apply(name.c_str(),int(argv.size()), &argv[0]);
0343 return;
0344 }
0345
0346 long result = PluginService::Create<long>(name, &description, &e);
0347 if (0 == result) {
0348 PluginDebug dbg;
0349 result = PluginService::Create<long>(name, &description, &e);
0350 if ( 0 == result ) {
0351 except("Compact","++ Failed to locate plugin %s - no factory: %s",
0352 name.c_str(), dbg.missingFactory(name).c_str());
0353 }
0354 }
0355 result = *(long*) result;
0356 if (result != 1) {
0357 except("Compact","++ Failed to execute plugin %s", name.c_str());
0358 }
0359 }
0360
0361
0362
0363
0364
0365 template <> void Converter<Constant>::operator()(xml_h e) const {
0366 if ( e.tag() != "include" ) {
0367 xml_ref_t constant(e);
0368 std::string nam = constant.attr<std::string>(_U(name));
0369 std::string val = constant.attr<std::string>(_U(value));
0370 std::string typ = constant.hasAttr(_U(type)) ? constant.attr<std::string>(_U(type)) : "number";
0371 Constant c(nam, val, typ);
0372 _toDictionary(nam, val, typ);
0373 description.addConstant(c);
0374 if ( s_debug.constants ) {
0375 printout(ALWAYS, "Compact",
0376 "++ Converting constant %-16s = %-32s [%s]", nam.c_str(), val.c_str(), typ.c_str());
0377 }
0378 return;
0379 }
0380 xml::DocumentHolder doc(xml::DocumentHandler().load(e, e.attr_value(_U(ref))));
0381 if ( s_debug.includes ) {
0382 printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
0383 }
0384 xml_h root = doc.root();
0385 xml_coll_t(root, _U(define)).for_each(_U(constant), Converter<Constant>(description));
0386 xml_coll_t(root, _U(constant)).for_each(Converter<Constant>(description));
0387 }
0388
0389
0390
0391
0392
0393 template <> void Converter<Header>::operator()(xml_h e) const {
0394 xml_comp_t c(e);
0395 Header h(e.attr<std::string>(_U(name)), e.attr<std::string>(_U(title), "Undefined"));
0396 h.setUrl(e.attr<std::string>(_U(url), "Undefined"));
0397 h.setAuthor(e.attr<std::string>(_U(author), "Undefined"));
0398 h.setStatus(e.attr<std::string>(_U(status), "development"));
0399 h.setVersion(e.attr<std::string>(_U(version), "Undefined"));
0400 h.setComment(e.hasChild(_U(comment)) ? e.child(_U(comment)).text() : "No Comment");
0401 description.setHeader(h);
0402 }
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 template <> void Converter<Material>::operator()(xml_h e) const {
0421 xml_ref_t x_mat(e);
0422 TGeoManager& mgr = description.manager();
0423 xml_tag_t mname = x_mat.name();
0424 const char* matname = mname.c_str();
0425 TGeoElementTable* table = mgr.GetElementTable();
0426 TGeoMaterial* mat = mgr.GetMaterial(matname);
0427 TGeoMixture* mix = dynamic_cast<TGeoMixture*>(mat);
0428 xml_coll_t fractions (x_mat, _U(fraction));
0429 xml_coll_t composites(x_mat, _U(composite));
0430
0431 if (0 == mat) {
0432 TGeoMaterial* comp_mat;
0433 TGeoElement* comp_elt;
0434 xml_h density = x_mat.child(_U(D), false);
0435 double dens_val = density.ptr() ? density.attr<double>(_U(value)) : 0.0;
0436 double dens_unit = 1.0;
0437
0438 if ( !density.ptr() ) {
0439 throw_print("Compact2Objects[ERROR]: material without density tag ( <D unit=\"g/cm3\" value=\"..\"/> ) provided: "
0440 + std::string( matname ) ) ;
0441 }
0442 if ( density.hasAttr(_U(unit)) ) {
0443 dens_unit = density.attr<double>(_U(unit))/xml::_toDouble(_Unicode(gram/cm3));
0444 }
0445 if ( dens_unit != 1.0 ) {
0446 dens_val *= dens_unit;
0447 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact","Density unit: %.3f [%s] raw: %.3f normalized: %.3f ",
0448 dens_unit, density.attr<std::string>(_U(unit)).c_str(), dens_val, (dens_val*dens_unit));
0449 }
0450 mat = mix = new TGeoMixture(matname, composites.size(), dens_val);
0451 std::size_t ifrac = 0;
0452 std::vector<double> composite_fractions;
0453 double composite_fractions_total = 0.0;
0454 for (composites.reset(); composites; ++composites) {
0455 std::string nam = composites.attr<std::string>(_U(ref));
0456 double fraction = composites.attr<double>(_U(n));
0457 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
0458 fraction *= comp_mat->GetA();
0459 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
0460 fraction *= comp_elt->A();
0461 else
0462 except("Compact2Objects","Converting material: %s Element missing: %s",mname.c_str(),nam.c_str());
0463 composite_fractions_total += fraction;
0464 composite_fractions.emplace_back(fraction);
0465 }
0466 for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) {
0467 std::string nam = composites.attr<std::string>(_U(ref));
0468 double fraction = composite_fractions[ifrac]/composite_fractions_total;
0469 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
0470 mix->AddElement(comp_mat, fraction);
0471 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
0472 mix->AddElement(comp_elt, fraction);
0473 }
0474 for (fractions.reset(); fractions; ++fractions) {
0475 std::string nam = fractions.attr<std::string>(_U(ref));
0476 double fraction = fractions.attr<double>(_U(n));
0477 if (0 != (comp_mat = mgr.GetMaterial(nam.c_str())))
0478 mix->AddElement(comp_mat, fraction);
0479 else if (0 != (comp_elt = table->FindElement(nam.c_str())))
0480 mix->AddElement(comp_elt, fraction);
0481 else
0482 throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " Element missing: " + nam);
0483 }
0484 xml_h temperature = x_mat.child(_U(T), false);
0485 double temp_val = description.stdConditions().temperature;
0486 if ( temperature.ptr() ) {
0487 double temp_unit = _toDouble("kelvin");
0488 if ( temperature.hasAttr(_U(unit)) )
0489 temp_unit = temperature.attr<double>(_U(unit));
0490 temp_val = temperature.attr<double>(_U(value)) * temp_unit;
0491 }
0492 xml_h pressure = x_mat.child(_U(P), false);
0493 double pressure_val = description.stdConditions().pressure;
0494 if ( pressure.ptr() ) {
0495 double pressure_unit = _toDouble("pascal");
0496 if ( pressure.hasAttr(_U(unit)) )
0497 pressure_unit = pressure.attr<double>(_U(unit));
0498 pressure_val = pressure.attr<double>(_U(value)) * pressure_unit;
0499 }
0500 #if 0
0501 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
0502 "++ ROOT raw temperature and pressure: %.3g %.3g",
0503 mat->GetTemperature(),mat->GetPressure());
0504 #endif
0505 mat->SetTemperature(temp_val);
0506 mat->SetPressure(pressure_val);
0507 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
0508 "++ Converting material %-16s Density: %9.7g Temperature:%9.7g [K] Pressure:%9.7g [hPa].",
0509 matname, dens_val, temp_val/dd4hep::kelvin, pressure_val/dd4hep::pascal/100.0);
0510
0511 mix->SetRadLen(0e0);
0512 mix->ComputeDerivedQuantities();
0513
0514
0515 for(xml_coll_t properties(x_mat, _U(constant)); properties; ++properties) {
0516 xml_elt_t p = properties;
0517 if ( p.hasAttr(_U(ref)) ) {
0518 bool err = kFALSE;
0519 std::string ref = p.attr<std::string>(_U(ref));
0520 mgr.GetProperty(ref.c_str(), &err);
0521 if ( err == kFALSE ) {
0522 std::string prop_nam = p.attr<std::string>(_U(name));
0523 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
0524 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
0525 "++ material %-16s add constant property: %s -> %s.",
0526 mat->GetName(), prop_nam.c_str(), ref.c_str());
0527 continue;
0528 }
0529
0530 throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " ConstProperty missing in TGeoManager: " + ref);
0531 }
0532 else if ( p.hasAttr(_U(value)) ) {
0533 std::stringstream str;
0534 std::string ref, prop_nam = p.attr<std::string>(_U(name));
0535 str << prop_nam << "_" << (void*)mat;
0536 ref = str.str();
0537 mgr.AddProperty(ref.c_str(), p.attr<double>(_U(value)));
0538 mat->AddConstProperty(prop_nam.c_str(), ref.c_str());
0539 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
0540 "++ material %-16s add constant property: %s -> %s.",
0541 mat->GetName(), prop_nam.c_str(), ref.c_str());
0542 }
0543 else if ( p.hasAttr(_U(option)) ) {
0544 std::string prop_nam = p.attr<std::string>(_U(name));
0545 std::string prop_typ = p.attr<std::string>(_U(option));
0546 mat->AddConstProperty(prop_nam.c_str(), prop_typ.c_str());
0547 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
0548 "++ material %-16s add constant property: %s -> %s.",
0549 mat->GetName(), prop_nam.c_str(), prop_typ.c_str());
0550 }
0551 }
0552
0553 for(xml_coll_t properties(x_mat, _U(property)); properties; ++properties) {
0554 xml_elt_t p = properties;
0555 if ( p.hasAttr(_U(ref)) ) {
0556 std::string ref = p.attr<std::string>(_U(ref));
0557 TGDMLMatrix* gdmlMat = mgr.GetGDMLMatrix(ref.c_str());
0558 if ( gdmlMat ) {
0559 std::string prop_nam = p.attr<std::string>(_U(name));
0560 mat->AddProperty(prop_nam.c_str(), ref.c_str());
0561 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
0562 "++ material %-16s add property: %s -> %s.",
0563 mat->GetName(), prop_nam.c_str(), ref.c_str());
0564 continue;
0565 }
0566
0567 throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " Property missing: " + ref);
0568 }
0569 }
0570 }
0571 TGeoMedium* medium = mgr.GetMedium(matname);
0572 if (0 == medium) {
0573 --unique_mat_id;
0574 medium = new TGeoMedium(matname, unique_mat_id, mat);
0575 medium->SetTitle("material");
0576 medium->SetUniqueID(unique_mat_id);
0577 }
0578
0579
0580 if (x_mat.hasAttr(_U(formula))) {
0581 std::string form = x_mat.attr<std::string>(_U(formula));
0582 if (form != matname) {
0583 medium = mgr.GetMedium(form.c_str());
0584 if (0 == medium) {
0585 --unique_mat_id;
0586 medium = new TGeoMedium(form.c_str(), unique_mat_id, mat);
0587 medium->SetTitle("material");
0588 medium->SetUniqueID(unique_mat_id);
0589 }
0590 }
0591 }
0592 }
0593
0594
0595
0596
0597
0598
0599
0600 template <> void Converter<Isotope>::operator()(xml_h e) const {
0601 xml_dim_t isotope(e);
0602 TGeoManager& mgr = description.manager();
0603 std::string nam = isotope.nameStr();
0604 TGeoElementTable* tab = mgr.GetElementTable();
0605 TGeoIsotope* iso = tab->FindIsotope(nam.c_str());
0606
0607
0608 if ( !iso ) {
0609 xml_ref_t atom(isotope.child(_U(atom)));
0610 std::string unit = atom.attr<std::string>(_U(unit));
0611 double value = atom.attr<double>(_U(value));
0612 double a = value * _multiply<double>(unit,"mol/g");
0613 int n = isotope.attr<int>(_U(N));
0614 int z = isotope.attr<int>(_U(Z));
0615 iso = new TGeoIsotope(nam.c_str(), z, n, a);
0616 printout(s_debug.isotopes ? ALWAYS : DEBUG, "Compact",
0617 "++ Converting isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol]",
0618 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
0619 }
0620 else {
0621 printout(s_debug.isotopes ? WARNING : DEBUG, "Compact",
0622 "++ Isotope %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
0623 iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
0624 }
0625 }
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641 template <> void Converter<Atom>::operator()(xml_h e) const {
0642 xml_ref_t elem(e);
0643 xml_tag_t name = elem.name();
0644 TGeoManager& mgr = description.manager();
0645 TGeoElementTable* tab = mgr.GetElementTable();
0646 TGeoElement* elt = tab->FindElement(name.c_str());
0647 if ( !elt ) {
0648 if ( elem.hasChild(_U(atom)) ) {
0649 xml_ref_t atom(elem.child(_U(atom)));
0650 std::string formula = elem.attr<std::string>(_U(formula));
0651 double value = atom.attr<double>(_U(value));
0652 std::string unit = atom.attr<std::string>(_U(unit));
0653 int z = elem.attr<int>(_U(Z));
0654 double a = value*_multiply<double>(unit,"mol/g");
0655 printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
0656 "++ Converting element %-16s [%-3s] Z:%3d A:%8.4f [g/mol]",
0657 name.c_str(), formula.c_str(), z, a);
0658 tab->AddElement(name.c_str(), formula.c_str(), z, a);
0659 }
0660 else {
0661 int num_isotopes = 0;
0662 std::string formula = elem.hasAttr(_U(formula)) ? elem.attr<std::string>(_U(formula)) : name.str();
0663 for( xml_coll_t i(elem,_U(fraction)); i; ++i)
0664 ++num_isotopes;
0665 elt = new TGeoElement(name.c_str(), formula.c_str(), num_isotopes);
0666 tab->AddElement(elt);
0667 for( xml_coll_t i(elem,_U(fraction)); i; ++i) {
0668 double frac = i.attr<double>(_U(n));
0669 std::string ref = i.attr<std::string>(_U(ref));
0670 TGeoIsotope* iso = tab->FindIsotope(ref.c_str());
0671 if ( !iso ) {
0672 except("Compact","Element %s cannot be constructed. Isotope '%s' (fraction: %.3f) missing!",
0673 name.c_str(), ref.c_str(), frac);
0674 }
0675 printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
0676 "++ Converting element %-16s Add isotope: %-16s fraction:%.4f.",
0677 name.c_str(), ref.c_str(), frac);
0678 elt->AddIsotope(iso, frac);
0679 }
0680 printout(s_debug.elements ? ALWAYS : DEBUG, "Compact",
0681 "++ Converted element %-16s [%-3s] Z:%3d A:%8.4f [g/mol] with %d isotopes.",
0682 name.c_str(), formula.c_str(), elt->Z(), elt->A(), num_isotopes);
0683 }
0684 elt = tab->FindElement(name.c_str());
0685 if (!elt) {
0686 throw_print("Failed to properly insert the Element:"+name+" into the element table!");
0687 }
0688 }
0689 else {
0690 printout(s_debug.elements ? WARNING : DEBUG, "Compact",
0691 "++ Element %-16s Z:%3d N:%3d A:%8.4f [g/mol] ALREADY defined. [Ignore definition]",
0692 elt->GetName(), elt->Z(), elt->N(), elt->A());
0693 }
0694 }
0695
0696
0697
0698
0699
0700
0701
0702
0703 template <> void Converter<STD_Conditions>::operator()(xml_h e) const {
0704 xml_dim_t cond(e);
0705
0706 if ( cond.ptr() ) {
0707 if ( cond.hasAttr(_U(type)) ) {
0708 description.setStdConditions(cond.typeStr());
0709 }
0710 xml_h temperature = cond.child(_U(T), false);
0711 double temp_val = description.stdConditions().temperature;
0712 if ( temperature.ptr() ) {
0713 double temp_unit = _toDouble("kelvin");
0714 if ( temperature.hasAttr(_U(unit)) )
0715 temp_unit = temperature.attr<double>(_U(unit));
0716 temp_val = temperature.attr<double>(_U(value)) * temp_unit;
0717 }
0718 xml_h pressure = cond.child(_U(P), false);
0719 double pressure_val = description.stdConditions().pressure;
0720 if ( pressure.ptr() ) {
0721 double pressure_unit = _toDouble("pascal");
0722 if ( pressure.hasAttr(_U(unit)) )
0723 pressure_unit = pressure.attr<double>(_U(unit));
0724 pressure_val = pressure.attr<double>(_U(value)) * pressure_unit;
0725 }
0726 description.setStdConditions(temp_val, pressure_val);
0727 printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
0728 "+++ Material standard conditions: Temperature: %.3f Kelvin Pressure: %.3f hPa",
0729 temp_val/_toDouble("kelvin"), pressure_val/_toDouble("hPa"));
0730 }
0731 }
0732
0733
0734
0735
0736
0737 template <> void Converter<OpticalSurface>::operator()(xml_h element) const {
0738 xml_elt_t e = element;
0739 TGeoManager& mgr = description.manager();
0740 std::string sname = e.attr<std::string>(_U(name));
0741 std::string ref, pname;
0742
0743
0744 OpticalSurface::EModel model = OpticalSurface::Model::kMglisur;
0745 OpticalSurface::EFinish finish = OpticalSurface::Finish::kFpolished;
0746 OpticalSurface::EType type = OpticalSurface::Type::kTdielectric_metal;
0747 Double_t value = 1.0;
0748 if ( e.hasAttr(_U(type)) ) type = OpticalSurface::stringToType(e.attr<std::string>(_U(type)));
0749 if ( e.hasAttr(_U(model)) ) model = OpticalSurface::stringToModel(e.attr<std::string>(_U(model)));
0750 if ( e.hasAttr(_U(finish)) ) finish = OpticalSurface::stringToFinish(e.attr<std::string>(_U(finish)));
0751 if ( e.hasAttr(_U(value)) ) value = e.attr<double>(_U(value));
0752 OpticalSurface surf(description, sname, model, finish, type, value);
0753 if ( s_debug.surface ) {
0754 printout(ALWAYS,"Compact","+++ Reading optical surface %s Typ:%d model:%d finish:%d value: %.3f",
0755 sname.c_str(), int(type), int(model), int(finish), value);
0756 }
0757 for (xml_coll_t props(e, _U(property)); props; ++props) {
0758 pname = props.attr<std::string>(_U(name));
0759 if ( props.hasAttr(_U(ref)) ) {
0760 bool err = kFALSE;
0761 ref = props.attr<std::string>(_U(ref));
0762 mgr.GetProperty(ref.c_str(), &err);
0763 surf->AddProperty(pname.c_str(), ref.c_str());
0764 if ( s_debug.surface ) {
0765 printout(ALWAYS,"Compact","+++ \t\t Property: %s -> %s", pname.c_str(), ref.c_str());
0766 }
0767 continue;
0768 }
0769 std::size_t cols = props.attr<long>(_U(coldim));
0770 xml_attr_t opt = props.attr_nothrow(_U(option));
0771 std::stringstream str(props.attr<std::string>(_U(values))), str_nam;
0772 std::string val;
0773 std::vector<double> values;
0774 while ( !str.eof() ) {
0775 val = "";
0776 str >> val;
0777 if ( val.empty() && !str.good() ) break;
0778 values.emplace_back(_toDouble(val));
0779 }
0780
0781 TGDMLMatrix* table = new TGDMLMatrix("",values.size()/cols, cols);
0782 if ( opt ) {
0783 std::string tit = e.attr<std::string>(opt);
0784 str_nam << tit << "|";
0785 }
0786 str_nam << pname << "__" << (void*)table;
0787 table->SetName(str_nam.str().c_str());
0788 table->SetTitle(pname.c_str());
0789 for (std::size_t i=0, n=values.size(); i<n; ++i)
0790 table->Set(i/cols, i%cols, values[i]);
0791 surf->AddProperty(pname.c_str(), table->GetName());
0792 description.manager().AddGDMLMatrix(table);
0793 }
0794 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
0795
0796
0797 for(xml_coll_t properties(e, _U(constant)); properties; ++properties) {
0798 xml_elt_t p = properties;
0799 pname = p.attr<std::string>(_U(name));
0800 if ( p.hasAttr(_U(ref)) ) {
0801 bool err = kFALSE;
0802 ref = p.attr<std::string>(_U(ref));
0803 mgr.GetProperty(ref.c_str(), &err);
0804 if ( err == kFALSE ) {
0805 surf->AddConstProperty(pname.c_str(), ref.c_str());
0806 printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
0807 "++ surface %-16s add constant property: %s -> %s.",
0808 surf->GetName(), pname.c_str(), ref.c_str());
0809 continue;
0810 }
0811
0812 throw_print("Compact2Objects[ERROR]: Converting surface: " + sname +
0813 " ConstProperty missing in TGeoManager: " + ref);
0814 }
0815 else if ( p.hasAttr(_U(value)) ) {
0816 std::stringstream str;
0817 str << pname << "_" << (void*)surf.ptr();
0818 ref = str.str();
0819 mgr.AddProperty(ref.c_str(), p.attr<double>(_U(value)));
0820 surf->AddConstProperty(pname.c_str(), ref.c_str());
0821 printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
0822 "++ surface %-16s add constant property: %s -> %s.",
0823 surf->GetName(), pname.c_str(), ref.c_str());
0824 }
0825 else if ( p.hasAttr(_U(option)) ) {
0826 std::string ptyp = p.attr<std::string>(_U(option));
0827 surf->AddConstProperty(pname.c_str(), ptyp.c_str());
0828 printout(s_debug.surface ? ALWAYS : DEBUG, "Compact",
0829 "++ surface %-16s add constant property: %s -> %s.",
0830 surf->GetName(), pname.c_str(), ptyp.c_str());
0831 }
0832 }
0833 #endif
0834 }
0835
0836
0837
0838
0839
0840
0841 template <> void Converter<PropertyConstant>::operator()(xml_h e) const {
0842 double value = e.attr<double>(_U(value));
0843 std::string name = e.attr<std::string>(_U(name));
0844 description.manager().AddProperty(name.c_str(), value);
0845 if ( s_debug.matrix ) {
0846 printout(ALWAYS,"Compact","+++ Reading property %s : %f",name.c_str(), value);
0847 }
0848 #if 0
0849 xml_attr_t opt = e.attr_nothrow(_U(title));
0850 if ( opt ) {
0851 std::string val = e.attr<std::string>(opt);
0852 TNamed* nam = description.manager().GetProperty(name.c_str());
0853 if ( !nam ) {
0854 except("Compact","Failed to access just added manager property: %s",name.c_str());
0855 }
0856 nam->SetTitle(val.c_str());
0857 }
0858 #endif
0859 }
0860
0861
0862
0863
0864
0865
0866 template <> void Converter<PropertyTable>::operator()(xml_h e) const {
0867 std::vector<double> vals;
0868 std::size_t cols = e.attr<unsigned long>(_U(coldim));
0869 std::stringstream str(e.attr<std::string>(_U(values)));
0870
0871 if ( s_debug.matrix ) {
0872 printout(ALWAYS,"Compact","+++ Reading property table %s with %d columns.",
0873 e.attr<std::string>(_U(name)).c_str(), cols);
0874 }
0875 vals.reserve(1024);
0876 while ( !str.eof() ) {
0877 std::string item;
0878 str >> item;
0879 if ( item.empty() && !str.good() ) break;
0880 vals.emplace_back(_toDouble(item));
0881 if ( s_debug.matrix ) {
0882 std::cout << " state:" << (str.good() ? "OK " : "BAD") << " '" << item << "'";
0883 if ( 0 == (vals.size()%cols) ) std::cout << std::endl;
0884 }
0885 }
0886 if ( s_debug.matrix ) {
0887 std::cout << std::endl;
0888 }
0889
0890 xml_attr_t opt = e.attr_nothrow(_U(option));
0891 PropertyTable tab(description,
0892 e.attr<std::string>(_U(name)),
0893 opt ? e.attr<std::string>(opt).c_str() : "",
0894 vals.size()/cols, cols);
0895 for( std::size_t i=0, n=vals.size(); i < n; ++i )
0896 tab->Set(i/cols, i%cols, vals[i]);
0897
0898 }
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 template <> void Converter<VisAttr>::operator()(xml_h e) const {
0915 VisAttr attr(e.attr<std::string>(_U(name)));
0916 float alpha = 1.0;
0917 float red = 1.0;
0918 float green = 1.0;
0919 float blue = 1.0;
0920 bool use_ref = false;
0921 if(e.hasAttr(_U(ref))) {
0922 use_ref = true;
0923 auto refName = e.attr<std::string>(_U(ref));
0924 const auto refAttr = description.visAttributes(refName);
0925 if(!refAttr.isValid() ) {
0926 except("Compact","+++ Reference VisAttr %s does not exist", refName.c_str());
0927 }
0928
0929
0930 refAttr.argb(alpha,red,green,blue);
0931 attr.setColor(alpha,red,green,blue);
0932 attr.setDrawingStyle( refAttr.drawingStyle());
0933 attr.setLineStyle( refAttr.lineStyle());
0934 attr.setShowDaughters(refAttr.showDaughters());
0935 attr.setVisible(refAttr.visible());
0936 }
0937 xml_dim_t dim(e);
0938 alpha = dim.alpha(alpha);
0939 red = dim.r(red );
0940 green = dim.g(green);
0941 blue = dim.b(blue );
0942
0943 printout(s_debug.visattr ? ALWAYS : DEBUG, "Compact",
0944 "++ Converting VisAttr structure: %-16s. Alpha=%.2f R=%.3f G=%.3f B=%.3f",
0945 attr.name(), alpha, red, green, blue);
0946 attr.setColor(alpha, red, green, blue);
0947 if (e.hasAttr(_U(visible)))
0948 attr.setVisible(e.attr<bool>(_U(visible)));
0949 if (e.hasAttr(_U(lineStyle))) {
0950 std::string ls = e.attr<std::string>(_U(lineStyle));
0951 if (ls == "unbroken")
0952 attr.setLineStyle(VisAttr::SOLID);
0953 else if (ls == "broken")
0954 attr.setLineStyle(VisAttr::DASHED);
0955 }
0956 else {
0957 if (!use_ref)
0958 attr.setLineStyle(VisAttr::SOLID);
0959 }
0960 if (e.hasAttr(_U(drawingStyle))) {
0961 std::string ds = e.attr<std::string>(_U(drawingStyle));
0962 if (ds == "wireframe")
0963 attr.setDrawingStyle(VisAttr::WIREFRAME);
0964 else if (ds == "solid")
0965 attr.setDrawingStyle(VisAttr::SOLID);
0966 }
0967 else {
0968 if (!use_ref)
0969 attr.setDrawingStyle(VisAttr::SOLID);
0970 }
0971 if (e.hasAttr(_U(showDaughters)))
0972 attr.setShowDaughters(e.attr<bool>(_U(showDaughters)));
0973 else {
0974 if (!use_ref)
0975 attr.setShowDaughters(true);
0976 }
0977 description.addVisAttribute(attr);
0978 }
0979
0980
0981
0982
0983 template <> void Converter<Region>::operator()(xml_h elt) const {
0984 xml_dim_t e = elt;
0985 Region region(e.nameStr());
0986 auto& limits = region.limits();
0987 xml_attr_t cut = elt.attr_nothrow(_U(cut));
0988 xml_attr_t threshold = elt.attr_nothrow(_U(threshold));
0989 xml_attr_t store_secondaries = elt.attr_nothrow(_U(store_secondaries));
0990 double ene = e.eunit(1.0), len = e.lunit(1.0);
0991
0992 printout(s_debug.regions ? ALWAYS : DEBUG, "Compact",
0993 "++ Converting region structure: %s.",region.name());
0994 if ( cut ) {
0995 region.setCut(elt.attr<double>(cut)*len);
0996 }
0997 if ( threshold ) {
0998 region.setThreshold(elt.attr<double>(threshold)*ene);
0999 }
1000 if ( store_secondaries ) {
1001 region.setStoreSecondaries(elt.attr<bool>(store_secondaries));
1002 }
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)));
1005 description.addRegion(region);
1006 }
1007
1008
1009
1010
1011
1012
1013
1014
1015
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> >();
1020
1021 const BitFieldCoder* bitfield = &opt->second->decoder;
1022 Segmentation segment(type, name, bitfield);
1023 if ( segment.isValid() ) {
1024 const DDSegmentation::Parameters& pars = segment.parameters();
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 ) {
1028 xml::Strng_t pNam(p->name());
1029 if ( seg.hasAttr(pNam) ) {
1030 std::string pType = p->type();
1031 if ( pType.compare("int") == 0 ) {
1032 typedef DDSegmentation::TypedSegmentationParameter<int> ParInt;
1033 static_cast<ParInt*>(p)->setTypedValue(seg.attr<int>(pNam));
1034 } else if ( pType.compare("float") == 0 ) {
1035 typedef DDSegmentation::TypedSegmentationParameter<float> ParFloat;
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());
1042 std::vector<std::string> elts = DDSegmentation::splitString(par);
1043 for (const std::string& spar : elts ) {
1044 if ( spar.empty() ) continue;
1045 valueVector.emplace_back(_toDouble(spar));
1046 }
1047 typedef DDSegmentation::TypedSegmentationParameter< std::vector<double> > ParDouVec;
1048 static_cast<ParDouVec*>(p)->setTypedValue(valueVector);
1049 } else if ( pType.compare("double" ) == 0) {
1050 typedef DDSegmentation::TypedSegmentationParameter<double>ParDouble;
1051 static_cast<ParDouble*>(p)->setTypedValue(seg.attr<double>(pNam));
1052 } else {
1053 p->setValue(seg.attr<std::string>(pNam));
1054 }
1055 } else if (not p->isOptional()) {
1056 throw_print("FAILED to create segmentation: " + type +
1057 ". Missing mandatory parameter: " + p->name() + "!");
1058 }
1059 }
1060 long key_min = 0, key_max = 0;
1061 DDSegmentation::Segmentation* base = segment->segmentation;
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);
1065 sub_conv(sub);
1066 if ( sub_object.first.isValid() ) {
1067 Segmentation sub_seg = sub_object.first;
1068 xml_dim_t x_seg(sub);
1069 if ( sub.hasAttr(_U(key_value)) ) {
1070 key_min = key_max = x_seg.key_value();
1071 }
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();
1075 }
1076 else {
1077 std::stringstream tree;
1078 xml::dump_tree(sub,tree);
1079 throw_print("Nested segmentations: Invalid key specification:"+tree.str());
1080 }
1081 printout(s_debug.segmentation ? ALWAYS : DEBUG,"Compact",
1082 "++ Segmentation [%s/%s]: Add sub-segmentation %s [%s]",
1083 name.c_str(), type.c_str(),
1084 sub_seg->segmentation->name().c_str(),
1085 sub_seg->segmentation->type().c_str());
1086 base->addSubsegmentation(key_min, key_max, sub_seg->segmentation);
1087 sub_seg->segmentation = 0;
1088 delete sub_seg.ptr();
1089 }
1090 }
1091 }
1092 opt->first = segment;
1093 }
1094
1095
1096
1097
1098
1099
1100
1101
1102 template <> void Converter<Readout>::operator()(xml_h e) const {
1103 xml_h seg = e.child(_U(segmentation), false);
1104 xml_h id = e.child(_U(id));
1105 std::string name = e.attr<std::string>(_U(name));
1106 std::pair<Segmentation,IDDescriptor> opt;
1107 Readout ro(name);
1108
1109 if (id) {
1110
1111 opt.second = IDDescriptor(name,id.text());
1112 description.addIDSpecification(opt.second);
1113 }
1114 if (seg) {
1115 Converter<Segmentation>(description,param,&opt)(seg);
1116 opt.first->setName(name);
1117 }
1118
1119
1120
1121 if ( opt.first.isValid() ) {
1122 ro.setSegmentation(opt.first);
1123 }
1124 if ( opt.second.isValid() ) {
1125 ro.setIDDescriptor(opt.second);
1126 }
1127
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() : "");
1131
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) {
1136 xml_dim_t c(coll);
1137 std::string coll_name = c.nameStr();
1138 std::string coll_key = hits_key;
1139 long key_min = 0, key_max = 0;
1140
1141 if ( c.hasAttr(_U(key)) ) {
1142 coll_key = c.attr<std::string>(_U(key));
1143 }
1144 if ( c.hasAttr(_U(key_value)) ) {
1145 key_max = key_min = c.key_value();
1146 }
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();
1150 }
1151 else {
1152 std::stringstream tree;
1153 xml::dump_tree(e,tree);
1154 throw_print("Readout: Invalid specification for multiple hit collections."+tree.str());
1155 }
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);
1159 HitCollection hits(coll_name, coll_key, key_min, key_max);
1160 ro->hits.emplace_back(hits);
1161 }
1162 }
1163 description.addReadout(ro);
1164 }
1165
1166 static long load_readout(Detector& description, xml_h element) {
1167 Converter<Readout> converter(description);
1168 converter(element);
1169 return 1;
1170 }
1171 DECLARE_XML_DOC_READER(readout,load_readout)
1172
1173
1174
1175
1176
1177
1178
1179
1180 template <> void Converter<LimitSet>::operator()(xml_h e) const {
1181 Limit limit;
1182 LimitSet ls(e.attr<std::string>(_U(name)));
1183 printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1184 "++ Converting LimitSet structure: %s.",ls.name());
1185 for (xml_coll_t c(e, _U(limit)); c; ++c) {
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));
1190 limit.value = _multiply<double>(limit.content, limit.unit);
1191 ls.addLimit(limit);
1192 printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1193 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1194 ls.name(), limit.name.c_str(), limit.particles.c_str(),
1195 limit.content.c_str(), limit.unit.c_str(), limit.value);
1196 }
1197 limit.name = "cut";
1198 for (xml_coll_t c(e, _U(cut)); c; ++c) {
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));
1202 limit.value = _multiply<double>(limit.content, limit.unit);
1203 ls.addCut(limit);
1204 printout(s_debug.limits ? ALWAYS : DEBUG, "Compact",
1205 "++ %s: add %-6s: [%s] = %s [%s] = %f",
1206 ls.name(), limit.name.c_str(), limit.particles.c_str(),
1207 limit.content.c_str(), limit.unit.c_str(), limit.value);
1208 }
1209 description.addLimitSet(ls);
1210 }
1211
1212
1213
1214
1215
1216
1217
1218 template <> void Converter<Property>::operator()(xml_h e) const {
1219 std::string name = e.attr<std::string>(_U(name));
1220 Detector::Properties& prp = description.properties();
1221 if ( name.empty() )
1222 throw_print("Failed to convert properties. No name given!");
1223
1224 std::vector<xml_attr_t> a = e.attributes();
1225 if ( prp.find(name) == prp.end() )
1226 prp.emplace(name, Detector::PropertyValues());
1227
1228 for (xml_attr_t i : a )
1229 prp[name].emplace(xml_tag_t(e.attr_name(i)).str(),e.attr<std::string>(i));
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239
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));
1244 CartesianField field = description.field(name);
1245 if ( !field.isValid() ) {
1246
1247 field = Ref_t(PluginService::Create<NamedObject*>(type, &description, &e));
1248 if ( !field.isValid() ) {
1249 PluginDebug dbg;
1250 PluginService::Create<NamedObject*>(type, &description, &e);
1251 throw_print("Failed to create field object of type "+type + ". "+dbg.missingFactory(type));
1252 }
1253 description.addField(field);
1254 msg = "created";
1255 }
1256 type = field.type();
1257
1258 CartesianField::Properties& prp = field.properties();
1259 for ( xml_coll_t c(e, _U(properties)); c; ++c ) {
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() ) {
1263 prp.emplace(props_name, Detector::PropertyValues());
1264 }
1265 for ( xml_attr_t i : a )
1266 prp[props_name].emplace(xml_tag_t(c.attr_name(i)).str(), c.attr<std::string>(i));
1267
1268 if (c.hasAttr(_U(global)) && c.attr<bool>(_U(global))) {
1269 description.field().properties() = prp;
1270 }
1271 }
1272 printout(INFO, "Compact", "++ Converted field: Successfully %s field %s [%s]", msg.c_str(), name.c_str(), type.c_str());
1273 }
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288 template <> void Converter<SensitiveDetector>::operator()(xml_h element) const {
1289 std::string name = element.attr<std::string>(_U(name));
1290 try {
1291 SensitiveDetector sd = description.sensitiveDetector(name);
1292 xml_attr_t type = element.attr_nothrow(_U(type));
1293 if ( type ) {
1294 sd.setType(element.attr<std::string>(type));
1295 }
1296 xml_attr_t verbose = element.attr_nothrow(_U(verbose));
1297 if ( verbose ) {
1298 sd.setVerbose(element.attr<bool>(verbose));
1299 }
1300 xml_attr_t combine = element.attr_nothrow(_U(combine_hits));
1301 if ( combine ) {
1302 sd.setCombineHits(element.attr<bool>(combine));
1303 }
1304 xml_attr_t limits = element.attr_nothrow(_U(limits));
1305 if ( limits ) {
1306 std::string l = element.attr<std::string>(limits);
1307 LimitSet ls = description.limitSet(l);
1308 if (!ls.isValid()) {
1309 throw_print("Converter<SensitiveDetector>: Request for non-existing limitset:" + l);
1310 }
1311 sd.setLimitSet(ls);
1312 }
1313 xml_attr_t region = element.attr_nothrow(_U(region));
1314 if ( region ) {
1315 std::string r = element.attr<std::string>(region);
1316 Region reg = description.region(r);
1317 if (!reg.isValid()) {
1318 throw_print("Converter<SensitiveDetector>: Request for non-existing region:" + r);
1319 }
1320 sd.setRegion(reg);
1321 }
1322 xml_attr_t hits = element.attr_nothrow(_U(hits_collection));
1323 if (hits) {
1324 sd.setHitsCollection(element.attr<std::string>(hits));
1325 }
1326 xml_attr_t ecut = element.attr_nothrow(_U(ecut));
1327 xml_attr_t eunit = element.attr_nothrow(_U(eunit));
1328 if (ecut && eunit) {
1329 double value = _multiply<double>(_toString(ecut), _toString(eunit));
1330 sd.setEnergyCutoff(value);
1331 }
1332 else if (ecut) {
1333 sd.setEnergyCutoff(element.attr<double>(ecut));
1334 }
1335 printout(DEBUG, "Compact", "SensitiveDetector-update: %-18s %-24s Hits:%-24s Cutoff:%7.3f", sd.name(),
1336 (" [" + sd.type() + "]").c_str(), sd.hitsCollection().c_str(), sd.energyCutoff());
1337 xml_attr_t sequence = element.attr_nothrow(_U(sequence));
1338 if (sequence) {
1339 }
1340 }
1341 catch (const std::exception& e) {
1342 printout(ERROR, "Compact", "++ FAILED to convert sensitive detector: %s: %s", name.c_str(), e.what());
1343 }
1344 catch (...) {
1345 printout(ERROR, "Compact", "++ FAILED to convert sensitive detector: %s: %s", name.c_str(), "UNKNONW Exception");
1346 }
1347 }
1348
1349 static void setChildTitles(const std::pair<std::string, DetElement>& e) {
1350 DetElement parent = e.second.parent();
1351 const DetElement::Children& children = e.second.children();
1352 if (::strlen(e.second->GetTitle()) == 0) {
1353 e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
1354 }
1355 for_each(children.begin(), children.end(), setChildTitles);
1356 }
1357
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 + ":";
1367
1368 if (req_dets && !strstr(req_dets, name_match.c_str()))
1369 return;
1370 if (req_typs && !strstr(req_typs, type_match.c_str()))
1371 return;
1372 if (ign_dets && strstr(ign_dets, name_match.c_str()))
1373 return;
1374 if (ign_typs && strstr(ign_typs, type_match.c_str()))
1375 return;
1376 xml_attr_t attr_ignore = element.attr_nothrow(_U(ignore));
1377 if ( attr_ignore ) {
1378 bool ignore_det = element.attr<bool>(_U(ignore));
1379 if ( ignore_det ) {
1380 printout(INFO, "Compact",
1381 "+++ Do not build subdetector:%s [ignore flag set]",
1382 name.c_str());
1383 return;
1384 }
1385 }
1386 try {
1387 std::string par_name;
1388 xml_attr_t attr_par = element.attr_nothrow(_U(parent));
1389 xml_elt_t elt_par(0);
1390 if (attr_par)
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() ) {
1395
1396
1397
1398 if ( par_name[0] == '$' ) par_name = xml::getEnviron(par_name);
1399 DetElement parent = description.detector(par_name);
1400 if ( !parent.isValid() ) {
1401 except("Compact","Failed to access valid parent detector of %s",name.c_str());
1402 }
1403 description.declareParent(name, parent);
1404 }
1405 xml_attr_t attr_ro = element.attr_nothrow(_U(readout));
1406 SensitiveDetector sd;
1407 Segmentation seg;
1408 if ( attr_ro ) {
1409 Readout ro = description.readout(element.attr<std::string>(attr_ro));
1410 if (!ro.isValid()) {
1411 except("Compact","No Readout structure present for detector:" + name);
1412 }
1413 seg = ro.segmentation();
1414 sd = SensitiveDetector(name, "sensitive");
1415 sd.setHitsCollection(ro.name());
1416 sd.setReadout(ro);
1417 description.addSensitiveDetector(sd);
1418 }
1419 Ref_t sens = sd;
1420 DetElement det(Ref_t(PluginService::Create<NamedObject*>(type, &description, &element, &sens)));
1421 if (det.isValid()) {
1422 setChildTitles(std::make_pair(name, det));
1423 if ( sd.isValid() ) {
1424 det->flag |= DetElement::Object::HAVE_SENSITIVE_DETECTOR;
1425 }
1426 if ( seg.isValid() ) {
1427 seg->sensitive = sd;
1428 seg->detector = det;
1429 }
1430 }
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() : ""));
1434
1435 if (!det.isValid()) {
1436 PluginDebug dbg;
1437 PluginService::Create<NamedObject*>(type, &description, &element, &sens);
1438 except("Compact","Failed to execute subdetector creation plugin. %s", dbg.missingFactory(type).c_str());
1439 }
1440 description.addDetector(det);
1441 description.surfaceManager().registerSurfaces(det);
1442 return;
1443 }
1444 catch (const std::exception& e) {
1445 printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
1446 std::terminate();
1447 }
1448 catch (...) {
1449 printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
1450 std::terminate();
1451 }
1452 }
1453
1454
1455 template <> void Converter<IncludeFile>::operator()(xml_h element) const {
1456 xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
1457 if ( s_debug.include_guard) {
1458
1459 if (check_process_file(description, doc.uri()))
1460 return;
1461 }
1462 xml_h root = doc.root();
1463 if ( s_debug.includes ) {
1464 printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
1465 }
1466 if ( root.tag() == "materials" || root.tag() == "elements" ) {
1467 xml_coll_t(root, _U(isotope)).for_each(Converter<Isotope>(this->description,0,0));
1468 xml_coll_t(root, _U(element)).for_each(Converter<Atom>(this->description));
1469 xml_coll_t(root, _U(material)).for_each(Converter<Material>(this->description));
1470 return;
1471 }
1472 this->description.fromXML(doc.uri(), this->description.buildType());
1473 }
1474
1475
1476 template <> void Converter<JsonFile>::operator()(xml_h element) const {
1477 std::string base = xml::DocumentHandler::system_directory(element);
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]);
1481 }
1482
1483
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("://");
1488 std::error_code ec;
1489
1490 if ( idx == std::string::npos && std::filesystem::exists(fname, ec) ) {
1491
1492 printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1493 this->description.fromXML(fname, this->description.buildType());
1494 }
1495 else if ( idx == std::string::npos ) {
1496
1497 std::string location = xml::DocumentHandler::system_path(element, fname);
1498 printout(level, "Compact","++ Processing xml document %s.", location.c_str());
1499 this->description.fromXML(location, this->description.buildType());
1500 }
1501 else if ( idx > 0 ) {
1502
1503 printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1504 this->description.fromXML(fname, this->description.buildType());
1505 }
1506 else {
1507
1508 printout(level, "Compact","++ Processing xml document %s.", fname.c_str());
1509 this->description.fromXML(fname, this->description.buildType());
1510 }
1511 }
1512
1513
1514 template <> void Converter<World>::operator()(xml_h element) const {
1515 xml_elt_t x_world(element);
1516 xml_comp_t x_shape = x_world.child(_U(shape), false);
1517 xml_attr_t att = x_world.getAttr(_U(material));
1518 Material mat = att ? description.material(x_world.attr<std::string>(att)) : description.air();
1519 Volume world_vol;
1520
1521
1522 if ( x_shape ) {
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());
1528 }
1529 else {
1530 world_vol = description.worldVolume();
1531 if ( !world_vol && att ) {
1532
1533
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,
1539 mat.name());
1540 description.manager().SetTopVolume(world_vol.ptr());
1541 }
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.");
1545 }
1546 }
1547
1548 if ( world_vol.isValid() ) {
1549 xml::configVolume(description, x_world, world_vol, false, true);
1550 auto vis = world_vol.visAttributes();
1551 if ( !vis.isValid() ) {
1552 vis = description.visAttributes("WorldVis");
1553 world_vol.setVisAttributes(vis);
1554 }
1555 }
1556 }
1557
1558
1559 template <> void Converter<Parallelworld_Volume>::operator()(xml_h element) const {
1560 xml_det_t parallel(element);
1561 xml_comp_t shape = parallel.child(_U(shape));
1562 xml_dim_t pos = element.child(_U(position),false);
1563 xml_dim_t rot = element.child(_U(rotation),false);
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);
1567 DetElement anchor(detail::tools::findElement(description, path));
1568 Position position = pos ? Position(pos.x(), pos.y(), pos.z()) : Position();
1569 RotationZYX rotation = rot ? RotationZYX(rot.z(), rot.y(), rot.x()) : RotationZYX();
1570
1571 Material mat = parallel.hasAttr(_U(material))
1572 ? description.material(parallel.attr<std::string>(_U(material)))
1573 : description.air();
1574 VisAttr vis = parallel.hasAttr(_U(vis))
1575 ? description.invisible()
1576 : description.visAttributes(parallel.visStr());
1577
1578 if ( !anchor.isValid() ) {
1579 except("Parallelworld_Volume",
1580 "++ FAILED Cannot identify the anchor of the tracking volume: '%s'",
1581 path.c_str());
1582 }
1583
1584
1585 Transform3D tr_volume(detail::matrix::_transform(anchor.nominal().worldTransformation().Inverse()));
1586 Solid sol(shape.createShape());
1587 Volume vol(name, sol, mat);
1588 Volume par = conn ? description.worldVolume() : description.parallelWorldVolume();
1589 PlacedVolume pv;
1590
1591
1592 vol.setVisAttributes(vis);
1593
1594 vol.setFlagBit(Volume::VETO_SIMU);
1595
1596
1597 Transform3D trafo = tr_volume * Transform3D(rotation,position);
1598 pv = par.placeVolume(vol, trafo);
1599 if ( !pv.isValid() ) {
1600 except("Parallelworld_Volume",
1601 "++ FAILED to place the tracking volume inside the anchor '%s'",path.c_str());
1602 }
1603 if ( name == "tracking_volume" ) {
1604 description.setTrackingVolume(vol);
1605 }
1606 printout(INFO, "Compact", "++ Converted successfully parallelworld_volume %s. anchor: %s vis:%s.",
1607 vol.name(), anchor.path().c_str(), vis.name());
1608 }
1609
1610
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" ) {
1614 xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
1615 if ( s_debug.include_guard ) {
1616
1617 if (check_process_file(description, doc.uri()))
1618 return;
1619 }
1620 if ( s_debug.includes ) {
1621 printout(ALWAYS, "Compact","++ Processing xml document %s.",doc.uri().c_str());
1622 }
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" )
1628 xml_coll_t(node, _U(constant)).for_each(Converter<Constant>(this->description));
1629 else if ( tag == "readouts" )
1630 xml_coll_t(node, _U(readout)).for_each(Converter<Readout>(this->description));
1631 else if ( tag == "regions" )
1632 xml_coll_t(node, _U(region)).for_each(Converter<Region>(this->description));
1633 else if ( tag == "limits" || tag == "limitsets" )
1634 xml_coll_t(node, _U(limitset)).for_each(Converter<LimitSet>(this->description));
1635 else if ( tag == "display" )
1636 xml_coll_t(node,_U(vis)).for_each(Converter<VisAttr>(this->description));
1637 else if ( tag == "detector" )
1638 Converter<DetElement>(this->description)(node);
1639 else if ( tag == "detectors" )
1640 xml_coll_t(node,_U(detector)).for_each(Converter<DetElement>(this->description));
1641 }
1642 else if ( type == "json" ) {
1643 Converter<JsonFile>(this->description)(element);
1644 }
1645 else if ( type == "gdml" ) {
1646 Converter<IncludeFile>(this->description)(element);
1647 }
1648 else if ( type == "include" ) {
1649 Converter<IncludeFile>(this->description)(element);
1650 }
1651 else if ( type == "xml-extended" ) {
1652 Converter<XMLFile>(this->description)(element);
1653 }
1654 else {
1655 except("Compact","++ FAILED Invalid file type:%s. This cannot be processed!",type.c_str());
1656 }
1657 }
1658
1659 template <> void Converter<Compact>::operator()(xml_h element) const {
1660 static int num_calls = 0;
1661 char text[32];
1662
1663 ++num_calls;
1664 xml_elt_t compact(element);
1665 bool steer_geometry = compact.hasChild(_U(geometry));
1666 bool open_geometry = true;
1667 bool close_document = true;
1668 bool close_geometry = true;
1669 bool build_reflections = false;
1670 xml_dim_t world = element.child(_U(world), false);
1671
1672
1673 if (element.hasChild(_U(debug)))
1674 (Converter<Debug>(description))(xml_h(compact.child(_U(debug))));
1675
1676 if ( steer_geometry ) {
1677 xml_elt_t steer = compact.child(_U(geometry));
1678 if ( steer.hasAttr(_U(open)) )
1679 open_geometry = steer.attr<bool>(_U(open));
1680 if ( steer.hasAttr(_U(close)) )
1681 close_document = steer.attr<bool>(_U(close));
1682 if ( steer.hasAttr(_U(reflect)) )
1683 build_reflections = steer.attr<bool>(_U(reflect));
1684 for (xml_coll_t clr(steer, _U(clear)); clr; ++clr) {
1685 std::string nam = clr.hasAttr(_U(name)) ? clr.attr<std::string>(_U(name)) : std::string();
1686 if ( nam.substr(0,6) == "elemen" ) {
1687 TGeoElementTable* table = description.manager().GetElementTable();
1688 table->TGeoElementTable::~TGeoElementTable();
1689 new(table) TGeoElementTable();
1690
1691 table->AddElement("VACUUM","VACUUM" ,0, 0, 0.0);
1692 printout(INFO,"Compact",
1693 "++ Cleared default ROOT TGeoElementTable contents. "
1694 "Must now be filled from XML!");
1695 }
1696 }
1697 }
1698
1699 if ( s_debug.materials || s_debug.elements ) {
1700 printout(INFO,"Compact","+++ UNIT System:");
1701 printout(INFO,"Compact","+++ Density: %8.3g Units:%8.3g",
1702 xml::_toDouble(_Unicode(gram/cm3)), dd4hep::gram/dd4hep::cm3);
1703 printout(INFO,"Compact","+++ GeV: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(GeV)),dd4hep::GeV);
1704 printout(INFO,"Compact","+++ sec: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(second)),dd4hep::second);
1705 printout(INFO,"Compact","+++ nanosecond: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(nanosecond)),dd4hep::nanosecond);
1706 printout(INFO,"Compact","+++ kilo: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(kilogram)),dd4hep::kilogram);
1707 printout(INFO,"Compact","+++ kilo: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(joule*s*s/(m*m))),
1708 dd4hep::joule*dd4hep::s*dd4hep::s/(dd4hep::meter*dd4hep::meter));
1709 printout(INFO,"Compact","+++ meter: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(meter)),dd4hep::meter);
1710 printout(INFO,"Compact","+++ ampere: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(ampere)),dd4hep::ampere);
1711 printout(INFO,"Compact","+++ degree: %8.3g Units:%8.3g",xml::_toDouble(_Unicode(degree)),dd4hep::degree);
1712 }
1713
1714 xml_coll_t(compact, _U(define)).for_each(_U(include), Converter<DetElementInclude>(description));
1715 xml_coll_t(compact, _U(define)).for_each(_U(constant), Converter<Constant>(description));
1716 xml_coll_t(compact, _U(std_conditions)).for_each( Converter<STD_Conditions>(description));
1717 xml_coll_t(compact, _U(includes)).for_each(_U(gdmlFile), Converter<IncludeFile>(description));
1718 xml_coll_t(compact, _U(includes)).for_each(_U(file), Converter<IncludeFile>(description));
1719
1720 if (element.hasChild(_U(info)))
1721 (Converter<Header>(description))(xml_h(compact.child(_U(info))));
1722
1723 xml_coll_t(compact, _U(properties)).for_each(_U(attributes), Converter<Property>(description));
1724
1725 xml_coll_t(compact, _U(properties)).for_each(_U(constant), Converter<PropertyConstant>(description));
1726 xml_coll_t(compact, _U(properties)).for_each(_U(matrix), Converter<PropertyTable>(description));
1727 xml_coll_t(compact, _U(properties)).for_each(_U(plugin), Converter<Plugin> (description));
1728 xml_coll_t(compact, _U(surfaces)).for_each(_U(opticalsurface), Converter<OpticalSurface>(description));
1729
1730 xml_coll_t(compact, _U(materials)).for_each(_U(element), Converter<Atom>(description));
1731 xml_coll_t(compact, _U(materials)).for_each(_U(material), Converter<Material>(description));
1732 xml_coll_t(compact, _U(materials)).for_each(_U(plugin), Converter<Plugin> (description));
1733
1734 printout(DEBUG, "Compact", "++ Converting visualization attributes...");
1735 xml_coll_t(compact, _U(display)).for_each(_U(include), Converter<DetElementInclude>(description));
1736 xml_coll_t(compact, _U(display)).for_each(_U(vis), Converter<VisAttr>(description));
1737 printout(DEBUG, "Compact", "++ Converting limitset structures...");
1738 xml_coll_t(compact, _U(limits)).for_each(_U(include), Converter<DetElementInclude>(description));
1739 xml_coll_t(compact, _U(limits)).for_each(_U(limitset), Converter<LimitSet>(description));
1740 printout(DEBUG, "Compact", "++ Converting region structures...");
1741 xml_coll_t(compact, _U(regions)).for_each(_U(include), Converter<DetElementInclude>(description));
1742 xml_coll_t(compact, _U(regions)).for_each(_U(region), Converter<Region>(description));
1743
1744 if ( world ) {
1745 (Converter<World>(description))(world);
1746 }
1747 if ( open_geometry ) description.init();
1748 printout(DEBUG, "Compact", "++ Converting readout structures...");
1749 xml_coll_t(compact, _U(readouts)).for_each(_U(readout), Converter<Readout>(description));
1750 printout(DEBUG, "Compact", "++ Converting included files with subdetector structures...");
1751 xml_coll_t(compact, _U(detectors)).for_each(_U(include), Converter<DetElementInclude>(description));
1752 printout(DEBUG, "Compact", "++ Converting detector structures...");
1753 xml_coll_t(compact, _U(detectors)).for_each(_U(detector), Converter<DetElement>(description));
1754 xml_coll_t(compact, _U(include)).for_each(Converter<DetElementInclude>(this->description));
1755
1756 xml_coll_t(compact, _U(includes)).for_each(_U(xml), Converter<XMLFile>(description));
1757 xml_coll_t(compact, _U(fields)).for_each(_U(field), Converter<CartesianField>(description));
1758 xml_coll_t(compact, _U(sensitive_detectors)).for_each(_U(sd), Converter<SensitiveDetector>(description));
1759 xml_coll_t(compact, _U(parallelworld_volume)).for_each(Converter<Parallelworld_Volume>(description));
1760
1761 if ( --num_calls == 0 && close_document ) {
1762 ::snprintf(text, sizeof(text), "%u", xml_h(element).checksum(0));
1763 description.addConstant(Constant("compact_checksum", text));
1764 description.endDocument(close_geometry);
1765 }
1766 if ( build_reflections ) {
1767 ReflectionBuilder rb(description);
1768 rb.execute();
1769 }
1770 xml_coll_t(compact, _U(plugins)).for_each(_U(plugin), Converter<Plugin> (description));
1771 xml_coll_t(compact, _U(plugins)).for_each(_U(include), Converter<XMLFile> (description));
1772 xml_coll_t(compact, _U(plugins)).for_each(_U(xml), Converter<XMLFile> (description));
1773 }
1774
1775 #ifdef _WIN32
1776 template Converter<Plugin>;
1777 template Converter<Constant>;
1778 template Converter<Material>;
1779 template Converter<Atom>;
1780 template Converter<VisAttr>;
1781 template Converter<Region>;
1782 template Converter<Readout>;
1783 template Converter<Segmentation>;
1784 template Converter<LimitSet>;
1785 template Converter<Property>;
1786 template Converter<CartesianField>;
1787 template Converter<SensitiveDetector>;
1788 template Converter<DetElement>;
1789 template Converter<GdmlFile>;
1790 template Converter<XMLFile>;
1791 template Converter<Header>;
1792 template Converter<DetElementInclude>;
1793 template Converter<Compact>;
1794
1795 #endif