File indexing completed on 2024-10-25 23:57:05
0001 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0002 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
0003
0004 #include <Math/Transform3D.h>
0005 #include <Math/EulerAngles.h>
0006
0007 #include <algorithm>
0008
0009 typedef CaloCellGeometry::Pt3D Pt3D;
0010 typedef CaloCellGeometry::Pt3DVec Pt3DVec;
0011 typedef CaloCellGeometry::Tr3D Tr3D;
0012
0013 typedef CaloSubdetectorGeometry::CCGFloat CCGFloat;
0014
0015 CaloSubdetectorGeometry::CaloSubdetectorGeometry()
0016 : m_parMgr(nullptr), m_cmgr(nullptr), m_deltaPhi(nullptr), m_deltaEta(nullptr) {}
0017
0018 CaloSubdetectorGeometry::~CaloSubdetectorGeometry() {
0019 delete m_cmgr;
0020 delete m_parMgr;
0021 if (m_deltaPhi)
0022 delete m_deltaPhi.load();
0023 if (m_deltaEta)
0024 delete m_deltaEta.load();
0025 }
0026
0027 void CaloSubdetectorGeometry::addValidID(const DetId& id) {
0028 auto pos = std::lower_bound(m_validIds.begin(), m_validIds.end(), id);
0029 m_validIds.insert(pos, id);
0030 }
0031
0032 const std::vector<DetId>& CaloSubdetectorGeometry::getValidDetIds(DetId::Detector , int ) const {
0033 return m_validIds;
0034 }
0035
0036 CaloSubdetectorGeometry::CellMayOwnPtr CaloSubdetectorGeometry::getGeometry(const DetId& id) const {
0037 return CellMayOwnPtr(cellGeomPtr(CaloGenericDetId(id).denseIndex()));
0038 }
0039
0040 bool CaloSubdetectorGeometry::present(const DetId& id) const {
0041 return std::find(m_validIds.begin(), m_validIds.end(), id) != m_validIds.end();
0042 }
0043
0044 DetId CaloSubdetectorGeometry::getClosestCell(const GlobalPoint& r) const {
0045 const CCGFloat eta(r.eta());
0046 const CCGFloat phi(r.phi());
0047 uint32_t index(~0);
0048 CCGFloat closest(1e9);
0049
0050 for (uint32_t i(0); i != m_validIds.size(); ++i) {
0051 auto cell = getGeometry(m_validIds[i]);
0052 if (nullptr != cell) {
0053 const GlobalPoint& p(cell->getPosition());
0054 const CCGFloat eta0(p.eta());
0055 const CCGFloat phi0(p.phi());
0056 const CCGFloat dR2(reco::deltaR2(eta0, phi0, eta, phi));
0057 if (dR2 < closest) {
0058 closest = dR2;
0059 index = i;
0060 }
0061 }
0062 }
0063 return (closest > 0.9e9 || (uint32_t)(~0) == index ? DetId(0) : m_validIds[index]);
0064 }
0065
0066 CaloSubdetectorGeometry::DetIdSet CaloSubdetectorGeometry::getCells(const GlobalPoint& r, double dR) const {
0067 const double dR2(dR * dR);
0068 const double eta(r.eta());
0069 const double phi(r.phi());
0070
0071 DetIdSet dss;
0072
0073 if (0.000001 < dR) {
0074 for (uint32_t i(0); i != m_validIds.size(); ++i) {
0075 auto cell = getGeometry(m_validIds[i]);
0076 if (nullptr != cell) {
0077 const GlobalPoint& p(cell->getPosition());
0078 const CCGFloat eta0(p.eta());
0079 if (fabs(eta - eta0) < dR) {
0080 const CCGFloat phi0(p.phi());
0081 CCGFloat delp(fabs(phi - phi0));
0082 if (delp > M_PI)
0083 delp = 2 * M_PI - delp;
0084 if (delp < dR) {
0085 const CCGFloat dist2(reco::deltaR2(eta0, phi0, eta, phi));
0086 if (dist2 < dR2)
0087 dss.insert(m_validIds[i]);
0088 }
0089 }
0090 }
0091 }
0092 }
0093 return dss;
0094 }
0095
0096 CaloSubdetectorGeometry::CellSet CaloSubdetectorGeometry::getCellSet(const GlobalPoint& r, double dR) const {
0097
0098 DetIdSet ids = getCells(r, dR);
0099 CellSet cells;
0100 cells.reserve(ids.size());
0101 static const auto do_not_delete = [](const void*) {};
0102 for (auto id : ids)
0103 cells.emplace_back(std::shared_ptr<CaloCellGeometry const>(getGeometry(id).get(), do_not_delete));
0104 return cells;
0105 }
0106
0107 void CaloSubdetectorGeometry::allocateCorners(CaloCellGeometry::CornersVec::size_type n) {
0108 assert(nullptr == m_cmgr);
0109 m_cmgr = new CaloCellGeometry::CornersMgr(n * (CaloCellGeometry::k_cornerSize), CaloCellGeometry::k_cornerSize);
0110
0111 m_validIds.reserve(n);
0112 }
0113
0114 void CaloSubdetectorGeometry::allocatePar(ParVec::size_type n, unsigned int m) {
0115 assert(nullptr == m_parMgr);
0116 m_parMgr = new ParMgr(n * m, m);
0117 }
0118
0119 void CaloSubdetectorGeometry::getSummary(CaloSubdetectorGeometry::TrVec& tVec,
0120 CaloSubdetectorGeometry::IVec& iVec,
0121 CaloSubdetectorGeometry::DimVec& dVec,
0122 CaloSubdetectorGeometry::IVec& ) const {
0123 tVec.reserve(m_validIds.size() * numberOfTransformParms());
0124 iVec.reserve(numberOfShapes() == 1 ? 1 : m_validIds.size());
0125 dVec.reserve(numberOfShapes() * numberOfParametersPerShape());
0126
0127 for (const auto& pv : parVecVec()) {
0128 for (float iv : pv) {
0129 dVec.emplace_back(iv);
0130 }
0131 }
0132
0133 for (uint32_t i(0); i != m_validIds.size(); ++i) {
0134 Tr3D tr;
0135 auto ptr{cellGeomPtr(i)};
0136 assert(nullptr != ptr);
0137 ptr->getTransform(tr, (Pt3DVec*)nullptr);
0138
0139 if (Tr3D() == tr) {
0140 const GlobalPoint& gp(ptr->getPosition());
0141 tr = HepGeom::Translate3D(gp.x(), gp.y(), gp.z());
0142 }
0143
0144 const CLHEP::Hep3Vector tt(tr.getTranslation());
0145 tVec.emplace_back(tt.x());
0146 tVec.emplace_back(tt.y());
0147 tVec.emplace_back(tt.z());
0148 if (6 == numberOfTransformParms()) {
0149 const CLHEP::HepRotation rr(tr.getRotation());
0150 const ROOT::Math::Transform3D rtr(
0151 rr.xx(), rr.xy(), rr.xz(), tt.x(), rr.yx(), rr.yy(), rr.yz(), tt.y(), rr.zx(), rr.zy(), rr.zz(), tt.z());
0152 ROOT::Math::EulerAngles ea;
0153 rtr.GetRotation(ea);
0154 tVec.emplace_back(ea.Phi());
0155 tVec.emplace_back(ea.Theta());
0156 tVec.emplace_back(ea.Psi());
0157 }
0158
0159 const CCGFloat* par(ptr->param());
0160
0161 unsigned int ishape(9999);
0162 for (unsigned int ivv(0); ivv != parVecVec().size(); ++ivv) {
0163 bool ok(true);
0164 const CCGFloat* pv(&(*parVecVec()[ivv].begin()));
0165 for (unsigned int k(0); k != numberOfParametersPerShape(); ++k) {
0166 ok = ok && (fabs(par[k] - pv[k]) < 1.e-6);
0167 }
0168 if (ok) {
0169 ishape = ivv;
0170 break;
0171 }
0172 }
0173 assert(9999 != ishape);
0174
0175 const unsigned int nn((numberOfShapes() == 1) ? (unsigned int)1 : m_validIds.size());
0176 if (iVec.size() < nn)
0177 iVec.emplace_back(ishape);
0178 }
0179 }
0180
0181 CCGFloat CaloSubdetectorGeometry::deltaPhi(const DetId& detId) const {
0182 const CaloGenericDetId cgId(detId);
0183
0184 if (!m_deltaPhi.load(std::memory_order_acquire)) {
0185 const uint32_t kSize(sizeForDenseIndex(detId));
0186 auto ptr = new std::vector<CCGFloat>(kSize);
0187 for (uint32_t i(0); i != kSize; ++i) {
0188 auto cellPtr{cellGeomPtr(i)};
0189 if (nullptr != cellPtr) {
0190 CCGFloat dPhi1(fabs(GlobalPoint((cellPtr->getCorners()[0].x() + cellPtr->getCorners()[1].x()) / 2.,
0191 (cellPtr->getCorners()[0].y() + cellPtr->getCorners()[1].y()) / 2.,
0192 (cellPtr->getCorners()[0].z() + cellPtr->getCorners()[1].z()) / 2.)
0193 .phi() -
0194 GlobalPoint((cellPtr->getCorners()[2].x() + cellPtr->getCorners()[3].x()) / 2.,
0195 (cellPtr->getCorners()[2].y() + cellPtr->getCorners()[3].y()) / 2.,
0196 (cellPtr->getCorners()[2].z() + cellPtr->getCorners()[3].z()) / 2.)
0197 .phi()));
0198 CCGFloat dPhi2(fabs(GlobalPoint((cellPtr->getCorners()[0].x() + cellPtr->getCorners()[3].x()) / 2.,
0199 (cellPtr->getCorners()[0].y() + cellPtr->getCorners()[3].y()) / 2.,
0200 (cellPtr->getCorners()[0].z() + cellPtr->getCorners()[3].z()) / 2.)
0201 .phi() -
0202 GlobalPoint((cellPtr->getCorners()[2].x() + cellPtr->getCorners()[1].x()) / 2.,
0203 (cellPtr->getCorners()[2].y() + cellPtr->getCorners()[1].y()) / 2.,
0204 (cellPtr->getCorners()[2].z() + cellPtr->getCorners()[1].z()) / 2.)
0205 .phi()));
0206 if (M_PI < dPhi1)
0207 dPhi1 = fabs(dPhi1 - 2. * M_PI);
0208 if (M_PI < dPhi2)
0209 dPhi2 = fabs(dPhi2 - 2. * M_PI);
0210 (*ptr)[i] = dPhi1 > dPhi2 ? dPhi1 : dPhi2;
0211 }
0212 }
0213 std::vector<CCGFloat>* expect = nullptr;
0214 bool exchanged = m_deltaPhi.compare_exchange_strong(expect, ptr, std::memory_order_acq_rel);
0215 if (!exchanged)
0216 delete ptr;
0217 }
0218 return (*m_deltaPhi.load(std::memory_order_acquire))[indexFor(detId)];
0219 }
0220
0221 CCGFloat CaloSubdetectorGeometry::deltaEta(const DetId& detId) const {
0222 if (!m_deltaEta.load(std::memory_order_acquire)) {
0223 const uint32_t kSize(sizeForDenseIndex(detId));
0224 auto ptr = new std::vector<CCGFloat>(kSize);
0225 for (uint32_t i(0); i != kSize; ++i) {
0226 auto cellPtr{cellGeomPtr(i)};
0227 if (nullptr != cellPtr) {
0228 const CCGFloat dEta1(fabs(GlobalPoint((cellPtr->getCorners()[0].x() + cellPtr->getCorners()[1].x()) / 2.,
0229 (cellPtr->getCorners()[0].y() + cellPtr->getCorners()[1].y()) / 2.,
0230 (cellPtr->getCorners()[0].z() + cellPtr->getCorners()[1].z()) / 2.)
0231 .eta() -
0232 GlobalPoint((cellPtr->getCorners()[2].x() + cellPtr->getCorners()[3].x()) / 2.,
0233 (cellPtr->getCorners()[2].y() + cellPtr->getCorners()[3].y()) / 2.,
0234 (cellPtr->getCorners()[2].z() + cellPtr->getCorners()[3].z()) / 2.)
0235 .eta()));
0236 const CCGFloat dEta2(fabs(GlobalPoint((cellPtr->getCorners()[0].x() + cellPtr->getCorners()[3].x()) / 2.,
0237 (cellPtr->getCorners()[0].y() + cellPtr->getCorners()[3].y()) / 2.,
0238 (cellPtr->getCorners()[0].z() + cellPtr->getCorners()[3].z()) / 2.)
0239 .eta() -
0240 GlobalPoint((cellPtr->getCorners()[2].x() + cellPtr->getCorners()[1].x()) / 2.,
0241 (cellPtr->getCorners()[2].y() + cellPtr->getCorners()[1].y()) / 2.,
0242 (cellPtr->getCorners()[2].z() + cellPtr->getCorners()[1].z()) / 2.)
0243 .eta()));
0244 (*ptr)[i] = dEta1 > dEta2 ? dEta1 : dEta2;
0245 }
0246 }
0247 std::vector<CCGFloat>* expect = nullptr;
0248 bool exchanged = m_deltaEta.compare_exchange_strong(expect, ptr, std::memory_order_acq_rel);
0249 if (!exchanged)
0250 delete ptr;
0251 }
0252 return (*m_deltaEta.load(std::memory_order_acquire))[indexFor(detId)];
0253 }
0254
0255 unsigned int CaloSubdetectorGeometry::indexFor(const DetId& id) const { return CaloGenericDetId(id).denseIndex(); }
0256
0257 unsigned int CaloSubdetectorGeometry::sizeForDenseIndex(const DetId& id) const {
0258 return CaloGenericDetId(id).sizeForDenseIndexing();
0259 }
0260
0261 CaloSubdetectorGeometry::CellPtr CaloSubdetectorGeometry::cellGeomPtr(uint32_t index) const {
0262
0263 return getGeometryRawPtr(index);
0264 }