File indexing completed on 2025-12-18 09:29:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "DD4hep/DetFactoryHelper.h"
0020 #include "DD4hep/DetectorHelper.h"
0021 #include "DD4hep/DD4hepUnits.h"
0022 #include "DD4hep/GeoHandler.h"
0023 #include "DD4hep/Printout.h"
0024 #include "DD4hep/Plugins.h"
0025 #include "DD4hep/detail/SegmentationsInterna.h"
0026 #include "DD4hep/detail/DetectorInterna.h"
0027 #include "DD4hep/detail/ObjectsInterna.h"
0028
0029 #include "XML/Utilities.h"
0030 #include "DDCMS/DDCMS.h"
0031
0032
0033 #include "TSystem.h"
0034 #include "TGeoManager.h"
0035 #include "TGeoMaterial.h"
0036
0037
0038 #include <climits>
0039 #include <iostream>
0040 #include <iomanip>
0041 #include <set>
0042 #include <map>
0043
0044 using namespace std;
0045 using namespace dd4hep;
0046 using namespace dd4hep::cms;
0047
0048
0049 namespace dd4hep {
0050
0051 namespace {
0052
0053 static UInt_t unique_mat_id = 0xAFFEFEED;
0054 double convertRadToDeg(double r) {
0055 return r*360e0/(2e0*M_PI);
0056 }
0057 class disabled_algo;
0058 class include_constants;
0059 class include_load;
0060 class include_unload;
0061 class print_xml_doc;
0062 class constantssection;
0063 class constant;
0064 class resolve {
0065 public:
0066 std::vector<xml::Document> includes;
0067 std::map<std::string,std::string> unresolvedConst, allConst, originalConst;
0068 };
0069
0070 class materialsection;
0071 class elementaryelement;
0072 class elementarymaterial;
0073 class compositematerial;
0074
0075 class rotationsection;
0076 class rotation;
0077 class transform3d;
0078
0079 class pospartsection;
0080 class division;
0081 class pospart;
0082
0083 class logicalpartsection;
0084 class logicalpart;
0085
0086 class solidsection;
0087 class extrudedpolygon;
0088 class shapeless;
0089 class trapezoid;
0090 class ellipsoid;
0091 class ellipticaltube;
0092 class pseudotrap;
0093 class polyhedra;
0094 class polycone;
0095 class torus;
0096 class trd1;
0097 class trunctubs;
0098 class cuttubs;
0099 class tubs;
0100 class orb;
0101 class box;
0102 class cone;
0103 class sphere;
0104 class unionsolid;
0105 class intersectionsolid;
0106 class subtractionsolid;
0107
0108 class algorithm;
0109
0110 class vissection;
0111 class vis;
0112 class debug;
0113 }
0114
0115
0116 template <> void Converter<debug>::operator()(xml_h element) const;
0117 template <> void Converter<print_xml_doc>::operator()(xml_h element) const;
0118 template <> void Converter<disabled_algo>::operator()(xml_h element) const;
0119
0120
0121 template <> void Converter<constantssection>::operator()(xml_h element) const;
0122 template <> void Converter<constant>::operator()(xml_h element) const;
0123 template <> void Converter<resolve>::operator()(xml_h element) const;
0124
0125
0126 template <> void Converter<vissection>::operator()(xml_h element) const;
0127
0128 template <> void Converter<vis>::operator()(xml_h element) const;
0129
0130
0131 template <> void Converter<materialsection>::operator()(xml_h element) const;
0132 template <> void Converter<elementaryelement>::operator()(xml_h element) const;
0133 template <> void Converter<elementarymaterial>::operator()(xml_h element) const;
0134 template <> void Converter<compositematerial>::operator()(xml_h element) const;
0135
0136
0137 template <> void Converter<rotationsection>::operator()(xml_h element) const;
0138
0139 template <> void Converter<rotation>::operator()(xml_h element) const;
0140 template <> void Converter<transform3d>::operator()(xml_h element) const;
0141
0142
0143 template <> void Converter<logicalpartsection>::operator()(xml_h element) const;
0144 template <> void Converter<logicalpart>::operator()(xml_h element) const;
0145
0146
0147 template <> void Converter<pospartsection>::operator()(xml_h element) const;
0148
0149 template <> void Converter<pospart>::operator()(xml_h element) const;
0150
0151 template <> void Converter<division>::operator()(xml_h element) const;
0152
0153
0154 template <> void Converter<solidsection>::operator()(xml_h element) const;
0155
0156 template <> void Converter<unionsolid>::operator()(xml_h element) const;
0157
0158 template <> void Converter<subtractionsolid>::operator()(xml_h element) const;
0159
0160 template <> void Converter<intersectionsolid>::operator()(xml_h element) const;
0161
0162 template <> void Converter<pseudotrap>::operator()(xml_h element) const;
0163
0164 template <> void Converter<extrudedpolygon>::operator()(xml_h element) const;
0165
0166 template <> void Converter<shapeless>::operator()(xml_h element) const;
0167
0168 template <> void Converter<trapezoid>::operator()(xml_h element) const;
0169
0170 template <> void Converter<polyhedra>::operator()(xml_h element) const;
0171
0172 template <> void Converter<polycone>::operator()(xml_h element) const;
0173
0174 template <> void Converter<ellipsoid>::operator()(xml_h element) const;
0175
0176 template <> void Converter<ellipticaltube>::operator()(xml_h element) const;
0177
0178 template <> void Converter<torus>::operator()(xml_h element) const;
0179
0180 template <> void Converter<tubs>::operator()(xml_h element) const;
0181
0182 template <> void Converter<cuttubs>::operator()(xml_h element) const;
0183
0184 template <> void Converter<trunctubs>::operator()(xml_h element) const;
0185
0186 template <> void Converter<sphere>::operator()(xml_h element) const;
0187
0188 template <> void Converter<trd1>::operator()(xml_h element) const;
0189
0190 template <> void Converter<cone>::operator()(xml_h element) const;
0191
0192 template <> void Converter<box>::operator()(xml_h element) const;
0193
0194 template <> void Converter<orb>::operator()(xml_h element) const;
0195
0196
0197 template <> void Converter<algorithm>::operator()(xml_h element) const;
0198
0199
0200 template <> void Converter<include_load>::operator()(xml_h element) const;
0201
0202 template <> void Converter<include_unload>::operator()(xml_h element) const;
0203
0204 template <> void Converter<include_constants>::operator()(xml_h element) const;
0205 }
0206
0207
0208 template <> void Converter<constantssection>::operator()(xml_h element) const {
0209 Namespace _ns(_param<ParsingContext>(), element);
0210 xml_coll_t(element, _CMU(Constant)).for_each(Converter<constant>(description,_ns.context,optional));
0211 }
0212
0213
0214 template <> void Converter<vissection>::operator()(xml_h element) const {
0215 Namespace _ns(_param<ParsingContext>(), element);
0216 xml_coll_t(element, _CMU(vis)).for_each(Converter<vis>(description,_ns.context,optional));
0217 }
0218
0219
0220 template <> void Converter<materialsection>::operator()(xml_h element) const {
0221 Namespace _ns(_param<ParsingContext>(), element);
0222 xml_coll_t(element, _CMU(ElementaryMaterial)).for_each(Converter<elementaryelement>(description,_ns.context,optional));
0223 xml_coll_t(element, _CMU(ElementaryMaterial)).for_each(Converter<elementarymaterial>(description,_ns.context,optional));
0224 xml_coll_t(element, _CMU(CompositeMaterial)).for_each(Converter<compositematerial>(description,_ns.context,optional));
0225 }
0226
0227 template <> void Converter<rotationsection>::operator()(xml_h element) const {
0228 Namespace _ns(_param<ParsingContext>(), element);
0229 xml_coll_t(element, _CMU(Rotation)).for_each(Converter<rotation>(description,_ns.context,optional));
0230 xml_coll_t(element, _CMU(ReflectionRotation)).for_each(Converter<rotation>(description,_ns.context,optional));
0231 }
0232
0233 template <> void Converter<pospartsection>::operator()(xml_h element) const {
0234 Namespace _ns(_param<ParsingContext>(), element);
0235 xml_coll_t(element, _CMU(Division)).for_each(Converter<division>(description,_ns.context,optional));
0236 xml_coll_t(element, _CMU(PosPart)).for_each(Converter<pospart>(description,_ns.context,optional));
0237 xml_coll_t(element, _CMU(Algorithm)).for_each(Converter<algorithm>(description,_ns.context,optional));
0238 }
0239
0240
0241 template <> void Converter<logicalpartsection>::operator()(xml_h element) const {
0242 Namespace _ns(_param<ParsingContext>(), element);
0243 xml_coll_t(element, _CMU(LogicalPart)).for_each(Converter<logicalpart>(description,_ns.context,optional));
0244 }
0245
0246 template <> void Converter<disabled_algo>::operator()(xml_h element) const {
0247 ParsingContext* c = _param<ParsingContext>();
0248 c->disabledAlgs.insert(element.attr<string>(_U(name)));
0249 }
0250
0251
0252 template <> void Converter<solidsection>::operator()(xml_h element) const {
0253 Namespace _ns(_param<ParsingContext>(), element);
0254 for(xml_coll_t solid(element, _U(star)); solid; ++solid) {
0255 string tag = solid.tag();
0256 if ( tag == "Box" )
0257 Converter<box>(description,_ns.context,optional)(solid);
0258 else if ( tag == "Polycone" )
0259 Converter<polycone>(description,_ns.context,optional)(solid);
0260 else if ( tag == "Polyhedra" )
0261 Converter<polyhedra>(description,_ns.context,optional)(solid);
0262 else if ( tag == "Tubs" )
0263 Converter<tubs>(description,_ns.context,optional)(solid);
0264 else if ( tag == "CutTubs" )
0265 Converter<cuttubs>(description,_ns.context,optional)(solid);
0266 else if ( tag == "TruncTubs" )
0267 Converter<trunctubs>(description,_ns.context,optional)(solid);
0268 else if ( tag == "Tube" )
0269 Converter<tubs>(description,_ns.context,optional)(solid);
0270 else if ( tag == "Trd1" )
0271 Converter<trd1>(description,_ns.context,optional)(solid);
0272 else if ( tag == "Cone" )
0273 Converter<cone>(description,_ns.context,optional)(solid);
0274 else if ( tag == "Sphere" )
0275 Converter<sphere>(description,_ns.context,optional)(solid);
0276 else if ( tag == "Ellipsoid" )
0277 Converter<ellipsoid>(description,_ns.context,optional)(solid);
0278 else if ( tag == "EllipticalTube" )
0279 Converter<ellipticaltube>(description,_ns.context,optional)(solid);
0280 else if ( tag == "Orb" )
0281 Converter<orb>(description,_ns.context,optional)(solid);
0282 else if ( tag == "Torus" )
0283 Converter<torus>(description,_ns.context,optional)(solid);
0284 else if ( tag == "PseudoTrap" )
0285 Converter<pseudotrap>(description,_ns.context,optional)(solid);
0286 else if ( tag == "ExtrudedPolygon" )
0287 Converter<extrudedpolygon>(description,_ns.context,optional)(solid);
0288 else if ( tag == "Trapezoid" )
0289 Converter<trapezoid>(description,_ns.context,optional)(solid);
0290 else if ( tag == "UnionSolid" )
0291 Converter<unionsolid>(description,_ns.context,optional)(solid);
0292 else if ( tag == "SubtractionSolid" )
0293 Converter<subtractionsolid>(description,_ns.context,optional)(solid);
0294 else if ( tag == "IntersectionSolid" )
0295 Converter<intersectionsolid>(description,_ns.context,optional)(solid);
0296 else if ( tag == "ShapelessSolid" )
0297 Converter<shapeless>(description,_ns.context,optional)(solid);
0298 else {
0299 string nam = xml_dim_t(solid).nameStr();
0300 printout(ERROR,"DDCMS","+++ Request to process unknown shape '%s' [%s]",
0301 nam.c_str(), tag.c_str());
0302 }
0303 }
0304 }
0305
0306
0307 template <> void Converter<constant>::operator()(xml_h element) const {
0308 Namespace _ns(_param<ParsingContext>());
0309 resolve* res = _option<resolve>();
0310 xml_dim_t constant = element;
0311 xml_dim_t par = constant.parent();
0312 bool eval = par.hasAttr(_U(eval)) ? par.attr<bool>(_U(eval)) : false;
0313 string val = constant.valueStr();
0314 string nam = constant.nameStr();
0315 string real = _ns.prepend(nam);
0316 string typ = eval ? "number" : "string";
0317 size_t idx = val.find('[');
0318
0319 if ( constant.hasAttr(_U(type)) )
0320 typ = constant.typeStr();
0321
0322 if ( idx == string::npos || typ == "string" ) {
0323 try {
0324 _ns.addConstant(nam, val, typ);
0325 res->allConst[real] = val;
0326 res->originalConst[real] = val;
0327 }
0328 catch(const exception& e) {
0329 printout(INFO,"DDCMS","++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
0330 real.c_str(), val.c_str(), typ.c_str(), e.what());
0331 }
0332 return;
0333 }
0334
0335 while ( idx != string::npos ) {
0336 ++idx;
0337 size_t idp = val.find(':',idx);
0338 size_t idq = val.find(']',idx);
0339 if ( idp == string::npos || idp > idq )
0340 val.insert(idx,_ns.name);
0341 else if ( idp != string::npos && idp < idq )
0342 val[idp] = NAMESPACE_SEP;
0343 idx = val.find('[',idx);
0344 }
0345
0346 printout(_ns.context->debug.constants ? ALWAYS : DEBUG,
0347 "Constant","Unresolved: %s -> %s",real.c_str(),val.c_str());
0348 res->allConst[real] = val;
0349 res->originalConst[real] = val;
0350 res->unresolvedConst[real] = val;
0351 }
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 template <> void Converter<vis>::operator()(xml_h e) const {
0362 Namespace _ns(_param<ParsingContext>());
0363 VisAttr attr(e.attr<string>(_U(name)));
0364 xml_dim_t dim(e);
0365 float alpha = dim.alpha(1.0);
0366 float red = dim.r(1.0);
0367 float green = dim.g(1.0);
0368 float blue = dim.b(1.0);
0369
0370 printout(_ns.context->debug.visattr ? ALWAYS : DEBUG, "Compact",
0371 "++ Converting VisAttr structure: %-16s. R=%.3f G=%.3f B=%.3f",
0372 attr.name(), red, green, blue);
0373 attr.setColor(alpha, red, green, blue);
0374 if ( e.hasAttr(_U(visible)) )
0375 attr.setVisible(e.attr<bool>(_U(visible)));
0376 if ( e.hasAttr(_U(lineStyle)) ) {
0377 string ls = e.attr<string>(_U(lineStyle));
0378 if (ls == "unbroken")
0379 attr.setLineStyle(VisAttr::SOLID);
0380 else if (ls == "broken")
0381 attr.setLineStyle(VisAttr::DASHED);
0382 }
0383 else {
0384 attr.setLineStyle(VisAttr::SOLID);
0385 }
0386 if (e.hasAttr(_U(drawingStyle))) {
0387 string ds = e.attr<string>(_U(drawingStyle));
0388 if (ds == "wireframe")
0389 attr.setDrawingStyle(VisAttr::WIREFRAME);
0390 else if (ds == "solid")
0391 attr.setDrawingStyle(VisAttr::SOLID);
0392 }
0393 else {
0394 attr.setDrawingStyle(VisAttr::SOLID);
0395 }
0396 if (e.hasAttr(_U(showDaughters)))
0397 attr.setShowDaughters(e.attr<bool>(_U(showDaughters)));
0398 else
0399 attr.setShowDaughters(true);
0400 description.addVisAttribute(attr);
0401 }
0402
0403
0404 template <> void Converter<elementaryelement>::operator()(xml_h element) const {
0405 Namespace _ns(_param<ParsingContext>());
0406 xml_dim_t xmat(element);
0407 string nam = _ns.prepend(xmat.nameStr());
0408 TGeoManager& mgr = description.manager();
0409 TGeoElementTable* tab = mgr.GetElementTable();
0410 TGeoElement* elt1 = tab->FindElement(xmat.nameStr().c_str());
0411 TGeoElement* elt2 = tab->FindElement(nam.c_str());
0412 static bool first = true;
0413 if ( first && _ns.context->debug.materials ) {
0414 first = false;
0415 printout(ALWAYS, "DDCMS"," +++ Units: gram: %7.3f ",dd4hep::g);
0416 printout(ALWAYS, "DDCMS"," +++ Units: cm3: %7.3f ",dd4hep::cm3);
0417 printout(ALWAYS, "DDCMS"," +++ Units: cm: %7.3f ",dd4hep::cm);
0418 printout(ALWAYS, "DDCMS"," +++ Units: mole: %7.3f ",dd4hep::mole);
0419 printout(ALWAYS, "DDCMS"," +++ Units: g/cm3: %7.3f ",dd4hep::g/dd4hep::cm3);
0420 printout(ALWAYS, "DDCMS"," +++ Units: g/mole: %7.3f ",dd4hep::g/dd4hep::mole);
0421 }
0422 if ( !elt1 || !elt2 ) {
0423 double atomicNumber = xmat.attr<double>(_CMU(atomicNumber));
0424 double atomicWeight = xmat.attr<double>(_CMU(atomicWeight))/(dd4hep::g/dd4hep::mole);
0425 int n = int(atomicNumber);
0426 printout(_ns.context->debug.materials ? ALWAYS : DEBUG, "DDCMS",
0427 "+++ Converting element %-32s atomic number: %3d weight: %8.3f [g/mol]",
0428 ('"'+nam+'"').c_str(), n, atomicWeight);
0429 elt1 = new TGeoElement(nam.c_str(),"CMS element", n, atomicWeight);
0430 tab->AddElement(elt1);
0431 }
0432 }
0433
0434
0435 template <> void Converter<elementarymaterial>::operator()(xml_h element) const {
0436 Namespace _ns(_param<ParsingContext>());
0437 xml_dim_t xmat(element);
0438 string nam = _ns.prepend(xmat.nameStr());
0439 TGeoManager& mgr = description.manager();
0440 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
0441 if ( 0 == mat ) {
0442 const char* matname = nam.c_str();
0443 double density = xmat.density() / (dd4hep::g/dd4hep::cm3);
0444
0445
0446 TGeoElementTable* tab = mgr.GetElementTable();
0447 TGeoMixture* mix = new TGeoMixture(nam.c_str(), 1, density);
0448 TGeoElement* elt = tab->FindElement(nam.c_str());
0449
0450 printout(_ns.context->debug.materials ? ALWAYS : DEBUG, "DDCMS",
0451 "+++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
0452 ('"'+nam+'"').c_str(), density, mix->GetDensity());
0453
0454 if ( !elt ) {
0455 printout(WARNING,"DDCMS",
0456 "+++ Converter<ElementaryMaterial> No element present with name:%s [FAKE IT]",
0457 matname);
0458 }
0459 #if 0
0460 if ( !elt ) {
0461 printout(WARNING,"DDCMS",
0462 "+++ Converter<ElementaryMaterial> No element present with name:%s [FAKE IT]",
0463 matname);
0464 int n = int(atomicNumber/2e0);
0465 if ( n < 2 ) n = 2;
0466 elt = new TGeoElement(xmat.nameStr().c_str(),"CMS element",n,atomicNumber);
0467
0468 }
0469 if ( elt->Z() == 0 ) {
0470 int n = int(atomicNumber/2e0);
0471 if ( n < 2 ) n = 2;
0472 elt = new TGeoElement((xmat.nameStr()+"-CMS").c_str(),"CMS element", n, atomicNumber);
0473 }
0474 #endif
0475 mix->AddElement(elt, 1.0);
0476 mix->SetRadLen(0e0);
0477 mix->ComputeDerivedQuantities();
0478
0479 TGeoMedium* medium = mgr.GetMedium(matname);
0480 if (0 == medium) {
0481 --unique_mat_id;
0482 medium = new TGeoMedium(matname, unique_mat_id, mix);
0483 medium->SetTitle("material");
0484 medium->SetUniqueID(unique_mat_id);
0485 }
0486 }
0487 }
0488
0489
0490 template <> void Converter<compositematerial>::operator()(xml_h element) const {
0491 Namespace _ns(_param<ParsingContext>());
0492 xml_dim_t xmat(element);
0493 string nam = _ns.prepend(xmat.nameStr());
0494 TGeoManager& mgr = description.manager();
0495 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
0496 if ( 0 == mat ) {
0497 const char* matname = nam.c_str();
0498 double density = xmat.density() / (dd4hep::g/dd4hep::cm3);
0499 xml_coll_t composites(xmat,_CMU(MaterialFraction));
0500 TGeoMixture* mix = new TGeoMixture(nam.c_str(), composites.size(), density);
0501
0502 for (composites.reset(); composites; ++composites) {
0503 xml_dim_t xfrac(composites);
0504 xml_dim_t xfrac_mat(xfrac.child(_CMU(rMaterial)));
0505 double fraction = xfrac.fraction();
0506 string fracname = _ns.real_name(xfrac_mat.nameStr());
0507
0508 TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
0509 if ( frac_mat ) {
0510 mix->AddElement(frac_mat, fraction);
0511 continue;
0512 }
0513 printout(WARNING,"DDCMS","+++ Composite material \"%s\" not present!",
0514 fracname.c_str());
0515 }
0516 mix->SetRadLen(0e0);
0517 mix->ComputeDerivedQuantities();
0518 printout(_ns.context->debug.materials ? ALWAYS : DEBUG, "DDCMS",
0519 "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
0520 ('"'+nam+'"').c_str(), density, mix->GetDensity());
0521
0522
0523 TGeoMedium* medium = mgr.GetMedium(matname);
0524 if (0 == medium) {
0525 --unique_mat_id;
0526 medium = new TGeoMedium(matname, unique_mat_id, mix);
0527 medium->SetTitle("material");
0528 medium->SetUniqueID(unique_mat_id);
0529 }
0530
0531 }
0532 }
0533
0534
0535 template <> void Converter<rotation>::operator()(xml_h element) const {
0536 ParsingContext* ctx = _param<ParsingContext>();
0537 Namespace _ns(ctx);
0538 xml_dim_t xrot(element);
0539 string nam = xrot.nameStr();
0540 PrintLevel lvl = ctx->debug.rotations ? ALWAYS : DEBUG;
0541 double thetaX = xrot.hasAttr(_CMU(thetaX)) ? _ns.attr<double>(xrot,_CMU(thetaX)) : 0e0;
0542 double phiX = xrot.hasAttr(_CMU(phiX)) ? _ns.attr<double>(xrot,_CMU(phiX)) : 0e0;
0543 double thetaY = xrot.hasAttr(_CMU(thetaY)) ? _ns.attr<double>(xrot,_CMU(thetaY)) : 0e0;
0544 double phiY = xrot.hasAttr(_CMU(phiY)) ? _ns.attr<double>(xrot,_CMU(phiY)) : 0e0;
0545 double thetaZ = xrot.hasAttr(_CMU(thetaZ)) ? _ns.attr<double>(xrot,_CMU(thetaZ)) : 0e0;
0546 double phiZ = xrot.hasAttr(_CMU(phiZ)) ? _ns.attr<double>(xrot,_CMU(phiZ)) : 0e0;
0547 Rotation3D rot = make_rotation3D(thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
0548
0549 _ns.addRotation(nam, rot);
0550 if ( isActivePrintLevel(lvl) ) {
0551 double det;
0552 Position x, y, z;
0553 stringstream str;
0554 rot.GetComponents(x,y,z);
0555 det = (x.Cross(y)).Dot(z);
0556 str << "+++ rotation: " << nam
0557 << " " << ((det>=0) ? "RIGHT" : "LEFT") << "-handed "
0558 << scientific << setprecision(2) << setw(9) << x << y << z << rot;
0559 printout(lvl, "DDCMS",
0560 "+++ Adding rotation: %-18s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
0561 _ns.prepend(nam).c_str(),thetaX,phiX,thetaY,phiY,thetaZ,phiZ);
0562 printout(lvl, "DDCMS", str.str().c_str());
0563 }
0564 }
0565
0566
0567 template <> void Converter<logicalpart>::operator()(xml_h element) const {
0568 Namespace _ns(_param<ParsingContext>());
0569 xml_dim_t e(element);
0570 string sol = e.child(_CMU(rSolid)).attr<string>(_U(name));
0571 string mat = e.child(_CMU(rMaterial)).attr<string>(_U(name));
0572 _ns.addVolume(Volume(e.nameStr(), _ns.solid(sol), _ns.material(mat)));
0573 }
0574
0575
0576 template <> void Converter<transform3d>::operator()(xml_h element) const {
0577 Namespace _ns(_param<ParsingContext>());
0578 Transform3D* tr = _option<Transform3D>();
0579 xml_dim_t e(element);
0580 xml_dim_t translation = e.child(_CMU(Translation),false);
0581 xml_dim_t rotation = e.child(_CMU(Rotation),false);
0582 xml_dim_t rRotation = e.child(_CMU(rRotation),false);
0583 xml_dim_t rReflectionRotation = e.child(_CMU(rReflectionRotation),false);
0584 Position pos;
0585 Rotation3D rot;
0586
0587 if ( translation.ptr() ) {
0588 double x = _ns.attr<double>(translation,_U(x));
0589 double y = _ns.attr<double>(translation,_U(y));
0590 double z = _ns.attr<double>(translation,_U(z));
0591 pos = Position(x,y,z);
0592 }
0593 if ( rotation.ptr() ) {
0594 double x = _ns.attr<double>(rotation,_U(x));
0595 double y = _ns.attr<double>(rotation,_U(y));
0596 double z = _ns.attr<double>(rotation,_U(z));
0597 rot = RotationZYX(z,y,x);
0598 }
0599 else if ( rRotation.ptr() ) {
0600 rot = _ns.rotation(rRotation.nameStr());
0601 }
0602 else if ( rReflectionRotation.ptr() ) {
0603 rot = _ns.rotation(rReflectionRotation.nameStr());
0604 }
0605 *tr = Transform3D(rot,pos);
0606 }
0607
0608
0609 template <> void Converter<pospart>::operator()(xml_h element) const {
0610 Namespace _ns(_param<ParsingContext>());
0611 xml_dim_t e(element);
0612 int copy = e.attr<int>(_CMU(copyNumber));
0613 string parent_nam = _ns.attr<string>(e.child(_CMU(rParent)),_U(name));
0614 string child_nam = _ns.attr<string>(e.child(_CMU(rChild)),_U(name));
0615 Volume parent = _ns.volume(parent_nam);
0616 Volume child = _ns.volume(child_nam, false);
0617 PrintLevel lvl = _ns.context->debug.placements ? ALWAYS : DEBUG;
0618 bool dbg = isActivePrintLevel(lvl);
0619
0620 if ( dbg ) {
0621 printout(lvl, "DDCMS", "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
0622 e.tag().c_str(),
0623 parent_nam.c_str(), parent.isValid() ? "VALID" : "INVALID",
0624 child_nam.c_str(), child.isValid() ? "VALID" : "INVALID",
0625 copy);
0626 }
0627 PlacedVolume pv;
0628 if ( child.isValid() ) {
0629 Transform3D trafo;
0630 Converter<transform3d>(description,param,&trafo)(element);
0631 pv = parent.placeVolume(child, copy, trafo);
0632 if ( dbg ) {
0633 stringstream str;
0634 Rotation3D r;
0635 Position p, x, y, z;
0636 xml_dim_t rRotation = e.child(_CMU(rRotation),false);
0637 xml_dim_t rReflectionRotation = e.child(_CMU(rReflectionRotation),false);
0638 trafo.GetDecomposition(r, p);
0639 r.GetComponents(x,y,z);
0640 double det = (x.Cross(y)).Dot(z);
0641 str << "+++ Rotation: " << (const char*)((det >=0) ? "RIGHT" : "LEFT") << "-handed ";
0642 if ( rRotation.ptr() ) str << rRotation.nameStr();
0643 if ( rReflectionRotation.ptr() ) str << rReflectionRotation.nameStr();
0644 str << " Pos: " << p << " Rotation:" << r;
0645 printout(lvl, "DDCMS", str.str().c_str());
0646 }
0647 }
0648 if ( !pv.isValid() ) {
0649 printout(ERROR,"DDCMS","+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
0650 parent.name(), child_nam.c_str(), yes_no(child.isValid()));
0651 }
0652 }
0653
0654 template <typename TYPE>
0655 static void convert_boolean(ParsingContext* ctx, xml_h element) {
0656 Namespace _ns(ctx);
0657 xml_dim_t e(element);
0658 string nam = e.nameStr();
0659 Solid solids[2];
0660 Solid boolean;
0661 int cnt = 0;
0662
0663 if ( e.hasChild(_CMU(rSolid)) ) {
0664 for(xml_coll_t c(element, _CMU(rSolid)); cnt<2 && c; ++c, ++cnt)
0665 solids[cnt] = _ns.solid(c.attr<string>(_U(name)));
0666 }
0667 else {
0668 if ( (solids[0] = _ns.solid(e.attr<string>(_CMU(firstSolid)))).isValid() ) ++cnt;
0669 if ( (solids[1] = _ns.solid(e.attr<string>(_CMU(secondSolid)))).isValid() ) ++cnt;
0670 }
0671 if ( cnt != 2 ) {
0672 except("DDCMS","+++ Failed to create boolean solid %s. Found only %d parts.",nam.c_str(), cnt);
0673 }
0674 printout(_ns.context->debug.placements ? ALWAYS : DEBUG, "DDCMS",
0675 "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
0676 nam.c_str(), solids[0]->GetName(), solids[1]->GetName());
0677
0678 if ( solids[0].isValid() && solids[1].isValid() ) {
0679 Transform3D trafo;
0680 Converter<transform3d>(*ctx->description,ctx,&trafo)(element);
0681 boolean = TYPE(solids[0],solids[1],trafo);
0682 }
0683 if ( !boolean.isValid() )
0684 except("DDCMS","+++ FAILED to construct subtraction solid: %s",nam.c_str());
0685 _ns.addSolid(nam,boolean);
0686 }
0687
0688
0689 template <> void Converter<unionsolid>::operator()(xml_h element) const {
0690 convert_boolean<UnionSolid>(_param<ParsingContext>(),element);
0691 }
0692
0693
0694 template <> void Converter<subtractionsolid>::operator()(xml_h element) const {
0695 convert_boolean<SubtractionSolid>(_param<ParsingContext>(),element);
0696 }
0697
0698
0699 template <> void Converter<intersectionsolid>::operator()(xml_h element) const {
0700 convert_boolean<IntersectionSolid>(_param<ParsingContext>(),element);
0701 }
0702
0703
0704 template <> void Converter<polycone>::operator()(xml_h element) const {
0705 Namespace _ns(_param<ParsingContext>());
0706 xml_dim_t e(element);
0707 string nam = e.nameStr();
0708 double startPhi = _ns.attr<double>(e,_CMU(startPhi));
0709 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi));
0710 vector<double> z, rmin, rmax;
0711
0712 for(xml_coll_t zplane(element, _CMU(RZPoint)); zplane; ++zplane) {
0713 rmin.push_back(0.0);
0714 rmax.push_back(_ns.attr<double>(zplane,_U(r)));
0715 z.push_back(_ns.attr<double>(zplane,_U(z)));
0716 }
0717 for(xml_coll_t zplane(element, _CMU(ZSection)); zplane; ++zplane) {
0718 rmin.push_back(_ns.attr<double>(zplane,_CMU(rMin)));
0719 rmax.push_back(_ns.attr<double>(zplane,_CMU(rMax)));
0720 z.push_back(_ns.attr<double>(zplane,_U(z)));
0721 }
0722 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0723 "+ Polycone: startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4ld z-planes",
0724 startPhi, deltaPhi, z.size());
0725 _ns.addSolid(nam, Polycone(startPhi,deltaPhi,rmin,rmax,z));
0726 }
0727
0728
0729 template <> void Converter<extrudedpolygon>::operator()(xml_h element) const {
0730 Namespace _ns(_param<ParsingContext>());
0731 xml_dim_t e(element);
0732 string nam = e.nameStr();
0733 vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
0734
0735 for(xml_coll_t sec(element, _CMU(ZXYSection)); sec; ++sec) {
0736 sec_z.push_back(_ns.attr<double>(sec,_U(z)));
0737 sec_x.push_back(_ns.attr<double>(sec,_U(x)));
0738 sec_y.push_back(_ns.attr<double>(sec,_U(y)));
0739 sec_scale.push_back(_ns.attr<double>(sec,_CMU(scale),1.0));
0740 }
0741 for(xml_coll_t pt(element, _CMU(XYPoint)); pt; ++pt) {
0742 pt_x.push_back(_ns.attr<double>(pt,_U(x)));
0743 pt_y.push_back(_ns.attr<double>(pt,_U(y)));
0744 }
0745 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0746 "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
0747 pt_x.size(), sec_z.size());
0748 _ns.addSolid(nam,ExtrudedPolygon(pt_x,pt_y,sec_z,sec_x,sec_y,sec_scale));
0749 }
0750
0751
0752 template <> void Converter<polyhedra>::operator()(xml_h element) const {
0753 Namespace _ns(_param<ParsingContext>());
0754 xml_dim_t e(element);
0755 string nam = e.nameStr();
0756 double numSide = _ns.attr<int>(e,_CMU(numSide));
0757 double startPhi = _ns.attr<double>(e,_CMU(startPhi));
0758 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi));
0759 vector<double> z, rmin, rmax;
0760
0761 for(xml_coll_t zplane(element, _CMU(RZPoint)); zplane; ++zplane) {
0762 rmin.push_back(0.0);
0763 rmax.push_back(_ns.attr<double>(zplane,_U(r)));
0764 z.push_back(_ns.attr<double>(zplane,_U(z)));
0765 }
0766 for(xml_coll_t zplane(element, _CMU(ZSection)); zplane; ++zplane) {
0767 rmin.push_back(_ns.attr<double>(zplane,_CMU(rMin)));
0768 rmax.push_back(_ns.attr<double>(zplane,_CMU(rMax)));
0769 z.push_back(_ns.attr<double>(zplane,_U(z)));
0770 }
0771 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0772 "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
0773 startPhi, deltaPhi, numSide, z.size());
0774 _ns.addSolid(nam, Polyhedra(numSide,startPhi,deltaPhi,z,rmin,rmax));
0775 }
0776
0777
0778 template <> void Converter<sphere>::operator()(xml_h element) const {
0779 Namespace _ns(_param<ParsingContext>());
0780 xml_dim_t e(element);
0781 string nam = e.nameStr();
0782 double rinner = _ns.attr<double>(e,_CMU(innerRadius));
0783 double router = _ns.attr<double>(e,_CMU(outerRadius));
0784 double startPhi = _ns.attr<double>(e,_CMU(startPhi));
0785 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi));
0786 double startTheta = _ns.attr<double>(e,_CMU(startTheta));
0787 double deltaTheta = _ns.attr<double>(e,_CMU(deltaTheta));
0788 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0789 "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]"
0790 " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
0791 rinner, router, startPhi, deltaPhi, startTheta, deltaTheta);
0792 _ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi, deltaPhi));
0793 }
0794
0795
0796 template <> void Converter<ellipsoid>::operator()(xml_h element) const {
0797 Namespace _ns(_param<ParsingContext>());
0798 xml_dim_t e(element);
0799 string nam = e.nameStr();
0800 double dx = _ns.attr<double>(e,_CMU(xSemiAxis));
0801 double dy = _ns.attr<double>(e,_CMU(ySemiAxis));
0802 double dz = _ns.attr<double>(e,_CMU(zSemiAxis));
0803 double zBot = _ns.attr<double>(e,_CMU(zBottomCut),0.0);
0804 double zTop = _ns.attr<double>(e,_CMU(zTopCut),0.0);
0805
0806 printout(WARNING, "DDCMS",
0807 "+ Ellipsoid UNSUPPORTED. '%s' REPLACED BY BOX "
0808 " xSemiAxis=%8.3f ySemiAxis=%8.3f zSemiAxis=%8.3f zBottomCut=%8.3f zTopCut=%8.3f [cm]",
0809 nam.c_str(), dx, dy, dz, zBot, zTop);
0810 _ns.addSolid(nam, Box(1,1,1));
0811 }
0812
0813
0814 template <> void Converter<torus>::operator()(xml_h element) const {
0815 Namespace _ns(_param<ParsingContext>());
0816 xml_dim_t e(element);
0817 string nam = e.nameStr();
0818 double r = _ns.attr<double>(e,_CMU(torusRadius));
0819 double rinner = _ns.attr<double>(e,_CMU(innerRadius));
0820 double router = _ns.attr<double>(e,_CMU(outerRadius));
0821 double startPhi = _ns.attr<double>(e,_CMU(startPhi));
0822 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi));
0823 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0824 "+ Torus: r=%8.3f [cm] r_inner=%8.3f [cm] r_outer=%8.3f [cm]"
0825 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
0826 r, rinner, router, startPhi, deltaPhi);
0827 _ns.addSolid(nam, Torus(r, rinner, router, startPhi, deltaPhi));
0828 }
0829
0830
0831 template <> void Converter<pseudotrap>::operator()(xml_h element) const {
0832 Namespace _ns(_param<ParsingContext>());
0833 xml_dim_t e(element);
0834 string nam = e.nameStr();
0835 double dx1 = _ns.attr<double>(e,_CMU(dx1));
0836 double dy1 = _ns.attr<double>(e,_CMU(dy1));
0837 double dx2 = _ns.attr<double>(e,_CMU(dx2));
0838 double dy2 = _ns.attr<double>(e,_CMU(dy2));
0839 double dz = _ns.attr<double>(e,_U(dz));
0840 double r = _ns.attr<double>(e,_U(radius));
0841 bool atMinusZ = _ns.attr<bool> (e,_CMU(atMinusZ));
0842 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0843 "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
0844 dz, dx1, dy1, dx2, dy2, r, yes_no(atMinusZ));
0845 _ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2, dz, r, atMinusZ));
0846 }
0847
0848
0849 template <> void Converter<trapezoid>::operator()(xml_h element) const {
0850 Namespace _ns(_param<ParsingContext>());
0851 xml_dim_t e(element);
0852 string nam = e.nameStr();
0853 double dz = _ns.attr<double>(e,_U(dz));
0854 double alp1 = _ns.attr<double>(e,_CMU(alp1));
0855 double bl1 = _ns.attr<double>(e,_CMU(bl1));
0856 double tl1 = _ns.attr<double>(e,_CMU(tl1));
0857 double h1 = _ns.attr<double>(e,_CMU(h1));
0858 double alp2 = _ns.attr<double>(e,_CMU(alp2));
0859 double bl2 = _ns.attr<double>(e,_CMU(bl2));
0860 double tl2 = _ns.attr<double>(e,_CMU(tl2));
0861 double h2 = _ns.attr<double>(e,_CMU(h2));
0862 double phi = _ns.attr<double>(e,_U(phi),0.0);
0863 double theta = _ns.attr<double>(e,_U(theta),0.0);
0864 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0865 "+ Trapezoid: dz=%8.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f theta=%.3f",
0866 dz, alp1, bl1, tl1, h1, alp2, bl2, tl2, h2, phi, theta);
0867 _ns.addSolid(nam, Trap(dz, theta, phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
0868 }
0869
0870
0871 template <> void Converter<trd1>::operator()(xml_h element) const {
0872 Namespace _ns(_param<ParsingContext>());
0873 xml_dim_t e(element);
0874 string nam = e.nameStr();
0875 double dx1 = _ns.attr<double>(e,_CMU(dx1));
0876 double dy1 = _ns.attr<double>(e,_CMU(dy1));
0877 double dx2 = _ns.attr<double>(e,_CMU(dx2),0.0);
0878 double dy2 = _ns.attr<double>(e,_CMU(dy2),0.0);
0879 double dz = _ns.attr<double>(e,_CMU(dz));
0880 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0881 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
0882 dz, dx1, dy1, dx2, dy2);
0883 if ( dy1 == dy2 )
0884 _ns.addSolid(nam, Trd1(dx1, dx2, dy1, dz));
0885 else
0886 _ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2, dz));
0887 }
0888
0889
0890 template <> void Converter<tubs>::operator()(xml_h element) const {
0891 Namespace _ns(_param<ParsingContext>());
0892 xml_dim_t e(element);
0893 string nam = e.nameStr();
0894 double dz = _ns.attr<double>(e,_CMU(dz));
0895 double rmin = _ns.attr<double>(e,_CMU(rMin));
0896 double rmax = _ns.attr<double>(e,_CMU(rMax));
0897 double startPhi = _ns.attr<double>(e,_CMU(startPhi),0.0);
0898 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi),2*M_PI);
0899 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0900 "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
0901 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]", dz, rmin, rmax, startPhi, deltaPhi);
0902 _ns.addSolid(nam, Tube(rmin,rmax,dz,startPhi,deltaPhi));
0903 }
0904
0905
0906 template <> void Converter<cuttubs>::operator()(xml_h element) const {
0907 Namespace _ns(_param<ParsingContext>());
0908 xml_dim_t e(element);
0909 string nam = e.nameStr();
0910 double dz = _ns.attr<double>(e,_CMU(dz));
0911 double rmin = _ns.attr<double>(e,_CMU(rMin));
0912 double rmax = _ns.attr<double>(e,_CMU(rMax));
0913 double startPhi = _ns.attr<double>(e,_CMU(startPhi));
0914 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi));
0915 double lx = _ns.attr<double>(e,_CMU(lx));
0916 double ly = _ns.attr<double>(e,_CMU(ly));
0917 double lz = _ns.attr<double>(e,_CMU(lz));
0918 double tx = _ns.attr<double>(e,_CMU(tx));
0919 double ty = _ns.attr<double>(e,_CMU(ty));
0920 double tz = _ns.attr<double>(e,_CMU(tz));
0921 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0922 "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
0923 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
0924 dz, rmin, rmax, startPhi, deltaPhi);
0925 _ns.addSolid(nam, CutTube(rmin,rmax,dz,startPhi,deltaPhi,lx,ly,lz,tx,ty,tz));
0926 }
0927
0928
0929 template <> void Converter<trunctubs>::operator()(xml_h element) const {
0930 Namespace _ns(_param<ParsingContext>());
0931 xml_dim_t e(element);
0932 string nam = e.nameStr();
0933 double zhalf = _ns.attr<double>(e,_CMU(zHalf));
0934 double rmin = _ns.attr<double>(e,_CMU(rMin));
0935 double rmax = _ns.attr<double>(e,_CMU(rMax));
0936 double startPhi = _ns.attr<double>(e,_CMU(startPhi));
0937 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi));
0938 double cutAtStart = _ns.attr<double>(e,_CMU(cutAtStart));
0939 double cutAtDelta = _ns.attr<double>(e,_CMU(cutAtDelta));
0940 bool cutInside = _ns.attr<bool>(e,_CMU(cutInside));
0941 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0942 "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
0943 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
0944 zhalf, rmin, rmax, startPhi, deltaPhi, cutAtStart, cutAtDelta, yes_no(cutInside));
0945 _ns.addSolid(nam, TruncatedTube(zhalf,rmin,rmax,startPhi,deltaPhi,cutAtStart,cutAtDelta,cutInside));
0946 }
0947
0948
0949 template <> void Converter<ellipticaltube>::operator()(xml_h element) const {
0950 Namespace _ns(_param<ParsingContext>());
0951 xml_dim_t e(element);
0952 string nam = e.nameStr();
0953 double dx = _ns.attr<double>(e,_CMU(xSemiAxis));
0954 double dy = _ns.attr<double>(e,_CMU(ySemiAxis));
0955 double dz = _ns.attr<double>(e,_CMU(zHeight));
0956 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0957 "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",dx,dy,dz);
0958 _ns.addSolid(nam, EllipticalTube(dx,dy,dz));
0959 }
0960
0961
0962 template <> void Converter<cone>::operator()(xml_h element) const {
0963 Namespace _ns(_param<ParsingContext>());
0964 xml_dim_t e(element);
0965 string nam = e.nameStr();
0966 double dz = _ns.attr<double>(e,_CMU(dz));
0967 double rmin1 = _ns.attr<double>(e,_CMU(rMin1));
0968 double rmin2 = _ns.attr<double>(e,_CMU(rMin2));
0969 double rmax1 = _ns.attr<double>(e,_CMU(rMax1));
0970 double rmax2 = _ns.attr<double>(e,_CMU(rMax2));
0971 double startPhi = _ns.attr<double>(e,_CMU(startPhi));
0972 double deltaPhi = _ns.attr<double>(e,_CMU(deltaPhi));
0973 double phi2 = startPhi + deltaPhi;
0974 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0975 "+ Cone: dz=%8.3f [cm]"
0976 " rmin1=%8.3f [cm] rmax1=%8.3f [cm]"
0977 " rmin2=%8.3f [cm] rmax2=%8.3f [cm]"
0978 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
0979 dz, rmin1, rmax1, rmin2, rmax2, startPhi, deltaPhi);
0980 _ns.addSolid(nam, ConeSegment(dz,rmin1,rmax1,rmin2,rmax2,startPhi,phi2));
0981 }
0982
0983
0984 template <> void Converter<shapeless>::operator()(xml_h element) const {
0985 Namespace _ns(_param<ParsingContext>());
0986 xml_dim_t e(element);
0987 string nam = e.nameStr();
0988 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
0989 "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Assembly%s", nam.c_str());
0990 _ns.addSolid(nam, Box(1,1,1));
0991 }
0992
0993
0994 template <> void Converter<box>::operator()(xml_h element) const {
0995 Namespace _ns(_param<ParsingContext>());
0996 xml_dim_t e(element);
0997 string nam = e.nameStr();
0998 double dx = _ns.attr<double>(e,_CMU(dx));
0999 double dy = _ns.attr<double>(e,_CMU(dy));
1000 double dz = _ns.attr<double>(e,_CMU(dz));
1001 printout(_ns.context->debug.shapes ? ALWAYS : DEBUG, "DDCMS",
1002 "+ Box: dx=%8.3f [cm] dy=%8.3f [cm] dz=%8.3f [cm]", dx, dy, dz);
1003 _ns.addSolid(nam, Box(dx,dy,dz));
1004 }
1005
1006
1007 template <> void Converter<orb>::operator()(xml_h element) const {
1008 Namespace _ns(_param<ParsingContext>());
1009 xml_dim_t e(element);
1010 string nam = e.nameStr();
1011 double r = _ns.attr<double>(e,_U(radius));
1012 printout(WARNING, "DDCMS",
1013 "+ Orb UNSUPPORTED. %s REPLACED BY BOX: r=%8.3f [cm]", nam.c_str(), r);
1014 _ns.addSolid(nam, Box(r,r,r));
1015 }
1016
1017
1018 template <> void Converter<include_load>::operator()(xml_h element) const {
1019 TString fname = element.attr<string>(_U(ref)).c_str();
1020 const char* path = gSystem->Getenv("DDCMS_XML_PATH");
1021 xml::Document doc;
1022 if ( path && gSystem->FindFile(path,fname) )
1023 doc = xml::DocumentHandler().load(fname.Data());
1024 else
1025 doc = xml::DocumentHandler().load(element, element.attr_value(_U(ref)));
1026 fname = xml::DocumentHandler::system_path(doc.root());
1027 printout(_param<ParsingContext>()->debug.includes ? ALWAYS : DEBUG,
1028 "DDCMS","+++ Processing the CMS detector description %s",fname.Data());
1029 _option<resolve>()->includes.push_back(doc);
1030 }
1031
1032
1033 template <> void Converter<include_unload>::operator()(xml_h element) const {
1034 string fname = xml::DocumentHandler::system_path(element);
1035 xml::DocumentHolder(xml_elt_t(element).document()).assign(0);
1036 printout(_param<ParsingContext>()->debug.includes ? ALWAYS : DEBUG,
1037 "DDCMS","+++ Finished processing %s",fname.c_str());
1038 }
1039
1040
1041 template <> void Converter<include_constants>::operator()(xml_h element) const {
1042 xml_coll_t(element, _CMU(ConstantsSection)).for_each(Converter<constantssection>(description,param,optional));
1043 }
1044
1045 namespace {
1046
1047
1048
1049
1050
1051
1052
1053 enum class DDAxes { x = 1, y = 2, z = 3, rho = 1, phi = 2, undefined };
1054 const std::map<std::string, DDAxes> axesmap{{"x", DDAxes::x},
1055 {"y", DDAxes::y},
1056 {"z", DDAxes::z},
1057 {"rho", DDAxes::rho},
1058 {"phi", DDAxes::phi},
1059 {"undefined", DDAxes::undefined}};
1060 }
1061
1062
1063 template <>
1064 void Converter<division>::operator()(xml_h element) const {
1065 Namespace _ns(_param<ParsingContext>());
1066 xml_dim_t e(element);
1067 string childName = e.nameStr();
1068 if (strchr(childName.c_str(), NAMESPACE_SEP) == nullptr)
1069 childName = _ns.prepend(childName);
1070
1071 string parentName = _ns.attr<string>(e, _CMU(parent));
1072 if (strchr(parentName.c_str(), NAMESPACE_SEP) == nullptr)
1073 parentName = _ns.prepend(parentName);
1074 string axis = _ns.attr<string>(e, _CMU(axis));
1075
1076
1077
1078 double offset = e.hasAttr(_CMU(offset)) ? _ns.attr<double>(e, _CMU(offset)) : 0e0;
1079 double width = e.hasAttr(_CMU(width)) ? _ns.attr<double>(e, _CMU(width)) : 0e0;
1080 int nReplicas = e.hasAttr(_CMU(nReplicas)) ? _ns.attr<int>(e, _CMU(nReplicas)) : 0;
1081
1082 printout(_ns.context->debug.placements ? ALWAYS : DEBUG,
1083 "DD4CMS",
1084 "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1085 parentName.c_str(),
1086 axis.c_str(),
1087 axesmap.at(axis),
1088 offset,
1089 width,
1090 childName.c_str());
1091
1092 Volume parent = _ns.volume(parentName);
1093
1094 const TGeoShape* shape = parent.solid();
1095 TClass* cl = shape->IsA();
1096 if (cl == TGeoTubeSeg::Class()) {
1097 const TGeoTubeSeg* sh = (const TGeoTubeSeg*)shape;
1098 double widthInDeg = convertRadToDeg(width);
1099 double startInDeg = convertRadToDeg(offset);
1100 int numCopies = (int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1101
1102 printout(_ns.context->debug.placements ? ALWAYS : DEBUG,
1103 "DD4CMS",
1104 "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1105 parent.solid().type(),
1106 axis.c_str(),
1107 axesmap.at(axis),
1108 startInDeg,
1109 widthInDeg,
1110 numCopies);
1111 Volume child = parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1112
1113 _ns.context->volumes[childName] = child;
1114 printout(_ns.context->debug.placements ? ALWAYS : DEBUG,
1115 "DD4CMS",
1116 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1117 e.tag().c_str(),
1118 parentName.c_str(),
1119 parent.isValid() ? "VALID" : "INVALID",
1120 child.name(),
1121 child.isValid() ? "VALID" : "INVALID",
1122 child->IsVolumeMulti() ? "YES" : "NO");
1123 } else if (cl == TGeoTrd1::Class() ) {
1124 double dy = static_cast<const TGeoTrd1*>(shape)->GetDy();
1125 printout(_ns.context->debug.placements ? ALWAYS : DEBUG,
1126 "DD4CMS",
1127 "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1128 parent.solid().type(),
1129 axis.c_str(),
1130 axesmap.at(axis),
1131 -dy + offset + width,
1132 width,
1133 nReplicas,
1134 dy);
1135
1136 Volume child = parent.divide(childName, static_cast<int>(axesmap.at(axis)), nReplicas, -dy + offset + width, width);
1137
1138 _ns.context->volumes[childName] = child;
1139 printout(_ns.context->debug.placements ? ALWAYS : DEBUG,
1140 "DD4CMS",
1141 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1142 e.tag().c_str(),
1143 parentName.c_str(),
1144 parent.isValid() ? "VALID" : "INVALID",
1145 child.name(),
1146 child.isValid() ? "VALID" : "INVALID",
1147 child->IsVolumeMulti() ? "YES" : "NO");
1148 } else {
1149 printout(ERROR, "DD4CMS", "++ FAILED Division of a %s is not implemented yet!", parent.solid().type());
1150 }
1151 }
1152
1153
1154 template <> void Converter<algorithm>::operator()(xml_h element) const {
1155 Namespace _ns(_param<ParsingContext>());
1156 xml_dim_t e(element);
1157 string name = e.nameStr();
1158 if ( _ns.context->disabledAlgs.find(name) != _ns.context->disabledAlgs.end() ) {
1159 printout(INFO,"DDCMS","+++ Skip disabled algorithms: %s",name.c_str());
1160 return;
1161 }
1162 try {
1163 size_t idx;
1164 SensitiveDetector sd;
1165 string type = "DDCMS_"+_ns.real_name(name);
1166 while ( (idx=type.find(NAMESPACE_SEP)) != string::npos ) type[idx]='_';
1167
1168
1169
1170 printout(_ns.context->debug.algorithms ? ALWAYS : DEBUG,
1171 "DDCMS","+++ Start executing algorithm %s....",type.c_str());
1172 LogDebug context(e.nameStr(),true);
1173 long ret = PluginService::Create<long>(type, &description, _ns.context, &element, &sd);
1174 if ( ret == 1 ) {
1175 printout(_ns.context->debug.algorithms ? ALWAYS : DEBUG,
1176 "DDCMS", "+++ Executed algorithm: %08lX = %s", ret, name.c_str());
1177 return;
1178 }
1179 #if 0
1180 DetElement det(PluginService::Create<NamedObject*>(type, &description, _ns.context, &element, &sd));
1181 if (det.isValid()) {
1182
1183 if ( sd.isValid() ) {
1184 det->flag |= DetElement::Object::HAVE_SENSITIVE_DETECTOR;
1185 }
1186 if ( seg.isValid() ) {
1187 seg->sensitive = sd;
1188 seg->detector = det;
1189 }
1190 }
1191 if (!det.isValid()) {
1192 PluginDebug dbg;
1193 PluginService::Create<NamedObject*>(type, &description, _ns.context, &element, &sd);
1194 except("DDCMS","Failed to execute subdetector creation plugin. " + dbg.missingFactory(type));
1195 }
1196 description.addDetector(det);
1197 #endif
1198
1199 printout(ERROR, "DDCMS", "++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",ret, name.c_str());
1200 return;
1201 }
1202 catch (const exception& exc) {
1203 printout(ERROR, "DDCMS", "++ FAILED to convert subdetector: %s: %s", name.c_str(), exc.what());
1204 terminate();
1205 }
1206 catch (...) {
1207 printout(ERROR, "DDCMS", "++ FAILED to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
1208 terminate();
1209 }
1210 }
1211
1212 template <> void Converter<debug>::operator()(xml_h dbg) const {
1213 Namespace _ns(_param<ParsingContext>());
1214 if ( dbg.hasChild(_CMU(debug_visattr)) ) _ns.context->debug.visattr = true;
1215 if ( dbg.hasChild(_CMU(debug_constants)) ) _ns.context->debug.constants = true;
1216 if ( dbg.hasChild(_CMU(debug_materials)) ) _ns.context->debug.materials = true;
1217 if ( dbg.hasChild(_CMU(debug_rotations)) ) _ns.context->debug.rotations = true;
1218 if ( dbg.hasChild(_CMU(debug_shapes)) ) _ns.context->debug.shapes = true;
1219 if ( dbg.hasChild(_CMU(debug_volumes)) ) _ns.context->debug.volumes = true;
1220 if ( dbg.hasChild(_CMU(debug_placements)) ) _ns.context->debug.placements = true;
1221 if ( dbg.hasChild(_CMU(debug_namespaces)) ) _ns.context->debug.namespaces = true;
1222 if ( dbg.hasChild(_CMU(debug_includes)) ) _ns.context->debug.includes = true;
1223 if ( dbg.hasChild(_CMU(debug_algorithms)) ) _ns.context->debug.algorithms = true;
1224 LogDebug::setDebugAlgorithms(_ns.context->debug.algorithms);
1225 }
1226
1227 template <> void Converter<resolve>::operator()(xml_h ) const {
1228 ParsingContext* ctx = _param<ParsingContext>();
1229 resolve* res = _option<resolve>();
1230 Namespace _ns(ctx);
1231 int count = 0;
1232
1233 printout(ctx->debug.constants ? ALWAYS : DEBUG,
1234 "DDCMS","+++ RESOLVING %ld unknown constants.....",res->unresolvedConst.size());
1235 while ( !res->unresolvedConst.empty() ) {
1236 for(auto i=res->unresolvedConst.begin(); i!=res->unresolvedConst.end(); ++i ) {
1237 const string& n = (*i).first;
1238 string rep;
1239 string& v = (*i).second;
1240 size_t idx, idq;
1241 for(idx=v.find('[',0); idx != string::npos; idx = v.find('[',idx+1) ) {
1242 idq = v.find(']',idx+1);
1243 rep = v.substr(idx+1,idq-idx-1);
1244 auto r = res->allConst.find(rep);
1245 if ( r != res->allConst.end() ) {
1246 rep = "("+(*r).second+")";
1247 v.replace(idx,idq-idx+1,rep);
1248 }
1249 }
1250 if ( v.find(']') == string::npos ) {
1251 if ( v.find("-+") != string::npos || v.find("+-") != string::npos ) {
1252 while ( (idx=v.find("-+")) != string::npos )
1253 v.replace(idx,2,"-");
1254 while ( (idx=v.find("+-")) != string::npos )
1255 v.replace(idx,2,"-");
1256 }
1257 printout(ctx->debug.constants ? ALWAYS : DEBUG,
1258 "DDCMS","+++ [%06ld] ---------- %-40s = %s",
1259 res->unresolvedConst.size()-1,n.c_str(),res->originalConst[n].c_str());
1260 _ns.addConstantNS(n, v, "number");
1261 res->unresolvedConst.erase(i);
1262 break;
1263 }
1264 }
1265 if ( ++count > 1000 ) break;
1266 }
1267 if ( !res->unresolvedConst.empty() ) {
1268 for(const auto& e : res->unresolvedConst )
1269 printout(ERROR,"DDCMS","+++ Unresolved constant: %-40s = %s.",e.first.c_str(), e.second.c_str());
1270 except("DDCMS","++ FAILED to resolve %ld constant entries:",res->unresolvedConst.size());
1271 }
1272 res->unresolvedConst.clear();
1273 res->originalConst.clear();
1274 res->allConst.clear();
1275 }
1276
1277 template <> void Converter<print_xml_doc>::operator()(xml_h element) const {
1278 string fname = xml::DocumentHandler::system_path(element);
1279 printout(_param<ParsingContext>()->debug.includes ? ALWAYS : DEBUG,
1280 "DDCMS","+++ Processing data from: %s",fname.c_str());
1281 }
1282
1283
1284 static long load_dddefinition(Detector& det, xml_h element) {
1285 xml_elt_t dddef(element);
1286 if ( dddef ) {
1287 static ParsingContext ctxt(&det);
1288 Namespace _ns(ctxt);
1289 string fname = xml::DocumentHandler::system_path(element);
1290 bool open_geometry = dddef.hasChild(_CMU(open_geometry));
1291 bool close_geometry = dddef.hasChild(_CMU(close_geometry));
1292
1293 xml_coll_t(dddef, _U(debug)).for_each(Converter<debug>(det,&ctxt));
1294
1295
1296
1297
1298 printout(INFO,"DDCMS","+++ Processing the CMS detector description %s",fname.c_str());
1299
1300 xml::Document doc;
1301 Converter<print_xml_doc> print_doc(det,&ctxt);
1302 try {
1303 resolve res;
1304 print_doc((doc=dddef.document()).root());
1305 xml_coll_t(dddef, _CMU(DisabledAlgo)).for_each(Converter<disabled_algo>(det,&ctxt,&res));
1306 xml_coll_t(dddef, _CMU(ConstantsSection)).for_each(Converter<constantssection>(det,&ctxt,&res));
1307 xml_coll_t(dddef, _CMU(VisSection)).for_each(Converter<vissection>(det,&ctxt));
1308 xml_coll_t(dddef, _CMU(RotationSection)).for_each(Converter<rotationsection>(det,&ctxt));
1309 xml_coll_t(dddef, _CMU(MaterialSection)).for_each(Converter<materialsection>(det,&ctxt));
1310
1311 xml_coll_t(dddef, _CMU(IncludeSection)).for_each(_CMU(Include), Converter<include_load>(det,&ctxt,&res));
1312
1313 for(xml::Document d : res.includes ) {
1314 print_doc((doc=d).root());
1315 Converter<include_constants>(det,&ctxt,&res)((doc=d).root());
1316 }
1317
1318 Converter<resolve>(det,&ctxt,&res)(dddef);
1319
1320 for(xml::Document d : res.includes ) {
1321 print_doc((doc=d).root());
1322 xml_coll_t(d.root(),_CMU(MaterialSection)).for_each(Converter<materialsection>(det,&ctxt));
1323 }
1324 if ( open_geometry ) {
1325 ctxt.geo_inited = true;
1326 det.init();
1327 _ns.addVolume(det.worldVolume());
1328 }
1329 for(xml::Document d : res.includes ) {
1330 print_doc((doc=d).root());
1331 xml_coll_t(d.root(),_CMU(RotationSection)).for_each(Converter<rotationsection>(det,&ctxt));
1332 }
1333 for(xml::Document d : res.includes ) {
1334 print_doc((doc=d).root());
1335 xml_coll_t(d.root(), _CMU(SolidSection)).for_each(Converter<solidsection>(det,&ctxt));
1336 }
1337 for(xml::Document d : res.includes ) {
1338 print_doc((doc=d).root());
1339 xml_coll_t(d.root(), _CMU(LogicalPartSection)).for_each(Converter<logicalpartsection>(det,&ctxt));
1340 }
1341 for(xml::Document d : res.includes ) {
1342 print_doc((doc=d).root());
1343 xml_coll_t(d.root(), _CMU(Algorithm)).for_each(Converter<algorithm>(det,&ctxt));
1344 }
1345 for(xml::Document d : res.includes ) {
1346 print_doc((doc=d).root());
1347 xml_coll_t(d.root(), _CMU(PosPartSection)).for_each(Converter<pospartsection>(det,&ctxt));
1348 }
1349
1350
1351 for(xml::Document d : res.includes ) Converter<include_unload>(det,&ctxt,&res)(d.root());
1352
1353 print_doc((doc=dddef.document()).root());
1354
1355 xml_coll_t(dddef, _CMU(SolidSection)).for_each(Converter<solidsection>(det,&ctxt));
1356 xml_coll_t(dddef, _CMU(LogicalPartSection)).for_each(Converter<logicalpartsection>(det,&ctxt));
1357 xml_coll_t(dddef, _CMU(Algorithm)).for_each(Converter<algorithm>(det,&ctxt));
1358 xml_coll_t(dddef, _CMU(PosPartSection)).for_each(Converter<pospartsection>(det,&ctxt));
1359
1360 }
1361 catch(const exception& e) {
1362 printout(ERROR,"DDCMS","Exception while processing xml source:%s",doc.uri().c_str());
1363 printout(ERROR,"DDCMS","----> %s", e.what());
1364 throw;
1365 }
1366
1367
1368 if ( close_geometry ) {
1369 det.endDocument();
1370 }
1371 printout(INFO,"DDDefinition","+++ Finished processing %s",fname.c_str());
1372 return 1;
1373 }
1374 except("DDDefinition","+++ FAILED to process unknown DOM tree [Invalid Handle]");
1375 return 0;
1376 }
1377
1378
1379 DECLARE_XML_DOC_READER(DDDefinition,load_dddefinition)