File indexing completed on 2024-04-06 12:14:57
0001
0002
0003
0004
0005
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
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 }
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 }
0192
0193 static long algorithm(dd4hep::Detector& , 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");
0198 const auto& covers = args.value<std::vector<std::string> >("CoverName");
0199 const auto& genMat = args.value<std::string>("GeneralMaterial");
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");
0215 const auto& names = args.value<std::vector<std::string> >("VolumeNames");
0216 const auto& layerThick = args.value<std::vector<double> >("Thickness");
0217 std::vector<int> copyNumber;
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");
0227 const auto& inOut = args.value<int>("InOut");
0228 const auto& layerFrontIn = args.value<std::vector<int> >("LayerFrontIn");
0229 const auto& layerBackIn = args.value<std::vector<int> >("LayerBackIn");
0230 std::vector<int> layerFrontOut;
0231 std::vector<int> layerBackOut;
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");
0249 const auto& layerSense = args.value<std::vector<int> >("LayerSense");
0250 const auto& maxModule = args.value<std::vector<int> >("MaxModule");
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");
0258 const auto& rMaxFine = args.value<double>("rMaxFine");
0259 const auto& waferW = args.value<double>("waferW");
0260 const auto& waferGap = args.value<double>("waferGap");
0261 const auto& absorbW = args.value<double>("absorberW");
0262 const auto& absorbH = args.value<double>("absorberH");
0263 const auto& rMax = args.value<double>("rMax");
0264 const auto& rMaxB = args.value<double>("rMaxB");
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;
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
0364 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalTBModuleX, algorithm)