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
0022 using namespace angle_units::operators;
0023
0024 class DDHGCalTBModuleX : public DDAlgorithm {
0025 public:
0026
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_;
0063 std::vector<std::string> covers_;
0064 std::string genMat_;
0065 std::vector<std::string> materials_;
0066 std::vector<std::string> names_;
0067 std::vector<double> layerThick_;
0068 std::vector<int> copyNumber_;
0069 std::vector<double> blockThick_;
0070 int inOut_;
0071 std::vector<int> layerFrontIn_;
0072 std::vector<int> layerBackIn_;
0073 std::vector<int> layerFrontOut_;
0074 std::vector<int> layerBackOut_;
0075 std::vector<int> layerType_;
0076 std::vector<int> layerSense_;
0077 std::vector<int> maxModule_;
0078 double zMinBlock_;
0079 double rMaxFine_;
0080 double waferW_;
0081 double waferGap_;
0082 double absorbW_;
0083 double absorbH_;
0084 double rMax_;
0085 double rMaxB_;
0086 std::string idName_;
0087 std::string idNameSpace_;
0088 std::unordered_set<int> copies_;
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
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 }
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");