CMS 3D CMS Logo

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