Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-04-21 02:53:11

0001 #include "DD4hep/DetFactoryHelper.h"
0002 #include "DD4hep/Printout.h"
0003 #include "DataFormats/Math/interface/angle_units.h"
0004 #include "DetectorDescription/DDCMS/interface/DDPlugins.h"
0005 #include "DetectorDescription/DDCMS/interface/BenchmarkGrd.h"
0006 #include "DetectorDescription/DDCMS/interface/DDutils.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #include "Geometry/CaloGeometry/interface/EcalTrapezoidParameters.h"
0009 #include "Math/AxisAngle.h"
0010 #include "CLHEP/Geometry/Point3D.h"
0011 #include "CLHEP/Geometry/Vector3D.h"
0012 #include "CLHEP/Geometry/Transform3D.h"
0013 
0014 //#define EDM_ML_DEBUG
0015 
0016 using namespace std;
0017 using namespace cms;
0018 using namespace dd4hep;
0019 using namespace angle_units::operators;
0020 
0021 using VecDouble = vector<double>;
0022 using VecStr = vector<string>;
0023 using EcalTrap = EcalTrapezoidParameters;
0024 
0025 using Pt3D = HepGeom::Point3D<double>;
0026 using Vec3 = CLHEP::Hep3Vector;
0027 using Rota = CLHEP::HepRotation;
0028 using Ro3D = HepGeom::Rotate3D;
0029 using Tl3D = HepGeom::Translate3D;
0030 using Tf3D = HepGeom::Transform3D;
0031 using RoX3D = HepGeom::RotateX3D;
0032 using RoZ3D = HepGeom::RotateZ3D;
0033 
0034 namespace {
0035 
0036   // Barrel volume
0037   struct Barrel {
0038     string name;         // Barrel volume name
0039     string mat;          // Barrel material name
0040     VecDouble vecZPts;   // Barrel list of z pts
0041     VecDouble vecRMin;   // Barrel list of rMin pts
0042     VecDouble vecRMax;   // Barrel list of rMax pts
0043     VecDouble vecTran;   // Barrel translation
0044     VecDouble vecRota;   // Barrel rotation
0045     VecDouble vecRota2;  // 2nd Barrel rotation
0046     VecDouble vecRota3;  // 3nd Barrel rotation
0047     double phiLo;        // Barrel phi lo
0048     double phiHi;        // Barrel phi hi
0049     double here;         // Barrel presence flag
0050   };
0051 
0052   // Supermodule volume
0053   struct Supermodule {
0054     string name;            // Supermodule volume name
0055     string mat;             // Supermodule material name
0056     VecDouble vecZPts;      // Supermodule list of z pts
0057     VecDouble vecRMin;      // Supermodule list of rMin pts
0058     VecDouble vecRMax;      // Supermodule list of rMax pts
0059     VecDouble vecTran;      // Supermodule translation
0060     VecDouble vecRota;      // Supermodule rotation
0061     VecDouble vecBTran;     // Base Supermodule translation
0062     VecDouble vecBRota;     // Base Supermodule rotation
0063     unsigned int nPerHalf;  // # Supermodules per half detector
0064     double lowPhi;          // Low   phi value of base supermodule
0065     double delPhi;          // Delta phi value of base supermodule
0066     double phiOff;          // Phi offset value supermodule
0067     VecDouble vecHere;      // Bit saying if a supermodule is present or not
0068     string cutName;         // Name of cut box
0069     double cutThick;        // Box thickness
0070     int cutShow;            // Non-zero means show the box on display (testing only)
0071     VecDouble vecCutTM;     // Translation for minus phi cut box
0072     VecDouble vecCutTP;     // Translation for plus  phi cut box
0073     double cutRM;           // Rotation for minus phi cut box
0074     double cutRP;           // Rotation for plus  phi cut box
0075     double expThick;        // Thickness (x) of supermodule expansion box
0076     double expWide;         // Width     (y) of supermodule expansion box
0077     double expYOff;         // Offset    (y) of supermodule expansion box
0078     string sideName;        // Supermodule Side Plate volume name
0079     string sideMat;         // Supermodule Side Plate material name
0080     double sideHigh;        // Side plate height
0081     double sideThick;       // Side plate thickness
0082     double sideYOffM;       // Side plate Y offset on minus phi side
0083     double sideYOffP;       // Side plate Y offset on plus  phi side
0084   };
0085 
0086   struct Crystal {
0087     VecDouble vecNomCryDimBF;  // Nominal crystal BF
0088     VecDouble vecNomCryDimCF;  // Nominal crystal CF
0089     VecDouble vecNomCryDimAR;  // Nominal crystal AR
0090     VecDouble vecNomCryDimBR;  // Nominal crystal BR
0091     VecDouble vecNomCryDimCR;  // Nominal crystal CR
0092     double nomCryDimAF;        // Nominal crystal AF
0093     double nomCryDimLZ;        // Nominal crystal LZ
0094 
0095     double underAF;  // undershoot of AF
0096     double underLZ;  // undershoot of LZ
0097     double underBF;  // undershoot of BF
0098     double underCF;  // undershoot of CF
0099     double underAR;  // undershoot of AR
0100     double underBR;  // undershoot of BR
0101     double underCR;  // undershoot of CR
0102 
0103     string name;      // string name of crystal volume
0104     string clrName;   // string name of clearance volume
0105     string wrapName;  // string name of wrap volume
0106     string wallName;  // string name of wall volume
0107 
0108     string mat;      // string name of crystal material
0109     string clrMat;   // string name of clearance material
0110     string wrapMat;  // string name of wrap material
0111     string wallMat;  // string name of wall material
0112   };
0113 
0114   struct Alveolus {
0115     double wallThAlv;        // alveoli wall thickness
0116     double wrapThAlv;        // wrapping thickness
0117     double clrThAlv;         // clearance thickness (nominal)
0118     VecDouble vecGapAlvEta;  // Extra clearance after each alveoli perp to crystal axis
0119 
0120     double wallFrAlv;  // alveoli wall frontage
0121     double wrapFrAlv;  // wrapping frontage
0122     double clrFrAlv;   // clearance frontage (nominal)
0123 
0124     double wallReAlv;  // alveoli wall rearage
0125     double wrapReAlv;  // wrapping rearage
0126     double clrReAlv;   // clearance rearage (nominal)
0127 
0128     unsigned int nCryTypes;      // number of crystal shapes
0129     unsigned int nCryPerAlvEta;  // number of crystals in eta per alveolus
0130   };
0131   struct Capsule {
0132     string name;       // Capsule
0133     double here;       //
0134     string mat;        //
0135     double xSizeHalf;  //
0136     double ySizeHalf;  //
0137     double thickHalf;  //
0138   };
0139 
0140   struct Ceramic {
0141     string name;       // Ceramic
0142     string mat;        //
0143     double xSizeHalf;  //
0144     double ySizeHalf;  //
0145     double thickHalf;  //
0146   };
0147 
0148   struct BulkSilicon {
0149     string name;       // Bulk Silicon
0150     string mat;        //
0151     double xSizeHalf;  //
0152     double ySizeHalf;  //
0153     double thickHalf;  //
0154   };
0155 
0156   struct APD {
0157     string name;   // APD
0158     string mat;    //
0159     double side;   //
0160     double thick;  //
0161     double z;      //
0162     double x1;     //
0163     double x2;     //
0164 
0165     string atjName;       // After-The-Junction
0166     string atjMat;        //
0167     double atjThickHalf;  //
0168 
0169     string sglName;   // APD-Silicone glue
0170     string sglMat;    //
0171     double sglThick;  //
0172 
0173     string aglName;   // APD-Glue
0174     string aglMat;    //
0175     double aglThick;  //
0176 
0177     string andName;   // APD-Non-Depleted
0178     string andMat;    //
0179     double andThick;  //
0180   };
0181 
0182   struct Web {
0183     double here;             // here flag
0184     string plName;           // string name of web plate volume
0185     string clrName;          // string name of web clearance volume
0186     string plMat;            // string name of web material
0187     string clrMat;           // string name of web clearance material
0188     VecDouble vecWebPlTh;    // Thickness of web plates
0189     VecDouble vecWebClrTh;   // Thickness of total web clearance
0190     VecDouble vecWebLength;  // Length of web plate
0191   };
0192 
0193   struct InnerLayerVolume {
0194     double here;            // here flag
0195     string name;            // string name of inner layer volume
0196     double phiLow;          // low phi of volumes
0197     double delPhi;          // delta phi of ily
0198     VecStr vecIlyMat;       // materials of inner layer volumes
0199     VecDouble vecIlyThick;  // Thicknesses of inner layer volumes
0200 
0201     string pipeName;                 // Cooling pipes
0202     double pipeHere;                 //
0203     string pipeMat;                  //
0204     double pipeODHalf;               //
0205     double pipeID;                   //
0206     VecDouble vecIlyPipeLengthHalf;  //
0207     VecDouble vecIlyPipeType;        //
0208     VecDouble vecIlyPipePhi;         //
0209     VecDouble vecIlyPipeZ;           //
0210 
0211     string pTMName;          // PTM
0212     double pTMHere;          //
0213     string pTMMat;           //
0214     double pTMWidthHalf;     //
0215     double pTMLengthHalf;    //
0216     double pTMHeightHalf;    //
0217     VecDouble vecIlyPTMZ;    //
0218     VecDouble vecIlyPTMPhi;  //
0219 
0220     string fanOutName;          // FanOut
0221     double fanOutHere;          //
0222     string fanOutMat;           //
0223     double fanOutWidthHalf;     //
0224     double fanOutLengthHalf;    //
0225     double fanOutHeightHalf;    //
0226     VecDouble vecIlyFanOutZ;    //
0227     VecDouble vecIlyFanOutPhi;  //
0228     string diffName;            // Diffuser
0229     string diffMat;             //
0230     double diffOff;             //
0231     double diffLengthHalf;      //
0232     string bndlName;            // Fiber bundle
0233     string bndlMat;             //
0234     double bndlOff;             //
0235     double bndlLengthHalf;      //
0236     string fEMName;             // FEM
0237     string fEMMat;              //
0238     double fEMWidthHalf;        //
0239     double fEMLengthHalf;       //
0240     double fEMHeightHalf;       //
0241     VecDouble vecIlyFEMZ;       //
0242     VecDouble vecIlyFEMPhi;     //
0243   };
0244 
0245   struct AlveolarWedge {
0246     string hawRName;           // string name of half-alveolar wedge
0247     string fawName;            // string name of full-alveolar wedge
0248     double fawHere;            // here flag
0249     double hawRHBIG;           // height at big end of half alveolar wedge
0250     double hawRhsml;           // height at small end of half alveolar wedge
0251     double hawRCutY;           // x dim of hawR cut box
0252     double hawRCutZ;           // y dim of hawR cut box
0253     double hawRCutDelY;        // y offset of hawR cut box from top of HAW
0254     double hawYOffCry;         // Y offset of crystal wrt HAW at front
0255     unsigned int nFawPerSupm;  // Number of Full Alv. Wedges per supermodule
0256     double fawPhiOff;          // Phi offset for FAW placement
0257     double fawDelPhi;          // Phi delta for FAW placement
0258     double fawPhiRot;          // Phi rotation of FAW about own axis prior to placement
0259     double fawRadOff;          // Radial offset for FAW placement
0260   };
0261 
0262   struct Grid {
0263     double here;   // here flag
0264     string name;   // Grid name
0265     string mat;    // Grid material
0266     double thick;  // Grid Thickness
0267   };
0268 
0269   struct Back {
0270     double xOff;         //
0271     double yOff;         //
0272     double here;         // here flag
0273     string sideName;     //  Back Sides
0274     double sideHere;     //
0275     double sideLength;   //
0276     double sideHeight;   //
0277     double sideWidth;    //
0278     double sideYOff1;    //
0279     double sideYOff2;    //
0280     double sideAngle;    //
0281     string sideMat;      //
0282     string plateName;    // back plate
0283     double plateHere;    //
0284     double plateLength;  //
0285     double plateThick;   //
0286     double plateWidth;   //
0287     string plateMat;     //
0288     string plate2Name;   // back plate2
0289     double plate2Thick;  //
0290     string plate2Mat;    //
0291   };
0292 
0293   struct Grille {
0294     string name;          // grille
0295     double here;          //
0296     double thick;         //
0297     double width;         //
0298     double zSpace;        //
0299     string mat;           //
0300     VecDouble vecHeight;  //
0301     VecDouble vecZOff;    //
0302 
0303     string edgeSlotName;    // Slots in Grille
0304     string edgeSlotMat;     //
0305     double edgeSlotHere;    //
0306     double edgeSlotHeight;  //
0307     double edgeSlotWidth;   //
0308 
0309     string midSlotName;          // Slots in Grille
0310     string midSlotMat;           //
0311     double midSlotHere;          //
0312     double midSlotWidth;         //
0313     double midSlotXOff;          //
0314     VecDouble vecMidSlotHeight;  //
0315   };
0316 
0317   struct BackPipe {
0318     double here;         // here flag
0319     string name;         //
0320     VecDouble vecDiam;   // pipes
0321     VecDouble vecThick;  // pipes
0322     string mat;          //
0323     string waterMat;     //
0324   };
0325 
0326   struct BackCooling {
0327     VecStr vecName;    // cooling circuits
0328     double here;       // here flag
0329     double barHere;    // here flag
0330     double barWidth;   //
0331     double barHeight;  //
0332     string mat;
0333     string barName;   // cooling bar
0334     double barThick;  //
0335     string barMat;
0336     string barSSName;   // cooling bar tubing
0337     double barSSThick;  //
0338     string barSSMat;
0339     string barWaName;   // cooling bar water
0340     double barWaThick;  //
0341     string barWaMat;
0342     double vFEHere;  // here flag
0343     string vFEName;
0344     string vFEMat;
0345     string backVFEName;
0346     string backVFEMat;
0347     VecDouble vecBackVFELyrThick;  //
0348     VecStr vecBackVFELyrName;      //
0349     VecStr vecBackVFELyrMat;       //
0350     VecDouble vecBackCoolNSec;     //
0351     VecDouble vecBackCoolSecSep;   //
0352     VecDouble vecBackCoolNPerSec;  //
0353   };
0354 
0355   struct BackMisc {
0356     double here;          // here flag
0357     VecDouble vecThick;   // misc materials
0358     VecStr vecName;       //
0359     VecStr vecMat;        //
0360     double backCBStdSep;  //
0361   };
0362 
0363   struct PatchPanel {
0364     double here;         // here flag
0365     string name;         //
0366     VecDouble vecThick;  // patch panel materials
0367     VecStr vecNames;     //
0368     VecStr vecMat;       //
0369   };
0370 
0371   struct BackCoolTank {
0372     double here;               // here flag
0373     string name;               // service tank
0374     double width;              //
0375     double thick;              //
0376     string mat;                //
0377     string waName;             //
0378     double waWidth;            //
0379     string waMat;              //
0380     string backBracketName;    //
0381     double backBracketHeight;  //
0382     string backBracketMat;     //
0383   };
0384 
0385   struct DryAirTube {
0386     double here;                 // here flag
0387     string name;                 // dry air tube
0388     unsigned int mbCoolTubeNum;  //
0389     double innDiam;              //
0390     double outDiam;              //
0391     string mat;                  //
0392   };
0393 
0394   struct MBCoolTube {
0395     double here;     // here flag
0396     string name;     // mothr bd cooling tube
0397     double innDiam;  //
0398     double outDiam;  //
0399     string mat;      //
0400   };
0401 
0402   struct MBManif {
0403     double here;     // here flag
0404     string name;     //mother bd manif
0405     double innDiam;  //
0406     double outDiam;  //
0407     string mat;      //
0408   };
0409 
0410   struct MBLyr {
0411     double here;              // here flag
0412     VecDouble vecMBLyrThick;  // mother bd lyrs
0413     VecStr vecMBLyrName;      //
0414     VecStr vecMBLyrMat;       //
0415   };
0416 
0417   struct Pincer {
0418     double rodHere;           // here flag
0419     string rodName;           // pincer rod
0420     string rodMat;            //
0421     VecDouble vecRodAzimuth;  //
0422 
0423     string envName;        // pincer envelope
0424     string envMat;         //
0425     double envWidthHalf;   //
0426     double envHeightHalf;  //
0427     double envLengthHalf;  //
0428     VecDouble vecEnvZOff;  //
0429 
0430     string blkName;        // pincer block
0431     string blkMat;         //
0432     double blkLengthHalf;  //
0433 
0434     string shim1Name;   // pincer shim
0435     double shimHeight;  //
0436     string shim2Name;   //
0437     string shimMat;     //
0438     double shim1Width;  //
0439     double shim2Width;  //
0440 
0441     string cutName;    // pincer block
0442     string cutMat;     //
0443     double cutWidth;   //
0444     double cutHeight;  //
0445   };
0446 
0447   const Rotation3D& myrot(cms::DDNamespace& ns, const string& nam, const CLHEP::HepRotation& r) {
0448     ns.addRotation(nam, Rotation3D(r.xx(), r.xy(), r.xz(), r.yx(), r.yy(), r.yz(), r.zx(), r.zy(), r.zz()));
0449     return ns.rotation(ns.prepend(nam));
0450   }
0451 
0452   Solid mytrap(const std::string& nam, const EcalTrapezoidParameters& t) {
0453 #ifdef EDM_ML_DEBUG
0454     edm::LogVerbatim("EBGeom") << nam << " Trap " << convertRadToDeg(t.theta()) << ":" << convertRadToDeg(t.phi())
0455                                << ":" << cms::convert2mm(t.h1()) << ":" << cms::convert2mm(t.bl1()) << ":"
0456                                << cms::convert2mm(t.tl1()) << ":" << convertRadToDeg(t.alp1()) << ":"
0457                                << cms::convert2mm(t.h2()) << ":" << cms::convert2mm(t.bl2()) << ":"
0458                                << cms::convert2mm(t.tl2()) << ":" << convertRadToDeg(t.alp2());
0459 #endif
0460     return Trap(
0461         nam, t.dz(), t.theta(), t.phi(), t.h1(), t.bl1(), t.tl1(), t.alp1(), t.h2(), t.bl2(), t.tl2(), t.alp2());
0462   }
0463 
0464   string_view mynamespace(string_view input) {
0465     string_view v = input;
0466     auto trim_pos = v.find(':');
0467     if (trim_pos != v.npos)
0468       v.remove_suffix(v.size() - (trim_pos + 1));
0469     return v;
0470   }
0471 }  // namespace
0472 
0473 static long algorithm(dd4hep::Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
0474   BenchmarkGrd counter("DDEcalBarrelNewAlgo");
0475   cms::DDNamespace ns(ctxt, e, true);
0476   cms::DDAlgoArguments args(ctxt, e);
0477 
0478   // TRICK!
0479   string myns{mynamespace(args.parentName()).data(), mynamespace(args.parentName()).size()};
0480 
0481   // Barrel volume
0482   // barrel parent volume
0483   Barrel bar;
0484   bar.name = myns + args.str("BarName");    // Barrel volume name
0485   bar.mat = args.str("BarMat");             // Barrel material name
0486   bar.vecZPts = args.vecDble("BarZPts");    // Barrel list of z pts
0487   bar.vecRMin = args.vecDble("BarRMin");    // Barrel list of rMin pts
0488   bar.vecRMax = args.vecDble("BarRMax");    // Barrel list of rMax pts
0489   bar.vecTran = args.vecDble("BarTran");    // Barrel translation
0490   bar.vecRota = args.vecDble("BarRota");    // Barrel rotation
0491   bar.vecRota2 = args.vecDble("BarRota2");  // 2nd Barrel rotation
0492   bar.vecRota3 = args.vecDble("BarRota3");  // 3rd Barrel rotation
0493   bar.phiLo = args.dble("BarPhiLo");        // Barrel phi lo
0494   bar.phiHi = args.dble("BarPhiHi");        // Barrel phi hi
0495   bar.here = args.dble("BarHere");          // Barrel presence flag
0496 
0497   // Supermodule volume
0498   Supermodule spm;
0499   spm.name = ns.prepend(args.str("SpmName"));        // Supermodule volume name
0500   spm.mat = args.str("SpmMat");                      // Supermodule material name
0501   spm.vecZPts = args.vecDble("SpmZPts");             // Supermodule list of z pts
0502   spm.vecRMin = args.vecDble("SpmRMin");             // Supermodule list of rMin pts
0503   spm.vecRMax = args.vecDble("SpmRMax");             // Supermodule list of rMax pts
0504   spm.vecTran = args.vecDble("SpmTran");             // Supermodule translation
0505   spm.vecRota = args.vecDble("SpmRota");             // Supermodule rotation
0506   spm.vecBTran = args.vecDble("SpmBTran");           // Base Supermodule translation
0507   spm.vecBRota = args.vecDble("SpmBRota");           // Base Supermodule rotation
0508   spm.nPerHalf = args.integer("SpmNPerHalf");        // # Supermodules per half detector
0509   spm.lowPhi = args.dble("SpmLowPhi");               // Low   phi value of base supermodule
0510   spm.delPhi = args.dble("SpmDelPhi");               // Delta phi value of base supermodule
0511   spm.phiOff = args.dble("SpmPhiOff");               // Phi offset value supermodule
0512   spm.vecHere = args.vecDble("SpmHere");             // Bit saying if a supermodule is present or not
0513   spm.cutName = ns.prepend(args.str("SpmCutName"));  // Name of cut box
0514   spm.cutThick = args.dble("SpmCutThick");           // Box thickness
0515   spm.cutShow = args.value<int>("SpmCutShow");       // Non-zero means show the box on display (testing only)
0516   spm.vecCutTM = args.vecDble("SpmCutTM");           // Translation for minus phi cut box
0517   spm.vecCutTP = args.vecDble("SpmCutTP");           // Translation for plus  phi cut box
0518   spm.cutRM = args.dble("SpmCutRM");                 // Rotation for minus phi cut box
0519   spm.cutRP = args.dble("SpmCutRP");                 // Rotation for plus  phi cut box
0520   spm.expThick = args.dble("SpmExpThick");           // Thickness (x) of supermodule expansion box
0521   spm.expWide = args.dble("SpmExpWide");             // Width     (y) of supermodule expansion box
0522   spm.expYOff = args.dble("SpmExpYOff");             // Offset    (y) of supermodule expansion box
0523   spm.sideName = myns + args.str("SpmSideName");     // Supermodule Side Plate volume name
0524   spm.sideMat = args.str("SpmSideMat");              // Supermodule Side Plate material name
0525   spm.sideHigh = args.dble("SpmSideHigh");           // Side plate height
0526   spm.sideThick = args.dble("SpmSideThick");         // Side plate thickness
0527   spm.sideYOffM = args.dble("SpmSideYOffM");         // Side plate Y offset on minus phi side
0528   spm.sideYOffP = args.dble("SpmSideYOffP");         // Side plate Y offset on plus  phi side
0529 
0530   Crystal cry;
0531   cry.nomCryDimAF = args.dble("NomCryDimAF");
0532   cry.nomCryDimLZ = args.dble("NomCryDimLZ");
0533   cry.vecNomCryDimBF = args.vecDble("NomCryDimBF");
0534   cry.vecNomCryDimCF = args.vecDble("NomCryDimCF");
0535   cry.vecNomCryDimAR = args.vecDble("NomCryDimAR");
0536   cry.vecNomCryDimBR = args.vecDble("NomCryDimBR");
0537   cry.vecNomCryDimCR = args.vecDble("NomCryDimCR");
0538 
0539   cry.underAF = args.dble("UnderAF");
0540   cry.underLZ = args.dble("UnderLZ");
0541   cry.underBF = args.dble("UnderBF");
0542   cry.underCF = args.dble("UnderCF");
0543   cry.underAR = args.dble("UnderAR");
0544   cry.underBR = args.dble("UnderBR");
0545   cry.underCR = args.dble("UnderCR");
0546 
0547   Alveolus alv;
0548   alv.wallThAlv = args.dble("WallThAlv");
0549   alv.wrapThAlv = args.dble("WrapThAlv");
0550   alv.clrThAlv = args.dble("ClrThAlv");
0551   alv.vecGapAlvEta = args.vecDble("GapAlvEta");
0552 
0553   alv.wallFrAlv = args.dble("WallFrAlv");
0554   alv.wrapFrAlv = args.dble("WrapFrAlv");
0555   alv.clrFrAlv = args.dble("ClrFrAlv");
0556 
0557   alv.wallReAlv = args.dble("WallReAlv");
0558   alv.wrapReAlv = args.dble("WrapReAlv");
0559   alv.clrReAlv = args.dble("ClrReAlv");
0560 
0561   alv.nCryTypes = args.integer("NCryTypes");
0562   alv.nCryPerAlvEta = args.integer("NCryPerAlvEta");
0563 
0564   cry.name = ns.prepend(args.str("CryName"));
0565   cry.clrName = ns.prepend(args.str("ClrName"));
0566   cry.wrapName = ns.prepend(args.str("WrapName"));
0567   cry.wallName = ns.prepend(args.str("WallName"));
0568 
0569   cry.mat = args.str("CryMat");
0570   cry.clrMat = args.str("ClrMat");
0571   cry.wrapMat = args.str("WrapMat");
0572   cry.wallMat = args.str("WallMat");
0573 
0574   Capsule cap;
0575   cap.name = ns.prepend(args.str("CapName"));
0576   cap.here = args.dble("CapHere");
0577   cap.mat = args.str("CapMat");
0578   cap.xSizeHalf = 0.5 * args.dble("CapXSize");
0579   cap.ySizeHalf = 0.5 * args.dble("CapYSize");
0580   cap.thickHalf = 0.5 * args.dble("CapThick");
0581 
0582   Ceramic cer;
0583   cer.name = ns.prepend(args.str("CerName"));
0584   cer.mat = args.str("CerMat");
0585   cer.xSizeHalf = 0.5 * args.dble("CerXSize");
0586   cer.ySizeHalf = 0.5 * args.dble("CerYSize");
0587   cer.thickHalf = 0.5 * args.dble("CerThick");
0588 
0589   BulkSilicon bSi;
0590   bSi.name = ns.prepend(args.str("BSiName"));
0591   bSi.mat = args.str("BSiMat");
0592   bSi.xSizeHalf = 0.5 * args.dble("BSiXSize");
0593   bSi.ySizeHalf = 0.5 * args.dble("BSiYSize");
0594   bSi.thickHalf = 0.5 * args.dble("BSiThick");
0595 
0596   APD apd;
0597   apd.name = ns.prepend(args.str("APDName"));
0598   apd.mat = args.str("APDMat");
0599   apd.side = args.dble("APDSide");
0600   apd.thick = args.dble("APDThick");
0601   apd.z = args.dble("APDZ");
0602   apd.x1 = args.dble("APDX1");
0603   apd.x2 = args.dble("APDX2");
0604 
0605   apd.atjName = ns.prepend(args.str("ATJName"));
0606   apd.atjMat = args.str("ATJMat");
0607   apd.atjThickHalf = 0.5 * args.dble("ATJThick");
0608 
0609   apd.sglName = ns.prepend(args.str("SGLName"));
0610   apd.sglMat = args.str("SGLMat");
0611   apd.sglThick = args.dble("SGLThick");
0612 
0613   apd.aglName = ns.prepend(args.str("AGLName"));
0614   apd.aglMat = args.str("AGLMat");
0615   apd.aglThick = args.dble("AGLThick");
0616 
0617   apd.andName = ns.prepend(args.str("ANDName"));
0618   apd.andMat = args.str("ANDMat");
0619   apd.andThick = args.dble("ANDThick");
0620 
0621   Web web;
0622   web.here = args.dble("WebHere");
0623   web.plName = ns.prepend(args.str("WebPlName"));
0624   web.clrName = ns.prepend(args.str("WebClrName"));
0625   web.plMat = args.str("WebPlMat");
0626   web.clrMat = args.str("WebClrMat");
0627   web.vecWebPlTh = args.vecDble("WebPlTh");
0628   web.vecWebClrTh = args.vecDble("WebClrTh");
0629   web.vecWebLength = args.vecDble("WebLength");
0630 
0631   InnerLayerVolume ily;
0632   ily.here = args.dble("IlyHere");
0633   ily.name = myns + args.str("IlyName");
0634   ily.phiLow = args.dble("IlyPhiLow");
0635   ily.delPhi = args.dble("IlyDelPhi");
0636   ily.vecIlyMat = args.vecStr("IlyMat");
0637   ily.vecIlyThick = args.vecDble("IlyThick");
0638 
0639   ily.pipeName = myns + args.str("IlyPipeName");
0640   ily.pipeHere = args.dble("IlyPipeHere");
0641   ily.pipeMat = args.str("IlyPipeMat");
0642   ily.pipeODHalf = 0.5 * args.dble("IlyPipeOD");
0643   ily.pipeID = args.dble("IlyPipeID");
0644   ily.vecIlyPipeLengthHalf = args.vecDble("IlyPipeLength");
0645   std::transform(ily.vecIlyPipeLengthHalf.begin(),
0646                  ily.vecIlyPipeLengthHalf.end(),
0647                  ily.vecIlyPipeLengthHalf.begin(),
0648                  [](double length) -> double { return 0.5 * length; });
0649 
0650   ily.vecIlyPipeType = args.vecDble("IlyPipeType");
0651   ily.vecIlyPipePhi = args.vecDble("IlyPipePhi");
0652   ily.vecIlyPipeZ = args.vecDble("IlyPipeZ");
0653 
0654   ily.pTMName = myns + args.str("IlyPTMName");
0655   ily.pTMHere = args.dble("IlyPTMHere");
0656   ily.pTMMat = args.str("IlyPTMMat");
0657   ily.pTMWidthHalf = 0.5 * args.dble("IlyPTMWidth");
0658   ily.pTMLengthHalf = 0.5 * args.dble("IlyPTMLength");
0659   ily.pTMHeightHalf = 0.5 * args.dble("IlyPTMHeight");
0660   ily.vecIlyPTMZ = args.vecDble("IlyPTMZ");
0661   ily.vecIlyPTMPhi = args.vecDble("IlyPTMPhi");
0662 
0663   ily.fanOutName = myns + args.str("IlyFanOutName");
0664   ily.fanOutHere = args.dble("IlyFanOutHere");
0665   ily.fanOutMat = args.str("IlyFanOutMat");
0666   ily.fanOutWidthHalf = 0.5 * args.dble("IlyFanOutWidth");
0667   ily.fanOutLengthHalf = 0.5 * args.dble("IlyFanOutLength");
0668   ily.fanOutHeightHalf = 0.5 * args.dble("IlyFanOutHeight");
0669   ily.vecIlyFanOutZ = args.vecDble("IlyFanOutZ");
0670   ily.vecIlyFanOutPhi = args.vecDble("IlyFanOutPhi");
0671   ily.diffName = myns + args.str("IlyDiffName");
0672   ily.diffMat = args.str("IlyDiffMat");
0673   ily.diffOff = args.dble("IlyDiffOff");
0674   ily.diffLengthHalf = 0.5 * args.dble("IlyDiffLength");
0675   ily.bndlName = myns + args.str("IlyBndlName");
0676   ily.bndlMat = args.str("IlyBndlMat");
0677   ily.bndlOff = args.dble("IlyBndlOff");
0678   ily.bndlLengthHalf = 0.5 * args.dble("IlyBndlLength");
0679   ily.fEMName = myns + args.str("IlyFEMName");
0680   ily.fEMMat = args.str("IlyFEMMat");
0681   ily.fEMWidthHalf = 0.5 * args.dble("IlyFEMWidth");
0682   ily.fEMLengthHalf = 0.5 * args.dble("IlyFEMLength");
0683   ily.fEMHeightHalf = 0.5 * args.dble("IlyFEMHeight");
0684   ily.vecIlyFEMZ = args.vecDble("IlyFEMZ");
0685   ily.vecIlyFEMPhi = args.vecDble("IlyFEMPhi");
0686 
0687   AlveolarWedge alvWedge;
0688   alvWedge.hawRName = myns + args.str("HawRName");
0689   alvWedge.fawName = myns + args.str("FawName");
0690   alvWedge.fawHere = args.dble("FawHere");
0691   alvWedge.hawRHBIG = args.dble("HawRHBIG");
0692   alvWedge.hawRhsml = args.dble("HawRhsml");
0693   alvWedge.hawRCutY = args.dble("HawRCutY");
0694   alvWedge.hawRCutZ = args.dble("HawRCutZ");
0695   alvWedge.hawRCutDelY = args.dble("HawRCutDelY");
0696   alvWedge.hawYOffCry = args.dble("HawYOffCry");
0697 
0698   alvWedge.nFawPerSupm = args.integer("NFawPerSupm");
0699   alvWedge.fawPhiOff = args.dble("FawPhiOff");
0700   alvWedge.fawDelPhi = args.dble("FawDelPhi");
0701   alvWedge.fawPhiRot = args.dble("FawPhiRot");
0702   alvWedge.fawRadOff = args.dble("FawRadOff");
0703 
0704   Grid grid;
0705   grid.here = args.dble("GridHere");
0706   grid.name = myns + args.str("GridName");
0707   grid.mat = args.str("GridMat");
0708   grid.thick = args.dble("GridThick");
0709 
0710   Back back;
0711   back.here = args.dble("BackHere");
0712   back.xOff = args.dble("BackXOff");
0713   back.yOff = args.dble("BackYOff");
0714   back.sideName = myns + args.str("BackSideName");
0715   back.sideHere = args.dble("BackSideHere");
0716   back.sideLength = args.dble("BackSideLength");
0717   back.sideHeight = args.dble("BackSideHeight");
0718   back.sideWidth = args.dble("BackSideWidth");
0719   back.sideYOff1 = args.dble("BackSideYOff1");
0720   back.sideYOff2 = args.dble("BackSideYOff2");
0721   back.sideAngle = args.dble("BackSideAngle");
0722   back.sideMat = args.str("BackSideMat");
0723   back.plateName = myns + args.str("BackPlateName");
0724   back.plateHere = args.dble("BackPlateHere");
0725   back.plateLength = args.dble("BackPlateLength");
0726   back.plateThick = args.dble("BackPlateThick");
0727   back.plateWidth = args.dble("BackPlateWidth");
0728   back.plateMat = args.str("BackPlateMat");
0729   back.plate2Name = myns + args.str("BackPlate2Name");
0730   back.plate2Thick = args.dble("BackPlate2Thick");
0731   back.plate2Mat = args.str("BackPlate2Mat");
0732 
0733   Grille grille;
0734   grille.name = myns + args.str("GrilleName");
0735   grille.here = args.dble("GrilleHere");
0736   grille.thick = args.dble("GrilleThick");
0737   grille.width = args.dble("GrilleWidth");
0738   grille.zSpace = args.dble("GrilleZSpace");
0739   grille.mat = args.str("GrilleMat");
0740   grille.vecHeight = args.vecDble("GrilleHeight");
0741   grille.vecZOff = args.vecDble("GrilleZOff");
0742 
0743   grille.edgeSlotName = myns + args.str("GrEdgeSlotName");
0744   grille.edgeSlotMat = args.str("GrEdgeSlotMat");
0745   grille.edgeSlotHere = args.dble("GrEdgeSlotHere");
0746   grille.edgeSlotHeight = args.dble("GrEdgeSlotHeight");
0747   grille.edgeSlotWidth = args.dble("GrEdgeSlotWidth");
0748   grille.midSlotName = myns + args.str("GrMidSlotName");
0749   grille.midSlotMat = args.str("GrMidSlotMat");
0750   grille.midSlotHere = args.dble("GrMidSlotHere");
0751   grille.midSlotWidth = args.dble("GrMidSlotWidth");
0752   grille.midSlotXOff = args.dble("GrMidSlotXOff");
0753   grille.vecMidSlotHeight = args.vecDble("GrMidSlotHeight");
0754 
0755   BackPipe backPipe;
0756   backPipe.here = args.dble("BackPipeHere");
0757   backPipe.name = myns + args.str("BackPipeName");
0758   backPipe.vecDiam = args.vecDble("BackPipeDiam");
0759   backPipe.vecThick = args.vecDble("BackPipeThick");
0760   backPipe.mat = args.str("BackPipeMat");
0761   backPipe.waterMat = args.str("BackPipeWaterMat");
0762 
0763   BackCooling backCool;
0764   backCool.here = args.dble("BackCoolHere");
0765   backCool.vecName = args.vecStr("BackCoolName");
0766   std::transform(backCool.vecName.begin(),
0767                  backCool.vecName.end(),
0768                  backCool.vecName.begin(),
0769                  [&myns](std::string name) -> std::string { return (myns + name); });
0770   backCool.barHere = args.dble("BackCoolBarHere");
0771   backCool.barWidth = args.dble("BackCoolBarWidth");
0772   backCool.barHeight = args.dble("BackCoolBarHeight");
0773   backCool.mat = args.str("BackCoolMat");
0774   backCool.barName = myns + args.str("BackCoolBarName");
0775   backCool.barThick = args.dble("BackCoolBarThick");
0776   backCool.barMat = args.str("BackCoolBarMat");
0777   backCool.barSSName = myns + args.str("BackCoolBarSSName");
0778   backCool.barSSThick = args.dble("BackCoolBarSSThick");
0779   backCool.barSSMat = args.str("BackCoolBarSSMat");
0780   backCool.barWaName = myns + args.str("BackCoolBarWaName");
0781   backCool.barWaThick = args.dble("BackCoolBarWaThick");
0782   backCool.barWaMat = args.str("BackCoolBarWaMat");
0783   backCool.vFEHere = args.dble("BackCoolVFEHere");
0784   backCool.vFEName = myns + args.str("BackCoolVFEName");
0785   backCool.vFEMat = args.str("BackCoolVFEMat");
0786   backCool.backVFEName = args.str("BackVFEName");
0787   backCool.backVFEMat = args.str("BackVFEMat");
0788   backCool.vecBackVFELyrThick = args.vecDble("BackVFELyrThick");
0789   backCool.vecBackVFELyrName = args.vecStr("BackVFELyrName");
0790   std::transform(backCool.vecBackVFELyrName.begin(),
0791                  backCool.vecBackVFELyrName.end(),
0792                  backCool.vecBackVFELyrName.begin(),
0793                  [&myns](std::string name) -> std::string { return (myns + name); });
0794   backCool.vecBackVFELyrMat = args.vecStr("BackVFELyrMat");
0795   backCool.vecBackCoolNSec = args.vecDble("BackCoolNSec");
0796   backCool.vecBackCoolSecSep = args.vecDble("BackCoolSecSep");
0797   backCool.vecBackCoolNPerSec = args.vecDble("BackCoolNPerSec");
0798 
0799   BackMisc backMisc;
0800   backMisc.here = args.dble("BackMiscHere");
0801   backMisc.vecThick = args.vecDble("BackMiscThick");
0802   backMisc.vecName = args.vecStr("BackMiscName");
0803   std::transform(backMisc.vecName.begin(),
0804                  backMisc.vecName.end(),
0805                  backMisc.vecName.begin(),
0806                  [&myns](std::string name) -> std::string { return (myns + name); });
0807   backMisc.vecMat = args.vecStr("BackMiscMat");
0808   backMisc.backCBStdSep = args.dble("BackCBStdSep");
0809 
0810   PatchPanel patchPanel;
0811   patchPanel.here = args.dble("PatchPanelHere");
0812   patchPanel.vecThick = args.vecDble("PatchPanelThick");
0813   patchPanel.vecNames = args.vecStr("PatchPanelNames");
0814   std::transform(patchPanel.vecNames.begin(),
0815                  patchPanel.vecNames.end(),
0816                  patchPanel.vecNames.begin(),
0817                  [&myns](std::string name) -> std::string { return (myns + name); });
0818 
0819   patchPanel.vecMat = args.vecStr("PatchPanelMat");
0820   patchPanel.name = myns + args.str("PatchPanelName");
0821 
0822   BackCoolTank backCoolTank;
0823   backCoolTank.here = args.dble("BackCoolTankHere");
0824   backCoolTank.name = myns + args.str("BackCoolTankName");
0825   backCoolTank.width = args.dble("BackCoolTankWidth");
0826   backCoolTank.thick = args.dble("BackCoolTankThick");
0827   backCoolTank.mat = args.str("BackCoolTankMat");
0828   backCoolTank.waName = myns + args.str("BackCoolTankWaName");
0829   backCoolTank.waWidth = args.dble("BackCoolTankWaWidth");
0830   backCoolTank.waMat = args.str("BackCoolTankWaMat");
0831   backCoolTank.backBracketName = myns + args.str("BackBracketName");
0832   backCoolTank.backBracketHeight = args.dble("BackBracketHeight");
0833   backCoolTank.backBracketMat = args.str("BackBracketMat");
0834 
0835   DryAirTube dryAirTube;
0836   dryAirTube.here = args.dble("DryAirTubeHere");
0837   dryAirTube.name = args.str("DryAirTubeName");
0838   dryAirTube.mbCoolTubeNum = args.integer("MBCoolTubeNum");
0839   dryAirTube.innDiam = args.dble("DryAirTubeInnDiam");
0840   dryAirTube.outDiam = args.dble("DryAirTubeOutDiam");
0841   dryAirTube.mat = args.str("DryAirTubeMat");
0842 
0843   MBCoolTube mbCoolTube;
0844   mbCoolTube.here = args.dble("MBCoolTubeHere");
0845   mbCoolTube.name = myns + args.str("MBCoolTubeName");
0846   mbCoolTube.innDiam = args.dble("MBCoolTubeInnDiam");
0847   mbCoolTube.outDiam = args.dble("MBCoolTubeOutDiam");
0848   mbCoolTube.mat = args.str("MBCoolTubeMat");
0849 
0850   MBManif mbManif;
0851   mbManif.here = args.dble("MBManifHere");
0852   mbManif.name = myns + args.str("MBManifName");
0853   mbManif.innDiam = args.dble("MBManifInnDiam");
0854   mbManif.outDiam = args.dble("MBManifOutDiam");
0855   mbManif.mat = args.str("MBManifMat");
0856 
0857   MBLyr mbLyr;
0858   mbLyr.here = args.dble("MBLyrHere");
0859   mbLyr.vecMBLyrThick = args.vecDble("MBLyrThick");
0860   mbLyr.vecMBLyrName = args.vecStr("MBLyrName");
0861   std::transform(mbLyr.vecMBLyrName.begin(),
0862                  mbLyr.vecMBLyrName.end(),
0863                  mbLyr.vecMBLyrName.begin(),
0864                  [&myns](std::string name) -> std::string { return (myns + name); });
0865   mbLyr.vecMBLyrMat = args.vecStr("MBLyrMat");
0866 
0867   Pincer pincer;
0868   pincer.rodHere = args.dble("PincerRodHere");
0869   pincer.rodName = myns + args.str("PincerRodName");
0870   pincer.rodMat = args.str("PincerRodMat");
0871   pincer.vecRodAzimuth = args.vecDble("PincerRodAzimuth");
0872   pincer.envName = myns + args.str("PincerEnvName");
0873   pincer.envMat = args.str("PincerEnvMat");
0874   pincer.envWidthHalf = 0.5 * args.dble("PincerEnvWidth");
0875   pincer.envHeightHalf = 0.5 * args.dble("PincerEnvHeight");
0876   pincer.envLengthHalf = 0.5 * args.dble("PincerEnvLength");
0877   pincer.vecEnvZOff = args.vecDble("PincerEnvZOff");
0878   pincer.blkName = myns + args.str("PincerBlkName");
0879   pincer.blkMat = args.str("PincerBlkMat");
0880   pincer.blkLengthHalf = 0.5 * args.dble("PincerBlkLength");
0881   pincer.shim1Name = myns + args.str("PincerShim1Name");
0882   pincer.shimHeight = args.dble("PincerShimHeight");
0883   pincer.shim2Name = myns + args.str("PincerShim2Name");
0884   pincer.shimMat = args.str("PincerShimMat");
0885   pincer.shim1Width = args.dble("PincerShim1Width");
0886   pincer.shim2Width = args.dble("PincerShim2Width");
0887   pincer.cutName = myns + args.str("PincerCutName");
0888   pincer.cutMat = args.str("PincerCutMat");
0889   pincer.cutWidth = args.dble("PincerCutWidth");
0890   pincer.cutHeight = args.dble("PincerCutHeight");
0891 
0892   Volume parentVolume = ns.volume(args.parentName());
0893   if (bar.here != 0) {
0894     const unsigned int copyOne(1);
0895     const unsigned int copyTwo(2);
0896     // Barrel parent volume----------------------------------------------------------
0897     Solid barSolid = Polycone(bar.name, bar.phiLo, (bar.phiHi - bar.phiLo), bar.vecRMin, bar.vecRMax, bar.vecZPts);
0898 #ifdef EDM_ML_DEBUG
0899     edm::LogVerbatim("EBGeom") << bar.name << " PolyCone from " << convertRadToDeg(bar.phiLo) << " to "
0900                                << convertRadToDeg(bar.phiHi) << " with " << bar.vecZPts.size() << " points";
0901     for (unsigned int k = 0; k < bar.vecZPts.size(); ++k)
0902       edm::LogVerbatim("EBGeom") << "[" << k << "] " << cms::convert2mm(bar.vecZPts[k]) << ":"
0903                                  << cms::convert2mm(bar.vecRMin[k]) << ":" << cms::convert2mm(bar.vecRMax[k]);
0904 #endif
0905     Position tran(bar.vecTran[0], bar.vecTran[1], bar.vecTran[2]);
0906     Rotation3D rotation = myrot(ns,
0907                                 bar.name + "Rot",
0908                                 Rota(Vec3(bar.vecRota3[0], bar.vecRota3[1], bar.vecRota3[2]), bar.vecRota3[3]) *
0909                                     Rota(Vec3(bar.vecRota2[0], bar.vecRota2[1], bar.vecRota2[2]), bar.vecRota2[3]) *
0910                                     Rota(Vec3(bar.vecRota[0], bar.vecRota[1], bar.vecRota[2]), bar.vecRota[3]));
0911     Volume barVolume = Volume(bar.name, barSolid, ns.material(bar.mat));
0912     parentVolume.placeVolume(barVolume, copyOne, Transform3D(rotation, tran));
0913 #ifdef EDM_ML_DEBUG
0914     edm::LogVerbatim("EBGeomX") << barVolume.name() << ":" << copyOne << " positioned in " << parentVolume.name()
0915                                 << " at (" << cms::convert2mm(tran.x()) << "," << cms::convert2mm(tran.y()) << ","
0916                                 << cms::convert2mm(tran.z()) << ") with rotation";
0917 #endif
0918     // End Barrel parent volume----------------------------------------------------------
0919 
0920     // Supermodule parent------------------------------------------------------------
0921 
0922     const string spmcut1ddname((0 != spm.cutShow) ? spm.name : (spm.name + "CUT1"));
0923     Solid ddspm = Polycone(spmcut1ddname, spm.lowPhi, spm.delPhi, spm.vecRMin, spm.vecRMax, spm.vecZPts);
0924 #ifdef EDM_ML_DEBUG
0925     edm::LogVerbatim("EBGeom") << spmcut1ddname << " PolyCone from " << convertRadToDeg(spm.lowPhi) << " to "
0926                                << convertRadToDeg(spm.lowPhi + spm.delPhi) << " with " << spm.vecZPts.size()
0927                                << " points";
0928     for (unsigned int k = 0; k < spm.vecZPts.size(); ++k)
0929       edm::LogVerbatim("EBGeom") << "[" << k << "] " << cms::convert2mm(spm.vecZPts[k]) << ":"
0930                                  << cms::convert2mm(spm.vecRMin[k]) << ":" << cms::convert2mm(spm.vecRMax[k]);
0931 #endif
0932 
0933     const unsigned int indx(0.5 * spm.vecRMax.size());
0934 
0935     // Deal with the cut boxes first
0936     array<double, 3> cutBoxParms{{1.05 * (spm.vecRMax[indx] - spm.vecRMin[indx]) * 0.5,
0937                                   0.5 * spm.cutThick,
0938                                   fabs(spm.vecZPts.back() - spm.vecZPts.front()) * 0.5 + 1.0 * dd4hep::mm}};
0939     Solid spmCutBox = Box(spm.cutName, cutBoxParms[0], cutBoxParms[1], cutBoxParms[2]);
0940 #ifdef EDM_ML_DEBUG
0941     edm::LogVerbatim("EBGeom") << spm.cutName << " Box " << cms::convert2mm(cutBoxParms[0]) << ":"
0942                                << cms::convert2mm(cutBoxParms[1]) << ":" << cms::convert2mm(cutBoxParms[2]);
0943 
0944 #endif
0945     Volume spmCutLog = Volume(spm.cutName, spmCutBox, ns.material(spm.mat));
0946 
0947     // Supermodule side platess
0948     array<double, 3> sideParms{{0.5 * spm.sideHigh, 0.5 * spm.sideThick, 0.5 * fabs(spm.vecZPts[1] - spm.vecZPts[0])}};
0949     Solid sideSolid = Box(spm.sideName, sideParms[0], sideParms[1], sideParms[2]);
0950 #ifdef EDM_ML_DEBUG
0951     edm::LogVerbatim("EBGeom") << spm.sideName << " Box " << cms::convert2mm(sideParms[0]) << ":"
0952                                << cms::convert2mm(sideParms[1]) << ":" << cms::convert2mm(sideParms[2]);
0953 #endif
0954     Volume sideLog = Volume(spm.sideName, sideSolid, ns.material(spm.sideMat));
0955 
0956     Solid temp1;
0957     Solid temp2;
0958     Position sideddtra1;
0959     Position sideddtra2;
0960     Transform3D alltrot1;
0961     Transform3D alltrot2;
0962     for (unsigned int icopy(1); icopy <= 2; ++icopy) {
0963       const std::vector<double>& tvec(1 == icopy ? spm.vecCutTM : spm.vecCutTP);
0964       double rang(1 == icopy ? spm.cutRM : spm.cutRP);
0965 
0966       const Position tr(tvec[0], tvec[1], tvec[2]);
0967       RotationZ ro(rang);
0968       const double ang(1 == icopy ? spm.lowPhi : spm.lowPhi + spm.delPhi);
0969       RotationZ ro1(ang);
0970       const Position tr1(
0971           0.5 * (spm.vecRMax[indx] + spm.vecRMin[indx]), 0, 0.5 * (spm.vecZPts.front() + spm.vecZPts.back()));
0972       Transform3D alltrot(Transform3D(Transform3D(ro1 * tr1) * tr) * ro);
0973       if (1 == icopy) {
0974         alltrot1 = alltrot;
0975         temp1 = SubtractionSolid(spm.name + "_T1", ddspm, spmCutBox, alltrot);
0976 #ifdef EDM_ML_DEBUG
0977         edm::LogVerbatim("EBGeom") << (spm.name + "_T1") << " Subtraction " << ddspm.name() << ":" << spmCutBox.name()
0978                                    << " at (" << cms::convert2mm(alltrot.Translation().Vect().x()) << ","
0979                                    << cms::convert2mm(alltrot.Translation().Vect().y()) << ","
0980                                    << cms::convert2mm(alltrot.Translation().Vect().z()) << ")";
0981 #endif
0982       } else {
0983         alltrot2 = alltrot;
0984         temp2 = SubtractionSolid(spm.name, temp1, spmCutBox, alltrot);
0985 #ifdef EDM_ML_DEBUG
0986         edm::LogVerbatim("EBGeom") << spm.name << " Subtraction " << temp1.name() << ":" << spmCutBox.name() << " at ("
0987                                    << cms::convert2mm(alltrot.Translation().Vect().x()) << ","
0988                                    << cms::convert2mm(alltrot.Translation().Vect().y()) << ","
0989                                    << cms::convert2mm(alltrot.Translation().Vect().z()) << ")";
0990 #endif
0991       }
0992       const Tl3D trSide(tvec[0],
0993                         tvec[1] + (1 == icopy ? 1. : -1.) * (cutBoxParms[1] + sideParms[1]) +
0994                             (1 == icopy ? spm.sideYOffM : spm.sideYOffP),
0995                         tvec[2]);
0996       const RoZ3D roSide(rang);
0997       const Tf3D sideRot(RoZ3D(1 == icopy ? spm.lowPhi : spm.lowPhi + spm.delPhi) *
0998                          Tl3D(spm.vecRMin.front() + sideParms[0], 0, spm.vecZPts.front() + sideParms[2]) * trSide *
0999                          roSide);
1000 
1001       Rotation3D sideddrot(myrot(ns, spm.sideName + std::to_string(icopy), sideRot.getRotation()));
1002       const Position sideddtra(sideRot.getTranslation());
1003       1 == icopy ? sideddtra1 = sideddtra : sideddtra2 = sideddtra;
1004     }
1005     Volume spmLog = Volume(spm.name, ((0 != spm.cutShow) ? ddspm : temp2), ns.material(spm.mat));
1006     if (0 != spm.cutShow) {
1007       spmLog.placeVolume(spmCutLog, 1, alltrot1);
1008 #ifdef EDM_ML_DEBUG
1009       edm::LogVerbatim("EBGeomX") << spmCutLog.name() << ":1 positioned in " << spmLog.name() << " at ("
1010                                   << cms::convert2mm(alltrot1.Translation().Vect().x()) << ","
1011                                   << cms::convert2mm(alltrot1.Translation().Vect().y()) << ","
1012                                   << cms::convert2mm(alltrot1.Translation().Vect().z()) << ") with rotation";
1013 #endif
1014       spmLog.placeVolume(spmCutLog, 1, alltrot2);
1015 #ifdef EDM_ML_DEBUG
1016       edm::LogVerbatim("EBGeomX") << spmCutLog.name() << ":1 positioned in " << spmLog.name() << " at ("
1017                                   << cms::convert2mm(alltrot2.Translation().Vect().x()) << ","
1018                                   << cms::convert2mm(alltrot2.Translation().Vect().y()) << ","
1019                                   << cms::convert2mm(alltrot2.Translation().Vect().z()) << ") with rotation";
1020 #endif
1021     }
1022     spmLog.placeVolume(sideLog, 1, Transform3D(ns.rotation(spm.sideName + std::to_string(1)), sideddtra1));
1023 #ifdef EDM_ML_DEBUG
1024     edm::LogVerbatim("EBGeomX") << sideLog.name() << ":1 positioned in " << spmLog.name() << " at ("
1025                                 << cms::convert2mm(sideddtra1.x()) << "," << cms::convert2mm(sideddtra1.y()) << ","
1026                                 << cms::convert2mm(sideddtra1.z()) << ") with rotation";
1027 #endif
1028     spmLog.placeVolume(sideLog, 2, Transform3D(ns.rotation(spm.sideName + std::to_string(2)), sideddtra2));
1029 #ifdef EDM_ML_DEBUG
1030     edm::LogVerbatim("EBGeomX") << sideLog.name() << ":2 positioned in " << spmLog.name() << " at ("
1031                                 << cms::convert2mm(sideddtra2.x()) << "," << cms::convert2mm(sideddtra2.y()) << ","
1032                                 << cms::convert2mm(sideddtra2.z()) << ") with rotation";
1033 #endif
1034 
1035     const double dphi(360._deg / (1. * spm.nPerHalf));
1036     for (unsigned int iphi(0); iphi < 2 * spm.nPerHalf; ++iphi) {
1037       const double phi(iphi * dphi + spm.phiOff);
1038 
1039       // this base rotation includes the base translation & rotation
1040       // plus flipping for the negative z hemisphere, plus
1041       // the phi rotation for this module
1042       const Tf3D rotaBase(RoZ3D(phi) * (iphi < spm.nPerHalf ? Ro3D() : RoX3D(180._deg)) *
1043                           Ro3D(spm.vecBRota[3], Vec3(spm.vecBRota[0], spm.vecBRota[1], spm.vecBRota[2])) *
1044                           Tl3D(Vec3(spm.vecBTran[0], spm.vecBTran[1], spm.vecBTran[2])));
1045 
1046       // here the individual rotations & translations of the supermodule
1047       // are implemented on top of the overall "base" rotation & translation
1048 
1049       const unsigned int offr(4 * iphi);
1050       const unsigned int offt(3 * iphi);
1051 
1052       const Ro3D r1(spm.vecRota[offr + 3], Vec3(spm.vecRota[offr + 0], spm.vecRota[offr + 1], spm.vecRota[offr + 2]));
1053 
1054       const Tf3D rotaExtra(r1 * Tl3D(Vec3(spm.vecTran[offt + 0], spm.vecTran[offt + 1], spm.vecTran[offt + 2])));
1055 
1056       const Tf3D both(rotaExtra * rotaBase);
1057 
1058       const Rotation3D rota(myrot(ns, spm.name + std::to_string(convertRadToDeg(phi)), both.getRotation()));
1059 
1060       if (spm.vecHere[iphi] != 0) {
1061         // convert from CLHEP to Position & etc.
1062         Position myTran(both.getTranslation().x(), both.getTranslation().y(), both.getTranslation().z());
1063         barVolume.placeVolume(spmLog, iphi + 1, Transform3D(rota, myTran));
1064 #ifdef EDM_ML_DEBUG
1065         edm::LogVerbatim("EBGeomX") << spmLog.name() << ":" << (iphi + 1) << " positioned in " << barVolume.name()
1066                                     << " at (" << cms::convert2mm(myTran.x()) << "," << cms::convert2mm(myTran.y())
1067                                     << "," << cms::convert2mm(myTran.z()) << ") with rotation";
1068 #endif
1069       }
1070     }
1071     // End Supermodule parent------------------------------------------------------------
1072 
1073     // Begin Inner Layer volumes---------------------------------------------------------
1074     const double ilyLengthHalf(0.5 * (spm.vecZPts[1] - spm.vecZPts[0]));
1075     double ilyRMin(spm.vecRMin[0]);
1076     double ilyThick(0);
1077     for (unsigned int ilyx(0); ilyx != ily.vecIlyThick.size(); ++ilyx) {
1078       ilyThick += ily.vecIlyThick[ilyx];
1079     }
1080     Solid ilySolid = Tube(ily.name,
1081                           ilyRMin,                   // rmin
1082                           ilyRMin + ilyThick,        // rmax
1083                           ilyLengthHalf,             // dz
1084                           ily.phiLow,                // startPhi
1085                           ily.phiLow + ily.delPhi);  // startPhi + deltaPhi
1086 #ifdef EDM_ML_DEBUG
1087     edm::LogVerbatim("EBGeom") << ily.name << " Tubs " << cms::convert2mm(ilyLengthHalf) << ":"
1088                                << cms::convert2mm(ilyRMin) << ":" << cms::convert2mm(ilyRMin + ilyThick) << ":"
1089                                << convertRadToDeg(ily.phiLow) << ":" << convertRadToDeg(ily.delPhi);
1090 #endif
1091     Volume ilyLog = Volume(ily.name, ilySolid, ns.material(spm.mat));
1092     spmLog.placeVolume(ilyLog, copyOne, Position(0, 0, ilyLengthHalf));
1093 #ifdef EDM_ML_DEBUG
1094     edm::LogVerbatim("EBGeomX") << ilyLog.name() << ":" << copyOne << " positioned in " << spmLog.name() << " at (0,0,"
1095                                 << cms::convert2mm(ilyLengthHalf) << ") with no rotation";
1096 #endif
1097     Volume ilyPipeLog[200];
1098     if (0 != ily.pipeHere) {
1099       for (unsigned int iPipeType(0); iPipeType != ily.vecIlyPipeLengthHalf.size(); ++iPipeType) {
1100         string pName(ily.pipeName + "_" + std::to_string(iPipeType + 1));
1101 
1102         Solid ilyPipeSolid = Tube(pName,
1103                                   0,                                    // rmin
1104                                   ily.pipeODHalf,                       // rmax
1105                                   ily.vecIlyPipeLengthHalf[iPipeType],  // dz
1106                                   0_deg,                                // startPhi
1107                                   360_deg);                             // startPhi + deltaPhi
1108 #ifdef EDM_ML_DEBUG
1109         edm::LogVerbatim("EBGeom") << pName << " Tubs " << cms::convert2mm(ily.vecIlyPipeLengthHalf[iPipeType])
1110                                    << ":0:" << cms::convert2mm(ily.pipeODHalf) << ":0:360";
1111 #endif
1112         ilyPipeLog[iPipeType] = Volume(pName, ilyPipeSolid, ns.material(ily.pipeMat));
1113 
1114         string pWaName(ily.pipeName + "Wa_" + std::to_string(iPipeType + 1));
1115         Solid ilyPipeWaSolid = Tube(pWaName,
1116                                     0,                                    // rmin
1117                                     0.5 * ily.pipeID,                     // rmax
1118                                     ily.vecIlyPipeLengthHalf[iPipeType],  // dz
1119                                     0_deg,                                // startPhi
1120                                     360_deg);                             // startPhi + deltaPhi
1121 #ifdef EDM_ML_DEBUG
1122         edm::LogVerbatim("EBGeom") << pWaName << " Tubs " << cms::convert2mm(ily.vecIlyPipeLengthHalf[iPipeType])
1123                                    << ":0:" << cms::convert2mm(0.5 * ily.pipeID) << ":0:360";
1124 #endif
1125         Volume ilyPipeWaLog = Volume(pWaName, ilyPipeWaSolid, ns.material(backPipe.waterMat));
1126         ilyPipeLog[iPipeType].placeVolume(ilyPipeWaLog, copyOne);
1127 #ifdef EDM_ML_DEBUG
1128         edm::LogVerbatim("EBGeomX") << ilyPipeWaLog.name() << ":" << copyOne << " positioned in "
1129                                     << ilyPipeLog[iPipeType].name() << " at (0,0,0) with no rotation";
1130 #endif
1131       }
1132     }
1133 
1134     Solid ilyPTMSolid = Box(ily.pTMName, ily.pTMHeightHalf, ily.pTMWidthHalf, ily.pTMLengthHalf);
1135 #ifdef EDM_ML_DEBUG
1136     edm::LogVerbatim("EBGeom") << ily.pTMName << " Box " << cms::convert2mm(ily.pTMHeightHalf) << ":"
1137                                << cms::convert2mm(ily.pTMWidthHalf) << ":" << cms::convert2mm(ily.pTMLengthHalf);
1138 #endif
1139     Volume ilyPTMLog = Volume(ily.pTMName, ilyPTMSolid, ns.material(ily.pTMMat));
1140 
1141     Solid ilyFanOutSolid = Box(ily.fanOutName, ily.fanOutHeightHalf, ily.fanOutWidthHalf, ily.fanOutLengthHalf);
1142 #ifdef EDM_ML_DEBUG
1143     edm::LogVerbatim("EBGeom") << ily.fanOutName << " Box " << cms::convert2mm(ily.fanOutHeightHalf) << ":"
1144                                << cms::convert2mm(ily.fanOutWidthHalf) << ":" << cms::convert2mm(ily.fanOutLengthHalf);
1145 #endif
1146     Volume ilyFanOutLog = Volume(ily.fanOutName, ilyFanOutSolid, ns.material(ily.fanOutMat));
1147 
1148     Solid ilyFEMSolid = Box(ily.fEMName, ily.fEMHeightHalf, ily.fEMWidthHalf, ily.fEMLengthHalf);
1149 #ifdef EDM_ML_DEBUG
1150     edm::LogVerbatim("EBGeom") << ily.fEMName << " Box " << cms::convert2mm(ily.fEMHeightHalf) << ":"
1151                                << cms::convert2mm(ily.fEMWidthHalf) << ":" << cms::convert2mm(ily.fEMLengthHalf);
1152 #endif
1153     Volume ilyFEMLog = Volume(ily.fEMName, ilyFEMSolid, ns.material(ily.fEMMat));
1154 
1155     Solid ilyDiffSolid = Box(ily.diffName, ily.fanOutHeightHalf, ily.fanOutWidthHalf, ily.diffLengthHalf);
1156 #ifdef EDM_ML_DEBUG
1157     edm::LogVerbatim("EBGeom") << ily.diffName << " Box " << cms::convert2mm(ily.fanOutHeightHalf) << ":"
1158                                << cms::convert2mm(ily.fanOutWidthHalf) << ":" << cms::convert2mm(ily.diffLengthHalf);
1159 #endif
1160     Volume ilyDiffLog = Volume(ily.diffName, ilyDiffSolid, ns.material(ily.diffMat));
1161 
1162     Solid ilyBndlSolid = Box(ily.bndlName, ily.fanOutHeightHalf, ily.fanOutWidthHalf, ily.bndlLengthHalf);
1163 #ifdef EDM_ML_DEBUG
1164     edm::LogVerbatim("EBGeom") << ily.bndlName << " Box " << cms::convert2mm(ily.fanOutHeightHalf) << ":"
1165                                << cms::convert2mm(ily.fanOutWidthHalf) << ":" << cms::convert2mm(ily.bndlLengthHalf);
1166 #endif
1167     Volume ilyBndlLog = Volume(ily.bndlName, ilyBndlSolid, ns.material(ily.bndlMat));
1168 
1169     ilyFanOutLog.placeVolume(
1170         ilyDiffLog, copyOne, Position(0, 0, -ily.fanOutLengthHalf + ily.diffLengthHalf + ily.diffOff));
1171 #ifdef EDM_ML_DEBUG
1172     edm::LogVerbatim("EBGeomX") << ilyDiffLog.name() << ":" << copyOne << " positioned in " << ilyFanOutLog.name()
1173                                 << " at (0,0,"
1174                                 << cms::convert2mm(-ily.fanOutLengthHalf + ily.diffLengthHalf + ily.diffOff)
1175                                 << ") with no rotation";
1176 #endif
1177     ilyFanOutLog.placeVolume(
1178         ilyBndlLog, copyOne, Position(0, 0, -ily.fanOutLengthHalf + ily.bndlLengthHalf + ily.bndlOff));
1179 #ifdef EDM_ML_DEBUG
1180     edm::LogVerbatim("EBGeomX") << ilyBndlLog.name() << ":" << copyOne << " positioned in " << ilyFanOutLog.name()
1181                                 << " at (0,0,"
1182                                 << cms::convert2mm(-ily.fanOutLengthHalf + ily.bndlLengthHalf + ily.bndlOff)
1183                                 << ") with no rotation";
1184 #endif
1185 
1186     Volume xilyLog;
1187     for (unsigned int iily(0); iily != ily.vecIlyThick.size(); ++iily) {
1188       const double ilyRMax(ilyRMin + ily.vecIlyThick[iily]);
1189       string xilyName(ily.name + std::to_string(iily));
1190       Solid xilySolid = Tube(xilyName, ilyRMin, ilyRMax, ilyLengthHalf, ily.phiLow, ily.phiLow + ily.delPhi);
1191 #ifdef EDM_ML_DEBUG
1192       edm::LogVerbatim("EBGeom") << xilyName << " Tubs " << cms::convert2mm(ilyLengthHalf) << ":"
1193                                  << cms::convert2mm(ilyRMin) << ":" << cms::convert2mm(ilyRMax) << ":"
1194                                  << convertRadToDeg(ily.phiLow) << ":" << convertRadToDeg(ily.delPhi);
1195 #endif
1196       xilyLog = ns.addVolume(Volume(xilyName, xilySolid, ns.material(ily.vecIlyMat[iily])));
1197       if (0 != ily.here) {
1198         ilyLog.placeVolume(xilyLog, copyOne);
1199 #ifdef EDM_ML_DEBUG
1200         edm::LogVerbatim("EBGeomX") << xilyLog.name() << ":" << copyOne << " positioned in " << ilyLog.name()
1201                                     << " at (0,0,0) with no rotation";
1202 #endif
1203         unsigned int copyNum[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1204 
1205         if (10 * dd4hep::mm < ily.vecIlyThick[iily] && ily.vecIlyThick.size() != (iily + 1) && 0 != ily.pipeHere) {
1206           if (0 != ily.pTMHere) {
1207             unsigned int ptmCopy(0);
1208             for (unsigned int ilyPTM(0); ilyPTM != ily.vecIlyPTMZ.size(); ++ilyPTM) {
1209               const double radius(ilyRMax - 1 * dd4hep::mm - ily.pTMHeightHalf);
1210               const double phi(ily.vecIlyPTMPhi[ilyPTM]);
1211               const double yy(radius * sin(phi));
1212               const double xx(radius * cos(phi));
1213               ++ptmCopy;
1214               xilyLog.placeVolume(
1215                   ilyPTMLog,
1216                   ptmCopy,
1217                   Transform3D(RotationZ(phi), Position(xx, yy, ily.vecIlyPTMZ[ilyPTM] - ilyLengthHalf)));
1218 #ifdef EDM_ML_DEBUG
1219               edm::LogVerbatim("EBGeomX")
1220                   << ilyPTMLog.name() << ":" << ptmCopy << " positioned in " << xilyLog.name() << " at ("
1221                   << cms::convert2mm(xx) << "," << cms::convert2mm(yy) << ","
1222                   << cms::convert2mm(ily.vecIlyPTMZ[ilyPTM] - ilyLengthHalf) << ") with rotation";
1223 #endif
1224             }
1225           }
1226           if (0 != ily.fanOutHere) {
1227             unsigned int fanOutCopy(0);
1228             for (unsigned int ilyFO(0); ilyFO != ily.vecIlyFanOutZ.size(); ++ilyFO) {
1229               const double radius(ilyRMax - 1 * dd4hep::mm - ily.fanOutHeightHalf);
1230               const double phi(ily.vecIlyFanOutPhi[ilyFO]);
1231               const double yy(radius * sin(phi));
1232               const double xx(radius * cos(phi));
1233               ++fanOutCopy;
1234               xilyLog.placeVolume(ilyFanOutLog,
1235                                   fanOutCopy,
1236                                   Transform3D(RotationZ(phi) * RotationY(180_deg),
1237                                               Position(xx, yy, ily.vecIlyFanOutZ[ilyFO] - ilyLengthHalf)));
1238 #ifdef EDM_ML_DEBUG
1239               edm::LogVerbatim("EBGeomX")
1240                   << ilyFanOutLog.name() << ":" << fanOutCopy << " positioned in " << xilyLog.name() << " at ("
1241                   << cms::convert2mm(xx) << "," << cms::convert2mm(yy) << ","
1242                   << cms::convert2mm(ily.vecIlyFanOutZ[ilyFO] - ilyLengthHalf) << ") with rotation";
1243 #endif
1244             }
1245             unsigned int femCopy(0);
1246             for (unsigned int ilyFEM(0); ilyFEM != ily.vecIlyFEMZ.size(); ++ilyFEM) {
1247               const double radius(ilyRMax - 1 * dd4hep::mm - ily.fEMHeightHalf);
1248               const double phi(ily.vecIlyFEMPhi[ilyFEM]);
1249               const double yy(radius * sin(phi));
1250               const double xx(radius * cos(phi));
1251               ++femCopy;
1252               xilyLog.placeVolume(
1253                   ilyFEMLog,
1254                   femCopy,
1255                   Transform3D(RotationZ(phi), Position(xx, yy, ily.vecIlyFEMZ[ilyFEM] - ilyLengthHalf)));
1256 #ifdef EDM_ML_DEBUG
1257               edm::LogVerbatim("EBGeomX")
1258                   << ilyFEMLog.name() << ":" << femCopy << " positioned in " << xilyLog.name() << " at ("
1259                   << cms::convert2mm(xx) << "," << cms::convert2mm(yy) << ","
1260                   << cms::convert2mm(ily.vecIlyFEMZ[ilyFEM] - ilyLengthHalf) << ") with rotation";
1261 #endif
1262             }
1263           }
1264           for (unsigned int iPipe(0); iPipe != ily.vecIlyPipePhi.size(); ++iPipe) {
1265             const unsigned int type(static_cast<unsigned int>(round(ily.vecIlyPipeType[iPipe])));
1266             const double zz(-ilyLengthHalf + ily.vecIlyPipeZ[iPipe] + (9 > type ? ily.vecIlyPipeLengthHalf[type] : 0));
1267 
1268             for (unsigned int ly(0); ly != 2; ++ly) {
1269               const double radius(0 == ly ? ilyRMin + ily.pipeODHalf + 1 * dd4hep::mm
1270                                           : ilyRMax - ily.pipeODHalf - 1 * dd4hep::mm);
1271               const double phi(ily.vecIlyPipePhi[iPipe]);
1272               const double yy(radius * sin(phi));
1273               const double xx(radius * cos(phi));
1274               ++copyNum[type];
1275               if (9 > type) {
1276                 xilyLog.placeVolume(ilyPipeLog[type], copyNum[type], Position(xx, yy, zz));
1277 #ifdef EDM_ML_DEBUG
1278                 edm::LogVerbatim("EBGeomX")
1279                     << ilyPipeLog[type].name() << ":" << copyNum[type] << " positioned in " << xilyLog.name() << " at ("
1280                     << cms::convert2mm(xx) << "," << cms::convert2mm(yy) << "," << cms::convert2mm(zz)
1281                     << ") with no rotation";
1282 #endif
1283               } else {
1284                 xilyLog.placeVolume(
1285                     ilyPipeLog[type],
1286                     copyNum[type],
1287                     Transform3D(Rotation3D(ROOT::Math::AxisAngle(ROOT::Math::AxisAngle::XYZVector(xx, yy, 0), 90_deg)),
1288                                 Position(xx, yy, zz)));
1289 #ifdef EDM_ML_DEBUG
1290                 edm::LogVerbatim("EBGeomX") << ilyPipeLog[type].name() << ":" << copyNum[type] << " positioned in "
1291                                             << xilyLog.name() << " at (" << cms::convert2mm(xx) << ","
1292                                             << cms::convert2mm(yy) << "," << cms::convert2mm(zz) << ") with rotation";
1293 #endif
1294               }
1295             }
1296           }
1297         }
1298       }
1299       ilyRMin = ilyRMax;
1300     }
1301     // End Inner Layer volumes---------------------------------------------------------
1302 
1303     string clyrName(ns.prepend("ECLYR"));
1304     std::vector<double> cri;
1305     std::vector<double> cro;
1306     std::vector<double> czz;
1307     czz.emplace_back(spm.vecZPts[1]);
1308     cri.emplace_back(spm.vecRMin[0]);
1309     cro.emplace_back(spm.vecRMin[0] + 25 * dd4hep::mm);
1310     czz.emplace_back(spm.vecZPts[2]);
1311     cri.emplace_back(spm.vecRMin[2]);
1312     cro.emplace_back(spm.vecRMin[2] + 10 * dd4hep::mm);
1313     Solid clyrSolid = Polycone(clyrName, -9.5_deg, 19_deg, cri, cro, czz);
1314 #ifdef EDM_ML_DEBUG
1315     edm::LogVerbatim("EBGeom") << clyrName << " PolyCone from -9.5 to 9.5 with " << czz.size() << " points";
1316     for (unsigned int k = 0; k < czz.size(); ++k)
1317       edm::LogVerbatim("EBGeom") << "[" << k << "] " << cms::convert2mm(czz[k]) << ":" << cms::convert2mm(cri[k]) << ":"
1318                                  << cms::convert2mm(cro[k]);
1319 #endif
1320     Volume clyrLog = Volume(clyrName, clyrSolid, ns.material(ily.vecIlyMat[4]));
1321     spmLog.placeVolume(clyrLog, copyOne);
1322 #ifdef EDM_ML_DEBUG
1323     edm::LogVerbatim("EBGeomX") << clyrLog.name() << ":" << copyOne << " positioned in " << spmLog.name()
1324                                 << " at (0,0,0) with no rotation";
1325 #endif
1326     // Begin Alveolar Wedge parent ------------------------------------------------------
1327     //----------------
1328 
1329     // the next few lines accumulate dimensions appropriate to crystal type 1
1330     // which we use to set some of the features of the half-alveolar wedge (hawR).
1331 
1332     const double BNom1(cry.vecNomCryDimCR[0]);
1333     const double bNom1(cry.vecNomCryDimCF[0]);
1334     const double sWall1(alv.wallThAlv);
1335     const double fWall1(alv.wallFrAlv);
1336     const double sWrap1(alv.wrapThAlv);
1337     const double fWrap1(alv.wrapFrAlv);
1338     const double sClr1(alv.clrThAlv);
1339     const double fClr1(alv.clrFrAlv);
1340     const double LNom1(cry.nomCryDimLZ);
1341     const double beta1(atan((BNom1 - bNom1) / LNom1));
1342     const double sinbeta1(sin(beta1));
1343 
1344     const double tana_hawR((BNom1 - bNom1) / LNom1);
1345 
1346     const double H_hawR(alvWedge.hawRHBIG);
1347     const double h_hawR(alvWedge.hawRhsml);
1348     const double a_hawR(bNom1 + sClr1 + 2 * sWrap1 + 2 * sWall1 - sinbeta1 * (fClr1 + fWrap1 + fWall1));
1349     const double B_hawR(a_hawR + H_hawR * tana_hawR);
1350     const double b_hawR(a_hawR + h_hawR * tana_hawR);
1351     const double L_hawR(spm.vecZPts[2]);
1352 
1353     const EcalTrap trapHAWR(0.5 * a_hawR,  //double aHalfLengthXNegZLoY , // bl1, A/2
1354                             0.5 * a_hawR,  //double aHalfLengthXPosZLoY , // bl2, a/2
1355                             0.5 * b_hawR,  //double aHalfLengthXPosZHiY , // tl2, b/2
1356                             0.5 * H_hawR,  //double aHalfLengthYNegZ    , // h1, H/2
1357                             0.5 * h_hawR,  //double aHalfLengthYPosZ    , // h2, h/2
1358                             0.5 * L_hawR,  //double aHalfLengthZ        , // dz,  L/2
1359                             90_deg,        //double aAngleAD            , // alfa1
1360                             0,             //double aCoord15X           , // x15
1361                             0              //double aCoord15Y             // y15
1362     );
1363 
1364     string hawRName1(alvWedge.hawRName + "1");
1365     Solid hawRSolid1 = mytrap(hawRName1, trapHAWR);
1366 
1367     const double al1_fawR(atan((B_hawR - a_hawR) / H_hawR) + M_PI_2);
1368 
1369     // here is trap for Full Alveolar Wedge
1370     const EcalTrap trapFAW(a_hawR,        //double aHalfLengthXNegZLoY , // bl1, A/2
1371                            a_hawR,        //double aHalfLengthXPosZLoY , // bl2, a/2
1372                            b_hawR,        //double aHalfLengthXPosZHiY , // tl2, b/2
1373                            0.5 * H_hawR,  //double aHalfLengthYNegZ    , // h1, H/2
1374                            0.5 * h_hawR,  //double aHalfLengthYPosZ    , // h2, h/2
1375                            0.5 * L_hawR,  //double aHalfLengthZ        , // dz,  L/2
1376                            al1_fawR,      //double aAngleAD            , // alfa1
1377                            0,             //double aCoord15X           , // x15
1378                            0              //double aCoord15Y             // y15
1379     );
1380 
1381     const string fawName1(alvWedge.fawName + "1");
1382     Solid fawSolid1 = mytrap(fawName1, trapFAW);
1383 
1384     const EcalTrap::VertexList vHAW(trapHAWR.vertexList());
1385     const EcalTrap::VertexList vFAW(trapFAW.vertexList());
1386 
1387     const double hawBoxClr(1 * dd4hep::mm);
1388 
1389     // HAW cut box to cut off back end of wedge
1390     const string hawCutName(alvWedge.hawRName + "CUTBOX");
1391     array<double, 3> hawBoxParms{{0.5 * b_hawR + hawBoxClr, 0.5 * alvWedge.hawRCutY, 0.5 * alvWedge.hawRCutZ}};
1392     Solid hawCutBox = Box(hawCutName, hawBoxParms[0], hawBoxParms[1], hawBoxParms[2]);
1393 #ifdef EDM_ML_DEBUG
1394     edm::LogVerbatim("EBGeom") << hawCutName << " Box " << cms::convert2mm(hawBoxParms[0]) << ":"
1395                                << cms::convert2mm(hawBoxParms[1]) << ":" << cms::convert2mm(hawBoxParms[2]);
1396 #endif
1397 
1398     const Pt3D b1(hawBoxParms[0], hawBoxParms[1], hawBoxParms[2]);
1399     const Pt3D b2(-hawBoxParms[0], hawBoxParms[1], hawBoxParms[2]);
1400     const Pt3D b3(-hawBoxParms[0], hawBoxParms[1], -hawBoxParms[2]);
1401 
1402     const double zDel(
1403         sqrt(4 * hawBoxParms[2] * hawBoxParms[2] - (h_hawR - alvWedge.hawRCutDelY) * (h_hawR - alvWedge.hawRCutDelY)));
1404 
1405     const Tf3D hawCutForm(b1,
1406                           b2,
1407                           b3,
1408                           vHAW[2] + Pt3D(hawBoxClr, -alvWedge.hawRCutDelY, 0),
1409                           vHAW[1] + Pt3D(-hawBoxClr, -alvWedge.hawRCutDelY, 0),
1410                           Pt3D(vHAW[0].x() - hawBoxClr, vHAW[0].y(), vHAW[0].z() - zDel));
1411 
1412     Solid hawRSolid = SubtractionSolid(hawRSolid1,
1413                                        hawCutBox,
1414                                        Transform3D(myrot(ns, hawCutName + "R", hawCutForm.getRotation()),
1415                                                    Position(hawCutForm.getTranslation().x(),
1416                                                             hawCutForm.getTranslation().y(),
1417                                                             hawCutForm.getTranslation().z())));
1418 #ifdef EDM_ML_DEBUG
1419     edm::LogVerbatim("EBGeom") << alvWedge.hawRName << " Subtraction " << hawRSolid1.name() << ":" << hawCutBox.name()
1420                                << " at (" << cms::convert2mm(hawCutForm.getTranslation().x()) << ","
1421                                << cms::convert2mm(hawCutForm.getTranslation().y()) << ","
1422                                << cms::convert2mm(hawCutForm.getTranslation().z()) << ")";
1423 #endif
1424     Volume hawRLog = Volume(alvWedge.hawRName, hawRSolid, ns.material(spm.mat));
1425 
1426     // FAW cut box to cut off back end of wedge
1427     const string fawCutName(alvWedge.fawName + "CUTBOX");
1428     const array<double, 3> fawBoxParms{{2 * hawBoxParms[0], hawBoxParms[1], hawBoxParms[2]}};
1429     Solid fawCutBox = Box(fawCutName, fawBoxParms[0], fawBoxParms[1], fawBoxParms[2]);
1430 #ifdef EDM_ML_DEBUG
1431     edm::LogVerbatim("EBGeom") << fawCutName << " Box " << cms::convert2mm(fawBoxParms[0]) << ":"
1432                                << cms::convert2mm(fawBoxParms[1]) << ":" << cms::convert2mm(fawBoxParms[2]);
1433 #endif
1434 
1435     const Pt3D bb1(fawBoxParms[0], fawBoxParms[1], fawBoxParms[2]);
1436     const Pt3D bb2(-fawBoxParms[0], fawBoxParms[1], fawBoxParms[2]);
1437     const Pt3D bb3(-fawBoxParms[0], fawBoxParms[1], -fawBoxParms[2]);
1438 
1439     const Tf3D fawCutForm(bb1,
1440                           bb2,
1441                           bb3,
1442                           vFAW[2] + Pt3D(2 * hawBoxClr, -5 * dd4hep::mm, 0),
1443                           vFAW[1] + Pt3D(-2 * hawBoxClr, -5 * dd4hep::mm, 0),
1444                           Pt3D(vFAW[1].x() - 2 * hawBoxClr, vFAW[1].y() - trapFAW.h(), vFAW[1].z() - zDel));
1445 
1446     Solid fawSolid = SubtractionSolid(fawSolid1,
1447                                       fawCutBox,
1448                                       Transform3D(myrot(ns, fawCutName + "R", fawCutForm.getRotation()),
1449                                                   Position(fawCutForm.getTranslation().x(),
1450                                                            fawCutForm.getTranslation().y(),
1451                                                            fawCutForm.getTranslation().z())));
1452 #ifdef EDM_ML_DEBUG
1453     edm::LogVerbatim("EBGeom") << alvWedge.fawName << " Subtraction " << fawSolid1.name() << ":" << fawCutBox.name()
1454                                << " at (" << cms::convert2mm(fawCutForm.getTranslation().x()) << ","
1455                                << cms::convert2mm(fawCutForm.getTranslation().y()) << ","
1456                                << cms::convert2mm(fawCutForm.getTranslation().z()) << ")";
1457 #endif
1458     Volume fawLog = Volume(alvWedge.fawName, fawSolid, ns.material(spm.mat));
1459 
1460     const Tf3D hawRform(vHAW[3],
1461                         vHAW[0],
1462                         vHAW[1],  // HAW inside FAW
1463                         vFAW[3],
1464                         0.5 * (vFAW[0] + vFAW[3]),
1465                         0.5 * (vFAW[1] + vFAW[2]));
1466 
1467     fawLog.placeVolume(
1468         hawRLog,
1469         copyOne,
1470         Transform3D(
1471             myrot(ns, alvWedge.hawRName + "R", hawRform.getRotation()),
1472             Position(hawRform.getTranslation().x(), hawRform.getTranslation().y(), hawRform.getTranslation().z())));
1473 #ifdef EDM_ML_DEBUG
1474     edm::LogVerbatim("EBGeomX") << hawRLog.name() << ":" << copyOne << " positioned in " << fawLog.name() << " at ("
1475                                 << cms::convert2mm(hawRform.getTranslation().x()) << ","
1476                                 << cms::convert2mm(hawRform.getTranslation().y()) << ","
1477                                 << cms::convert2mm(hawRform.getTranslation().z()) << ") with rotation";
1478 #endif
1479 
1480     fawLog.placeVolume(
1481         hawRLog,
1482         copyTwo,
1483         Transform3D(
1484             Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.) * RotationY(M_PI),  // rotate about Y after refl thru Z
1485             Position(-hawRform.getTranslation().x(), -hawRform.getTranslation().y(), -hawRform.getTranslation().z())));
1486 #ifdef EDM_ML_DEBUG
1487     edm::LogVerbatim("EBGeomX") << hawRLog.name() << ":" << copyTwo << " positioned in " << fawLog.name() << " at ("
1488                                 << cms::convert2mm(-hawRform.getTranslation().x()) << ","
1489                                 << cms::convert2mm(-hawRform.getTranslation().y()) << ","
1490                                 << cms::convert2mm(-hawRform.getTranslation().z()) << ") with rotation";
1491 #endif
1492     for (unsigned int iPhi(1); iPhi <= alvWedge.nFawPerSupm; ++iPhi) {
1493       const double rPhi(alvWedge.fawPhiOff + (iPhi - 0.5) * alvWedge.fawDelPhi);
1494 
1495       const Tf3D fawform(RoZ3D(rPhi) *
1496                          Tl3D(alvWedge.fawRadOff + (trapFAW.H() + trapFAW.h()) / 4, 0, 0.5 * trapFAW.L()) *
1497                          RoZ3D(-90_deg + alvWedge.fawPhiRot));
1498       if (alvWedge.fawHere) {
1499         spmLog.placeVolume(
1500             fawLog,
1501             iPhi,
1502             Transform3D(
1503                 myrot(ns, alvWedge.fawName + "_Rot" + std::to_string(iPhi), fawform.getRotation()),
1504                 Position(fawform.getTranslation().x(), fawform.getTranslation().y(), fawform.getTranslation().z())));
1505 #ifdef EDM_ML_DEBUG
1506         edm::LogVerbatim("EBGeomX") << fawLog.name() << ":" << iPhi << " positioned in " << spmLog.name() << " at ("
1507                                     << cms::convert2mm(fawform.getTranslation().x()) << ","
1508                                     << cms::convert2mm(fawform.getTranslation().y()) << ","
1509                                     << cms::convert2mm(fawform.getTranslation().z()) << ") with rotation";
1510 #endif
1511       }
1512     }
1513 
1514     // End Alveolar Wedge parent ------------------------------------------------------
1515 
1516     // Begin Grid + Tablet insertion
1517 
1518     const double h_Grid(grid.thick);
1519 
1520     const EcalTrap trapGrid(0.5 * (B_hawR - h_Grid * (B_hawR - a_hawR) / H_hawR),  // bl1, A/2
1521                             0.5 * (b_hawR - h_Grid * (B_hawR - a_hawR) / H_hawR),  // bl2, a/2
1522                             0.5 * b_hawR,                                          // tl2, b/2
1523                             0.5 * h_Grid,                                          // h1, H/2
1524                             0.5 * h_Grid,                                          // h2, h/2
1525                             0.5 * (L_hawR - 8 * dd4hep::cm),                       // dz,  L/2
1526                             90_deg,                                                // alfa1
1527                             0,                                                     // x15
1528                             H_hawR - h_hawR                                        // y15
1529     );
1530 
1531     Solid gridSolid = mytrap(grid.name, trapGrid);
1532     Volume gridLog = Volume(grid.name, gridSolid, ns.material(grid.mat));
1533 
1534     const EcalTrap::VertexList vGrid(trapGrid.vertexList());
1535 
1536     const Tf3D gridForm(vGrid[4],
1537                         vGrid[5],
1538                         vGrid[6],  // Grid inside HAW
1539                         vHAW[5] - Pt3D(0, h_Grid, 0),
1540                         vHAW[5],
1541                         vHAW[6]);
1542 
1543     if (0 != grid.here) {
1544       hawRLog.placeVolume(
1545           gridLog,
1546           copyOne,
1547           Transform3D(
1548               myrot(ns, grid.name + "R", gridForm.getRotation()),
1549               Position(gridForm.getTranslation().x(), gridForm.getTranslation().y(), gridForm.getTranslation().z())));
1550 #ifdef EDM_ML_DEBUG
1551       edm::LogVerbatim("EBGeomX") << gridLog.name() << ":" << copyOne << " positioned in " << hawRLog.name() << " at ("
1552                                   << cms::convert2mm(gridForm.getTranslation().x()) << ","
1553                                   << cms::convert2mm(gridForm.getTranslation().y()) << ","
1554                                   << cms::convert2mm(gridForm.getTranslation().z()) << ") with rotation";
1555 #endif
1556     }
1557     // End Grid + Tablet insertion
1558 
1559     // begin filling Wedge with crystal plus supports --------------------------
1560 
1561     const double aNom(cry.nomCryDimAF);
1562     const double LNom(cry.nomCryDimLZ);
1563 
1564     const double AUnd(cry.underAR);
1565     const double aUnd(cry.underAF);
1566     const double bUnd(cry.underCF);
1567     const double HUnd(cry.underBR);
1568     const double hUnd(cry.underBF);
1569     const double LUnd(cry.underLZ);
1570 
1571     const double sWall(alv.wallThAlv);
1572     const double sWrap(alv.wrapThAlv);
1573     const double sClr(alv.clrThAlv);
1574 
1575     const double fWall(alv.wallFrAlv);
1576     const double fWrap(alv.wrapFrAlv);
1577     const double fClr(alv.clrFrAlv);
1578 
1579     const double rWall(alv.wallReAlv);
1580     const double rWrap(alv.wrapReAlv);
1581     const double rClr(alv.clrReAlv);
1582 
1583     // theta is angle in yz plane between z axis & leading edge of crystal
1584     double theta(90_deg);
1585     double zee(0);
1586     double side(0);
1587     double zeta(0_deg);  // increment in theta for last crystal
1588 
1589     for (unsigned int cryType(1); cryType <= alv.nCryTypes; ++cryType) {
1590       const string sType("_" + std::string(10 > cryType ? "0" : "") + std::to_string(cryType));
1591 
1592 #ifdef EDM_ML_DEBUG
1593       edm::LogVerbatim("EcalGeom") << "Crytype=" << cryType;
1594 #endif
1595       const double ANom(cry.vecNomCryDimAR[cryType - 1]);
1596       const double BNom(cry.vecNomCryDimCR[cryType - 1]);
1597       const double bNom(cry.vecNomCryDimCF[cryType - 1]);
1598       const double HNom(cry.vecNomCryDimBR[cryType - 1]);
1599       const double hNom(cry.vecNomCryDimBF[cryType - 1]);
1600 
1601       const double alfCry(90_deg + atan((bNom - bUnd - aNom + aUnd) / (hNom - hUnd)));
1602 
1603       const EcalTrap trapCry(0.5 * (ANom - AUnd),        //double aHalfLengthXNegZLoY , // bl1, A/2
1604                              0.5 * (aNom - aUnd),        //double aHalfLengthXPosZLoY , // bl2, a/2
1605                              0.5 * (bNom - bUnd),        //double aHalfLengthXPosZHiY , // tl2, b/2
1606                              0.5 * (HNom - HUnd),        //double aHalfLengthYNegZ    , // h1, H/2
1607                              0.5 * (hNom - hUnd),        //double aHalfLengthYPosZ    , // h2, h/2
1608                              0.5 * (LNom - LUnd),        //double aHalfLengthZ        , // dz,  L/2
1609                              alfCry,                     //double aAngleAD            , // alfa1
1610                              aNom - aUnd - ANom + AUnd,  //double aCoord15X           , // x15
1611                              hNom - hUnd - HNom + HUnd   //double aCoord15Y             // y15
1612       );
1613 
1614       const string cryDDName(cry.name + sType);
1615       Solid crySolid = mytrap(cry.name, trapCry);
1616       Volume cryLog = Volume(cryDDName, crySolid, ns.material(cry.mat));
1617 
1618       //++++++++++++++++++++++++++++++++++  APD ++++++++++++++++++++++++++++++++++
1619       const unsigned int copyCap(1);
1620       const string capDDName(cap.name + sType);
1621       Solid capSolid = Box(capDDName, cap.xSizeHalf, cap.ySizeHalf, cap.thickHalf);
1622 #ifdef EDM_ML_DEBUG
1623       edm::LogVerbatim("EBGeom") << capDDName << " Box " << cms::convert2mm(cap.xSizeHalf) << ":"
1624                                  << cms::convert2mm(cap.ySizeHalf) << ":" << cms::convert2mm(cap.thickHalf);
1625 #endif
1626       Volume capLog = Volume(capDDName, capSolid, ns.material(cap.mat));
1627 
1628       const string sglDDName(apd.sglName + sType);
1629       Solid sglSolid = Box(sglDDName, cap.xSizeHalf, cap.ySizeHalf, apd.sglThick / 2.);
1630 #ifdef EDM_ML_DEBUG
1631       edm::LogVerbatim("EBGeom") << sglDDName << " Box " << cms::convert2mm(cap.xSizeHalf) << ":"
1632                                  << cms::convert2mm(cap.ySizeHalf) << ":" << cms::convert2mm(apd.sglThick / 2.);
1633 #endif
1634       Volume sglLog = Volume(sglDDName, sglSolid, ns.material(apd.sglMat));
1635       const unsigned int copySGL(1);
1636 
1637       const string cerDDName(cer.name + sType);
1638       Solid cerSolid = Box(cerDDName, cer.xSizeHalf, cer.ySizeHalf, cer.thickHalf);
1639 #ifdef EDM_ML_DEBUG
1640       edm::LogVerbatim("EBGeom") << cerDDName << " Box " << cms::convert2mm(cer.xSizeHalf) << ":"
1641                                  << cms::convert2mm(cer.ySizeHalf) << ":" << cms::convert2mm(cer.thickHalf);
1642 #endif
1643       Volume cerLog = Volume(cerDDName, cerSolid, ns.material(cer.mat));
1644       unsigned int copyCER(0);
1645 
1646       const string bsiDDName(bSi.name + sType);
1647       Solid bsiSolid = Box(bsiDDName, bSi.xSizeHalf, bSi.ySizeHalf, bSi.thickHalf);
1648 #ifdef EDM_ML_DEBUG
1649       edm::LogVerbatim("EBGeom") << bsiDDName << " Box " << cms::convert2mm(bSi.xSizeHalf) << ":"
1650                                  << cms::convert2mm(bSi.ySizeHalf) << ":" << cms::convert2mm(bSi.thickHalf);
1651 #endif
1652       Volume bsiLog = Volume(bsiDDName, bsiSolid, ns.material(bSi.mat));
1653       const unsigned int copyBSi(1);
1654 
1655       const string atjDDName(apd.atjName + sType);
1656       Solid atjSolid = Box(atjDDName, 0.5 * apd.side, 0.5 * apd.side, apd.atjThickHalf);
1657 #ifdef EDM_ML_DEBUG
1658       edm::LogVerbatim("EBGeom") << atjDDName << " Box " << cms::convert2mm(0.5 * apd.side) << ":"
1659                                  << cms::convert2mm(0.5 * apd.side) << ":" << cms::convert2mm(apd.atjThickHalf);
1660 #endif
1661       Volume atjLog = Volume(atjDDName, atjSolid, ns.material(apd.atjMat));
1662       const unsigned int copyATJ(1);
1663 
1664       const string aglDDName(apd.aglName + sType);
1665       Solid aglSolid = Box(aglDDName, bSi.xSizeHalf, bSi.ySizeHalf, 0.5 * apd.aglThick);
1666 #ifdef EDM_ML_DEBUG
1667       edm::LogVerbatim("EBGeom") << aglDDName << " Box " << cms::convert2mm(bSi.xSizeHalf) << ":"
1668                                  << cms::convert2mm(bSi.ySizeHalf) << ":" << cms::convert2mm(0.5 * apd.aglThick);
1669 #endif
1670       Volume aglLog = Volume(aglDDName, aglSolid, ns.material(apd.aglMat));
1671       const unsigned int copyAGL(1);
1672 
1673       const string andDDName(apd.andName + sType);
1674       Solid andSolid = Box(andDDName, 0.5 * apd.side, 0.5 * apd.side, 0.5 * apd.andThick);
1675 #ifdef EDM_ML_DEBUG
1676       edm::LogVerbatim("EBGeom") << andDDName << " Box " << cms::convert2mm(0.5 * apd.side) << ":"
1677                                  << cms::convert2mm(0.5 * apd.side) << ":" << cms::convert2mm(0.5 * apd.andThick);
1678 #endif
1679       Volume andLog = Volume(andDDName, andSolid, ns.material(apd.andMat));
1680       const unsigned int copyAND(1);
1681 
1682       const string apdDDName(apd.name + sType);
1683       Solid apdSolid = Box(apdDDName, 0.5 * apd.side, 0.5 * apd.side, 0.5 * apd.thick);
1684 #ifdef EDM_ML_DEBUG
1685       edm::LogVerbatim("EBGeom") << apdDDName << " Box " << cms::convert2mm(0.5 * apd.side) << ":"
1686                                  << cms::convert2mm(0.5 * apd.side) << ":" << cms::convert2mm(0.5 * apd.thick);
1687 #endif
1688       Volume apdLog = Volume(apdDDName, apdSolid, ns.material(apd.mat));
1689       const unsigned int copyAPD(1);
1690 
1691       //++++++++++++++++++++++++++++++++++ END APD ++++++++++++++++++++++++++++++++++
1692 
1693       const double delta(atan((HNom - hNom) / LNom));
1694       const double sindelta(sin(delta));
1695 
1696       const double gamma(atan((ANom - aNom) / LNom));
1697       const double singamma(sin(gamma));
1698 
1699       const double beta(atan((BNom - bNom) / LNom));
1700       const double sinbeta(sin(beta));
1701 
1702       // Now clearance trap
1703       const double alfClr(90_deg + atan((bNom - aNom) / (hNom + sClr)));
1704 
1705       const EcalTrap trapClr(0.5 * (ANom + sClr + rClr * singamma),  //double aHalfLengthXNegZLoY , // bl1, A/2
1706                              0.5 * (aNom + sClr - fClr * singamma),  //double aHalfLengthXPosZLoY , // bl2, a/2
1707                              0.5 * (bNom + sClr - fClr * sinbeta),   //double aHalfLengthXPosZHiY , // tl2, b/2
1708                              0.5 * (HNom + sClr + rClr * sindelta),  //double aHalfLengthYNegZ    , // h1,  H/2
1709                              0.5 * (hNom + sClr - fClr * sindelta),  //double aHalfLengthYPosZ    , // h2,  h/2
1710                              0.5 * (LNom + fClr + rClr),             // dz,  L/2
1711                              alfClr,                                 //double aAngleAD            , // alfa1
1712                              aNom - ANom,                            //double aCoord15X           , // x15
1713                              hNom - HNom                             //double aCoord15Y             // y15
1714       );
1715 
1716       const string clrDDName(cry.clrName + sType);
1717       Solid clrSolid = mytrap(clrDDName, trapClr);
1718       Volume clrLog = Volume(clrDDName, clrSolid, ns.material(cry.clrMat));
1719 
1720       // Now wrap trap
1721       const double alfWrap(90_deg + atan((bNom - aNom) / (hNom + sClr + 2. * sWrap)));
1722 
1723       const EcalTrap trapWrap(0.5 * (trapClr.A() + 2. * sWrap + rWrap * singamma),  // bl1, A/2
1724                               0.5 * (trapClr.a() + 2. * sWrap - fWrap * singamma),  // bl2, a/2
1725                               0.5 * (trapClr.b() + 2. * sWrap - fWrap * sinbeta),   // tl2, b/2
1726                               0.5 * (trapClr.H() + 2. * sWrap + rWrap * sindelta),  // h1,  H/2
1727                               0.5 * (trapClr.h() + 2. * sWrap - fWrap * sindelta),  // h2,  h/2
1728                               0.5 * (trapClr.L() + fWrap + rWrap),                  // dz,  L/2
1729                               alfWrap,  //double aAngleAD            , // alfa1
1730                               aNom - ANom - (cryType > 9 ? 0 : 0.020 * dd4hep::mm),
1731                               hNom - HNom  //double aCoord15Y             // y15
1732       );
1733 
1734       const string wrapDDName(cry.wrapName + sType);
1735       Solid wrapSolid = mytrap(wrapDDName, trapWrap);
1736       Volume wrapLog = Volume(wrapDDName, wrapSolid, ns.material(cry.wrapMat));
1737 
1738       // Now wall trap
1739 
1740       const double alfWall(90_deg + atan((bNom - aNom) / (hNom + sClr + 2. * sWrap + 2. * sWall)));
1741 
1742       const EcalTrap trapWall(0.5 * (trapWrap.A() + 2 * sWall + rWall * singamma),  // A/2
1743                               0.5 * (trapWrap.a() + 2 * sWall - fWall * singamma),  // a/2
1744                               0.5 * (trapWrap.b() + 2 * sWall - fWall * sinbeta),   // b/2
1745                               0.5 * (trapWrap.H() + 2 * sWall + rWall * sindelta),  // H/2
1746                               0.5 * (trapWrap.h() + 2 * sWall - fWall * sindelta),  // h/2
1747                               0.5 * (trapWrap.L() + fWall + rWall),                 // L/2
1748                               alfWall,                                              // alfa1
1749                               aNom - ANom - (cryType < 10 ? 0.150 * dd4hep::mm : 0.100 * dd4hep::mm),
1750                               hNom - HNom  // y15
1751       );
1752 
1753       const string wallDDName(cry.wallName + sType);
1754       Solid wallSolid = mytrap(wallDDName, trapWall);
1755       Volume wallLog = Volume(wallDDName, wallSolid, ns.material(cry.wallMat));
1756 
1757       // Now for placement of cry within clr
1758       const Vec3 cryToClr(0., 0., 0.5 * (rClr - fClr));
1759       clrLog.placeVolume(cryLog, copyOne, Position(0, 0, 0.5 * (rClr - fClr)));
1760 #ifdef EDM_ML_DEBUG
1761       edm::LogVerbatim("EBGeomX") << cryLog.name() << ":" << copyOne << " positioned in " << clrLog.name()
1762                                   << " at (0,0," << cms::convert2mm(0.5 * (rClr - fClr)) << ") with no rotation";
1763 #endif
1764       if (0 != cap.here) {
1765         bsiLog.placeVolume(aglLog, copyAGL, Position(0, 0, -0.5 * apd.aglThick + bSi.thickHalf));
1766 #ifdef EDM_ML_DEBUG
1767         edm::LogVerbatim("EBGeomX") << aglLog.name() << ":" << copyAGL << " positioned in " << bsiLog.name()
1768                                     << " at (0,0," << cms::convert2mm(-0.5 * apd.aglThick + bSi.thickHalf)
1769                                     << ") with no rotation";
1770 #endif
1771         bsiLog.placeVolume(andLog, copyAND, Position(0, 0, -0.5 * apd.andThick - apd.aglThick + bSi.thickHalf));
1772 #ifdef EDM_ML_DEBUG
1773         edm::LogVerbatim("EBGeomX") << andLog.name() << ":" << copyAND << " positioned in " << bsiLog.name()
1774                                     << " at (0,0,"
1775                                     << cms::convert2mm(-0.5 * apd.andThick - apd.aglThick + bSi.thickHalf)
1776                                     << ") with no rotation";
1777 #endif
1778         bsiLog.placeVolume(
1779             apdLog, copyAPD, Position(0, 0, -0.5 * apd.thick - apd.andThick - apd.aglThick + bSi.thickHalf));
1780 #ifdef EDM_ML_DEBUG
1781         edm::LogVerbatim("EBGeomX") << apdLog.name() << ":" << copyAPD << " positioned in " << bsiLog.name()
1782                                     << " at (0,0,"
1783                                     << cms::convert2mm(-0.5 * apd.thick - apd.andThick - apd.aglThick + bSi.thickHalf)
1784                                     << ") with no rotation";
1785 #endif
1786         bsiLog.placeVolume(atjLog,
1787                            copyATJ,
1788                            Position(0, 0, -apd.atjThickHalf - apd.thick - apd.andThick - apd.aglThick + bSi.thickHalf));
1789 #ifdef EDM_ML_DEBUG
1790         edm::LogVerbatim("EBGeomX") << atjLog.name() << ":" << copyATJ << " positioned in " << bsiLog.name()
1791                                     << " at (0,0,"
1792                                     << cms::convert2mm(-apd.atjThickHalf - apd.thick - apd.andThick - apd.aglThick +
1793                                                        bSi.thickHalf)
1794                                     << ") with no rotation";
1795 #endif
1796         cerLog.placeVolume(bsiLog, copyBSi, Position(0, 0, -bSi.thickHalf + cer.thickHalf));
1797 #ifdef EDM_ML_DEBUG
1798         edm::LogVerbatim("EBGeomX") << bsiLog.name() << ":" << copyBSi << " positioned in " << cerLog.name()
1799                                     << " at (0,0," << cms::convert2mm(-bSi.thickHalf + cer.thickHalf)
1800                                     << ") with no rotation";
1801 #endif
1802         capLog.placeVolume(sglLog, copySGL, Position(0, 0, -0.5 * apd.sglThick + cap.thickHalf));
1803 #ifdef EDM_ML_DEBUG
1804         edm::LogVerbatim("EBGeomX") << sglLog.name() << ":" << copySGL << " positioned in " << capLog.name()
1805                                     << " at (0,0," << cms::convert2mm(-0.5 * apd.sglThick + cap.thickHalf)
1806                                     << ") with no rotation";
1807 #endif
1808 
1809         for (unsigned int ijkl(0); ijkl != 2; ++ijkl) {
1810           capLog.placeVolume(cerLog,
1811                              ++copyCER,
1812                              Position(trapCry.bl1() - (0 == ijkl ? apd.x1 : apd.x2),
1813                                       trapCry.h1() - apd.z,
1814                                       -apd.sglThick - cer.thickHalf + cap.thickHalf));
1815 #ifdef EDM_ML_DEBUG
1816           edm::LogVerbatim("EBGeomX") << cerLog.name() << ":" << copyCER << " positioned in " << capLog.name()
1817                                       << " at (" << cms::convert2mm(trapCry.bl1() - (0 == ijkl ? apd.x1 : apd.x2))
1818                                       << "," << cms::convert2mm(trapCry.h1() - apd.z) << ","
1819                                       << cms::convert2mm(-apd.sglThick - cer.thickHalf + cap.thickHalf)
1820                                       << ") with no rotation";
1821 #endif
1822         }
1823         clrLog.placeVolume(capLog, copyCap, Position(0, 0, -trapCry.dz() - cap.thickHalf + 0.5 * (rClr - fClr)));
1824 #ifdef EDM_ML_DEBUG
1825         edm::LogVerbatim("EBGeomX") << capLog.name() << ":" << copyCap << " positioned in " << clrLog.name()
1826                                     << " at (0,0,"
1827                                     << cms::convert2mm(-trapCry.dz() - cap.thickHalf + 0.5 * (rClr - fClr))
1828                                     << ") with no rotation";
1829 #endif
1830       }
1831 
1832       const Vec3 clrToWrap(0, 0, 0.5 * (rWrap - fWrap));
1833       wrapLog.placeVolume(clrLog, copyOne, Position(0, 0, 0.5 * (rWrap - fWrap)));  //SAME as cryToWrap
1834 #ifdef EDM_ML_DEBUG
1835       edm::LogVerbatim("EBGeomX") << clrLog.name() << ":" << copyOne << " positioned in " << wrapLog.name()
1836                                   << " at (0,0," << cms::convert2mm(0.5 * (rWrap - fWrap)) << ") with no rotation";
1837 #endif
1838 
1839       // Now for placement of clr within wall
1840       const Vec3 wrapToWall1(0, 0, 0.5 * (rWall - fWall));
1841       const Vec3 wrapToWall(Vec3((cryType > 9 ? 0 : 0.005 * dd4hep::mm), 0, 0) + wrapToWall1);
1842       wallLog.placeVolume(
1843           wrapLog,
1844           copyOne,
1845           Position(Vec3((cryType > 9 ? 0 : 0.005 * dd4hep::mm), 0, 0) + wrapToWall1));  //SAME as wrapToWall
1846 #ifdef EDM_ML_DEBUG
1847       edm::LogVerbatim("EBGeomX") << wrapLog.name() << ":" << copyOne << " positioned in " << wallLog.name() << " at ("
1848                                   << cms::convert2mm(wrapToWall.x()) << "," << cms::convert2mm(wrapToWall.y()) << ","
1849                                   << cms::convert2mm(wrapToWall.z()) << ") with no rotation";
1850 #endif
1851 
1852       const EcalTrap::VertexList vWall(trapWall.vertexList());
1853       const EcalTrap::VertexList vCry(trapCry.vertexList());
1854 
1855       const double sidePrime(0.5 * (trapWall.a() - trapCry.a()));
1856       const double frontPrime(fWall + fWrap + fClr + 0.5 * LUnd);
1857 
1858       // define web plates with clearance ===========================================
1859 
1860       if (1 == cryType)  // first web plate: inside clearance volume
1861       {
1862         const unsigned int iWeb(0);
1863         const Pt3D corner(vHAW[4] + Pt3D(0, alvWedge.hawYOffCry, 0));
1864         const unsigned int copyOne(1);
1865         const double LWebx(web.vecWebLength[iWeb]);
1866         const double BWebx(trapWall.b() + (trapWall.B() - trapWall.b()) * LWebx / trapWall.L());
1867 
1868         const double thick(web.vecWebPlTh[iWeb] + web.vecWebClrTh[iWeb]);
1869         const EcalTrap trapWebClr(0.5 * BWebx,           // A/2
1870                                   0.5 * trapWall.b(),    // a/2
1871                                   0.5 * trapWall.b(),    // b/2
1872                                   0.5 * thick,           // H/2
1873                                   0.5 * thick,           // h/2
1874                                   0.5 * LWebx,           // L/2
1875                                   90_deg,                // alfa1
1876                                   trapWall.b() - BWebx,  // x15
1877                                   0                      // y15
1878         );
1879         std::string webClrName(web.clrName + std::to_string(iWeb));
1880         Solid webClrSolid = mytrap(webClrName, trapWebClr);
1881         Volume webClrLog = Volume(webClrName, webClrSolid, ns.material(web.clrMat));
1882 
1883         const EcalTrap trapWebPl(0.5 * trapWebClr.A(),             // A/2
1884                                  0.5 * trapWebClr.a(),             // a/2
1885                                  0.5 * trapWebClr.b(),             // b/2
1886                                  0.5 * web.vecWebPlTh[iWeb],       // H/2
1887                                  0.5 * web.vecWebPlTh[iWeb],       // h/2
1888                                  0.5 * trapWebClr.L(),             // L/2
1889                                  90._deg,                          // alfa1
1890                                  trapWebClr.b() - trapWebClr.B(),  // x15
1891                                  0                                 // y15
1892         );
1893         std::string webPlName(web.plName + std::to_string(iWeb));
1894         Solid webPlSolid = mytrap(webPlName, trapWebPl);
1895         Volume webPlLog = Volume(webPlName, webPlSolid, ns.material(web.plMat));
1896 
1897         webClrLog.placeVolume(webPlLog, copyOne);  // place plate inside clearance volume
1898 #ifdef EDM_ML_DEBUG
1899         edm::LogVerbatim("EBGeomX") << webPlLog.name() << ":" << copyOne << " positioned in " << webClrName
1900                                     << " at (0,0,0) with no rotation";
1901 #endif
1902         const EcalTrap::VertexList vWeb(trapWebClr.vertexList());
1903 
1904         zee += trapWebClr.h() / sin(theta);
1905 
1906         const double beta(theta + delta);
1907 
1908         const double zWeb(zee - frontPrime * cos(beta) + sidePrime * sin(beta));
1909         const double yWeb(frontPrime * sin(beta) + sidePrime * cos(beta));
1910 
1911         const Pt3D wedge3(corner + Pt3D(0, -yWeb, zWeb));
1912         const Pt3D wedge2(wedge3 + Pt3D(0, trapWebClr.h() * cos(theta), -trapWebClr.h() * sin(theta)));
1913         const Pt3D wedge1(wedge3 + Pt3D(trapWebClr.a(), 0, 0));
1914 #ifdef EDM_ML_DEBUG
1915         edm::LogVerbatim("EcalGeom") << "trap1=" << vWeb[0] << ", trap2=" << vWeb[2] << ", trap3=" << vWeb[3];
1916         edm::LogVerbatim("EcalGeom") << "wedge1=" << wedge1 << ", wedge2=" << wedge2 << ", wedge3=" << wedge3;
1917 #endif
1918         const Tf3D tForm(vWeb[0], vWeb[2], vWeb[3], wedge1, wedge2, wedge3);
1919 
1920         if (0 != web.here) {
1921           hawRLog.placeVolume(
1922               webClrLog,
1923               copyOne,
1924               Transform3D(
1925                   myrot(ns, webClrName + std::to_string(iWeb), tForm.getRotation()),
1926                   Position(tForm.getTranslation().x(), tForm.getTranslation().y(), tForm.getTranslation().z())));
1927 #ifdef EDM_ML_DEBUG
1928           edm::LogVerbatim("EBGeomX") << webClrLog.name() << ":" << copyOne << " positioned in " << hawRLog.name()
1929                                       << " at (" << cms::convert2mm(tForm.getTranslation().x()) << ","
1930                                       << cms::convert2mm(tForm.getTranslation().y()) << ","
1931                                       << cms::convert2mm(tForm.getTranslation().z()) << ") with rotation";
1932 #endif
1933         }
1934         zee += alv.vecGapAlvEta[0];
1935       }
1936 
1937       for (unsigned int etaAlv(1); etaAlv <= alv.nCryPerAlvEta; ++etaAlv) {
1938 #ifdef EDM_ML_DEBUG
1939         edm::LogVerbatim("EcalGeom") << "theta=" << convertRadToDeg(theta) << ", sidePrime=" << sidePrime
1940                                      << ", frontPrime=" << frontPrime << ",  zeta=" << zeta << ", delta=" << delta
1941                                      << ",  zee=" << zee;
1942 #endif
1943 
1944         zee += 0.075 * dd4hep::mm + (side * cos(zeta) + trapWall.h() - sidePrime) / sin(theta);
1945 
1946         // make transform for placing enclosed crystal
1947 
1948         const Pt3D trap2(vCry[2] + cryToClr + clrToWrap + wrapToWall);
1949 
1950         const Pt3D trap3(trap2 + Pt3D(0, -trapCry.h(), 0));
1951         const Pt3D trap1(trap3 + Pt3D(-trapCry.a(), 0, 0));
1952 
1953         const Pt3D wedge3(vHAW[4] + Pt3D(sidePrime, alvWedge.hawYOffCry, zee));
1954         const Pt3D wedge2(wedge3 + Pt3D(0, trapCry.h() * cos(theta), -trapCry.h() * sin(theta)));
1955         const Pt3D wedge1(wedge3 + Pt3D(trapCry.a(), 0, 0));
1956 
1957         const Tf3D tForm1(trap1, trap2, trap3, wedge1, wedge2, wedge3);
1958 
1959         const double xx(0.050 * dd4hep::mm);
1960 
1961         const Tf3D tForm(HepGeom::Translate3D(xx, 0, 0) * tForm1);
1962         hawRLog.placeVolume(
1963             wallLog,
1964             etaAlv,
1965             Transform3D(myrot(ns, wallDDName + "_" + std::to_string(etaAlv), tForm.getRotation()),
1966                         Position(tForm.getTranslation().x(), tForm.getTranslation().y(), tForm.getTranslation().z())));
1967 #ifdef EDM_ML_DEBUG
1968         edm::LogVerbatim("EBGeomX") << wallLog.name() << ":" << etaAlv << " positioned in " << hawRLog.name() << " at ("
1969                                     << cms::convert2mm(tForm.getTranslation().x()) << ","
1970                                     << cms::convert2mm(tForm.getTranslation().y()) << ","
1971                                     << cms::convert2mm(tForm.getTranslation().z()) << ") with rotation";
1972 #endif
1973         theta -= delta;
1974         side = sidePrime;
1975         zeta = delta;
1976       }
1977       if (5 == cryType || 9 == cryType || 13 == cryType || 17 == cryType) {  // web plates
1978         zee += 0.5 * alv.vecGapAlvEta[cryType] / sin(theta);
1979 
1980         const unsigned int iWeb(cryType / 4);
1981         const Pt3D corner(vHAW[4] + Pt3D(0, alvWedge.hawYOffCry, 0));
1982         const unsigned int copyOne(1);
1983         const double LWebx(web.vecWebLength[iWeb]);
1984         const double BWebx(trapWall.a() + (trapWall.A() - trapWall.a()) * LWebx / trapWall.L());
1985 
1986         const double thick(web.vecWebPlTh[iWeb] + web.vecWebClrTh[iWeb]);
1987         const EcalTrap trapWebClr(0.5 * BWebx,           // A/2
1988                                   0.5 * trapWall.a(),    // a/2
1989                                   0.5 * trapWall.a(),    // b/2
1990                                   0.5 * thick,           // H/2
1991                                   0.5 * thick,           // h/2
1992                                   0.5 * LWebx,           // L/2
1993                                   90_deg,                // alfa1
1994                                   trapWall.a() - BWebx,  // x15
1995                                   0                      // y15
1996         );
1997         std::string webClrName(web.clrName + std::to_string(iWeb));
1998         Solid webClrSolid = mytrap(webClrName, trapWebClr);
1999         Volume webClrLog = Volume(webClrName, webClrSolid, ns.material(web.clrMat));
2000 
2001         const EcalTrap trapWebPl(0.5 * trapWebClr.A(),             // A/2
2002                                  0.5 * trapWebClr.a(),             // a/2
2003                                  0.5 * trapWebClr.b(),             // b/2
2004                                  0.5 * web.vecWebPlTh[iWeb],       // H/2
2005                                  0.5 * web.vecWebPlTh[iWeb],       // h/2
2006                                  0.5 * trapWebClr.L(),             // L/2
2007                                  90._deg,                          // alfa1
2008                                  trapWebClr.b() - trapWebClr.B(),  // x15
2009                                  0                                 // y15
2010         );
2011         std::string webPlName(web.plName + std::to_string(iWeb));
2012         Solid webPlSolid = mytrap(webPlName, trapWebPl);
2013         Volume webPlLog = Volume(webPlName, webPlSolid, ns.material(web.plMat));
2014 
2015         webClrLog.placeVolume(webPlLog, copyOne);  // place plate inside clearance volume
2016 #ifdef EDM_ML_DEBUG
2017         edm::LogVerbatim("EBGeomX") << webPlLog.name() << ":" << copyOne << " positioned in " << webClrName
2018                                     << " at (0,0,0) with no rotation";
2019 #endif
2020         const EcalTrap::VertexList vWeb(trapWebClr.vertexList());
2021 
2022         zee += trapWebClr.h() / sin(theta);
2023 
2024         const double beta(theta + delta);
2025 
2026         const double zWeb(zee - frontPrime * cos(beta) + sidePrime * sin(beta));
2027         const double yWeb(frontPrime * sin(beta) + sidePrime * cos(beta));
2028 
2029         const Pt3D wedge3(corner + Pt3D(0, -yWeb, zWeb));
2030         const Pt3D wedge2(wedge3 + Pt3D(0, trapWebClr.h() * cos(theta), -trapWebClr.h() * sin(theta)));
2031         const Pt3D wedge1(wedge3 + Pt3D(trapWebClr.a(), 0, 0));
2032 #ifdef EDM_ML_DEBUG
2033         edm::LogVerbatim("EcalGeom") << "trap1=" << vWeb[0] << ", trap2=" << vWeb[2] << ", trap3=" << vWeb[3];
2034         edm::LogVerbatim("EcalGeom") << "wedge1=" << wedge1 << ", wedge2=" << wedge2 << ", wedge3=" << wedge3;
2035 #endif
2036         const Tf3D tForm(vWeb[0], vWeb[2], vWeb[3], wedge1, wedge2, wedge3);
2037 
2038         if (0 != web.here) {
2039           hawRLog.placeVolume(
2040               webClrLog,
2041               copyOne,
2042               Transform3D(
2043                   myrot(ns, webClrName + std::to_string(iWeb), tForm.getRotation()),
2044                   Position(tForm.getTranslation().x(), tForm.getTranslation().y(), tForm.getTranslation().z())));
2045 #ifdef EDM_ML_DEBUG
2046           edm::LogVerbatim("EBGeomX") << webClrLog.name() << ":" << copyOne << " positioned in " << hawRLog.name()
2047                                       << " at (" << cms::convert2mm(tForm.getTranslation().x()) << ","
2048                                       << cms::convert2mm(tForm.getTranslation().y()) << ","
2049                                       << cms::convert2mm(tForm.getTranslation().z()) << ") with rotation";
2050 #endif
2051         }
2052 
2053         zee += 0.5 * alv.vecGapAlvEta[cryType] / sin(theta);
2054       } else {
2055         if (17 != cryType)
2056           zee += alv.vecGapAlvEta[cryType] / sin(theta);
2057       }
2058     }
2059     // END   filling Wedge with crystal plus supports --------------------------
2060 
2061     //------------------------------------------------------------------------
2062     //------------------------------------------------------------------------
2063     //------------------------------------------------------------------------
2064     //------------------------------------------------------------------------
2065     //**************** Material at outer radius of supermodule ***************
2066     //------------------------------------------------------------------------
2067     //------------------------------------------------------------------------
2068     //------------------------------------------------------------------------
2069     //------------------------------------------------------------------------
2070 
2071     if (0 != back.here) {
2072       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2073       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2074       //!!!!!!!!!!!!!!     Begin Back Cover Plate     !!!!!!!!!!!!!!!!!!!!!!!
2075       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2076       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2077 
2078       const Position outtra(back.xOff + 0.5 * back.sideHeight, back.yOff, 0.5 * back.sideLength);
2079 
2080       const double realBPthick(back.plateThick + back.plate2Thick);
2081       array<double, 3> backPlateParms{{0.5 * back.plateWidth, 0.5 * realBPthick, 0.5 * back.plateLength}};
2082       Solid backPlateSolid = Box(back.plateName, backPlateParms[0], backPlateParms[1], backPlateParms[2]);
2083 #ifdef EDM_ML_DEBUG
2084       edm::LogVerbatim("EBGeom") << back.plateName << " Box " << cms::convert2mm(backPlateParms[0]) << ":"
2085                                  << cms::convert2mm(backPlateParms[1]) << ":" << cms::convert2mm(backPlateParms[2]);
2086 #endif
2087       Volume backPlateLog = Volume(back.plateName, backPlateSolid, ns.material(back.plateMat));
2088 
2089       const Position backPlateTra(
2090           0.5 * back.sideHeight + backPlateParms[1], 0, backPlateParms[2] - 0.5 * back.sideLength);
2091 
2092       Solid backPlate2Solid =
2093           Box(back.plate2Name, 0.5 * back.plateWidth, 0.5 * back.plate2Thick, 0.5 * back.plateLength);
2094 #ifdef EDM_ML_DEBUG
2095       edm::LogVerbatim("EBGeom") << back.plate2Name << " Box " << cms::convert2mm(0.5 * back.plateWidth) << ":"
2096                                  << cms::convert2mm(0.5 * back.plate2Thick) << ":"
2097                                  << cms::convert2mm(0.5 * back.plateLength);
2098 #endif
2099       Volume backPlate2Log = Volume(back.plate2Name, backPlate2Solid, ns.material(back.plate2Mat));
2100 
2101       const Position backPlate2Tra(0, -backPlateParms[1] + back.plate2Thick / 2., 0);
2102       if (0 != back.plateHere) {
2103         backPlateLog.placeVolume(backPlate2Log, copyOne, Transform3D(backPlate2Tra));
2104 #ifdef EDM_ML_DEBUG
2105         edm::LogVerbatim("EBGeomX") << backPlate2Log.name() << ":" << copyOne << " positioned in "
2106                                     << backPlateLog.name() << " at (" << cms::convert2mm(backPlate2Tra.x()) << ","
2107                                     << cms::convert2mm(backPlate2Tra.y()) << "," << cms::convert2mm(backPlate2Tra.z())
2108                                     << ") with no rotation";
2109 #endif
2110         spmLog.placeVolume(
2111             backPlateLog,
2112             copyOne,
2113             Transform3D(myrot(ns, back.plateName + "Rot5", CLHEP::HepRotationZ(270_deg)), outtra + backPlateTra));
2114 #ifdef EDM_ML_DEBUG
2115         edm::LogVerbatim("EBGeomX") << backPlateLog.name() << ":" << copyOne << " positioned in " << spmLog.name()
2116                                     << " at (" << cms::convert2mm((outtra + backPlateTra).x()) << ","
2117                                     << cms::convert2mm((outtra + backPlateTra).y()) << ","
2118                                     << cms::convert2mm((outtra + backPlateTra).z()) << ") with rotation";
2119 #endif
2120       }
2121       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2122       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2123       //!!!!!!!!!!!!!!     End Back Cover Plate       !!!!!!!!!!!!!!!!!!!!!!!
2124       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2125       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2126 
2127       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2128       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2129       //!!!!!!!!!!!!!!     Begin Back Side Plates    !!!!!!!!!!!!!!!!!!!!!!!
2130       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2131       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2132 
2133       const EcalTrap trapBS(back.sideWidth / 2.,   //double aHalfLengthXNegZLoY , // bl1, A/2
2134                             back.sideWidth / 2.,   //double aHalfLengthXPosZLoY , // bl2, a/2
2135                             back.sideWidth / 4.,   //double aHalfLengthXPosZHiY , // tl2, b/2
2136                             back.sideHeight / 2.,  //double aHalfLengthYNegZ    , // h1, H/2
2137                             back.sideHeight / 2.,  //double aHalfLengthYPosZ    , // h2, h/2
2138                             back.sideLength / 2.,  //double aHalfLengthZ        , // dz,  L/2
2139                             back.sideAngle,        //double aAngleAD            , // alfa1
2140                             0,                     //double aCoord15X           , // x15
2141                             0                      //double aCoord15Y             // y15
2142       );
2143 
2144       Solid backSideSolid = mytrap(back.sideName, trapBS);
2145       Volume backSideLog = Volume(back.sideName, backSideSolid, ns.material(back.sideMat));
2146 
2147       const Position backSideTra1(0, back.plateWidth / 2 + back.sideYOff1, 1 * dd4hep::mm);
2148       if (0 != back.sideHere) {
2149         spmLog.placeVolume(
2150             backSideLog,
2151             copyOne,
2152             Transform3D(myrot(ns, back.sideName + "Rot8", CLHEP::HepRotationX(180_deg) * CLHEP::HepRotationZ(90_deg)),
2153                         outtra + backSideTra1));
2154 #ifdef EDM_ML_DEBUG
2155         edm::LogVerbatim("EBGeomX") << backSideLog.name() << ":" << copyOne << " positioned in " << spmLog.name()
2156                                     << " at (" << cms::convert2mm((outtra + backSideTra1).x()) << ","
2157                                     << cms::convert2mm((outtra + backSideTra1).y()) << ","
2158                                     << cms::convert2mm((outtra + backSideTra1).z()) << ") with rotation";
2159 #endif
2160         const Position backSideTra2(0, -back.plateWidth / 2 + back.sideYOff2, 1 * dd4hep::mm);
2161         spmLog.placeVolume(
2162             backSideLog,
2163             copyTwo,
2164             Transform3D(myrot(ns, back.sideName + "Rot9", CLHEP::HepRotationZ(90_deg)), outtra + backSideTra2));
2165 #ifdef EDM_ML_DEBUG
2166         edm::LogVerbatim("EBGeomX") << backSideLog.name() << ":" << copyTwo << " positioned in " << spmLog.name()
2167                                     << " at (" << cms::convert2mm((outtra + backSideTra2).x()) << ","
2168                                     << cms::convert2mm((outtra + backSideTra2).y()) << ","
2169                                     << cms::convert2mm((outtra + backSideTra2).z()) << ") with rotation";
2170 #endif
2171       }
2172       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2173       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2174       //!!!!!!!!!!!!!!     End Back Side Plates       !!!!!!!!!!!!!!!!!!!!!!!
2175       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2176       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2177 
2178       //=====================
2179       const double backCoolWidth(backCool.barWidth + 2. * backCoolTank.width);
2180 
2181       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2182       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2183       //!!!!!!!!!!!!!!     Begin Mother Board Cooling Manifold Setup !!!!!!!!
2184       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2185       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2186 
2187       const double manifCut(2 * dd4hep::mm);
2188 
2189       Solid mBManifSolid = Tube(0, mbManif.outDiam / 2, backCoolWidth / 2. - manifCut, 0_deg, 360_deg);
2190 #ifdef EDM_ML_DEBUG
2191       edm::LogVerbatim("EBGeom") << mbManif.name << " Tubs " << cms::convert2mm(backCoolWidth / 2. - manifCut)
2192                                  << ":0:" << cms::convert2mm(mbManif.outDiam / 2) << ":0:360";
2193 #endif
2194       Volume mBManifLog = Volume(mbManif.name, mBManifSolid, ns.material(mbManif.mat));
2195 
2196       const string mBManifWaName(mbManif.name + "Wa");
2197       Solid mBManifWaSolid = Tube(0, mbManif.innDiam / 2, backCoolWidth / 2. - manifCut, 0_deg, 360_deg);
2198 #ifdef EDM_ML_DEBUG
2199       edm::LogVerbatim("EBGeom") << mBManifWaName << " Tubs " << cms::convert2mm(backCoolWidth / 2. - manifCut)
2200                                  << ":0:" << cms::convert2mm(mbManif.innDiam / 2) << ":0:360";
2201 #endif
2202       Volume mBManifWaLog(mBManifWaName, mBManifWaSolid, ns.material(backPipe.waterMat));
2203       mBManifLog.placeVolume(mBManifWaLog, copyOne);
2204 #ifdef EDM_ML_DEBUG
2205       edm::LogVerbatim("EBGeomX") << mBManifWaLog.name() << ":" << copyOne << " positioned in " << mBManifLog.name()
2206                                   << " at (0,0,0) with no rotation";
2207 #endif
2208 
2209       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2210       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2211       //!!!!!!!!!!!!!!     End Mother Board Cooling Manifold Setup   !!!!!!!!
2212       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2213       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2214       //=====================
2215 
2216       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2217       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2218       //!!!!!!!!!!!!!!     Begin Loop over Grilles & MB Cooling Manifold !!!!
2219       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2220       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2221       const double deltaY(-5 * dd4hep::mm);
2222 
2223       Solid grEdgeSlotSolid =
2224           Box(grille.edgeSlotName, grille.edgeSlotHeight / 2., grille.edgeSlotWidth / 2., grille.thick / 2.);
2225 #ifdef EDM_ML_DEBUG
2226       edm::LogVerbatim("EBGeom") << grille.edgeSlotName << " Box " << cms::convert2mm(grille.edgeSlotHeight / 2.) << ":"
2227                                  << cms::convert2mm(grille.edgeSlotWidth / 2.) << ":"
2228                                  << cms::convert2mm(grille.thick / 2.);
2229 #endif
2230       Volume grEdgeSlotLog = Volume(grille.edgeSlotName, grEdgeSlotSolid, ns.material(grille.edgeSlotMat));
2231 
2232       unsigned int edgeSlotCopy(0);
2233       unsigned int midSlotCopy(0);
2234 
2235       Volume grMidSlotLog[4];
2236 
2237       for (unsigned int iGr(0); iGr != grille.vecHeight.size(); ++iGr) {
2238         string gName(grille.name + std::to_string(iGr));
2239         Solid grilleSolid = Box(gName, grille.vecHeight[iGr] / 2., backCoolWidth / 2., grille.thick / 2.);
2240 #ifdef EDM_ML_DEBUG
2241         edm::LogVerbatim("EBGeom") << gName << " Box " << cms::convert2mm(grille.vecHeight[iGr] / 2.) << ":"
2242                                    << cms::convert2mm(backCoolWidth / 2.) << ":" << cms::convert2mm(grille.thick / 2.);
2243 #endif
2244         Volume grilleLog = Volume(gName, grilleSolid, ns.material(grille.mat));
2245 
2246         const Position grilleTra(-realBPthick / 2 - grille.vecHeight[iGr] / 2,
2247                                  deltaY,
2248                                  grille.vecZOff[iGr] + grille.thick / 2 - back.sideLength / 2);
2249         const Position gTra(outtra + backPlateTra + grilleTra);
2250 
2251         if (0 != grille.midSlotHere && 0 != iGr) {
2252           if (0 == (iGr - 1) % 2) {
2253             string mName(grille.midSlotName + std::to_string(iGr / 2));
2254             Solid grMidSlotSolid =
2255                 Box(mName, grille.vecMidSlotHeight[(iGr - 1) / 2] / 2., grille.midSlotWidth / 2., grille.thick / 2.);
2256 #ifdef EDM_ML_DEBUG
2257             edm::LogVerbatim("EBGeom") << mName << " Box "
2258                                        << cms::convert2mm(grille.vecMidSlotHeight[(iGr - 1) / 2] / 2.) << ":"
2259                                        << cms::convert2mm(grille.midSlotWidth / 2.) << ":"
2260                                        << cms::convert2mm(grille.thick / 2.);
2261 #endif
2262             grMidSlotLog[(iGr - 1) / 2] = Volume(mName, grMidSlotSolid, ns.material(grille.midSlotMat));
2263           }
2264           grilleLog.placeVolume(
2265               grMidSlotLog[(iGr - 1) / 2],
2266               ++midSlotCopy,
2267               Transform3D(Position(
2268                   grille.vecHeight[iGr] / 2. - grille.vecMidSlotHeight[(iGr - 1) / 2] / 2., +grille.midSlotXOff, 0)));
2269 #ifdef EDM_ML_DEBUG
2270           edm::LogVerbatim("EBGeomX") << grMidSlotLog[(iGr - 1) / 2].name() << ":" << midSlotCopy << " positioned in "
2271                                       << grilleLog.name() << " at ("
2272                                       << cms::convert2mm(grille.vecHeight[iGr] / 2. -
2273                                                          grille.vecMidSlotHeight[(iGr - 1) / 2] / 2.)
2274                                       << "," << cms::convert2mm(grille.midSlotXOff) << ",0) with no rotation";
2275 #endif
2276           grilleLog.placeVolume(
2277               grMidSlotLog[(iGr - 1) / 2],
2278               ++midSlotCopy,
2279               Transform3D(Position(
2280                   grille.vecHeight[iGr] / 2. - grille.vecMidSlotHeight[(iGr - 1) / 2] / 2., -grille.midSlotXOff, 0)));
2281 #ifdef EDM_ML_DEBUG
2282           edm::LogVerbatim("EBGeomX") << grMidSlotLog[(iGr - 1) / 2].name() << ":" << midSlotCopy << " positioned in "
2283                                       << grilleLog.name() << " at ("
2284                                       << cms::convert2mm(grille.vecHeight[iGr] / 2. -
2285                                                          grille.vecMidSlotHeight[(iGr - 1) / 2] / 2.)
2286                                       << "," << cms::convert2mm(-grille.midSlotXOff) << ",0) with no rotation";
2287 #endif
2288         }
2289 
2290         if (0 != grille.edgeSlotHere && 0 != iGr) {
2291           grilleLog.placeVolume(grEdgeSlotLog,
2292                                 ++edgeSlotCopy,
2293                                 Transform3D(Position(grille.vecHeight[iGr] / 2. - grille.edgeSlotHeight / 2.,
2294                                                      backCoolWidth / 2 - grille.edgeSlotWidth / 2.,
2295                                                      0)));
2296 #ifdef EDM_ML_DEBUG
2297           edm::LogVerbatim("EBGeomX") << grEdgeSlotLog.name() << ":" << edgeSlotCopy << " positioned in "
2298                                       << grilleLog.name() << " at ("
2299                                       << cms::convert2mm(grille.vecHeight[iGr] / 2. - grille.edgeSlotHeight / 2.) << ","
2300                                       << cms::convert2mm(backCoolWidth / 2 - grille.edgeSlotWidth / 2.)
2301                                       << ",0) with no rotation";
2302 #endif
2303           grilleLog.placeVolume(grEdgeSlotLog,
2304                                 ++edgeSlotCopy,
2305                                 Transform3D(Position(grille.vecHeight[iGr] / 2. - grille.edgeSlotHeight / 2.,
2306                                                      -backCoolWidth / 2 + grille.edgeSlotWidth / 2.,
2307                                                      0)));
2308 #ifdef EDM_ML_DEBUG
2309           edm::LogVerbatim("EBGeomX") << grEdgeSlotLog.name() << ":" << edgeSlotCopy << " positioned in "
2310                                       << grilleLog.name() << " at ("
2311                                       << cms::convert2mm(grille.vecHeight[iGr] / 2. - grille.edgeSlotHeight / 2.) << ","
2312                                       << cms::convert2mm(-backCoolWidth / 2 + grille.edgeSlotWidth / 2.)
2313                                       << ",0) with no rotation";
2314 #endif
2315         }
2316         if (0 != grille.here) {
2317           spmLog.placeVolume(grilleLog, iGr, Transform3D(gTra));
2318 #ifdef EDM_ML_DEBUG
2319           edm::LogVerbatim("EBGeomX") << grilleLog.name() << ":" << iGr << " positioned in " << spmLog.name() << " at ("
2320                                       << cms::convert2mm(gTra.x()) << "," << cms::convert2mm(gTra.y()) << ","
2321                                       << cms::convert2mm(gTra.z()) << ") with no rotation";
2322 #endif
2323         }
2324 
2325         if ((0 != iGr % 2) && (0 != mbManif.here)) {
2326           spmLog.placeVolume(mBManifLog,
2327                              iGr,
2328                              Transform3D(myrot(ns, mbManif.name + "R1", CLHEP::HepRotationX(90_deg)),
2329                                          gTra - Position(-mbManif.outDiam / 2. + grille.vecHeight[iGr] / 2.,
2330                                                          manifCut,
2331                                                          grille.thick / 2. + 3 * mbManif.outDiam / 2.)));
2332 #ifdef EDM_ML_DEBUG
2333           edm::LogVerbatim("EBGeomX") << mBManifLog.name() << ":" << iGr << " positioned in " << spmLog.name()
2334                                       << " at ("
2335                                       << cms::convert2mm(gTra.x() + mbManif.outDiam / 2. - grille.vecHeight[iGr] / 2.)
2336                                       << "," << cms::convert2mm(gTra.y() - manifCut) << ","
2337                                       << cms::convert2mm(gTra.z() - grille.thick / 2. - 3 * mbManif.outDiam / 2.)
2338                                       << ") with rotation";
2339 #endif
2340           spmLog.placeVolume(mBManifLog,
2341                              iGr - 1,
2342                              Transform3D(myrot(ns, mbManif.name + "R2", CLHEP::HepRotationX(90_deg)),
2343                                          gTra - Position(-3 * mbManif.outDiam / 2. + grille.vecHeight[iGr] / 2.,
2344                                                          manifCut,
2345                                                          grille.thick / 2 + 3 * mbManif.outDiam / 2.)));
2346 #ifdef EDM_ML_DEBUG
2347           edm::LogVerbatim("EBGeomX") << mBManifLog.name() << ":" << (iGr - 1) << " positioned in " << spmLog.name()
2348                                       << " at ("
2349                                       << cms::convert2mm(gTra.x() + 3 * mbManif.outDiam / 2. -
2350                                                          grille.vecHeight[iGr] / 2.)
2351                                       << "," << cms::convert2mm(gTra.y() - manifCut) << ","
2352                                       << cms::convert2mm(gTra.z() - grille.thick / 2 - 3 * mbManif.outDiam / 2.)
2353                                       << ") with rotation";
2354 #endif
2355         }
2356       }
2357 
2358       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2359       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2360       //!!!!!!!!!!!!!!     End Loop over Grilles & MB Cooling Manifold   !!!!
2361       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2362       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2363 
2364       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2365       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2366       //!!!!!!!!!!!!!!     Begin Cooling Bar Setup    !!!!!!!!!!!!!!!!!!!!!!!
2367       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2368       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2369 
2370       Solid backCoolBarSolid =
2371           Box(backCool.barName, backCool.barHeight / 2., backCool.barWidth / 2., backCool.barThick / 2.);
2372 #ifdef EDM_ML_DEBUG
2373       edm::LogVerbatim("EBGeom") << backCool.barName << " Box " << cms::convert2mm(backCool.barHeight / 2.) << ":"
2374                                  << cms::convert2mm(backCool.barWidth / 2.) << ":"
2375                                  << cms::convert2mm(backCool.barThick / 2.);
2376 #endif
2377       Volume backCoolBarLog = Volume(backCool.barName, backCoolBarSolid, ns.material(backCool.barMat));
2378 
2379       Solid backCoolBarSSSolid =
2380           Box(backCool.barSSName, backCool.barHeight / 2., backCool.barWidth / 2., backCool.barSSThick / 2.);
2381 #ifdef EDM_ML_DEBUG
2382       edm::LogVerbatim("EBGeom") << backCool.barSSName << " Box " << cms::convert2mm(backCool.barHeight / 2.) << ":"
2383                                  << cms::convert2mm(backCool.barWidth / 2.) << ":"
2384                                  << cms::convert2mm(backCool.barSSThick / 2.);
2385 #endif
2386       Volume backCoolBarSSLog = Volume(backCool.barSSName, backCoolBarSSSolid, ns.material(backCool.barSSMat));
2387       const Position backCoolBarSSTra(0, 0, 0);
2388       backCoolBarLog.placeVolume(backCoolBarSSLog, copyOne, Transform3D(backCoolBarSSTra));
2389 #ifdef EDM_ML_DEBUG
2390       edm::LogVerbatim("EBGeomX") << backCoolBarSSLog.name() << ":" << copyOne << " positioned in "
2391                                   << backCoolBarLog.name() << " at (" << cms::convert2mm(backCoolBarSSTra.x()) << ","
2392                                   << cms::convert2mm(backCoolBarSSTra.y()) << ","
2393                                   << cms::convert2mm(backCoolBarSSTra.z()) << ") with no rotation";
2394 #endif
2395 
2396       Solid backCoolBarWaSolid =
2397           Box(backCool.barWaName, backCool.barHeight / 2., backCool.barWidth / 2., backCool.barWaThick / 2.);
2398 #ifdef EDM_ML_DEBUG
2399       edm::LogVerbatim("EBGeom") << backCool.barWaName << " Box " << cms::convert2mm(backCool.barHeight / 2.) << ":"
2400                                  << cms::convert2mm(backCool.barWidth / 2.) << ":"
2401                                  << cms::convert2mm(backCool.barWaThick / 2.);
2402 #endif
2403       Volume backCoolBarWaLog = Volume(backCool.barWaName, backCoolBarWaSolid, ns.material(backCool.barWaMat));
2404       const Position backCoolBarWaTra(0, 0, 0);
2405       backCoolBarSSLog.placeVolume(backCoolBarWaLog, copyOne, Transform3D(backCoolBarWaTra));
2406 #ifdef EDM_ML_DEBUG
2407       edm::LogVerbatim("EBGeomX") << backCoolBarWaLog.name() << ":" << copyOne << " positioned in "
2408                                   << backCoolBarSSLog.name() << " at (" << cms::convert2mm(backCoolBarWaTra.x()) << ","
2409                                   << cms::convert2mm(backCoolBarWaTra.y()) << ","
2410                                   << cms::convert2mm(backCoolBarWaTra.z()) << ") with no rotation";
2411 #endif
2412 
2413       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2414       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2415       //!!!!!!!!!!!!!!     End Cooling Bar Setup      !!!!!!!!!!!!!!!!!!!!!!!
2416       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2417       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2418 
2419       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2420       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2421       //!!!!!!!!!!!!!!     Begin VFE Card Setup       !!!!!!!!!!!!!!!!!!!!!!!
2422       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2423       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2424 
2425       double thickVFE(0);
2426       for (unsigned int iLyr(0); iLyr != backCool.vecBackVFELyrThick.size(); ++iLyr) {
2427         thickVFE += backCool.vecBackVFELyrThick[iLyr];
2428       }
2429       Solid backVFESolid =
2430           Box((myns + backCool.backVFEName), backCool.barHeight / 2., backCool.barWidth / 2., thickVFE / 2.);
2431 #ifdef EDM_ML_DEBUG
2432       edm::LogVerbatim("EBGeom") << (myns + backCool.backVFEName) << " Box " << cms::convert2mm(backCool.barHeight / 2.)
2433                                  << ":" << cms::convert2mm(backCool.barWidth / 2.) << ":"
2434                                  << cms::convert2mm(thickVFE / 2.);
2435 #endif
2436       Volume backVFELog =
2437           ns.addVolume(Volume(myns + backCool.backVFEName, backVFESolid, ns.material(backCool.backVFEMat)));
2438       Position offTra(0, 0, -thickVFE / 2);
2439       for (unsigned int iLyr(0); iLyr != backCool.vecBackVFELyrThick.size(); ++iLyr) {
2440         Solid backVFELyrSolid = Box(backCool.vecBackVFELyrName[iLyr],
2441                                     backCool.barHeight / 2.,
2442                                     backCool.barWidth / 2.,
2443                                     backCool.vecBackVFELyrThick[iLyr] / 2.);
2444 #ifdef EDM_ML_DEBUG
2445         edm::LogVerbatim("EBGeom") << backCool.vecBackVFELyrName[iLyr] << " Box "
2446                                    << cms::convert2mm(backCool.barHeight / 2.) << ":"
2447                                    << cms::convert2mm(backCool.barWidth / 2.) << ":"
2448                                    << cms::convert2mm(backCool.vecBackVFELyrThick[iLyr] / 2.);
2449 #endif
2450         Volume backVFELyrLog =
2451             Volume(backCool.vecBackVFELyrName[iLyr], backVFELyrSolid, ns.material(backCool.vecBackVFELyrMat[iLyr]));
2452         const Position backVFELyrTra(0, 0, backCool.vecBackVFELyrThick[iLyr] / 2);
2453         backVFELog.placeVolume(backVFELyrLog, copyOne, Transform3D(backVFELyrTra + offTra));
2454 #ifdef EDM_ML_DEBUG
2455         edm::LogVerbatim("EBGeomX") << backVFELyrLog.name() << ":" << copyOne << " positioned in " << backVFELog.name()
2456                                     << " at (" << cms::convert2mm((backVFELyrTra + offTra).x()) << ","
2457                                     << cms::convert2mm((backVFELyrTra + offTra).y()) << ","
2458                                     << cms::convert2mm((backVFELyrTra + offTra).z()) << ") with no rotation";
2459 #endif
2460         offTra += 2 * backVFELyrTra;
2461       }
2462 
2463       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2464       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2465       //!!!!!!!!!!!!!!     End VFE Card Setup         !!!!!!!!!!!!!!!!!!!!!!!
2466       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2467       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2468 
2469       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2470       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2471       //!!!!!!!!!!!!!!     Begin Cooling Bar + VFE Setup  !!!!!!!!!!!!!!!!!!!
2472       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2473       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2474 
2475       const double halfZCoolVFE(thickVFE + backCool.barThick / 2.);
2476       Solid backCoolVFESolid = Box(backCool.barHeight / 2., backCool.barWidth / 2., halfZCoolVFE);
2477 #ifdef EDM_ML_DEBUG
2478       edm::LogVerbatim("EBGeom") << backCool.vFEName << " Box " << cms::convert2mm(backCool.barHeight / 2.) << ":"
2479                                  << cms::convert2mm(backCool.barWidth / 2.) << ":" << cms::convert2mm(halfZCoolVFE);
2480 #endif
2481       Volume backCoolVFELog = ns.addVolume(Volume(backCool.vFEName, backCoolVFESolid, ns.material(backCool.vFEMat)));
2482       if (0 != backCool.barHere) {
2483         backCoolVFELog.placeVolume(backCoolBarLog, copyOne, Transform3D());
2484 #ifdef EDM_ML_DEBUG
2485         edm::LogVerbatim("EBGeomX") << backCoolBarLog.name() << ":" << copyOne << " positioned in "
2486                                     << backCoolVFELog.name() << " at (0,0,0) with no rotation";
2487 #endif
2488       }
2489       if (0 != backCool.vFEHere) {
2490         backCoolVFELog.placeVolume(
2491             backVFELog, copyOne, Transform3D(Position(0, 0, backCool.barThick / 2. + thickVFE / 2.)));
2492 #ifdef EDM_ML_DEBUG
2493         edm::LogVerbatim("EBGeomX") << backVFELog.name() << ":" << copyOne << " positioned in " << backCoolVFELog.name()
2494                                     << " at (0,0," << cms::convert2mm(backCool.barThick / 2. + thickVFE / 2.)
2495                                     << ") with no rotation";
2496 #endif
2497       }
2498       backCoolVFELog.placeVolume(backVFELog,
2499                                  copyTwo,
2500                                  Transform3D(myrot(ns, backCool.vFEName + "Flip", CLHEP::HepRotationX(180_deg)),
2501                                              Position(0, 0, -backCool.barThick / 2. - thickVFE / 2.)));
2502 #ifdef EDM_ML_DEBUG
2503       edm::LogVerbatim("EBGeomX") << backVFELog.name() << ":" << copyTwo << " positioned in " << backCoolVFELog.name()
2504                                   << " at (0,0," << cms::convert2mm(-backCool.barThick / 2. - thickVFE / 2.)
2505                                   << ") with rotation";
2506 #endif
2507 
2508       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2509       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2510       //!!!!!!!!!!!!!!     End Cooling Bar + VFE Setup    !!!!!!!!!!!!!!!!!!!
2511       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2512       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2513 
2514       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2515       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2516       //!!!!!!!!!!!!!! Begin Placement of Readout & Cooling by Module  !!!!!!
2517       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2518       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2519       unsigned int iCVFECopy(1);
2520       unsigned int iSep(0);
2521       unsigned int iNSec(0);
2522       const unsigned int nMisc(backMisc.vecThick.size() / 4);
2523       for (unsigned int iMod(0); iMod != 4; ++iMod) {
2524         const double pipeLength(grille.vecZOff[2 * iMod + 1] - grille.vecZOff[2 * iMod] - grille.thick -
2525                                 3 * dd4hep::mm);
2526         const double pipeZPos(grille.vecZOff[2 * iMod + 1] - pipeLength / 2 - 1.5 * dd4hep::mm);
2527 
2528         // accumulate total height of parent volume
2529         double backCoolHeight(backCool.barHeight + mbCoolTube.outDiam);
2530         for (unsigned int iMisc(0); iMisc != nMisc; ++iMisc) {
2531           backCoolHeight += backMisc.vecThick[iMod * nMisc + iMisc];
2532         }
2533         double bottomThick(mbCoolTube.outDiam);
2534         for (unsigned int iMB(0); iMB != mbLyr.vecMBLyrThick.size(); ++iMB) {
2535           backCoolHeight += mbLyr.vecMBLyrThick[iMB];
2536           bottomThick += mbLyr.vecMBLyrThick[iMB];
2537         }
2538 
2539         const double halfZBCool((pipeLength - 2 * mbManif.outDiam - grille.zSpace) / 2);
2540         Solid backCoolSolid = Box(backCool.vecName[iMod], backCoolHeight / 2., backCoolWidth / 2., halfZBCool);
2541 #ifdef EDM_ML_DEBUG
2542         edm::LogVerbatim("EBGeom") << backCool.vecName[iMod] << " Box " << cms::convert2mm(backCoolHeight / 2.) << ":"
2543                                    << cms::convert2mm(backCoolWidth / 2.) << ":" << cms::convert2mm(halfZBCool);
2544 #endif
2545         Volume backCoolLog = Volume(backCool.vecName[iMod], backCoolSolid, ns.material(spm.mat));
2546 
2547         const Position bCoolTra(
2548             -realBPthick / 2 + backCoolHeight / 2 - grille.vecHeight[2 * iMod],
2549             deltaY,
2550             grille.vecZOff[2 * iMod] + grille.thick + grille.zSpace + halfZBCool - back.sideLength / 2);
2551         if (0 != backCool.here) {
2552           spmLog.placeVolume(backCoolLog, iMod + 1, outtra + backPlateTra + bCoolTra);
2553 #ifdef EDM_ML_DEBUG
2554           edm::LogVerbatim("EBGeomX") << backCoolLog.name() << ":" << (iMod + 1) << " positioned in " << spmLog.name()
2555                                       << " at (" << cms::convert2mm((outtra + backPlateTra + bCoolTra).x()) << ","
2556                                       << cms::convert2mm((outtra + backPlateTra + bCoolTra).y()) << ","
2557                                       << cms::convert2mm((outtra + backPlateTra + bCoolTra).z())
2558                                       << ") with no rotation";
2559 #endif
2560         }
2561 
2562         //===
2563         const double backCoolTankHeight(backCool.barHeight);  // - backBracketHeight() ) ;
2564         const double halfZTank(halfZBCool - 5 * dd4hep::cm);
2565 
2566         string bTankName(backCoolTank.name + std::to_string(iMod + 1));
2567         Solid backCoolTankSolid = Box(bTankName, backCoolTankHeight / 2., backCoolTank.width / 2., halfZTank);
2568 #ifdef EDM_ML_DEBUG
2569         edm::LogVerbatim("EBGeom") << bTankName << " Box " << cms::convert2mm(backCoolTankHeight / 2.) << ":"
2570                                    << cms::convert2mm(backCoolTank.width / 2.) << ":" << cms::convert2mm(halfZTank);
2571 #endif
2572         Volume backCoolTankLog = Volume(bTankName, backCoolTankSolid, ns.material(backCoolTank.mat));
2573         if (0 != backCoolTank.here) {
2574           backCoolLog.placeVolume(backCoolTankLog,
2575                                   copyOne,
2576                                   Transform3D(Rotation3D(),
2577                                               Position(-backCoolHeight / 2 + backCoolTankHeight / 2. + bottomThick,
2578                                                        backCool.barWidth / 2. + backCoolTank.width / 2.,
2579                                                        0)));
2580 #ifdef EDM_ML_DEBUG
2581           edm::LogVerbatim("EBGeomX") << backCoolTankLog.name() << ":" << copyOne << " positioned in "
2582                                       << backCoolLog.name() << " at ("
2583                                       << cms::convert2mm(-backCoolHeight / 2 + backCoolTankHeight / 2. + bottomThick)
2584                                       << "," << cms::convert2mm(backCool.barWidth / 2. + backCoolTank.width / 2.)
2585                                       << ",0) with no rotation";
2586 #endif
2587         }
2588 
2589         string bTankWaName(backCoolTank.waName + std::to_string(iMod + 1));
2590         Solid backCoolTankWaSolid = Box(bTankWaName,
2591                                         backCoolTankHeight / 2. - backCoolTank.thick / 2.,
2592                                         backCoolTank.waWidth / 2.,
2593                                         halfZTank - backCoolTank.thick / 2.);
2594 #ifdef EDM_ML_DEBUG
2595         edm::LogVerbatim("EBGeom") << bTankWaName << " Box "
2596                                    << cms::convert2mm(backCoolTankHeight / 2. - backCoolTank.thick / 2.) << ":"
2597                                    << cms::convert2mm(backCoolTank.waWidth / 2.) << ":"
2598                                    << cms::convert2mm(halfZTank - backCoolTank.thick / 2.);
2599 #endif
2600         Volume backCoolTankWaLog = Volume(bTankWaName, backCoolTankWaSolid, ns.material(backCoolTank.waMat));
2601         backCoolTankLog.placeVolume(backCoolTankWaLog, copyOne, Transform3D(Rotation3D(), Position(0, 0, 0)));
2602 #ifdef EDM_ML_DEBUG
2603         edm::LogVerbatim("EBGeomX") << backCoolTankWaLog.name() << ":" << copyOne << " positioned in "
2604                                     << backCoolTankLog.name() << " at (0,0,0) with no rotation";
2605 #endif
2606 
2607         string bBracketName(backCoolTank.backBracketName + std::to_string(iMod + 1));
2608         Solid backBracketSolid =
2609             Box(bBracketName, backCoolTank.backBracketHeight / 2., backCoolTank.width / 2., halfZTank);
2610 #ifdef EDM_ML_DEBUG
2611         edm::LogVerbatim("EBGeom") << bBracketName << " Box " << cms::convert2mm(backCoolTank.backBracketHeight / 2.)
2612                                    << ":" << cms::convert2mm(backCoolTank.width / 2.) << ":"
2613                                    << cms::convert2mm(halfZTank);
2614 #endif
2615         Volume backBracketLog = Volume(bBracketName, backBracketSolid, ns.material(backCoolTank.backBracketMat));
2616         if (0 != backCoolTank.here) {
2617           backCoolLog.placeVolume(backBracketLog,
2618                                   copyOne,
2619                                   Transform3D(Rotation3D(),
2620                                               Position(backCool.barHeight - backCoolHeight / 2. -
2621                                                            backCoolTank.backBracketHeight / 2. + bottomThick,
2622                                                        -backCool.barWidth / 2. - backCoolTank.width / 2.,
2623                                                        0)));
2624 #ifdef EDM_ML_DEBUG
2625           edm::LogVerbatim("EBGeomX") << backBracketLog.name() << ":" << copyOne << " positioned in "
2626                                       << backCoolLog.name() << " at ("
2627                                       << cms::convert2mm(backCool.barHeight - backCoolHeight / 2. -
2628                                                          backCoolTank.backBracketHeight / 2. + bottomThick)
2629                                       << "," << cms::convert2mm(-backCool.barWidth / 2. - backCoolTank.width / 2.)
2630                                       << ",0) with no rotation";
2631 #endif
2632         }
2633         //===
2634 
2635         Position bSumTra(backCool.barHeight - backCoolHeight / 2. + bottomThick, 0, 0);
2636         for (unsigned int j(0); j != nMisc; ++j) {  // loop over miscellaneous layers
2637           Solid bSolid = Box(backMisc.vecName[iMod * nMisc + j],
2638                              backMisc.vecThick[iMod * nMisc + j] / 2,
2639                              backCool.barWidth / 2. + backCoolTank.width,
2640                              halfZBCool);
2641 #ifdef EDM_ML_DEBUG
2642           edm::LogVerbatim("EBGeom") << backMisc.vecName[iMod * nMisc + j] << " Box "
2643                                      << cms::convert2mm(backMisc.vecThick[iMod * nMisc + j] / 2) << ":"
2644                                      << cms::convert2mm(backCool.barWidth / 2. + backCoolTank.width) << ":"
2645                                      << cms::convert2mm(halfZBCool);
2646 #endif
2647 
2648           Volume bLog =
2649               Volume(backMisc.vecName[iMod * nMisc + j], bSolid, ns.material(backMisc.vecMat[iMod * nMisc + j]));
2650 
2651           const Position bTra(backMisc.vecThick[iMod * nMisc + j] / 2, 0, 0);
2652 
2653           if (0 != backMisc.here) {
2654             backCoolLog.placeVolume(bLog, copyOne, Transform3D(Rotation3D(), bSumTra + bTra));
2655 #ifdef EDM_ML_DEBUG
2656             edm::LogVerbatim("EBGeomX") << bLog.name() << ":" << copyOne << " positioned in " << backCoolLog.name()
2657                                         << " at (" << cms::convert2mm((bSumTra + bTra).x()) << ","
2658                                         << cms::convert2mm((bSumTra + bTra).y()) << ","
2659                                         << cms::convert2mm((bSumTra + bTra).z()) << ") with no rotation";
2660 #endif
2661           }
2662 
2663           bSumTra += 2 * bTra;
2664         }
2665 
2666         const double bHalfWidth(backCool.barWidth / 2. + backCoolTank.width);
2667 
2668         if (0 != mbLyr.here) {
2669           Position mTra(-backCoolHeight / 2. + mbCoolTube.outDiam, 0, 0);
2670           for (unsigned int j(0); j != mbLyr.vecMBLyrThick.size(); ++j)  // loop over MB layers
2671           {
2672             Solid mSolid = Box(mbLyr.vecMBLyrThick[j] / 2, bHalfWidth, halfZBCool);
2673 #ifdef EDM_ML_DEBUG
2674             edm::LogVerbatim("EBGeom") << (mbLyr.vecMBLyrName[j] + "_" + std::to_string(iMod + 1)) << " Box "
2675                                        << cms::convert2mm(mbLyr.vecMBLyrThick[j] / 2) << ":"
2676                                        << cms::convert2mm(bHalfWidth) << ":" << cms::convert2mm(halfZBCool);
2677 #endif
2678             Volume mLog = Volume(
2679                 mbLyr.vecMBLyrName[j] + "_" + std::to_string(iMod + 1), mSolid, ns.material(mbLyr.vecMBLyrMat[j]));
2680 
2681             mTra += Position(mbLyr.vecMBLyrThick[j] / 2.0, 0, 0);
2682             backCoolLog.placeVolume(mLog, copyOne, Transform3D(Rotation3D(), mTra));
2683 #ifdef EDM_ML_DEBUG
2684             edm::LogVerbatim("EBGeomX") << mLog.name() << ":" << copyOne << " positioned in " << backCoolLog.name()
2685                                         << " at (" << cms::convert2mm(mTra.x()) << "," << cms::convert2mm(mTra.y())
2686                                         << "," << cms::convert2mm(mTra.z()) << ") with no rotation";
2687 #endif
2688             mTra += Position(mbLyr.vecMBLyrThick[j] / 2.0, 0, 0);
2689           }
2690         }
2691 
2692         if (0 != mbCoolTube.here) {
2693           const string mBName(mbCoolTube.name + "_" + std::to_string(iMod + 1));
2694 
2695           Solid mBCoolTubeSolid = Tube(0, mbCoolTube.outDiam / 2, halfZBCool, 0_deg, 360_deg);
2696 #ifdef EDM_ML_DEBUG
2697           edm::LogVerbatim("EBGeom") << mBName << " Tubs " << cms::convert2mm(halfZBCool)
2698                                      << ":0:" << cms::convert2mm(mbCoolTube.outDiam / 2) << ":0:360";
2699 #endif
2700           Volume mBLog = Volume(mBName, mBCoolTubeSolid, ns.material(mbCoolTube.mat));
2701 
2702           const string mBWaName(mbCoolTube.name + "Wa_" + std::to_string(iMod + 1));
2703           Solid mBCoolTubeWaSolid = Tube(mBWaName, 0, mbCoolTube.innDiam / 2, halfZBCool, 0_deg, 360_deg);
2704 #ifdef EDM_ML_DEBUG
2705           edm::LogVerbatim("EBGeom") << mBWaName << " Tubs " << cms::convert2mm(halfZBCool)
2706                                      << ":0:" << cms::convert2mm(mbCoolTube.innDiam / 2) << ":0:360";
2707 #endif
2708           Volume mBWaLog = Volume(mBWaName, mBCoolTubeWaSolid, ns.material(backPipe.waterMat));
2709           mBLog.placeVolume(mBWaLog, copyOne);
2710 #ifdef EDM_ML_DEBUG
2711           edm::LogVerbatim("EBGeomX") << mBWaLog.name() << ":" << copyOne << " positioned in " << mBLog.name()
2712                                       << " at (0,0,0) with no rotation";
2713 #endif
2714 
2715           for (unsigned int j(0); j != dryAirTube.mbCoolTubeNum; ++j)  // loop over all MB cooling circuits
2716           {
2717             backCoolLog.placeVolume(mBLog,
2718                                     2 * j + 1,
2719                                     Transform3D(Rotation3D(),
2720                                                 Position(-backCoolHeight / 2.0 + mbCoolTube.outDiam / 2.,
2721                                                          -bHalfWidth + (j + 1) * bHalfWidth / 5,
2722                                                          0)));
2723 #ifdef EDM_ML_DEBUG
2724             edm::LogVerbatim("EBGeomX") << mBLog.name() << ":" << (2 * j + 1) << " positioned in " << backCoolLog.name()
2725                                         << " at (" << cms::convert2mm(-backCoolHeight / 2.0 + mbCoolTube.outDiam / 2.)
2726                                         << "," << cms::convert2mm(-bHalfWidth + (j + 1) * bHalfWidth / 5)
2727                                         << ",0) with no rotation";
2728 #endif
2729           }
2730         }
2731 
2732         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2733         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2734         //!!!!!!!!!!!!!! Begin Back Water Pipes   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2735         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2736         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2737         if (0 != backPipe.here && 0 != iMod) {
2738           string bPipeName(backPipe.name + "_" + std::to_string(iMod + 1));
2739           string bInnerName(backPipe.name + "_H2O_" + std::to_string(iMod + 1));
2740 
2741           Solid backPipeSolid = Tube(bPipeName, 0, backPipe.vecDiam[iMod] / 2, pipeLength / 2, 0_deg, 360_deg);
2742           Solid backInnerSolid =
2743               Tube(bInnerName, 0, backPipe.vecDiam[iMod] / 2 - backPipe.vecThick[iMod], pipeLength / 2, 0_deg, 360_deg);
2744 #ifdef EDM_ML_DEBUG
2745           edm::LogVerbatim("EBGeom") << bPipeName << " Tubs " << cms::convert2mm(pipeLength / 2)
2746                                      << ":0:" << cms::convert2mm(backPipe.vecDiam[iMod] / 2) << ":0:360";
2747           edm::LogVerbatim("EBGeom") << bInnerName << " Tubs " << cms::convert2mm(pipeLength / 2)
2748                                      << ":0:" << cms::convert2mm(backPipe.vecDiam[iMod] / 2 - backPipe.vecThick[iMod])
2749                                      << ":0:360";
2750 #endif
2751 
2752           Volume backPipeLog = Volume(bPipeName, backPipeSolid, ns.material(backPipe.mat));
2753           Volume backInnerLog = Volume(bInnerName, backInnerSolid, ns.material(backPipe.waterMat));
2754 
2755           const Position bPipeTra1(back.xOff + back.sideHeight - 0.7 * backPipe.vecDiam[iMod],
2756                                    back.yOff + back.plateWidth / 2 - back.sideWidth - 0.7 * backPipe.vecDiam[iMod],
2757                                    pipeZPos);
2758 
2759           spmLog.placeVolume(backPipeLog, copyOne, Transform3D(Rotation3D(), bPipeTra1));
2760 #ifdef EDM_ML_DEBUG
2761           edm::LogVerbatim("EBGeomX") << backPipeLog.name() << ":" << copyOne << " positioned in " << spmLog.name()
2762                                       << " at (" << cms::convert2mm(bPipeTra1.x()) << ","
2763                                       << cms::convert2mm(bPipeTra1.y()) << "," << cms::convert2mm(bPipeTra1.z())
2764                                       << ") with no rotation";
2765 #endif
2766           const Position bPipeTra2(
2767               bPipeTra1.x(), back.yOff - back.plateWidth / 2 + back.sideWidth + backPipe.vecDiam[iMod], bPipeTra1.z());
2768 
2769           spmLog.placeVolume(backPipeLog, copyTwo, Transform3D(Rotation3D(), bPipeTra2));
2770 #ifdef EDM_ML_DEBUG
2771           edm::LogVerbatim("EBGeomX") << backPipeLog.name() << ":" << copyTwo << " positioned in " << spmLog.name()
2772                                       << " at (" << cms::convert2mm(bPipeTra2.x()) << ","
2773                                       << cms::convert2mm(bPipeTra2.y()) << "," << cms::convert2mm(bPipeTra2.z())
2774                                       << ") with no rotation";
2775 #endif
2776 
2777           backPipeLog.placeVolume(backInnerLog, copyOne, Transform3D(Rotation3D(), Position()));
2778 #ifdef EDM_ML_DEBUG
2779           edm::LogVerbatim("EBGeomX") << backInnerLog.name() << ":" << copyOne << " positioned in "
2780                                       << backPipeLog.name() << " at (0,0,0) with no rotation";
2781 #endif
2782         }
2783         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2784         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2785         //!!!!!!!!!!!!!! End Back Water Pipes   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2786         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2787         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2788 
2789         //=================================================
2790 
2791         if (0 != dryAirTube.here) {
2792           string dryAirTubName(dryAirTube.name + std::to_string(iMod + 1));
2793 
2794           Solid dryAirTubeSolid =
2795               Tube(dryAirTubName, dryAirTube.innDiam / 2, dryAirTube.outDiam / 2, pipeLength / 2, 0_deg, 360_deg);
2796 #ifdef EDM_ML_DEBUG
2797           edm::LogVerbatim("EBGeom") << dryAirTubName << " Tubs " << cms::convert2mm(pipeLength / 2) << ":"
2798                                      << cms::convert2mm(dryAirTube.innDiam / 2) << ":"
2799                                      << cms::convert2mm(dryAirTube.outDiam / 2) << ":0:360";
2800 #endif
2801           Volume dryAirTubeLog = Volume((myns + dryAirTubName), dryAirTubeSolid, ns.material(dryAirTube.mat));
2802 
2803           const Position dryAirTubeTra1(back.xOff + back.sideHeight - 0.7 * dryAirTube.outDiam - backPipe.vecDiam[iMod],
2804                                         back.yOff + back.plateWidth / 2 - back.sideWidth - 1.2 * dryAirTube.outDiam,
2805                                         pipeZPos);
2806 
2807           spmLog.placeVolume(dryAirTubeLog, copyOne, Transform3D(Rotation3D(), dryAirTubeTra1));
2808 #ifdef EDM_ML_DEBUG
2809           edm::LogVerbatim("EBGeomX") << dryAirTubeLog.name() << ":" << copyOne << " positioned in " << spmLog.name()
2810                                       << " at (" << cms::convert2mm(dryAirTubeTra1.x()) << ","
2811                                       << cms::convert2mm(dryAirTubeTra1.y()) << ","
2812                                       << cms::convert2mm(dryAirTubeTra1.z()) << ") with no rotation";
2813 #endif
2814 
2815           const Position dryAirTubeTra2(dryAirTubeTra1.x(),
2816                                         back.yOff - back.plateWidth / 2 + back.sideWidth + 0.7 * dryAirTube.outDiam,
2817                                         dryAirTubeTra1.z());
2818 
2819           spmLog.placeVolume(dryAirTubeLog, copyTwo, Transform3D(Rotation3D(), dryAirTubeTra2));
2820 #ifdef EDM_ML_DEBUG
2821           edm::LogVerbatim("EBGeomX") << dryAirTubeLog.name() << ":" << copyTwo << " positioned in " << spmLog.name()
2822                                       << " at (" << cms::convert2mm(dryAirTubeTra2.x()) << ","
2823                                       << cms::convert2mm(dryAirTubeTra2.y()) << ","
2824                                       << cms::convert2mm(dryAirTubeTra2.z()) << ") with no rotation";
2825 #endif
2826         }
2827         //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2828 
2829         // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2830         // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2831         // !!!!!!!!!!!!!! Begin Placement of Cooling + VFE Cards          !!!!!!
2832         // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2833         // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2834 
2835         Position cTra(backCool.barHeight / 2. - backCoolHeight / 2. + bottomThick, 0, -halfZTank + halfZCoolVFE);
2836         const unsigned int numSec(static_cast<unsigned int>(backCool.vecBackCoolNSec[iMod]));
2837         for (unsigned int jSec(0); jSec != numSec; ++jSec) {
2838           const unsigned int nMax(static_cast<unsigned int>(backCool.vecBackCoolNPerSec[iNSec++]));
2839           for (unsigned int iBar(0); iBar != nMax; ++iBar) {
2840             backCoolLog.placeVolume(backCoolVFELog, iCVFECopy++, cTra);
2841 #ifdef EDM_ML_DEBUG
2842             edm::LogVerbatim("EBGeomX") << backCoolVFELog.name() << ":" << iCVFECopy << " positioned in "
2843                                         << backCoolLog.name() << " at (" << cms::convert2mm(cTra.x()) << ","
2844                                         << cms::convert2mm(cTra.y()) << "," << cms::convert2mm(cTra.z())
2845                                         << ") with no rotation";
2846 #endif
2847             cTra += Position(0, 0, backMisc.backCBStdSep);
2848           }
2849           cTra -= Position(0, 0, backMisc.backCBStdSep);  // backspace to previous
2850           if (jSec != numSec - 1)
2851             cTra += Position(0, 0, backCool.vecBackCoolSecSep[iSep++]);  // now take atypical step
2852         }
2853         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2854         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2855         //!!!!!!!!!!!!!! End Placement of Cooling + VFE Cards            !!!!!!
2856         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2857         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2858       }
2859 
2860       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2861       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2862       //!!!!!!!!!!!!!! End Placement of Readout & Cooling by Module    !!!!!!
2863       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2864       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2865 
2866       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2867       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2868       //!!!!!!!!!!!!!! Begin Patch Panel   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2869       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2870       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2871 
2872       double patchHeight(0);
2873       for (unsigned int iPatch(0); iPatch != patchPanel.vecThick.size(); ++iPatch) {
2874         patchHeight += patchPanel.vecThick[iPatch];
2875       }
2876 
2877       array<double, 3> patchParms{
2878           {patchHeight / 2., backCool.barWidth / 2., (spm.vecZPts.back() - grille.vecZOff.back() - grille.thick) / 2}};
2879       Solid patchSolid = Box(patchParms[0], patchParms[1], patchParms[2]);
2880 #ifdef EDM_ML_DEBUG
2881       edm::LogVerbatim("EBGeom") << patchPanel.name << " Box " << cms::convert2mm(patchParms[0]) << ":"
2882                                  << cms::convert2mm(patchParms[1]) << ":" << cms::convert2mm(patchParms[2]);
2883 #endif
2884       Volume patchLog = Volume(patchPanel.name, patchSolid, ns.material(spm.mat));
2885 
2886       const Position patchTra(back.xOff + 4 * dd4hep::mm, 0, grille.vecZOff.back() + grille.thick + patchParms[2]);
2887       if (0 != patchPanel.here) {
2888         spmLog.placeVolume(patchLog, copyOne, patchTra);
2889 #ifdef EDM_ML_DEBUG
2890         edm::LogVerbatim("EBGeomX") << patchLog.name() << ":" << copyOne << " positioned in " << spmLog.name()
2891                                     << " at (" << cms::convert2mm(patchTra.x()) << "," << cms::convert2mm(patchTra.y())
2892                                     << "," << cms::convert2mm(patchTra.z()) << ") with no rotation";
2893 #endif
2894       }
2895 
2896       Position pTra(-patchParms[0], 0, 0);
2897 
2898       for (unsigned int j(0); j != patchPanel.vecNames.size(); ++j) {
2899         Solid pSolid = Box(patchPanel.vecThick[j] / 2., patchParms[1], patchParms[2]);
2900 #ifdef EDM_ML_DEBUG
2901         edm::LogVerbatim("EBGeom") << patchPanel.vecNames[j] << " Box " << cms::convert2mm(patchPanel.vecThick[j] / 2.)
2902                                    << ":" << cms::convert2mm(patchParms[1]) << ":" << cms::convert2mm(patchParms[2]);
2903 #endif
2904         Volume pLog = Volume(patchPanel.vecNames[j], pSolid, ns.material(patchPanel.vecMat[j]));
2905 
2906         pTra += Position(patchPanel.vecThick[j] / 2, 0, 0);
2907         patchLog.placeVolume(pLog, copyOne, pTra);
2908 #ifdef EDM_ML_DEBUG
2909         edm::LogVerbatim("EBGeomX") << pLog.name() << ":" << copyOne << " positioned in " << patchLog.name() << " at ("
2910                                     << cms::convert2mm(pTra.x()) << "," << cms::convert2mm(pTra.y()) << ","
2911                                     << cms::convert2mm(pTra.z()) << ") with no rotation";
2912 #endif
2913 
2914         pTra += Position(patchPanel.vecThick[j] / 2, 0, 0);
2915       }
2916       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2917       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2918       //!!!!!!!!!!!!!! End Patch Panel     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2919       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2920       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2921 
2922       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2923       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2924       //!!!!!!!!!!!!!! Begin Pincers       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2925       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2926       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2927 
2928       if (0 != pincer.rodHere) {
2929         // Make hierarchy of rods, envelopes, blocks, shims, and cutouts
2930 
2931         Solid rodSolid = Box(pincer.rodName, pincer.envWidthHalf, pincer.envHeightHalf, ilyLengthHalf);
2932 #ifdef EDM_ML_DEBUG
2933         edm::LogVerbatim("EBGeom") << pincer.rodName << " Box " << cms::convert2mm(pincer.envWidthHalf) << ":"
2934                                    << cms::convert2mm(pincer.envHeightHalf) << ":" << cms::convert2mm(ilyLengthHalf);
2935 #endif
2936         Volume rodLog = Volume(pincer.rodName, rodSolid, ns.material(pincer.rodMat));
2937 
2938         array<double, 3> envParms{{pincer.envWidthHalf, pincer.envHeightHalf, pincer.envLengthHalf}};
2939         Solid envSolid = Box(pincer.envName, envParms[0], envParms[1], envParms[2]);
2940 #ifdef EDM_ML_DEBUG
2941         edm::LogVerbatim("EBGeom") << pincer.envName << " Box " << cms::convert2mm(envParms[0]) << ":"
2942                                    << cms::convert2mm(envParms[1]) << ":" << cms::convert2mm(envParms[2]);
2943 #endif
2944         Volume envLog = Volume(pincer.envName, envSolid, ns.material(pincer.envMat));
2945 
2946         array<double, 3> blkParms{{pincer.envWidthHalf, pincer.envHeightHalf, pincer.blkLengthHalf}};
2947         Solid blkSolid = Box(pincer.blkName, blkParms[0], blkParms[1], blkParms[2]);
2948 #ifdef EDM_ML_DEBUG
2949         edm::LogVerbatim("EBGeom") << pincer.blkName << " Box " << cms::convert2mm(blkParms[0]) << ":"
2950                                    << cms::convert2mm(blkParms[1]) << ":" << cms::convert2mm(blkParms[2]);
2951 #endif
2952         Volume blkLog = Volume(pincer.blkName, blkSolid, ns.material(pincer.blkMat));
2953 
2954         envLog.placeVolume(blkLog, copyOne, Position(0, 0, pincer.envLengthHalf - pincer.blkLengthHalf));
2955 #ifdef EDM_ML_DEBUG
2956         edm::LogVerbatim("EBGeomX") << blkLog.name() << ":" << copyOne << " positioned in " << envLog.name()
2957                                     << " at (0,0," << cms::convert2mm(pincer.envLengthHalf - pincer.blkLengthHalf)
2958                                     << ") with no rotation";
2959 #endif
2960 
2961         array<double, 3> cutParms{{pincer.cutWidth / 2., pincer.cutHeight / 2., pincer.blkLengthHalf}};
2962         Solid cutSolid = Box(pincer.cutName, cutParms[0], cutParms[1], cutParms[2]);
2963 #ifdef EDM_ML_DEBUG
2964         edm::LogVerbatim("EBGeom") << pincer.cutName << " Box " << cms::convert2mm(cutParms[0]) << ":"
2965                                    << cms::convert2mm(cutParms[1]) << ":" << cms::convert2mm(cutParms[2]);
2966 #endif
2967         Volume cutLog = Volume(pincer.cutName, cutSolid, ns.material(pincer.cutMat));
2968         blkLog.placeVolume(
2969             cutLog,
2970             copyOne,
2971             Position(
2972                 +blkParms[0] - cutParms[0] - pincer.shim1Width + pincer.shim2Width, -blkParms[1] + cutParms[1], 0));
2973 #ifdef EDM_ML_DEBUG
2974         edm::LogVerbatim("EBGeomX") << cutLog.name() << ":" << copyOne << " positioned in " << blkLog.name() << " at ("
2975                                     << cms::convert2mm(+blkParms[0] - cutParms[0] - pincer.shim1Width +
2976                                                        pincer.shim2Width)
2977                                     << "," << cms::convert2mm(-blkParms[1] + cutParms[1]) << ",0) with no rotation";
2978 #endif
2979         array<double, 3> shim2Parms{{pincer.shim2Width / 2., pincer.shimHeight / 2., pincer.blkLengthHalf}};
2980         Solid shim2Solid = Box(pincer.shim2Name, shim2Parms[0], shim2Parms[1], shim2Parms[2]);
2981 #ifdef EDM_ML_DEBUG
2982         edm::LogVerbatim("EBGeom") << pincer.shim2Name << " Box " << cms::convert2mm(shim2Parms[0]) << ":"
2983                                    << cms::convert2mm(shim2Parms[1]) << ":" << cms::convert2mm(shim2Parms[2]);
2984 #endif
2985         Volume shim2Log = Volume(pincer.shim2Name, shim2Solid, ns.material(pincer.shimMat));
2986         cutLog.placeVolume(shim2Log, copyOne, Position(+cutParms[0] - shim2Parms[0], -cutParms[1] + shim2Parms[1], 0));
2987 #ifdef EDM_ML_DEBUG
2988         edm::LogVerbatim("EBGeomX") << shim2Log.name() << ":" << copyOne << " positioned in " << cutLog.name()
2989                                     << " at (" << cms::convert2mm(cutParms[0] - shim2Parms[0]) << ","
2990                                     << cms::convert2mm(-cutParms[1] + shim2Parms[1]) << ",0) with no rotation";
2991 #endif
2992 
2993         array<double, 3> shim1Parms{
2994             {pincer.shim1Width / 2., pincer.shimHeight / 2., pincer.envLengthHalf - pincer.blkLengthHalf}};
2995         Solid shim1Solid = Box(pincer.shim1Name, shim1Parms[0], shim1Parms[1], shim1Parms[2]);
2996 #ifdef EDM_ML_DEBUG
2997         edm::LogVerbatim("EBGeom") << pincer.shim1Name << " Box " << cms::convert2mm(shim1Parms[0]) << ":"
2998                                    << cms::convert2mm(shim1Parms[1]) << ":" << cms::convert2mm(shim1Parms[2]);
2999 #endif
3000         Volume shim1Log = Volume(pincer.shim1Name, shim1Solid, ns.material(pincer.shimMat));
3001         envLog.placeVolume(
3002             shim1Log,
3003             copyOne,
3004             Position(+envParms[0] - shim1Parms[0], -envParms[1] + shim1Parms[1], -envParms[2] + shim1Parms[2]));
3005 #ifdef EDM_ML_DEBUG
3006         edm::LogVerbatim("EBGeomX") << shim1Log.name() << ":" << copyOne << " positioned in " << envLog.name()
3007                                     << " at (" << cms::convert2mm(envParms[0] - shim1Parms[0]) << ","
3008                                     << cms::convert2mm(-envParms[1] + shim1Parms[1]) << ","
3009                                     << cms::convert2mm(-envParms[2] + shim1Parms[2]) << ") with no rotation";
3010 #endif
3011 
3012         for (unsigned int iEnv(0); iEnv != pincer.vecEnvZOff.size(); ++iEnv) {
3013           rodLog.placeVolume(
3014               envLog, 1 + iEnv, Position(0, 0, -ilyLengthHalf + pincer.vecEnvZOff[iEnv] - pincer.envLengthHalf));
3015 #ifdef EDM_ML_DEBUG
3016           edm::LogVerbatim("EBGeomX") << envLog.name() << ":" << (1 + iEnv) << " positioned in " << rodLog.name()
3017                                       << " at (0,0,"
3018                                       << cms::convert2mm(-ilyLengthHalf + pincer.vecEnvZOff[iEnv] -
3019                                                          pincer.envLengthHalf)
3020                                       << ") with no rotation";
3021 #endif
3022         }
3023 
3024         // Place the rods
3025         const double radius(ilyRMin - pincer.envHeightHalf - 1 * dd4hep::mm);
3026         const string xilyName(ily.name + std::to_string(ily.vecIlyMat.size() - 1));
3027 
3028         for (unsigned int iRod(0); iRod != pincer.vecRodAzimuth.size(); ++iRod) {
3029           const Position rodTra(radius * cos(pincer.vecRodAzimuth[iRod]), radius * sin(pincer.vecRodAzimuth[iRod]), 0);
3030           xilyLog.placeVolume(rodLog,
3031                               1 + iRod,
3032                               Transform3D(myrot(ns,
3033                                                 pincer.rodName + std::to_string(iRod),
3034                                                 CLHEP::HepRotationZ(90_deg + pincer.vecRodAzimuth[iRod])),
3035                                           rodTra));
3036 #ifdef EDM_ML_DEBUG
3037           edm::LogVerbatim("EBGeomX") << rodLog.name() << ":" << (1 + iRod) << " positioned in " << xilyLog.name()
3038                                       << " at (" << cms::convert2mm(rodTra.x()) << "," << cms::convert2mm(rodTra.y())
3039                                       << "," << cms::convert2mm(rodTra.z()) << ") with rotation";
3040 #endif
3041         }
3042       }
3043       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3044       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3045       //!!!!!!!!!!!!!! End   Pincers       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3046       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3047       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3048     }
3049   }
3050 
3051   return 1;
3052 }
3053 
3054 DECLARE_DDCMS_DETELEMENT(DDCMS_ecal_DDEcalBarrelNewAlgoSubtraction, algorithm)