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