CMS 3D CMS Logo

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