File indexing completed on 2024-04-06 12:14:54
0001
0002
0003
0004
0005
0006
0007
0008 #include <cmath>
0009 #include <memory>
0010 #include <string>
0011 #include <unordered_set>
0012 #include <vector>
0013
0014 #include "DD4hep/DetFactoryHelper.h"
0015 #include "DataFormats/Math/interface/angle_units.h"
0016 #include "DetectorDescription/DDCMS/interface/DDPlugins.h"
0017 #include "DetectorDescription/DDCMS/interface/DDutils.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 #include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h"
0020 #include "Geometry/HGCalCommonData/interface/HGCalParameters.h"
0021 #include "Geometry/HGCalCommonData/interface/HGCalTypes.h"
0022 #include "Geometry/HGCalCommonData/interface/HGCalWaferType.h"
0023
0024
0025 using namespace angle_units::operators;
0026
0027 struct HGCalHEAlgo {
0028 HGCalHEAlgo() { throw cms::Exception("HGCalGeom") << "Wrong initialization to HGCalHEAlgo"; }
0029 HGCalHEAlgo(cms::DDParsingContext& ctxt, xml_h e) {
0030 cms::DDNamespace ns(ctxt, e, true);
0031 cms::DDAlgoArguments args(ctxt, e);
0032
0033 #ifdef EDM_ML_DEBUG
0034 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: Creating an instance";
0035 #endif
0036
0037 dd4hep::Volume mother = ns.volume(args.parentName());
0038 waferNames_ = args.value<std::vector<std::string>>("WaferNames");
0039 #ifdef EDM_ML_DEBUG
0040 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << waferNames_.size() << " wafers";
0041 for (unsigned int i = 0; i < waferNames_.size(); ++i)
0042 edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << waferNames_[i];
0043 #endif
0044 materials_ = args.value<std::vector<std::string>>("MaterialNames");
0045 volumeNames_ = args.value<std::vector<std::string>>("VolumeNames");
0046 thickness_ = args.value<std::vector<double>>("Thickness");
0047 copyNumber_.resize(materials_.size(), 1);
0048 #ifdef EDM_ML_DEBUG
0049 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << materials_.size() << " types of volumes";
0050 for (unsigned int i = 0; i < volumeNames_.size(); ++i)
0051 edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << volumeNames_[i] << " of thickness "
0052 << cms::convert2mm(thickness_[i]) << " filled with " << materials_[i]
0053 << " first copy number " << copyNumber_[i];
0054 #endif
0055 layerNumbers_ = args.value<std::vector<int>>("Layers");
0056 layerThick_ = args.value<std::vector<double>>("LayerThick");
0057 rMixLayer_ = args.value<std::vector<double>>("LayerRmix");
0058 #ifdef EDM_ML_DEBUG
0059 edm::LogVerbatim("HGCalGeom") << "There are " << layerNumbers_.size() << " blocks";
0060 for (unsigned int i = 0; i < layerNumbers_.size(); ++i)
0061 edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << cms::convert2mm(layerThick_[i])
0062 << " Rmid " << cms::convert2mm(rMixLayer_[i]) << " with " << layerNumbers_[i]
0063 << " layers";
0064 #endif
0065 layerType_ = args.value<std::vector<int>>("LayerType");
0066 layerSense_ = args.value<std::vector<int>>("LayerSense");
0067 firstLayer_ = args.value<int>("FirstLayer");
0068 absorbMode_ = args.value<int>("AbsorberMode");
0069 sensitiveMode_ = args.value<int>("SensitiveMode");
0070 #ifdef EDM_ML_DEBUG
0071 edm::LogVerbatim("HGCalGeom") << "First Layer " << firstLayer_ << " and "
0072 << "Absober:Sensitive mode " << absorbMode_ << ":" << sensitiveMode_;
0073 #endif
0074 layerCenter_ = args.value<std::vector<int>>("LayerCenter");
0075 #ifdef EDM_ML_DEBUG
0076 for (unsigned int i = 0; i < layerCenter_.size(); ++i)
0077 edm::LogVerbatim("HGCalGeom") << "LayerCenter [" << i << "] " << layerCenter_[i];
0078 #endif
0079 if (firstLayer_ > 0) {
0080 for (unsigned int i = 0; i < layerType_.size(); ++i) {
0081 if (layerSense_[i] > 0) {
0082 int ii = layerType_[i];
0083 copyNumber_[ii] = firstLayer_;
0084 #ifdef EDM_ML_DEBUG
0085 edm::LogVerbatim("HGCalGeom") << "First copy number for layer type " << i << ":" << ii << " with "
0086 << materials_[ii] << " changed to " << copyNumber_[ii];
0087 #endif
0088 break;
0089 }
0090 }
0091 }
0092 #ifdef EDM_ML_DEBUG
0093 edm::LogVerbatim("HGCalGeom") << "There are " << layerType_.size() << " layers";
0094 for (unsigned int i = 0; i < layerType_.size(); ++i)
0095 edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType_[i] << " sensitive class "
0096 << layerSense_[i];
0097 #endif
0098 materialsTop_ = args.value<std::vector<std::string>>("TopMaterialNames");
0099 namesTop_ = args.value<std::vector<std::string>>("TopVolumeNames");
0100 layerThickTop_ = args.value<std::vector<double>>("TopLayerThickness");
0101 layerTypeTop_ = args.value<std::vector<int>>("TopLayerType");
0102 copyNumberTop_.resize(materialsTop_.size(), 1);
0103 #ifdef EDM_ML_DEBUG
0104 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << materialsTop_.size() << " types of volumes in the top part";
0105 for (unsigned int i = 0; i < materialsTop_.size(); ++i)
0106 edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << namesTop_[i] << " of thickness "
0107 << cms::convert2mm(layerThickTop_[i]) << " filled with " << materialsTop_[i]
0108 << " first copy number " << copyNumberTop_[i];
0109 edm::LogVerbatim("HGCalGeom") << "There are " << layerTypeTop_.size() << " layers in the top part";
0110 for (unsigned int i = 0; i < layerTypeTop_.size(); ++i)
0111 edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerTypeTop_[i];
0112 #endif
0113 materialsBot_ = args.value<std::vector<std::string>>("BottomMaterialNames");
0114 namesBot_ = args.value<std::vector<std::string>>("BottomVolumeNames");
0115 layerTypeBot_ = args.value<std::vector<int>>("BottomLayerType");
0116 layerSenseBot_ = args.value<std::vector<int>>("BottomLayerSense");
0117 layerThickBot_ = args.value<std::vector<double>>("BottomLayerThickness");
0118 copyNumberBot_.resize(materialsBot_.size(), 1);
0119 #ifdef EDM_ML_DEBUG
0120 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << materialsBot_.size()
0121 << " types of volumes in the bottom part";
0122 for (unsigned int i = 0; i < materialsBot_.size(); ++i)
0123 edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << namesBot_[i] << " of thickness "
0124 << cms::convert2mm(layerThickBot_[i]) << " filled with " << materialsBot_[i]
0125 << " first copy number " << copyNumberBot_[i];
0126 edm::LogVerbatim("HGCalGeom") << "There are " << layerTypeBot_.size() << " layers in the bottom part";
0127 for (unsigned int i = 0; i < layerTypeBot_.size(); ++i)
0128 edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerTypeBot_[i]
0129 << " sensitive class " << layerSenseBot_[i];
0130 #endif
0131 zMinBlock_ = args.value<double>("zMinBlock");
0132 rad100to200_ = args.value<std::vector<double>>("rad100to200");
0133 rad200to300_ = args.value<std::vector<double>>("rad200to300");
0134 zMinRadPar_ = args.value<double>("zMinForRadPar");
0135 choiceType_ = args.value<int>("choiceType");
0136 nCutRadPar_ = args.value<int>("nCornerCut");
0137 fracAreaMin_ = args.value<double>("fracAreaMin");
0138 waferSize_ = args.value<double>("waferSize");
0139 waferSepar_ = args.value<double>("SensorSeparation");
0140 sectors_ = args.value<int>("Sectors");
0141 alpha_ = (1._pi) / sectors_;
0142 cosAlpha_ = cos(alpha_);
0143 #ifdef EDM_ML_DEBUG
0144 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: zStart " << cms::convert2mm(zMinBlock_)
0145 << " radius for wafer type separation uses " << rad100to200_.size()
0146 << " parameters; zmin " << cms::convert2mm(zMinRadPar_) << " cutoff " << choiceType_
0147 << ":" << nCutRadPar_ << ":" << fracAreaMin_ << " wafer width "
0148 << cms::convert2mm(waferSize_) << " separations " << cms::convert2mm(waferSepar_)
0149 << " sectors " << sectors_ << ":" << convertRadToDeg(alpha_) << ":" << cosAlpha_;
0150 for (unsigned int k = 0; k < rad100to200_.size(); ++k)
0151 edm::LogVerbatim("HGCalGeom") << "[" << k << "] 100-200 " << rad100to200_[k] << " 200-300 " << rad200to300_[k];
0152 #endif
0153 slopeB_ = args.value<std::vector<double>>("SlopeBottom");
0154 zFrontB_ = args.value<std::vector<double>>("ZFrontBottom");
0155 rMinFront_ = args.value<std::vector<double>>("RMinFront");
0156 slopeT_ = args.value<std::vector<double>>("SlopeTop");
0157 zFrontT_ = args.value<std::vector<double>>("ZFrontTop");
0158 rMaxFront_ = args.value<std::vector<double>>("RMaxFront");
0159 #ifdef EDM_ML_DEBUG
0160 for (unsigned int i = 0; i < slopeB_.size(); ++i)
0161 edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << cms::convert2mm(zFrontB_[i]) << " Rmin "
0162 << cms::convert2mm(rMinFront_[i]) << " Slope " << slopeB_[i];
0163 for (unsigned int i = 0; i < slopeT_.size(); ++i)
0164 edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << cms::convert2mm(zFrontT_[i]) << " Rmax "
0165 << cms::convert2mm(rMaxFront_[i]) << " Slope " << slopeT_[i];
0166 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: NameSpace " << ns.name();
0167 #endif
0168
0169 waferType_ = std::make_unique<HGCalWaferType>(rad100to200_,
0170 rad200to300_,
0171 cms::convert2mm((waferSize_ + waferSepar_)),
0172 cms::convert2mm(zMinRadPar_),
0173 choiceType_,
0174 nCutRadPar_,
0175 fracAreaMin_);
0176
0177 #ifdef EDM_ML_DEBUG
0178 edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalHEAlgo...";
0179 copies_.clear();
0180 #endif
0181
0182 double zi(zMinBlock_);
0183 int laymin(0);
0184 for (unsigned int i = 0; i < layerNumbers_.size(); i++) {
0185 double zo = zi + layerThick_[i];
0186 double routF = HGCalGeomTools::radius(zi, zFrontT_, rMaxFront_, slopeT_);
0187 int laymax = laymin + layerNumbers_[i];
0188 double zz = zi;
0189 double thickTot(0);
0190 for (int ly = laymin; ly < laymax; ++ly) {
0191 int ii = layerType_[ly];
0192 int copy = copyNumber_[ii];
0193 double hthick = 0.5 * thickness_[ii];
0194 double rinB = HGCalGeomTools::radius(zo, zFrontB_, rMinFront_, slopeB_);
0195 zz += hthick;
0196 thickTot += thickness_[ii];
0197
0198 std::string name = volumeNames_[ii] + std::to_string(copy);
0199
0200 #ifdef EDM_ML_DEBUG
0201 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: Layer " << ly << ":" << ii << " Front " << cms::convert2mm(zi)
0202 << ", " << cms::convert2mm(routF) << " Back " << cms::convert2mm(zo) << ", "
0203 << cms::convert2mm(rinB) << " superlayer thickness "
0204 << cms::convert2mm(layerThick_[i]);
0205 #endif
0206
0207 dd4hep::Material matter = ns.material(materials_[ii]);
0208 dd4hep::Volume glog;
0209
0210 if (layerSense_[ly] < 1) {
0211 std::vector<double> pgonZ, pgonRin, pgonRout;
0212 if (layerSense_[ly] == 0 || absorbMode_ == 0) {
0213 double rmax =
0214 (std::min(routF, HGCalGeomTools::radius(zz + hthick, zFrontT_, rMaxFront_, slopeT_)) * cosAlpha_) -
0215 tol1_;
0216 pgonZ.emplace_back(-hthick);
0217 pgonZ.emplace_back(hthick);
0218 pgonRin.emplace_back(rinB);
0219 pgonRin.emplace_back(rinB);
0220 pgonRout.emplace_back(rmax);
0221 pgonRout.emplace_back(rmax);
0222 } else {
0223 HGCalGeomTools::radius(zz - hthick,
0224 zz + hthick,
0225 zFrontB_,
0226 rMinFront_,
0227 slopeB_,
0228 zFrontT_,
0229 rMaxFront_,
0230 slopeT_,
0231 -layerSense_[ly],
0232 pgonZ,
0233 pgonRin,
0234 pgonRout);
0235 for (unsigned int isec = 0; isec < pgonZ.size(); ++isec) {
0236 pgonZ[isec] -= zz;
0237 pgonRout[isec] = pgonRout[isec] * cosAlpha_ - tol1_;
0238 }
0239 }
0240
0241 dd4hep::Solid solid = dd4hep::Polyhedra(sectors_, -alpha_, 2._pi, pgonZ, pgonRin, pgonRout);
0242 ns.addSolidNS(ns.prepend(name), solid);
0243 glog = dd4hep::Volume(solid.name(), solid, matter);
0244 ns.addVolumeNS(glog);
0245 #ifdef EDM_ML_DEBUG
0246 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << solid.name() << " polyhedra of " << sectors_
0247 << " sectors covering " << convertRadToDeg(-alpha_) << ":"
0248 << convertRadToDeg(-alpha_ + 2._pi) << " with " << pgonZ.size() << " sections";
0249 for (unsigned int k = 0; k < pgonZ.size(); ++k)
0250 edm::LogVerbatim("HGCalGeom") << "[" << k << "] z " << cms::convert2mm(pgonZ[k]) << " R "
0251 << cms::convert2mm(pgonRin[k]) << ":" << cms::convert2mm(pgonRout[k]);
0252 #endif
0253 } else {
0254 double rins =
0255 (sensitiveMode_ < 1) ? rinB : HGCalGeomTools::radius(zz + hthick, zFrontB_, rMinFront_, slopeB_);
0256 double routs =
0257 (sensitiveMode_ < 1) ? routF : HGCalGeomTools::radius(zz - hthick, zFrontT_, rMaxFront_, slopeT_);
0258 dd4hep::Solid solid = dd4hep::Tube(rins, routs, hthick, 0.0, 2._pi);
0259 ns.addSolidNS(ns.prepend(name), solid);
0260 glog = dd4hep::Volume(solid.name(), solid, matter);
0261 ns.addVolumeNS(glog);
0262
0263 #ifdef EDM_ML_DEBUG
0264 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << solid.name() << " Tubs made of " << matter.name()
0265 << " of dimensions " << cms::convert2mm(rinB) << ":" << cms::convert2mm(rins)
0266 << ", " << cms::convert2mm(routF) << ":" << cms::convert2mm(routs) << ", "
0267 << cms::convert2mm(hthick) << ", 0.0, 360.0 and positioned in: " << glog.name()
0268 << " number " << copy;
0269 #endif
0270 positionMix(ctxt, e, glog, name, copy, thickness_[ii], matter, rins, rMixLayer_[i], routs, zz);
0271 }
0272
0273 dd4hep::Position r1(0, 0, zz);
0274 mother.placeVolume(glog, copy, r1);
0275 ++copyNumber_[ii];
0276 #ifdef EDM_ML_DEBUG
0277 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << glog.name() << " number " << copy << " positioned in "
0278 << mother.name() << " at (0,0," << cms::convert2mm(zz) << ") with no rotation";
0279 #endif
0280 zz += hthick;
0281 }
0282 zi = zo;
0283 laymin = laymax;
0284 if (std::abs(thickTot - layerThick_[i]) >= tol2_) {
0285 if (thickTot > layerThick_[i]) {
0286 edm::LogError("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(layerThick_[i])
0287 << " is smaller than " << cms::convert2mm(thickTot)
0288 << ": thickness of all its components **** ERROR ****";
0289 } else {
0290 edm::LogWarning("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(layerThick_[i])
0291 << " does not match with " << cms::convert2mm(thickTot) << " of the components";
0292 }
0293 }
0294 }
0295
0296 #ifdef EDM_ML_DEBUG
0297 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << copies_.size() << " different wafer copy numbers";
0298 int k(0);
0299 for (std::unordered_set<int>::const_iterator itr = copies_.begin(); itr != copies_.end(); ++itr, ++k) {
0300 edm::LogVerbatim("HGCalGeom") << "Copy [" << k << "] : " << (*itr);
0301 }
0302 copies_.clear();
0303 edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalHEAlgo construction...";
0304 #endif
0305 }
0306
0307 void positionMix(cms::DDParsingContext& ctxt,
0308 xml_h e,
0309 const dd4hep::Volume& glog,
0310 const std::string& nameM,
0311 int copyM,
0312 double thick,
0313 const dd4hep::Material& matter,
0314 double rin,
0315 double rmid,
0316 double rout,
0317 double zz) {
0318 cms::DDNamespace ns(ctxt, e, true);
0319
0320 dd4hep::Volume glog1;
0321 for (unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) {
0322 int ii = layerTypeTop_[ly];
0323 copyNumberTop_[ii] = copyM;
0324 }
0325 for (unsigned int ly = 0; ly < layerTypeBot_.size(); ++ly) {
0326 int ii = layerTypeBot_[ly];
0327 copyNumberBot_[ii] = copyM;
0328 }
0329 double hthick = 0.5 * thick;
0330
0331 std::string name = nameM + "Top";
0332
0333 dd4hep::Solid solid = dd4hep::Tube(rmid, rout, hthick, 0.0, 2._pi);
0334 ns.addSolidNS(ns.prepend(name), solid);
0335 glog1 = dd4hep::Volume(solid.name(), solid, matter);
0336 ns.addVolumeNS(glog1);
0337 #ifdef EDM_ML_DEBUG
0338 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << solid.name() << " Tubs made of " << matter.name()
0339 << " of dimensions " << cms::convert2mm(rmid) << ", " << cms::convert2mm(rout) << ", "
0340 << cms::convert2mm(hthick) << ", 0.0, 360.0";
0341 #endif
0342 glog.placeVolume(glog1, 1);
0343
0344 #ifdef EDM_ML_DEBUG
0345 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << glog1.name() << " number 1 positioned in " << glog.name()
0346 << " at (0,0,0) with no rotation";
0347 #endif
0348 double thickTot(0), zpos(-hthick);
0349 for (unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) {
0350 int ii = layerTypeTop_[ly];
0351 int copy = copyNumberTop_[ii];
0352 double hthickl = 0.5 * layerThickTop_[ii];
0353 thickTot += layerThickTop_[ii];
0354 name = namesTop_[ii] + std::to_string(copy);
0355 #ifdef EDM_ML_DEBUG
0356 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: Layer " << ly << ":" << ii << " R " << cms::convert2mm(rmid)
0357 << ":" << cms::convert2mm(rout) << " Thick " << cms::convert2mm(layerThickTop_[ii]);
0358 #endif
0359
0360 dd4hep::Material matter1 = ns.material(materialsTop_[ii]);
0361 solid = dd4hep::Tube(rmid, rout, hthickl, 0.0, 2._pi);
0362 ns.addSolidNS(ns.prepend(name), solid);
0363 dd4hep::Volume glog2 = dd4hep::Volume(solid.name(), solid, matter1);
0364 ns.addVolumeNS(glog2);
0365
0366 #ifdef EDM_ML_DEBUG
0367 double eta1 = -log(tan(0.5 * atan(rmid / zz)));
0368 double eta2 = -log(tan(0.5 * atan(rout / zz)));
0369 edm::LogVerbatim("HGCalGeom") << name << " z|rin|rout " << cms::convert2mm(zz) << ":" << cms::convert2mm(rmid)
0370 << ":" << cms::convert2mm(rout) << " eta " << eta1 << ":" << eta2;
0371 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << solid.name() << " Tubs made of " << matter1.name()
0372 << " of dimensions " << cms::convert2mm(rmid) << ", " << cms::convert2mm(rout)
0373 << ", " << cms::convert2mm(hthickl) << ", 0.0, 360.0";
0374 #endif
0375 zpos += hthickl;
0376
0377 dd4hep::Position r1(0, 0, zpos);
0378 glog1.placeVolume(glog2, copy, r1);
0379
0380 #ifdef EDM_ML_DEBUG
0381 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: Position " << glog2.name() << " number " << copy << " in "
0382 << glog1.name() << " at (0,0," << cms::convert2mm(zpos) << ") with no rotation";
0383 #endif
0384 ++copyNumberTop_[ii];
0385 zpos += hthickl;
0386 }
0387 if (std::abs(thickTot - thick) >= tol2_) {
0388 if (thickTot > thick) {
0389 edm::LogError("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(thick) << " is smaller than "
0390 << cms::convert2mm(thickTot)
0391 << ": thickness of all its components in the top part **** ERROR ****";
0392 } else {
0393 edm::LogWarning("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(thick)
0394 << " does not match with " << cms::convert2mm(thickTot)
0395 << " of the components in top part";
0396 }
0397 }
0398
0399
0400 name = nameM + "Bottom";
0401
0402 solid = dd4hep::Tube(rin, rmid, hthick, 0.0, 2._pi);
0403 ns.addSolidNS(ns.prepend(name), solid);
0404 glog1 = dd4hep::Volume(solid.name(), solid, matter);
0405 ns.addVolumeNS(glog1);
0406
0407 #ifdef EDM_ML_DEBUG
0408 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << solid.name() << " Tubs made of " << matter.name()
0409 << " of dimensions " << cms::convert2mm(rin) << ", " << cms::convert2mm(rmid) << ", "
0410 << cms::convert2mm(hthick) << ", 0.0, 360.0";
0411 #endif
0412
0413 glog.placeVolume(glog1, 1);
0414 #ifdef EDM_ML_DEBUG
0415 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << glog1.name() << " number 1 positioned in " << glog.name()
0416 << " at (0,0,0) with no rotation";
0417 #endif
0418 thickTot = 0;
0419 zpos = -hthick;
0420 for (unsigned int ly = 0; ly < layerTypeBot_.size(); ++ly) {
0421 int ii = layerTypeBot_[ly];
0422 int copy = copyNumberBot_[ii];
0423 double hthickl = 0.5 * layerThickBot_[ii];
0424 thickTot += layerThickBot_[ii];
0425 name = namesBot_[ii] + std::to_string(copy);
0426 #ifdef EDM_ML_DEBUG
0427 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: Layer " << ly << ":" << ii << " R " << cms::convert2mm(rin)
0428 << ":" << cms::convert2mm(rmid) << " Thick " << cms::convert2mm(layerThickBot_[ii]);
0429 #endif
0430
0431 dd4hep::Material matter1 = ns.material(materialsBot_[ii]);
0432 solid = dd4hep::Tube(rin, rmid, hthickl, 0.0, 2._pi);
0433 ns.addSolidNS(ns.prepend(name), solid);
0434 dd4hep::Volume glog2 = dd4hep::Volume(solid.name(), solid, matter1);
0435 ns.addVolumeNS(glog2);
0436
0437 #ifdef EDM_ML_DEBUG
0438 double eta1 = -log(tan(0.5 * atan(rin / zz)));
0439 double eta2 = -log(tan(0.5 * atan(rmid / zz)));
0440 edm::LogVerbatim("HGCalGeom") << name << " z|rin|rout " << cms::convert2mm(zz) << ":" << cms::convert2mm(rin)
0441 << ":" << cms::convert2mm(rmid) << " eta " << eta1 << ":" << eta2;
0442 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << solid.name() << " Tubs made of " << matter1.name()
0443 << " of dimensions " << cms::convert2mm(rin) << ", " << cms::convert2mm(rmid)
0444 << ", " << cms::convert2mm(hthickl) << ", 0.0, 360.0";
0445 #endif
0446 zpos += hthickl;
0447
0448 dd4hep::Position r1(0, 0, zpos);
0449 glog1.placeVolume(glog2, copy, r1);
0450 #ifdef EDM_ML_DEBUG
0451 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: Position " << glog2.name() << " number " << copy << " in "
0452 << glog1.name() << " at (0,0," << cms::convert2mm(zpos) << ") with no rotation";
0453 #endif
0454 if (layerSenseBot_[ly] != 0) {
0455 #ifdef EDM_ML_DEBUG
0456 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: z " << cms::convert2mm((zz + zpos)) << " Center " << copy
0457 << ":" << (copy - firstLayer_) << ":" << layerCenter_[copy - firstLayer_];
0458 #endif
0459 positionSensitive(ctxt, e, glog2, rin, rmid, zz + zpos, layerSenseBot_[ly], layerCenter_[copy - firstLayer_]);
0460 }
0461 zpos += hthickl;
0462 ++copyNumberBot_[ii];
0463 }
0464 if (std::abs(thickTot - thick) >= tol2_) {
0465 if (thickTot > thick) {
0466 edm::LogError("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(thick) << " is smaller than "
0467 << cms::convert2mm(thickTot)
0468 << ": thickness of all its components in the top part **** ERROR ****";
0469 } else {
0470 edm::LogWarning("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(thick)
0471 << " does not match with " << cms::convert2mm(thickTot)
0472 << " of the components in top part";
0473 }
0474 }
0475 }
0476
0477 void positionSensitive(cms::DDParsingContext& ctxt,
0478 xml_h e,
0479 const dd4hep::Volume& glog,
0480 double rin,
0481 double rout,
0482 double zpos,
0483 int layertype,
0484 int layercenter) {
0485 cms::DDNamespace ns(ctxt, e, true);
0486 static const double sqrt3 = std::sqrt(3.0);
0487 double r = 0.5 * (waferSize_ + waferSepar_);
0488 double R = 2.0 * r / sqrt3;
0489 double dy = 0.75 * R;
0490 int N = (int)(0.5 * rout / r) + 2;
0491 const auto& xyoff = geomTools_.shiftXY(layercenter, (waferSize_ + waferSepar_));
0492 #ifdef EDM_ML_DEBUG
0493 int ium(0), ivm(0), iumAll(0), ivmAll(0), kount(0), ntot(0), nin(0);
0494 std::vector<int> ntype(6, 0);
0495 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: " << glog.name() << " rout " << cms::convert2mm(rout) << " N " << N
0496 << " for maximum u, v Offset; Shift " << cms::convert2mm(xyoff.first) << ":"
0497 << cms::convert2mm(xyoff.second) << " WaferSize "
0498 << cms::convert2mm((waferSize_ + waferSepar_));
0499 #endif
0500 for (int u = -N; u <= N; ++u) {
0501 for (int v = -N; v <= N; ++v) {
0502 int nr = 2 * v;
0503 int nc = -2 * u + v;
0504 double xpos = xyoff.first + nc * r;
0505 double ypos = xyoff.second + nr * dy;
0506 const auto& corner = HGCalGeomTools::waferCorner(xpos, ypos, r, R, rin, rout, false);
0507 #ifdef EDM_ML_DEBUG
0508 int iu = std::abs(u);
0509 int iv = std::abs(v);
0510 ++ntot;
0511 #endif
0512 if (corner.first > 0) {
0513 int type = waferType_->getType((xpos / dd4hep::mm), (ypos / dd4hep::mm), (zpos / dd4hep::mm));
0514 int copy = HGCalTypes::packTypeUV(type, u, v);
0515 #ifdef EDM_ML_DEBUG
0516 if (iu > ium)
0517 ium = iu;
0518 if (iv > ivm)
0519 ivm = iv;
0520 kount++;
0521 if (copies_.count(copy) == 0)
0522 copies_.insert(copy);
0523 #endif
0524 if (corner.first == (int)(HGCalParameters::k_CornerSize)) {
0525 #ifdef EDM_ML_DEBUG
0526 if (iu > iumAll)
0527 iumAll = iu;
0528 if (iv > ivmAll)
0529 ivmAll = iv;
0530 ++nin;
0531 #endif
0532
0533 dd4hep::Position tran(xpos, ypos, 0.0);
0534 if (layertype > 1)
0535 type += 3;
0536 glog.placeVolume(ns.volume(waferNames_[type]), copy, tran);
0537
0538 #ifdef EDM_ML_DEBUG
0539 ++ntype[type];
0540 edm::LogVerbatim("HGCalGeom")
0541 << "DDHGCalHEAlgo: " << glog.name() << " number " << copy << " positioned in " << glog.name() << " at ("
0542 << cms::convert2mm(xpos) << "," << cms::convert2mm(ypos) << ",0) with no rotation";
0543 #endif
0544 }
0545 }
0546 }
0547 }
0548 #ifdef EDM_ML_DEBUG
0549 edm::LogVerbatim("HGCalGeom") << "DDHGCalHEAlgo: Maximum # of u " << ium << ":" << iumAll << " # of v " << ivm
0550 << ":" << ivmAll << " and " << nin << ":" << kount << ":" << ntot << " wafers ("
0551 << ntype[0] << ":" << ntype[1] << ":" << ntype[2] << ":" << ntype[3] << ":"
0552 << ntype[4] << ":" << ntype[5] << ") for " << glog.name() << " R "
0553 << cms::convert2mm(rin) << ":" << cms::convert2mm(rout);
0554 #endif
0555 }
0556
0557
0558 HGCalGeomTools geomTools_;
0559 std::unique_ptr<HGCalWaferType> waferType_;
0560
0561 std::vector<std::string> waferNames_;
0562 std::vector<std::string> materials_;
0563 std::vector<std::string> volumeNames_;
0564 std::vector<double> thickness_;
0565 std::vector<int> copyNumber_;
0566 std::vector<int> layerNumbers_;
0567 std::vector<double> layerThick_;
0568 std::vector<double> rMixLayer_;
0569 std::vector<int> layerType_;
0570 std::vector<int> layerSense_;
0571 int firstLayer_;
0572 int absorbMode_;
0573 int sensitiveMode_;
0574 std::vector<std::string> materialsTop_;
0575 std::vector<std::string> namesTop_;
0576 std::vector<double> layerThickTop_;
0577 std::vector<int> layerTypeTop_;
0578 std::vector<int> copyNumberTop_;
0579 std::vector<std::string> materialsBot_;
0580 std::vector<std::string> namesBot_;
0581 std::vector<double> layerThickBot_;
0582 std::vector<int> layerTypeBot_;
0583 std::vector<int> copyNumberBot_;
0584 std::vector<int> layerSenseBot_;
0585 std::vector<int> layerCenter_;
0586
0587 double zMinBlock_;
0588 std::vector<double> rad100to200_;
0589 std::vector<double> rad200to300_;
0590 double zMinRadPar_;
0591 int choiceType_;
0592 int nCutRadPar_;
0593 double fracAreaMin_;
0594 double waferSize_;
0595 double waferSepar_;
0596 int sectors_;
0597 std::vector<double> slopeB_;
0598 std::vector<double> zFrontB_;
0599 std::vector<double> rMinFront_;
0600 std::vector<double> slopeT_;
0601 std::vector<double> zFrontT_;
0602 std::vector<double> rMaxFront_;
0603 std::unordered_set<int> copies_;
0604 double alpha_, cosAlpha_;
0605
0606 static constexpr double tol1_ = 0.01 * dd4hep::mm;
0607 static constexpr double tol2_ = 0.00001 * dd4hep::mm;
0608 };
0609
0610 static long algorithm(dd4hep::Detector& , cms::DDParsingContext& ctxt, xml_h e) {
0611 HGCalHEAlgo heAlgo(ctxt, e);
0612 return cms::s_executed;
0613 }
0614
0615 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalHEAlgo, algorithm)