Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:15:14

0001 #include "Geometry/HGCalTBCommonData/interface/HGCalTBGeomParameters.h"
0002 
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 
0006 #include "DataFormats/Math/interface/GeantUnits.h"
0007 #include "DataFormats/Math/interface/Point3D.h"
0008 #include "DetectorDescription/Core/interface/DDConstant.h"
0009 #include "DetectorDescription/Core/interface/DDFilter.h"
0010 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0011 #include "DetectorDescription/Core/interface/DDSolid.h"
0012 #include "DetectorDescription/Core/interface/DDValue.h"
0013 #include "DetectorDescription/Core/interface/DDutils.h"
0014 #include "DetectorDescription/RegressionTest/interface/DDErrorDetection.h"
0015 #include "Geometry/HGCalCommonData/interface/HGCalTypes.h"
0016 #include "Geometry/HGCalCommonData/interface/HGCalWaferIndex.h"
0017 
0018 #include <algorithm>
0019 #include <sstream>
0020 #include <unordered_set>
0021 
0022 //#define EDM_ML_DEBUG
0023 using namespace geant_units::operators;
0024 
0025 const double tolerance = 0.001;
0026 const double tolmin = 1.e-20;
0027 
0028 HGCalTBGeomParameters::HGCalTBGeomParameters() : sqrt3_(std::sqrt(3.0)) {
0029 #ifdef EDM_ML_DEBUG
0030   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters::HGCalTBGeomParameters "
0031                                 << "constructor";
0032 #endif
0033 }
0034 
0035 void HGCalTBGeomParameters::loadGeometryHexagon(const DDFilteredView& _fv,
0036                                                 HGCalTBParameters& php,
0037                                                 const std::string& sdTag1,
0038                                                 const DDCompactView* cpv,
0039                                                 const std::string& sdTag2,
0040                                                 const std::string& sdTag3,
0041                                                 HGCalGeometryMode::WaferMode mode) {
0042   DDFilteredView fv = _fv;
0043   bool dodet(true);
0044   std::map<int, HGCalTBGeomParameters::layerParameters> layers;
0045   std::vector<HGCalTBParameters::hgtrform> trforms;
0046   std::vector<bool> trformUse;
0047 
0048   while (dodet) {
0049     const DDSolid& sol = fv.logicalPart().solid();
0050     // Layers first
0051     std::vector<int> copy = fv.copyNumbers();
0052     int nsiz = static_cast<int>(copy.size());
0053     int lay = (nsiz > 0) ? copy[nsiz - 1] : 0;
0054     int zp = (nsiz > 2) ? copy[nsiz - 3] : -1;
0055     if (zp != 1)
0056       zp = -1;
0057     if (lay == 0) {
0058       throw cms::Exception("DDException") << "Funny layer # " << lay << " zp " << zp << " in " << nsiz << " components";
0059     } else {
0060       if (std::find(php.layer_.begin(), php.layer_.end(), lay) == php.layer_.end())
0061         php.layer_.emplace_back(lay);
0062       auto itr = layers.find(lay);
0063       if (itr == layers.end()) {
0064         double rin(0), rout(0);
0065         double zz = HGCalTBParameters::k_ScaleFromDDD * fv.translation().Z();
0066         if ((sol.shape() == DDSolidShape::ddpolyhedra_rz) || (sol.shape() == DDSolidShape::ddpolyhedra_rrz)) {
0067           const DDPolyhedra& polyhedra = static_cast<DDPolyhedra>(sol);
0068           const std::vector<double>& rmin = polyhedra.rMinVec();
0069           const std::vector<double>& rmax = polyhedra.rMaxVec();
0070           rin = 0.5 * HGCalTBParameters::k_ScaleFromDDD * (rmin[0] + rmin[1]);
0071           rout = 0.5 * HGCalTBParameters::k_ScaleFromDDD * (rmax[0] + rmax[1]);
0072         } else if (sol.shape() == DDSolidShape::ddtubs) {
0073           const DDTubs& tube = static_cast<DDTubs>(sol);
0074           rin = HGCalTBParameters::k_ScaleFromDDD * tube.rIn();
0075           rout = HGCalTBParameters::k_ScaleFromDDD * tube.rOut();
0076         }
0077         HGCalTBGeomParameters::layerParameters laypar(rin, rout, zz);
0078         layers[lay] = laypar;
0079       }
0080       DD3Vector x, y, z;
0081       fv.rotation().GetComponents(x, y, z);
0082       const CLHEP::HepRep3x3 rotation(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
0083       const CLHEP::HepRotation hr(rotation);
0084       double xx = HGCalTBParameters::k_ScaleFromDDD * fv.translation().X();
0085       if (std::abs(xx) < tolerance)
0086         xx = 0;
0087       double yy = HGCalTBParameters::k_ScaleFromDDD * fv.translation().Y();
0088       if (std::abs(yy) < tolerance)
0089         yy = 0;
0090       double zz = HGCalTBParameters::k_ScaleFromDDD * fv.translation().Z();
0091       const CLHEP::Hep3Vector h3v(xx, yy, zz);
0092       HGCalTBParameters::hgtrform mytrf;
0093       mytrf.zp = zp;
0094       mytrf.lay = lay;
0095       mytrf.sec = 0;
0096       mytrf.subsec = 0;
0097       mytrf.h3v = h3v;
0098       mytrf.hr = hr;
0099       trforms.emplace_back(mytrf);
0100       trformUse.emplace_back(false);
0101     }
0102     dodet = fv.next();
0103   }
0104 
0105   // Then wafers
0106   // This assumes layers are build starting from 1 (which on 25 Jan 2016, they
0107   // were) to ensure that new copy numbers are always added to the end of the
0108   // list.
0109   std::unordered_map<int32_t, int32_t> copies;
0110   HGCalTBParameters::layer_map copiesInLayers(layers.size() + 1);
0111   std::vector<int32_t> wafer2copy;
0112   std::vector<HGCalTBGeomParameters::cellParameters> wafers;
0113   std::string attribute = "Volume";
0114   DDValue val1(attribute, sdTag2, 0.0);
0115   DDSpecificsMatchesValueFilter filter1{val1};
0116   DDFilteredView fv1(*cpv, filter1);
0117   bool ok = fv1.firstChild();
0118   if (!ok) {
0119     throw cms::Exception("DDException") << "Attribute " << val1 << " not found but needed.";
0120   } else {
0121     dodet = true;
0122     std::unordered_set<std::string> names;
0123     while (dodet) {
0124       const DDSolid& sol = fv1.logicalPart().solid();
0125       const std::string& name = fv1.logicalPart().name().name();
0126       std::vector<int> copy = fv1.copyNumbers();
0127       int nsiz = static_cast<int>(copy.size());
0128       int wafer = (nsiz > 0) ? copy[nsiz - 1] : 0;
0129       int layer = (nsiz > 1) ? copy[nsiz - 2] : 0;
0130       if (nsiz < 2) {
0131         throw cms::Exception("DDException") << "Funny wafer # " << wafer << " in " << nsiz << " components";
0132       } else if (layer > static_cast<int>(layers.size())) {
0133         edm::LogWarning("HGCalGeom") << "Funny wafer # " << wafer << " Layer " << layer << ":" << layers.size()
0134                                      << " among " << nsiz << " components";
0135       } else {
0136         auto itr = copies.find(wafer);
0137         auto cpy = copiesInLayers[layer].find(wafer);
0138         if (itr != copies.end() && cpy == copiesInLayers[layer].end()) {
0139           copiesInLayers[layer][wafer] = itr->second;
0140         }
0141         if (itr == copies.end()) {
0142           copies[wafer] = wafer2copy.size();
0143           copiesInLayers[layer][wafer] = wafer2copy.size();
0144           double xx = HGCalTBParameters::k_ScaleFromDDD * fv1.translation().X();
0145           if (std::abs(xx) < tolerance)
0146             xx = 0;
0147           double yy = HGCalTBParameters::k_ScaleFromDDD * fv1.translation().Y();
0148           if (std::abs(yy) < tolerance)
0149             yy = 0;
0150           wafer2copy.emplace_back(wafer);
0151           GlobalPoint p(xx, yy, HGCalTBParameters::k_ScaleFromDDD * fv1.translation().Z());
0152           HGCalTBGeomParameters::cellParameters cell(false, wafer, p);
0153           wafers.emplace_back(cell);
0154           if (names.count(name) == 0) {
0155             std::vector<double> zv, rv;
0156             if (mode == HGCalGeometryMode::Polyhedra) {
0157               const DDPolyhedra& polyhedra = static_cast<DDPolyhedra>(sol);
0158               zv = polyhedra.zVec();
0159               rv = polyhedra.rMaxVec();
0160             } else {
0161               const DDExtrudedPolygon& polygon = static_cast<DDExtrudedPolygon>(sol);
0162               zv = polygon.zVec();
0163               rv = polygon.xVec();
0164             }
0165             php.waferR_ = 2.0 * HGCalTBParameters::k_ScaleFromDDDToG4 * rv[0] * tan30deg_;
0166             php.waferSize_ = HGCalTBParameters::k_ScaleFromDDD * rv[0];
0167             double dz = 0.5 * HGCalTBParameters::k_ScaleFromDDDToG4 * (zv[1] - zv[0]);
0168 #ifdef EDM_ML_DEBUG
0169             edm::LogVerbatim("HGCalGeom")
0170                 << "Mode " << mode << " R " << php.waferSize_ << ":" << php.waferR_ << " z " << dz;
0171 #endif
0172             HGCalTBParameters::hgtrap mytr;
0173             mytr.lay = 1;
0174             mytr.bl = php.waferR_;
0175             mytr.tl = php.waferR_;
0176             mytr.h = php.waferR_;
0177             mytr.dz = dz;
0178             mytr.alpha = 0.0;
0179             mytr.cellSize = waferSize_;
0180             php.fillModule(mytr, false);
0181             names.insert(name);
0182           }
0183         }
0184       }
0185       dodet = fv1.next();
0186     }
0187   }
0188 
0189   // Finally the cells
0190   std::map<int, int> wafertype;
0191   std::map<int, HGCalTBGeomParameters::cellParameters> cellsf, cellsc;
0192   DDValue val2(attribute, sdTag3, 0.0);
0193   DDSpecificsMatchesValueFilter filter2{val2};
0194   DDFilteredView fv2(*cpv, filter2);
0195   ok = fv2.firstChild();
0196   if (!ok) {
0197     throw cms::Exception("DDException") << "Attribute " << val2 << " not found but needed.";
0198   } else {
0199     dodet = true;
0200     while (dodet) {
0201       const DDSolid& sol = fv2.logicalPart().solid();
0202       const std::string& name = sol.name().name();
0203       std::vector<int> copy = fv2.copyNumbers();
0204       int nsiz = static_cast<int>(copy.size());
0205       int cellx = (nsiz > 0) ? copy[nsiz - 1] : 0;
0206       int wafer = (nsiz > 1) ? copy[nsiz - 2] : 0;
0207       int cell = HGCalTypes::getUnpackedCell6(cellx);
0208       int type = HGCalTypes::getUnpackedCellType6(cellx);
0209       if (type != 1 && type != 2) {
0210         throw cms::Exception("DDException")
0211             << "Funny cell # " << cell << " type " << type << " in " << nsiz << " components";
0212       } else {
0213         auto ktr = wafertype.find(wafer);
0214         if (ktr == wafertype.end())
0215           wafertype[wafer] = type;
0216         bool newc(false);
0217         std::map<int, HGCalTBGeomParameters::cellParameters>::iterator itr;
0218         double cellsize = php.cellSize_[0];
0219         if (type == 1) {
0220           itr = cellsf.find(cell);
0221           newc = (itr == cellsf.end());
0222         } else {
0223           itr = cellsc.find(cell);
0224           newc = (itr == cellsc.end());
0225           cellsize = php.cellSize_[1];
0226         }
0227         if (newc) {
0228           bool half = (name.find("Half") != std::string::npos);
0229           double xx = HGCalTBParameters::k_ScaleFromDDD * fv2.translation().X();
0230           double yy = HGCalTBParameters::k_ScaleFromDDD * fv2.translation().Y();
0231           if (half) {
0232             math::XYZPointD p1(-2.0 * cellsize / 9.0, 0, 0);
0233             math::XYZPointD p2 = fv2.rotation()(p1);
0234             xx += (HGCalTBParameters::k_ScaleFromDDD * (p2.X()));
0235             yy += (HGCalTBParameters::k_ScaleFromDDD * (p2.Y()));
0236 #ifdef EDM_ML_DEBUG
0237             if (std::abs(p2.X()) < HGCalTBParameters::tol)
0238               p2.SetX(0.0);
0239             if (std::abs(p2.Z()) < HGCalTBParameters::tol)
0240               p2.SetZ(0.0);
0241             edm::LogVerbatim("HGCalGeom") << "Wafer " << wafer << " Type " << type << " Cell " << cellx << " local "
0242                                           << xx << ":" << yy << " new " << p1 << ":" << p2;
0243 #endif
0244           }
0245           HGCalTBGeomParameters::cellParameters cp(half, wafer, GlobalPoint(xx, yy, 0));
0246           if (type == 1) {
0247             cellsf[cell] = cp;
0248           } else {
0249             cellsc[cell] = cp;
0250           }
0251         }
0252       }
0253       dodet = fv2.next();
0254     }
0255   }
0256 
0257   loadGeometryHexagon(
0258       layers, trforms, trformUse, copies, copiesInLayers, wafer2copy, wafers, wafertype, cellsf, cellsc, php);
0259 }
0260 
0261 void HGCalTBGeomParameters::loadGeometryHexagon(const cms::DDCompactView* cpv,
0262                                                 HGCalTBParameters& php,
0263                                                 const std::string& sdTag1,
0264                                                 const std::string& sdTag2,
0265                                                 const std::string& sdTag3,
0266                                                 HGCalGeometryMode::WaferMode mode) {
0267   const cms::DDFilter filter("Volume", sdTag1);
0268   cms::DDFilteredView fv((*cpv), filter);
0269   std::map<int, HGCalTBGeomParameters::layerParameters> layers;
0270   std::vector<HGCalTBParameters::hgtrform> trforms;
0271   std::vector<bool> trformUse;
0272   std::vector<std::pair<int, int> > trused;
0273 
0274   while (fv.firstChild()) {
0275     const std::vector<double>& pars = fv.parameters();
0276     // Layers first
0277     std::vector<int> copy = fv.copyNos();
0278     int nsiz = static_cast<int>(copy.size());
0279     int lay = (nsiz > 0) ? copy[0] : 0;
0280     int zp = (nsiz > 2) ? copy[2] : -1;
0281     if (zp != 1)
0282       zp = -1;
0283     if (lay == 0) {
0284       throw cms::Exception("DDException") << "Funny layer # " << lay << " zp " << zp << " in " << nsiz << " components";
0285     } else {
0286       if (std::find(php.layer_.begin(), php.layer_.end(), lay) == php.layer_.end())
0287         php.layer_.emplace_back(lay);
0288       auto itr = layers.find(lay);
0289       double zz = HGCalTBParameters::k_ScaleFromDD4hep * fv.translation().Z();
0290       if (itr == layers.end()) {
0291         double rin(0), rout(0);
0292         if (dd4hep::isA<dd4hep::Polyhedra>(fv.solid())) {
0293           rin = 0.5 * HGCalTBParameters::k_ScaleFromDD4hep * (pars[5] + pars[8]);
0294           rout = 0.5 * HGCalTBParameters::k_ScaleFromDD4hep * (pars[6] + pars[9]);
0295         } else if (dd4hep::isA<dd4hep::Tube>(fv.solid())) {
0296           dd4hep::Tube tubeSeg(fv.solid());
0297           rin = HGCalTBParameters::k_ScaleFromDD4hep * tubeSeg.rMin();
0298           rout = HGCalTBParameters::k_ScaleFromDD4hep * tubeSeg.rMax();
0299         }
0300         HGCalTBGeomParameters::layerParameters laypar(rin, rout, zz);
0301         layers[lay] = laypar;
0302       }
0303       std::pair<int, int> layz(lay, zp);
0304       if (std::find(trused.begin(), trused.end(), layz) == trused.end()) {
0305         trused.emplace_back(layz);
0306         DD3Vector x, y, z;
0307         fv.rotation().GetComponents(x, y, z);
0308         const CLHEP::HepRep3x3 rotation(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
0309         const CLHEP::HepRotation hr(rotation);
0310         double xx = HGCalTBParameters::k_ScaleFromDD4hep * fv.translation().X();
0311         if (std::abs(xx) < tolerance)
0312           xx = 0;
0313         double yy = HGCalTBParameters::k_ScaleFromDD4hep * fv.translation().Y();
0314         if (std::abs(yy) < tolerance)
0315           yy = 0;
0316         double zz = HGCalTBParameters::k_ScaleFromDD4hep * fv.translation().Z();
0317         const CLHEP::Hep3Vector h3v(xx, yy, zz);
0318         HGCalTBParameters::hgtrform mytrf;
0319         mytrf.zp = zp;
0320         mytrf.lay = lay;
0321         mytrf.sec = 0;
0322         mytrf.subsec = 0;
0323         mytrf.h3v = h3v;
0324         mytrf.hr = hr;
0325         trforms.emplace_back(mytrf);
0326         trformUse.emplace_back(false);
0327       }
0328     }
0329   }
0330 
0331   // Then wafers
0332   // This assumes layers are build starting from 1 (which on 25 Jan 2016, they
0333   // were) to ensure that new copy numbers are always added to the end of the
0334   // list.
0335   std::unordered_map<int32_t, int32_t> copies;
0336   HGCalTBParameters::layer_map copiesInLayers(layers.size() + 1);
0337   std::vector<int32_t> wafer2copy;
0338   std::vector<HGCalTBGeomParameters::cellParameters> wafers;
0339   const cms::DDFilter filter1("Volume", sdTag2);
0340   cms::DDFilteredView fv1((*cpv), filter1);
0341   bool ok = fv1.firstChild();
0342   if (!ok) {
0343     throw cms::Exception("DDException") << "Attribute " << sdTag2 << " not found but needed.";
0344   } else {
0345     bool dodet = true;
0346     std::unordered_set<std::string> names;
0347     while (dodet) {
0348       const std::string name = static_cast<std::string>(fv1.name());
0349       std::vector<int> copy = fv1.copyNos();
0350       int nsiz = static_cast<int>(copy.size());
0351       int wafer = (nsiz > 0) ? copy[0] : 0;
0352       int layer = (nsiz > 1) ? copy[1] : 0;
0353       if (nsiz < 2) {
0354         throw cms::Exception("DDException") << "Funny wafer # " << wafer << " in " << nsiz << " components";
0355       } else if (layer > static_cast<int>(layers.size())) {
0356         edm::LogWarning("HGCalGeom") << "Funny wafer # " << wafer << " Layer " << layer << ":" << layers.size()
0357                                      << " among " << nsiz << " components";
0358       } else {
0359         auto itr = copies.find(wafer);
0360         auto cpy = copiesInLayers[layer].find(wafer);
0361         if (itr != copies.end() && cpy == copiesInLayers[layer].end()) {
0362           copiesInLayers[layer][wafer] = itr->second;
0363         }
0364         if (itr == copies.end()) {
0365           copies[wafer] = wafer2copy.size();
0366           copiesInLayers[layer][wafer] = wafer2copy.size();
0367           double xx = HGCalTBParameters::k_ScaleFromDD4hep * fv1.translation().X();
0368           if (std::abs(xx) < tolerance)
0369             xx = 0;
0370           double yy = HGCalTBParameters::k_ScaleFromDD4hep * fv1.translation().Y();
0371           if (std::abs(yy) < tolerance)
0372             yy = 0;
0373           wafer2copy.emplace_back(wafer);
0374           GlobalPoint p(xx, yy, HGCalTBParameters::k_ScaleFromDD4hep * fv1.translation().Z());
0375           HGCalTBGeomParameters::cellParameters cell(false, wafer, p);
0376           wafers.emplace_back(cell);
0377           if (names.count(name) == 0) {
0378             double zv[2], rv;
0379             const std::vector<double>& pars = fv1.parameters();
0380             if (mode == HGCalGeometryMode::Polyhedra) {
0381               zv[0] = pars[4];
0382               zv[1] = pars[7];
0383               rv = pars[6];
0384             } else {
0385               zv[0] = pars[3];
0386               zv[1] = pars[9];
0387               rv = pars[4];
0388             }
0389             php.waferR_ = 2.0 * HGCalTBParameters::k_ScaleFromDD4hepToG4 * rv * tan30deg_;
0390             php.waferSize_ = HGCalTBParameters::k_ScaleFromDD4hep * rv;
0391             double dz = 0.5 * HGCalTBParameters::k_ScaleFromDD4hepToG4 * (zv[1] - zv[0]);
0392 #ifdef EDM_ML_DEBUG
0393             edm::LogVerbatim("HGCalGeom")
0394                 << "Mode " << mode << " R " << php.waferSize_ << ":" << php.waferR_ << " z " << dz;
0395 #endif
0396             HGCalTBParameters::hgtrap mytr;
0397             mytr.lay = 1;
0398             mytr.bl = php.waferR_;
0399             mytr.tl = php.waferR_;
0400             mytr.h = php.waferR_;
0401             mytr.dz = dz;
0402             mytr.alpha = 0.0;
0403             mytr.cellSize = waferSize_;
0404             php.fillModule(mytr, false);
0405             names.insert(name);
0406           }
0407         }
0408       }
0409       dodet = fv1.firstChild();
0410     }
0411   }
0412 
0413   // Finally the cells
0414   std::map<int, int> wafertype;
0415   std::map<int, HGCalTBGeomParameters::cellParameters> cellsf, cellsc;
0416   const cms::DDFilter filter2("Volume", sdTag3);
0417   cms::DDFilteredView fv2((*cpv), filter2);
0418   ok = fv2.firstChild();
0419   if (!ok) {
0420     throw cms::Exception("DDException") << "Attribute " << sdTag3 << " not found but needed.";
0421   } else {
0422     bool dodet = true;
0423     while (dodet) {
0424       const std::string name = static_cast<std::string>(fv2.name());
0425       std::vector<int> copy = fv2.copyNos();
0426       int nsiz = static_cast<int>(copy.size());
0427       int cellx = (nsiz > 0) ? copy[0] : 0;
0428       int wafer = (nsiz > 1) ? copy[1] : 0;
0429       int cell = HGCalTypes::getUnpackedCell6(cellx);
0430       int type = HGCalTypes::getUnpackedCellType6(cellx);
0431       if (type != 1 && type != 2) {
0432         throw cms::Exception("DDException")
0433             << "Funny cell # " << cell << " type " << type << " in " << nsiz << " components";
0434       } else {
0435         auto ktr = wafertype.find(wafer);
0436         if (ktr == wafertype.end())
0437           wafertype[wafer] = type;
0438         bool newc(false);
0439         std::map<int, HGCalTBGeomParameters::cellParameters>::iterator itr;
0440         double cellsize = php.cellSize_[0];
0441         if (type == 1) {
0442           itr = cellsf.find(cell);
0443           newc = (itr == cellsf.end());
0444         } else {
0445           itr = cellsc.find(cell);
0446           newc = (itr == cellsc.end());
0447           cellsize = php.cellSize_[1];
0448         }
0449         if (newc) {
0450           bool half = (name.find("Half") != std::string::npos);
0451           double xx = HGCalTBParameters::k_ScaleFromDD4hep * fv2.translation().X();
0452           double yy = HGCalTBParameters::k_ScaleFromDD4hep * fv2.translation().Y();
0453           if (half) {
0454             math::XYZPointD p1(-2.0 * cellsize / 9.0, 0, 0);
0455             math::XYZPointD p2 = fv2.rotation()(p1);
0456             xx += (HGCalTBParameters::k_ScaleFromDDD * (p2.X()));
0457             yy += (HGCalTBParameters::k_ScaleFromDDD * (p2.Y()));
0458 #ifdef EDM_ML_DEBUG
0459             if (std::abs(p2.X()) < HGCalTBParameters::tol)
0460               p2.SetX(0.0);
0461             if (std::abs(p2.Z()) < HGCalTBParameters::tol)
0462               p2.SetZ(0.0);
0463             edm::LogVerbatim("HGCalGeom") << "Wafer " << wafer << " Type " << type << " Cell " << cellx << " local "
0464                                           << xx << ":" << yy << " new " << p1 << ":" << p2;
0465 #endif
0466           }
0467           HGCalTBGeomParameters::cellParameters cp(half, wafer, GlobalPoint(xx, yy, 0));
0468           if (type == 1) {
0469             cellsf[cell] = cp;
0470           } else {
0471             cellsc[cell] = cp;
0472           }
0473         }
0474       }
0475       dodet = fv2.firstChild();
0476     }
0477   }
0478 
0479   loadGeometryHexagon(
0480       layers, trforms, trformUse, copies, copiesInLayers, wafer2copy, wafers, wafertype, cellsf, cellsc, php);
0481 }
0482 
0483 void HGCalTBGeomParameters::loadGeometryHexagon(const std::map<int, HGCalTBGeomParameters::layerParameters>& layers,
0484                                                 std::vector<HGCalTBParameters::hgtrform>& trforms,
0485                                                 std::vector<bool>& trformUse,
0486                                                 const std::unordered_map<int32_t, int32_t>& copies,
0487                                                 const HGCalTBParameters::layer_map& copiesInLayers,
0488                                                 const std::vector<int32_t>& wafer2copy,
0489                                                 const std::vector<HGCalTBGeomParameters::cellParameters>& wafers,
0490                                                 const std::map<int, int>& wafertype,
0491                                                 const std::map<int, HGCalTBGeomParameters::cellParameters>& cellsf,
0492                                                 const std::map<int, HGCalTBGeomParameters::cellParameters>& cellsc,
0493                                                 HGCalTBParameters& php) {
0494   if (((cellsf.size() + cellsc.size()) == 0) || (wafers.empty()) || (layers.empty())) {
0495     throw cms::Exception("DDException") << "HGCalTBGeomParameters: mismatch between geometry and specpar: cells "
0496                                         << cellsf.size() << ":" << cellsc.size() << " wafers " << wafers.size()
0497                                         << " layers " << layers.size();
0498   }
0499 
0500   for (unsigned int i = 0; i < layers.size(); ++i) {
0501     for (auto& layer : layers) {
0502       if (layer.first == static_cast<int>(i + php.firstLayer_)) {
0503         php.layerIndex_.emplace_back(i);
0504         php.rMinLayHex_.emplace_back(layer.second.rmin);
0505         php.rMaxLayHex_.emplace_back(layer.second.rmax);
0506         php.zLayerHex_.emplace_back(layer.second.zpos);
0507         break;
0508       }
0509     }
0510   }
0511 
0512   for (unsigned int i = 0; i < php.layer_.size(); ++i) {
0513     for (unsigned int i1 = 0; i1 < trforms.size(); ++i1) {
0514       if (!trformUse[i1] && php.layerGroup_[trforms[i1].lay - 1] == static_cast<int>(i + 1)) {
0515         trforms[i1].h3v *= static_cast<double>(HGCalTBParameters::k_ScaleFromDDD);
0516         trforms[i1].lay = (i + 1);
0517         trformUse[i1] = true;
0518         php.fillTrForm(trforms[i1]);
0519         int nz(1);
0520         for (unsigned int i2 = i1 + 1; i2 < trforms.size(); ++i2) {
0521           if (!trformUse[i2] && trforms[i2].zp == trforms[i1].zp &&
0522               php.layerGroup_[trforms[i2].lay - 1] == static_cast<int>(i + 1)) {
0523             php.addTrForm(trforms[i2].h3v);
0524             nz++;
0525             trformUse[i2] = true;
0526           }
0527         }
0528         if (nz > 0) {
0529           php.scaleTrForm(double(1.0 / nz));
0530         }
0531       }
0532     }
0533   }
0534 
0535   double rmin = HGCalTBParameters::k_ScaleFromDDD * php.waferR_;
0536   for (unsigned i = 0; i < wafer2copy.size(); ++i) {
0537     php.waferCopy_.emplace_back(wafer2copy[i]);
0538     php.waferPosX_.emplace_back(wafers[i].xyz.x());
0539     php.waferPosY_.emplace_back(wafers[i].xyz.y());
0540     auto ktr = wafertype.find(wafer2copy[i]);
0541     int typet = (ktr == wafertype.end()) ? 0 : (ktr->second);
0542     php.waferTypeT_.emplace_back(typet);
0543     double r = wafers[i].xyz.perp();
0544     int type(3);
0545     for (int k = 1; k < 4; ++k) {
0546       if ((r + rmin) <= php.boundR_[k]) {
0547         type = k;
0548         break;
0549       }
0550     }
0551     php.waferTypeL_.emplace_back(type);
0552   }
0553   php.copiesInLayers_ = copiesInLayers;
0554   php.nSectors_ = static_cast<int>(php.waferCopy_.size());
0555 
0556   std::vector<HGCalTBGeomParameters::cellParameters>::const_iterator itrf = wafers.end();
0557   for (unsigned int i = 0; i < cellsf.size(); ++i) {
0558     auto itr = cellsf.find(i);
0559     if (itr == cellsf.end()) {
0560       throw cms::Exception("DDException") << "HGCalTBGeomParameters: missing info for fine cell number " << i;
0561     } else {
0562       double xx = (itr->second).xyz.x();
0563       double yy = (itr->second).xyz.y();
0564       int waf = (itr->second).wafer;
0565       std::pair<double, double> xy = cellPosition(wafers, itrf, waf, xx, yy);
0566       php.cellFineX_.emplace_back(xy.first);
0567       php.cellFineY_.emplace_back(xy.second);
0568       php.cellFineHalf_.emplace_back((itr->second).half);
0569     }
0570   }
0571   itrf = wafers.end();
0572   for (unsigned int i = 0; i < cellsc.size(); ++i) {
0573     auto itr = cellsc.find(i);
0574     if (itr == cellsc.end()) {
0575       throw cms::Exception("DDException") << "HGCalTBGeomParameters: missing info for coarse cell number " << i;
0576     } else {
0577       double xx = (itr->second).xyz.x();
0578       double yy = (itr->second).xyz.y();
0579       int waf = (itr->second).wafer;
0580       std::pair<double, double> xy = cellPosition(wafers, itrf, waf, xx, yy);
0581       php.cellCoarseX_.emplace_back(xy.first);
0582       php.cellCoarseY_.emplace_back(xy.second);
0583       php.cellCoarseHalf_.emplace_back((itr->second).half);
0584     }
0585   }
0586   int depth(0);
0587   for (unsigned int i = 0; i < php.layerGroup_.size(); ++i) {
0588     bool first(true);
0589     for (unsigned int k = 0; k < php.layerGroup_.size(); ++k) {
0590       if (php.layerGroup_[k] == static_cast<int>(i + 1)) {
0591         if (first) {
0592           php.depth_.emplace_back(i + 1);
0593           php.depthIndex_.emplace_back(depth);
0594           php.depthLayerF_.emplace_back(k);
0595           ++depth;
0596           first = false;
0597         }
0598       }
0599     }
0600   }
0601   HGCalTBParameters::hgtrap mytr = php.getModule(0, false);
0602   mytr.bl *= HGCalTBParameters::k_ScaleFromDDD;
0603   mytr.tl *= HGCalTBParameters::k_ScaleFromDDD;
0604   mytr.h *= HGCalTBParameters::k_ScaleFromDDD;
0605   mytr.dz *= HGCalTBParameters::k_ScaleFromDDD;
0606   mytr.cellSize *= HGCalTBParameters::k_ScaleFromDDD;
0607   double dz = mytr.dz;
0608   php.fillModule(mytr, true);
0609   mytr.dz = 2 * dz;
0610   php.fillModule(mytr, true);
0611   mytr.dz = 3 * dz;
0612   php.fillModule(mytr, true);
0613 #ifdef EDM_ML_DEBUG
0614   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters finds " << php.zLayerHex_.size() << " layers";
0615   for (unsigned int i = 0; i < php.zLayerHex_.size(); ++i) {
0616     int k = php.layerIndex_[i];
0617     edm::LogVerbatim("HGCalGeom") << "Layer[" << i << ":" << k << ":" << php.layer_[k]
0618                                   << "] with r = " << php.rMinLayHex_[i] << ":" << php.rMaxLayHex_[i]
0619                                   << " at z = " << php.zLayerHex_[i];
0620   }
0621   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters has " << php.depthIndex_.size() << " depths";
0622   for (unsigned int i = 0; i < php.depthIndex_.size(); ++i) {
0623     int k = php.depthIndex_[i];
0624     edm::LogVerbatim("HGCalGeom") << "Reco Layer[" << i << ":" << k << "]  First Layer " << php.depthLayerF_[i]
0625                                   << " Depth " << php.depth_[k];
0626   }
0627   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters finds " << php.nSectors_ << " wafers";
0628   for (unsigned int i = 0; i < php.waferCopy_.size(); ++i)
0629     edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << ": " << php.waferCopy_[i] << "] type " << php.waferTypeL_[i]
0630                                   << ":" << php.waferTypeT_[i] << " at (" << php.waferPosX_[i] << ","
0631                                   << php.waferPosY_[i] << ",0)";
0632   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: wafer radius " << php.waferR_ << " and dimensions of the "
0633                                 << "wafers:";
0634   edm::LogVerbatim("HGCalGeom") << "Sim[0] " << php.moduleLayS_[0] << " dx " << php.moduleBlS_[0] << ":"
0635                                 << php.moduleTlS_[0] << " dy " << php.moduleHS_[0] << " dz " << php.moduleDzS_[0]
0636                                 << " alpha " << php.moduleAlphaS_[0];
0637   for (unsigned int k = 0; k < php.moduleLayR_.size(); ++k)
0638     edm::LogVerbatim("HGCalGeom") << "Rec[" << k << "] " << php.moduleLayR_[k] << " dx " << php.moduleBlR_[k] << ":"
0639                                   << php.moduleTlR_[k] << " dy " << php.moduleHR_[k] << " dz " << php.moduleDzR_[k]
0640                                   << " alpha " << php.moduleAlphaR_[k];
0641   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters finds " << php.cellFineX_.size() << " fine cells in a  wafer";
0642   for (unsigned int i = 0; i < php.cellFineX_.size(); ++i)
0643     edm::LogVerbatim("HGCalGeom") << "Fine Cell[" << i << "] at (" << php.cellFineX_[i] << "," << php.cellFineY_[i]
0644                                   << ",0)";
0645   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters finds " << php.cellCoarseX_.size()
0646                                 << " coarse cells in a wafer";
0647   for (unsigned int i = 0; i < php.cellCoarseX_.size(); ++i)
0648     edm::LogVerbatim("HGCalGeom") << "Coarse Cell[" << i << "] at (" << php.cellCoarseX_[i] << ","
0649                                   << php.cellCoarseY_[i] << ",0)";
0650   edm::LogVerbatim("HGCalGeom") << "Obtained " << php.trformIndex_.size() << " transformation matrices";
0651   for (unsigned int k = 0; k < php.trformIndex_.size(); ++k) {
0652     edm::LogVerbatim("HGCalGeom") << "Matrix[" << k << "] (" << std::hex << php.trformIndex_[k] << std::dec
0653                                   << ") Translation (" << php.trformTranX_[k] << ", " << php.trformTranY_[k] << ", "
0654                                   << php.trformTranZ_[k] << " Rotation (" << php.trformRotXX_[k] << ", "
0655                                   << php.trformRotYX_[k] << ", " << php.trformRotZX_[k] << ", " << php.trformRotXY_[k]
0656                                   << ", " << php.trformRotYY_[k] << ", " << php.trformRotZY_[k] << ", "
0657                                   << php.trformRotXZ_[k] << ", " << php.trformRotYZ_[k] << ", " << php.trformRotZZ_[k]
0658                                   << ")";
0659   }
0660   edm::LogVerbatim("HGCalGeom") << "Dump copiesInLayers for " << php.copiesInLayers_.size() << " layers";
0661   for (unsigned int k = 0; k < php.copiesInLayers_.size(); ++k) {
0662     const auto& theModules = php.copiesInLayers_[k];
0663     edm::LogVerbatim("HGCalGeom") << "Layer " << k << ":" << theModules.size();
0664     int k2(0);
0665     for (std::unordered_map<int, int>::const_iterator itr = theModules.begin(); itr != theModules.end(); ++itr, ++k2) {
0666       edm::LogVerbatim("HGCalGeom") << "[" << k2 << "] " << itr->first << ":" << itr->second;
0667     }
0668   }
0669 #endif
0670 }
0671 
0672 void HGCalTBGeomParameters::loadSpecParsHexagon(const DDFilteredView& fv,
0673                                                 HGCalTBParameters& php,
0674                                                 const DDCompactView* cpv,
0675                                                 const std::string& sdTag1,
0676                                                 const std::string& sdTag2) {
0677   DDsvalues_type sv(fv.mergedSpecifics());
0678   php.boundR_ = getDDDArray("RadiusBound", sv, 4);
0679   rescale(php.boundR_, HGCalTBParameters::k_ScaleFromDDD);
0680   php.rLimit_ = getDDDArray("RadiusLimits", sv, 2);
0681   rescale(php.rLimit_, HGCalTBParameters::k_ScaleFromDDD);
0682   php.levelT_ = dbl_to_int(getDDDArray("LevelTop", sv, 0));
0683 
0684   // Grouping of layers
0685   php.layerGroup_ = dbl_to_int(getDDDArray("GroupingZFine", sv, 0));
0686   php.layerGroupM_ = dbl_to_int(getDDDArray("GroupingZMid", sv, 0));
0687   php.layerGroupO_ = dbl_to_int(getDDDArray("GroupingZOut", sv, 0));
0688   php.slopeMin_ = getDDDArray("Slope", sv, 1);
0689 
0690   // Wafer size
0691   std::string attribute = "Volume";
0692   DDSpecificsMatchesValueFilter filter1{DDValue(attribute, sdTag1, 0.0)};
0693   DDFilteredView fv1(*cpv, filter1);
0694   if (fv1.firstChild()) {
0695     DDsvalues_type sv(fv1.mergedSpecifics());
0696     const auto& dummy = getDDDArray("WaferSize", sv, 0);
0697     waferSize_ = dummy[0];
0698   }
0699 
0700   // Cell size
0701   DDSpecificsMatchesValueFilter filter2{DDValue(attribute, sdTag2, 0.0)};
0702   DDFilteredView fv2(*cpv, filter2);
0703   if (fv2.firstChild()) {
0704     DDsvalues_type sv(fv2.mergedSpecifics());
0705     php.cellSize_ = getDDDArray("CellSize", sv, 0);
0706   }
0707 
0708   loadSpecParsHexagon(php);
0709 }
0710 
0711 void HGCalTBGeomParameters::loadSpecParsHexagon(const cms::DDFilteredView& fv,
0712                                                 HGCalTBParameters& php,
0713                                                 const std::string& sdTag1,
0714                                                 const std::string& sdTag2,
0715                                                 const std::string& sdTag3,
0716                                                 const std::string& sdTag4) {
0717   php.boundR_ = fv.get<std::vector<double> >(sdTag4, "RadiusBound");
0718   rescale(php.boundR_, HGCalTBParameters::k_ScaleFromDD4hep);
0719   php.rLimit_ = fv.get<std::vector<double> >(sdTag4, "RadiusLimits");
0720   rescale(php.rLimit_, HGCalTBParameters::k_ScaleFromDD4hep);
0721   php.levelT_ = dbl_to_int(fv.get<std::vector<double> >(sdTag4, "LevelTop"));
0722 
0723   // Grouping of layers
0724   php.layerGroup_ = dbl_to_int(fv.get<std::vector<double> >(sdTag1, "GroupingZFine"));
0725   php.layerGroupM_ = dbl_to_int(fv.get<std::vector<double> >(sdTag1, "GroupingZMid"));
0726   php.layerGroupO_ = dbl_to_int(fv.get<std::vector<double> >(sdTag1, "GroupingZOut"));
0727   php.slopeMin_ = fv.get<std::vector<double> >(sdTag4, "Slope");
0728   if (php.slopeMin_.empty())
0729     php.slopeMin_.emplace_back(0);
0730 
0731   // Wafer size
0732   const auto& dummy = fv.get<std::vector<double> >(sdTag2, "WaferSize");
0733   waferSize_ = dummy[0] * HGCalTBParameters::k_ScaleFromDD4hepToG4;
0734 
0735   // Cell size
0736   php.cellSize_ = fv.get<std::vector<double> >(sdTag3, "CellSize");
0737   rescale(php.cellSize_, HGCalTBParameters::k_ScaleFromDD4hepToG4);
0738 
0739   loadSpecParsHexagon(php);
0740 }
0741 
0742 void HGCalTBGeomParameters::loadSpecParsHexagon(const HGCalTBParameters& php) {
0743 #ifdef EDM_ML_DEBUG
0744   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: wafer radius ranges"
0745                                 << " for cell grouping " << php.boundR_[0] << ":" << php.boundR_[1] << ":"
0746                                 << php.boundR_[2] << ":" << php.boundR_[3];
0747   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: Minimum/maximum R " << php.rLimit_[0] << ":"
0748                                 << php.rLimit_[1];
0749   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: LevelTop " << php.levelT_[0];
0750   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: minimum slope " << php.slopeMin_[0]
0751                                 << " and layer groupings "
0752                                 << "for the 3 ranges:";
0753   for (unsigned int k = 0; k < php.layerGroup_.size(); ++k)
0754     edm::LogVerbatim("HGCalGeom") << "[" << k << "] " << php.layerGroup_[k] << ":" << php.layerGroupM_[k] << ":"
0755                                   << php.layerGroupO_[k];
0756   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: Wafer Size: " << waferSize_;
0757   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: " << php.cellSize_.size() << " cells of sizes:";
0758   for (unsigned int k = 0; k < php.cellSize_.size(); ++k)
0759     edm::LogVerbatim("HGCalGeom") << " [" << k << "] " << php.cellSize_[k];
0760   edm::LogVerbatim("HGCalGeom") << "HGCalTBGeomParameters: First Layer " << php.firstLayer_;
0761 #endif
0762 }
0763 
0764 void HGCalTBGeomParameters::loadWaferHexagon(HGCalTBParameters& php) {
0765   double waferW(HGCalTBParameters::k_ScaleFromDDD * waferSize_), rmin(HGCalTBParameters::k_ScaleFromDDD * php.waferR_);
0766   double rin(php.rLimit_[0]), rout(php.rLimit_[1]), rMaxFine(php.boundR_[1]);
0767 #ifdef EDM_ML_DEBUG
0768   edm::LogVerbatim("HGCalGeom") << "Input waferWidth " << waferW << ":" << rmin << " R Limits: " << rin << ":" << rout
0769                                 << " Fine " << rMaxFine;
0770 #endif
0771   // Clear the vectors
0772   php.waferCopy_.clear();
0773   php.waferTypeL_.clear();
0774   php.waferTypeT_.clear();
0775   php.waferPosX_.clear();
0776   php.waferPosY_.clear();
0777   double dx = 0.5 * waferW;
0778   double dy = 3.0 * dx * tan(30._deg);
0779   double rr = 2.0 * dx * tan(30._deg);
0780   int ncol = static_cast<int>(2.0 * rout / waferW) + 1;
0781   int nrow = static_cast<int>(rout / (waferW * tan(30._deg))) + 1;
0782   int ns2 = (2 * ncol + 1) * (2 * nrow + 1) * php.layer_.size();
0783   int incm(0), inrm(0);
0784   HGCalTBParameters::layer_map copiesInLayers(php.layer_.size() + 1);
0785   HGCalTBParameters::waferT_map waferTypes(ns2 + 1);
0786 #ifdef EDM_ML_DEBUG
0787   int kount(0), ntot(0);
0788   edm::LogVerbatim("HGCalGeom") << "Row " << nrow << " Column " << ncol;
0789 #endif
0790   for (int nr = -nrow; nr <= nrow; ++nr) {
0791     int inr = (nr >= 0) ? nr : -nr;
0792     for (int nc = -ncol; nc <= ncol; ++nc) {
0793       int inc = (nc >= 0) ? nc : -nc;
0794       if (inr % 2 == inc % 2) {
0795         double xpos = nc * dx;
0796         double ypos = nr * dy;
0797         std::pair<int, int> corner = HGCalGeomTools::waferCorner(xpos, ypos, dx, rr, rin, rout, true);
0798         double rpos = std::sqrt(xpos * xpos + ypos * ypos);
0799         int typet = (rpos < rMaxFine) ? 1 : 2;
0800         int typel(3);
0801         for (int k = 1; k < 4; ++k) {
0802           if ((rpos + rmin) <= php.boundR_[k]) {
0803             typel = k;
0804             break;
0805           }
0806         }
0807 #ifdef EDM_ML_DEBUG
0808         ++ntot;
0809 #endif
0810         if (corner.first > 0) {
0811           int copy = HGCalTypes::packTypeUV(typel, nc, nr);
0812           if (inc > incm)
0813             incm = inc;
0814           if (inr > inrm)
0815             inrm = inr;
0816 #ifdef EDM_ML_DEBUG
0817           kount++;
0818           edm::LogVerbatim("HGCalGeom") << kount << ":" << ntot << " Copy " << copy << " Type " << typel << ":" << typet
0819                                         << " Location " << corner.first << " Position " << xpos << ":" << ypos
0820                                         << " Layers " << php.layer_.size();
0821 #endif
0822           php.waferCopy_.emplace_back(copy);
0823           php.waferTypeL_.emplace_back(typel);
0824           php.waferTypeT_.emplace_back(typet);
0825           php.waferPosX_.emplace_back(xpos);
0826           php.waferPosY_.emplace_back(ypos);
0827           for (unsigned int il = 0; il < php.layer_.size(); ++il) {
0828             std::pair<int, int> corner =
0829                 HGCalGeomTools::waferCorner(xpos, ypos, dx, rr, php.rMinLayHex_[il], php.rMaxLayHex_[il], true);
0830             if (corner.first > 0) {
0831               auto cpy = copiesInLayers[php.layer_[il]].find(copy);
0832               if (cpy == copiesInLayers[php.layer_[il]].end())
0833                 copiesInLayers[php.layer_[il]][copy] =
0834                     ((corner.first == static_cast<int>(HGCalTBParameters::k_CornerSize)) ? php.waferCopy_.size() : -1);
0835             }
0836             if ((corner.first > 0) && (corner.first < static_cast<int>(HGCalTBParameters::k_CornerSize))) {
0837               int wl = HGCalWaferIndex::waferIndex(php.layer_[il], copy, 0, true);
0838               waferTypes[wl] = corner;
0839             }
0840           }
0841         }
0842       }
0843     }
0844   }
0845   php.copiesInLayers_ = copiesInLayers;
0846   php.waferTypes_ = waferTypes;
0847   php.nSectors_ = static_cast<int>(php.waferCopy_.size());
0848   php.waferUVMax_ = 0;
0849 #ifdef EDM_ML_DEBUG
0850   edm::LogVerbatim("HGCalGeom") << "HGCalWaferHexagon: # of columns " << incm << " # of rows " << inrm << " and "
0851                                 << kount << ":" << ntot << " wafers; R " << rin << ":" << rout;
0852   edm::LogVerbatim("HGCalGeom") << "Dump copiesInLayers for " << php.copiesInLayers_.size() << " layers";
0853   for (unsigned int k = 0; k < copiesInLayers.size(); ++k) {
0854     const auto& theModules = copiesInLayers[k];
0855     edm::LogVerbatim("HGCalGeom") << "Layer " << k << ":" << theModules.size();
0856     int k2(0);
0857     for (std::unordered_map<int, int>::const_iterator itr = theModules.begin(); itr != theModules.end(); ++itr, ++k2) {
0858       edm::LogVerbatim("HGCalGeom") << "[" << k2 << "] " << itr->first << ":" << itr->second;
0859     }
0860   }
0861 #endif
0862 }
0863 
0864 void HGCalTBGeomParameters::loadCellParsHexagon(const DDCompactView* cpv, HGCalTBParameters& php) {
0865   // Special parameters for cell parameters
0866   std::string attribute = "OnlyForHGCalNumbering";
0867   DDSpecificsHasNamedValueFilter filter1{attribute};
0868   DDFilteredView fv1(*cpv, filter1);
0869   bool ok = fv1.firstChild();
0870 
0871   if (ok) {
0872     php.cellFine_ = dbl_to_int(cpv->vector("waferFine"));
0873     php.cellCoarse_ = dbl_to_int(cpv->vector("waferCoarse"));
0874   }
0875 
0876   loadCellParsHexagon(php);
0877 }
0878 
0879 void HGCalTBGeomParameters::loadCellParsHexagon(const cms::DDVectorsMap& vmap, HGCalTBParameters& php) {
0880   for (auto const& it : vmap) {
0881     if (dd4hep::dd::compareEqual(dd4hep::dd::noNamespace(it.first), "waferFine")) {
0882       for (const auto& i : it.second)
0883         php.cellFine_.emplace_back(std::round(i));
0884     } else if (dd4hep::dd::compareEqual(dd4hep::dd::noNamespace(it.first), "waferCoarse")) {
0885       for (const auto& i : it.second)
0886         php.cellCoarse_.emplace_back(std::round(i));
0887     }
0888   }
0889 
0890   loadCellParsHexagon(php);
0891 }
0892 
0893 void HGCalTBGeomParameters::loadCellParsHexagon(const HGCalTBParameters& php) {
0894 #ifdef EDM_ML_DEBUG
0895   edm::LogVerbatim("HGCalGeom") << "HGCalLoadCellPars: " << php.cellFine_.size() << " rows for fine cells";
0896   for (unsigned int k = 0; k < php.cellFine_.size(); ++k)
0897     edm::LogVerbatim("HGCalGeom") << "[" << k << "]: " << php.cellFine_[k];
0898   edm::LogVerbatim("HGCalGeom") << "HGCalLoadCellPars: " << php.cellCoarse_.size() << " rows for coarse cells";
0899   for (unsigned int k = 0; k < php.cellCoarse_.size(); ++k)
0900     edm::LogVerbatim("HGCalGeom") << "[" << k << "]: " << php.cellCoarse_[k];
0901 #endif
0902 }
0903 
0904 std::vector<double> HGCalTBGeomParameters::getDDDArray(const std::string& str,
0905                                                        const DDsvalues_type& sv,
0906                                                        const int nmin) {
0907   DDValue value(str);
0908   if (DDfetch(&sv, value)) {
0909     const std::vector<double>& fvec = value.doubles();
0910     int nval = fvec.size();
0911     if (nmin > 0) {
0912       if (nval < nmin) {
0913         throw cms::Exception("DDException")
0914             << "HGCalTBGeomParameters:  # of " << str << " bins " << nval << " < " << nmin << " ==> illegal";
0915       }
0916     } else {
0917       if (nval < 1 && nmin == 0) {
0918         throw cms::Exception("DDException")
0919             << "HGCalTBGeomParameters: # of " << str << " bins " << nval << " < 1 ==> illegal"
0920             << " (nmin=" << nmin << ")";
0921       }
0922     }
0923     return fvec;
0924   } else {
0925     if (nmin >= 0) {
0926       throw cms::Exception("DDException") << "HGCalTBGeomParameters: cannot get array " << str;
0927     }
0928     std::vector<double> fvec;
0929     return fvec;
0930   }
0931 }
0932 
0933 std::pair<double, double> HGCalTBGeomParameters::cellPosition(
0934     const std::vector<HGCalTBGeomParameters::cellParameters>& wafers,
0935     std::vector<HGCalTBGeomParameters::cellParameters>::const_iterator& itrf,
0936     int wafer,
0937     double xx,
0938     double yy) {
0939   if (itrf == wafers.end()) {
0940     for (std::vector<HGCalTBGeomParameters::cellParameters>::const_iterator itr = wafers.begin(); itr != wafers.end();
0941          ++itr) {
0942       if (itr->wafer == wafer) {
0943         itrf = itr;
0944         break;
0945       }
0946     }
0947   }
0948   double dx(0), dy(0);
0949   if (itrf != wafers.end()) {
0950     dx = (xx - itrf->xyz.x());
0951     if (std::abs(dx) < tolerance)
0952       dx = 0;
0953     dy = (yy - itrf->xyz.y());
0954     if (std::abs(dy) < tolerance)
0955       dy = 0;
0956   }
0957   return std::make_pair(dx, dy);
0958 }
0959 
0960 void HGCalTBGeomParameters::rescale(std::vector<double>& v, const double s) {
0961   std::for_each(v.begin(), v.end(), [s](double& n) { n *= s; });
0962 }
0963 
0964 void HGCalTBGeomParameters::resetZero(std::vector<double>& v) {
0965   for (auto& n : v) {
0966     if (std::abs(n) < tolmin)
0967       n = 0;
0968   }
0969 }