Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:15:01

0001 #include <algorithm>
0002 #include <cmath>
0003 #include <string>
0004 #include <unordered_set>
0005 #include <vector>
0006 
0007 #include "DataFormats/Math/interface/angle_units.h"
0008 #include "DetectorDescription/Core/interface/DDAlgorithm.h"
0009 #include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"
0010 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0011 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0012 #include "DetectorDescription/Core/interface/DDMaterial.h"
0013 #include "DetectorDescription/Core/interface/DDSolid.h"
0014 #include "DetectorDescription/Core/interface/DDSplit.h"
0015 #include "DetectorDescription/Core/interface/DDTypes.h"
0016 #include "DetectorDescription/Core/interface/DDutils.h"
0017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0018 #include "FWCore/PluginManager/interface/PluginFactory.h"
0019 #include "Geometry/HGCalCommonData/interface/HGCalTypes.h"
0020 
0021 //#define EDM_ML_DEBUG
0022 using namespace angle_units::operators;
0023 
0024 class DDHGCalTBModuleX : public DDAlgorithm {
0025 public:
0026   // Constructor and Destructor
0027   DDHGCalTBModuleX();  //
0028   ~DDHGCalTBModuleX() override;
0029 
0030   void initialize(const DDNumericArguments& nArgs,
0031                   const DDVectorArguments& vArgs,
0032                   const DDMapArguments& mArgs,
0033                   const DDStringArguments& sArgs,
0034                   const DDStringVectorArguments& vsArgs) override;
0035   void execute(DDCompactView& cpv) override;
0036 
0037 protected:
0038   void constructBlocks(const DDLogicalPart&, DDCompactView& cpv);
0039   void constructLayers(int block,
0040                        int layerFront,
0041                        int layerBack,
0042                        double zFront,
0043                        double thick,
0044                        bool ignore,
0045                        const DDLogicalPart&,
0046                        DDCompactView&);
0047   void positionSensitive(double zpos,
0048                          int copyIn,
0049                          int type,
0050                          double rmax,
0051                          int ncrMax,
0052                          bool ignoreCenter,
0053                          const std::string&,
0054                          const DDMaterial&,
0055                          const DDLogicalPart&,
0056                          DDCompactView& cpv);
0057 
0058 private:
0059   static constexpr double tolerance_ = 0.00001;
0060   const double factor_, tan30deg_;
0061 
0062   std::vector<std::string> wafer_;      // Wafers
0063   std::vector<std::string> covers_;     // Insensitive layers of hexagonal size
0064   std::string genMat_;                  // General material used for blocks
0065   std::vector<std::string> materials_;  // Material names in each layer
0066   std::vector<std::string> names_;      // Names of each layer
0067   std::vector<double> layerThick_;      // Thickness of the material
0068   std::vector<int> copyNumber_;         // Copy numbers (initiated to 1)
0069   std::vector<double> blockThick_;      // Thickness of each section
0070   int inOut_;                           // Number of inner+outer parts
0071   std::vector<int> layerFrontIn_;       // First layer index (inner) in block
0072   std::vector<int> layerBackIn_;        // Last layer index (inner) in block
0073   std::vector<int> layerFrontOut_;      // First layer index (outner) in block
0074   std::vector<int> layerBackOut_;       // Last layer index (outner) in block
0075   std::vector<int> layerType_;          // Type of the layer
0076   std::vector<int> layerSense_;         // Content of a layer
0077   std::vector<int> maxModule_;          // Maximum # of row/column
0078   double zMinBlock_;                    // Starting z-value of the block
0079   double rMaxFine_;                     // Maximum r-value for fine wafer
0080   double waferW_;                       // Width of the wafer
0081   double waferGap_;                     // Gap between 2 wafers
0082   double absorbW_;                      // Width of the absorber
0083   double absorbH_;                      // Height of the absorber
0084   double rMax_;                         // Maximum radial extent
0085   double rMaxB_;                        // Maximum radial extent of a block
0086   std::string idName_;                  // Name of the "parent" volume.
0087   std::string idNameSpace_;             // Namespace of this and ALL sub-parts
0088   std::unordered_set<int> copies_;      // List of copy #'s
0089 };
0090 
0091 DDHGCalTBModuleX::DDHGCalTBModuleX() : factor_(0.5 * sqrt(2.0)), tan30deg_(tan(30._deg)) {
0092 #ifdef EDM_ML_DEBUG
0093   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX info: Creating instance";
0094 #endif
0095 }
0096 
0097 DDHGCalTBModuleX::~DDHGCalTBModuleX() {}
0098 
0099 void DDHGCalTBModuleX::initialize(const DDNumericArguments& nArgs,
0100                                   const DDVectorArguments& vArgs,
0101                                   const DDMapArguments&,
0102                                   const DDStringArguments& sArgs,
0103                                   const DDStringVectorArguments& vsArgs) {
0104   wafer_ = vsArgs["WaferName"];
0105   covers_ = vsArgs["CoverName"];
0106   genMat_ = sArgs["GeneralMaterial"];
0107 #ifdef EDM_ML_DEBUG
0108   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Material " << genMat_ << " with " << wafer_.size() << " wafers";
0109   unsigned int i(0);
0110   for (auto wafer : wafer_) {
0111     edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafer;
0112     ++i;
0113   }
0114   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << covers_.size() << " covers";
0115   i = 0;
0116   for (auto cover : covers_) {
0117     edm::LogVerbatim("HGCalGeom") << "Cover[" << i << "] " << cover;
0118     ++i;
0119   }
0120 #endif
0121   materials_ = vsArgs["MaterialNames"];
0122   names_ = vsArgs["VolumeNames"];
0123   layerThick_ = vArgs["Thickness"];
0124   for (unsigned int k = 0; k < layerThick_.size(); ++k)
0125     copyNumber_.emplace_back(1);
0126 #ifdef EDM_ML_DEBUG
0127   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << materials_.size() << " types of volumes";
0128   for (unsigned int i = 0; i < names_.size(); ++i)
0129     edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names_[i] << " of thickness " << layerThick_[i]
0130                                   << " filled with " << materials_[i] << " first copy number " << copyNumber_[i];
0131 #endif
0132   inOut_ = nArgs["InOut"];
0133   blockThick_ = vArgs["BlockThick"];
0134   layerFrontIn_ = dbl_to_int(vArgs["LayerFrontIn"]);
0135   layerBackIn_ = dbl_to_int(vArgs["LayerBackIn"]);
0136   if (inOut_ > 1) {
0137     layerFrontOut_ = dbl_to_int(vArgs["LayerFrontOut"]);
0138     layerBackOut_ = dbl_to_int(vArgs["LayerBackOut"]);
0139   }
0140 #ifdef EDM_ML_DEBUG
0141   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << blockThick_.size() << " blocks with in/out " << inOut_;
0142   for (unsigned int i = 0; i < blockThick_.size(); ++i) {
0143     if (inOut_ > 1)
0144       edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << blockThick_[i] << " with inner layers "
0145                                     << layerFrontIn_[i] << ":" << layerBackIn_[i] << " and outer layers "
0146                                     << layerFrontOut_[i] << ":" << layerBackOut_[i];
0147     else
0148       edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << blockThick_[i] << " with inner layers "
0149                                     << layerFrontIn_[i] << ":" << layerBackIn_[i];
0150   }
0151 #endif
0152   layerType_ = dbl_to_int(vArgs["LayerType"]);
0153   layerSense_ = dbl_to_int(vArgs["LayerSense"]);
0154   maxModule_ = dbl_to_int(vArgs["MaxModule"]);
0155 #ifdef EDM_ML_DEBUG
0156   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << layerType_.size() << " layers";
0157   for (unsigned int i = 0; i < layerType_.size(); ++i)
0158     edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType_[i] << " sensitive class "
0159                                   << layerSense_[i] << " and " << maxModule_[i] << " maximum row/columns";
0160 #endif
0161   zMinBlock_ = nArgs["zMinBlock"];
0162   rMaxFine_ = nArgs["rMaxFine"];
0163   waferW_ = nArgs["waferW"];
0164   waferGap_ = nArgs["waferGap"];
0165   absorbW_ = nArgs["absorberW"];
0166   absorbH_ = nArgs["absorberH"];
0167   rMax_ = nArgs["rMax"];
0168   rMaxB_ = nArgs["rMaxB"];
0169 #ifdef EDM_ML_DEBUG
0170   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: zStart " << zMinBlock_ << " rFineCoarse " << rMaxFine_
0171                                 << " wafer width " << waferW_ << " gap among wafers " << waferGap_ << " absorber width "
0172                                 << absorbW_ << " absorber height " << absorbH_ << " rMax " << rMax_ << ":" << rMaxB_;
0173 #endif
0174   idNameSpace_ = DDCurrentNamespace::ns();
0175 #ifdef EDM_ML_DEBUG
0176   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: NameSpace " << idNameSpace_ << " Parent Name "
0177                                 << parent().name().name();
0178 #endif
0179 }
0180 
0181 ////////////////////////////////////////////////////////////////////
0182 // DDHGCalTBModuleX methods...
0183 ////////////////////////////////////////////////////////////////////
0184 
0185 void DDHGCalTBModuleX::execute(DDCompactView& cpv) {
0186 #ifdef EDM_ML_DEBUG
0187   edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalTBModuleX...";
0188 #endif
0189   copies_.clear();
0190   constructBlocks(parent(), cpv);
0191 #ifdef EDM_ML_DEBUG
0192   edm::LogVerbatim("HGCalGeom") << copies_.size() << " different wafer copy numbers";
0193 #endif
0194   copies_.clear();
0195 #ifdef EDM_ML_DEBUG
0196   edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalTBModuleX construction";
0197 #endif
0198 }
0199 
0200 void DDHGCalTBModuleX::constructBlocks(const DDLogicalPart& parent, DDCompactView& cpv) {
0201 #ifdef EDM_ML_DEBUG
0202   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Inside constructBlock";
0203 #endif
0204   double zi(zMinBlock_);
0205   for (unsigned int i = 0; i < blockThick_.size(); i++) {
0206     double zo = zi + blockThick_[i];
0207     std::string name = parent.ddname().name() + "Block" + std::to_string(i);
0208 #ifdef EDM_ML_DEBUG
0209     edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Block " << i << ":" << name << " z " << zi << ":" << zo << " R "
0210                                   << rMaxB_ << " T " << blockThick_[i];
0211 #endif
0212     DDName matName(DDSplit(genMat_).first, DDSplit(genMat_).second);
0213     DDMaterial matter(matName);
0214     DDSolid solid = DDSolidFactory::tubs(DDName(name, idNameSpace_), 0.5 * blockThick_[i], 0, rMaxB_, 0.0, 2._pi);
0215     DDLogicalPart glog = DDLogicalPart(solid.ddname(), matter, solid);
0216     double zz = zi + 0.5 * blockThick_[i];
0217     DDTranslation r1(0, 0, zz);
0218     DDRotation rot;
0219     cpv.position(glog, parent, i, r1, rot);
0220 #ifdef EDM_ML_DEBUG
0221     edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << i << " positioned in "
0222                                   << parent.name() << " at " << r1 << " with " << rot;
0223 #endif
0224     constructLayers(i, layerFrontIn_[i], layerBackIn_[i], -0.5 * blockThick_[i], blockThick_[i], false, glog, cpv);
0225     if (inOut_ > 1)
0226       constructLayers(i, layerFrontOut_[i], layerBackOut_[i], -0.5 * blockThick_[i], blockThick_[i], true, glog, cpv);
0227     zi = zo;
0228   }
0229 #ifdef EDM_ML_DEBUG
0230   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: All blocks are "
0231                                 << "placed in " << zMinBlock_ << ":" << zi;
0232 #endif
0233 }
0234 
0235 void DDHGCalTBModuleX::constructLayers(int block,
0236                                        int firstLayer,
0237                                        int lastLayer,
0238                                        double zFront,
0239                                        double totalWidth,
0240                                        bool ignoreCenter,
0241                                        const DDLogicalPart& module,
0242                                        DDCompactView& cpv) {
0243 #ifdef EDM_ML_DEBUG
0244   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: \t\tInside Block " << block << " Layers " << firstLayer << ":"
0245                                 << lastLayer << " zFront " << zFront << " thickness " << totalWidth << " ignore Center "
0246                                 << ignoreCenter;
0247 #endif
0248   double zi(zFront), thickTot(0);
0249   for (int ly = firstLayer; ly <= lastLayer; ++ly) {
0250     int ii = layerType_[ly];
0251     int copy = copyNumber_[ii];
0252     double zz = zi + (0.5 * layerThick_[ii]);
0253     double zo = zi + layerThick_[ii];
0254     thickTot += layerThick_[ii];
0255 
0256     std::string name = "HGCal" + names_[ii] + std::to_string(copy);
0257 #ifdef EDM_ML_DEBUG
0258     edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " Layer " << ly << ":" << ii << " Z " << zi << ":"
0259                                   << zo << " Thick " << layerThick_[ii] << " Sense " << layerSense_[ly];
0260 #endif
0261     DDName matName(DDSplit(materials_[ii]).first, DDSplit(materials_[ii]).second);
0262     DDMaterial matter(matName);
0263     DDLogicalPart glog;
0264     if (layerSense_[ly] == 0) {
0265       DDSolid solid = DDSolidFactory::box(DDName(name, idNameSpace_), absorbW_, absorbH_, 0.5 * layerThick_[ii]);
0266       glog = DDLogicalPart(solid.ddname(), matter, solid);
0267 #ifdef EDM_ML_DEBUG
0268       edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << solid.name() << " box of dimension " << absorbW_ << ":"
0269                                     << absorbH_ << ":" << 0.5 * layerThick_[ii];
0270 #endif
0271       DDTranslation r1(0, 0, zz);
0272       DDRotation rot;
0273       cpv.position(glog, module, copy, r1, rot);
0274 #ifdef EDM_ML_DEBUG
0275       edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << copy << " positioned in "
0276                                     << module.name() << " at " << r1 << " with " << rot;
0277 #endif
0278     } else if (layerSense_[ly] > 0) {
0279       positionSensitive(zz, copy, layerSense_[ly], rMax_, maxModule_[ly], ignoreCenter, name, matter, module, cpv);
0280     }
0281     ++copyNumber_[ii];
0282     zi = zo;
0283   }  // End of loop over layers in a block
0284 
0285   if (fabs(thickTot - totalWidth) < tolerance_) {
0286   } else if (thickTot > totalWidth) {
0287     edm::LogError("HGCalGeom") << "Thickness of the partition " << totalWidth << " is smaller than " << thickTot
0288                                << ": total thickness of all its components in " << module.name() << " Layers "
0289                                << firstLayer << ":" << lastLayer << ":" << ignoreCenter << "**** ERROR ****";
0290   } else if (thickTot < totalWidth) {
0291     edm::LogWarning("HGCalGeom") << "Thickness of the partition " << totalWidth << " does not match with " << thickTot
0292                                  << " of the components in " << module.name() << " Layers " << firstLayer << ":"
0293                                  << lastLayer << ":" << ignoreCenter;
0294   }
0295 }
0296 
0297 void DDHGCalTBModuleX::positionSensitive(double zpos,
0298                                          int copyIn,
0299                                          int type,
0300                                          double rout,
0301                                          int ncrMax,
0302                                          bool ignoreCenter,
0303                                          const std::string& nameIn,
0304                                          const DDMaterial& matter,
0305                                          const DDLogicalPart& glog,
0306                                          DDCompactView& cpv) {
0307   double ww = (waferW_ + waferGap_);
0308   double dx = 0.5 * ww;
0309   double dy = 3.0 * dx * tan30deg_;
0310   double rr = 2.0 * dx * tan30deg_;
0311   int ncol = (int)(2.0 * rout / ww) + 1;
0312   int nrow = (int)(rout / (ww * tan30deg_)) + 1;
0313 #ifdef EDM_ML_DEBUG
0314   int incm(0), inrm(0);
0315   edm::LogVerbatim("HGCalGeom") << glog.ddname() << " Copy " << copyIn << " Type " << type << " rout " << rout
0316                                 << " Row " << nrow << " column " << ncol << " ncrMax " << ncrMax << " Z " << zpos
0317                                 << " Center " << ignoreCenter << " name " << nameIn << " matter " << matter.name();
0318   int kount(0);
0319 #endif
0320   if (ncrMax >= 0) {
0321     nrow = std::min(nrow, ncrMax);
0322     ncol = std::min(ncol, ncrMax);
0323   }
0324   for (int nr = -nrow; nr <= nrow; ++nr) {
0325     int inr = std::abs(nr);
0326     for (int nc = -ncol; nc <= ncol; ++nc) {
0327       int inc = std::abs(nc);
0328       if ((inr % 2 == inc % 2) && (!ignoreCenter || nc != 0 || nr != 0)) {
0329         double xpos = nc * dx;
0330         double ypos = nr * dy;
0331         double xc[6], yc[6];
0332         xc[0] = xpos + dx;
0333         yc[0] = ypos - 0.5 * rr;
0334         xc[1] = xpos + dx;
0335         yc[1] = ypos + 0.5 * rr;
0336         xc[2] = xpos;
0337         yc[2] = ypos + rr;
0338         xc[3] = xpos - dx;
0339         yc[3] = ypos + 0.5 * rr;
0340         xc[4] = xpos + dx;
0341         yc[4] = ypos - 0.5 * rr;
0342         xc[5] = xpos;
0343         yc[5] = ypos - rr;
0344         bool cornerAll(true);
0345         for (int k = 0; k < 6; ++k) {
0346           double rpos = std::sqrt(xc[k] * xc[k] + yc[k] * yc[k]);
0347           if (rpos > rout)
0348             cornerAll = false;
0349         }
0350         if (cornerAll) {
0351           double rpos = std::sqrt(xpos * xpos + ypos * ypos);
0352           DDTranslation tran(xpos, ypos, zpos);
0353           DDRotation rotation;
0354           int copy = HGCalTypes::packTypeUV(0, nc, nr);
0355           DDName name, nameX;
0356           if (type == 1) {
0357             nameX = DDName(DDSplit(covers_[0]).first, DDSplit(covers_[0]).second);
0358             std::string name0 = nameIn + "M" + std::to_string(copy);
0359             DDLogicalPart glog1 = DDLogicalPart(DDName(name0, idNameSpace_), matter, nameX);
0360             cpv.position(glog1.ddname(), glog.ddname(), copyIn, tran, rotation);
0361 #ifdef EDM_ML_DEBUG
0362             edm::LogVerbatim("HGCalGeom")
0363                 << "DDHGCalTBModuleX: " << glog1.ddname() << " number " << copyIn << " positioned in " << glog.ddname()
0364                 << " at " << tran << " with " << rotation;
0365 #endif
0366             name = (rpos < rMaxFine_) ? DDName(DDSplit(wafer_[0]).first, DDSplit(wafer_[0]).second)
0367                                       : DDName(DDSplit(wafer_[1]).first, DDSplit(wafer_[1]).second);
0368             DDTranslation tran1;
0369             cpv.position(name, glog1.ddname(), copy, tran1, rotation);
0370 #ifdef EDM_ML_DEBUG
0371             edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " number " << copy << " positioned in "
0372                                           << glog1.ddname() << " at " << tran1 << " with " << rotation;
0373 #endif
0374             if (copies_.count(copy) == 0 && type == 1)
0375               copies_.insert(copy);
0376           } else {
0377             name = DDName(DDSplit(covers_[type - 1]).first, DDSplit(covers_[type - 1]).second);
0378             copy += copyIn * 1000000;
0379             cpv.position(name, glog.ddname(), copy, tran, rotation);
0380 #ifdef EDM_ML_DEBUG
0381             edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " number " << copy << " positioned in "
0382                                           << glog.ddname() << " at " << tran << " with " << rotation;
0383 #endif
0384           }
0385 #ifdef EDM_ML_DEBUG
0386           if (inc > incm)
0387             incm = inc;
0388           if (inr > inrm)
0389             inrm = inr;
0390           kount++;
0391 #endif
0392         }
0393       }
0394     }
0395   }
0396 #ifdef EDM_ML_DEBUG
0397   edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: # of columns " << incm << " # of rows " << inrm << " and "
0398                                 << kount << " wafers for " << glog.ddname();
0399 #endif
0400 }
0401 
0402 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDHGCalTBModuleX, "hgcal:DDHGCalTBModuleX");