CMS 3D CMS Logo

hcalCalibUtils.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <fstream>
3 #include <algorithm>
4 #include <numeric>
5 
6 #include "TString.h"
9 
10 //#include "Calibration/HcalCalibAlgos/plugins/CommonUsefulStuff.h"
14 
15 void sumDepths(std::vector<TCell>& selectCells) {
16  // Assignes teh sum of the energy in cells with the same iEta, iPhi to the cell with depth=1.
17  // All cells with depth>1 are removed form the container. If
18  // the cell at depth=1 is not present: create it and follow the procedure.
19 
20  if (selectCells.empty())
21  return;
22 
23  std::vector<TCell> selectCellsDepth1;
24  std::vector<TCell> selectCellsHighDepth;
25 
26  //
27  // NB: Here we add depth 3 for iEta==16 in *HE* to the value in the barrel
28  // this approach is reflected in several of the following loops: make sure
29  // to check when making changes.
30  //
31  // In some documents it is described as having depth 1, the mapping in CMSSW uses depth 3.
32 
33  for (std::vector<TCell>::iterator i_it = selectCells.begin(); i_it != selectCells.end(); ++i_it) {
34  if (HcalDetId(i_it->id()).depth() == 1) {
35  selectCellsDepth1.push_back(*i_it);
36  } else {
37  selectCellsHighDepth.push_back(*i_it);
38  }
39  }
40 
41  // case where depth 1 has zero energy, but higher depths with same (iEta, iPhi) have energy.
42  // For iEta<15 there is one depth -> selectCellsHighDepth is empty and we do not get in the loop.
43  for (std::vector<TCell>::iterator i_it2 = selectCellsHighDepth.begin(); i_it2 != selectCellsHighDepth.end();
44  ++i_it2) {
45  // protect against corrupt data
46  if (HcalDetId(i_it2->id()).ietaAbs() < 15 && HcalDetId(i_it2->id()).depth() > 1) {
47  edm::LogWarning("HcalCalib") << "ERROR!!! there are no HB cells with depth>1 for iEta<15!\n"
48  << "Check the input data...\nHCalDetId: " << HcalDetId(i_it2->id());
49  return;
50  }
51 
52  bool foundDepthOne = false;
53  for (std::vector<TCell>::iterator i_it = selectCellsDepth1.begin(); i_it != selectCellsDepth1.end(); ++i_it) {
54  if (HcalDetId(i_it->id()).ieta() == HcalDetId(i_it2->id()).ieta() &&
55  HcalDetId(i_it->id()).iphi() == HcalDetId(i_it2->id()).iphi())
56  foundDepthOne = true;
57  continue;
58  }
59  if (!foundDepthOne) { // create entry for depth 1 with 0 energy
60 
61  UInt_t newId;
62  if (abs(HcalDetId(i_it2->id()).ieta()) == 16)
63  newId = HcalDetId(HcalBarrel, HcalDetId(i_it2->id()).ieta(), HcalDetId(i_it2->id()).iphi(), 1);
64  else
65  newId =
66  HcalDetId(HcalDetId(i_it2->id()).subdet(), HcalDetId(i_it2->id()).ieta(), HcalDetId(i_it2->id()).iphi(), 1);
67 
68  selectCellsDepth1.push_back(TCell(newId, 0.0));
69  }
70  }
71 
72  for (std::vector<TCell>::iterator i_it = selectCellsDepth1.begin(); i_it != selectCellsDepth1.end(); ++i_it) {
73  for (std::vector<TCell>::iterator i_it2 = selectCellsHighDepth.begin(); i_it2 != selectCellsHighDepth.end();
74  ++i_it2) {
75  if (HcalDetId(i_it->id()).ieta() == HcalDetId(i_it2->id()).ieta() &&
76  HcalDetId(i_it->id()).iphi() == HcalDetId(i_it2->id()).iphi()) {
77  i_it->SetE(i_it->e() + i_it2->e());
78  i_it2->SetE(0.0); // paranoid, aren't we...
79  }
80  }
81  }
82 
83  // replace the original vectors with the new ones
84  selectCells = selectCellsDepth1;
85 
86  return;
87 }
88 
89 void combinePhi(std::vector<TCell>& selectCells) {
90  // Map: NxN -> N cluster
91  // Comine the targetE of cells with the same iEta
92 
93  if (selectCells.empty())
94  return;
95 
96  // new container for the TCells
97  // dummy cell id created with iEta; iPhi=1; depth
98  // if combinePhi() is run after combining depths, depth=1
99  std::vector<TCell> combinedCells;
100 
101  std::map<UInt_t, std::vector<Float_t> > etaSliceE; // keyed by id of cell with iEta and **iPhi=1**
102 
103  // map the cells to the eta ring
104  std::vector<TCell>::iterator i_it = selectCells.begin();
105  for (; i_it != selectCells.end(); ++i_it) {
106  DetId id = HcalDetId(i_it->id());
107  UInt_t thisKey = HcalDetId(HcalDetId(id).subdet(), HcalDetId(id).ieta(), 1, HcalDetId(id).depth());
108  etaSliceE[thisKey].push_back(i_it->e());
109  }
110 
111  std::map<UInt_t, std::vector<Float_t> >::iterator m_it = etaSliceE.begin();
112  for (; m_it != etaSliceE.end(); ++m_it) {
113  combinedCells.push_back(TCell(m_it->first, accumulate(m_it->second.begin(), m_it->second.end(), 0.0)));
114  }
115 
116  // replace the original TCell vector with the new one
117  selectCells = combinedCells;
118 }
119 
120 void combinePhi(std::vector<TCell>& selectCells, std::vector<TCell>& combinedCells) {
121  // Map: NxN -> N cluster
122  // Comine the targetE of cells with the same iEta
123 
124  if (selectCells.empty())
125  return;
126 
127  std::map<UInt_t, std::vector<Float_t> > etaSliceE; // keyed by id of cell with iEta and **iPhi=1**
128 
129  // map the cells to the eta ring
130  std::vector<TCell>::iterator i_it = selectCells.begin();
131  for (; i_it != selectCells.end(); ++i_it) {
132  DetId id = HcalDetId(i_it->id());
133  UInt_t thisKey = HcalDetId(HcalDetId(id).subdet(), HcalDetId(id).ieta(), 1, HcalDetId(id).depth());
134  etaSliceE[thisKey].push_back(i_it->e());
135  }
136 
137  std::map<UInt_t, std::vector<Float_t> >::iterator m_it = etaSliceE.begin();
138  for (; m_it != etaSliceE.end(); ++m_it) {
139  combinedCells.push_back(TCell(m_it->first, accumulate(m_it->second.begin(), m_it->second.end(), 0.0)));
140  }
141 }
142 
143 void getIEtaIPhiForHighestE(std::vector<TCell>& selectCells, Int_t& iEtaMostE, UInt_t& iPhiMostE) {
144  std::vector<TCell> summedDepthsCells = selectCells;
145 
146  sumDepths(summedDepthsCells);
147  std::vector<TCell>::iterator highCell = summedDepthsCells.begin();
148 
149  // sum depths locally to get highest energy tower
150 
151  Float_t highE = -999;
152 
153  for (std::vector<TCell>::iterator it = summedDepthsCells.begin(); it != summedDepthsCells.end(); ++it) {
154  if (highE < it->e()) {
155  highCell = it;
156  highE = it->e();
157  }
158  }
159 
160  iEtaMostE = HcalDetId(highCell->id()).ieta();
161  iPhiMostE = HcalDetId(highCell->id()).iphi();
162 
163  return;
164 }
165 
166 //
167 // Remove RecHits outside the 3x3 cluster and replace the vector that will
168 // be used in the minimization. Acts on "event" level.
169 // This can not be done for iEta>20 due to segmentation => in principle the result should be restricted
170 // to iEta<20. Attempted to minimize affect at the boundary without a sharp jump.
171 
172 void filterCells3x3(std::vector<TCell>& selectCells, Int_t iEtaMaxE, UInt_t iPhiMaxE) {
173  std::vector<TCell> filteredCells;
174 
175  Int_t dEta, dPhi;
176 
177  for (std::vector<TCell>::iterator it = selectCells.begin(); it != selectCells.end(); ++it) {
178  Bool_t passDEta = false;
179  Bool_t passDPhi = false;
180 
181  dEta = HcalDetId(it->id()).ieta() - iEtaMaxE;
182  dPhi = HcalDetId(it->id()).iphi() - iPhiMaxE;
183 
184  if (dPhi > 36)
185  dPhi -= 72;
186  if (dPhi < -36)
187  dPhi += 72;
188 
189  if (abs(dEta) <= 1 || (iEtaMaxE * HcalDetId(it->id()).ieta() == -1))
190  passDEta = true;
191 
192  if (abs(iEtaMaxE) <= 20) {
193  if (abs(HcalDetId(it->id()).ieta()) <= 20) {
194  if (abs(dPhi) <= 1)
195  passDPhi = true;
196  } else {
197  // iPhi is labelled by odd numbers
198  if (iPhiMaxE % 2 == 0) {
199  if (abs(dPhi) <= 1)
200  passDPhi = true;
201  } else {
202  if (dPhi == -2 || dPhi == 0)
203  passDPhi = true;
204  }
205  }
206 
207  } // if hottest cell with iEta<=20
208 
209  else {
210  if (abs(HcalDetId(it->id()).ieta()) <= 20) {
211  if (abs(dPhi) <= 1 || dPhi == 2)
212  passDPhi = true;
213  } else {
214  if (abs(dPhi) <= 2)
215  passDPhi = true;
216  }
217  } // if hottest cell with iEta>20
218 
219  if (passDEta && passDPhi)
220  filteredCells.push_back(*it);
221  }
222 
223  selectCells = filteredCells;
224 
225  return;
226 }
227 
228 //
229 // Remove RecHits outside the 5x5 cluster and replace the vector that will
230 // be used in the minimization. Acts on "event" level
231 // In principle the ntuple should be produced with 5x5 already precelected
232 //
233 // Size for iEta>20 is 3x3, but the segmentation changes by x2 in phi.
234 // There is some bias in the selection of towers near the boundary
235 
236 void filterCells5x5(std::vector<TCell>& selectCells, Int_t iEtaMaxE, UInt_t iPhiMaxE) {
237  std::vector<TCell> filteredCells;
238 
239  Int_t dEta, dPhi;
240 
241  for (std::vector<TCell>::iterator it = selectCells.begin(); it != selectCells.end(); ++it) {
242  dEta = HcalDetId(it->id()).ieta() - iEtaMaxE;
243  dPhi = HcalDetId(it->id()).iphi() - iPhiMaxE;
244 
245  if (dPhi > 36)
246  dPhi -= 72;
247  if (dPhi < -36)
248  dPhi += 72;
249 
250  bool passDPhi = (abs(dPhi) < 3);
251 
252  bool passDEta = (abs(dEta) < 3 || (iEtaMaxE * HcalDetId(it->id()).ieta() == -2));
253  // includes +/- eta boundary
254 
255  if (passDPhi && passDEta)
256  filteredCells.push_back(*it);
257  }
258 
259  selectCells = filteredCells;
260 
261  return;
262 }
263 
264 // this is for the problematic layer near the HB/HE boundary
265 // sum depths 1,2 in towers 15,16
266 
267 void sumSmallDepths(std::vector<TCell>& selectCells) {
268  if (selectCells.empty())
269  return;
270 
271  std::vector<TCell> newCells; // holds unaffected cells to which the modified ones are added
272  std::vector<TCell> manipulatedCells; // the ones that are combined
273 
274  for (std::vector<TCell>::iterator i_it = selectCells.begin(); i_it != selectCells.end(); ++i_it) {
275  if ((HcalDetId(i_it->id()).ietaAbs() == 15 && HcalDetId(i_it->id()).depth() <= 2) ||
276  (HcalDetId(i_it->id()).ietaAbs() == 16 && HcalDetId(i_it->id()).depth() <= 2)) {
277  manipulatedCells.push_back(*i_it);
278  } else {
279  newCells.push_back(*i_it);
280  }
281  }
282 
283  // if the list is empty there is nothing to manipulate
284  // leave the original vector unchanged
285 
286  if (manipulatedCells.empty()) {
287  newCells.clear();
288  return;
289  }
290 
291  // See what cells are needed to hold the combined information:
292  // Make holders for depth=1 for each (iEta,iPhi)
293  // if a cell with these values is present in "manupulatedCells"
294  std::vector<UInt_t> dummyIds; // to keep track of kreated cells
295  std::vector<TCell> createdCells; // cells that need to be added or they exists;
296 
297  for (std::vector<TCell>::iterator i_it = manipulatedCells.begin(); i_it != manipulatedCells.end(); ++i_it) {
298  UInt_t dummyId =
299  HcalDetId(HcalDetId(i_it->id()).subdet(), HcalDetId(i_it->id()).ieta(), HcalDetId(i_it->id()).iphi(), 1);
300  if (find(dummyIds.begin(), dummyIds.end(), dummyId) == dummyIds.end()) {
301  dummyIds.push_back(dummyId);
302  createdCells.push_back(TCell(dummyId, 0.0));
303  }
304  }
305 
306  for (std::vector<TCell>::iterator i_it = createdCells.begin(); i_it != createdCells.end(); ++i_it) {
307  for (std::vector<TCell>::iterator i_it2 = manipulatedCells.begin(); i_it2 != manipulatedCells.end(); ++i_it2) {
308  if (HcalDetId(i_it->id()).ieta() == HcalDetId(i_it2->id()).ieta() &&
309  HcalDetId(i_it->id()).iphi() == HcalDetId(i_it2->id()).iphi() && HcalDetId(i_it2->id()).depth() <= 2) {
310  i_it->SetE(i_it->e() + i_it2->e());
311  }
312  }
313  }
314 
315  for (std::vector<TCell>::iterator i_it = createdCells.begin(); i_it != createdCells.end(); ++i_it) {
316  newCells.push_back(*i_it);
317  }
318 
319  // replace the original vectors with the new ones
320  selectCells = newCells;
321 
322  return;
323 }
324 
325 void filterCellsInCone(std::vector<TCell>& selectCells,
326  const GlobalPoint hitPositionHcal,
327  Float_t maxConeDist,
328  const CaloGeometry* theCaloGeometry) {
329  std::vector<TCell> filteredCells;
330 
331  for (std::vector<TCell>::iterator it = selectCells.begin(); it != selectCells.end(); ++it) {
332  GlobalPoint recHitPoint;
333  DetId id = it->id();
334  if (id.det() == DetId::Hcal) {
335  recHitPoint = (static_cast<const HcalGeometry*>(theCaloGeometry->getSubdetectorGeometry(id)))->getPosition(id);
336  } else {
337  recHitPoint = GlobalPoint(theCaloGeometry->getPosition(id));
338  }
339 
340  if (getDistInPlaneSimple(hitPositionHcal, recHitPoint) <= maxConeDist)
341  filteredCells.push_back(*it);
342  }
343 
344  selectCells = filteredCells;
345 
346  return;
347 }
348 
349 // From Jim H. => keep till the code is included centrally
350 /*
351 double getDistInPlaneSimple(const GlobalPoint caloPoint, const GlobalPoint rechitPoint) {
352 
353  // Simplified version of getDistInPlane
354  // Assume track direction is origin -> point of hcal intersection
355 
356  const GlobalVector caloIntersectVector(caloPoint.x(),
357  caloPoint.y(),
358  caloPoint.z());
359 
360  const GlobalVector caloIntersectUnitVector = caloIntersectVector.unit();
361 
362  const GlobalVector rechitVector(rechitPoint.x(),
363  rechitPoint.y(),
364  rechitPoint.z());
365 
366  const GlobalVector rechitUnitVector = rechitVector.unit();
367 
368  double dotprod = caloIntersectUnitVector.dot(rechitUnitVector);
369  double rechitdist = caloIntersectVector.mag()/dotprod;
370 
371 
372  const GlobalVector effectiveRechitVector = rechitdist*rechitUnitVector;
373  const GlobalPoint effectiveRechitPoint(effectiveRechitVector.x(),
374  effectiveRechitVector.y(),
375  effectiveRechitVector.z());
376 
377 
378  GlobalVector distance_vector = effectiveRechitPoint-caloPoint;
379 
380  if (dotprod > 0.)
381  {
382  return distance_vector.mag();
383  }
384  else
385  {
386  return 999999.;
387 
388  }
389 
390 
391 }
392 */
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
void filterCells5x5(std::vector< TCell > &selectCells, Int_t iEtaMaxE, UInt_t iPhiMaxE)
Definition: TCell.h:15
void sumDepths(std::vector< TCell > &selectCells)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
void getIEtaIPhiForHighestE(std::vector< TCell > &selectCells, Int_t &iEtaMostE, UInt_t &iPhiMostE)
ALPAKA_FN_ACC ALPAKA_FN_INLINE uint32_t ietaAbs(uint32_t id)
GlobalPoint getPosition(const DetId &id) const
Get the position of a given detector id.
Definition: CaloGeometry.cc:50
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Definition: DetId.h:17
void combinePhi(std::vector< TCell > &selectCells)
void filterCellsInCone(std::vector< TCell > &selectCells, const GlobalPoint hitPositionHcal, Float_t maxConeDist, const CaloGeometry *theCaloGeometry)
void sumSmallDepths(std::vector< TCell > &selectCells)
double getDistInPlaneSimple(const GlobalPoint caloPoint, const GlobalPoint rechitPoint)
Definition: ConeDefinition.h:9
void filterCells3x3(std::vector< TCell > &selectCells, Int_t iEtaMaxE, UInt_t iPhiMaxE)
Log< level::Warning, false > LogWarning
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34