File indexing completed on 2024-09-24 22:51:13
0001 #include <DetectorDescription/Core/interface/DDMaterial.h>
0002 #include <DetectorDescription/Core/interface/DDPartSelection.h>
0003 #include <DetectorDescription/Core/interface/DDSolid.h>
0004 #include <DetectorDescription/Core/interface/DDSolidShapes.h>
0005 #include <DetectorDescription/Core/interface/DDSpecifics.h>
0006 #include <DetectorDescription/OfflineDBLoader/interface/DDCoreToDDXMLOutput.h>
0007 #include "DetectorDescription/Core/interface/DDRotationMatrix.h"
0008 #include "DetectorDescription/Core/interface/DDTranslation.h"
0009 #include "DetectorDescription/Core/interface/DDName.h"
0010 #include "DetectorDescription/Core/interface/DDPosData.h"
0011 #include "DetectorDescription/Core/interface/DDTransform.h"
0012 #include "DetectorDescription/Core/interface/DDValue.h"
0013 #include "DetectorDescription/Core/interface/DDValuePair.h"
0014
0015 #include "DetectorDescription/DDCMS/interface/DDSolidShapes.h"
0016 #include "DetectorDescription/DDCMS/interface/DDNamespace.h"
0017
0018 #include "DataFormats/Math/interface/GeantUnits.h"
0019 #include "DataFormats/Math/interface/Rounding.h"
0020 #include "FWCore/Utilities/interface/Exception.h"
0021 #include "Math/GenVector/Cartesian3D.h"
0022 #include "Math/GenVector/DisplacementVector3D.h"
0023 #include "Math/GenVector/Rotation3D.h"
0024
0025 #include "DD4hep/Filter.h"
0026 #include "DD4hep/Shapes.h"
0027
0028 #include "TGeoMedium.h"
0029
0030 #include <cstddef>
0031 #include <iomanip>
0032 #include <vector>
0033
0034 using namespace geant_units::operators;
0035
0036 template <class NumType>
0037 static inline constexpr NumType convertGPerCcToMgPerCc(NumType gPerCc)
0038 {
0039 return (gPerCc * 1000.);
0040 }
0041
0042 static constexpr double tol0 = 1.e-11;
0043 static constexpr double reflectTol = 1.0e-3;
0044
0045 namespace cms::rotation_utils {
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 static const std::string identityHash(
0058 "1.00000000.00000000.00000000.00000001.00000000.00000000.00000000.00000001.0000000");
0059
0060 static void addRotWithNewName(cms::DDNamespace& ns, std::string& name, const dd4hep::Rotation3D& rot) {
0061 const dd4hep::Rotation3D& rot2 = rot;
0062 name = name + "_DdNoNa";
0063 ns.addRotation(name, rot2);
0064 }
0065
0066 static void addRotWithNewName(cms::DDNamespace& ns, std::string& name, const Double_t* rot) {
0067 using namespace cms_rounding;
0068 dd4hep::Rotation3D rot2(roundIfNear0(rot[0], tol0),
0069 roundIfNear0(rot[1], tol0),
0070 roundIfNear0(rot[2], tol0),
0071 roundIfNear0(rot[3], tol0),
0072 roundIfNear0(rot[4], tol0),
0073 roundIfNear0(rot[5], tol0),
0074 roundIfNear0(rot[6], tol0),
0075 roundIfNear0(rot[7], tol0),
0076 roundIfNear0(rot[8], tol0));
0077 addRotWithNewName(ns, name, rot2);
0078 }
0079
0080 template <typename T>
0081 static const std::string& rotName(const T& rot, const cms::DDParsingContext& context) {
0082 std::string hashVal = rotHash(rot);
0083 auto rotNameIter = context.rotRevMap.find(hashVal);
0084 if (rotNameIter != context.rotRevMap.end()) {
0085 return (rotNameIter->second);
0086 }
0087 static const std::string nullStr{"NULL"};
0088 return (nullStr);
0089 }
0090
0091 }
0092
0093 std::string DDCoreToDDXMLOutput::trimShapeName(const std::string& solidName) {
0094 size_t trimPt = solidName.find("_shape_0x");
0095 if (trimPt != std::string::npos)
0096 return (solidName.substr(0, trimPt));
0097 return (solidName);
0098 }
0099
0100 void DDCoreToDDXMLOutput::solid(const dd4hep::Solid& solid, const cms::DDParsingContext& context, std::ostream& xos) {
0101 cms::DDSolidShape shape = cms::dd::value(cms::DDSolidShapeMap, std::string(solid.title()));
0102 switch (shape) {
0103 case cms::DDSolidShape::ddunion:
0104 case cms::DDSolidShape::ddsubtraction:
0105 case cms::DDSolidShape::ddintersection: {
0106 dd4hep::BooleanSolid rs(solid);
0107 if (shape == cms::DDSolidShape::ddunion) {
0108 xos << "<UnionSolid ";
0109 } else if (shape == cms::DDSolidShape::ddsubtraction) {
0110 xos << "<SubtractionSolid ";
0111 } else if (shape == cms::DDSolidShape::ddintersection) {
0112 xos << "<IntersectionSolid ";
0113 }
0114 xos << "name=\"" << trimShapeName(solid.name()) << "\">" << std::endl;
0115 xos << "<rSolid name=\"" << trimShapeName(rs.leftShape().name()) << "\"/>" << std::endl;
0116 xos << "<rSolid name=\"" << trimShapeName(rs.rightShape().name()) << "\"/>" << std::endl;
0117 const Double_t* trans = rs.rightMatrix()->GetTranslation();
0118 xos << "<Translation x=\"" << trans[0] << "*mm\"";
0119 xos << " y=\"" << trans[1] << "*mm\"";
0120 xos << " z=\"" << trans[2] << "*mm\"";
0121 xos << "/>" << std::endl;
0122 auto rot = rs.rightMatrix()->GetRotationMatrix();
0123
0124 if (cms::rotation_utils::rotHash(rot) != cms::rotation_utils::identityHash) {
0125 std::string rotNameStr = cms::rotation_utils::rotName(rot, context);
0126 xos << "<rRotation name=\"" << rotNameStr << "\"/>" << std::endl;
0127 }
0128 if (shape == cms::DDSolidShape::ddunion) {
0129 xos << "</UnionSolid>" << std::endl;
0130 } else if (shape == cms::DDSolidShape::ddsubtraction) {
0131 xos << "</SubtractionSolid>" << std::endl;
0132 } else if (shape == cms::DDSolidShape::ddintersection) {
0133 xos << "</IntersectionSolid>" << std::endl;
0134 }
0135 break;
0136 }
0137 case cms::DDSolidShape::ddbox: {
0138 dd4hep::Box rs(solid);
0139 xos << "<Box name=\"" << trimShapeName(rs.name()) << "\""
0140 << " dx=\"" << rs.x() << "*mm\""
0141 << " dy=\"" << rs.y() << "*mm\""
0142 << " dz=\"" << rs.z() << "*mm\"/>" << std::endl;
0143 break;
0144 }
0145 case cms::DDSolidShape::ddtubs: {
0146 dd4hep::Tube rs(solid);
0147 double startPhi = convertRadToDeg(rs.startPhi());
0148 if (startPhi > 180. && startPhi <= 360.)
0149 startPhi -= 360.;
0150
0151
0152
0153 xos << "<Tubs name=\"" << trimShapeName(rs.name()) << "\""
0154 << " rMin=\"" << rs.rMin() << "*mm\""
0155 << " rMax=\"" << rs.rMax() << "*mm\""
0156 << " dz=\"" << rs.dZ() << "*mm\""
0157 << " startPhi=\"" << startPhi << "*deg\""
0158 << " deltaPhi=\"" << convertRadToDeg(rs.endPhi() - rs.startPhi()) << "*deg\"/>" << std::endl;
0159 break;
0160 }
0161 case cms::DDSolidShape::ddtrd1: {
0162 dd4hep::Trd1 rs(solid);
0163 xos << "<Trd1 name=\"" << trimShapeName(rs.name()) << "\""
0164 << " dz=\"" << rs.dZ() << "*mm\""
0165 << " dy1=\"" << rs.dY() << "*mm\""
0166 << " dy2=\"" << rs.dY() << "*mm\""
0167 << " dx1=\"" << rs.dX1() << "*mm\""
0168 << " dx2=\"" << rs.dX2() << "*mm\"/>" << std::endl;
0169 break;
0170 }
0171 case cms::DDSolidShape::ddtrd2: {
0172 dd4hep::Trd2 rs(solid);
0173 xos << "<Trd1 name=\"" << trimShapeName(rs.name()) << "\""
0174 << " dz=\"" << rs.dZ() << "*mm\""
0175 << " dy1=\"" << rs.dY1() << "*mm\""
0176 << " dy2=\"" << rs.dY2() << "*mm\""
0177 << " dx1=\"" << rs.dX1() << "*mm\""
0178 << " dx2=\"" << rs.dX2() << "*mm\"/>" << std::endl;
0179 break;
0180 }
0181 case cms::DDSolidShape::ddtrap: {
0182 dd4hep::Trap rs(solid);
0183 xos << std::setprecision(8);
0184
0185
0186
0187 xos << "<Trapezoid name=\"" << trimShapeName(rs.name()) << "\""
0188 << " dz=\"" << rs.dZ() << "*mm\""
0189 << " theta=\"" << convertRadToDeg(rs.theta()) << "*deg\""
0190 << " phi=\"" << convertRadToDeg(rs.phi()) << "*deg\""
0191 << " h1=\"" << rs.high1() << "*mm\""
0192 << " bl1=\"" << rs.bottomLow1() << "*mm\""
0193 << " tl1=\"" << rs.topLow1() << "*mm\""
0194 << " alp1=\"" << convertRadToDeg(rs.alpha1()) << "*deg\""
0195 << " h2=\"" << rs.high2() << "*mm\""
0196 << " bl2=\"" << rs.bottomLow2() << "*mm\""
0197 << " tl2=\"" << rs.topLow2() << "*mm\""
0198 << " alp2=\"" << convertRadToDeg(rs.alpha2()) << "*deg\"/>" << std::endl;
0199 xos << std::setprecision(5);
0200
0201
0202
0203
0204
0205 break;
0206 }
0207 case cms::DDSolidShape::ddcons: {
0208 dd4hep::ConeSegment rs(solid);
0209 double startPhi = convertRadToDeg(rs.startPhi());
0210 if (startPhi > 180. && startPhi <= 360.)
0211 startPhi -= 360.;
0212
0213
0214
0215 xos << "<Cone name=\"" << trimShapeName(rs.name()) << "\""
0216 << " dz=\"" << rs.dZ() << "*mm\""
0217 << " rMin1=\"" << rs.rMin1() << "*mm\""
0218 << " rMax1=\"" << rs.rMax1() << "*mm\""
0219 << " rMin2=\"" << rs.rMin2() << "*mm\""
0220 << " rMax2=\"" << rs.rMax2() << "*mm\""
0221 << " startPhi=\"" << startPhi << "*deg\""
0222 << " deltaPhi=\"" << convertRadToDeg(rs.endPhi() - rs.startPhi()) << "*deg\"/>" << std::endl;
0223 break;
0224 }
0225 case cms::DDSolidShape::ddpolycone: {
0226
0227
0228
0229
0230
0231
0232
0233 dd4hep::Polycone rs(solid);
0234 xos << "<Polycone name=\"" << trimShapeName(rs.name()) << "\""
0235 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0236 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\">" << std::endl;
0237 const std::vector<double>& zV(rs.zPlaneZ());
0238 const std::vector<double>& rMinV(rs.zPlaneRmin());
0239 const std::vector<double>& rMaxV(rs.zPlaneRmax());
0240 for (size_t i = 0; i < zV.size(); ++i) {
0241 xos << "<ZSection z=\"" << zV[i] << "*mm\""
0242 << " rMin=\"" << rMinV[i] << "*mm\""
0243 << " rMax=\"" << rMaxV[i] << "*mm\"/>" << std::endl;
0244 }
0245 xos << "</Polycone>" << std::endl;
0246 break;
0247 }
0248 case cms::DDSolidShape::ddpolyhedra: {
0249 dd4hep::Polyhedra rs(solid);
0250 xos << "<Polyhedra name=\"" << trimShapeName(rs.name()) << "\""
0251 << " numSide=\"" << rs.numEdges() << "\""
0252 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0253 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\">" << std::endl;
0254 const std::vector<double>& zV(rs.zPlaneZ());
0255 const std::vector<double>& rMinV(rs.zPlaneRmin());
0256 const std::vector<double>& rMaxV(rs.zPlaneRmax());
0257 for (size_t i = 0; i < zV.size(); ++i) {
0258 xos << "<ZSection z=\"" << zV[i] << "*mm\""
0259 << " rMin=\"" << rMinV[i] << "*mm\""
0260 << " rMax=\"" << rMaxV[i] << "*mm\"/>" << std::endl;
0261 }
0262 xos << "</Polyhedra>" << std::endl;
0263 break;
0264 }
0265 case cms::DDSolidShape::ddtrunctubs: {
0266 dd4hep::TruncatedTube rs(solid);
0267 xos << "<TruncTubs name=\"" << trimShapeName(rs.name()) << "\""
0268 << " zHalf=\"" << rs.dZ() << "*mm\""
0269 << " rMin=\"" << rs.rMin() << "*mm\""
0270 << " rMax=\"" << rs.rMax() << "*mm\""
0271 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0272 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\""
0273 << " cutAtStart=\"" << rs.cutAtStart() << "*mm\""
0274 << " cutAtDelta=\"" << rs.cutAtDelta() << "*mm\""
0275 << " cutInside=\"" << (rs.cutInside() ? "true" : "false") << "\"/>" << std::endl;
0276 break;
0277 }
0278 case cms::DDSolidShape::ddtorus: {
0279 dd4hep::Torus rs(solid);
0280 xos << "<Torus name=\"" << trimShapeName(rs.name()) << "\""
0281 << " innerRadius=\"" << rs.rMin() << "*mm\""
0282 << " outerRadius=\"" << rs.rMax() << "*mm\""
0283 << " torusRadius=\"" << rs.r() << "*mm\""
0284 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0285 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\"/>" << std::endl;
0286 break;
0287 }
0288 case cms::DDSolidShape::ddellipticaltube: {
0289 dd4hep::EllipticalTube rs(solid);
0290 xos << "<EllipticalTube name=\"" << trimShapeName(rs.name()) << "\""
0291 << " xSemiAxis=\"" << rs.a() << "*mm\""
0292 << " ySemiAxis=\"" << rs.b() << "*mm\""
0293 << " zHeight=\"" << rs.dZ() << "*mm\"/>" << std::endl;
0294 break;
0295 }
0296 case cms::DDSolidShape::ddcuttubs: {
0297 dd4hep::CutTube rs(solid);
0298 const std::vector<double>& pLowNorm(rs.lowNormal());
0299 const std::vector<double>& pHighNorm(rs.highNormal());
0300
0301 xos << "<CutTubs name=\"" << trimShapeName(solid.name()) << "\""
0302 << " dz=\"" << rs.dZ() << "*mm\""
0303 << " rMin=\"" << rs.rMin() << "*mm\""
0304 << " rMax=\"" << rs.rMax() << "*mm\""
0305 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0306 << " deltaPhi=\"" << convertRadToDeg(rs.endPhi() - rs.startPhi()) << "*deg\""
0307 << " lx=\"" << pLowNorm[0] << "\""
0308 << " ly=\"" << pLowNorm[1] << "\""
0309 << " lz=\"" << pLowNorm[2] << "\""
0310 << " tx=\"" << pHighNorm[0] << "\""
0311 << " ty=\"" << pHighNorm[1] << "\""
0312 << " tz=\"" << pHighNorm[2] << "\"/>" << std::endl;
0313 break;
0314 }
0315 case cms::DDSolidShape::ddextrudedpolygon: {
0316 dd4hep::ExtrudedPolygon rs(solid);
0317 std::vector<double> x = rs.x();
0318 std::vector<double> y = rs.y();
0319 std::vector<double> z = rs.z();
0320 std::vector<double> zx = rs.zx();
0321 std::vector<double> zy = rs.zy();
0322 std::vector<double> zs = rs.zscale();
0323
0324 xos << "<ExtrudedPolygon name=\"" << trimShapeName(rs.name()) << "\"";
0325 for (unsigned int i = 0; i < x.size(); ++i)
0326 xos << " <XYPoint x=\"" << x[i] << "*mm\" y=\"" << y[i] << "*mm\"/>\n";
0327 for (unsigned int k = 0; k < z.size(); ++k)
0328 xos << " <ZXYSection z=\"" << z[k] << "*mm\" x=\"" << zx[k] << "*mm\" y=\"" << zy[k] << "*mm scale=" << zs[k]
0329 << "*mm\"/>\n";
0330 xos << "</ExtrudedPolygon>\n";
0331 break;
0332 }
0333 case cms::DDSolidShape::dd_not_init:
0334 default:
0335 throw cms::Exception("DDException")
0336 << "DDCoreToDDXMLOutput::solid " << solid.name() << ", shape ID = " << static_cast<int>(shape)
0337 << ", solid title = " << solid.title();
0338 break;
0339 }
0340 }
0341
0342 void DDCoreToDDXMLOutput::solid(const DDSolid& solid, std::ostream& xos) {
0343 switch (solid.shape()) {
0344 case DDSolidShape::ddunion:
0345 case DDSolidShape::ddsubtraction:
0346 case DDSolidShape::ddintersection: {
0347 DDBooleanSolid rs(solid);
0348 if (solid.shape() == DDSolidShape::ddunion) {
0349 xos << "<UnionSolid ";
0350 } else if (solid.shape() == DDSolidShape::ddsubtraction) {
0351 xos << "<SubtractionSolid ";
0352 } else if (solid.shape() == DDSolidShape::ddintersection) {
0353 xos << "<IntersectionSolid ";
0354 }
0355 xos << "name=\"" << rs.toString() << "\">" << std::endl;
0356
0357
0358 xos << "<rSolid name=\"" << rs.solidA().toString() << "\"/>" << std::endl;
0359 xos << "<rSolid name=\"" << rs.solidB().toString() << "\"/>" << std::endl;
0360 xos << "<Translation x=\"" << rs.translation().X() << "*mm\"";
0361 xos << " y=\"" << rs.translation().Y() << "*mm\"";
0362 xos << " z=\"" << rs.translation().Z() << "*mm\"";
0363 xos << "/>" << std::endl;
0364 std::string rotName = rs.rotation().toString();
0365 if (rotName == ":") {
0366 rotName = "gen:ID";
0367 }
0368 xos << "<rRotation name=\"" << rs.rotation().toString() << "\"/>" << std::endl;
0369 if (solid.shape() == DDSolidShape::ddunion) {
0370 xos << "</UnionSolid>" << std::endl;
0371 } else if (solid.shape() == DDSolidShape::ddsubtraction) {
0372 xos << "</SubtractionSolid>" << std::endl;
0373 } else if (solid.shape() == DDSolidShape::ddintersection) {
0374 xos << "</IntersectionSolid>" << std::endl;
0375 }
0376 break;
0377 }
0378 case DDSolidShape::ddbox: {
0379
0380 DDBox rs(solid);
0381 xos << "<Box name=\"" << rs.toString() << "\""
0382 << " dx=\"" << rs.halfX() << "*mm\""
0383 << " dy=\"" << rs.halfY() << "*mm\""
0384 << " dz=\"" << rs.halfZ() << "*mm\"/>" << std::endl;
0385 break;
0386 }
0387 case DDSolidShape::ddtubs: {
0388
0389
0390
0391 DDTubs rs(solid);
0392 xos << "<Tubs name=\"" << rs.toString() << "\""
0393 << " rMin=\"" << rs.rIn() << "*mm\""
0394 << " rMax=\"" << rs.rOut() << "*mm\""
0395 << " dz=\"" << rs.zhalf() << "*mm\""
0396 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0397 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\"/>" << std::endl;
0398 break;
0399 }
0400 case DDSolidShape::ddtrap: {
0401
0402
0403
0404
0405 DDTrap rs(solid);
0406 xos << "<Trapezoid name=\"" << rs.toString() << "\""
0407 << " dz=\"" << rs.halfZ() << "*mm\""
0408 << " theta=\"" << convertRadToDeg(rs.theta()) << "*deg\""
0409 << " phi=\"" << convertRadToDeg(rs.phi()) << "*deg\""
0410 << " h1=\"" << rs.y1() << "*mm\""
0411 << " bl1=\"" << rs.x1() << "*mm\""
0412 << " tl1=\"" << rs.x2() << "*mm\""
0413 << " alp1=\"" << convertRadToDeg(rs.alpha1()) << "*deg\""
0414 << " h2=\"" << rs.y2() << "*mm\""
0415 << " bl2=\"" << rs.x3() << "*mm\""
0416 << " tl2=\"" << rs.x4() << "*mm\""
0417 << " alp2=\"" << convertRadToDeg(rs.alpha2()) << "*deg\"/>" << std::endl;
0418 break;
0419 }
0420 case DDSolidShape::ddcons: {
0421 DDCons rs(solid);
0422 xos << "<Cone name=\"" << rs.toString() << "\""
0423 << " dz=\"" << rs.zhalf() << "*mm\""
0424 << " rMin1=\"" << rs.rInMinusZ() << "*mm\""
0425 << " rMax1=\"" << rs.rOutMinusZ() << "*mm\""
0426 << " rMin2=\"" << rs.rInPlusZ() << "*mm\""
0427 << " rMax2=\"" << rs.rOutPlusZ() << "*mm\""
0428 << " startPhi=\"" << convertRadToDeg(rs.phiFrom()) << "*deg\""
0429 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\"/>" << std::endl;
0430 break;
0431 }
0432 case DDSolidShape::ddpolycone_rz: {
0433 DDPolycone rs(solid);
0434 xos << "<Polycone name=\"" << rs.toString() << "\""
0435 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0436 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\">" << std::endl;
0437 const std::vector<double>& zV(rs.zVec());
0438 const std::vector<double>& rV(rs.rVec());
0439 for (size_t i = 0; i < zV.size(); ++i) {
0440 xos << "<RZPoint r=\"" << rV[i] << "*mm\""
0441 << " z=\"" << zV[i] << "*mm\"/>" << std::endl;
0442 }
0443 xos << "</Polycone>" << std::endl;
0444 break;
0445 }
0446 case DDSolidShape::ddpolyhedra_rz: {
0447 DDPolyhedra rs(solid);
0448 xos << "<Polyhedra name=\"" << rs.toString() << "\""
0449 << " numSide=\"" << rs.sides() << "\""
0450 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0451 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\">" << std::endl;
0452 const std::vector<double>& zV(rs.zVec());
0453 const std::vector<double>& rV(rs.rVec());
0454 for (size_t i = 0; i < zV.size(); ++i) {
0455 xos << "<RZPoint r=\"" << rV[i] << "*mm\""
0456 << " z=\"" << zV[i] << "*mm\"/>" << std::endl;
0457 }
0458 xos << "</Polyhedra>" << std::endl;
0459 break;
0460 }
0461 case DDSolidShape::ddpolycone_rrz: {
0462
0463
0464
0465
0466
0467
0468
0469 DDPolycone rs(solid);
0470 xos << "<Polycone name=\"" << rs.toString() << "\""
0471 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0472 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\">" << std::endl;
0473 const std::vector<double>& zV(rs.zVec());
0474 const std::vector<double>& rMinV(rs.rMinVec());
0475 const std::vector<double>& rMaxV(rs.rMaxVec());
0476 for (size_t i = 0; i < zV.size(); ++i) {
0477 xos << "<ZSection z=\"" << zV[i] << "*mm\""
0478 << " rMin=\"" << rMinV[i] << "*mm\""
0479 << " rMax=\"" << rMaxV[i] << "*mm\"/>" << std::endl;
0480 }
0481 xos << "</Polycone>" << std::endl;
0482 break;
0483 }
0484 case DDSolidShape::ddpolyhedra_rrz: {
0485 DDPolyhedra rs(solid);
0486 xos << "<Polyhedra name=\"" << rs.toString() << "\""
0487 << " numSide=\"" << rs.sides() << "\""
0488 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0489 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\">" << std::endl;
0490 const std::vector<double>& zV(rs.zVec());
0491 const std::vector<double>& rMinV(rs.rMinVec());
0492 const std::vector<double>& rMaxV(rs.rMaxVec());
0493 for (size_t i = 0; i < zV.size(); ++i) {
0494 xos << "<ZSection z=\"" << zV[i] << "*mm\""
0495 << " rMin=\"" << rMinV[i] << "*mm\""
0496 << " rMax=\"" << rMaxV[i] << "*mm\"/>" << std::endl;
0497 }
0498 xos << "</Polyhedra>" << std::endl;
0499 break;
0500 }
0501 case DDSolidShape::ddpseudotrap: {
0502
0503 DDPseudoTrap rs(solid);
0504 xos << "<PseudoTrap name=\"" << rs.toString() << "\""
0505 << " dx1=\"" << rs.x1() << "*mm\""
0506 << " dx2=\"" << rs.x2() << "*mm\""
0507 << " dy1=\"" << rs.y1() << "*mm\""
0508 << " dy2=\"" << rs.y2() << "*mm\""
0509 << " dz=\"" << rs.halfZ() << "*mm\""
0510 << " radius=\"" << rs.radius() << "*mm\""
0511 << " atMinusZ=\"" << (rs.atMinusZ() ? "true" : "false") << "\"/>" << std::endl;
0512 break;
0513 }
0514 case DDSolidShape::ddtrunctubs: {
0515
0516
0517
0518 DDTruncTubs rs(solid);
0519 xos << "<TruncTubs name=\"" << rs.toString() << "\""
0520 << " zHalf=\"" << rs.zHalf() << "*mm\""
0521 << " rMin=\"" << rs.rIn() << "*mm\""
0522 << " rMax=\"" << rs.rOut() << "*mm\""
0523 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0524 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\""
0525 << " cutAtStart=\"" << rs.cutAtStart() << "*mm\""
0526 << " cutAtDelta=\"" << rs.cutAtDelta() << "*mm\""
0527 << " cutInside=\"" << (rs.cutInside() ? "true" : "false") << "\"/>" << std::endl;
0528 break;
0529 }
0530 case DDSolidShape::ddshapeless: {
0531 DDShapelessSolid rs(solid);
0532 xos << "<ShapelessSolid name=\"" << rs.toString() << "\"/>" << std::endl;
0533 break;
0534 }
0535 case DDSolidShape::ddtorus: {
0536
0537
0538 DDTorus rs(solid);
0539 xos << "<Torus name=\"" << rs.toString() << "\""
0540 << " innerRadius=\"" << rs.rMin() << "*mm\""
0541 << " outerRadius=\"" << rs.rMax() << "*mm\""
0542 << " torusRadius=\"" << rs.rTorus() << "*mm\""
0543 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0544 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\"/>" << std::endl;
0545 break;
0546 }
0547 case DDSolidShape::ddellipticaltube: {
0548
0549
0550
0551 DDEllipticalTube rs(solid);
0552 xos << "<EllipticalTube name=\"" << rs.toString() << "\""
0553 << " xSemiAxis=\"" << rs.xSemiAxis() << "*mm\""
0554 << " ySemiAxis=\"" << rs.ySemiAxis() << "*mm\""
0555 << " zHeight=\"" << rs.zHeight() << "*mm\"/>" << std::endl;
0556 break;
0557 }
0558 case DDSolidShape::ddcuttubs: {
0559
0560
0561
0562 DDCutTubs rs(solid);
0563 const std::array<double, 3>& pLowNorm(rs.lowNorm());
0564 const std::array<double, 3>& pHighNorm(rs.highNorm());
0565
0566 xos << "<CutTubs name=\"" << rs.toString() << "\""
0567 << " dz=\"" << rs.zhalf() << "*mm\""
0568 << " rMin=\"" << rs.rIn() << "*mm\""
0569 << " rMax=\"" << rs.rOut() << "*mm\""
0570 << " startPhi=\"" << convertRadToDeg(rs.startPhi()) << "*deg\""
0571 << " deltaPhi=\"" << convertRadToDeg(rs.deltaPhi()) << "*deg\""
0572 << " lx=\"" << pLowNorm[0] << "\""
0573 << " ly=\"" << pLowNorm[1] << "\""
0574 << " lz=\"" << pLowNorm[2] << "\""
0575 << " tx=\"" << pHighNorm[0] << "\""
0576 << " ty=\"" << pHighNorm[1] << "\""
0577 << " tz=\"" << pHighNorm[2] << "\"/>" << std::endl;
0578 break;
0579 }
0580 case DDSolidShape::ddextrudedpolygon: {
0581 DDExtrudedPolygon rs(solid);
0582 std::vector<double> x = rs.xVec();
0583 std::vector<double> y = rs.yVec();
0584 std::vector<double> z = rs.zVec();
0585 std::vector<double> zx = rs.zxVec();
0586 std::vector<double> zy = rs.zyVec();
0587 std::vector<double> zs = rs.zscaleVec();
0588
0589 xos << "<ExtrudedPolygon name=\"" << rs.toString() << "\"";
0590 for (unsigned int i = 0; i < x.size(); ++i)
0591 xos << " <XYPoint x=\"" << x[i] << "*mm\" y=\"" << y[i] << "*mm\"/>\n";
0592 for (unsigned int k = 0; k < z.size(); ++k)
0593 xos << " <ZXYSection z=\"" << z[k] << "*mm\" x=\"" << zx[k] << "*mm\" y=\"" << zy[k] << "*mm scale=" << zs[k]
0594 << "*mm\"/>\n";
0595 xos << "</ExtrudedPolygon>\n";
0596 break;
0597 }
0598 case DDSolidShape::dd_not_init:
0599 default:
0600 throw cms::Exception("DDException")
0601 << "DDCoreToDDXMLOutput::solid(...) " << solid.name() << " either not inited or no such solid.";
0602 break;
0603 }
0604 }
0605
0606 void DDCoreToDDXMLOutput::material(const DDMaterial& material, std::ostream& xos) {
0607 int noc = material.noOfConstituents();
0608 if (noc == 0) {
0609 xos << "<ElementaryMaterial name=\"" << material.toString() << "\""
0610 << " density=\"" << std::scientific << std::setprecision(5) << convertUnitsTo(1._mg_per_cm3, material.density())
0611 << "*mg/cm3\""
0612 << " atomicWeight=\"" << std::fixed << convertUnitsTo(1._g_per_mole, material.a()) << "*g/mole\""
0613 << std::setprecision(0) << std::fixed << " atomicNumber=\"" << material.z() << "\"/>" << std::endl;
0614 } else {
0615 xos << "<CompositeMaterial name=\"" << material.toString() << "\""
0616 << " density=\"" << std::scientific << std::setprecision(5) << convertUnitsTo(1._mg_per_cm3, material.density())
0617 << "*mg/cm3\""
0618 << " method=\"mixture by weight\">" << std::endl;
0619
0620 int j = 0;
0621 for (; j < noc; ++j) {
0622 xos << "<MaterialFraction fraction=\"" << std::fixed << std::setprecision(9) << material.constituent(j).second
0623 << "\">" << std::endl;
0624 xos << "<rMaterial name=\"" << material.constituent(j).first.name() << "\"/>" << std::endl;
0625 xos << "</MaterialFraction>" << std::endl;
0626 }
0627 xos << "</CompositeMaterial>" << std::endl;
0628 }
0629 }
0630
0631 void DDCoreToDDXMLOutput::material(const std::string& matName,
0632 double density,
0633 const std::vector<cms::DDParsingContext::CompositeMaterial>& matRefs,
0634 std::ostream& xos) {
0635 xos << "<CompositeMaterial name=\"" << matName << "\""
0636 << " density=\"" << std::scientific << std::setprecision(5) << convertGPerCcToMgPerCc(density) << "*mg/cm3\""
0637 << " method=\"mixture by weight\">" << std::endl;
0638
0639 for (auto compIter = matRefs.begin(); compIter != matRefs.end(); ++compIter) {
0640 xos << "<MaterialFraction fraction=\"" << std::fixed << std::setprecision(9) << compIter->fraction << "\">"
0641 << std::endl;
0642 xos << "<rMaterial name=\"" << compIter->name << "\"/>" << std::endl;
0643 xos << "</MaterialFraction>" << std::endl;
0644 }
0645 xos << "</CompositeMaterial>" << std::endl;
0646 }
0647
0648 void DDCoreToDDXMLOutput::element(const TGeoMaterial* material, std::ostream& xos) {
0649 int noc = material->GetNelements();
0650 if (noc == 1) {
0651 TGeoElement* elem = material->GetElement();
0652 std::string nameLowerCase(elem->GetTitle());
0653
0654 for (size_t index = 1; index < nameLowerCase.size(); ++index) {
0655 nameLowerCase[index] = tolower(nameLowerCase[index]);
0656 }
0657 std::string trimName(dd4hep::dd::noNamespace(material->GetName()));
0658
0659
0660
0661
0662
0663 if (trimName == nameLowerCase || nameLowerCase == "Hydrogen" || nameLowerCase == "Phosphorus" ||
0664 (nameLowerCase == "Boron" && trimName.compare(0, 3, "Bor") == 0)) {
0665 xos << "<ElementaryMaterial name=\"" << material->GetName() << "\""
0666 << " density=\"" << std::scientific << std::setprecision(5) << convertGPerCcToMgPerCc(material->GetDensity())
0667 << "*mg/cm3\""
0668 << " atomicWeight=\"" << std::fixed << material->GetA() << "*g/mole\"" << std::setprecision(0) << std::fixed
0669 << " atomicNumber=\"" << material->GetZ() << "\"/>" << std::endl;
0670 }
0671 }
0672 }
0673
0674 void DDCoreToDDXMLOutput::rotation(const DDRotation& rotation, std::ostream& xos, const std::string& rotn) {
0675 DD3Vector x, y, z;
0676 rotation.rotation().GetComponents(x, y, z);
0677 double a, b, c;
0678 x.GetCoordinates(a, b, c);
0679 x.SetCoordinates(
0680 cms_rounding::roundIfNear0(a, tol0), cms_rounding::roundIfNear0(b, tol0), cms_rounding::roundIfNear0(c, tol0));
0681 y.GetCoordinates(a, b, c);
0682 y.SetCoordinates(
0683 cms_rounding::roundIfNear0(a, tol0), cms_rounding::roundIfNear0(b, tol0), cms_rounding::roundIfNear0(c, tol0));
0684 z.GetCoordinates(a, b, c);
0685 z.SetCoordinates(
0686 cms_rounding::roundIfNear0(a, tol0), cms_rounding::roundIfNear0(b, tol0), cms_rounding::roundIfNear0(c, tol0));
0687 double check = (x.Cross(y)).Dot(z);
0688
0689 bool reflection((1. - check) > reflectTol);
0690 std::string rotName = rotation.toString();
0691 if (rotName == ":") {
0692 if (!rotn.empty()) {
0693 rotName = rotn;
0694 std::cout << "about to try to make a new DDRotation... should fail!" << std::endl;
0695 DDRotation rot(DDName(rotn), std::make_unique<DDRotationMatrix>(rotation.rotation()));
0696 std::cout << "new rotation: " << rot << std::endl;
0697 } else {
0698 std::cout << "WARNING: MAKING AN UNNAMED ROTATION" << std::endl;
0699 }
0700 }
0701 if (!reflection) {
0702 xos << "<Rotation ";
0703 } else {
0704 xos << "<ReflectionRotation ";
0705 }
0706 using namespace cms_rounding;
0707 xos << "name=\"" << rotName << "\""
0708 << " phiX=\"" << roundIfNear0(convertRadToDeg(x.phi()), tol0) << "*deg\""
0709 << " thetaX=\"" << roundIfNear0(convertRadToDeg(x.theta()), tol0) << "*deg\""
0710 << " phiY=\"" << roundIfNear0(convertRadToDeg(y.phi()), tol0) << "*deg\""
0711 << " thetaY=\"" << roundIfNear0(convertRadToDeg(y.theta()), tol0) << "*deg\""
0712 << " phiZ=\"" << roundIfNear0(convertRadToDeg(z.phi()), tol0) << "*deg\""
0713 << " thetaZ=\"" << roundIfNear0(convertRadToDeg(z.theta()), tol0) << "*deg\"/>" << std::endl;
0714 }
0715
0716 void DDCoreToDDXMLOutput::rotation(const dd4hep::Rotation3D& rotation,
0717 std::ostream& xos,
0718 const cms::DDParsingContext& context,
0719 const std::string& rotn) {
0720 ROOT::Math::XYZVector x, y, z;
0721 rotation.GetComponents(x, y, z);
0722 double a, b, c;
0723 x.GetCoordinates(a, b, c);
0724 x.SetCoordinates(
0725 cms_rounding::roundIfNear0(a, tol0), cms_rounding::roundIfNear0(b, tol0), cms_rounding::roundIfNear0(c, tol0));
0726 y.GetCoordinates(a, b, c);
0727 y.SetCoordinates(
0728 cms_rounding::roundIfNear0(a, tol0), cms_rounding::roundIfNear0(b, tol0), cms_rounding::roundIfNear0(c, tol0));
0729 z.GetCoordinates(a, b, c);
0730 z.SetCoordinates(
0731 cms_rounding::roundIfNear0(a, tol0), cms_rounding::roundIfNear0(b, tol0), cms_rounding::roundIfNear0(c, tol0));
0732 double check = (x.Cross(y)).Dot(z);
0733
0734 bool reflection((1. - check) > reflectTol);
0735 if (!reflection) {
0736 xos << "<Rotation ";
0737 } else {
0738 xos << "<ReflectionRotation ";
0739 }
0740 using namespace cms_rounding;
0741 xos << "name=\"" << rotn << "\""
0742 << " phiX=\"" << roundIfNear0(convertRadToDeg(x.phi()), tol0) << "*deg\""
0743 << " thetaX=\"" << roundIfNear0(convertRadToDeg(x.theta()), tol0) << "*deg\""
0744 << " phiY=\"" << roundIfNear0(convertRadToDeg(y.phi()), tol0) << "*deg\""
0745 << " thetaY=\"" << roundIfNear0(convertRadToDeg(y.theta()), tol0) << "*deg\""
0746 << " phiZ=\"" << roundIfNear0(convertRadToDeg(z.phi()), tol0) << "*deg\""
0747 << " thetaZ=\"" << roundIfNear0(convertRadToDeg(z.theta()), tol0) << "*deg\"/>" << std::endl;
0748 }
0749
0750 void DDCoreToDDXMLOutput::logicalPart(const DDLogicalPart& lp, std::ostream& xos) {
0751 xos << "<LogicalPart name=\"" << lp.toString() << "\">" << std::endl;
0752 xos << "<rSolid name=\"" << lp.solid().toString() << "\"/>" << std::endl;
0753 xos << "<rMaterial name=\"" << lp.material().toString() << "\"/>" << std::endl;
0754 xos << "</LogicalPart>" << std::endl;
0755 }
0756
0757 void DDCoreToDDXMLOutput::logicalPart(const std::string& asName, std::ostream& xos) {
0758 xos << "<LogicalPart name=\"" << asName << "\">" << std::endl;
0759 xos << "<rSolid name=\"" << asName << "\"/>" << std::endl;
0760 xos << "<rMaterial name=\"materials:Air\"/>" << std::endl;
0761 xos << "</LogicalPart>" << std::endl;
0762 }
0763
0764 void DDCoreToDDXMLOutput::logicalPart(const TGeoVolume& lp, std::ostream& xos) {
0765 xos << "<LogicalPart name=\"" << lp.GetName() << "\">" << std::endl;
0766 auto solid = lp.GetShape();
0767 if (solid != nullptr) {
0768 xos << "<rSolid name=\"" << trimShapeName(solid->GetName()) << "\"/>" << std::endl;
0769 }
0770 auto material = lp.GetMaterial();
0771 if (material != nullptr) {
0772 xos << "<rMaterial name=\"" << material->GetName() << "\"/>" << std::endl;
0773 }
0774 xos << "</LogicalPart>" << std::endl;
0775 }
0776
0777 void DDCoreToDDXMLOutput::position(const TGeoVolume& parent,
0778 const TGeoNode& child,
0779 const std::string& childVolName,
0780 cms::DDParsingContext& context,
0781 std::ostream& xos) {
0782 xos << "<PosPart copyNumber=\"" << child.GetNumber() << "\">" << std::endl;
0783 xos << "<rParent name=\"" << parent.GetName() << "\"/>" << std::endl;
0784 xos << "<rChild name=\"" << childVolName << "\"/>" << std::endl;
0785
0786 const auto matrix = child.GetMatrix();
0787 if (matrix != nullptr) {
0788 if (!matrix->IsIdentity()) {
0789 auto rot = matrix->GetRotationMatrix();
0790 if (cms::rotation_utils::rotHash(rot) != cms::rotation_utils::identityHash) {
0791 std::string rotNameStr = cms::rotation_utils::rotName(rot, context);
0792 if (rotNameStr == "NULL") {
0793 rotNameStr = child.GetName();
0794 rotNameStr += parent.GetName();
0795 cms::DDNamespace nameSpace(context);
0796 cms::rotation_utils::addRotWithNewName(nameSpace, rotNameStr, rot);
0797 }
0798 xos << "<rRotation name=\"" << rotNameStr << "\"/>" << std::endl;
0799 }
0800 }
0801 auto trans = matrix->GetTranslation();
0802 using namespace cms_rounding;
0803 xos << "<Translation x=\"" << roundIfNear0(trans[0]) << "*mm\"";
0804 xos << " y=\"" << roundIfNear0(trans[1]) << "*mm\"";
0805 xos << " z=\"" << roundIfNear0(trans[2]) << "*mm\"";
0806 xos << "/>" << std::endl;
0807 }
0808 xos << "</PosPart>" << std::endl;
0809 }
0810
0811 void DDCoreToDDXMLOutput::position(const DDLogicalPart& parent,
0812 const DDLogicalPart& child,
0813 DDPosData* edgeToChild,
0814 int& rotNameSeed,
0815 std::ostream& xos) {
0816 std::string rotName = edgeToChild->ddrot().toString();
0817 DDRotationMatrix myIDENT;
0818
0819 xos << "<PosPart copyNumber=\"" << edgeToChild->copyno() << "\">" << std::endl;
0820 xos << "<rParent name=\"" << parent.toString() << "\"/>" << std::endl;
0821 xos << "<rChild name=\"" << child.toString() << "\"/>" << std::endl;
0822 if ((edgeToChild->ddrot().rotation()) != myIDENT) {
0823 if (rotName == ":") {
0824 rotation(edgeToChild->ddrot(), xos);
0825 } else {
0826 xos << "<rRotation name=\"" << rotName << "\"/>" << std::endl;
0827 }
0828 }
0829 using namespace cms_rounding;
0830 xos << "<Translation x=\"" << roundIfNear0(edgeToChild->translation().x()) << "*mm\""
0831 << " y=\"" << roundIfNear0(edgeToChild->translation().y()) << "*mm\""
0832 << " z=\"" << roundIfNear0(edgeToChild->translation().z()) << "*mm\"/>" << std::endl;
0833 xos << "</PosPart>" << std::endl;
0834 }
0835
0836 void DDCoreToDDXMLOutput::specpar(const DDSpecifics& sp, std::ostream& xos) {
0837 xos << "<SpecPar name=\"" << sp.toString() << "\" eval=\"false\">" << std::endl;
0838
0839
0840 for (const auto& psit : sp.selection()) {
0841 xos << "<PartSelector path=\"" << psit << "\"/>" << std::endl;
0842 }
0843
0844
0845 for (const auto& vit : sp.specifics()) {
0846 const DDValue& v = vit.second;
0847 size_t s = v.size();
0848 size_t i = 0;
0849
0850 const std::vector<std::string>& strvec = v.strings();
0851 if (v.isEvaluated()) {
0852 for (; i < s; ++i) {
0853 xos << "<Parameter name=\"" << v.name() << "\""
0854 << " value=\"" << v[i] << "\""
0855 << " eval=\"true\"/>" << std::endl;
0856 }
0857 } else {
0858 for (; i < s; ++i) {
0859 xos << "<Parameter name=\"" << v.name() << "\""
0860 << " value=\"" << strvec[i] << "\""
0861 << " eval=\"false\"/>" << std::endl;
0862 }
0863 }
0864 }
0865 xos << "</SpecPar>" << std::endl;
0866 }
0867
0868 void DDCoreToDDXMLOutput::specpar(const std::string& name, const dd4hep::SpecPar& specPar, std::ostream& xos) {
0869 xos << "<SpecPar name=\"" << name << "\" eval=\"false\">" << std::endl;
0870
0871 for (const auto& psit : specPar.paths) {
0872 xos << "<PartSelector path=\"" << psit << "\"/>" << std::endl;
0873 }
0874
0875 for (const auto& vit : specPar.spars) {
0876 for (const auto& sit : vit.second) {
0877 xos << "<Parameter name=\"" << vit.first << "\""
0878 << " value=\"" << sit << "\""
0879 << " eval=\"false\"/>" << std::endl;
0880 }
0881 }
0882 for (const auto& vit : specPar.numpars) {
0883 for (const auto& sit : vit.second) {
0884 xos << "<Parameter name=\"" << vit.first << "\""
0885 << " value=\"" << sit << "\""
0886 << " eval=\"true\"/>" << std::endl;
0887 }
0888 }
0889 xos << "</SpecPar>" << std::endl;
0890 }
0891
0892 void DDCoreToDDXMLOutput::specpar(const std::pair<DDsvalues_type, std::set<const DDPartSelection*>>& pssv,
0893 std::ostream& xos) {
0894 static const std::string madeName("specparname");
0895 static int numspecpars(0);
0896 std::ostringstream ostr;
0897 ostr << numspecpars++;
0898 std::string spname = madeName + ostr.str();
0899 xos << "<SpecPar name=\"" << spname << "\" eval=\"false\">" << std::endl;
0900 for (const auto& psit : pssv.second) {
0901 xos << "<PartSelector path=\"" << *psit << "\"/>" << std::endl;
0902 }
0903
0904
0905 for (const auto& vit : pssv.first) {
0906 const DDValue& v = vit.second;
0907 size_t s = v.size();
0908 size_t i = 0;
0909
0910 const std::vector<std::string>& strvec = v.strings();
0911 if (v.isEvaluated()) {
0912 for (; i < s; ++i) {
0913 xos << "<Parameter name=\"" << v.name() << "\""
0914 << " value=\"" << v[i] << "\""
0915 << " eval=\"true\"/>" << std::endl;
0916 }
0917 } else {
0918 for (; i < s; ++i) {
0919 xos << "<Parameter name=\"" << v.name() << "\""
0920 << " value=\"" << strvec[i] << "\""
0921 << " eval=\"false\"/>" << std::endl;
0922 }
0923 }
0924 }
0925
0926 xos << "</SpecPar>" << std::endl;
0927 }