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