Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:14:57

0001 /*
0002  * DDHGCalTBModuleX.cc
0003  *
0004  *  Created on: 27-Aug-2019
0005  *      Author: S. Banerjee
0006  */
0007 
0008 #include <unordered_set>
0009 
0010 #include "DataFormats/Math/interface/angle_units.h"
0011 #include "DD4hep/DetFactoryHelper.h"
0012 #include "DetectorDescription/Core/interface/DDSplit.h"
0013 #include "DetectorDescription/DDCMS/interface/DDPlugins.h"
0014 #include "DetectorDescription/DDCMS/interface/DDutils.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/Utilities/interface/Exception.h"
0017 #include "Geometry/HGCalCommonData/interface/HGCalTypes.h"
0018 
0019 //#define EDM_ML_DEBUG
0020 using namespace angle_units::operators;
0021 
0022 namespace DDHGCalGeom {
0023   void constructLayers(const cms::DDNamespace& ns,
0024                        const std::vector<std::string>& wafers,
0025                        const std::vector<std::string>& covers,
0026                        const std::vector<int>& layerType,
0027                        const std::vector<int>& layerSense,
0028                        const std::vector<int>& maxModule,
0029                        const std::vector<std::string>& names,
0030                        const std::vector<std::string>& materials,
0031                        std::vector<int>& copyNumber,
0032                        const std::vector<double>& layerThick,
0033                        const double& absorbW,
0034                        const double& absorbH,
0035                        const double& waferTot,
0036                        const double& rMax,
0037                        const double& rMaxFine,
0038                        std::unordered_set<int>& copies,
0039                        int firstLayer,
0040                        int lastLayer,
0041                        double zFront,
0042                        double totalWidth,
0043                        bool ignoreCenter,
0044                        dd4hep::Volume& module) {
0045     static constexpr double tolerance = 0.00001 * dd4hep::mm;
0046     static const double tan30deg = tan(30._deg);
0047     double zi(zFront), thickTot(0);
0048     for (int ly = firstLayer; ly <= lastLayer; ++ly) {
0049       int ii = layerType[ly];
0050       int copy = copyNumber[ii];
0051       double zz = zi + (0.5 * layerThick[ii]);
0052       double zo = zi + layerThick[ii];
0053       thickTot += layerThick[ii];
0054 
0055       std::string name = "HGCal" + names[ii] + std::to_string(copy);
0056 #ifdef EDM_ML_DEBUG
0057       edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " Layer " << ly << ":" << ii << " Z "
0058                                     << cms::convert2mm(zi) << ":" << cms::convert2mm(zo) << " Thick "
0059                                     << cms::convert2mm(layerThick[ii]) << " Sense " << layerSense[ly];
0060 #endif
0061       dd4hep::Material matter = ns.material(materials[ii]);
0062       dd4hep::Volume glog;
0063       if (layerSense[ly] == 0) {
0064         dd4hep::Solid solid = dd4hep::Box(absorbW, absorbH, 0.5 * layerThick[ii]);
0065         ns.addSolidNS(ns.prepend(name), solid);
0066         glog = dd4hep::Volume(solid.name(), solid, matter);
0067 #ifdef EDM_ML_DEBUG
0068         edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << solid.name() << " box of dimension "
0069                                       << cms::convert2mm(absorbW) << ":" << cms::convert2mm(absorbH) << ":"
0070                                       << cms::convert2mm(0.5 * layerThick[ii]);
0071 #endif
0072         dd4hep::Position r1(0, 0, zz);
0073         module.placeVolume(glog, copy, r1);
0074 #ifdef EDM_ML_DEBUG
0075         edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << copy << " positioned in "
0076                                       << module.name() << " at (0,0," << cms::convert2mm(zz) << ") with no rotation";
0077 #endif
0078       } else if (layerSense[ly] > 0) {
0079         double dx = 0.5 * waferTot;
0080         double dy = 3.0 * dx * tan30deg;
0081         double rr = 2.0 * dx * tan30deg;
0082         int ncol = (int)(2.0 * rMax / waferTot) + 1;
0083         int nrow = (int)(rMax / (waferTot * tan30deg)) + 1;
0084 #ifdef EDM_ML_DEBUG
0085         int incm(0), inrm(0);
0086         edm::LogVerbatim("HGCalGeom") << module.name() << " Copy " << copy << " Type " << layerSense[ly] << " rout "
0087                                       << cms::convert2mm(rMax) << " Row " << nrow << " column " << ncol << " ncrMax "
0088                                       << maxModule[ly] << " Z " << cms::convert2mm(zz) << " Center " << ignoreCenter
0089                                       << " name " << name << " matter " << matter.name();
0090         int kount(0);
0091 #endif
0092         if (maxModule[ly] >= 0) {
0093           nrow = std::min(nrow, maxModule[ly]);
0094           ncol = std::min(ncol, maxModule[ly]);
0095         }
0096         for (int nr = -nrow; nr <= nrow; ++nr) {
0097           int inr = std::abs(nr);
0098           for (int nc = -ncol; nc <= ncol; ++nc) {
0099             int inc = std::abs(nc);
0100             if ((inr % 2 == inc % 2) && (!ignoreCenter || nc != 0 || nr != 0)) {
0101               double xpos = nc * dx;
0102               double ypos = nr * dy;
0103               double xc[6], yc[6];
0104               xc[0] = xpos + dx;
0105               yc[0] = ypos - 0.5 * rr;
0106               xc[1] = xpos + dx;
0107               yc[1] = ypos + 0.5 * rr;
0108               xc[2] = xpos;
0109               yc[2] = ypos + rr;
0110               xc[3] = xpos - dx;
0111               yc[3] = ypos + 0.5 * rr;
0112               xc[4] = xpos + dx;
0113               yc[4] = ypos - 0.5 * rr;
0114               xc[5] = xpos;
0115               yc[5] = ypos - rr;
0116               bool cornerAll(true);
0117               for (int k = 0; k < 6; ++k) {
0118                 double rpos = std::sqrt(xc[k] * xc[k] + yc[k] * yc[k]);
0119                 if (rpos > rMax)
0120                   cornerAll = false;
0121               }
0122               if (cornerAll) {
0123                 double rpos = std::sqrt(xpos * xpos + ypos * ypos);
0124                 dd4hep::Position tran(xpos, ypos, zz);
0125                 int copyx = HGCalTypes::packTypeUV(0, nc, nr);
0126                 if (layerSense[ly] == 1) {
0127                   dd4hep::Solid solid = ns.solid(covers[0]);
0128                   std::string name0 = name + "M" + std::to_string(copyx);
0129                   name0 = ns.prepend(name0);
0130                   dd4hep::Volume glog1 = dd4hep::Volume(name0, solid, matter);
0131                   module.placeVolume(glog1, copy, tran);
0132 #ifdef EDM_ML_DEBUG
0133                   edm::LogVerbatim("HGCalGeom")
0134                       << "DDHGCalTBModuleX: " << glog1.name() << " number " << copy << " positioned in "
0135                       << module.name() << " at (" << cms::convert2mm(xpos) << "," << cms::convert2mm(ypos) << ","
0136                       << cms::convert2mm(zz) << ") with no rotation";
0137 #endif
0138                   dd4hep::Volume glog2 = (rpos < rMaxFine) ? ns.volume(wafers[0]) : ns.volume(wafers[1]);
0139                   glog1.placeVolume(glog2, copyx);
0140 #ifdef EDM_ML_DEBUG
0141                   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog2.name() << " number " << copyx
0142                                                 << " positioned in " << glog1.name() << " at (0,0,0) with no rotation";
0143 #endif
0144                   if (layerSense[ly] == 1)
0145                     copies.insert(copy);
0146                 } else {
0147                   dd4hep::Volume glog2 = ns.volume(covers[layerSense[ly] - 1]);
0148                   copyx += (copy * 1000000);
0149                   module.placeVolume(glog2, copyx, tran);
0150 #ifdef EDM_ML_DEBUG
0151                   edm::LogVerbatim("HGCalGeom")
0152                       << "DDHGCalTBModuleX: " << glog2.name() << " number " << copyx << " positioned in "
0153                       << module.name() << " at (" << cms::convert2mm(xpos) << "," << cms::convert2mm(ypos) << ","
0154                       << cms::convert2mm(zz) << ") with no rotation";
0155 #endif
0156                 }
0157 #ifdef EDM_ML_DEBUG
0158                 if (inc > incm)
0159                   incm = inc;
0160                 if (inr > inrm)
0161                   inrm = inr;
0162                 kount++;
0163 #endif
0164               }
0165             }
0166           }
0167         }
0168 #ifdef EDM_ML_DEBUG
0169         edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: # of columns " << incm << " # of rows " << inrm << " and "
0170                                       << kount << " wafers for " << module.name();
0171 #endif
0172       }
0173       ++copyNumber[ii];
0174       zi = zo;
0175     }  // End of loop over layers in a block
0176 
0177     if (fabs(thickTot - totalWidth) > tolerance) {
0178       if (thickTot > totalWidth) {
0179         edm::LogError("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(totalWidth)
0180                                    << " is smaller than " << cms::convert2mm(thickTot)
0181                                    << ": total thickness of all its components in " << module.name() << " Layers "
0182                                    << firstLayer << ":" << lastLayer << ":" << ignoreCenter << "**** ERROR ****";
0183       } else {
0184         edm::LogWarning("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(totalWidth)
0185                                      << " does not match with " << cms::convert2mm(thickTot) << " of the components in "
0186                                      << module.name() << " Layers " << firstLayer << ":" << lastLayer << ":"
0187                                      << ignoreCenter;
0188       }
0189     }
0190   }
0191 }  // namespace DDHGCalGeom
0192 
0193 static long algorithm(dd4hep::Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
0194   cms::DDNamespace ns(ctxt, e, true);
0195   cms::DDAlgoArguments args(ctxt, e);
0196 
0197   const auto& wafers = args.value<std::vector<std::string> >("WaferName");  // Wafers
0198   const auto& covers = args.value<std::vector<std::string> >("CoverName");  // Insensitive layers of hexagonal size
0199   const auto& genMat = args.value<std::string>("GeneralMaterial");          // General material used for blocks
0200 #ifdef EDM_ML_DEBUG
0201   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Material " << genMat << " with " << wafers.size() << " wafers";
0202   unsigned int i(0);
0203   for (auto wafer : wafers) {
0204     edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafer;
0205     ++i;
0206   }
0207   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << covers.size() << " covers";
0208   i = 0;
0209   for (auto cover : covers) {
0210     edm::LogVerbatim("HGCalGeom") << "Cover[" << i << "] " << cover;
0211     ++i;
0212   }
0213 #endif
0214   const auto& materials = args.value<std::vector<std::string> >("MaterialNames");  // Material names in each layer
0215   const auto& names = args.value<std::vector<std::string> >("VolumeNames");        // Names of each layer
0216   const auto& layerThick = args.value<std::vector<double> >("Thickness");          // Thickness of the material
0217   std::vector<int> copyNumber;                                                     // Copy numbers (initiated to 1)
0218   copyNumber.resize(materials.size(), 1);
0219 #ifdef EDM_ML_DEBUG
0220   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << materials.size() << " types of volumes";
0221   for (unsigned int i = 0; i < names.size(); ++i)
0222     edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names[i] << " of thickness "
0223                                   << cms::convert2mm(layerThick[i]) << " filled with " << materials[i]
0224                                   << " first copy number " << copyNumber[i];
0225 #endif
0226   const auto& blockThick = args.value<std::vector<double> >("BlockThick");   // Thickness of each section
0227   const auto& inOut = args.value<int>("InOut");                              // Number of inner+outer parts
0228   const auto& layerFrontIn = args.value<std::vector<int> >("LayerFrontIn");  // First layer index (inner) in block
0229   const auto& layerBackIn = args.value<std::vector<int> >("LayerBackIn");    // Last layer index (inner) in block
0230   std::vector<int> layerFrontOut;                                            // First layer index (outner) in block
0231   std::vector<int> layerBackOut;                                             // Last layer index (outner) in block
0232   if (inOut > 1) {
0233     layerFrontOut = args.value<std::vector<int> >("LayerFrontOut");
0234     layerBackOut = args.value<std::vector<int> >("LayerBackOut");
0235   }
0236 #ifdef EDM_ML_DEBUG
0237   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << blockThick.size() << " blocks with in/out " << inOut;
0238   for (unsigned int i = 0; i < blockThick.size(); ++i) {
0239     if (inOut > 1)
0240       edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << cms::convert2mm(blockThick[i])
0241                                     << " with inner layers " << layerFrontIn[i] << ":" << layerBackIn[i]
0242                                     << " and outer layers " << layerFrontOut[i] << ":" << layerBackOut[i];
0243     else
0244       edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << cms::convert2mm(blockThick[i])
0245                                     << " with inner layers " << layerFrontIn[i] << ":" << layerBackIn[i];
0246   }
0247 #endif
0248   const auto& layerType = args.value<std::vector<int> >("LayerType");    // Type of the layer
0249   const auto& layerSense = args.value<std::vector<int> >("LayerSense");  // Content of a layer
0250   const auto& maxModule = args.value<std::vector<int> >("MaxModule");    // Maximum # of row/column
0251 #ifdef EDM_ML_DEBUG
0252   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << layerType.size() << " layers";
0253   for (unsigned int i = 0; i < layerType.size(); ++i)
0254     edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType[i] << " sensitive class "
0255                                   << layerSense[i] << " and " << maxModule[i] << " maximum row/columns";
0256 #endif
0257   const auto& zMinBlock = args.value<double>("zMinBlock");  // Starting z-value of the block
0258   const auto& rMaxFine = args.value<double>("rMaxFine");    // Maximum r-value for fine wafer
0259   const auto& waferW = args.value<double>("waferW");        // Width of the wafer
0260   const auto& waferGap = args.value<double>("waferGap");    // Gap between 2 wafers
0261   const auto& absorbW = args.value<double>("absorberW");    // Width of the absorber
0262   const auto& absorbH = args.value<double>("absorberH");    // Height of the absorber
0263   const auto& rMax = args.value<double>("rMax");            // Maximum radial extent
0264   const auto& rMaxB = args.value<double>("rMaxB");          // Maximum radial extent of a block
0265   double waferTot = waferW + waferGap;
0266   std::string idName = DDSplit(args.parentName()).first;
0267 #ifdef EDM_ML_DEBUG
0268   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: zStart " << cms::convert2mm(zMinBlock) << " rFineCoarse "
0269                                 << cms::convert2mm(rMaxFine) << " wafer width " << cms::convert2mm(waferW)
0270                                 << " gap among wafers " << cms::convert2mm(waferGap) << " absorber width "
0271                                 << cms::convert2mm(absorbW) << " absorber height " << cms::convert2mm(absorbH)
0272                                 << " rMax " << cms::convert2mm(rMax) << ":" << cms::convert2mm(rMaxB);
0273   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: NameSpace " << ns.name() << " Parent Name " << idName;
0274 #endif
0275   std::unordered_set<int> copies;  // List of copy #'s
0276   copies.clear();
0277 
0278   dd4hep::Volume parent = ns.volume(args.parentName());
0279   double zi(zMinBlock);
0280   for (unsigned int i = 0; i < blockThick.size(); i++) {
0281     double zo = zi + blockThick[i];
0282     std::string name = idName + "Block" + std::to_string(i);
0283 #ifdef EDM_ML_DEBUG
0284     edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Block " << i << ":" << name << " z " << cms::convert2mm(zi)
0285                                   << ":" << cms::convert2mm(zo) << " R " << cms::convert2mm(rMaxB) << " T "
0286                                   << cms::convert2mm(blockThick[i]);
0287 #endif
0288     dd4hep::Material matter = ns.material(genMat);
0289     dd4hep::Solid solid = dd4hep::Tube(0, rMaxB, 0.5 * blockThick[i], 0.0, 2._pi);
0290     ns.addSolidNS(ns.prepend(name), solid);
0291     dd4hep::Volume glog = dd4hep::Volume(solid.name(), solid, matter);
0292     double zz = zi + 0.5 * blockThick[i];
0293     dd4hep::Position r1(0, 0, zz);
0294     parent.placeVolume(glog, i, r1);
0295 #ifdef EDM_ML_DEBUG
0296     edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << i << " positioned in "
0297                                   << args.parentName() << " at (0,0," << cms::convert2mm(zz) << ") with no rotation";
0298     edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: \t\tInside Block " << i << " Layers " << layerFrontIn[i] << ":"
0299                                   << layerBackIn[i] << " zFront " << -cms::convert2mm(0.5 * blockThick[i])
0300                                   << " thickness " << cms::convert2mm(blockThick[i]) << " ignore Center 0";
0301 #endif
0302     DDHGCalGeom::constructLayers(ns,
0303                                  wafers,
0304                                  covers,
0305                                  layerType,
0306                                  layerSense,
0307                                  maxModule,
0308                                  names,
0309                                  materials,
0310                                  copyNumber,
0311                                  layerThick,
0312                                  absorbW,
0313                                  absorbH,
0314                                  waferTot,
0315                                  rMax,
0316                                  rMaxFine,
0317                                  copies,
0318                                  layerFrontIn[i],
0319                                  layerBackIn[i],
0320                                  -0.5 * blockThick[i],
0321                                  blockThick[i],
0322                                  false,
0323                                  glog);
0324     if (inOut > 1) {
0325 #ifdef EDM_ML_DEBUG
0326       edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: \t\tInside Block " << i << " Layers " << layerFrontOut[i]
0327                                     << ":" << layerBackOut[i] << " zFront " << -cms::convert2mm(0.5 * blockThick[i])
0328                                     << " thickness " << cms::convert2mm(blockThick[i]) << " ignore Center 1";
0329 #endif
0330       DDHGCalGeom::constructLayers(ns,
0331                                    wafers,
0332                                    covers,
0333                                    layerType,
0334                                    layerSense,
0335                                    maxModule,
0336                                    names,
0337                                    materials,
0338                                    copyNumber,
0339                                    layerThick,
0340                                    absorbW,
0341                                    absorbH,
0342                                    waferTot,
0343                                    rMax,
0344                                    rMaxFine,
0345                                    copies,
0346                                    layerFrontOut[i],
0347                                    layerBackOut[i],
0348                                    -0.5 * blockThick[i],
0349                                    blockThick[i],
0350                                    true,
0351                                    glog);
0352     }
0353     zi = zo;
0354   }
0355 #ifdef EDM_ML_DEBUG
0356   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: All blocks are placed in " << cms::convert2mm(zMinBlock) << ":"
0357                                 << cms::convert2mm(zi) << " with " << copies.size() << " different wafer copy numbers";
0358 #endif
0359 
0360   return cms::s_executed;
0361 }
0362 
0363 // first argument is the type from the xml file
0364 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalTBModuleX, algorithm)