diff --git a/Geometry/HGCalCommonData/data/dd4hep/testHGCalV14.xml b/Geometry/HGCalCommonData/data/dd4hep/testHGCalV14.xml new file mode 100644 index 0000000000000..0795efed778b4 --- /dev/null +++ b/Geometry/HGCalCommonData/data/dd4hep/testHGCalV14.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Geometry/HGCalCommonData/interface/HGCalTypes.h b/Geometry/HGCalCommonData/interface/HGCalTypes.h index 4f235eb1fff5d..00a3a674dc962 100644 --- a/Geometry/HGCalCommonData/interface/HGCalTypes.h +++ b/Geometry/HGCalCommonData/interface/HGCalTypes.h @@ -63,6 +63,20 @@ class HGCalTypes { enum TileType { TileFine = 0, TileCoarseCast = 1, TileCoarseMould = 2 }; enum TileSiPMType { SiPMUnknown = 0, SiPMSmall = 2, SiPMLarge = 4 }; + + static int32_t packTypeUV(int type, int u, int v); + static int32_t getUnpackedType(int id); + static int32_t getUnpackedU(int id); + static int32_t getUnpackedV(int id); + +private: + static constexpr int32_t facu_ = 1; + static constexpr int32_t facv_ = 100; + static constexpr int32_t factype_ = 1000000; + static constexpr int32_t signu_ = 10000; + static constexpr int32_t signv_ = 100000; + static constexpr int32_t maxuv_ = 100; + static constexpr int32_t maxsign_ = 10; }; #endif diff --git a/Geometry/HGCalCommonData/plugins/DDHGCalEEFileAlgo.cc b/Geometry/HGCalCommonData/plugins/DDHGCalEEFileAlgo.cc index 878931820fbf3..2eaed1660209b 100644 --- a/Geometry/HGCalCommonData/plugins/DDHGCalEEFileAlgo.cc +++ b/Geometry/HGCalCommonData/plugins/DDHGCalEEFileAlgo.cc @@ -18,6 +18,7 @@ #include "FWCore/PluginManager/interface/PluginFactory.h" #include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h" #include "Geometry/HGCalCommonData/interface/HGCalParameters.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" #include "Geometry/HGCalCommonData/interface/HGCalWaferIndex.h" #include "Geometry/HGCalCommonData/interface/HGCalWaferType.h" @@ -355,9 +356,11 @@ void DDHGCalEEFileAlgo::positionSensitive( << (waferSize_ + waferSepar_); #endif for (int u = -N; u <= N; ++u) { - int iu = std::abs(u); for (int v = -N; v <= N; ++v) { +#ifdef EDM_ML_DEBUG + int iu = std::abs(u); int iv = std::abs(v); +#endif int nr = 2 * v; int nc = -2 * u + v; double xpos = xyoff.first + nc * r; @@ -373,11 +376,7 @@ void DDHGCalEEFileAlgo::positionSensitive( #endif int type = HGCalWaferType::getType(HGCalWaferIndex::waferIndex(layer, u, v, false), waferIndex_, waferTypes_); if (corner.first > 0 && type >= 0) { - int copy = type * 1000000 + iv * 100 + iu; - if (u < 0) - copy += 10000; - if (v < 0) - copy += 100000; + int copy = HGCalTypes::packTypeUV(type, u, v); #ifdef EDM_ML_DEBUG if (iu > ium) ium = iu; diff --git a/Geometry/HGCalCommonData/plugins/DDHGCalHEFileAlgo.cc b/Geometry/HGCalCommonData/plugins/DDHGCalHEFileAlgo.cc index b4eb97ec50536..c464226a5c0e0 100644 --- a/Geometry/HGCalCommonData/plugins/DDHGCalHEFileAlgo.cc +++ b/Geometry/HGCalCommonData/plugins/DDHGCalHEFileAlgo.cc @@ -17,6 +17,7 @@ #include "FWCore/PluginManager/interface/PluginFactory.h" #include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h" #include "Geometry/HGCalCommonData/interface/HGCalParameters.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" #include "Geometry/HGCalCommonData/interface/HGCalWaferIndex.h" #include "Geometry/HGCalCommonData/interface/HGCalWaferType.h" @@ -544,9 +545,11 @@ void DDHGCalHEFileAlgo::positionSensitive( << ":" << xyoff.second << " WaferSize " << (waferSize_ + waferSepar_); #endif for (int u = -N; u <= N; ++u) { - int iu = std::abs(u); for (int v = -N; v <= N; ++v) { +#ifdef EDM_ML_DEBUG + int iu = std::abs(u); int iv = std::abs(v); +#endif int nr = 2 * v; int nc = -2 * u + v; double xpos = xyoff.first + nc * r; @@ -557,11 +560,7 @@ void DDHGCalHEFileAlgo::positionSensitive( #endif int type = HGCalWaferType::getType(HGCalWaferIndex::waferIndex(layer, u, v, false), waferIndex_, waferTypes_); if (corner.first > 0 && type >= 0) { - int copy = type * 1000000 + iv * 100 + iu; - if (u < 0) - copy += 10000; - if (v < 0) - copy += 100000; + int copy = HGCalTypes::packTypeUV(type, u, v); #ifdef EDM_ML_DEBUG if (iu > ium) ium = iu; diff --git a/Geometry/HGCalCommonData/plugins/dd4hep/DDHGCalEEFileAlgo.cc b/Geometry/HGCalCommonData/plugins/dd4hep/DDHGCalEEFileAlgo.cc new file mode 100644 index 0000000000000..48485e3077df9 --- /dev/null +++ b/Geometry/HGCalCommonData/plugins/dd4hep/DDHGCalEEFileAlgo.cc @@ -0,0 +1,401 @@ +/////////////////////////////////////////////////////////////////////////////// +// File: DDHGCalEEFileAlgo.cc +// Description: Geometry factory class for HGCal (EE and HESil) using +// information from the file for dd4hep +/////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include + +#include "Geometry/HGCalCommonData/interface/HGCalParameters.h" +#include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" +#include "Geometry/HGCalCommonData/interface/HGCalWaferIndex.h" +#include "Geometry/HGCalCommonData/interface/HGCalWaferType.h" +#include "DD4hep/DetFactoryHelper.h" +#include "DataFormats/Math/interface/CMSUnits.h" +#include "DetectorDescription/DDCMS/interface/DDPlugins.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +//#define EDM_ML_DEBUG +using namespace cms_units::operators; + +struct HGCalEEFileAlgo { + HGCalEEFileAlgo() { throw cms::Exception("HGCalGeom") << "Wrong initialization to HGCalEEFileAlgo"; } + HGCalEEFileAlgo(cms::DDParsingContext& ctxt, xml_h e) { + cms::DDNamespace ns(ctxt, e, true); + cms::DDAlgoArguments args(ctxt, e); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: Creating an instance"; +#endif + static constexpr double tol1 = 0.01; + static constexpr double tol2 = 0.00001; + + dd4hep::Volume mother = ns.volume(args.parentName()); + wafers_ = args.value>("WaferNames"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << wafers_.size() << " wafers"; + for (unsigned int i = 0; i < wafers_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafers_[i]; +#endif + materials_ = args.value>("MaterialNames"); + names_ = args.value>("VolumeNames"); + thick_ = args.value>("Thickness"); + copyNumber_.resize(materials_.size(), 1); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << materials_.size() << " types of volumes"; + for (unsigned int i = 0; i < names_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names_[i] << " of thickness " << thick_[i] + << " filled with " << materials_[i] << " first copy number " << copyNumber_[i]; +#endif + layers_ = args.value>("Layers"); + layerThick_ = args.value>("LayerThick"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "There are " << layers_.size() << " blocks"; + for (unsigned int i = 0; i < layers_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << layerThick_[i] << " with " << layers_[i] + << " layers"; +#endif + layerType_ = args.value>("LayerType"); + layerSense_ = args.value>("LayerSense"); + firstLayer_ = args.value("FirstLayer"); + absorbMode_ = args.value("AbsorberMode"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "First Layer " << firstLayer_ << " and " + << "Absober mode " << absorbMode_; +#endif + layerCenter_ = args.value>("LayerCenter"); +#ifdef EDM_ML_DEBUG + for (unsigned int i = 0; i < layerCenter_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "LayerCenter [" << i << "] " << layerCenter_[i]; +#endif + if (firstLayer_ > 0) { + for (unsigned int i = 0; i < layerType_.size(); ++i) { + if (layerSense_[i] > 0) { + int ii = layerType_[i]; + copyNumber_[ii] = firstLayer_; +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "First copy number for layer type " << i << ":" << ii << " with " + << materials_[ii] << " changed to " << copyNumber_[ii]; +#endif + break; + } + } + } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "There are " << layerType_.size() << " layers"; + for (unsigned int i = 0; i < layerType_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType_[i] << " sensitive class " + << layerSense_[i]; +#endif + zMinBlock_ = args.value("zMinBlock"); + rad100to200_ = args.value>("rad100to200"); + rad200to300_ = args.value>("rad200to300"); + zMinRadPar_ = args.value("zMinForRadPar"); + choiceType_ = args.value("choiceType"); + nCutRadPar_ = args.value("nCornerCut"); + fracAreaMin_ = args.value("fracAreaMin"); + waferSize_ = args.value("waferSize"); + waferSepar_ = args.value("SensorSeparation"); + sectors_ = args.value("Sectors"); + alpha_ = (1._pi) / sectors_; + cosAlpha_ = cos(alpha_); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "zStart " << zMinBlock_ << " radius for wafer type separation uses " + << rad100to200_.size() << " parameters; zmin " << zMinRadPar_ << " cutoff " + << choiceType_ << ":" << nCutRadPar_ << ":" << fracAreaMin_ << " wafer width " + << waferSize_ << " separations " << waferSepar_ << " sectors " << sectors_ << ":" + << convertRadToDeg(alpha_) << ":" << cosAlpha_; + for (unsigned int k = 0; k < rad100to200_.size(); ++k) + edm::LogVerbatim("HGCalGeom") << "[" << k << "] 100-200 " << rad100to200_[k] << " 200-300 " << rad200to300_[k]; +#endif + waferIndex_ = args.value>("WaferIndex"); + waferTypes_ = args.value>("WaferTypes"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "waferTypes with " << waferTypes_.size() << " entries"; + for (unsigned int k = 0; k < waferTypes_.size(); ++k) + edm::LogVerbatim("HGCalGeom") << "[" << k << "] " << waferIndex_[k] << " (" + << HGCalWaferIndex::waferLayer(waferIndex_[k]) << ", " + << HGCalWaferIndex::waferU(waferIndex_[k]) << ", " + << HGCalWaferIndex::waferV(waferIndex_[k]) << ") : " << waferTypes_[k]; +#endif + slopeB_ = args.value>("SlopeBottom"); + zFrontB_ = args.value>("ZFrontBottom"); + rMinFront_ = args.value>("RMinFront"); + slopeT_ = args.value>("SlopeTop"); + zFrontT_ = args.value>("ZFrontTop"); + rMaxFront_ = args.value>("RMaxFront"); +#ifdef EDM_ML_DEBUG + for (unsigned int i = 0; i < slopeB_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << zFrontB_[i] << " Rmin " << rMinFront_[i] + << " Slope " << slopeB_[i]; + for (unsigned int i = 0; i < slopeT_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << zFrontT_[i] << " Rmax " << rMaxFront_[i] + << " Slope " << slopeT_[i]; + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: NameSpace " << ns.name(); +#endif + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalEEFileAlgo..."; + copies_.clear(); +#endif + + double zi(zMinBlock_); + int laymin(0); + for (unsigned int i = 0; i < layers_.size(); ++i) { + double zo = zi + layerThick_[i]; + double routF = HGCalGeomTools::radius(zi, zFrontT_, rMaxFront_, slopeT_); + int laymax = laymin + layers_[i]; + double zz = zi; + double thickTot(0); + for (int ly = laymin; ly < laymax; ++ly) { + int ii = layerType_[ly]; + int copy = copyNumber_[ii]; + double hthick = 0.5 * thick_[ii]; + double rinB = HGCalGeomTools::radius(zo, zFrontB_, rMinFront_, slopeB_); + zz += hthick; + thickTot += thick_[ii]; + + std::string name = names_[ii] + std::to_string(copy); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: Layer " << ly << ":" << ii << " Front " << zi << ", " + << routF << " Back " << zo << ", " << rinB << " superlayer thickness " + << layerThick_[i]; +#endif + + dd4hep::Material matter = ns.material(materials_[ii]); + dd4hep::Volume glog; + + if (layerSense_[ly] < 1) { + std::vector pgonZ, pgonRin, pgonRout; + if (layerSense_[ly] == 0 || absorbMode_ == 0) { + double rmax = routF * cosAlpha_ - tol1; + pgonZ.emplace_back(-hthick); + pgonZ.emplace_back(hthick); + pgonRin.emplace_back(rinB); + pgonRin.emplace_back(rinB); + pgonRout.emplace_back(rmax); + pgonRout.emplace_back(rmax); + } else { + HGCalGeomTools::radius(zz - hthick, + zz + hthick, + zFrontB_, + rMinFront_, + slopeB_, + zFrontT_, + rMaxFront_, + slopeT_, + -layerSense_[ly], + pgonZ, + pgonRin, + pgonRout); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: z " << (zz - hthick) << ":" << (zz + hthick) + << " with " << pgonZ.size() << " palnes"; + for (unsigned int isec = 0; isec < pgonZ.size(); ++isec) + edm::LogVerbatim("HGCalGeom") + << "[" << isec << "] z " << pgonZ[isec] << " R " << pgonRin[isec] << ":" << pgonRout[isec]; +#endif + for (unsigned int isec = 0; isec < pgonZ.size(); ++isec) { + pgonZ[isec] -= zz; + pgonRout[isec] = pgonRout[isec] * cosAlpha_ - tol1; + } + } + dd4hep::Solid solid = dd4hep::Polyhedra(sectors_, -alpha_, 2._pi, pgonZ, pgonRin, pgonRout); + ns.addSolidNS(ns.prepend(name), solid); + glog = dd4hep::Volume(solid.name(), solid, matter); + ns.addVolumeNS(glog); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << solid.name() << " polyhedra of " << sectors_ + << " sectors covering " << convertRadToDeg(-alpha_) << ":" + << convertRadToDeg(-alpha_ + 2._pi) << " with " << pgonZ.size() + << " sections and filled with " << matter.name(); + for (unsigned int k = 0; k < pgonZ.size(); ++k) + edm::LogVerbatim("HGCalGeom") + << "[" << k << "] z " << pgonZ[k] << " R " << pgonRin[k] << ":" << pgonRout[k]; +#endif + } else { + dd4hep::Solid solid = dd4hep::Tube(rinB, routF, hthick, 0.0, 2._pi); + ns.addSolidNS(ns.prepend(name), solid); + glog = dd4hep::Volume(solid.name(), solid, matter); + ns.addVolumeNS(glog); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << solid.name() << " Tubs made of " << matter.name() + << " of dimensions " << rinB << ", " << routF << ", " << hthick + << ", 0.0, 360.0 and position " << glog.name() << " number " << copy << ":" + << layerCenter_[copy - 1]; +#endif + positionSensitive(ctxt, e, glog, rinB, routF, zz, layerSense_[ly], (copy - 1)); + } + + dd4hep::Position r1(0, 0, zz); + mother.placeVolume(glog, copy, r1); + ++copyNumber_[ii]; +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << glog.name() << " number " << copy << " positioned in " + << mother.name() << " at " << r1 << " with no rotation"; +#endif + zz += hthick; + } // End of loop over layers in a block + zi = zo; + laymin = laymax; + // Make consistency check of all the partitions of the block + if (std::abs(thickTot - layerThick_[i]) >= tol2) { + if (thickTot > layerThick_[i]) { + edm::LogError("HGCalGeom") << "Thickness of the partition " << layerThick_[i] << " is smaller than " + << thickTot << ": thickness of all its components **** ERROR ****"; + } else { + edm::LogWarning("HGCalGeom") << "Thickness of the partition " << layerThick_[i] << " does not match with " + << thickTot << " of the components"; + } + } + } // End of loop over blocks + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << copies_.size() << " different wafer copy numbers"; + int k(0); + for (std::unordered_set::const_iterator itr = copies_.begin(); itr != copies_.end(); ++itr, ++k) { + edm::LogVerbatim("HGCalGeom") << "Copy [" << k << "] : " << (*itr); + } + copies_.clear(); + edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalEEFileAlgo construction..."; +#endif + } + + void positionSensitive(cms::DDParsingContext& ctxt, + xml_h e, + const dd4hep::Volume& glog, + double rin, + double rout, + double zpos, + int layertype, + int layer) { + cms::DDNamespace ns(ctxt, e, true); + static const double sqrt3 = std::sqrt(3.0); + int layercenter = layerCenter_[layer]; + double r = 0.5 * (waferSize_ + waferSepar_); + double R = 2.0 * r / sqrt3; + double dy = 0.75 * R; + int N = (int)(0.5 * rout / r) + 2; + const auto& xyoff = geomTools_.shiftXY(layercenter, (waferSize_ + waferSepar_)); +#ifdef EDM_ML_DEBUG + int ium(0), ivm(0), iumAll(0), ivmAll(0), kount(0), ntot(0), nin(0); + std::vector ntype(6, 0); + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << glog.name() << " rin:rout " << rin << ":" << rout + << " zpos " << zpos << " N " << N << " for maximum u, v; r " << r << " R " << R + << " dy " << dy << " Shift " << xyoff.first << ":" << xyoff.second << " WaferSize " + << (waferSize_ + waferSepar_); +#endif + for (int u = -N; u <= N; ++u) { + for (int v = -N; v <= N; ++v) { +#ifdef EDM_ML_DEBUG + int iu = std::abs(u); + int iv = std::abs(v); +#endif + int nr = 2 * v; + int nc = -2 * u + v; + double xpos = xyoff.first + nc * r; + double ypos = xyoff.second + nr * dy; + const auto& corner = HGCalGeomTools::waferCorner(xpos, ypos, r, R, rin, rout, false); +#ifdef EDM_ML_DEBUG + ++ntot; + if (((corner.first <= 0) && std::abs(u) < 5 && std::abs(v) < 5) || (std::abs(u) < 2 && std::abs(v) < 2)) { + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: " << glog.name() << " R " << rin << ":" << rout + << "\n Z " << zpos << " LayerType " << layertype << " u " << u << " v " << v + << " with " << corner.first << " corners"; + } +#endif + int type = HGCalWaferType::getType(HGCalWaferIndex::waferIndex(layer, u, v, false), waferIndex_, waferTypes_); + if (corner.first > 0 && type >= 0) { + int copy = HGCalTypes::packTypeUV(type, u, v); +#ifdef EDM_ML_DEBUG + if (iu > ium) + ium = iu; + if (iv > ivm) + ivm = iv; + kount++; + if (copies_.count(copy) == 0) + copies_.insert(copy); +#endif + if (corner.first == (int)(HGCalParameters::k_CornerSize)) { +#ifdef EDM_ML_DEBUG + if (iu > iumAll) + iumAll = iu; + if (iv > ivmAll) + ivmAll = iv; + ++nin; +#endif + dd4hep::Position tran(xpos, ypos, 0.0); + if (layertype > 1) + type += 3; + glog.placeVolume(ns.volume(wafers_[type]), copy, tran); +#ifdef EDM_ML_DEBUG + ++ntype[type]; + edm::LogVerbatim("HGCalGeom") + << " DDHGCalEEFileAlgo: " << wafers_[type] << " number " << copy << " type " << layertype << ":" << type + << " positioned in " << glog.name() << " at " << tran << " with no rotation"; +#endif + } + } + } + } + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalEEFileAlgo: Maximum # of u " << ium << ":" << iumAll << " # of v " << ivm + << ":" << ivmAll << " and " << nin << ":" << kount << ":" << ntot << " wafers (" + << ntype[0] << ":" << ntype[1] << ":" << ntype[2] << ":" << ntype[3] << ":" + << ntype[4] << ":" << ntype[5] << ") for " << glog.name() << " R " << rin << ":" + << rout; +#endif + } + + //Required data members to cache the values from XML file + HGCalGeomTools geomTools_; + + std::vector wafers_; // Wafers + std::vector materials_; // Materials + std::vector names_; // Names + std::vector thick_; // Thickness of the material + std::vector copyNumber_; // Initial copy numbers + std::vector layers_; // Number of layers in a section + std::vector layerThick_; // Thickness of each section + std::vector layerType_; // Type of the layer + std::vector layerSense_; // Content of a layer (sensitive?) + std::vector layerCenter_; // Centering of the wafers + int firstLayer_; // Copy # of the first sensitive layer + int absorbMode_; // Absorber mode + double zMinBlock_; // Starting z-value of the block + std::vector rad100to200_; // Parameters for 120-200mum trans. + std::vector rad200to300_; // Parameters for 200-300mum trans. + double zMinRadPar_; // Minimum z for radius parametriz. + std::vector waferIndex_; // Wafer index for the types + std::vector waferTypes_; // Wafer types + int choiceType_; // Type of parametrization to be used + int nCutRadPar_; // Cut off threshold for corners + double fracAreaMin_; // Minimum fractional conatined area + double waferSize_; // Width of the wafer + double waferSepar_; // Sensor separation + int sectors_; // Sectors + std::vector slopeB_; // Slope at the lower R + std::vector zFrontB_; // Starting Z values for the slopes + std::vector rMinFront_; // Corresponding rMin's + std::vector slopeT_; // Slopes at the larger R + std::vector zFrontT_; // Starting Z values for the slopes + std::vector rMaxFront_; // Corresponding rMax's + std::unordered_set copies_; // List of copy #'s + double alpha_, cosAlpha_; +}; + +static long algorithm(dd4hep::Detector& /* description */, + cms::DDParsingContext& ctxt, + xml_h e, + dd4hep::SensitiveDetector& /* sens */) { + HGCalEEFileAlgo eealgo(ctxt, e); + return cms::s_executed; +} + +DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalEEFileAlgo, algorithm) diff --git a/Geometry/HGCalCommonData/plugins/dd4hep/DDHGCalHEFileAlgo.cc b/Geometry/HGCalCommonData/plugins/dd4hep/DDHGCalHEFileAlgo.cc new file mode 100644 index 0000000000000..c0c85a59674ee --- /dev/null +++ b/Geometry/HGCalCommonData/plugins/dd4hep/DDHGCalHEFileAlgo.cc @@ -0,0 +1,599 @@ +/////////////////////////////////////////////////////////////////////////////// +// File: DDHGCalHEFileAlgo.cc +// Description: Geometry factory class for HGCal (Mix) adopted for DD4HEP +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +#include "Geometry/HGCalCommonData/interface/HGCalParameters.h" +#include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" +#include "Geometry/HGCalCommonData/interface/HGCalWaferIndex.h" +#include "Geometry/HGCalCommonData/interface/HGCalWaferType.h" +#include "DD4hep/DetFactoryHelper.h" +#include "DataFormats/Math/interface/CMSUnits.h" +#include "DetectorDescription/DDCMS/interface/DDPlugins.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +//#define EDM_ML_DEBUG +using namespace cms_units::operators; + +struct HGCalHEAlgo { + HGCalHEAlgo() { throw cms::Exception("HGCalGeom") << "Wrong initialization to HGCalHEAlgo"; } + HGCalHEAlgo(cms::DDParsingContext& ctxt, xml_h e) { + cms::DDNamespace ns(ctxt, e, true); + cms::DDAlgoArguments args(ctxt, e); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: Creating an instance"; +#endif + + static constexpr double tol1 = 0.01; + dd4hep::Volume mother = ns.volume(args.parentName()); + + waferNames_ = args.value>("WaferNames"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << waferNames_.size() << " wafers"; + for (unsigned int i = 0; i < waferNames_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << waferNames_[i]; +#endif + materials_ = args.value>("MaterialNames"); + volumeNames_ = args.value>("VolumeNames"); + thickness_ = args.value>("Thickness"); + copyNumber_.resize(materials_.size(), 1); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << materials_.size() << " types of volumes"; + for (unsigned int i = 0; i < volumeNames_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << volumeNames_[i] << " of thickness " << thickness_[i] + << " filled with " << materials_[i] << " first copy number " << copyNumber_[i]; +#endif + layerNumbers_ = args.value>("Layers"); + layerThick_ = args.value>("LayerThick"); + rMixLayer_ = args.value>("LayerRmix"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "There are " << layerNumbers_.size() << " blocks"; + for (unsigned int i = 0; i < layerNumbers_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << layerThick_[i] << " Rmid " + << rMixLayer_[i] << " with " << layerNumbers_[i] << " layers"; +#endif + layerType_ = args.value>("LayerType"); + layerSense_ = args.value>("LayerSense"); + firstLayer_ = args.value("FirstLayer"); + absorbMode_ = args.value("AbsorberMode"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "First Layer " << firstLayer_ << " and " + << "Absober mode " << absorbMode_; +#endif + layerCenter_ = args.value>("LayerCenter"); +#ifdef EDM_ML_DEBUG + for (unsigned int i = 0; i < layerCenter_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "LayerCenter [" << i << "] " << layerCenter_[i]; +#endif + if (firstLayer_ > 0) { + for (unsigned int i = 0; i < layerType_.size(); ++i) { + if (layerSense_[i] > 0) { + int ii = layerType_[i]; + copyNumber_[ii] = firstLayer_; +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "First copy number for layer type " << i << ":" << ii << " with " + << materials_[ii] << " changed to " << copyNumber_[ii]; +#endif + break; + } + } + } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "There are " << layerType_.size() << " layers"; + for (unsigned int i = 0; i < layerType_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType_[i] << " sensitive class " + << layerSense_[i]; +#endif + materialsTop_ = args.value>("TopMaterialNames"); + namesTop_ = args.value>("TopVolumeNames"); + layerThickTop_ = args.value>("TopLayerThickness"); + layerTypeTop_ = args.value>("TopLayerType"); + copyNumberTop_.resize(materialsTop_.size(), 1); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << materialsTop_.size() + << " types of volumes in the top part"; + for (unsigned int i = 0; i < materialsTop_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << namesTop_[i] << " of thickness " << layerThickTop_[i] + << " filled with " << materialsTop_[i] << " first copy number " + << copyNumberTop_[i]; + edm::LogVerbatim("HGCalGeom") << "There are " << layerTypeTop_.size() << " layers in the top part"; + for (unsigned int i = 0; i < layerTypeTop_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerTypeTop_[i]; +#endif + materialsBot_ = args.value>("BottomMaterialNames"); + namesBot_ = args.value>("BottomVolumeNames"); + layerTypeBot_ = args.value>("BottomLayerType"); + layerSenseBot_ = args.value>("BottomLayerSense"); + layerThickBot_ = args.value>("BottomLayerThickness"); + copyNumberBot_.resize(materialsBot_.size(), 1); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << materialsBot_.size() + << " types of volumes in the bottom part"; + for (unsigned int i = 0; i < materialsBot_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << namesBot_[i] << " of thickness " << layerThickBot_[i] + << " filled with " << materialsBot_[i] << " first copy number " + << copyNumberBot_[i]; + edm::LogVerbatim("HGCalGeom") << "There are " << layerTypeBot_.size() << " layers in the bottom part"; + for (unsigned int i = 0; i < layerTypeBot_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerTypeBot_[i] + << " sensitive class " << layerSenseBot_[i]; +#endif + zMinBlock_ = args.value("zMinBlock"); + rad100to200_ = args.value>("rad100to200"); + rad200to300_ = args.value>("rad200to300"); + zMinRadPar_ = args.value("zMinForRadPar"); + choiceType_ = args.value("choiceType"); + nCutRadPar_ = args.value("nCornerCut"); + fracAreaMin_ = args.value("fracAreaMin"); + waferSize_ = args.value("waferSize"); + waferSepar_ = args.value("SensorSeparation"); + sectors_ = args.value("Sectors"); + alpha_ = (1._pi) / sectors_; + cosAlpha_ = cos(alpha_); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: zStart " << zMinBlock_ + << " radius for wafer type separation uses " << rad100to200_.size() + << " parameters; zmin " << zMinRadPar_ << " cutoff " << choiceType_ << ":" + << nCutRadPar_ << ":" << fracAreaMin_ << " wafer width " << waferSize_ + << " separations " << waferSepar_ << " sectors " << sectors_ << ":" + << convertRadToDeg(alpha_) << ":" << cosAlpha_; + for (unsigned int k = 0; k < rad100to200_.size(); ++k) + edm::LogVerbatim("HGCalGeom") << "[" << k << "] 100-200 " << rad100to200_[k] << " 200-300 " << rad200to300_[k]; +#endif + waferIndex_ = args.value>("WaferIndex"); + waferTypes_ = args.value>("WaferTypes"); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "waferTypes with " << waferTypes_.size() << " entries"; + for (unsigned int k = 0; k < waferTypes_.size(); ++k) + edm::LogVerbatim("HGCalGeom") << "[" << k << "] " << waferIndex_[k] << " (" + << HGCalWaferIndex::waferLayer(waferIndex_[k]) << ", " + << HGCalWaferIndex::waferU(waferIndex_[k]) << ", " + << HGCalWaferIndex::waferV(waferIndex_[k]) << ") : " << waferTypes_[k]; +#endif + slopeB_ = args.value>("SlopeBottom"); + zFrontB_ = args.value>("ZFrontBottom"); + rMinFront_ = args.value>("RMinFront"); + slopeT_ = args.value>("SlopeTop"); + zFrontT_ = args.value>("ZFrontTop"); + rMaxFront_ = args.value>("RMaxFront"); +#ifdef EDM_ML_DEBUG + for (unsigned int i = 0; i < slopeB_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << zFrontB_[i] << " Rmin " << rMinFront_[i] + << " Slope " << slopeB_[i]; + for (unsigned int i = 0; i < slopeT_.size(); ++i) + edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << zFrontT_[i] << " Rmax " << rMaxFront_[i] + << " Slope " << slopeT_[i]; + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: NameSpace " << ns.name(); + + edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalHEFileAlgo..."; + copies_.clear(); +#endif + + double zi(zMinBlock_); + int laymin(0); + for (unsigned int i = 0; i < layerNumbers_.size(); i++) { + double zo = zi + layerThick_[i]; + double routF = HGCalGeomTools::radius(zi, zFrontT_, rMaxFront_, slopeT_); + int laymax = laymin + layerNumbers_[i]; + double zz = zi; + double thickTot(0); + for (int ly = laymin; ly < laymax; ++ly) { + int ii = layerType_[ly]; + int copy = copyNumber_[ii]; + double hthick = 0.5 * thickness_[ii]; + double rinB = HGCalGeomTools::radius(zo, zFrontB_, rMinFront_, slopeB_); + zz += hthick; + thickTot += thickness_[ii]; + + std::string name = volumeNames_[ii] + std::to_string(copy); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: Layer " << ly << ":" << ii << " Front " << zi << ", " + << routF << " Back " << zo << ", " << rinB << " superlayer thickness " + << layerThick_[i]; +#endif + + dd4hep::Material matter = ns.material(materials_[ii]); + dd4hep::Volume glog; + + if (layerSense_[ly] < 1) { + std::vector pgonZ, pgonRin, pgonRout; + if (layerSense_[ly] == 0 || absorbMode_ == 0) { + double rmax = + (std::min(routF, HGCalGeomTools::radius(zz + hthick, zFrontT_, rMaxFront_, slopeT_)) * cosAlpha_) - + tol1; + pgonZ.emplace_back(-hthick); + pgonZ.emplace_back(hthick); + pgonRin.emplace_back(rinB); + pgonRin.emplace_back(rinB); + pgonRout.emplace_back(rmax); + pgonRout.emplace_back(rmax); + } else { + HGCalGeomTools::radius(zz - hthick, + zz + hthick, + zFrontB_, + rMinFront_, + slopeB_, + zFrontT_, + rMaxFront_, + slopeT_, + -layerSense_[ly], + pgonZ, + pgonRin, + pgonRout); + for (unsigned int isec = 0; isec < pgonZ.size(); ++isec) { + pgonZ[isec] -= zz; + pgonRout[isec] = pgonRout[isec] * cosAlpha_ - tol1; + } + } + + dd4hep::Solid solid = dd4hep::Polyhedra(sectors_, -alpha_, 2._pi, pgonZ, pgonRin, pgonRout); + ns.addSolidNS(ns.prepend(name), solid); + glog = dd4hep::Volume(solid.name(), solid, matter); + ns.addVolumeNS(glog); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << solid.name() << " polyhedra of " << sectors_ + << " sectors covering " << convertRadToDeg(-alpha_) << ":" + << convertRadToDeg(-alpha_ + 2._pi) << " with " << pgonZ.size() << " sections"; + for (unsigned int k = 0; k < pgonZ.size(); ++k) + edm::LogVerbatim("HGCalGeom") + << "[" << k << "] z " << pgonZ[k] << " R " << pgonRin[k] << ":" << pgonRout[k]; +#endif + } else { + dd4hep::Solid solid = dd4hep::Tube(rinB, routF, hthick, 0.0, 2._pi); + ns.addSolidNS(ns.prepend(name), solid); + glog = dd4hep::Volume(solid.name(), solid, matter); + ns.addVolumeNS(glog); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << solid.name() << " Tubs made of " << matter.name() + << " of dimensions " << rinB << ", " << routF << ", " << hthick + << ", 0.0, 360.0 and positioned in: " << glog.name() << " number " << copy; +#endif + positionMix(ctxt, e, glog, name, copy, thickness_[ii], matter, rinB, rMixLayer_[i], routF, zz); + } + + dd4hep::Position r1(0, 0, zz); + mother.placeVolume(glog, copy, r1); + ++copyNumber_[ii]; +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << glog.name() << " number " << copy << " positioned in " + << mother.name() << " at " << r1 << " with no rotation"; +#endif + zz += hthick; + } // End of loop over layers in a block + zi = zo; + laymin = laymax; + if (std::abs(thickTot - layerThick_[i]) > tol2_) { + if (thickTot > layerThick_[i]) { + edm::LogError("HGCalGeom") << "Thickness of the partition " << layerThick_[i] << " is smaller than " + << thickTot << ": thickness of all its components **** ERROR ****"; + } else { + edm::LogWarning("HGCalGeom") << "Thickness of the partition " << layerThick_[i] << " does not match with " + << thickTot << " of the components"; + } + } + } // End of loop over blocks + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << copies_.size() << " different wafer copy numbers"; + int k(0); + for (std::unordered_set::const_iterator itr = copies_.begin(); itr != copies_.end(); ++itr, ++k) { + edm::LogVerbatim("HGCalGeom") << "Copy [" << k << "] : " << (*itr); + } + copies_.clear(); + edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalHEFileAlgo construction..."; +#endif + } + + void positionMix(cms::DDParsingContext& ctxt, + xml_h e, + const dd4hep::Volume& glog, + const std::string& nameM, + int copyM, + double thick, + const dd4hep::Material& matter, + double rin, + double rmid, + double rout, + double zz) { + cms::DDNamespace ns(ctxt, e, true); + + dd4hep::Volume glog1; + for (unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) { + int ii = layerTypeTop_[ly]; + copyNumberTop_[ii] = copyM; + } + for (unsigned int ly = 0; ly < layerTypeBot_.size(); ++ly) { + int ii = layerTypeBot_[ly]; + copyNumberBot_[ii] = copyM; + } + double hthick = 0.5 * thick; + // Make the top part first + std::string name = nameM + "Top"; + + dd4hep::Solid solid = dd4hep::Tube(rmid, rout, hthick, 0.0, 2._pi); + ns.addSolidNS(ns.prepend(name), solid); + glog1 = dd4hep::Volume(solid.name(), solid, matter); + ns.addVolumeNS(glog1); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << solid.name() << " Tubs made of " << matter.name() + << " of dimensions " << rmid << ", " << rout << ", " << hthick << ", 0.0, 360.0"; +#endif + glog.placeVolume(glog1, 1); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << glog1.name() << " number 1 positioned in " << glog.name() + << " at (0, 0, 0) with no rotation"; +#endif + double thickTot(0), zpos(-hthick); + for (unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) { + int ii = layerTypeTop_[ly]; + int copy = copyNumberTop_[ii]; + double hthickl = 0.5 * layerThickTop_[ii]; + thickTot += layerThickTop_[ii]; + name = namesTop_[ii] + std::to_string(copy); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: Layer " << ly << ":" << ii << " R " << rmid << ":" << rout + << " Thick " << layerThickTop_[ii]; +#endif + + dd4hep::Material matter1 = ns.material(materialsTop_[ii]); + solid = dd4hep::Tube(rmid, rout, hthickl, 0.0, 2._pi); + ns.addSolidNS(ns.prepend(name), solid); + dd4hep::Volume glog2 = dd4hep::Volume(solid.name(), solid, matter1); + ns.addVolumeNS(glog2); + +#ifdef EDM_ML_DEBUG + double eta1 = -log(tan(0.5 * atan(rmid / zz))); + double eta2 = -log(tan(0.5 * atan(rout / zz))); + edm::LogVerbatim("HGCalGeom") << name << " z|rin|rout " << zz << ":" << rmid << ":" << rout << " eta " << eta1 + << ":" << eta2; + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << solid.name() << " Tubs made of " << matter1.name() + << " of dimensions " << rmid << ", " << rout << ", " << hthickl << ", 0.0, 360.0"; +#endif + zpos += hthickl; + + dd4hep::Position r1(0, 0, zpos); + glog1.placeVolume(glog2, copy, r1); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: Position " << glog2.name() << " number " << copy << " in " + << glog1.name() << " at " << r1 << " with no rotation"; +#endif + ++copyNumberTop_[ii]; + zpos += hthickl; + } + if (std::abs(thickTot - thick) > tol2_) { + if (thickTot > thick) { + edm::LogError("HGCalGeom") << "Thickness of the partition " << thick << " is smaller than " << thickTot + << ": thickness of all its components in the top part **** ERROR ****"; + } else { + edm::LogWarning("HGCalGeom") << "Thickness of the partition " << thick << " does not match with " << thickTot + << " of the components in top part"; + } + } + + // Make the bottom part next + name = nameM + "Bottom"; + + solid = dd4hep::Tube(rin, rmid, hthick, 0.0, 2._pi); + ns.addSolidNS(ns.prepend(name), solid); + glog1 = dd4hep::Volume(solid.name(), solid, matter); + ns.addVolumeNS(glog1); + +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << solid.name() << " Tubs made of " << matter.name() + << " of dimensions " << rin << ", " << rmid << ", " << hthick << ", 0.0, 360.0"; +#endif + + glog.placeVolume(glog1, 1); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << glog1.name() << " number 1 positioned in " << glog.name() + << " at (0, 0, 0) with no rotation"; +#endif + thickTot = 0; + zpos = -hthick; + for (unsigned int ly = 0; ly < layerTypeBot_.size(); ++ly) { + int ii = layerTypeBot_[ly]; + int copy = copyNumberBot_[ii]; + double hthickl = 0.5 * layerThickBot_[ii]; + thickTot += layerThickBot_[ii]; + name = namesBot_[ii] + std::to_string(copy); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: Layer " << ly << ":" << ii << " R " << rin << ":" << rmid + << " Thick " << layerThickBot_[ii]; +#endif + + dd4hep::Material matter1 = ns.material(materialsBot_[ii]); + solid = dd4hep::Tube(rin, rmid, hthickl, 0.0, 2._pi); + ns.addSolidNS(ns.prepend(name), solid); + dd4hep::Volume glog2 = dd4hep::Volume(solid.name(), solid, matter1); + ns.addVolumeNS(glog2); + +#ifdef EDM_ML_DEBUG + double eta1 = -log(tan(0.5 * atan(rin / zz))); + double eta2 = -log(tan(0.5 * atan(rmid / zz))); + edm::LogVerbatim("HGCalGeom") << name << " z|rin|rout " << zz << ":" << rin << ":" << rmid << " eta " << eta1 + << ":" << eta2; + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << solid.name() << " Tubs made of " << matter1.name() + << " of dimensions " << rin << ", " << rmid << ", " << hthickl << ", 0.0, 360.0"; +#endif + zpos += hthickl; + + dd4hep::Position r1(0, 0, zpos); + glog1.placeVolume(glog2, copy, r1); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: Position " << glog2.name() << " number " << copy << " in " + << glog1.name() << " at " << r1 << " with no rotation"; +#endif + if (layerSenseBot_[ly] != 0) { +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: z " << (zz + zpos) << " Center " << copy << ":" + << (copy - firstLayer_) << ":" << layerCenter_[copy - firstLayer_]; +#endif + positionSensitive(ctxt, e, glog2, rin, rmid, zz + zpos, layerSenseBot_[ly], (copy - firstLayer_)); + } + zpos += hthickl; + ++copyNumberBot_[ii]; + } + if (std::abs(thickTot - thick) > tol2_) { + if (thickTot > thick) { + edm::LogError("HGCalGeom") << "Thickness of the partition " << thick << " is smaller than " << thickTot + << ": thickness of all its components in the top part **** ERROR ****"; + } else { + edm::LogWarning("HGCalGeom") << "Thickness of the partition " << thick << " does not match with " << thickTot + << " of the components in top part"; + } + } + } + + void positionSensitive(cms::DDParsingContext& ctxt, + xml_h e, + const dd4hep::Volume& glog, + double rin, + double rout, + double zpos, + int layertype, + int layer) { + cms::DDNamespace ns(ctxt, e, true); + int layercenter = layerCenter_[layer]; + static const double sqrt3 = std::sqrt(3.0); + double r = 0.5 * (waferSize_ + waferSepar_); + double R = 2.0 * r / sqrt3; + double dy = 0.75 * R; + int N = (int)(0.5 * rout / r) + 2; + const auto& xyoff = geomTools_.shiftXY(layercenter, (waferSize_ + waferSepar_)); +#ifdef EDM_ML_DEBUG + int ium(0), ivm(0), iumAll(0), ivmAll(0), kount(0), ntot(0), nin(0); + std::vector ntype(6, 0); + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << glog.name() << " rout " << rout << " N " << N + << " for maximum u, v Offset; Shift " << xyoff.first << ":" << xyoff.second + << " WaferSize " << (waferSize_ + waferSepar_); +#endif + for (int u = -N; u <= N; ++u) { + for (int v = -N; v <= N; ++v) { +#ifdef EDM_ML_DEBUG + int iu = std::abs(u); + int iv = std::abs(v); +#endif + int nr = 2 * v; + int nc = -2 * u + v; + double xpos = xyoff.first + nc * r; + double ypos = xyoff.second + nr * dy; + const auto& corner = HGCalGeomTools::waferCorner(xpos, ypos, r, R, rin, rout, false); +#ifdef EDM_ML_DEBUG + ++ntot; +#endif + int type = HGCalWaferType::getType(HGCalWaferIndex::waferIndex(layer, u, v, false), waferIndex_, waferTypes_); + if (corner.first > 0 && type >= 0) { + int copy = HGCalTypes::packTypeUV(type, u, v); +#ifdef EDM_ML_DEBUG + if (iu > ium) + ium = iu; + if (iv > ivm) + ivm = iv; + kount++; + if (copies_.count(copy) == 0) + copies_.insert(copy); +#endif + if (corner.first == (int)(HGCalParameters::k_CornerSize)) { +#ifdef EDM_ML_DEBUG + if (iu > iumAll) + iumAll = iu; + if (iv > ivmAll) + ivmAll = iv; + ++nin; +#endif + + dd4hep::Position tran(xpos, ypos, 0.0); + if (layertype > 1) + type += 3; + glog.placeVolume(ns.volume(waferNames_[type]), copy, tran); + +#ifdef EDM_ML_DEBUG + ++ntype[type]; + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: " << glog.name() << " number " << copy + << " positioned in " << glog.name() << " at " << tran << " with no rotation"; +#endif + } + } + } + } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "DDHGCalHEFileAlgo: Maximum # of u " << ium << ":" << iumAll << " # of v " << ivm + << ":" << ivmAll << " and " << nin << ":" << kount << ":" << ntot << " wafers (" + << ntype[0] << ":" << ntype[1] << ":" << ntype[2] << ":" << ntype[3] << ":" + << ntype[4] << ":" << ntype[5] << ") for " << glog.name() << " R " << rin << ":" + << rout; +#endif + } + + //Required data members to cache the values from XML file + HGCalGeomTools geomTools_; + static constexpr double tol2_ = 0.00001; + + std::vector waferNames_; // Wafer names + std::vector materials_; // Materials + std::vector volumeNames_; // Names + std::vector thickness_; // Thickness of the material + std::vector copyNumber_; // Initial copy numbers + std::vector layerNumbers_; // Number of layers in a section + std::vector layerThick_; // Thickness of each section + std::vector rMixLayer_; // Partition between Si/Sci part + std::vector layerType_; // Type of the layer + std::vector layerSense_; // Content of a layer (sensitive?) + int firstLayer_; // Copy # of the first sensitive layer + int absorbMode_; // Absorber mode + std::vector materialsTop_; // Materials of top layers + std::vector namesTop_; // Names of top layers + std::vector layerThickTop_; // Thickness of the top sections + std::vector layerTypeTop_; // Type of the Top layer + std::vector copyNumberTop_; // Initial copy numbers (top section) + std::vector materialsBot_; // Materials of bottom layers + std::vector namesBot_; // Names of bottom layers + std::vector layerThickBot_; // Thickness of the bottom sections + std::vector layerTypeBot_; // Type of the bottom layers + std::vector copyNumberBot_; // Initial copy numbers (bot section) + std::vector layerSenseBot_; // Content of bottom layer (sensitive?) + std::vector layerCenter_; // Centering of the wafers + + double zMinBlock_; // Starting z-value of the block + std::vector rad100to200_; // Parameters for 120-200mum trans. + std::vector rad200to300_; // Parameters for 200-300mum trans. + double zMinRadPar_; // Minimum z for radius parametriz. + int choiceType_; // Type of parametrization to be used + int nCutRadPar_; // Cut off threshold for corners + double fracAreaMin_; // Minimum fractional conatined area + double waferSize_; // Width of the wafer + double waferSepar_; // Sensor separation + int sectors_; // Sectors + std::vector waferIndex_; // Wafer index for the types + std::vector waferTypes_; // Wafer types + std::vector slopeB_; // Slope at the lower R + std::vector zFrontB_; // Starting Z values for the slopes + std::vector rMinFront_; // Corresponding rMin's + std::vector slopeT_; // Slopes at the larger R + std::vector zFrontT_; // Starting Z values for the slopes + std::vector rMaxFront_; // Corresponding rMax's + std::unordered_set copies_; // List of copy #'s + double alpha_, cosAlpha_; +}; + +static long algorithm(dd4hep::Detector& /* description */, + cms::DDParsingContext& ctxt, + xml_h e, + dd4hep::SensitiveDetector& /* sens */) { + HGCalHEAlgo healgo(ctxt, e); + return cms::s_executed; +} + +DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalHEFileAlgo, algorithm) diff --git a/Geometry/HGCalCommonData/src/HGCalTypes.cc b/Geometry/HGCalCommonData/src/HGCalTypes.cc new file mode 100644 index 0000000000000..1d59508d9b3f8 --- /dev/null +++ b/Geometry/HGCalCommonData/src/HGCalTypes.cc @@ -0,0 +1,26 @@ +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" + +int32_t HGCalTypes::packTypeUV(int type, int u, int v) { + int32_t iu = std::abs(u); + int32_t iv = std::abs(v); + int32_t copy = type * factype_ + iv * facv_ + iu; + if (u < 0) + copy += signu_; + if (v < 0) + copy += signv_; + return copy; +} + +int32_t HGCalTypes::getUnpackedType(int copy) { return (copy / factype_); } + +int32_t HGCalTypes::getUnpackedU(int copy) { + int32_t iu = (copy % maxuv_); + int32_t u = (((copy / signu_) % maxsign_) > 0) ? -iu : iu; + return u; +} + +int32_t HGCalTypes::getUnpackedV(int copy) { + int32_t iv = ((copy / facv_) % maxuv_); + int32_t v = (((copy / signv_) % maxsign_) > 0) ? -iv : iv; + return v; +}