CMS 3D CMS Logo

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