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