File indexing completed on 2024-04-06 12:05:32
0001 #include "DetectorDescription/Parser/src/DDLDivision.h"
0002 #include "DetectorDescription/Core/interface/DDAxes.h"
0003 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0004 #include "DetectorDescription/Core/interface/DDName.h"
0005 #include "DetectorDescription/Core/interface/DDSolid.h"
0006 #include "DetectorDescription/Core/interface/DDSolidShapes.h"
0007 #include "DetectorDescription/Core/interface/ClhepEvaluator.h"
0008 #include "DetectorDescription/Parser/interface/DDLElementRegistry.h"
0009 #include "DetectorDescription/Parser/src/DDDividedBox.h"
0010 #include "DetectorDescription/Parser/src/DDDividedCons.h"
0011 #include "DetectorDescription/Parser/src/DDDividedGeometryObject.h"
0012 #include "DetectorDescription/Parser/src/DDDividedPolycone.h"
0013 #include "DetectorDescription/Parser/src/DDDividedPolyhedra.h"
0014 #include "DetectorDescription/Parser/src/DDDividedTrd.h"
0015 #include "DetectorDescription/Parser/src/DDDividedTubs.h"
0016 #include "DetectorDescription/Parser/src/DDXMLElement.h"
0017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0018
0019 #include <cstddef>
0020 #include <map>
0021 #include <ostream>
0022 #include <utility>
0023
0024 class DDCompactView;
0025
0026 DDLDivision::DDLDivision(DDLElementRegistry* myreg) : DDXMLElement(myreg) {}
0027
0028 void DDLDivision::preProcessElement(const std::string& name, const std::string& nmspace, DDCompactView& cpv) {}
0029
0030 void DDLDivision::processElement(const std::string& name, const std::string& nmspace, DDCompactView& cpv) {
0031 DDXMLAttribute atts = getAttributeSet();
0032
0033 DDName parent = getDDName(nmspace, "parent");
0034 ClhepEvaluator& ev = myRegistry_->evaluator();
0035 size_t ax = 0;
0036 while (DDAxesNames::name(DDAxes(ax)) != atts.find("axis")->second && DDAxesNames::name(DDAxes(ax)) != "undefined")
0037 ++ax;
0038
0039 DDLogicalPart lp(parent);
0040 if (!lp.isDefined().second || !lp.solid().isDefined().second) {
0041 std::string em("DetectorDescription Parser DDLDivision::processElement(...) failed.");
0042 em += " The solid of the parent logical part MUST be defined before the Division is made.";
0043 em += "\n name= " + getDDName(nmspace).ns() + ":" + getDDName(nmspace).name();
0044 em += "\n parent= " + parent.ns() + ":" + parent.name();
0045 throwError(em);
0046 }
0047
0048 DDDivision div;
0049
0050 if (atts.find("nReplicas") != atts.end() && atts.find("width") != atts.end() && atts.find("offset") != atts.end()) {
0051 div = DDDivision(getDDName(nmspace),
0052 parent,
0053 DDAxes(ax),
0054 int(ev.eval(nmspace, atts.find("nReplicas")->second)),
0055 ev.eval(nmspace, atts.find("width")->second),
0056 ev.eval(nmspace, atts.find("offset")->second));
0057 } else if (atts.find("nReplicas") != atts.end() && atts.find("offset") != atts.end()) {
0058 div = DDDivision(getDDName(nmspace),
0059 parent,
0060 DDAxes(ax),
0061 int(ev.eval(nmspace, atts.find("nReplicas")->second)),
0062 ev.eval(nmspace, atts.find("offset")->second));
0063 } else if (atts.find("width") != atts.end() && atts.find("offset") != atts.end()) {
0064 div = DDDivision(getDDName(nmspace),
0065 parent,
0066 DDAxes(ax),
0067 ev.eval(nmspace, atts.find("width")->second),
0068 ev.eval(nmspace, atts.find("offset")->second));
0069 } else {
0070 std::string em("DetectorDescription Parser DDLDivision::processElement(...) failed.");
0071 em += " Allowed combinations are attributes width&offset OR nReplicas&offset OR nReplicas&width&offset.";
0072 em += "\n name= " + getDDName(nmspace).ns() + ":" + getDDName(nmspace).name();
0073 em += "\n parent= " + parent.ns() + ":" + parent.name();
0074 throwError(em);
0075 }
0076 DDDividedGeometryObject* dg = makeDivider(div, &cpv);
0077 dg->execute();
0078 delete dg;
0079
0080 clear();
0081 }
0082
0083 DDDividedGeometryObject* DDLDivision::makeDivider(const DDDivision& div, DDCompactView* cpv) {
0084 DDDividedGeometryObject* dg = nullptr;
0085
0086 switch (div.parent().solid().shape()) {
0087 case DDSolidShape::ddbox:
0088 if (div.axis() == DDAxes::x)
0089 dg = new DDDividedBoxX(div, cpv);
0090 else if (div.axis() == DDAxes::y)
0091 dg = new DDDividedBoxY(div, cpv);
0092 else if (div.axis() == DDAxes::z)
0093 dg = new DDDividedBoxZ(div, cpv);
0094 else {
0095 std::string s = "DDLDivision can not divide a ";
0096 s += DDSolidShapesName::name(div.parent().solid().shape());
0097 s += " along axis " + DDAxesNames::name(div.axis());
0098 s += ".";
0099 s += "\n name= " + div.name().ns() + ":" + div.name().name();
0100 s += "\n parent= " + div.parent().name().ns() + ":" + div.parent().name().name();
0101 throwError(s);
0102 }
0103 break;
0104
0105 case DDSolidShape::ddtubs:
0106 if (div.axis() == DDAxes::rho)
0107 dg = new DDDividedTubsRho(div, cpv);
0108 else if (div.axis() == DDAxes::phi)
0109 dg = new DDDividedTubsPhi(div, cpv);
0110 else if (div.axis() == DDAxes::z)
0111 dg = new DDDividedTubsZ(div, cpv);
0112 else {
0113 std::string s = "DDLDivision can not divide a ";
0114 s += DDSolidShapesName::name(div.parent().solid().shape());
0115 s += " along axis " + DDAxesNames::name(div.axis());
0116 s += ".";
0117 s += "\n name= " + div.name().ns() + ":" + div.name().name();
0118 s += "\n parent= " + div.parent().name().ns() + ":" + div.parent().name().name();
0119 throwError(s);
0120 }
0121 break;
0122
0123 case DDSolidShape::ddtrap:
0124 if (div.axis() == DDAxes::x)
0125 dg = new DDDividedTrdX(div, cpv);
0126 else if (div.axis() == DDAxes::y)
0127 dg = new DDDividedTrdY(div, cpv);
0128 else if (div.axis() == DDAxes::z)
0129 dg = new DDDividedTrdZ(div, cpv);
0130 else {
0131 std::string s = "DDLDivision can not divide a ";
0132 s += DDSolidShapesName::name(div.parent().solid().shape());
0133 s += " along axis ";
0134 s += DDAxesNames::name(div.axis());
0135 s += ".";
0136 s += "\n name= " + div.name().ns() + ":" + div.name().name();
0137 s += "\n parent= " + div.parent().name().ns() + ":" + div.parent().name().name();
0138 throwError(s);
0139 }
0140 break;
0141
0142 case DDSolidShape::ddcons:
0143 if (div.axis() == DDAxes::rho)
0144 dg = new DDDividedConsRho(div, cpv);
0145 else if (div.axis() == DDAxes::phi)
0146 dg = new DDDividedConsPhi(div, cpv);
0147 else if (div.axis() == DDAxes::z)
0148 dg = new DDDividedConsZ(div, cpv);
0149 else {
0150 std::string s = "DDLDivision can not divide a ";
0151 s += DDSolidShapesName::name(div.parent().solid().shape());
0152 s += " along axis " + DDAxesNames::name(div.axis());
0153 s += ".";
0154 s += "\n name= " + div.name().ns() + ":" + div.name().name();
0155 s += "\n parent= " + div.parent().name().ns() + ":" + div.parent().name().name();
0156 throwError(s);
0157 }
0158 break;
0159
0160 case DDSolidShape::ddpolycone_rrz:
0161 if (div.axis() == DDAxes::rho)
0162 dg = new DDDividedPolyconeRho(div, cpv);
0163 else if (div.axis() == DDAxes::phi)
0164 dg = new DDDividedPolyconePhi(div, cpv);
0165 else if (div.axis() == DDAxes::z)
0166 dg = new DDDividedPolyconeZ(div, cpv);
0167 else {
0168 std::string s = "DDLDivision can not divide a ";
0169 s += DDSolidShapesName::name(div.parent().solid().shape());
0170 s += " along axis ";
0171 s += DDAxesNames::name(div.axis());
0172 s += ".";
0173 s += "\n name= " + div.name().ns() + ":" + div.name().name();
0174 s += "\n parent= " + div.parent().name().ns() + ":" + div.parent().name().name();
0175 throwError(s);
0176 }
0177 break;
0178
0179 case DDSolidShape::ddpolyhedra_rrz:
0180 if (div.axis() == DDAxes::rho)
0181 dg = new DDDividedPolyhedraRho(div, cpv);
0182 else if (div.axis() == DDAxes::phi)
0183 dg = new DDDividedPolyhedraPhi(div, cpv);
0184 else if (div.axis() == DDAxes::z)
0185 dg = new DDDividedPolyhedraZ(div, cpv);
0186 else {
0187 std::string s = "DDLDivision can not divide a ";
0188 s += DDSolidShapesName::name(div.parent().solid().shape());
0189 s += " along axis ";
0190 s += DDAxesNames::name(div.axis());
0191 s += ".";
0192 s += "\n name= " + div.name().ns() + ":" + div.name().name();
0193 s += "\n parent= " + div.parent().name().ns() + ":" + div.parent().name().name();
0194 throwError(s);
0195 }
0196 break;
0197
0198 case DDSolidShape::ddpolycone_rz:
0199 case DDSolidShape::ddpolyhedra_rz: {
0200 std::string s = "ERROR: A Polycone or Polyhedra can not be divided on any axis if it's\n";
0201 s += "original definition used r and z instead of ZSections. This has\n";
0202 s += "not (yet) been implemented.";
0203 s += "\n name= " + div.name().ns() + ":" + div.name().name();
0204 s += "\n parent= " + div.parent().name().ns() + ":" + div.parent().name().name();
0205 } break;
0206
0207 case DDSolidShape::ddunion:
0208 case DDSolidShape::ddsubtraction:
0209 case DDSolidShape::ddintersection:
0210 case DDSolidShape::ddshapeless:
0211 case DDSolidShape::ddpseudotrap:
0212 case DDSolidShape::ddtrunctubs:
0213 case DDSolidShape::dd_not_init: {
0214 std::string s = "DDLDivision can not divide a ";
0215 s += DDSolidShapesName::name(div.parent().solid().shape());
0216 s += " at all (yet?). Requested axis was ";
0217 s += DDAxesNames::name(div.axis());
0218 s += ".\n";
0219 throwError(s);
0220 } break;
0221 default:
0222 break;
0223 }
0224 return dg;
0225 }