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