CMS 3D CMS Logo

EcalEndcapGeometry.cc
Go to the documentation of this file.
7 #include <CLHEP/Geometry/Point3D.h>
8 #include <CLHEP/Geometry/Plane3D.h>
9 
13 typedef HepGeom::Plane3D<CCGFloat> Pl3D;
14 
15 //#define EDM_ML_DEBUG
16 
18  : _nnmods(316),
19  _nncrys(25),
20  zeP(0.),
21  zeN(0.),
22  m_wref(0.),
23  m_del(0.),
24  m_nref(0),
25  m_borderMgr(nullptr),
26  m_borderPtrVec(nullptr),
27  m_avgZ(-1),
28  m_check(false),
29  m_cellVec(k_NumberOfCellsForCorners) {
30  m_xlo[0] = 999.;
31  m_xlo[1] = 999.;
32  m_xhi[0] = -999.;
33  m_xhi[1] = -999.;
34  m_ylo[0] = 999.;
35  m_ylo[1] = 999.;
36  m_yhi[0] = -999.;
37  m_yhi[1] = -999.;
38  m_xoff[0] = 0.;
39  m_xoff[1] = 0.;
40  m_yoff[0] = 0.;
41  m_yoff[1] = 0.;
42 }
43 
45  if (m_borderPtrVec) {
46  auto ptr = m_borderPtrVec.load(std::memory_order_acquire);
47  for (auto& v : (*ptr)) {
48  delete v;
49  v = nullptr;
50  }
51  delete m_borderPtrVec.load();
52  }
53  delete m_borderMgr.load();
54 }
55 
57  const CaloGenericDetId gid(id);
58 
59  assert(gid.isEE());
60  unsigned int index(EEDetId(id).ix() / 51 + (EEDetId(id).zside() < 0 ? 0 : 2));
61 
62  return index;
63 }
64 
66  return EEDetId(20 + 50 * (iLoc % 2), 50, 2 * (iLoc / 2) - 1);
67 }
68 
70  return (unsigned int)DetId::Ecal - 1;
71 }
72 
74  zeP = 0.;
75  zeN = 0.;
76  unsigned nP = 0;
77  unsigned nN = 0;
78  m_nref = 0;
79 
80  for (uint32_t i(0); i != m_cellVec.size(); ++i) {
81  auto cell = cellGeomPtr(i);
82  if (nullptr != cell) {
83  const CCGFloat z(cell->getPosition().z());
84  if (z > 0.) {
85  zeP += z;
86  ++nP;
87  } else {
88  zeN += z;
89  ++nN;
90  }
92  const unsigned int ix(myId.ix());
93  const unsigned int iy(myId.iy());
94  if (ix > m_nref)
95  m_nref = ix;
96  if (iy > m_nref)
97  m_nref = iy;
98  }
99  }
100  if (0 < nP)
101  zeP /= (CCGFloat)nP;
102  if (0 < nN)
103  zeN /= (CCGFloat)nN;
104 
105  m_xlo[0] = 999;
106  m_xhi[0] = -999;
107  m_ylo[0] = 999;
108  m_yhi[0] = -999;
109  m_xlo[1] = 999;
110  m_xhi[1] = -999;
111  m_ylo[1] = 999;
112  m_yhi[1] = -999;
113  for (uint32_t i(0); i != m_cellVec.size(); ++i) {
114  auto cell = cellGeomPtr(i);
115  if (nullptr != cell) {
116  const GlobalPoint& p(cell->getPosition());
117  const CCGFloat z(p.z());
118  const CCGFloat zz(0 > z ? zeN : zeP);
119  const CCGFloat x(p.x() * zz / z);
120  const CCGFloat y(p.y() * zz / z);
121 
122  if (0 > z && x < m_xlo[0])
123  m_xlo[0] = x;
124  if (0 < z && x < m_xlo[1])
125  m_xlo[1] = x;
126  if (0 > z && y < m_ylo[0])
127  m_ylo[0] = y;
128  if (0 < z && y < m_ylo[1])
129  m_ylo[1] = y;
130 
131  if (0 > z && x > m_xhi[0])
132  m_xhi[0] = x;
133  if (0 < z && x > m_xhi[1])
134  m_xhi[1] = x;
135  if (0 > z && y > m_yhi[0])
136  m_yhi[0] = y;
137  if (0 < z && y > m_yhi[1])
138  m_yhi[1] = y;
139  }
140  }
141 
142  m_xoff[0] = (m_xhi[0] + m_xlo[0]) / 2.;
143  m_xoff[1] = (m_xhi[1] + m_xlo[1]) / 2.;
144  m_yoff[0] = (m_yhi[0] + m_ylo[0]) / 2.;
145  m_yoff[1] = (m_yhi[1] + m_ylo[1]) / 2.;
146 
147  m_del = (m_xhi[0] - m_xlo[0] + m_xhi[1] - m_xlo[1] + m_yhi[0] - m_ylo[0] + m_yhi[1] - m_ylo[1]);
148 
149  if (1 != m_nref)
150  m_wref = m_del / (4. * (m_nref - 1));
151 
152  m_xlo[0] -= m_wref / 2;
153  m_xlo[1] -= m_wref / 2;
154  m_xhi[0] += m_wref / 2;
155  m_xhi[1] += m_wref / 2;
156 
157  m_ylo[0] -= m_wref / 2;
158  m_ylo[1] -= m_wref / 2;
159  m_yhi[0] += m_wref / 2;
160  m_yhi[1] += m_wref / 2;
161 
162  m_del += m_wref;
163 
164 #ifdef EDM_ML_DEBUG
165  edm::LogVerbatim("EcalGeom") << "zeP=" << zeP << ", zeN=" << zeN << ", nP=" << nP << ", nN=" << nN;
166 
167  edm::LogVerbatim("EcalGeom") << "xlo[0]=" << m_xlo[0] << ", xlo[1]=" << m_xlo[1] << ", xhi[0]=" << m_xhi[0]
168  << ", xhi[1]=" << m_xhi[1] << "\nylo[0]=" << m_ylo[0] << ", ylo[1]=" << m_ylo[1]
169  << ", yhi[0]=" << m_yhi[0] << ", yhi[1]=" << m_yhi[1];
170 
171  edm::LogVerbatim("EcalGeom") << "xoff[0]=" << m_xoff[0] << ", xoff[1]" << m_xoff[1] << ", yoff[0]=" << m_yoff[0]
172  << ", yoff[1]" << m_yoff[1];
173 
174  edm::LogVerbatim("EcalGeom") << "nref=" << m_nref << ", m_wref=" << m_wref;
175 #endif
176 }
177 
179  const CCGFloat xlo(0 > z ? m_xlo[0] : m_xlo[1]);
180  const int i(1 + int((x - xlo) / m_wref));
181 
182  return (1 > i ? 1 : (m_nref < (unsigned int)i ? m_nref : (unsigned int)i));
183 }
184 
186  const CCGFloat ylo(0 > z ? m_ylo[0] : m_ylo[1]);
187  const int i(1 + int((y - ylo) / m_wref));
188 
189  return (1 > i ? 1 : (m_nref < (unsigned int)i ? m_nref : (unsigned int)i));
190 }
191 
192 EEDetId EcalEndcapGeometry::gId(float x, float y, float z) const {
193  const CCGFloat fac(fabs((0 > z ? zeN : zeP) / z));
194  const unsigned int ix(xindex(x * fac, z));
195  const unsigned int iy(yindex(y * fac, z));
196  const unsigned int iz(z > 0 ? 1 : -1);
197 
198  if (EEDetId::validDetId(ix, iy, iz)) {
199  return EEDetId(ix, iy, iz); // first try is on target
200  } else // try nearby coordinates, spiraling out from center
201  {
202  for (unsigned int i(1); i != 6; ++i) {
203  for (unsigned int k(0); k != 8; ++k) {
204  const int jx(0 == k || 4 == k || 5 == k ? +i : (1 == k || 5 < k ? -i : 0));
205  const int jy(2 == k || 4 == k || 6 == k ? +i : (3 == k || 5 == k || 7 == k ? -i : 0));
206  if (EEDetId::validDetId(ix + jx, iy + jy, iz)) {
207  return EEDetId(ix + jx, iy + jy, iz);
208  }
209  }
210  }
211  }
212  return EEDetId(); // nowhere near any crystal
213 }
214 
215 // Get closest cell, etc...
217  try {
218  EEDetId mycellID(gId(r.x(), r.y(), r.z())); // educated guess
219 
220  if (EEDetId::validDetId(mycellID.ix(), mycellID.iy(), mycellID.zside())) {
221  // now get points in convenient ordering
222 
223  Pt3D A;
224  Pt3D B;
225  Pt3D C;
226  Pt3D point(r.x(), r.y(), r.z());
227  // D.K. : equation of plane : AA*x+BB*y+CC*z+DD=0;
228  // finding equation for each edge
229 
230  // ================================================================
231  CCGFloat x, y, z;
232  unsigned offset = 0;
233  int zsign = 1;
234  //================================================================
235 
236  // compute the distance of the point with respect of the 4 crystal lateral planes
237 
238  if (nullptr != getGeometry(mycellID)) {
239  const GlobalPoint& myPosition = getGeometry(mycellID)->getPosition();
240 
241  x = myPosition.x();
242  y = myPosition.y();
243  z = myPosition.z();
244 
245  offset = 0;
246  // This will disappear when Andre has applied his fix
247 
248  if (z > 0) {
249  if (x > 0 && y > 0)
250  offset = 1;
251  else if (x < 0 && y > 0)
252  offset = 2;
253  else if (x > 0 && y < 0)
254  offset = 0;
255  else if (x < 0 && y < 0)
256  offset = 3;
257  zsign = 1;
258  } else {
259  if (x > 0 && y > 0)
260  offset = 3;
261  else if (x < 0 && y > 0)
262  offset = 2;
263  else if (x > 0 && y < 0)
264  offset = 0;
265  else if (x < 0 && y < 0)
266  offset = 1;
267  zsign = -1;
268  }
269  GlobalPoint corners[8];
270  for (unsigned ic = 0; ic < 4; ++ic) {
271  corners[ic] = getGeometry(mycellID)->getCorners()[(unsigned)((zsign * ic + offset) % 4)];
272  corners[4 + ic] = getGeometry(mycellID)->getCorners()[(unsigned)(4 + (zsign * ic + offset) % 4)];
273  }
274 
275  CCGFloat SS[4];
276  for (short i = 0; i < 4; ++i) {
277  A = Pt3D(corners[i % 4].x(), corners[i % 4].y(), corners[i % 4].z());
278  B = Pt3D(corners[(i + 1) % 4].x(), corners[(i + 1) % 4].y(), corners[(i + 1) % 4].z());
279  C = Pt3D(corners[4 + (i + 1) % 4].x(), corners[4 + (i + 1) % 4].y(), corners[4 + (i + 1) % 4].z());
280  Pl3D plane(A, B, C);
281  plane.normalize();
282  CCGFloat distance = plane.distance(point);
283  if (corners[0].z() < 0.)
284  distance = -distance;
285  SS[i] = distance;
286  }
287 
288  // Only one move in necessary direction
289 
290  const bool yout(0 > SS[0] * SS[2]);
291  const bool xout(0 > SS[1] * SS[3]);
292 
293  if (yout || xout) {
294  const int ydel(!yout ? 0 : (0 < SS[0] ? -1 : 1));
295  const int xdel(!xout ? 0 : (0 < SS[1] ? -1 : 1));
296  const unsigned int ix(mycellID.ix() + xdel);
297  const unsigned int iy(mycellID.iy() + ydel);
298  const unsigned int iz(mycellID.zside());
299  if (EEDetId::validDetId(ix, iy, iz))
300  mycellID = EEDetId(ix, iy, iz);
301  }
302 
303  return mycellID;
304  }
305  return DetId(0);
306  }
307  } catch (cms::Exception& e) {
308  return DetId(0);
309  }
310  return DetId(0);
311 }
312 
314  CaloSubdetectorGeometry::DetIdSet dis; // return object
315  if (0.000001 < dR) {
316  if (dR > M_PI / 2.) // this code assumes small dR
317  {
318  dis = CaloSubdetectorGeometry::getCells(r, dR); // base class version
319  } else {
320  const float dR2(dR * dR);
321  const float reta(r.eta());
322  const float rphi(r.phi());
323  const float rx(r.x());
324  const float ry(r.y());
325  const float rz(r.z());
326  const float fac(std::abs(zeP / rz));
327  const float xx(rx * fac); // xyz at endcap z
328  const float yy(ry * fac);
329  const float zz(rz * fac);
330 
331  const float xang(std::atan(xx / zz));
332  const float lowX(zz > 0 ? zz * std::tan(xang - dR) : zz * std::tan(xang + dR));
333  const float highX(zz > 0 ? zz * std::tan(xang + dR) : zz * std::tan(xang - dR));
334  const float yang(std::atan(yy / zz));
335  const float lowY(zz > 0 ? zz * std::tan(yang - dR) : zz * std::tan(yang + dR));
336  const float highY(zz > 0 ? zz * std::tan(yang + dR) : zz * std::tan(yang - dR));
337 
338  const float refxlo(0 > rz ? m_xlo[0] : m_xlo[1]);
339  const float refxhi(0 > rz ? m_xhi[0] : m_xhi[1]);
340  const float refylo(0 > rz ? m_ylo[0] : m_ylo[1]);
341  const float refyhi(0 > rz ? m_yhi[0] : m_yhi[1]);
342 
343  if (lowX < refxhi && // proceed if any possible overlap with the endcap
344  lowY < refyhi && highX > refxlo && highY > refylo) {
345  const int ix_ctr(xindex(xx, rz));
346  const int iy_ctr(yindex(yy, rz));
347  const int iz(rz > 0 ? 1 : -1);
348 
349  const int ix_hi(ix_ctr + int((highX - xx) / m_wref) + 2);
350  const int ix_lo(ix_ctr - int((xx - lowX) / m_wref) - 2);
351 
352  const int iy_hi(iy_ctr + int((highY - yy) / m_wref) + 2);
353  const int iy_lo(iy_ctr - int((yy - lowY) / m_wref) - 2);
354 
355  for (int kx(ix_lo); kx <= ix_hi; ++kx) {
356  if (kx > 0 && kx <= (int)m_nref) {
357  for (int ky(iy_lo); ky <= iy_hi; ++ky) {
358  if (ky > 0 && ky <= (int)m_nref) {
359  if (EEDetId::validDetId(kx, ky, iz)) // reject invalid ids
360  {
361  const EEDetId id(kx, ky, iz);
362  const CaloCellGeometry* cell(&m_cellVec[id.denseIndex()]);
363  const float eta(cell->etaPos());
364  const float phi(cell->phiPos());
365  if (reco::deltaR2(eta, phi, reta, rphi) < dR2)
366  dis.insert(id);
367  }
368  }
369  }
370  }
371  }
372  }
373  }
374  }
375  return dis;
376 }
377 
379  OrderedListOfEBDetId* ptr(nullptr);
380  auto ptrVec = m_borderPtrVec.load(std::memory_order_acquire);
381  if (!ptrVec) {
382  if (0 != id.rawId() && nullptr != getGeometry(id)) {
383  const float phi(370. + getGeometry(id)->getPosition().phi().degrees());
384  const int iPhi(1 + int(phi) % 360);
385  const int iz(id.zside());
386  if (!m_borderMgr.load(std::memory_order_acquire)) {
387  EZMgrFL<EBDetId>* expect = nullptr;
388  auto ptrMgr = new EZMgrFL<EBDetId>(720 * 9, 9);
389  bool exchanged = m_borderMgr.compare_exchange_strong(expect, ptrMgr, std::memory_order_acq_rel);
390  if (!exchanged)
391  delete ptrMgr;
392  }
393  VecOrdListEBDetIdPtr* expect = nullptr;
394  auto ptrVec = new VecOrdListEBDetIdPtr();
395  ptrVec->reserve(720);
396  for (unsigned int i(0); i != 720; ++i) {
397  const int kz(360 > i ? -1 : 1);
398  const int iEta(kz * 85);
399  const int iEtam1(kz * 84);
400  const int iEtam2(kz * 83);
401  const int jPhi(i % 360 + 1);
402  OrderedListOfEBDetId& olist(*new OrderedListOfEBDetId(m_borderMgr.load(std::memory_order_acquire)));
403  olist[0] = EBDetId(iEta, jPhi);
404  olist[1] = EBDetId(iEta, myPhi(jPhi + 1));
405  olist[2] = EBDetId(iEta, myPhi(jPhi - 1));
406  olist[3] = EBDetId(iEtam1, jPhi);
407  olist[4] = EBDetId(iEtam1, myPhi(jPhi + 1));
408  olist[5] = EBDetId(iEtam1, myPhi(jPhi - 1));
409  olist[6] = EBDetId(iEta, myPhi(jPhi + 2));
410  olist[7] = EBDetId(iEta, myPhi(jPhi - 2));
411  olist[8] = EBDetId(iEtam2, jPhi);
412  ptrVec->emplace_back(&olist);
413  }
414  bool exchanged = m_borderPtrVec.compare_exchange_strong(expect, ptrVec, std::memory_order_acq_rel);
415  if (!exchanged)
416  delete ptrVec;
417  ptrVec = m_borderPtrVec.load(std::memory_order_acquire);
418  ptr = (*ptrVec)[(iPhi - 1) + (0 > iz ? 0 : 360)];
419  }
420  }
421  return ptr;
422 }
423 
424 void EcalEndcapGeometry::localCorners(Pt3DVec& lc, const CCGFloat* pv, unsigned int /*i*/, Pt3D& ref) {
426 }
427 
429  const GlobalPoint& f1, const GlobalPoint& f2, const GlobalPoint& f3, const CCGFloat* parm, const DetId& detId) {
430  const unsigned int cellIndex(EEDetId(detId).denseIndex());
431  m_cellVec[cellIndex] = TruncatedPyramid(cornersMgr(), f1, f2, f3, parm);
432  addValidID(detId);
433 }
434 
436  if (!m_check.load(std::memory_order_acquire)) {
437  CCGFloat sum(0);
438  for (unsigned int i(0); i != m_cellVec.size(); ++i) {
439  auto cell = cellGeomPtr(i);
440  if (nullptr != cell) {
441  sum += fabs(cell->getPosition().z());
442  }
443  }
444  m_avgZ = sum / m_cellVec.size();
445  m_check.store(true, std::memory_order_release);
446  }
447  return m_avgZ;
448 }
449 
451  // Modify the RawPtr class
452  const CaloCellGeometry* cell(&m_cellVec[index]);
453  return (m_cellVec.size() < index || nullptr == cell->param() ? nullptr : cell);
454 }
455 
456 bool EcalEndcapGeometry::present(const DetId& id) const {
457  if (id.det() == DetId::Ecal && id.subdetId() == EcalEndcap) {
458  EEDetId eeId(id);
459  if (EEDetId::validDetId(eeId.ix(), eeId.iy(), eeId.zside()))
460  return true;
461  }
462  return false;
463 }
static EEDetId detIdFromDenseIndex(uint32_t din)
Definition: EEDetId.h:220
static void localCorners(Pt3DVec &vec, const CCGFloat *pv, Pt3D &ref)
Log< level::Info, true > LogVerbatim
double degrees(double radiants)
def degrees
CaloCellGeometry::Pt3DVec Pt3DVec
~EcalEndcapGeometry() override
Definition: APVGainStruct.h:7
virtual float phiPos() const
T z() const
Definition: PV3DBase.h:61
static void localCorners(Pt3DVec &lc, const CCGFloat *pv, unsigned int i, Pt3D &ref)
CaloCellGeometry::Pt3D Pt3D
int ix() const
Definition: EEDetId.h:77
int zside(DetId const &)
std::vector< Pt3D > Pt3DVec
static unsigned int alignmentTransformIndexGlobal(const DetId &id)
assert(be >=bs)
CaloCellGeometry::CCGFloat CCGFloat
float float float z
std::atomic< EZMgrFL< EBDetId > * > m_borderMgr
static unsigned int alignmentTransformIndexLocal(const DetId &id)
CaloCellGeometry::Pt3D Pt3D
HepGeom::Plane3D< CCGFloat > Pl3D
CaloCellGeometry::CCGFloat CCGFloat
const CaloCellGeometry * getGeometryRawPtr(uint32_t index) const override
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
virtual float etaPos() const
virtual DetIdSet getCells(const GlobalPoint &r, double dR) const
Get a list of all cells within a dR of the given cell.
std::atomic< VecOrdListEBDetIdPtr * > m_borderPtrVec
CCGFloat avgAbsZFrontFaceCenter() const
CaloCellGeometry::Pt3DVec Pt3DVec
bool present(const DetId &id) const override
is this detid present in the geometry?
unsigned int yindex(CCGFloat y, CCGFloat z) const
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< OrderedListOfEBDetId * > VecOrdListEBDetIdPtr
unsigned int xindex(CCGFloat x, CCGFloat z) const
EEDetId gId(float x, float y, float z) const
HepGeom::Plane3D< CCGFloat > Pl3D
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
#define M_PI
Definition: DetId.h:17
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
void addValidID(const DetId &id)
int zside() const
Definition: EEDetId.h:71
static int myPhi(int i)
static bool validDetId(int crystal_ix, int crystal_iy, int iz)
Definition: EEDetId.h:248
CaloCellGeometry::CornersMgr * cornersMgr()
CaloSubdetectorGeometry::DetIdSet getCells(const GlobalPoint &r, double dR) const override
Get a list of all cells within a dR of the given cell.
CaloCellGeometry::CCGFloat CCGFloat
HepGeom::Point3D< CCGFloat > Pt3D
void newCell(const GlobalPoint &f1, const GlobalPoint &f2, const GlobalPoint &f3, const CCGFloat *parm, const DetId &detId) override
Definition: EZMgrFL.h:8
std::atomic< bool > m_check
A base class to handle the particular shape of Ecal Xtals. Taken from ORCA Calorimetry Code...
DetId getClosestCell(const GlobalPoint &r) const override
bool isEE() const
EZArrayFL< EBDetId > OrderedListOfEBDetId
static DetId detIdFromLocalAlignmentIndex(unsigned int iLoc)
float x
virtual std::shared_ptr< const CaloCellGeometry > cellGeomPtr(uint32_t index) const
const OrderedListOfEBDetId * getClosestBarrelCells(EEDetId id) const
Definition: APVGainStruct.h:7
const CCGFloat * param() const
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
int iy() const
Definition: EEDetId.h:83
void initializeParms() override