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;
+}