CMS 3D CMS Logo

EcalBarrelGeometry.cc
Go to the documentation of this file.
7 
8 #include <CLHEP/Geometry/Point3D.h>
9 #include <CLHEP/Geometry/Plane3D.h>
10 #include <CLHEP/Geometry/Vector3D.h>
11 
12 #include <iomanip>
13 #include <iostream>
14 
18 typedef HepGeom::Plane3D<CCGFloat> Pl3D;
19 
21  : _nnxtalEta(85),
22  _nnxtalPhi(360),
23  _PhiBaskets(18),
24  m_borderMgr(nullptr),
25  m_borderPtrVec(nullptr),
26  m_radius(-1.),
27  m_check(false),
28  m_cellVec(k_NumberOfCellsForCorners) {
29  const int neba[] = {25, 45, 65, 85};
30  _EtaBaskets = std::vector<int>(neba, neba + 4);
31 }
32 
34  if (m_borderPtrVec) {
35  auto ptr = m_borderPtrVec.load(std::memory_order_acquire);
36  for (auto& v : (*ptr)) {
37  delete v;
38  v = nullptr;
39  }
40  delete m_borderPtrVec.load();
41  }
42  delete m_borderMgr.load();
43 }
44 
46  const CaloGenericDetId gid(id);
47 
48  assert(gid.isEB());
49 
50  unsigned int index(EBDetId(id).ism() - 1);
51 
52  return index;
53 }
54 
56  return EBDetId(iLoc + 1, 1, EBDetId::SMCRYSTALMODE);
57 }
58 
60  return (unsigned int)DetId::Ecal - 1;
61 }
62 // Get closest cell, etc...
64  // z is the easy one
65  int leverx = 1;
66  int levery = 1;
67  CCGFloat pointz = r.z();
68  int zbin = 1;
69  if (pointz < 0)
70  zbin = -1;
71 
72  // Now find the closest eta
73  CCGFloat pointeta = r.eta();
74  // double eta;
75  CCGFloat deta = 999.;
76  int etabin = 1;
77 
78  int guessed_eta = (int)(fabs(pointeta) / 0.0174) + 1;
79  int guessed_eta_begin = guessed_eta - 1;
80  int guessed_eta_end = guessed_eta + 1;
81  if (guessed_eta_begin < 1)
82  guessed_eta_begin = 1;
83  if (guessed_eta_end > 85)
84  guessed_eta_end = 85;
85 
86  for (int bin = guessed_eta_begin; bin <= guessed_eta_end; bin++) {
87  try {
88  if (!present(EBDetId(zbin * bin, 1, EBDetId::ETAPHIMODE)))
89  continue;
90 
91  CCGFloat eta = getGeometry(EBDetId(zbin * bin, 1, EBDetId::ETAPHIMODE))->etaPos();
92 
93  if (fabs(pointeta - eta) < deta) {
94  deta = fabs(pointeta - eta);
95  etabin = bin;
96  } else
97  break;
98  } catch (cms::Exception& e) {
99  }
100  }
101 
102  // Now the closest phi. always same number of phi bins(!?)
103  constexpr CCGFloat twopi = M_PI + M_PI;
104  // 10 degree tilt
105  constexpr CCGFloat tilt = twopi / 36.;
106 
107  CCGFloat pointphi = r.phi() + tilt;
108 
109  // put phi in correct range (0->2pi)
110  if (pointphi > twopi)
111  pointphi -= twopi;
112  if (pointphi < 0)
113  pointphi += twopi;
114 
115  //calculate phi bin, distinguish + and - eta
116  int phibin = static_cast<int>(pointphi / (twopi / _nnxtalPhi)) + 1;
117  // if(point.z()<0.0)
118  // {
119  // phibin = nxtalPhi/2 - 1 - phibin;
120  // if(phibin<0)
121  // phibin += nxtalPhi;
122  // }
123  try {
124  EBDetId myCell(zbin * etabin, phibin, EBDetId::ETAPHIMODE);
125 
126  if (!present(myCell))
127  return DetId(0);
128 
129  Pt3D A;
130  Pt3D B;
131  Pt3D C;
132  Pt3D point(r.x(), r.y(), r.z());
133 
134  // D.K. : equation of plane : AA*x+BB*y+CC*z+DD=0;
135  // finding equation for each edge
136 
137  // Since the point can lie between crystals, it is necessary to keep track of the movements
138  // to avoid infinite loops
139  CCGFloat history[4]{0.f};
140 
141  //
142  // stop movement in eta direction when closest cell was found (point between crystals)
143  int start = 1;
144  int counter = 0;
145  // Moving until find closest crystal in eta and phi directions (leverx and levery)
146  while (leverx == 1 || levery == 1) {
147  leverx = 0;
148  levery = 0;
149  const CaloCellGeometry::CornersVec& corners(getGeometry(myCell)->getCorners());
150  CCGFloat SS[4];
151 
152  // compute the distance of the point with respect of the 4 crystal lateral planes
153  for (short i = 0; i < 4; ++i) {
154  A = Pt3D(corners[i % 4].x(), corners[i % 4].y(), corners[i % 4].z());
155  B = Pt3D(corners[(i + 1) % 4].x(), corners[(i + 1) % 4].y(), corners[(i + 1) % 4].z());
156  C = Pt3D(corners[4 + (i + 1) % 4].x(), corners[4 + (i + 1) % 4].y(), corners[4 + (i + 1) % 4].z());
157  Pl3D plane(A, B, C);
158  plane.normalize();
159  CCGFloat distance = plane.distance(point);
160  if (plane.d() > 0.)
161  distance = -distance;
162  if (corners[0].z() < 0.)
163  distance = -distance;
164  SS[i] = distance;
165  }
166 
167  // SS's - normals
168  // check position of the point with respect to opposite side of crystal
169  // if SS's have opposite sign, the point lies inside that crystal
170 
171  if ((SS[0] > 0. && SS[2] > 0.) || (SS[0] < 0. && SS[2] < 0.)) {
172  levery = 1;
173  if (history[0] > 0. && history[2] > 0. && SS[0] < 0 && SS[2] < 0 &&
174  (fabs(SS[0]) + fabs(SS[2])) > (fabs(history[0]) + fabs(history[2])))
175  levery = 0;
176  if (history[0] < 0. && history[2] < 0. && SS[0] > 0 && SS[2] > 0 &&
177  (fabs(SS[0]) + fabs(SS[2])) > (fabs(history[0]) + fabs(history[2])))
178  levery = 0;
179 
180  if (SS[0] > 0.) {
181  EBDetId nextPoint;
182  if (myCell.iphi() == EBDetId::MIN_IPHI)
183  nextPoint = EBDetId(myCell.ieta(), EBDetId::MAX_IPHI);
184  else
185  nextPoint = EBDetId(myCell.ieta(), myCell.iphi() - 1);
186  if (present(nextPoint))
187  myCell = nextPoint;
188  else
189  levery = 0;
190  } else {
191  EBDetId nextPoint;
192  if (myCell.iphi() == EBDetId::MAX_IPHI)
193  nextPoint = EBDetId(myCell.ieta(), EBDetId::MIN_IPHI);
194  else
195  nextPoint = EBDetId(myCell.ieta(), myCell.iphi() + 1);
196  if (present(nextPoint))
197  myCell = nextPoint;
198  else
199  levery = 0;
200  }
201  }
202 
203  if (((SS[1] > 0. && SS[3] > 0.) || (SS[1] < 0. && SS[3] < 0.)) && start == 1) {
204  leverx = 1;
205 
206  if (history[1] > 0. && history[3] > 0. && SS[1] < 0 && SS[3] < 0 &&
207  (fabs(SS[1]) + fabs(SS[3])) > (fabs(history[1]) + fabs(history[3]))) {
208  leverx = 0;
209  start = 0;
210  }
211 
212  if (history[1] < 0. && history[3] < 0. && SS[1] > 0 && SS[3] > 0 &&
213  (fabs(SS[1]) + fabs(SS[3])) > (fabs(history[1]) + fabs(history[3]))) {
214  leverx = 0;
215  start = 0;
216  }
217 
218  if (SS[1] > 0.) {
219  EBDetId nextPoint;
220  if (myCell.ieta() == -1)
221  nextPoint = EBDetId(1, myCell.iphi());
222  else {
223  int nieta = myCell.ieta() + 1;
224  if (nieta == 86)
225  nieta = 85;
226  nextPoint = EBDetId(nieta, myCell.iphi());
227  }
228  if (present(nextPoint))
229  myCell = nextPoint;
230  else
231  leverx = 0;
232  } else {
233  EBDetId nextPoint;
234  if (myCell.ieta() == 1)
235  nextPoint = EBDetId(-1, myCell.iphi());
236  else {
237  int nieta = myCell.ieta() - 1;
238  if (nieta == -86)
239  nieta = -85;
240  nextPoint = EBDetId(nieta, myCell.iphi());
241  }
242  if (present(nextPoint))
243  myCell = nextPoint;
244  else
245  leverx = 0;
246  }
247  }
248 
249  // Update the history. If the point lies between crystals, the closest one
250  // is returned
251  std::copy(SS, SS + 4, history);
252 
253  counter++;
254  if (counter == 10) {
255  leverx = 0;
256  levery = 0;
257  }
258  }
259  // D.K. if point lies netween cells, take a closest cell.
260  return DetId(myCell);
261  } catch (cms::Exception& e) {
262  return DetId(0);
263  }
264 }
265 
267  constexpr int maxphi(EBDetId::MAX_IPHI);
268  constexpr int maxeta(EBDetId::MAX_IETA);
269  constexpr float scale(maxphi / (2 * M_PI)); // angle to index
270 
271  CaloSubdetectorGeometry::DetIdSet dis; // this is the return object
272 
273  if (0.000001 < dR) {
274  if (dR > M_PI / 2.) // this version needs "small" dR
275  {
276  dis = CaloSubdetectorGeometry::getCells(r, dR); // base class version
277  } else {
278  const float dR2(dR * dR);
279  const float reta(r.eta());
280  const float rz(r.z());
281  const float rphi(r.phi());
282  const float lowEta(reta - dR);
283  const float highEta(reta + dR);
284 
285  if (highEta > -1.5 && lowEta < 1.5) // in barrel
286  {
287  const int ieta_center(int(reta * scale + ((rz < 0) ? (-1) : (1))));
288  const float phi(rphi < 0 ? rphi + float(2 * M_PI) : rphi);
289  const int iphi_center(int(phi * scale + 11.f)); // phi=-9.4deg is iphi=1
290 
291  const float fr(dR * scale); // # crystal widths in dR
292  const float frp(1.08f * fr + 1.f); // conservatively above fr
293  const float frm(0.92f * fr - 1.f); // conservatively below fr
294  const int idr((int)frp); // integerize
295  const int idr2p((int)(frp * frp));
296  const int idr2m(frm > 0 ? int(frm * frm) : 0);
297 
298  for (int de(-idr); de <= idr; ++de) // over eta limits
299  {
300  int ieta(de + ieta_center);
301 
302  if (std::abs(ieta) <= maxeta && ieta != 0) // eta is in EB
303  {
304  const int de2(de * de);
305  for (int dp(-idr); dp <= idr; ++dp) // over phi limits
306  {
307  const int irange2(dp * dp + de2);
308 
309  if (irange2 <= idr2p) // cut off corners that must be too far away
310  {
311  const int iphi((iphi_center + dp + maxphi - 1) % maxphi + 1);
312 
313  if (iphi != 0) {
314  const EBDetId id(ieta, iphi);
315 
316  bool ok(irange2 < idr2m); // no more calculation necessary if inside this radius
317 
318  if (!ok) // if not ok, then we have to test this cell for being inside cone
319  {
320  const CaloCellGeometry* cell(&m_cellVec[id.denseIndex()]);
321  const float eta(cell->etaPos());
322  const float phi(cell->phiPos());
323  ok = (reco::deltaR2(eta, phi, reta, rphi) < dR2);
324  }
325  if (ok)
326  dis.insert(id);
327  }
328  }
329  }
330  }
331  }
332  }
333  }
334  }
335  return dis;
336 }
337 
339  OrderedListOfEEDetId* ptr(nullptr);
340  auto ptrVec = m_borderPtrVec.load(std::memory_order_acquire);
341  if (!ptrVec) {
342  if (0 != id.rawId()) {
343  const int iPhi(id.iphi());
344  const int iz(id.ieta() > 0 ? 1 : -1);
345  const EEDetId eeid(EEDetId::idOuterRing(iPhi, iz));
346  const int iq(eeid.iquadrant());
347  const int xout(1 == iq || 4 == iq ? 1 : -1);
348  const int yout(1 == iq || 2 == iq ? 1 : -1);
349  if (!m_borderMgr.load(std::memory_order_acquire)) {
350  EZMgrFL<EEDetId>* expect = nullptr;
351  auto ptrMgr = new EZMgrFL<EEDetId>(720 * 9, 9);
352  bool exchanged = m_borderMgr.compare_exchange_strong(expect, ptrMgr, std::memory_order_acq_rel);
353  if (!exchanged)
354  delete ptrMgr;
355  }
356  VecOrdListEEDetIdPtr* expect = nullptr;
357  auto ptrVec = new VecOrdListEEDetIdPtr();
358  ptrVec->reserve(720);
359  for (unsigned int i(0); i != 720; ++i) {
360  const int kz(360 > i ? -1 : 1);
361  const EEDetId eeid(EEDetId::idOuterRing(i % 360 + 1, kz));
362 
363  const int jx(eeid.ix());
364  const int jy(eeid.iy());
365 
366  OrderedListOfEEDetId& olist(*new OrderedListOfEEDetId(m_borderMgr.load(std::memory_order_acquire)));
367  int il(0);
368 
369  for (unsigned int k(1); k <= 25; ++k) {
370  const int kx(1 == k || 2 == k || 3 == k || 12 == k || 13 == k
371  ? 0
372  : (4 == k || 6 == k || 8 == k || 15 == k || 20 == k
373  ? 1
374  : (5 == k || 7 == k || 9 == k || 16 == k || 19 == k
375  ? -1
376  : (10 == k || 14 == k || 21 == k || 22 == k || 25 == k ? 2 : -2))));
377  const int ky(1 == k || 4 == k || 5 == k || 10 == k || 11 == k
378  ? 0
379  : (2 == k || 6 == k || 7 == k || 14 == k || 17 == k
380  ? 1
381  : (3 == k || 8 == k || 9 == k || 18 == k || 21 == k
382  ? -1
383  : (12 == k || 15 == k || 16 == k || 22 == k || 23 == k ? 2 : -2))));
384 
385  if (8 >= il && EEDetId::validDetId(jx + kx * xout, jy + ky * yout, kz)) {
386  olist[il++] = EEDetId(jx + kx * xout, jy + ky * yout, kz);
387  }
388  }
389  ptrVec->emplace_back(&olist);
390  }
391  bool exchanged = m_borderPtrVec.compare_exchange_strong(expect, ptrVec, std::memory_order_acq_rel);
392  if (!exchanged)
393  delete ptrVec;
394  ptrVec = m_borderPtrVec.load(std::memory_order_acquire);
395  ptr = (*ptrVec)[iPhi - 1 + (0 > iz ? 0 : 360)];
396  }
397  }
398  return ptr;
399 }
400 
401 void EcalBarrelGeometry::localCorners(Pt3DVec& lc, const CCGFloat* pv, unsigned int i, Pt3D& ref) {
402  const bool negz(EBDetId::kSizeForDenseIndexing / 2 > i);
403  const bool odd(1 == i % 2);
404 
405  if (((negz && !odd) || (!negz && odd))) {
407  } else {
409  }
410 }
411 
413  const GlobalPoint& f1, const GlobalPoint& f2, const GlobalPoint& f3, const CCGFloat* parm, const DetId& detId) {
414  const unsigned int cellIndex(EBDetId(detId).denseIndex());
415  m_cellVec[cellIndex] = TruncatedPyramid(cornersMgr(), f1, f2, f3, parm);
416  addValidID(detId);
417 }
418 
420  if (!m_check.load(std::memory_order_acquire)) {
421  CCGFloat sum(0);
422  for (uint32_t i(0); i != m_cellVec.size(); ++i) {
423  auto cell(cellGeomPtr(i));
424  if (nullptr != cell) {
425  const GlobalPoint& pos(cell->getPosition());
426  sum += pos.perp();
427  }
428  }
429  m_radius = sum / m_cellVec.size();
430  m_check.store(true, std::memory_order_release);
431  }
432  return m_radius;
433 }
434 
436  // Modify the RawPtr class
437  const CaloCellGeometry* cell(&m_cellVec[index]);
438  return (m_cellVec.size() < index || nullptr == cell->param() ? nullptr : cell);
439 }
440 
441 bool EcalBarrelGeometry::present(const DetId& id) const {
442  if (id.det() == DetId::Ecal && id.subdetId() == EcalBarrel) {
443  EBDetId ebId(id);
444  if (EBDetId::validDetId(ebId.ieta(), ebId.iphi()))
445  return true;
446  }
447  return false;
448 }
Definition: start.py:1
static unsigned int alignmentTransformIndexGlobal(const DetId &id)
static const int MIN_IPHI
Definition: EBDetId.h:135
Definition: APVGainStruct.h:7
virtual float phiPos() const
CaloSubdetectorGeometry::DetIdSet getCells(const GlobalPoint &r, double dR) const override
Get a list of all cells within a dR of the given cell.
CaloCellGeometry::Pt3DVec Pt3DVec
int iphi() const
get the crystal iphi
Definition: EBDetId.h:51
std::atomic< bool > m_check
int ix() const
Definition: EEDetId.h:77
const OrderedListOfEEDetId * getClosestEndcapCells(EBDetId id) const
std::vector< int > _EtaBaskets
std::vector< Pt3D > Pt3DVec
assert(be >=bs)
int iquadrant() const
Definition: EEDetId.cc:206
EZArrayFL< EEDetId > OrderedListOfEEDetId
CaloCellGeometry::CCGFloat CCGFloat
CaloCellGeometry::CCGFloat CCGFloat
void newCell(const GlobalPoint &f1, const GlobalPoint &f2, const GlobalPoint &f3, const CCGFloat *parm, const DetId &detId) override
static bool validDetId(int i, int j)
check if a valid index combination
Definition: EBDetId.h:118
~EcalBarrelGeometry() override
int ieta() const
get the crystal ieta
Definition: EBDetId.h:49
HepGeom::Plane3D< CCGFloat > Pl3D
static void localCornersSwap(Pt3DVec &vec, const CCGFloat *pv, Pt3D &ref)
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.
ALPAKA_FN_ACC static ALPAKA_FN_INLINE float dR2(Position4 pos1, Position4 pos2)
CCGFloat avgRadiusXYFrontFaceCenter() const
static DetId detIdFromLocalAlignmentIndex(unsigned int iLoc)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
std::atomic< VecOrdListEEDetIdPtr * > m_borderPtrVec
static const int ETAPHIMODE
Definition: EBDetId.h:158
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
CaloCellGeometry::Pt3DVec Pt3DVec
CaloCellGeometry::Pt3D Pt3D
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)
static const int MAX_IPHI
Definition: EBDetId.h:137
bool isEB() const
static bool validDetId(int crystal_ix, int crystal_iy, int iz)
Definition: EEDetId.h:248
CaloCellGeometry::CornersMgr * cornersMgr()
static const int MAX_IETA
Definition: EBDetId.h:136
HepGeom::Point3D< CCGFloat > Pt3D
Definition: EZMgrFL.h:8
DetId getClosestCell(const GlobalPoint &r) const override
std::atomic< EZMgrFL< EEDetId > * > m_borderMgr
bool present(const DetId &id) const override
is this detid present in the geometry?
A base class to handle the particular shape of Ecal Xtals. Taken from ORCA Calorimetry Code...
std::vector< OrderedListOfEEDetId * > VecOrdListEEDetIdPtr
static EEDetId idOuterRing(int iPhi, int zEnd)
Definition: EEDetId.cc:339
virtual std::shared_ptr< const CaloCellGeometry > cellGeomPtr(uint32_t index) const
Definition: APVGainStruct.h:7
const CaloCellGeometry * getGeometryRawPtr(uint32_t index) const override
static const int SMCRYSTALMODE
Definition: EBDetId.h:159
int ism(int ieta, int iphi)
Definition: EcalPyUtils.cc:49
static void localCornersReflection(Pt3DVec &vec, const CCGFloat *pv, Pt3D &ref)
const CCGFloat * param() const
static unsigned int alignmentTransformIndexLocal(const DetId &id)
*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
CaloCellGeometry::Pt3D Pt3D
int iy() const
Definition: EEDetId.h:83
static void localCorners(Pt3DVec &lc, const CCGFloat *pv, unsigned int i, Pt3D &ref)