CMS 3D CMS Logo

CaloGeometryHelper.cc
Go to the documentation of this file.
2 
3 //#include "FWCore/ParameterSet/interface/ParameterSet.h"
4 
5 // needed for the debugging
10 
17 
20 
22 
23 #include <algorithm>
24 
26 {
28  psLayer1Z_ = 303;
29  psLayer2Z_ = 307;
30 }
31 
33 {
34  // std::cout << " In the constructor with ParameterSet " << std::endl;
35  psLayer1Z_ = 303;
36  psLayer2Z_ = 307;
37 }
38 
40 {
43  bfield_ = bField;
45 
47  {
48  ESDetId cps1(getEcalPreshowerGeometry()->getClosestCellInPlane(GlobalPoint(80.,80.,303.),1));
50  ESDetId cps2(getEcalPreshowerGeometry()->getClosestCellInPlane(GlobalPoint(80.,80.,307.),2));
52  LogDebug("CaloGeometryTools") << " Preshower layer positions " << psLayer1Z_ << " " << psLayer2Z_ << std::endl;
53  }
54  else
55  LogDebug("CaloGeometryTools") << " No preshower present" << std::endl;
56 
57  // std::cout << " Preshower layer positions " << psLayer1Z_ << " " << psLayer2Z_ << std::endl;
58 
59 }
60 
62 {;
63 }
64 
65 DetId CaloGeometryHelper::getClosestCell(const XYZPoint& point, bool ecal, bool central) const
66 {
67  DetId result;
68  if(ecal)
69  {
70  if(central)
71  {
72  // std::cout << "EcalBarrelGeometry_" << " " << EcalBarrelGeometry_ << std::endl;
73  result = EcalBarrelGeometry_->getClosestCell(GlobalPoint(point.X(),point.Y(),point.Z()));
74 #ifdef DEBUGGCC
75  if(result.null()) return result;
76  GlobalPoint ip=GlobalPoint(point.X(),point.Y(),point.Z());
78  float deltaeta2 = ip.eta()-cc.eta();
79  deltaeta2 *= deltaeta2;
80  float deltaphi2 = acos(cos(ip.phi()-cc.phi()));
81  deltaphi2 *= deltaphi2;
82  Histos::instance()->fill("h100",point.eta(),sqrt(deltaeta2+deltaphi2));
83 #endif
84  }
85  else
86  {
87  result = EcalEndcapGeometry_->getClosestCell(GlobalPoint(point.X(),point.Y(),point.Z()));
88 #ifdef DEBUGGCC
89  if(result.null())
90  {
91  return result;
92  }
93  GlobalPoint ip=GlobalPoint(point.X(),point.Y(),point.Z());
95  Histos::instance()->fill("h110",point.eta(),(ip-cc).perp());
96 #endif
97  }
98  }
99  else
100  {
101  result=HcalGeometry_->getClosestCell(GlobalPoint(point.X(),point.Y(),point.Z()));
102  HcalDetId myDetId(result);
103 
104  // special patch for HF
105  if ( myDetId.subdetId() == HcalForward ) {
106  int mylayer;
107  if ( fabs(point.Z()) > 1132. ) {
108  mylayer = 2;
109  } else {
110  mylayer = 1;
111  }
112  HcalDetId myDetId2((HcalSubdetector)myDetId.subdetId(),myDetId.ieta(),myDetId.iphi(),mylayer);
113  result = myDetId2;
114  return result;
115  }
116 
117 
118  if(result.subdetId()!=HcalEndcap) return result;
119  // Special patch to correct the HCAL geometry
120  if(myDetId.depth()==3) return result;
121 
122  int ieta=myDetId.ietaAbs();
123  float azmin=400.458;
124 
125  if(ieta<=17)
126  return result;
127  else if(ieta>=18 && ieta<=26)
128  azmin += 35.0; // don't consider ieta=18 nose separately
129  else if(ieta>=27)
130  azmin += 21.0;
131 
132  HcalDetId first(HcalEndcap,myDetId.ieta(),myDetId.iphi(),1);
133  bool layer2=(fabs(point.Z())>azmin);
134  if(!layer2)
135  {
136  return first;
137  }
138  else
139  {
140  HcalDetId second(HcalEndcap,myDetId.ieta(),myDetId.iphi(),2);
141  if(second!=HcalDetId()) result=second;
142  }
143 #ifdef DEBUGGCC
144  if(result.null())
145  {
146  return result;
147  }
148  GlobalPoint ip=GlobalPoint(point.x(),point.y(),point.z());
150  float deltaeta2 = ip.eta()-cc.eta();
151  deltaeta2 *= deltaeta2;
152  float deltaphi2 = acos(cos(ip.phi()-cc.phi()));
153  deltaphi2 *= deltaphi2;
154 
155  Histos::instance()->fill("h120",point.eta(),sqrt(deltaeta2+deltaphi2));
156 #endif
157 
158  }
159  return result;
160 }
161 
162 void CaloGeometryHelper::getWindow(const DetId& pivot,int s1,int s2,std::vector<DetId>& vec) const
163 {
164  // currently the getWindow method is the same for EcalBarrelTopology and EndcapTopology
165  // (implemented in CaloSubDetectorTopology)
166  // optimized versions are foreseen
167  vec=getEcalTopology(pivot.subdetId())->getWindow(pivot,s1,s2);
169  sort(vec.begin(),vec.end(),distance);
170 }
171 
172 void CaloGeometryHelper::buildCrystal(const DetId & cell,Crystal& xtal) const
173 {
174  if(cell.subdetId()==EcalBarrel)
175  {
176  xtal=Crystal(cell,&barrelCrystals_[EBDetId(cell).hashedIndex()]);
177  return;
178  }
179  if(cell.subdetId()==EcalEndcap)
180  {
181  xtal=Crystal(cell,&endcapCrystals_[EEDetId(cell).hashedIndex()]);
182  return;
183  }
184 }
185 
186 // Build the array of (max)8 neighbors
188 {
189 
191  NORTHEAST};
192 
193  const unsigned nbarrel = EBDetId::kSizeForDenseIndexing;
194  // Barrel first. The hashed index runs from 0 to 61199
195  barrelNeighbours_.resize(nbarrel);
196 
197  //std::cout << " Building the array of neighbours (barrel) " ;
198 
199  const std::vector<DetId>& vec(EcalBarrelGeometry_->getValidDetIds(DetId::Ecal,EcalBarrel));
200  unsigned size=vec.size();
201  for(unsigned ic=0; ic<size; ++ic)
202  {
203  // We get the 9 cells in a square.
204  std::vector<DetId> neighbours(EcalBarrelTopology_->getWindow(vec[ic],3,3));
205  // std::cout << " Cell " << EBDetId(vec[ic]) << std::endl;
206  unsigned nneighbours=neighbours.size();
207 
208  unsigned hashedindex=EBDetId(vec[ic]).hashedIndex();
209  if(hashedindex>=nbarrel)
210  {
211  LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
212  }
213 
214 
215  // If there are 9 cells, it is easy, and this order is know:
216 // 6 7 8
217 // 3 4 5
218 // 0 1 2 (0 = SOUTHWEST)
219 
220  if(nneighbours==9)
221  {
222  //barrelNeighbours_[hashedindex].reserve(8);
223  unsigned int nn=0;
224  for(unsigned in=0;in<nneighbours;++in)
225  {
226  // remove the centre
227  if(neighbours[in]!=vec[ic])
228  {
229  barrelNeighbours_[hashedindex][nn]=(neighbours[in]);
230  nn++;
231  // std::cout << " Neighbour " << in << " " << EBDetId(neighbours[in]) << std::endl;
232  }
233  }
234  }
235  else
236  {
237  DetId central(vec[ic]);
238  //barrelNeighbours_[hashedindex].resize(8,DetId(0));
239  for(unsigned idir=0;idir<8;++idir)
240  {
241  DetId testid=central;
242  bool status=move(testid,orderedDir[idir],false);
243  if(status) barrelNeighbours_[hashedindex][idir]=testid;
244  }
245 
246  }
247  }
248 
249  // Moved to the endcap
250 
251  // std::cout << " done " << size << std::endl;
252  // std::cout << " Building the array of neighbours (endcap) " ;
253 
254 
255  const std::vector<DetId> & vece(EcalEndcapGeometry_->getValidDetIds(DetId::Ecal,EcalEndcap));
256  size=vece.size();
257  // There are some holes in the hashedIndex for the EE. Hence the array is bigger than the number
258  // of crystals
259  const unsigned nendcap=EEDetId::kSizeForDenseIndexing;
260 
261  endcapNeighbours_.resize(nendcap);
262  for(unsigned ic=0; ic<size; ++ic)
263  {
264  // We get the 9 cells in a square.
265  std::vector<DetId> neighbours(EcalEndcapTopology_->getWindow(vece[ic],3,3));
266  unsigned nneighbours=neighbours.size();
267  // remove the centre
268  unsigned hashedindex=EEDetId(vece[ic]).hashedIndex();
269 
270  if(hashedindex>=nendcap)
271  {
272  LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
273  }
274 
275  if(nneighbours==9)
276  {
277  //endcapNeighbours_[hashedindex].reserve(8);
278  unsigned int nn=0;
279  for(unsigned in=0;in<nneighbours;++in)
280  {
281  // remove the centre
282  if(neighbours[in]!=vece[ic])
283  {
284  endcapNeighbours_[hashedindex][nn]=(neighbours[in]);
285  nn++;
286  }
287  }
288  }
289  else
290  {
291  DetId central(vece[ic]);
292  //endcapNeighbours_[hashedindex].resize(8,DetId(0));
293  for(unsigned idir=0;idir<8;++idir)
294  {
295  DetId testid=central;
296  bool status=move(testid,orderedDir[idir],false);
297  if(status) endcapNeighbours_[hashedindex][idir]=testid;
298  }
299 
300  }
301  }
302  // std::cout << " done " << size <<std::endl;
304 }
305 
307 {
308  return (detid.subdetId()==EcalBarrel)?barrelNeighbours_[EBDetId(detid).hashedIndex()]:
310 }
311 
312 bool CaloGeometryHelper::move(DetId& cell, const CaloDirection&dir,bool fast) const
313 {
314  DetId originalcell = cell;
315  if(dir==NONE || cell==DetId(0)) return false;
316 
317  // Conversion CaloDirection and index in the table
318  // CaloDirection :NONE,SOUTH,SOUTHEAST,SOUTHWEST,EAST,WEST, NORTHEAST,NORTHWEST,NORTH
319  // Table : SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH, NORTHEAST
320  static const int calodirections[9]={-1,1,2,0,4,3,7,5,6};
321 
322  if(fast&&neighbourmapcalculated_)
323  {
324  DetId result = (originalcell.subdetId()==EcalBarrel) ?
325  barrelNeighbours_[EBDetId(originalcell).hashedIndex()][calodirections[dir]]:
326  endcapNeighbours_[EEDetId(originalcell).hashedIndex()][calodirections[dir]];
327  bool status = !result.null();
328  cell = result;
329  return status;
330  }
331 
332  if(dir==NORTH || dir ==SOUTH || dir==EAST || dir==WEST)
333  {
334  return simplemove(cell,dir);
335  }
336  else
337  {
338  if(dir == NORTHEAST || dir==NORTHWEST || dir==SOUTHEAST || dir==SOUTHWEST)
339  return diagonalmove(cell,dir);
340  }
341 
342  cell = DetId(0);
343  return false;
344 }
345 
346 
348 {
349  std::vector<DetId> neighbours;
350  if(cell.subdetId()==EcalBarrel)
351  neighbours = EcalBarrelTopology_->getNeighbours(cell,dir);
352  else if(cell.subdetId()==EcalEndcap)
353  neighbours= EcalEndcapTopology_->getNeighbours(cell,dir);
354 
355  if(neighbours.size()>0 && !neighbours[0].null())
356  {
357  cell = neighbours[0];
358  return true;
359  }
360  else
361  {
362  cell = DetId(0);
363  return false;
364  }
365 }
366 
368 {
369  bool result;
370  // One has to try both paths
371  if(dir==NORTHEAST)
372  {
373  result = simplemove(cell,NORTH);
374  if(result)
375  return simplemove(cell,EAST);
376  else
377  {
378  result = simplemove(cell,EAST);
379  if(result)
380  return simplemove(cell,NORTH);
381  else
382  return false;
383  }
384  }
385  else if(dir==NORTHWEST)
386  {
387  result = simplemove(cell,NORTH);
388  if(result)
389  return simplemove(cell,WEST);
390  else
391  {
392  result = simplemove(cell,WEST);
393  if(result)
394  return simplemove(cell,NORTH);
395  else
396  return false;
397  }
398  }
399  else if(dir == SOUTHEAST)
400  {
401  result = simplemove(cell,SOUTH);
402  if(result)
403  return simplemove(cell,EAST);
404  else
405  {
406  result = simplemove(cell,EAST);
407  if(result)
408  return simplemove(cell,SOUTH);
409  else
410  return false;
411  }
412  }
413  else if(dir == SOUTHWEST)
414  {
415  result = simplemove(cell,SOUTH);
416  if(result)
417  return simplemove(cell,WEST);
418  else
419  {
420  result = simplemove(cell,SOUTH);
421  if(result)
422  return simplemove(cell,WEST);
423  else
424  return false;
425  }
426  }
427  cell = DetId(0);
428  return false;
429 }
430 
431 bool CaloGeometryHelper::borderCrossing(const DetId& c1, const DetId& c2) const
432 {
433  if(c1.subdetId()!=c2.subdetId()) return false;
434 
435  if(c1.subdetId()==EcalBarrel)
436  {
437  // there is a crack if the two cells don't belong to the same
438  // module
439  EBDetId cc1(c1);
440  EBDetId cc2(c2);
441  return (cc1.im()!=cc2.im()||cc1.ism()!=cc2.ism() );
442  }
443 
444 if(c1.subdetId()==EcalEndcap)
445  {
446  // there is a crack if the two cells don't belong to the same
447  // module
448  return (EEDetId(c1).isc()!=EEDetId(c2).isc());
449  }
450  return false;
451 }
452 
454 {
455  const unsigned nbarrel = EBDetId::kSizeForDenseIndexing;
456  // Barrel first. The hashed index runs from 0 to 61199
457  barrelCrystals_.resize(nbarrel,BaseCrystal());
458 
459  //std::cout << " Building the array of crystals (barrel) " ;
460  const std::vector<DetId>& vec(EcalBarrelGeometry_->getValidDetIds(DetId::Ecal,EcalBarrel));
461  unsigned size=vec.size();
462  const CaloCellGeometry * geom=0;
463  for(unsigned ic=0; ic<size; ++ic)
464  {
465  unsigned hashedindex=EBDetId(vec[ic]).hashedIndex();
466  geom = EcalBarrelGeometry_->getGeometry(vec[ic]);
467  BaseCrystal xtal(vec[ic]);
468  xtal.setCorners(geom->getCorners(),geom->getPosition());
469  barrelCrystals_[hashedindex]=xtal;
470  }
471 
472  // std::cout << " done " << size << std::endl;
473  // std::cout << " Building the array of crystals (endcap) " ;
474 
475 
476  const std::vector<DetId>& vece(EcalEndcapGeometry_->getValidDetIds(DetId::Ecal,EcalEndcap));
477  size=vece.size();
478  // There are some holes in the hashedIndex for the EE. Hence the array is bigger than the number
479  // of crystals
480  const unsigned nendcap=EEDetId::kSizeForDenseIndexing;
481 
482  endcapCrystals_.resize(nendcap,BaseCrystal());
483  for(unsigned ic=0; ic<size; ++ic)
484  {
485  unsigned hashedindex=EEDetId(vece[ic]).hashedIndex();
486  geom = EcalEndcapGeometry_->getGeometry(vece[ic]);
487  BaseCrystal xtal(vece[ic]);
488  xtal.setCorners(geom->getCorners(),geom->getPosition());
489  endcapCrystals_[hashedindex]=xtal;
490  }
491  // std::cout << " done " << size << std::endl;
492 }
#define LogDebug(id)
size
Write out results.
int hashedIndex() const
get a compact index for arrays
Definition: EBDetId.h:86
void setCorners(const CaloCellGeometry::CornersVec &vec, const GlobalPoint &pos)
Definition: BaseCrystal.cc:14
virtual std::vector< DetId > getNeighbours(const DetId &id, const CaloDirection &dir) const
void buildCrystal(const DetId &id, Crystal &) const
DetId getClosestCell(const GlobalPoint &r) const override
const EcalEndcapGeometry * EcalEndcapGeometry_
Definition: Calorimeter.h:78
virtual const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
int isc() const
Definition: EEDetId.cc:285
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
const EcalPreshowerGeometry * getEcalPreshowerGeometry() const
Definition: Calorimeter.h:55
const CaloSubdetectorTopology * EcalEndcapTopology_
Definition: Calorimeter.h:84
std::vector< NeiVect > endcapNeighbours_
bool borderCrossing(const DetId &, const DetId &) const
int ism() const
get the ECAL/SM id
Definition: EBDetId.h:61
virtual const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const
Get a list of valid detector ids (for the given subdetector)
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
const CaloSubdetectorGeometry * getEcalGeometry(int subdetn) const
Definition: Calorimeter.cc:136
math::XYZVector XYZPoint
U second(std::pair< T, U > const &p)
static const CaloDirection orderedDir[8]
int im() const
get the number of module inside the SM (1-4)
Definition: EBDetId.h:66
int hashedIndex(int ieta, int iphi)
Definition: EcalPyUtils.cc:42
void fill(const std::string &name, float val1, float val2=1., float val3=1.)
Fill an histogram.
Definition: Histos.cc:168
int depth() const
get the tower depth
Definition: HcalDetId.cc:108
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
int ieta() const
get the cell ieta
Definition: HcalDetId.h:56
std::vector< BaseCrystal > endcapCrystals_
static Histos * instance()
Definition: Histos.cc:15
HcalSubdetector
Definition: HcalAssistant.h:31
const EcalBarrelGeometry * EcalBarrelGeometry_
Definition: Calorimeter.h:77
const CaloSubdetectorTopology * getEcalTopology(int subdetn) const
Definition: Calorimeter.cc:145
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
std::vector< NeiVect > barrelNeighbours_
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.cc:98
virtual DetId getClosestCell(const GlobalPoint &r) const
int iphi() const
get the cell iphi
Definition: HcalDetId.cc:103
Definition: DetId.h:18
bool diagonalmove(DetId &cell, const CaloDirection &dir) const
int hashedIndex() const
Definition: EEDetId.h:182
virtual std::vector< DetId > getWindow(const DetId &id, const int &northSouthSize, const int &eastWestSize) const
std::array< DetId, 8 > NeiVect
void getWindow(const DetId &pivot, int s1, int s2, std::vector< DetId > &) const
bool null() const
is this a null id ?
Definition: DetId.h:45
const CaloSubdetectorGeometry * HcalGeometry_
Definition: Calorimeter.h:79
CornersVec const & getCorners() const
Returns the corner points of this cell&#39;s volume.
T eta() const
Definition: PV3DBase.h:76
T perp() const
Magnitude of transverse component.
const CaloSubdetectorTopology * EcalBarrelTopology_
Definition: Calorimeter.h:83
std::vector< BaseCrystal > barrelCrystals_
dbl *** dir
Definition: mlp_gen.cc:35
CaloDirection
Codes the local directions in the cell lattice.
Definition: CaloDirection.h:9
DetId getClosestCell(const GlobalPoint &r) const override
DetId getClosestCell(const XYZPoint &point, bool ecal, bool central) const
void initialize(double bField)
bool simplemove(DetId &cell, const CaloDirection &dir) 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
const NeiVect & getNeighbours(const DetId &det) const
bool move(DetId &cell, const CaloDirection &dir, bool fast=true) const