CMS 3D CMS Logo

hcalCalib.cc
Go to the documentation of this file.
1 #define hcalCalib_cxx
2 
3 // TSelector-based code for getting the HCAL resp. correction
4 // from physics events. Works for DiJet and IsoTrack calibration.
5 //
6 // Anton Anastassov (Northwestern)
7 // Email: aa@fnal.gov
8 //
9 //
10 
13 
14 #include <TH2.h>
15 #include <TStyle.h>
16 #include "TFile.h"
17 
18 #include <iostream>
19 #include <fstream>
20 
21 #include <sstream>
22 #include <string>
23 
24 #include <map>
25 #include <numeric>
26 #include <algorithm>
27 #include <set>
28 
30 
31 #include "TMatrixF.h"
32 #include "TMatrixD.h"
33 #include "TDecompSVD.h"
34 #include "TDecompQRH.h"
35 
38 
39 using namespace std;
40 
41 UInt_t nEvents;
42 
43 TFile* histoFile;
44 
45 // sanity check histograms
46 TH1F* h1_trkP;
47 TH1F* h1_allTrkP;
48 
50 
51 TH1F* h1_rawSumE;
52 TH1F* h1_rawResp;
53 TH1F* h1_corResp;
59 
62 
63 // histograms based on iEta, iPhi of refPosition forthe cluster (at the moment: hottest tower)
64 // expect range |iEta|<=24 (to do: add flexibility for arbitrary range)
65 TH1F* h1_corRespIEta[48];
66 
67 void hcalCalib::Begin(TTree* /*tree*/) {
68  TString option = GetOption();
69 
70  nEvents = 0;
71 
72  if (APPLY_PHI_SYM_COR_FLAG && !ReadPhiSymCor()) {
73  cout << "\nERROR: Failed to read the phi symmetry corrections." << endl;
74  cout << "Check if the filename is correct. If the corrections are not needed, set the corresponding flag to "
75  "\"false\"\n"
76  << endl;
77 
78  cout << "\nThe program will be terminated\n" << endl;
79 
80  exit(1);
81  }
82 
83  // cellEnergies.reserve(1000000);
84  // cellIds.reserve(1000000);
85  // targetEnergies.reserve(1000000);
86 
87  histoFile = new TFile(HISTO_FILENAME.Data(), "RECREATE");
88 
89  h1_trkP = new TH1F("h1_trkP", "Track momenta; p_{trk} (GeV); Number of tracks", 100, 0, 200);
90  h1_allTrkP = new TH1F("h1_allTrkP", "Track momenta - all tracks; p_{trk} (GeV); Number of tracks", 100, 0, 200);
91 
92  h1_selTrkP_iEta10 = new TH1F(
93  "h1_selTrkP_iEta10", "Track momenta - tracks with |iEta|<10; p_{trk} (GeV); Number of tracks", 100, 0, 200);
94 
95  if (CALIB_TYPE == "ISO_TRACK")
96  h1_rawSumE = new TH1F("h1_rawSumE", "Cluster Energy; E_{cl} (GeV); Number of tracks", 100, 0, 200);
97  else
98  h1_rawSumE = new TH1F("h1_rawSumE", "Cluster Energy; E_{cl} (GeV); Number of tracks", 1000, 0, 2000);
99 
100  h1_rawResp = new TH1F("h1_rawResp", "Uncorrected response: |iEta|<24; E_{had}/p; Number of tracks", 300, 0, 3);
101  h1_corResp = new TH1F("h1_corResp", "Corrected response: |iEta|<24; E_{had}/p; Number of tracks", 300, 0, 3);
102 
104  new TH1F("h1_rawRespBarrel", "Uncorrected response: |iEta|<15; E_{had}/p; Number of tracks", 300, 0, 3);
106  new TH1F("h1_corRespBarrel", "Corrected response: |iEta|<15; E_{had}/p; Number of tracks", 300, 0, 3);
107 
109  new TH1F("h1_rawRespEndcap", "Uncorrected response: 17<|iEta|<24; E_{had}/p; Number of tracks", 300, 0, 3);
111  new TH1F("h1_corRespEndcap", "Corrected response: 17<|iEta|<24; E_{had}/p; Number of tracks", 300, 0, 3);
112 
113  h1_numEventsTwrIEta = new TH1F("h1_numEventsTwrIEta", "h1_numEventsTwrIEta", 80, -40, 40);
114 
115  h2_dHitRefBarrel = new TH2F("h2_dHitRefBarrel",
116  "{#Delta}i{#phi} vs {#Delta}i{#eta} of hit and most energetic "
117  "tower(|i{#eta}|<16);{#Delta}i{#eta}; {#Delta}i{#phi}",
118  10,
119  -5,
120  5,
121  10,
122  -5,
123  5);
124  h2_dHitRefEndcap = new TH2F("h2_dHitRefEndcap",
125  "{#Delta}i{#phi} vs {#Delta}i{#eta} of hit and most energetic tower (16<|i{#eta}|<25) "
126  ";{#Delta}i{#eta}; {#Delta}i{#phi}",
127  10,
128  -5,
129  5,
130  10,
131  -5,
132  5);
133 
134  TString histoName = "isoTrack_";
135 
136  for (Int_t i = 0; i < 48; ++i) {
137  Long_t iEta;
138  if (i < 24)
139  iEta = i - 24;
140  else
141  iEta = i - 23;
142  TString hn = histoName + iEta;
143  h1_corRespIEta[i] = new TH1F(hn, hn, 300, 0, 3.0);
144  }
145 
146 } // end of Begin()
147 
148 //void hcalCalib::SlaveBegin(TTree * /*tree*/) {
149 // TString option = GetOption();
150 //}
151 
152 Bool_t hcalCalib::Process(Long64_t entry) {
153  // fChain->GetTree()->GetEntry(entry);
154  GetEntry(entry);
155 
156  set<UInt_t> uniqueIds; // for testing: check if there are duplicate cells (AA)
157 
158  Bool_t acceptEvent = kTRUE;
159 
160  ++nEvents;
161 
162  if (!(nEvents % 100000))
163  cout << "event: " << nEvents << endl;
164 
165  h1_allTrkP->Fill(targetE);
166 
167  if (targetE < MIN_TARGET_E || targetE > MAX_TARGET_E)
168  return kFALSE;
169  ;
170 
171  // make local copy as the cells may be modified due to phi/depth sum, phi corrections etc
172  vector<TCell> selectCells;
173 
174  if (cells->GetSize() == 0)
175  return kFALSE;
176 
177  if (CALIB_TYPE == "DI_JET" && probeJetEmFrac > 0.999)
178  return kTRUE;
179 
180  for (Int_t i = 0; i < cells->GetSize(); ++i) {
181  TCell* thisCell = (TCell*)cells->At(i);
182 
183  if (HcalDetId(thisCell->id()).subdet() == HcalOuter)
184  continue; // reject HO, make a switch!
185 
186  if (HcalDetId(thisCell->id()).subdet() != HcalBarrel && HcalDetId(thisCell->id()).subdet() != HcalEndcap &&
187  HcalDetId(thisCell->id()).subdet() != HcalForward) {
188  cout << "Unknown or wrong hcal subdetector: " << HcalDetId(thisCell->id()).subdet() << endl;
189  }
190 
191  // Apply phi symmetry corrections if the flag is set
192  if (APPLY_PHI_SYM_COR_FLAG)
193  thisCell->SetE(phiSymCor[thisCell->id()] * thisCell->e());
194 
195  if (thisCell->e() > MIN_CELL_E)
196  selectCells.push_back(*thisCell);
197  }
198 
199  if (selectCells.empty()) {
200  cout << "NO CELLS ABOVE THRESHOLD FOUND FOR TARGET!!!" << endl;
201  }
202 
203  if (SUM_DEPTHS)
204  sumDepths(selectCells);
205  else if (SUM_SMALL_DEPTHS)
206  sumSmallDepths(selectCells); // depth 1,2 in twrs 15,16
207 
208  // most energetic tower (IsoTracks) or centroid of probe jet (DiJets)
209  pair<Int_t, UInt_t> refPos;
210 
211  Int_t dEtaHitRef = 999;
212  Int_t dPhiHitRef = 999;
213 
214  if (CALIB_TYPE == "ISO_TRACK") {
215  Int_t iEtaMaxE; // filled by reference in getIEtaIPhiForHighestE
216  UInt_t iPhiMaxE; //
217 
218  getIEtaIPhiForHighestE(selectCells, iEtaMaxE, iPhiMaxE);
219 
220  dEtaHitRef = iEtaMaxE - iEtaHit;
221  dPhiHitRef = iPhiMaxE - iPhiHit;
222 
223  if (dPhiHitRef < -36)
224  dPhiHitRef += 72;
225  if (dPhiHitRef > 36)
226  dPhiHitRef -= 72;
227 
228  if (iEtaHit * iEtaMaxE < 0) {
229  if (dEtaHitRef < 0)
230  dEtaHitRef += 1;
231  if (dEtaHitRef > 0)
232  dEtaHitRef -= 1;
233  }
234 
235  if (abs(iEtaHit) < 16)
236  h2_dHitRefBarrel->Fill(dEtaHitRef, dPhiHitRef);
237  if (abs(iEtaHit) > 16 && abs(iEtaHit) < 25)
238  h2_dHitRefEndcap->Fill(dEtaHitRef, dPhiHitRef);
239 
240  // --------------------------------------------------
241  // Choice of cluster definition
242  //
243  // fixed size NxN clusters as specified in to config file
244  if (!USE_CONE_CLUSTERING) {
245  if (abs(iEtaMaxE) < 16 && HB_CLUSTER_SIZE == 3)
246  filterCells3x3(selectCells, iEtaMaxE, iPhiMaxE);
247  if (abs(iEtaMaxE) > 15 && HE_CLUSTER_SIZE == 3)
248  filterCells3x3(selectCells, iEtaMaxE, iPhiMaxE);
249 
250  if (abs(iEtaMaxE) < 16 && HB_CLUSTER_SIZE == 5)
251  filterCells5x5(selectCells, iEtaMaxE, iPhiMaxE);
252  if (abs(iEtaMaxE) > 15 && HE_CLUSTER_SIZE == 5)
253  filterCells5x5(selectCells, iEtaMaxE, iPhiMaxE);
254  } else {
255  // calculate distance at hcal surface
256  const GlobalPoint hitPositionHcal(xTrkHcal, yTrkHcal, zTrkHcal);
257  filterCellsInCone(selectCells, hitPositionHcal, MAX_CONE_DIST, theCaloGeometry);
258  }
259 
260  refPos.first = iEtaMaxE;
261  refPos.second = iPhiMaxE;
262 
263  } else if (CALIB_TYPE == "DI_JET") { // Apply selection cuts on DiJet events here
264 
265  if (etVetoJet > MAX_ET_THIRD_JET)
266  acceptEvent = kFALSE;
267 
268  Float_t jetsDPhi = probeJetP4->DeltaPhi(*tagJetP4);
269  if (fabs(jetsDPhi * 180.0 / M_PI) < MIN_DPHI_DIJETS)
270  acceptEvent = kFALSE;
271 
272  if (probeJetEmFrac > MAX_PROBEJET_EMFRAC)
273  acceptEvent = kFALSE;
274  if (fabs(probeJetP4->Eta()) < MIN_PROBEJET_ABSETA)
275  acceptEvent = kFALSE;
276  if (fabs(tagJetP4->Eta()) > MAX_TAGJET_ABSETA)
277  acceptEvent = kFALSE;
278  if (fabs(tagJetP4->Et()) < MIN_TAGJET_ET)
279  acceptEvent = kFALSE;
280 
281  if (acceptEvent) {
282  Int_t iEtaMaxE; // filled by reference in getIEtaIPhiForHighestE
283  UInt_t iPhiMaxE; //
284 
285  getIEtaIPhiForHighestE(selectCells, iEtaMaxE, iPhiMaxE);
286 
287  // The ref position for the jet is not used in the minimization at this time.
288  // It will be needed if we attempt to do matrix inversion: then the question is
289  // which value is better suited: the centroid of the jet or the hottest tower...
290 
291  // refPos.first = iEtaHit;
292  // refPos.second = iPhiHit;
293 
294  refPos.first = iEtaMaxE;
295  refPos.second = iPhiMaxE;
296 
297  if (abs(iEtaMaxE) > 40)
298  acceptEvent = kFALSE; // for testing : set as parameter (AA)
299  }
300  }
301 
302  if (COMBINE_PHI)
303  combinePhi(selectCells);
304 
305  // fill the containers for the minimization prcedures
306  vector<Float_t> energies;
307  vector<UInt_t> ids;
308 
309  for (vector<TCell>::iterator i_it = selectCells.begin(); i_it != selectCells.end(); ++i_it) {
310  // for testing : fill only unique id's
311 
312  if (uniqueIds.insert(i_it->id()).second) {
313  energies.push_back(i_it->e());
314  ids.push_back(i_it->id());
315  }
316  }
317 
318  if (CALIB_TYPE == "ISO_TRACK") {
319  if (accumulate(energies.begin(), energies.end(), 0.0) / targetE < MIN_EOVERP)
320  acceptEvent = kFALSE;
321  if (accumulate(energies.begin(), energies.end(), 0.0) / targetE > MAX_EOVERP)
322  acceptEvent = kFALSE;
323 
324  if (emEnergy > MAX_TRK_EME)
325  acceptEvent = kFALSE;
326 
327  if (abs(dEtaHitRef) > 1 || abs(dPhiHitRef) > 1)
328  acceptEvent = kFALSE;
329 
330  // Have to check if for |iEta|>20 (and neighboring region) the dPhiHitRef
331  // should be relaxed to 2. The neighboring towers have dPhi=2...
332  }
333 
334  h1_rawSumE->Fill(accumulate(energies.begin(), energies.end(), 0.0));
335 
336  // here we fill the information for the minimization procedure
337  if (acceptEvent) {
338  cellEnergies.push_back(energies);
339  cellIds.push_back(ids);
340  targetEnergies.push_back(targetE);
341  refIEtaIPhi.push_back(refPos);
342 
343  if (abs(refPos.first) <= 10)
344  h1_selTrkP_iEta10->Fill(targetE);
345  }
346 
347  // Clean up
348  energies.clear();
349  ids.clear();
350  selectCells.clear();
351 
352  return kTRUE;
353 }
354 
355 //void hcalCalib::SlaveTerminate() {}
356 
358  cout << "\n\nFinished reading the events.\n";
359  cout << "Number of input objects: " << cellIds.size() << endl;
360  cout << "Performing minimization: depending on selected method can take some time...\n\n";
361 
362  for (vector<pair<Int_t, UInt_t> >::iterator it_rp = refIEtaIPhi.begin(); it_rp != refIEtaIPhi.end(); ++it_rp) {
363  Float_t weight = (abs(it_rp->first) < 21) ? 1.0 / 72.0 : 1.0 / 36.0;
364  h1_numEventsTwrIEta->Fill(it_rp->first, weight);
365  }
366 
367  if (CALIB_METHOD == "MATRIX_INV_OF_ETA_AVE") {
368  GetCoefFromMtrxInvOfAve();
369  } else if (CALIB_METHOD == "L3" || CALIB_METHOD == "L3_AND_MTRX_INV") {
370  int eventWeight = 2; // 2 is the default (try at some point 0,1,2,3)
371  MinL3AlgoUniv<UInt_t>* thisL3Algo = new MinL3AlgoUniv<UInt_t>(eventWeight);
372  int numIterations = 10; // default 10
373 
374  solution = thisL3Algo->iterate(cellEnergies, cellIds, targetEnergies, numIterations);
375 
376  // in order to handle the case where sumDepths="false", but the flag to sum depths 1,2 in HB towers 15, 16
377  // is set (sumSmallDepths) we create entries in "solution" to create equal correction here
378  // for each encountered coef in depth one.
379 
380  if (!SUM_DEPTHS && SUM_SMALL_DEPTHS) {
381  vector<UInt_t> idForSummedCells;
382 
383  for (map<UInt_t, Float_t>::iterator m_it = solution.begin(); m_it != solution.end(); ++m_it) {
384  if (HcalDetId(m_it->first).ietaAbs() != 15 && HcalDetId(m_it->first).ietaAbs() != 16)
385  continue;
386  if (HcalDetId(m_it->first).subdet() != HcalBarrel)
387  continue;
388  if (HcalDetId(m_it->first).depth() == 1)
389  idForSummedCells.push_back(HcalDetId(m_it->first));
390  }
391 
392  for (vector<UInt_t>::iterator v_it = idForSummedCells.begin(); v_it != idForSummedCells.end(); ++v_it) {
393  UInt_t addCoefId = HcalDetId(HcalBarrel, HcalDetId(*v_it).ieta(), HcalDetId(*v_it).iphi(), 2);
394  solution[addCoefId] = solution[*v_it];
395  }
396 
397  } // end of special treatment for "sumSmallDepths" mode
398 
399  if (CALIB_METHOD == "L3_AND_MTRX_INV") {
400  GetCoefFromMtrxInvOfAve();
401 
402  // loop over the solution from L3 and multiply by the additional factor from
403  // the matrix inversion. Set coef outside of the valid calibration region =1.
404  for (map<UInt_t, Float_t>::iterator it_s = solution.begin(); it_s != solution.end(); ++it_s) {
405  Int_t iEtaSol = HcalDetId(it_s->first).ieta();
406  if (abs(iEtaSol) < CALIB_ABS_IETA_MIN || abs(iEtaSol) > CALIB_ABS_IETA_MAX)
407  it_s->second = 1.0;
408  else
409  it_s->second *= iEtaCoefMap[iEtaSol];
410  }
411 
412  } // if CALIB_METHOD=="L3_AND_MTRX_INV"
413 
414  } // end of L3 or L3 + mtrx inversion minimization
415 
416  // done getting the constants -> write the formatted file
417  makeTextFile();
418 
419  // fill some histograms
420  Float_t rawResp = 0;
421  Float_t corResp = 0;
422  Int_t maxIEta = 0;
423  Int_t minIEta = 999;
424 
425  for (unsigned int i = 0; i < cellEnergies.size(); ++i) {
426  Int_t iEta;
427  for (unsigned int j = 0; j < (cellEnergies[i]).size(); ++j) {
428  iEta = HcalDetId(cellIds[i][j]).ieta();
429  rawResp += (cellEnergies[i])[j];
430 
431  if (CALIB_METHOD == "L3_AND_MTRX_INV") {
432  corResp += (solution[cellIds[i][j]] * cellEnergies[i][j]);
433  } else if (CALIB_METHOD == "L3") {
434  corResp += (solution[cellIds[i][j]] * (cellEnergies[i][j]));
435  } else if (CALIB_METHOD == "MATRIX_INV_OF_ETA_AVE") {
436  corResp += (iEtaCoefMap[iEta] * cellEnergies[i][j]);
437  }
438 
439  if (maxIEta < abs(iEta))
440  maxIEta = abs(iEta);
441  if (minIEta > abs(iEta))
442  minIEta = abs(iEta);
443  }
444 
445  rawResp /= targetEnergies[i];
446  corResp /= targetEnergies[i];
447 
448  // fill histograms based on iEta on ref point of the cluster (for now: hottest tower)
449  // expect range |iEta|<=24 (to do: add flexibility for arbitrary range)
450 
451  if (CALIB_TYPE == "ISO_TRACK") {
452  Int_t ind = refIEtaIPhi[i].first;
453  (ind < 0) ? (ind += 24) : (ind += 23);
454  if (ind >= 0 && ind < 48) {
455  h1_corRespIEta[ind]->Fill(corResp);
456  }
457 
458  // fill histograms for cases where all towers are in the barrel or endcap
459  if (maxIEta < 25) {
460  h1_rawResp->Fill(rawResp);
461  h1_corResp->Fill(corResp);
462  }
463  if (maxIEta < 15) {
464  h1_rawRespBarrel->Fill(rawResp);
465  h1_corRespBarrel->Fill(corResp);
466  } else if (maxIEta < 25 && minIEta > 16) {
467  h1_rawRespEndcap->Fill(rawResp);
468  h1_corRespEndcap->Fill(corResp);
469  }
470  } // histograms for isotrack calibration
471 
472  else {
473  // put jet plots here
474  }
475 
476  rawResp = 0;
477  corResp = 0;
478  maxIEta = 0;
479  minIEta = 999;
480  }
481 
482  // save the histograms
483  h1_trkP->Write();
484  h1_allTrkP->Write();
485 
486  h1_selTrkP_iEta10->Write();
487 
488  h1_rawSumE->Write();
489  h1_rawResp->Write();
490  h1_corResp->Write();
491  h1_rawRespBarrel->Write();
492  h1_corRespBarrel->Write();
493  h1_rawRespEndcap->Write();
494  h1_corRespEndcap->Write();
495  h1_numEventsTwrIEta->Write();
496  h2_dHitRefBarrel->Write();
497  h2_dHitRefEndcap->Write();
498  for (Int_t i = 0; i < 48; ++i) {
499  h1_corRespIEta[i]->Write();
500  }
501 
502  histoFile->Write();
503  histoFile->Close();
504 
505  cout << "\n Finished calibration.\n " << endl;
506 
507 } // end of Terminate()
508 
509 //**************************************************************************************************************
510 
512  // these maps are keyed by iEta
513  map<Int_t, Float_t> aveTargetE;
514  map<Int_t, Int_t> nEntries; // count hits
515 
516  // iEtaRef iEtaCell, energy
517  map<Int_t, map<Int_t, Float_t> > aveHitE; // add energies in the loop, normalize after that
518 
519  for (unsigned int i = 0; i < cellEnergies.size(); ++i) {
520  Int_t iEtaRef = refIEtaIPhi[i].first;
521  aveTargetE[iEtaRef] += targetEnergies[i];
522  nEntries[iEtaRef]++;
523 
524  // for hybrid method: matrix inv of averages preceeded by L3
525  if (CALIB_METHOD == "L3_AND_MTRX_INV") {
526  for (unsigned int j = 0; j < (cellEnergies[i]).size(); ++j) {
527  aveHitE[iEtaRef][HcalDetId(cellIds[i][j]).ieta()] += (solution[cellIds[i][j]] * cellEnergies[i][j]);
528  }
529  } else if (CALIB_METHOD == "MATRIX_INV_OF_ETA_AVE") {
530  for (unsigned int j = 0; j < (cellEnergies[i]).size(); ++j) {
531  aveHitE[iEtaRef][HcalDetId(cellIds[i][j]).ieta()] += cellEnergies[i][j];
532  }
533  }
534 
535  } // end of loop of entries
536 
537  // scale by number of entries to get the averages
538  Float_t norm = 1.0;
539  for (map<Int_t, Float_t>::iterator m_it = aveTargetE.begin(); m_it != aveTargetE.end(); ++m_it) {
540  Int_t iEta = m_it->first;
541  norm = (nEntries[iEta] > 0) ? 1.0 / (nEntries[iEta]) : 1.0;
542  aveTargetE[iEta] *= norm;
543 
544  map<Int_t, Float_t>::iterator n_it = (aveHitE[iEta]).begin();
545 
546  Float_t sumRawE = 0;
547  for (; n_it != (aveHitE[iEta]).end(); ++n_it) {
548  (n_it->second) *= norm;
549  sumRawE += (n_it->second);
550  }
551 
552  } // end of scaling by number of entries
553 
554  Int_t ONE_SIDE_IETA_RANGE = CALIB_ABS_IETA_MAX - CALIB_ABS_IETA_MIN + 1;
555 
556  // conversion from iEta to index for the linear system
557  // contains elements only in the valid range for *matrix inversion*
558  vector<Int_t> iEtaList;
559 
560  for (Int_t i = -CALIB_ABS_IETA_MAX; i <= CALIB_ABS_IETA_MAX; ++i) {
561  if (abs(i) < CALIB_ABS_IETA_MIN)
562  continue;
563  iEtaList.push_back(i);
564  }
565 
566  TMatrixD A(2 * ONE_SIDE_IETA_RANGE, 2 * ONE_SIDE_IETA_RANGE);
567  TMatrixD b(2 * ONE_SIDE_IETA_RANGE, 1);
568  TMatrixD x(2 * ONE_SIDE_IETA_RANGE, 1);
569 
570  for (Int_t i = 0; i < 2 * ONE_SIDE_IETA_RANGE; ++i) {
571  for (Int_t j = 0; j < 2 * ONE_SIDE_IETA_RANGE; ++j) {
572  A(i, j) = 0.0;
573  }
574  }
575 
576  for (UInt_t i = 0; i < iEtaList.size(); ++i) {
577  b(i, 0) = aveTargetE[iEtaList[i]];
578 
579  map<Int_t, Float_t>::iterator n_it = aveHitE[iEtaList[i]].begin();
580  for (; n_it != aveHitE[iEtaList[i]].end(); ++n_it) {
581  if (fabs(n_it->first) > CALIB_ABS_IETA_MAX || fabs(n_it->first) < CALIB_ABS_IETA_MIN)
582  continue;
583  Int_t j = Int_t(find(iEtaList.begin(), iEtaList.end(), n_it->first) - iEtaList.begin());
584  A(i, j) = n_it->second;
585  }
586  }
587 
588  TMatrixD coef = b;
589  TDecompQRH qrh(A);
590  Bool_t hasSolution = qrh.MultiSolve(coef);
591 
592  if (hasSolution && (CALIB_METHOD == "L3_AND_MTRX_INV" || CALIB_METHOD == "MATRIX_INV_OF_ETA_AVE")) {
593  for (UInt_t i = 0; i < iEtaList.size(); ++i) {
594  iEtaCoefMap[iEtaList[i]] = coef(i, 0);
595  }
596  }
597 }
598 
600  std::ifstream phiSymFile(PHI_SYM_COR_FILENAME.Data());
601 
602  if (!phiSymFile) {
603  cout << "\nERROR: Can not find file with phi symmetry constants \"" << PHI_SYM_COR_FILENAME.Data() << "\"" << endl;
604  return kFALSE;
605  }
606 
607  // assumes the format used in CSA08, first line is a comment
608 
609  Int_t iEta;
610  UInt_t iPhi;
611  UInt_t depth;
612  TString sdName;
613  UInt_t detId;
614 
615  Float_t value;
617 
619 
620  while (getline(phiSymFile, line)) {
621  if (line.empty() || line[0] == '#')
622  continue;
623 
624  std::istringstream linestream(line);
625  linestream >> iEta >> iPhi >> depth >> sdName >> value >> hex >> detId;
626 
627  if (sdName == "HB")
628  sd = HcalBarrel;
629  else if (sdName == "HE")
630  sd = HcalEndcap;
631  else if (sdName == "HO")
632  sd = HcalOuter;
633  else if (sdName == "HF")
634  sd = HcalForward;
635  else {
636  cout << "\nInvalid detector name in phi symmetry constants file: " << sdName.Data() << endl;
637  cout << "Check file and rerun!\n" << endl;
638  return kFALSE;
639  }
640 
641  // check if the data is consistent
642 
643  if (HcalDetId(sd, iEta, iPhi, depth) != HcalDetId(detId)) {
644  cout << "\nInconsistent info in phi symmetry file: subdet, iEta, iPhi, depth do not match rawId!\n" << endl;
645  return kFALSE;
646  }
647  HcalDetId hId(detId);
648  if (!topo_->valid(hId)) {
649  cout << "\nInvalid DetId from: iEta=" << iEta << " iPhi=" << iPhi << " depth=" << depth
650  << " subdet=" << sdName.Data() << " detId=" << detId << endl
651  << endl;
652  return kFALSE;
653  }
654 
655  phiSymCor[HcalDetId(sd, iEta, iPhi, depth)] = value;
656  }
657 
658  return kTRUE;
659 }
660 
662  //{ HcalEmpty=0, HcalBarrel=1, HcalEndcap=2, HcalOuter=3, HcalForward=4, HcalTriggerTower=5, HcalOther=7 };
663 
664  TString sdName[8] = {"EMPTY", "HB", "HE", "HO", "HF", "TRITWR", "UNDEF", "OTHER"};
665 
666  FILE* constFile = fopen(OUTPUT_COR_COEF_FILENAME.Data(), "w+");
667 
668  // header of the constants file
669  fprintf(constFile, "%1s%16s%16s%16s%16s%9s%11s\n", "#", "eta", "phi", "depth", "det", "value", "DetId");
670 
671  // Order loops to produce sequence of constants as for phi symmetry
672 
673  for (Int_t sd = 1; sd <= 4; sd++) {
674  for (Int_t e = 1; e <= 50; e++) {
675  Int_t eta;
676 
677  for (Int_t side = 0; side < 2; side++) {
678  eta = (side == 0) ? -e : e; //ta *= (-1);
679 
680  for (Int_t phi = 1; phi <= 72; phi++) {
681  for (Int_t d = 1; d < 5; d++) {
682  if (!topo_->valid(HcalDetId(HcalSubdetector(sd), eta, phi, d)))
683  continue;
684  HcalDetId id(HcalSubdetector(sd), eta, phi, d);
685  Float_t corrFactor = 1.0;
686 
687  if (abs(eta) >= CALIB_ABS_IETA_MIN && abs(eta) <= CALIB_ABS_IETA_MAX && HcalSubdetector(sd) != HcalOuter) {
688  // if (abs(eta)>=CALIB_ABS_IETA_MIN && abs(eta)<=22 && HcalSubdetector(sd)!=HcalOuter) {
689 
690  // need some care when depths were summed for iEta=16 =>
691  // the coeficients are saved in depth 1 of HB: affects
692  Int_t subdetInd = sd;
693 
694  if (abs(eta) == 16 && HcalSubdetector(sd) == HcalEndcap && SUM_DEPTHS) {
695  subdetInd = 1;
696  }
697 
698  if (CALIB_METHOD == "L3" || CALIB_METHOD == "L3_AND_MTRX_INV") {
699  if (SUM_DEPTHS && COMBINE_PHI)
700  corrFactor = solution[HcalDetId(HcalSubdetector(subdetInd), eta, 1, 1)];
701  else if (SUM_DEPTHS)
702  corrFactor = solution[HcalDetId(HcalSubdetector(subdetInd), eta, phi, 1)];
703  else if (COMBINE_PHI)
704  corrFactor = solution[HcalDetId(HcalSubdetector(sd), eta, 1, d)];
705  else
706  corrFactor = solution[HcalDetId(HcalSubdetector(sd), eta, phi, d)];
707 
708  // Remark: a new case was added (sumSmallDepths) where the first two depths in towers 15,16
709  // are summed and stored in depth 1.
710  // For now we create the correction coef for depth 2 (set equal to depth 1)
711  // after the call to the L3 minimizer so that this case is also handled without modifying the
712  // logic above. Probably it is better to move it here?
713 
714  } // L3
715 
716  else if (CALIB_METHOD == "MATRIX_INV_OF_ETA_AVE") {
717  corrFactor = iEtaCoefMap[eta];
718  }
719 
720  else if (CALIB_METHOD == "ISO_TRK_PHI_SYM") {
721  corrFactor = solution[HcalDetId(HcalSubdetector(sd), eta, phi, d)];
722  }
723 
724  } // if within the calibration range
725 
726  fprintf(constFile, "%17i%16i%16i%16s%9.5f%11X\n", eta, phi, d, sdName[sd].Data(), corrFactor, id.rawId());
727  }
728  }
729  }
730  }
731  }
732 
733  return;
734 }
void filterCellsInCone(std::vector< TCell > &selectCells, const GlobalPoint hitPositionHcal, Float_t maxConeDist, const CaloGeometry *theCaloGeometry)
size
Write out results.
TH1F * h1_corRespBarrel
Definition: hcalCalib.cc:55
TFile * histoFile
Definition: hcalCalib.cc:43
TH1F * h1_corRespIEta[48]
Definition: hcalCalib.cc:65
TH1F * h1_rawRespBarrel
Definition: hcalCalib.cc:54
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:146
void GetCoefFromMtrxInvOfAve()
Definition: hcalCalib.cc:511
void Begin(TTree *tree) override
Definition: hcalCalib.cc:67
TH2F * h2_dHitRefEndcap
Definition: hcalCalib.cc:61
TH2F * h2_dHitRefBarrel
Definition: hcalCalib.cc:60
TH1F * h1_allTrkP
Definition: hcalCalib.cc:47
Definition: weight.py:1
Float_t e()
Definition: TCell.h:31
Definition: TCell.h:15
TH1F * h1_numEventsTwrIEta
Definition: hcalCalib.cc:58
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
TH1F * h1_rawSumE
Definition: hcalCalib.cc:51
U second(std::pair< T, U > const &p)
void combinePhi(std::vector< TCell > &selectCells)
TH1F * h1_selTrkP_iEta10
Definition: hcalCalib.cc:49
int depth() const
get the tower depth
Definition: HcalDetId.h:166
UInt_t id()
Definition: TCell.h:32
int ieta() const
get the cell ieta
Definition: HcalDetId.h:159
void Terminate() override
Definition: hcalCalib.cc:357
HcalSubdetector
Definition: HcalAssistant.h:31
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define end
Definition: vmac.h:39
void SetE(Float_t e)
Definition: TCell.h:34
void filterCells3x3(std::vector< TCell > &selectCells, Int_t iEta, UInt_t iPhi)
#define M_PI
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.h:154
TH1F * h1_corRespEndcap
Definition: hcalCalib.cc:57
TH1F * h1_rawResp
Definition: hcalCalib.cc:52
int iphi() const
get the cell iphi
Definition: HcalDetId.h:161
TH1F * h1_rawRespEndcap
Definition: hcalCalib.cc:56
TH1F * h1_trkP
Definition: hcalCalib.cc:46
TH1F * h1_corResp
Definition: hcalCalib.cc:53
double sd
double b
Definition: hdecay.h:120
void sumSmallDepths(std::vector< TCell > &selectCells)
void makeTextFile()
Definition: hcalCalib.cc:661
Bool_t Process(Long64_t entry) override
Definition: hcalCalib.cc:152
Bool_t ReadPhiSymCor()
Definition: hcalCalib.cc:599
#define begin
Definition: vmac.h:32
void filterCells5x5(std::vector< TCell > &selectCells, Int_t iEta, UInt_t iPhi)
IDmap iterate(const std::vector< std::vector< float > > &eventMatrix, const std::vector< std::vector< IDdet > > &idMatrix, const std::vector< float > &energyVector, const int &nIter, const bool &normalizeFlag=false)
Definition: MinL3AlgoUniv.h:81
void sumDepths(std::vector< TCell > &selectCells)
UInt_t nEvents
Definition: hcalCalib.cc:41
void getIEtaIPhiForHighestE(std::vector< TCell > &selectCells, Int_t &iEta, UInt_t &iPhi)