Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-25 02:44:37

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // File: DDHGCalPassive.cc
0003 // Description: Geometry factory class for the passive part of a full silicon
0004 //              module
0005 // Created by Sunanda Banerjee
0006 ///////////////////////////////////////////////////////////////////////////////
0007 
0008 #include <string>
0009 #include <vector>
0010 #include <sstream>
0011 
0012 #include "DD4hep/DetFactoryHelper.h"
0013 #include "DataFormats/Math/interface/angle_units.h"
0014 #include "DetectorDescription/DDCMS/interface/DDPlugins.h"
0015 #include "DetectorDescription/DDCMS/interface/DDutils.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017 #include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h"
0018 
0019 //#define EDM_ML_DEBUG
0020 using namespace angle_units::operators;
0021 
0022 struct HGCalPassive {
0023   HGCalPassive() { throw cms::Exception("HGCalGeom") << "Wrong initialization to HGCalPassive"; }
0024   HGCalPassive(cms::DDParsingContext& ctxt, xml_h e) {
0025     cms::DDNamespace ns(ctxt, e, true);
0026     cms::DDAlgoArguments args(ctxt, e);
0027 #ifdef EDM_ML_DEBUG
0028     edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: Creating an instance";
0029 #endif
0030     std::string parentName = args.parentName();
0031     std::string material = args.value<std::string>("ModuleMaterial");  // Material name for mother volume
0032     double thick = args.value<double>("Thickness");                    // Thickness of the section
0033     double zMinBlock = args.value<double>("zMinBlock");                // z-position of the first layer
0034     double moduleThick = args.value<double>("ModuleThick");            // Thickness of the overall module
0035     std::vector<std::string> tagLayer =
0036         args.value<std::vector<std::string>>("TagLayer");  // Tag of the layer (to be added to name)
0037     std::vector<std::string> tagSector =
0038         args.value<std::vector<std::string>>("TagSector");  // Tag of the sector (to be added to name)
0039     int parts = args.value<int>("Parts");                   // number of parts in units of 30 degree
0040     double phi0 = args.value<double>("PhiStart");           // Start phi of the first cassette
0041     double dphi = (2._pi) / tagSector.size();               // delta phi of the cassette
0042 #ifdef EDM_ML_DEBUG
0043     edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << tagLayer.size() << " Modules with base name " << parentName
0044                                   << " made of " << material << " T " << thick << " Sectors " << tagSector.size()
0045                                   << " Parts " << parts << " phi0 " << convertRadToDeg(phi0);
0046     for (unsigned int i = 0; i < tagLayer.size(); ++i)
0047       edm::LogVerbatim("HGCalGeom") << "Layer " << i << " Tag " << tagLayer[i] << " T " << moduleThick;
0048     for (unsigned int i = 0; i < tagSector.size(); ++i)
0049       edm::LogVerbatim("HGCalGeom") << "Sector " << i << " Tag " << tagSector[i] << " W " << convertRadToDeg(dphi);
0050 #endif
0051     std::vector<std::string> layerNames = args.value<std::vector<std::string>>("LayerNames");  // Names of the layers
0052     std::vector<std::string> materials =
0053         args.value<std::vector<std::string>>("LayerMaterials");                          // Materials of the layers
0054     std::vector<double> layerThick = args.value<std::vector<double>>("LayerThickness");  // Thickness of layers
0055 #ifdef EDM_ML_DEBUG
0056     edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << layerNames.size() << " types of volumes";
0057     for (unsigned int i = 0; i < layerNames.size(); ++i)
0058       edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << layerNames[i] << " of thickness " << layerThick[i]
0059                                     << " filled with " << materials[i];
0060 #endif
0061 
0062     std::vector<int> layerType = args.value<std::vector<int>>("LayerType");  // Layer types
0063 #ifdef EDM_ML_DEBUG
0064     std::ostringstream st1;
0065     for (unsigned int i = 0; i < layerType.size(); ++i)
0066       st1 << " [" << i << "] " << layerType[i];
0067     edm::LogVerbatim("HGCalGeom") << "There are " << layerType.size() << " blocks" << st1.str();
0068 #endif
0069 
0070     double shiftTop = args.value<double>("ShiftTop");     // Tolerance at the top
0071     double shiftBot = args.value<double>("ShiftBottom");  // Tolerance at the bottom
0072 #ifdef EDM_ML_DEBUG
0073     edm::LogVerbatim("HGCalGeom") << "Shifts st the top " << shiftTop << " and at the bottom " << shiftBot;
0074 #endif
0075 
0076     std::vector<double> slopeB = args.value<std::vector<double>>("SlopeBottom");    // Slope at the lower R
0077     std::vector<double> zFrontB = args.value<std::vector<double>>("ZFrontBottom");  // Starting Z values for the slopes
0078     std::vector<double> rMinFront = args.value<std::vector<double>>("RMinFront");   // Corresponding rMin's
0079     std::vector<double> slopeT = args.value<std::vector<double>>("SlopeTop");       // Slopes at the larger R
0080     std::vector<double> zFrontT = args.value<std::vector<double>>("ZFrontTop");     // Starting Z values for the slopes
0081     std::vector<double> rMaxFront = args.value<std::vector<double>>("RMaxFront");   // Corresponding rMax's
0082 #ifdef EDM_ML_DEBUG
0083     for (unsigned int i = 0; i < slopeB.size(); ++i)
0084       edm::LogVerbatim("HGCalGeom") << "Bottom Block [" << i << "] Zmin " << zFrontB[i] << " Rmin " << rMinFront[i]
0085                                     << " Slope " << slopeB[i];
0086     for (unsigned int i = 0; i < slopeT.size(); ++i)
0087       edm::LogVerbatim("HGCalGeom") << "Top Block [" << i << "] Zmin " << zFrontT[i] << " Rmax " << rMaxFront[i]
0088                                     << " Slope " << slopeT[i];
0089 
0090     edm::LogVerbatim("HGCalGeom") << "==>> Executing DDHGCalPassive...";
0091 #endif
0092 
0093     static constexpr double tol = 0.00001;
0094 
0095     // Loop over Layers
0096     double zim(zMinBlock);
0097     //Loop over layers
0098     for (unsigned int j = 0; j < tagLayer.size(); ++j) {
0099       double routF = HGCalGeomTools::radius(zim, zFrontT, rMaxFront, slopeT) - shiftTop;
0100       double zo = zim + moduleThick;
0101       double rinB = HGCalGeomTools::radius(zo, zFrontB, rMinFront, slopeB) + shiftBot;
0102       zim += moduleThick;
0103       for (unsigned int k = 0; k < tagSector.size(); ++k) {
0104         std::string parentName = args.parentName() + tagLayer[j] + tagSector[k];
0105         double phi1 = phi0 + k * dphi;
0106         double phi2 = phi1 + dphi;
0107         double phi0 = phi1 + 0.5 * dphi;
0108         // First the mother
0109         std::vector<double> xM, yM;
0110         if (parts == 1) {
0111           xM = {rinB * cos(phi1), routF * cos(phi1), routF * cos(phi2), rinB * cos(phi2)};
0112           yM = {rinB * sin(phi1), routF * sin(phi1), routF * sin(phi2), rinB * sin(phi2)};
0113         } else {
0114           // workaround for https://github.com/cms-sw/cmssw/issues/44931#issuecomment-2134850535
0115           std::vector<double> xTmp = {rinB * cos(phi1),
0116                                       routF * cos(phi1),
0117                                       routF * cos(phi0),
0118                                       routF * cos(phi2),
0119                                       rinB * cos(phi2),
0120                                       rinB * cos(phi0)};
0121           std::vector<double> yTmp = {rinB * sin(phi1),
0122                                       routF * sin(phi1),
0123                                       routF * sin(phi0),
0124                                       routF * sin(phi2),
0125                                       rinB * sin(phi2),
0126                                       rinB * sin(phi0)};
0127           xM = std::move(xTmp);
0128           yM = std::move(yTmp);
0129         }
0130         std::vector<double> zw = {-0.5 * thick, 0.5 * thick};
0131         std::vector<double> zx(2, 0), zy(2, 0), scale(2, 1.0);
0132         dd4hep::Solid solid = dd4hep::ExtrudedPolygon(xM, yM, zw, zx, zy, scale);
0133         ns.addSolidNS(ns.prepend(parentName), solid);
0134         dd4hep::Material matter = ns.material(material);
0135         dd4hep::Volume glogM = dd4hep::Volume(solid.name(), solid, matter);
0136 #ifdef EDM_ML_DEBUG
0137         edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << solid.name() << " extruded polygon made of "
0138                                       << matter.name() << " z|x|y|s (0) " << zw[0] << ":" << zx[0] << ":" << zy[0]
0139                                       << ":" << scale[0] << " z|x|y|s (1) " << zw[1] << ":" << zx[1] << ":" << zy[1]
0140                                       << ":" << scale[1] << " and " << xM.size() << " edges";
0141         for (unsigned int kk = 0; kk < xM.size(); ++kk)
0142           edm::LogVerbatim("HGCalGeom") << "[" << kk << "] " << xM[kk] << ":" << yM[kk];
0143 #endif
0144 
0145         // Then the layers
0146         std::vector<dd4hep::Volume> glogs(materials.size());
0147         std::vector<int> copyNumber(materials.size(), 1);
0148         double zi(-0.5 * thick), thickTot(0.0);
0149         for (unsigned int l = 0; l < layerType.size(); l++) {
0150           unsigned int i = layerType[l];
0151           if (copyNumber[i] == 1) {
0152             zw[0] = -0.5 * layerThick[i];
0153             zw[1] = 0.5 * layerThick[i];
0154             std::string layerName = parentName + layerNames[i];
0155             solid = dd4hep::ExtrudedPolygon(xM, yM, zw, zx, zy, scale);
0156             ns.addSolidNS(ns.prepend(layerName), solid);
0157             dd4hep::Material matter = ns.material(materials[i]);
0158             glogs[i] = dd4hep::Volume(solid.name(), solid, matter);
0159 #ifdef EDM_ML_DEBUG
0160             edm::LogVerbatim("HGCalGeom")
0161                 << "DDHGCalPassive: Layer " << i << ":" << l << ":" << solid.name() << " extruded polygon made of "
0162                 << matter.name() << " z|x|y|s (0) " << zw[0] << ":" << zx[0] << ":" << zy[0] << ":" << scale[0]
0163                 << " z|x|y|s (1) " << zw[1] << ":" << zx[1] << ":" << zy[1] << ":" << scale[1] << " and " << xM.size()
0164                 << " edges";
0165             for (unsigned int kk = 0; kk < xM.size(); ++kk)
0166               edm::LogVerbatim("HGCalGeom") << "[" << kk << "] " << xM[kk] << ":" << yM[kk];
0167 #endif
0168           }
0169           dd4hep::Position tran0(0, 0, (zi + 0.5 * layerThick[i]));
0170           glogM.placeVolume(glogs[i], copyNumber[i], tran0);
0171 #ifdef EDM_ML_DEBUG
0172           edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << glogs[i].name() << " number " << copyNumber[i]
0173                                         << " positioned in " << glogM.name() << " at (0, 0, "
0174                                         << cms::convert2mm(zi + 0.5 * layerThick[i]) << ") with no rotation";
0175 #endif
0176           ++copyNumber[i];
0177           zi += layerThick[i];
0178           thickTot += layerThick[i];
0179         }
0180         if ((std::abs(thickTot - thick) >= tol) && (!layerType.empty())) {
0181           if (thickTot > thick) {
0182             edm::LogError("HGCalGeom") << "Thickness of the partition " << thick << " is smaller than " << thickTot
0183                                        << ": thickness of all its components **** ERROR ****";
0184           } else {
0185             edm::LogWarning("HGCalGeom") << "Thickness of the partition " << thick << " does not match with "
0186                                          << thickTot << " of the components";
0187           }
0188         }
0189       }
0190     }
0191   }
0192 };
0193 
0194 static long algorithm(dd4hep::Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
0195   HGCalPassive passiveAlgo(ctxt, e);
0196   return cms::s_executed;
0197 }
0198 
0199 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalPassive, algorithm)