Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:30

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // File: DDHCalEndcapAlgo.cc
0003 //   adapted from CCal(G4)HcalEndcap.cc
0004 // Description: Geometry factory class for Hcal Endcap
0005 ///////////////////////////////////////////////////////////////////////////////
0006 
0007 #include <cmath>
0008 #include <algorithm>
0009 #include <map>
0010 #include <string>
0011 #include <vector>
0012 
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "FWCore/PluginManager/interface/PluginFactory.h"
0015 #include "DataFormats/Math/interface/angle_units.h"
0016 #include "DetectorDescription/Core/interface/DDutils.h"
0017 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0018 #include "DetectorDescription/Core/interface/DDSolid.h"
0019 #include "DetectorDescription/Core/interface/DDMaterial.h"
0020 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0021 #include "DetectorDescription/Core/interface/DDSplit.h"
0022 #include "DetectorDescription/Core/interface/DDTypes.h"
0023 #include "DetectorDescription/Core/interface/DDAlgorithm.h"
0024 #include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"
0025 
0026 //#define EDM_ML_DEBUG
0027 using namespace angle_units::operators;
0028 
0029 class DDHCalEndcapAlgo : public DDAlgorithm {
0030 public:
0031   //Constructor and Destructor
0032   DDHCalEndcapAlgo();
0033   ~DDHCalEndcapAlgo() override;
0034 
0035   //Get Methods
0036   const std::string& getGenMat() const { return genMaterial; }
0037   const std::string& getRotation() const { return rotation; }
0038   int getNsectors() const { return nsectors; }
0039   int getNsectortot() const { return nsectortot; }
0040   int getEndcaps() const { return nEndcap; }
0041   int equipModule(unsigned int i) const { return eModule[i]; }
0042   double getZShift() const { return zShift; }
0043 
0044   double getZFront() const { return zFront; }
0045   double getZEnd() const { return zEnd; }
0046   double getZiNose() const { return ziNose; }
0047   double getZiL0Nose() const { return ziL0Nose; }
0048   double getZiBody() const { return ziBody; }
0049   double getZiL0Body() const { return ziL0Body; }
0050   double getZiKink() const { return ziKink; }
0051   double getZ0Beam() const { return z0Beam; }
0052   double getZ1Beam() const { return z1Beam; }
0053   double getZiDip() const { return ziDip; }
0054   double getDzStep() const { return dzStep; }
0055   double getDzShift() const { return dzShift; }
0056   double getZShiftHac2() const { return zShiftHac2; }
0057 
0058   double getRout() const { return rout; }
0059   double getRinKink() const { return riKink; }
0060   double getRinDip() const { return riDip; }
0061   double getRoutDip() const { return roDip; }
0062   double getHeboxDepth() const { return heboxDepth; }
0063   double getDrEnd() const { return drEnd; }
0064   double getAngTop() const { return angTop; }
0065   double getAngBot() const { return angBot; }
0066   double getAngGap() const { return angGap; }
0067   double getSlope() const { return slope; }
0068 
0069   const std::string& getAbsMat() const { return absMat; }
0070   int getModules() const { return modules; }
0071   const std::string& getModName(unsigned int i) const { return modName[i]; }
0072   const std::string& getModMat(unsigned int i) const { return modMat[i]; }
0073   int getModType(unsigned int i) const { return modType[i]; }
0074   int getSectionModule(unsigned i) const { return sectionModule[i]; }
0075   int getLayerN(unsigned int i) const { return layerN[i]; }
0076   int getLayer(unsigned int i, unsigned int j) const;
0077   double getThick(unsigned int i) const { return thick[i]; }
0078   double getTrim(unsigned int i, unsigned int j) const;
0079   double getZminBlock(unsigned i) const { return zminBlock[i]; }
0080   double getZmaxBlock(unsigned i) const { return zmaxBlock[i]; }
0081   double getRinBlock1(unsigned i) const { return rinBlock1[i]; }
0082   double getRinBlock2(unsigned i) const { return rinBlock2[i]; }
0083   double getRoutBlock1(unsigned i) const { return routBlock1[i]; }
0084   double getRoutBlock2(unsigned i) const { return routBlock2[i]; }
0085 
0086   int getPhi() const { return phiSections; }
0087   const std::string& getPhiName(unsigned int i) const { return phiName[i]; }
0088   int getLayers() const { return layers; }
0089   const std::string& getLayerName(unsigned int i) const { return layerName[i]; }
0090   int getLayerType(unsigned int i) const { return layerType[i]; }
0091   double getLayerT(unsigned int i) const { return layerT[i]; }
0092   double getScintT(unsigned int i) const { return scintT[i]; }
0093   const std::string& getPlastMat() const { return plastMat; }
0094   const std::string& getScintMat() const { return scintMat; }
0095   const std::string& getRotMat() const { return rotmat; }
0096   double getTolPos() const { return tolPos; }
0097   double getTolAbs() const { return tolAbs; }
0098 
0099   void initialize(const DDNumericArguments& nArgs,
0100                   const DDVectorArguments& vArgs,
0101                   const DDMapArguments& mArgs,
0102                   const DDStringArguments& sArgs,
0103                   const DDStringVectorArguments& vsArgs) override;
0104 
0105   void execute(DDCompactView& cpv) override;
0106 
0107 protected:
0108   void constructGeneralVolume(DDCompactView& cpv);
0109   void constructInsideSector(const DDLogicalPart& sector, DDCompactView& cpv);
0110   void parameterLayer(int iphi,
0111                       double rinF,
0112                       double routF,
0113                       double rinB,
0114                       double routB,
0115                       double zi,
0116                       double zo,
0117                       double& yh1,
0118                       double& bl1,
0119                       double& tl1,
0120                       double& yh2,
0121                       double& bl2,
0122                       double& tl2,
0123                       double& alp,
0124                       double& theta,
0125                       double& phi,
0126                       double& xpos,
0127                       double& ypos,
0128                       double& zcpv);
0129   void parameterLayer0(int mod,
0130                        int layer,
0131                        int iphi,
0132                        double& yh,
0133                        double& bl,
0134                        double& tl,
0135                        double& alp,
0136                        double& xpos,
0137                        double& ypos,
0138                        double& zcpv);
0139   void constructInsideModule0(const DDLogicalPart& module, int mod, DDCompactView& cpv);
0140   void constructInsideModule(const DDLogicalPart& module, int mod, DDCompactView& cpv);
0141   void constructScintLayer(const DDLogicalPart& glog,
0142                            double pDz,
0143                            double yh,
0144                            double bl,
0145                            double tl,
0146                            double alp,
0147                            const std::string& name,
0148                            int id,
0149                            DDCompactView& cpv);
0150 
0151 private:
0152   std::string genMaterial;   //General material
0153   int nsectors;              //Number of potenital straight edges
0154   int nsectortot;            //Number of straight edges (actual)
0155   int nEndcap;               //Number of endcaps
0156   std::vector<int> eModule;  //Modules to be present in part i (?)
0157   std::string rotHalf;       //Rotation matrix for half
0158   std::string rotns;         //Name space for rotation
0159   std::string rotation;      //Rotation matrix to place in mother
0160   double zShift;             //needed for TB setup (move HE)
0161 
0162   double zFront;      //Z of the front section
0163   double zEnd;        //Outer Z of the HE
0164   double ziNose;      //Starting Z of the nose
0165   double ziL0Nose;    //Starting Z of layer 0 at nose
0166   double ziBody;      //Starting Z of the body
0167   double ziL0Body;    //Starting Z of layer 0 at body
0168   double ziKink;      //Position of the kink point
0169   double z0Beam;      //Position of gap front along z-axis
0170   double z1Beam;      //Position of gap end   along z-axis
0171   double ziDip;       //Starting Z of dipped part of body
0172   double dzStep;      //Width in Z of a layer
0173   double dzShift;     //Shift in Z for HE
0174   double zShiftHac2;  //needed for TB (remove part Hac2)
0175 
0176   double rout;        //Outer R of the HE
0177   double riKink;      //Inner radius at kink point
0178   double riDip;       //Inner radius at the dip point
0179   double roDip;       //Outer radius at the dip point
0180   double heboxDepth;  //Depth of the HE box
0181   double drEnd;       //Shift in R for the end absorber
0182 
0183   double angTop;  //Angle of top end of HE
0184   double angBot;  //Angle of the bottom end of HE
0185   double angGap;  //Gap angle (in degrees)
0186   double slope;   //Slope of the gap on HE side
0187 
0188   std::string absMat;                //Absorber     material
0189   int modules;                       //Number of modules
0190   std::vector<std::string> modName;  //Name
0191   std::vector<std::string> modMat;   //Material
0192   std::vector<int> modType;          //Type (0/1 for front/standard)
0193   std::vector<int> sectionModule;    //Number of sections in a module
0194   std::vector<int> layerN;           //Number of layers
0195   std::vector<int> layerN0;          //Layer numbers in section 0
0196   std::vector<int> layerN1;          //Layer numbers in section 1
0197   std::vector<int> layerN2;          //Layer numbers in section 2
0198   std::vector<int> layerN3;          //Layer numbers in section 3
0199   std::vector<int> layerN4;          //Layer numbers in section 4
0200   std::vector<int> layerN5;          //Layer numbers in section 5
0201   std::vector<double> thick;         //Thickness of absorber/air
0202   std::vector<double> trimLeft;      //Trimming of left  layers in module
0203   std::vector<double> trimRight;     //Trimming of right layers in module
0204   std::vector<double> zminBlock;     //Minimum Z
0205   std::vector<double> zmaxBlock;     //Maximum Z
0206   std::vector<double> rinBlock1;     //Inner Radius
0207   std::vector<double> routBlock1;    //Outer Radius at zmin
0208   std::vector<double> rinBlock2;     //Inner Radius
0209   std::vector<double> routBlock2;    //Outer Radius at zmax
0210 
0211   int phiSections;                     //Number of phi sections
0212   std::vector<std::string> phiName;    //Name of Phi sections
0213   int layers;                          //Number of layers
0214   std::vector<std::string> layerName;  //Layer Names
0215   std::vector<int> layerType;          //Detector type in each layer
0216   std::vector<double> layerT;          //Layer thickness (plastic + scint.)
0217   std::vector<double> scintT;          //Scintillator thickness
0218   std::string plastMat;                //Plastic      material
0219   std::string scintMat;                //Scintillator material
0220   std::string rotmat;                  //Rotation matrix for positioning
0221 
0222   std::string idName;       //Name of the "parent" volume.
0223   std::string idNameSpace;  //Namespace of this and ALL sub-parts
0224   int idOffset;             // Geant4 ID's...    = 4000;
0225 
0226   double tolPos, tolAbs;  //Tolerances
0227 };
0228 
0229 DDHCalEndcapAlgo::DDHCalEndcapAlgo()
0230     : modMat(0),
0231       modType(0),
0232       sectionModule(0),
0233       layerN(0),
0234       layerN0(0),
0235       layerN1(0),
0236       layerN2(0),
0237       layerN3(0),
0238       layerN4(0),
0239       layerN5(0),
0240       thick(0),
0241       trimLeft(0),
0242       trimRight(0),
0243       zminBlock(0),
0244       zmaxBlock(0),
0245       rinBlock1(0),
0246       routBlock1(0),
0247       rinBlock2(0),
0248       routBlock2(0),
0249       layerType(0),
0250       layerT(0),
0251       scintT(0) {
0252 #ifdef EDM_ML_DEBUG
0253   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Creating an instance";
0254 #endif
0255 }
0256 
0257 DDHCalEndcapAlgo::~DDHCalEndcapAlgo() {}
0258 
0259 int DDHCalEndcapAlgo::getLayer(unsigned int i, unsigned int j) const {
0260   switch (i) {
0261     case 0:
0262       return layerN0[j];
0263       break;
0264 
0265     case 1:
0266       return layerN1[j];
0267       break;
0268 
0269     case 2:
0270       return layerN2[j];
0271       break;
0272 
0273     case 3:
0274       return layerN3[j];
0275       break;
0276 
0277     case 4:
0278       return layerN4[j];
0279       break;
0280 
0281     case 5:
0282       return layerN5[j];
0283       break;
0284 
0285     default:
0286       return 0;
0287   }
0288 }
0289 
0290 double DDHCalEndcapAlgo::getTrim(unsigned int i, unsigned int j) const {
0291   if (j == 0)
0292     return trimLeft[i];
0293   else
0294     return trimRight[j];
0295 }
0296 
0297 void DDHCalEndcapAlgo::initialize(const DDNumericArguments& nArgs,
0298                                   const DDVectorArguments& vArgs,
0299                                   const DDMapArguments&,
0300                                   const DDStringArguments& sArgs,
0301                                   const DDStringVectorArguments& vsArgs) {
0302   genMaterial = sArgs["MaterialName"];
0303   rotation = sArgs["Rotation"];
0304   nsectors = int(nArgs["Sector"]);
0305   nsectortot = int(nArgs["SectorTot"]);
0306   nEndcap = int(nArgs["Endcap"]);
0307   rotHalf = sArgs["RotHalf"];
0308   rotns = sArgs["RotNameSpace"];
0309   zShift = nArgs["ZShift"];
0310 
0311   zFront = nArgs["ZFront"];
0312   zEnd = nArgs["ZEnd"];
0313   ziNose = nArgs["ZiNose"];
0314   ziL0Nose = nArgs["ZiL0Nose"];
0315   ziBody = nArgs["ZiBody"];
0316   ziL0Body = nArgs["ZiL0Body"];
0317   z0Beam = nArgs["Z0Beam"];
0318   ziDip = nArgs["ZiDip"];
0319   dzStep = nArgs["DzStep"];
0320   zShiftHac2 = nArgs["ZShiftHac2"];
0321   double gap = nArgs["Gap"];
0322   double z1 = nArgs["Z1"];
0323   double r1 = nArgs["R1"];
0324   rout = nArgs["Rout"];
0325   heboxDepth = nArgs["HEboxDepth"];
0326   drEnd = nArgs["DrEnd"];
0327   double etamin = nArgs["Etamin"];
0328   angBot = nArgs["AngBot"];
0329   angGap = nArgs["AngGap"];
0330 
0331 #ifdef EDM_ML_DEBUG
0332   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: General material " << genMaterial << "\tSectors " << nsectors
0333                                << ",  " << nsectortot << "\tEndcaps " << nEndcap << "\tRotation matrix for half "
0334                                << rotns << ":" << rotHalf << "\n\tzFront " << zFront << " zEnd " << zEnd << " ziNose "
0335                                << ziNose << " ziL0Nose " << ziL0Nose << " ziBody " << ziBody << " ziL0Body " << ziL0Body
0336                                << " z0Beam " << z0Beam << " ziDip " << ziDip << " dzStep " << dzStep << " Gap " << gap
0337                                << " z1 " << z1 << "\n\tr1 " << r1 << " rout " << rout << " HeboxDepth " << heboxDepth
0338                                << " drEnd " << drEnd << "\tetamin " << etamin << " Bottom angle " << angBot
0339                                << " Gap angle " << angGap << " Z-Shift " << zShift << " " << zShiftHac2;
0340 #endif
0341 
0342   //Derived quantities
0343   angTop = 2.0 * atan(exp(-etamin));
0344   slope = tan(angGap);
0345   z1Beam = z1 - r1 / slope;
0346   ziKink = z1Beam + rout / slope;
0347   riKink = ziKink * tan(angBot);
0348   riDip = ziDip * tan(angBot);
0349   roDip = rout - heboxDepth;
0350   dzShift = (z1Beam - z0Beam) - gap / sin(angGap);
0351 
0352 #ifdef EDM_ML_DEBUG
0353   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: angTop " << convertRadToDeg(angTop) << "\tSlope " << slope
0354                                << "\tDzShift " << dzShift << "\n\tz1Beam " << z1Beam << "\tziKink" << ziKink
0355                                << "\triKink " << riKink << "\triDip " << riDip << "\n\troDip " << roDip << "\tRotation "
0356                                << rotation;
0357 #endif
0358 
0359   ///////////////////////////////////////////////////////////////
0360   //Modules
0361   absMat = sArgs["AbsMat"];
0362   modules = int(nArgs["Modules"]);
0363 
0364 #ifdef EDM_ML_DEBUG
0365   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Number of modules " << modules << " and absorber material "
0366                                << absMat;
0367 #endif
0368 
0369   modName = vsArgs["ModuleName"];
0370   modMat = vsArgs["ModuleMat"];
0371   modType = dbl_to_int(vArgs["ModuleType"]);
0372   sectionModule = dbl_to_int(vArgs["SectionModule"]);
0373   thick = vArgs["ModuleThick"];
0374   trimLeft = vArgs["TrimLeft"];
0375   trimRight = vArgs["TrimRight"];
0376   eModule = dbl_to_int(vArgs["EquipModule"]);
0377   layerN = dbl_to_int(vArgs["LayerN"]);
0378   layerN0 = dbl_to_int(vArgs["LayerN0"]);
0379   layerN1 = dbl_to_int(vArgs["LayerN1"]);
0380   layerN2 = dbl_to_int(vArgs["LayerN2"]);
0381   layerN3 = dbl_to_int(vArgs["LayerN3"]);
0382   layerN4 = dbl_to_int(vArgs["LayerN4"]);
0383   layerN5 = dbl_to_int(vArgs["LayerN5"]);
0384 
0385 #ifdef EDM_ML_DEBUG
0386   for (int i = 0; i < modules; i++) {
0387     edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << modName[i] << " type " << modType[i] << " Sections "
0388                                  << sectionModule[i] << " thickness of absorber/air " << thick[i] << " trim "
0389                                  << trimLeft[i] << ", " << trimRight[i] << " equip module " << eModule[i] << " with "
0390                                  << layerN[i] << " layers";
0391     if (i == 0) {
0392       for (int j = 0; j < layerN[i]; j++) {
0393         edm::LogVerbatim("HCalGeom") << "\t " << layerN0[j] << "/" << layerN0[j + 1];
0394       }
0395     } else if (i == 1) {
0396       for (int j = 0; j < layerN[i]; j++) {
0397         edm::LogVerbatim("HCalGeom") << "\t " << layerN1[j] << "/" << layerN1[j + 1];
0398       }
0399     } else if (i == 2) {
0400       for (int j = 0; j < layerN[i]; j++) {
0401         edm::LogVerbatim("HCalGeom") << "\t " << layerN2[j];
0402       }
0403     } else if (i == 3) {
0404       for (int j = 0; j < layerN[i]; j++) {
0405         edm::LogVerbatim("HCalGeom") << "\t " << layerN3[j];
0406       }
0407     } else if (i == 4) {
0408       for (int j = 0; j < layerN[i]; j++) {
0409         edm::LogVerbatim("HCalGeom") << "\t " << layerN4[j];
0410       }
0411     } else if (i == 5) {
0412       for (int j = 0; j < layerN[i]; j++) {
0413         edm::LogVerbatim("HCalGeom") << "\t " << layerN5[j];
0414       }
0415     }
0416   }
0417 #endif
0418 
0419   ///////////////////////////////////////////////////////////////
0420   //Layers
0421   phiSections = int(nArgs["PhiSections"]);
0422   phiName = vsArgs["PhiName"];
0423   layers = int(nArgs["Layers"]);
0424   layerName = vsArgs["LayerName"];
0425   layerType = dbl_to_int(vArgs["LayerType"]);
0426   layerT = vArgs["LayerT"];
0427   scintT = vArgs["ScintT"];
0428   scintMat = sArgs["ScintMat"];
0429   plastMat = sArgs["PlastMat"];
0430   rotmat = sArgs["RotMat"];
0431 
0432 #ifdef EDM_ML_DEBUG
0433   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Phi Sections " << phiSections;
0434   for (int i = 0; i < phiSections; i++)
0435     edm::LogVerbatim("HCalGeom") << "\tName[" << i << "] : " << phiName[i];
0436   edm::LogVerbatim("HCalGeom") << "\tPlastic: " << plastMat << "\tScintillator: " << scintMat << "\tRotation matrix "
0437                                << rotns << ":" << rotmat << "\n\tNumber of layers " << layers;
0438   for (int i = 0; i < layers; i++) {
0439     edm::LogVerbatim("HCalGeom") << "\t" << layerName[i] << "\tType " << layerType[i] << "\tThickness " << layerT[i]
0440                                  << "\tScint.Thick " << scintT[i];
0441   }
0442 #endif
0443 
0444   ///////////////////////////////////////////////////////////////
0445   // Derive bounding of the modules
0446   int module = 0;
0447   // Layer 0 (Nose)
0448   if (modules > 0) {
0449     zminBlock.emplace_back(ziL0Nose);
0450     zmaxBlock.emplace_back(zminBlock[module] + layerT[0] + 0.5 * dzStep);
0451     rinBlock1.emplace_back(zminBlock[module] * tan(angTop));
0452     rinBlock2.emplace_back(zmaxBlock[module] * tan(angTop));
0453     routBlock1.emplace_back((zminBlock[module] - z1Beam) * slope);
0454     routBlock2.emplace_back((zmaxBlock[module] - z1Beam) * slope);
0455     module++;
0456   }
0457 
0458   // Layer 0 (Body)
0459   if (modules > 1) {
0460     zminBlock.emplace_back(ziL0Body);
0461     zmaxBlock.emplace_back(zminBlock[module] + layerT[0] + 0.5 * dzStep);
0462     rinBlock1.emplace_back(zminBlock[module] * tan(angBot));
0463     rinBlock2.emplace_back(zmaxBlock[module] * tan(angBot));
0464     routBlock1.emplace_back(zminBlock[module] * tan(angTop));
0465     routBlock2.emplace_back(zmaxBlock[module] * tan(angTop));
0466     module++;
0467   }
0468 
0469   // Hac1
0470   if (modules > 2) {
0471     zminBlock.emplace_back(ziNose);
0472     zmaxBlock.emplace_back(ziBody);
0473     rinBlock1.emplace_back(zminBlock[module] * tan(angTop));
0474     rinBlock2.emplace_back(zmaxBlock[module] * tan(angTop));
0475     routBlock1.emplace_back((zminBlock[module] - z1Beam) * slope);
0476     routBlock2.emplace_back((zmaxBlock[module] - z1Beam) * slope);
0477     module++;
0478   }
0479 
0480   // Hac2
0481   if (modules > 3) {
0482     zminBlock.emplace_back(ziBody);
0483     zmaxBlock.emplace_back(zminBlock[module] + layerN[3] * dzStep);
0484     rinBlock1.emplace_back(zminBlock[module] * tan(angBot));
0485     rinBlock2.emplace_back(zmaxBlock[module] * tan(angBot));
0486     routBlock1.emplace_back((zmaxBlock[module - 1] - z1Beam) * slope);
0487     routBlock2.emplace_back(rout);
0488     module++;
0489   }
0490 
0491   // Hac3
0492   if (modules > 4) {
0493     zminBlock.emplace_back(zmaxBlock[module - 1]);
0494     zmaxBlock.emplace_back(zminBlock[module] + layerN[4] * dzStep);
0495     rinBlock1.emplace_back(zminBlock[module] * tan(angBot));
0496     rinBlock2.emplace_back(zmaxBlock[module] * tan(angBot));
0497     routBlock1.emplace_back(rout);
0498     routBlock2.emplace_back(rout);
0499     module++;
0500   }
0501 
0502   // Hac4
0503   if (modules > 5) {
0504     zminBlock.emplace_back(zmaxBlock[module - 1]);
0505     zmaxBlock.emplace_back(zminBlock[module] + layerN[5] * dzStep);
0506     rinBlock1.emplace_back(zminBlock[module] * tan(angBot));
0507     rinBlock2.emplace_back(zmaxBlock[module] * tan(angBot));
0508     routBlock1.emplace_back(rout);
0509     routBlock2.emplace_back(roDip);
0510     module++;
0511   }
0512 
0513 #ifdef EDM_ML_DEBUG
0514   for (int i = 0; i < module; i++)
0515     edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Module " << i << "\tZ/Rin/Rout " << zminBlock[i] << ", "
0516                                  << zmaxBlock[i] << "/ " << rinBlock1[i] << ", " << rinBlock2[i] << "/ "
0517                                  << routBlock1[i] << ", " << routBlock2[i];
0518 #endif
0519 
0520   idName = sArgs["MotherName"];
0521   idNameSpace = DDCurrentNamespace::ns();
0522   idOffset = int(nArgs["IdOffset"]);
0523 
0524 #ifdef EDM_ML_DEBUG
0525   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Parent " << parent().name() << " idName " << idName
0526                                << " NameSpace " << idNameSpace << " Offset " << idOffset;
0527 #endif
0528 
0529   tolPos = nArgs["TolPos"];
0530   tolAbs = nArgs["TolAbs"];
0531 
0532 #ifdef EDM_ML_DEBUG
0533   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Tolerances - Positioning " << tolPos << " Absorber " << tolAbs;
0534 #endif
0535 }
0536 
0537 ////////////////////////////////////////////////////////////////////
0538 // DDHCalEndcapAlgo methods...
0539 ////////////////////////////////////////////////////////////////////
0540 
0541 void DDHCalEndcapAlgo::execute(DDCompactView& cpv) {
0542 #ifdef EDM_ML_DEBUG
0543   edm::LogVerbatim("HCalGeom") << "==>> Constructing DDHCalEndcapAlgo...";
0544 #endif
0545 
0546   constructGeneralVolume(cpv);
0547 
0548 #ifdef EDM_ML_DEBUG
0549   edm::LogVerbatim("HCalGeom") << "<<== End of DDHCalEndcapAlgo construction ...";
0550 #endif
0551 }
0552 
0553 //----------------------start here for DDD work!!! ---------------
0554 
0555 void DDHCalEndcapAlgo::constructGeneralVolume(DDCompactView& cpv) {
0556 #ifdef EDM_ML_DEBUG
0557   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: General volume...";
0558 #endif
0559 
0560   bool proto = true;
0561   for (int i = 0; i < 3; i++)
0562     if (equipModule(i) > 0)
0563       proto = false;
0564 
0565   DDRotation rot;
0566   if (DDSplit(getRotation()).first == "NULL")
0567     rot = DDRotation();
0568   else
0569     rot = DDRotation(DDName(DDSplit(getRotation()).first, DDSplit(getRotation()).second));
0570 
0571 #ifdef EDM_ML_DEBUG
0572   edm::LogVerbatim("HCalGeom") << " First " << DDSplit(getRotation()).first << " Second "
0573                                << DDSplit(getRotation()).second << " Rotation " << rot;
0574 #endif
0575 
0576   DDTranslation r0(0, 0, getZShift());
0577   double alpha = (1._pi) / getNsectors();
0578   double dphi = getNsectortot() * (2._pi) / getNsectors();
0579 
0580   //!!!!!!!!!!!!!!!!!Should be zero. And removed as soon as
0581   //vertical walls are allowed in SolidPolyhedra
0582   double delz = 0;
0583 
0584   std::vector<double> pgonZ, pgonRmin, pgonRmax;
0585   if (proto) {
0586     double zf = getZiBody() + getZShiftHac2();
0587     pgonZ.emplace_back(zf - getDzShift());
0588     pgonRmin.emplace_back(zf * tan(getAngBot()));
0589     pgonRmax.emplace_back((zf - getZ1Beam()) * getSlope());
0590   } else {
0591     pgonZ.emplace_back(getZFront() - getDzShift());
0592     pgonRmin.emplace_back(getZFront() * tan(getAngTop()));
0593     pgonRmax.emplace_back((getZFront() - getZ1Beam()) * getSlope());
0594     pgonZ.emplace_back(getZiL0Body() - getDzShift());
0595     pgonRmin.emplace_back(getZiL0Body() * tan(getAngTop()));
0596     pgonRmax.emplace_back((getZiL0Body() - getZ1Beam()) * getSlope());
0597     pgonZ.emplace_back(getZiL0Body() - getDzShift());
0598     pgonRmin.emplace_back(getZiL0Body() * tan(getAngBot()));
0599     pgonRmax.emplace_back((getZiL0Body() - getZ1Beam()) * getSlope());
0600   }
0601   pgonZ.emplace_back(getZiKink() - getDzShift());
0602   pgonRmin.emplace_back(getRinKink());
0603   pgonRmax.emplace_back(getRout());
0604   pgonZ.emplace_back(getZiDip() - getDzShift());
0605   pgonRmin.emplace_back(getRinDip());
0606   pgonRmax.emplace_back(getRout());
0607   pgonZ.emplace_back(getZiDip() - getDzShift() + delz);
0608   pgonRmin.emplace_back(getRinDip());
0609   pgonRmax.emplace_back(getRoutDip());
0610   pgonZ.emplace_back(getZEnd() - getDzShift());
0611   pgonRmin.emplace_back(getZEnd() * tan(getAngBot()));
0612   pgonRmax.emplace_back(getRoutDip());
0613   pgonZ.emplace_back(getZEnd());
0614   pgonRmin.emplace_back(getZEnd() * tan(getAngBot()));
0615   pgonRmax.emplace_back(getRoutDip());
0616 
0617   std::string name("Null");
0618   DDSolid solid;
0619   solid =
0620       DDSolidFactory::polyhedra(DDName(idName, idNameSpace), getNsectortot(), -alpha, dphi, pgonZ, pgonRmin, pgonRmax);
0621 #ifdef EDM_ML_DEBUG
0622   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(idName, idNameSpace) << " Polyhedra made of "
0623                                << getGenMat() << " with " << getNsectortot() << " sectors from "
0624                                << convertRadToDeg(-alpha) << " to " << convertRadToDeg(-alpha + dphi) << " and with "
0625                                << pgonZ.size() << " sections";
0626   for (unsigned int i = 0; i < pgonZ.size(); i++)
0627     edm::LogVerbatim("HCalGeom") << "\t\tZ = " << pgonZ[i] << "\tRmin = " << pgonRmin[i] << "\tRmax = " << pgonRmax[i];
0628 #endif
0629 
0630   DDName matname(DDSplit(getGenMat()).first, DDSplit(getGenMat()).second);
0631   DDMaterial matter(matname);
0632   DDLogicalPart genlogic(DDName(idName, idNameSpace), matter, solid);
0633 
0634   DDName parentName = parent().name();
0635   cpv.position(DDName(idName, idNameSpace), parentName, 1, r0, rot);
0636 
0637 #ifdef EDM_ML_DEBUG
0638   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(idName, idNameSpace) << " number 1 positioned in "
0639                                << parentName << " at " << r0 << " with " << rot;
0640 #endif
0641 
0642   if (getEndcaps() != 1) {
0643     rot = DDRotation(DDName(rotHalf, rotns));
0644     cpv.position(DDName(idName, idNameSpace), parentName, 2, r0, rot);
0645 
0646 #ifdef EDM_ML_DEBUG
0647     edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(idName, idNameSpace) << " number 2 "
0648                                  << "positioned in " << parentName << " at " << r0 << " with " << rot;
0649 #endif
0650   }
0651 
0652   //Forward half
0653   name = idName + "Front";
0654   std::vector<double> pgonZMod, pgonRminMod, pgonRmaxMod;
0655   for (unsigned int i = 0; i < (pgonZ.size() - 1); i++) {
0656     pgonZMod.emplace_back(pgonZ[i] + getDzShift());
0657     pgonRminMod.emplace_back(pgonRmin[i]);
0658     pgonRmaxMod.emplace_back(pgonRmax[i]);
0659   }
0660   solid = DDSolidFactory::polyhedra(
0661       DDName(name, idNameSpace), getNsectortot(), -alpha, dphi, pgonZMod, pgonRminMod, pgonRmaxMod);
0662 
0663 #ifdef EDM_ML_DEBUG
0664   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(name, idNameSpace) << " Polyhedra made of "
0665                                << getGenMat() << " with " << getNsectortot() << " sectors from "
0666                                << convertRadToDeg(-alpha) << " to " << convertRadToDeg(-alpha + dphi) << " and with "
0667                                << pgonZMod.size() << " sections ";
0668   for (unsigned int i = 0; i < pgonZMod.size(); i++)
0669     edm::LogVerbatim("HCalGeom") << "\t\tZ = " << pgonZMod[i] << "\tRmin = " << pgonRminMod[i]
0670                                  << "\tRmax = " << pgonRmaxMod[i];
0671 #endif
0672 
0673   DDLogicalPart genlogich(DDName(name, idNameSpace), matter, solid);
0674 
0675   cpv.position(genlogich, genlogic, 1, DDTranslation(0.0, 0.0, -getDzShift()), DDRotation());
0676 
0677 #ifdef EDM_ML_DEBUG
0678   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << genlogich.name() << " number 1 positioned in "
0679                                << genlogic.name() << " at (0,0," << -getDzShift() << ") with no rotation";
0680 #endif
0681 
0682   //Construct sector (from -alpha to +alpha)
0683   name = idName + "Module";
0684   solid =
0685       DDSolidFactory::polyhedra(DDName(name, idNameSpace), 1, -alpha, 2 * alpha, pgonZMod, pgonRminMod, pgonRmaxMod);
0686 #ifdef EDM_ML_DEBUG
0687   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(name, idNameSpace) << " Polyhedra made of "
0688                                << getGenMat() << " with 1 sector from " << convertRadToDeg(-alpha) << " to "
0689                                << convertRadToDeg(alpha) << " and with " << pgonZMod.size() << " sections";
0690   for (unsigned int i = 0; i < pgonZMod.size(); i++)
0691     edm::LogVerbatim("HCalGeom") << "\t\tZ = " << pgonZMod[i] << "\tRmin = " << pgonRminMod[i]
0692                                  << "\tRmax = " << pgonRmaxMod[i];
0693 #endif
0694 
0695   DDLogicalPart seclogic(DDName(name, idNameSpace), matter, solid);
0696 
0697   for (int ii = 0; ii < getNsectortot(); ii++) {
0698     double phi = ii * 2 * alpha;
0699     DDRotation rotation;
0700     std::string rotstr("NULL");
0701     if (phi != 0) {
0702       rotstr = "R" + formatAsDegreesInInteger(phi);
0703       rotation = DDRotation(DDName(rotstr, rotns));
0704       if (!rotation) {
0705 #ifdef EDM_ML_DEBUG
0706         edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Creating a new rotation " << rotstr << "\t 90,"
0707                                      << convertRadToDeg(phi) << ", 90," << convertRadToDeg(phi + 90._deg) << ", 0, 0";
0708 #endif
0709         rotation = DDrot(DDName(rotstr, rotns), 90._deg, phi, 90._deg, (90._deg + phi), 0, 0);
0710       }  //if !rotation
0711     }  //if phi!=0
0712 
0713     cpv.position(seclogic, genlogich, ii + 1, DDTranslation(0.0, 0.0, 0.0), rotation);
0714 
0715 #ifdef EDM_ML_DEBUG
0716     edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << seclogic.name() << " number " << ii + 1 << " positioned in "
0717                                  << genlogich.name() << " at (0,0,0) with " << rotation;
0718 #endif
0719   }
0720 
0721   //Construct the things inside the sector
0722   constructInsideSector(seclogic, cpv);
0723 
0724   //Backward half
0725   name = idName + "Back";
0726   std::vector<double> pgonZBack, pgonRminBack, pgonRmaxBack;
0727   pgonZBack.emplace_back(getZEnd() - getDzShift());
0728   pgonRminBack.emplace_back(pgonZBack[0] * tan(getAngBot()) + getDrEnd());
0729   pgonRmaxBack.emplace_back(getRoutDip());
0730   pgonZBack.emplace_back(getZEnd());
0731   pgonRminBack.emplace_back(pgonZBack[1] * tan(getAngBot()) + getDrEnd());
0732   pgonRmaxBack.emplace_back(getRoutDip());
0733   solid = DDSolidFactory::polyhedra(
0734       DDName(name, idNameSpace), getNsectortot(), -alpha, dphi, pgonZBack, pgonRminBack, pgonRmaxBack);
0735 
0736 #ifdef EDM_ML_DEBUG
0737   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(name, idNameSpace) << " Polyhedra made of "
0738                                << getAbsMat() << " with " << getNsectortot() << " sectors from "
0739                                << convertRadToDeg(-alpha) << " to " << convertRadToDeg(-alpha + dphi) << " and with "
0740                                << pgonZBack.size() << " sections";
0741   for (unsigned int i = 0; i < pgonZBack.size(); i++)
0742     edm::LogVerbatim("HCalGeom") << "\t\tZ = " << pgonZBack[i] << "\tRmin = " << pgonRminBack[i]
0743                                  << "\tRmax = " << pgonRmaxBack[i];
0744 #endif
0745 
0746   DDName absMatname(DDSplit(getAbsMat()).first, DDSplit(getAbsMat()).second);
0747   DDMaterial absMatter(absMatname);
0748   DDLogicalPart glog(DDName(name, idNameSpace), absMatter, solid);
0749 
0750   cpv.position(glog, genlogic, 1, DDTranslation(0.0, 0.0, 0.0), DDRotation());
0751 
0752 #ifdef EDM_ML_DEBUG
0753   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << glog.name() << " number 1 positioned in " << genlogic.name()
0754                                << " at (0,0,0) with no rotation";
0755 #endif
0756 }
0757 
0758 void DDHCalEndcapAlgo::constructInsideSector(const DDLogicalPart& sector, DDCompactView& cpv) {
0759 #ifdef EDM_ML_DEBUG
0760   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Modules (" << getModules() << ") ...";
0761 #endif
0762 
0763   double alpha = (1._pi) / getNsectors();
0764 
0765   for (int i = 0; i < getModules(); i++) {
0766     std::string name = idName + getModName(i);
0767     DDName matname(DDSplit(getModMat(i)).first, DDSplit(getModMat(i)).second);
0768     DDMaterial matter(matname);
0769 
0770     if (equipModule(i) > 0) {
0771       int nsec = getSectionModule(i);
0772 
0773       //!!!!!!!!!!!!!!!!!Should be zero. And removed as soon as
0774       //vertical walls are allowed in SolidPolyhedra
0775       double deltaz = 0;
0776 
0777       std::vector<double> pgonZ, pgonRmin, pgonRmax;
0778       if (nsec == 3) {
0779         double zf = getZminBlock(i) + getZShiftHac2();
0780         pgonZ.emplace_back(zf);
0781         pgonRmin.emplace_back(zf * tan(getAngBot()));
0782         pgonRmax.emplace_back((zf - getZ1Beam()) * getSlope());
0783         pgonZ.emplace_back(getZiKink());
0784         pgonRmin.emplace_back(getRinKink());
0785         pgonRmax.emplace_back(getRout());
0786       } else {
0787         pgonZ.emplace_back(getZminBlock(i));
0788         pgonRmin.emplace_back(getRinBlock1(i));
0789         pgonRmax.emplace_back(getRoutBlock1(i));
0790       }
0791       if (nsec == 4) {
0792         pgonZ.emplace_back(getZiDip());
0793         pgonRmin.emplace_back(getRinDip());
0794         pgonRmax.emplace_back(getRout());
0795         pgonZ.emplace_back(pgonZ[1] + deltaz);
0796         pgonRmin.emplace_back(pgonRmin[1]);
0797         pgonRmax.emplace_back(getRoutDip());
0798       }
0799       pgonZ.emplace_back(getZmaxBlock(i));
0800       pgonRmin.emplace_back(getRinBlock2(i));
0801       pgonRmax.emplace_back(getRoutBlock2(i));
0802 
0803       //Solid & volume
0804       DDSolid solid;
0805       solid = DDSolidFactory::polyhedra(DDName(name, idNameSpace), 1, -alpha, 2 * alpha, pgonZ, pgonRmin, pgonRmax);
0806 
0807 #ifdef EDM_ML_DEBUG
0808       edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(name, idNameSpace) << " Polyhedra made of "
0809                                    << getModMat(i) << " with 1 sector from " << convertRadToDeg(-alpha) << " to "
0810                                    << convertRadToDeg(alpha) << " and with " << nsec << " sections";
0811       for (unsigned int k = 0; k < pgonZ.size(); k++)
0812         edm::LogVerbatim("HCalGeom") << "\t\tZ = " << pgonZ[k] << "\tRmin = " << pgonRmin[k]
0813                                      << "\tRmax = " << pgonRmax[k];
0814 #endif
0815 
0816       DDLogicalPart glog(DDName(name, idNameSpace), matter, solid);
0817 
0818       cpv.position(glog, sector, i + 1, DDTranslation(0.0, 0.0, 0.0), DDRotation());
0819 
0820 #ifdef EDM_ML_DEBUG
0821       edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << glog.name() << " number " << i + 1 << " positioned in "
0822                                    << sector.name() << " at (0,0,0) with no rotation";
0823 #endif
0824 
0825       if (getModType(i) == 0)
0826         constructInsideModule0(glog, i, cpv);
0827       else
0828         constructInsideModule(glog, i, cpv);
0829     }
0830   }
0831 }
0832 
0833 void DDHCalEndcapAlgo::parameterLayer0(int mod,
0834                                        int layer,
0835                                        int iphi,
0836                                        double& yh,
0837                                        double& bl,
0838                                        double& tl,
0839                                        double& alp,
0840                                        double& xpos,
0841                                        double& ypos,
0842                                        double& zpos) {
0843   //Given module and layer number compute parameters of trapezoid
0844   //and positioning parameters
0845   double alpha = (1._pi) / getNsectors();
0846 
0847 #ifdef EDM_ML_DEBUG
0848   edm::LogVerbatim("HCalGeom") << "Input " << iphi << " " << layer << " " << iphi << " Alpha "
0849                                << convertRadToDeg(alpha);
0850 #endif
0851 
0852   double zi, zo;
0853   if (iphi == 0) {
0854     zi = getZminBlock(mod);
0855     zo = zi + getLayerT(layer);
0856   } else {
0857     zo = getZmaxBlock(mod);
0858     zi = zo - getLayerT(layer);
0859   }
0860   double rin, rout;
0861   if (mod == 0) {
0862     rin = zo * tan(getAngTop());
0863     rout = (zi - getZ1Beam()) * getSlope();
0864   } else {
0865     rin = zo * tan(getAngBot());
0866     rout = zi * tan(getAngTop());
0867   }
0868   yh = 0.5 * (rout - rin);
0869   bl = 0.5 * rin * tan(alpha);
0870   tl = 0.5 * rout * tan(alpha);
0871   xpos = 0.5 * (rin + rout);
0872   ypos = 0.5 * (bl + tl);
0873   zpos = 0.5 * (zi + zo);
0874   yh -= getTrim(mod, iphi);
0875   bl -= getTrim(mod, iphi);
0876   tl -= getTrim(mod, iphi);
0877   alp = atan(0.5 * tan(alpha));
0878   if (iphi == 0) {
0879     ypos = -ypos;
0880   } else {
0881     alp = -alp;
0882   }
0883 
0884 #ifdef EDM_ML_DEBUG
0885   edm::LogVerbatim("HCalGeom") << "Output Dimensions " << yh << " " << bl << " " << tl << " " << convertRadToDeg(alp)
0886                                << " Position " << xpos << " " << ypos << " " << zpos;
0887 #endif
0888 }
0889 
0890 void DDHCalEndcapAlgo::parameterLayer(int iphi,
0891                                       double rinF,
0892                                       double routF,
0893                                       double rinB,
0894                                       double routB,
0895                                       double zi,
0896                                       double zo,
0897                                       double& yh1,
0898                                       double& bl1,
0899                                       double& tl1,
0900                                       double& yh2,
0901                                       double& bl2,
0902                                       double& tl2,
0903                                       double& alp,
0904                                       double& theta,
0905                                       double& phi,
0906                                       double& xpos,
0907                                       double& ypos,
0908                                       double& zpos) {
0909   //Given rin, rout compute parameters of the trapezoid and
0910   //position of the trapezoid for a standrd layer
0911   double alpha = (1._pi) / getNsectors();
0912 
0913 #ifdef EDM_ML_DEBUG
0914   edm::LogVerbatim("HCalGeom") << "Input " << iphi << " Front " << rinF << " " << routF << " " << zi << " Back " << rinB
0915                                << " " << routB << " " << zo << " Alpha " << convertRadToDeg(alpha);
0916 #endif
0917 
0918   yh1 = 0.5 * (routF - rinB);
0919   bl1 = 0.5 * rinB * tan(alpha);
0920   tl1 = 0.5 * routF * tan(alpha);
0921   yh2 = 0.5 * (routF - rinB);
0922   bl2 = 0.5 * rinB * tan(alpha);
0923   tl2 = 0.5 * routF * tan(alpha);
0924   double dx = 0.25 * (bl2 + tl2 - bl1 - tl1);
0925   double dy = 0.5 * (rinB + routF - rinB - routF);
0926   xpos = 0.25 * (rinB + routF + rinB + routF);
0927   ypos = 0.25 * (bl2 + tl2 + bl1 + tl1);
0928   zpos = 0.5 * (zi + zo);
0929   alp = atan(0.5 * tan(alpha));
0930   //  ypos-= getTolPos();
0931   if (iphi == 0) {
0932     ypos = -ypos;
0933   } else {
0934     alp = -alp;
0935     dx = -dx;
0936   }
0937   double r = sqrt(dx * dx + dy * dy);
0938   theta = atan(r / (zo - zi));
0939   phi = atan2(dy, dx);
0940 
0941 #ifdef EDM_ML_DEBUG
0942   edm::LogVerbatim("HCalGeom") << "Output Dimensions " << yh1 << " " << bl1 << " " << tl1 << " " << yh2 << " " << bl2
0943                                << " " << tl2 << " " << convertRadToDeg(alp) << " " << convertRadToDeg(theta) << " "
0944                                << convertRadToDeg(phi) << " Position " << xpos << " " << ypos << " " << zpos;
0945 #endif
0946 }
0947 
0948 void DDHCalEndcapAlgo::constructInsideModule0(const DDLogicalPart& module, int mod, DDCompactView& cpv) {
0949 #ifdef EDM_ML_DEBUG
0950   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: \t\tInside module0 ..." << mod;
0951 #endif
0952 
0953   ///////////////////////////////////////////////////////////////
0954   //Pointers to the Rotation Matrices and to the Materials
0955   std::string rotstr = getRotMat();
0956   DDRotation rot(DDName(rotstr, rotns));
0957   DDName matName(DDSplit(getAbsMat()).first, DDSplit(getAbsMat()).second);
0958   DDMaterial matabsorbr(matName);
0959   DDName plasName(DDSplit(getPlastMat()).first, DDSplit(getPlastMat()).second);
0960   DDMaterial matplastic(plasName);
0961 
0962   int layer = getLayer(mod, 0);
0963   int layer0 = getLayer(mod, 1);
0964   std::string name;
0965   double xpos, ypos, zpos;
0966   DDSolid solid;
0967   DDLogicalPart glog, plog;
0968   for (int iphi = 0; iphi < getPhi(); iphi++) {
0969     double yh, bl, tl, alp;
0970     parameterLayer0(mod, layer, iphi, yh, bl, tl, alp, xpos, ypos, zpos);
0971     name = module.name().name() + getLayerName(layer) + getPhiName(iphi);
0972     solid =
0973         DDSolidFactory::trap(DDName(name, idNameSpace), 0.5 * getLayerT(layer), 0, 0, yh, bl, tl, alp, yh, bl, tl, alp);
0974 
0975 #ifdef EDM_ML_DEBUG
0976     edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << solid.name() << " Trap made of " << getPlastMat()
0977                                  << " of dimensions " << 0.5 * getLayerT(layer) << ", 0, 0, " << yh << ", " << bl
0978                                  << ", " << tl << ", " << convertRadToDeg(alp) << ", " << yh << ", " << bl << ", " << tl
0979                                  << ", " << convertRadToDeg(alp);
0980 #endif
0981 
0982     glog = DDLogicalPart(solid.ddname(), matplastic, solid);
0983 
0984     DDTranslation r1(xpos, ypos, zpos);
0985     cpv.position(glog, module, idOffset + layer + 1, r1, rot);
0986 
0987 #ifdef EDM_ML_DEBUG
0988     edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << glog.name() << " number " << idOffset + layer + 1
0989                                  << " positioned in " << module.name() << " at " << r1 << " with " << rot;
0990 #endif
0991 
0992     //Now construct the layer of scintillator inside this
0993     int copyNo = layer0 * 10 + getLayerType(layer);
0994     name = getModName(mod) + getLayerName(layer) + getPhiName(iphi);
0995     constructScintLayer(glog, getScintT(layer), yh, bl, tl, alp, name, copyNo, cpv);
0996   }
0997 
0998   //Now the absorber layer
0999   double zi = getZminBlock(mod) + getLayerT(layer);
1000   double zo = zi + 0.5 * getDzStep();
1001   double rinF, routF, rinB, routB;
1002   if (mod == 0) {
1003     rinF = zi * tan(getAngTop());
1004     routF = (zi - getZ1Beam()) * getSlope();
1005     rinB = zo * tan(getAngTop());
1006     routB = (zo - getZ1Beam()) * getSlope();
1007   } else {
1008     rinF = zi * tan(getAngBot());
1009     routF = zi * tan(getAngTop());
1010     rinB = zo * tan(getAngBot());
1011     routB = zo * tan(getAngTop());
1012   }
1013 
1014 #ifdef EDM_ML_DEBUG
1015   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Module " << mod << " Front " << zi << ", " << rinF << ", " << routF
1016                                << " Back " << zo << ", " << rinB << ", " << routB;
1017 #endif
1018 
1019   double yh1, bl1, tl1, yh2, bl2, tl2, theta, phi, alp;
1020   parameterLayer(0, rinF, routF, rinB, routB, zi, zo, yh1, bl1, tl1, yh2, bl2, tl2, alp, theta, phi, xpos, ypos, zpos);
1021   double fact = getTolAbs();
1022 
1023 #ifdef EDM_ML_DEBUG
1024   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Trim " << fact << " Param " << yh1 << ", " << bl1 << ", " << tl1
1025                                << ", " << yh2 << ", " << bl2 << ", " << tl2;
1026 #endif
1027 
1028   bl1 -= fact;
1029   tl1 -= fact;
1030   bl2 -= fact;
1031   tl2 -= fact;
1032 
1033   name = module.name().name() + "Absorber";
1034   solid = DDSolidFactory::trap(
1035       DDName(name, idNameSpace), 0.5 * getThick(mod), theta, phi, yh1, bl1, tl1, alp, yh2, bl2, tl2, alp);
1036 #ifdef EDM_ML_DEBUG
1037   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << solid.name() << " Trap made of " << getAbsMat()
1038                                << " of dimensions " << 0.5 * getThick(mod) << ", " << convertRadToDeg(theta) << ", "
1039                                << convertRadToDeg(phi) << ", " << yh1 << ", " << bl1 << ", " << tl1 << ", "
1040                                << convertRadToDeg(alp) << ", " << yh2 << ", " << bl2 << ", " << tl2 << ", "
1041                                << convertRadToDeg(alp);
1042 #endif
1043 
1044   glog = DDLogicalPart(solid.ddname(), matabsorbr, solid);
1045 
1046   DDTranslation r2(xpos, ypos, zpos);
1047   cpv.position(glog, module, 1, r2, rot);
1048 
1049 #ifdef EDM_ML_DEBUG
1050   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << glog.name() << " number 1 positioned in " << module.name()
1051                                << " at " << r2 << " with " << rot;
1052 #endif
1053 }
1054 
1055 void DDHCalEndcapAlgo::constructInsideModule(const DDLogicalPart& module, int mod, DDCompactView& cpv) {
1056 #ifdef EDM_ML_DEBUG
1057   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: \t\tInside module ..." << mod;
1058 #endif
1059 
1060   ///////////////////////////////////////////////////////////////
1061   //Pointers to the Rotation Matrices and to the Materials
1062   std::string rotstr = getRotMat();
1063   DDRotation rot(DDName(rotstr, rotns));
1064   DDName matName(DDSplit(getGenMat()).first, DDSplit(getGenMat()).second);
1065   DDMaterial matter(matName);
1066   DDName plasName(DDSplit(getPlastMat()).first, DDSplit(getPlastMat()).second);
1067   DDMaterial matplastic(plasName);
1068 
1069   double alpha = (1._pi) / getNsectors();
1070   double zi = getZminBlock(mod);
1071 
1072   for (int i = 0; i < getLayerN(mod); i++) {
1073     std::string name;
1074     DDSolid solid;
1075     DDLogicalPart glog, plog;
1076     int layer = getLayer(mod, i);
1077     double zo = zi + 0.5 * getDzStep();
1078 
1079     for (int iphi = 0; iphi < getPhi(); iphi++) {
1080       double ziAir = zo - getThick(mod);
1081       double rinF, rinB;
1082       if (layer == 1) {
1083         rinF = ziAir * tan(getAngTop());
1084         rinB = zo * tan(getAngTop());
1085       } else {
1086         rinF = ziAir * tan(getAngBot());
1087         rinB = zo * tan(getAngBot());
1088       }
1089       double routF = (ziAir - getZ1Beam()) * getSlope();
1090       double routB = (zo - getZ1Beam()) * getSlope();
1091       if (routF > getRoutBlock2(mod))
1092         routF = getRoutBlock2(mod);
1093       if (routB > getRoutBlock2(mod))
1094         routB = getRoutBlock2(mod);
1095 
1096 #ifdef EDM_ML_DEBUG
1097       edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: Layer " << i << " Phi " << iphi << " Front " << ziAir << ", "
1098                                    << rinF << ", " << routF << " Back " << zo << ", " << rinB << ", " << routB;
1099 #endif
1100 
1101       double yh1, bl1, tl1, yh2, bl2, tl2, theta, phi, alp;
1102       double xpos, ypos, zpos;
1103       parameterLayer(
1104           iphi, rinF, routF, rinB, routB, ziAir, zo, yh1, bl1, tl1, yh2, bl2, tl2, alp, theta, phi, xpos, ypos, zpos);
1105 
1106       name = module.name().name() + getLayerName(layer) + getPhiName(iphi) + "Air";
1107       solid = DDSolidFactory::trap(
1108           DDName(name, idNameSpace), 0.5 * getThick(mod), theta, phi, yh1, bl1, tl1, alp, yh2, bl2, tl2, alp);
1109 
1110 #ifdef EDM_ML_DEBUG
1111       edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << solid.name() << " Trap made of " << getGenMat()
1112                                    << " of dimensions " << 0.5 * getThick(mod) << ", " << convertRadToDeg(theta) << ", "
1113                                    << convertRadToDeg(phi) << ", " << yh1 << ", " << bl1 << ", " << tl1 << ", "
1114                                    << convertRadToDeg(alp) << ", " << yh2 << ", " << bl2 << ", " << tl2 << ", "
1115                                    << convertRadToDeg(alp);
1116 #endif
1117 
1118       glog = DDLogicalPart(solid.ddname(), matter, solid);
1119 
1120       DDTranslation r1(xpos, ypos, zpos);
1121       cpv.position(glog, module, layer + 1, r1, rot);
1122 
1123 #ifdef EDM_ML_DEBUG
1124       edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << glog.name() << " number " << layer + 1
1125                                    << " positioned in " << module.name() << " at " << r1 << " with " << rot;
1126 #endif
1127 
1128       //Now the plastic with scintillators
1129       double yh = 0.5 * (routF - rinB) - getTrim(mod, iphi);
1130       double bl = 0.5 * rinB * tan(alpha) - getTrim(mod, iphi);
1131       double tl = 0.5 * routF * tan(alpha) - getTrim(mod, iphi);
1132       name = module.name().name() + getLayerName(layer) + getPhiName(iphi);
1133       solid = DDSolidFactory::trap(
1134           DDName(name, idNameSpace), 0.5 * getLayerT(layer), 0, 0, yh, bl, tl, alp, yh, bl, tl, alp);
1135 
1136 #ifdef EDM_ML_DEBUG
1137       edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << solid.name() << " Trap made of " << getPlastMat()
1138                                    << " of dimensions " << 0.5 * getLayerT(layer) << ", 0, 0, " << yh << ", " << bl
1139                                    << ", " << tl << ", " << convertRadToDeg(alp) << ", " << yh << ", " << bl << ", "
1140                                    << tl << ", " << convertRadToDeg(alp);
1141 #endif
1142 
1143       plog = DDLogicalPart(solid.ddname(), matplastic, solid);
1144 
1145       ypos = 0.5 * (routF + rinB) - xpos;
1146       DDTranslation r2(0., ypos, 0.);
1147       cpv.position(plog, glog, idOffset + layer + 1, r2, DDRotation());
1148 
1149 #ifdef EDM_ML_DEBUG
1150       edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << plog.name() << " number " << idOffset + layer + 1
1151                                    << " positioned in " << glog.name() << " at " << r2 << " with no rotation";
1152 #endif
1153 
1154       //Constructin the scintillators inside
1155       int copyNo = layer * 10 + getLayerType(layer);
1156       name = getModName(mod) + getLayerName(layer) + getPhiName(iphi);
1157       constructScintLayer(plog, getScintT(layer), yh, bl, tl, alp, name, copyNo, cpv);
1158       zo += 0.5 * getDzStep();
1159     }  // End of loop over phi indices
1160     zi = zo - 0.5 * getDzStep();
1161   }  // End of loop on layers
1162 }
1163 
1164 void DDHCalEndcapAlgo::constructScintLayer(const DDLogicalPart& detector,
1165                                            double dz,
1166                                            double yh,
1167                                            double bl,
1168                                            double tl,
1169                                            double alp,
1170                                            const std::string& nm,
1171                                            int id,
1172                                            DDCompactView& cpv) {
1173   DDName matname(DDSplit(getScintMat()).first, DDSplit(getScintMat()).second);
1174   DDMaterial matter(matname);
1175   std::string name = idName + "Scintillator" + nm;
1176 
1177   DDSolid solid = DDSolidFactory::trap(DDName(name, idNameSpace), 0.5 * dz, 0, 0, yh, bl, tl, alp, yh, bl, tl, alp);
1178 
1179 #ifdef EDM_ML_DEBUG
1180   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << DDName(name, idNameSpace) << " Trap made of " << getScintMat()
1181                                << " of dimensions " << 0.5 * dz << ", 0, 0, " << yh << ", " << bl << ", " << tl << ", "
1182                                << convertRadToDeg(alp) << ", " << yh << ", " << bl << ", " << tl << ", "
1183                                << convertRadToDeg(alp);
1184 #endif
1185 
1186   DDLogicalPart glog(solid.ddname(), matter, solid);
1187 
1188   cpv.position(glog, detector, id, DDTranslation(0, 0, 0), DDRotation());
1189 
1190 #ifdef EDM_ML_DEBUG
1191   edm::LogVerbatim("HCalGeom") << "DDHCalEndcapAlgo: " << glog.name() << " number " << id << " positioned in "
1192                                << detector.name() << " at (0,0,0) with no rotation";
1193 #endif
1194 }
1195 
1196 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDHCalEndcapAlgo, "hcal:DDHCalEndcapAlgo");