CMS 3D CMS Logo

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