CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HcalNoiseMonitor.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <fstream>
3 #include <algorithm>
4 
6 
11 
16 
21 
25 
27 
29 {
30  Online_ = ps.getUntrackedParameter<bool>("online",false);
31  mergeRuns_ = ps.getUntrackedParameter<bool>("mergeRuns",false);
32  enableCleanup_ = ps.getUntrackedParameter<bool>("enableCleanup",false);
33  debug_ = ps.getUntrackedParameter<int>("debug",0);
34  prefixME_ = ps.getUntrackedParameter<std::string>("subSystemFolder","Hcal/");
35  if(prefixME_.substr(prefixME_.size()-1,prefixME_.size())!="/")
36  prefixME_.append("/");
37  subdir_ = ps.getUntrackedParameter<std::string>("TaskFolder","NoiseMonitor_Hcal");
38  if(subdir_.size()>0 && subdir_.substr(subdir_.size()-1,subdir_.size())!="/")
39  subdir_.append("/");
40  subdir_=prefixME_+subdir_;
41  AllowedCalibTypes_ = ps.getUntrackedParameter<std::vector<int> > ("AllowedCalibTypes");
42  skipOutOfOrderLS_ = ps.getUntrackedParameter<bool>("skipOutOfOrderLS",false);
43  NLumiBlocks_ = ps.getUntrackedParameter<int>("NLumiBlocks",4000);
44  makeDiagnostics_ = ps.getUntrackedParameter<bool>("makeDiagnostics",false);
45 
46  triggers_=ps.getUntrackedParameter<std::vector<std::string> >("nzsHLTnames");
47  //["HLT_HcalPhiSym","HLT_HcalNoise_8E29]
48  period_=ps.getUntrackedParameter<int>("NoiseeventPeriod",4096); //4096
50  hltresultsLabel_ = ps.getUntrackedParameter<edm::InputTag>("HLTResultsLabel");
51  hbheDigiLabel_ = ps.getUntrackedParameter<edm::InputTag>("hbheDigiLabel");
52  hbheRechitLabel_ = ps.getUntrackedParameter<edm::InputTag>("hbheRechitLabel");
54 
55  mTrianglePeakTS = 4; // for now...
56 
57  mE2E10MinEnergy = ps.getUntrackedParameter<double>("E2E10MinEnergy");
58  mMinE2E10 = ps.getUntrackedParameter<double>("MinE2E10");
59  mMaxE2E10 = ps.getUntrackedParameter<double>("MaxE2E10");
60  mMaxHPDHitCount = ps.getUntrackedParameter<int>("MaxHPDHitCount");
61  mMaxHPDNoOtherHitCount = ps.getUntrackedParameter<int>("MaxHPDNoOtherHitCount");
62  mMaxADCZeros = ps.getUntrackedParameter<int>("MaxADCZeros");
63  mTotalZeroMinEnergy = ps.getUntrackedParameter<double>("TotalZeroMinEnergy");
64  setupDone_ = false;
65 }
66 
68 
70 {
71 }
72 
74 {
75  if(dbe_)
76  {
79  }
80 }
81 
83 {
84  if(debug_ > 1)
85  std::cout <<"HcalNoiseMonitor::beginRun"<< std::endl;
86 
88 
89  if(tevt_ == 0)
90  setup();
91 
92  if(mergeRuns_ == false)
93  reset();
94 
95  return;
96 }
97 
98 
100 {
101  if (setupDone_)
102  return;
103  setupDone_ = true;
105 
106  if(debug_ > 1)
107  std::cout << "<HcalNoiseMonitor::setup> Creating histograms" << std::endl;
108 
109  if(dbe_)
110  {
112 
113  // Fit-based
114  dbe_->setCurrentFolder(subdir_ + "DoubleChi2/");
115 
116  hNominalChi2 = dbe_->book1D("Nominal_fit_chi2", "Nominal fit chi2, total charge > 20 fC", 100, 0, 200);
117  hNominalChi2->setAxisTitle("Nominal fit #chi^{2}", 1);
118 
119  hLinearChi2 = dbe_->book1D("Linear_fit_chi2", "Linear fit chi2, total charge > 20 fC", 100, 0, 200);
120  hLinearChi2->setAxisTitle("Linear fit #chi^{2}", 1);
121 
122  hLinearTestStatistics = dbe_->book1D("Lambda_linear", "#Lambda_{linear}, total charge > 20 fC", 100, -10, 10);
123  hLinearTestStatistics->setAxisTitle("#Lambda_{linear}", 1);
124 
125  hRMS8OverMax = dbe_->book1D("RMS8_over_Max", "RMS8/max, total charge > 20 fC", 100, 0, 2);
126  hRMS8OverMax->setAxisTitle("RMS8/max", 1);
127 
128  hRMS8OverMaxTestStatistics = dbe_->book1D("Lambda_RMS8_over_max", "#Lambda_{RMS8/Max}, total charge > 20 fC",
129  100, -30, 10);
130  hRMS8OverMaxTestStatistics->setAxisTitle("#Lambda_{RMS8/Max}", 1);
131 
132  hLambdaLinearVsTotalCharge = dbe_->book2D("Lambda_linear_vs_total_charge", "#Lambda_{Linear}",
133  50, -5, 5, 25, 0, 500);
134  hLambdaLinearVsTotalCharge->setAxisTitle("#Lambda_{linear}", 1);
135  hLambdaLinearVsTotalCharge->setAxisTitle("Total charge", 2);
136 
137  hLambdaRMS8MaxVsTotalCharge = dbe_->book2D("Lambda_RMS8Max_vs_total_charge", "#Lambda_{RMS8/Max}",
138  50, -15, 5, 25, 0, 500);
139  hLambdaRMS8MaxVsTotalCharge->setAxisTitle("#Lambda_{RMS8/Max}", 1);
140  hLambdaRMS8MaxVsTotalCharge->setAxisTitle("Total charge", 2);
141 
142  hTriangleLeftSlopeVsTS4 = dbe_->book2D("Triangle_fit_left_slope",
143  "Triangle fit left distance vs. TS4", 50, 0, 10, 25, 0, 500);
144  hTriangleLeftSlopeVsTS4->setAxisTitle("Left slope", 1);
145  hTriangleLeftSlopeVsTS4->setAxisTitle("Peak time slice", 2);
146 
147  hTriangleRightSlopeVsTS4 = dbe_->book2D("Triangle_fit_right_slope",
148  "Triangle fit right distance vs. peak time slice", 50, 0, 10, 25, 0, 500);
149  hTriangleRightSlopeVsTS4->setAxisTitle("Left slope", 1);
150  hTriangleRightSlopeVsTS4->setAxisTitle("Peak time slice", 2);
151 
152  SetupEtaPhiHists(hFailLinearEtaPhi, "Fail_linear_Eta_Phi_Map", "");
153  SetupEtaPhiHists(hFailRMSMaxEtaPhi, "Fail_RMS8Max_Eta_Phi_Map", "");
154  SetupEtaPhiHists(hFailTriangleEtaPhi, "Fail_triangle_Eta_Phi_Map", "");
155 
156  // High-level isolation filter
157  dbe_->setCurrentFolder(subdir_ + "IsolationVariable/");
158 
159  SetupEtaPhiHists(hFailIsolationEtaPhi, "Fail_isolation_Eta_Phi_Map", "");
160 
161  // TS4 vs. TS5 variable
162  dbe_->setCurrentFolder(subdir_ + "TS4TS5Variable/");
163 
164  hTS4TS5RelativeDifference = dbe_->book1D("TS4_TS5_relative_difference",
165  "(TS4-TS5)/(TS4+TS5), total charge > 20 fC", 100, -1, 1);
166  hTS4TS5RelativeDifference->setAxisTitle("(TS4 - TS5) / (TS4 + TS5)", 1);
167 
168  hTS4TS5RelativeDifferenceVsCharge = dbe_->book2D("TS4_TS5_relative_difference_charge",
169  "(TS4-TS5)/(TS4+TS5) vs. Charge", 25, 0, 400, 75, -1, 1);
171  hTS4TS5RelativeDifferenceVsCharge->setAxisTitle("(TS4 - TS5) / (TS4 + TS5)", 2);
172 
173  // Noise summary object
174  dbe_->setCurrentFolder(subdir_ + "NoiseMonitoring/");
175 
176  hMaxZeros = dbe_->book1D("Max_Zeros", "Max zeros", 15, -0.5, 14.5);
177 
178  hTotalZeros = dbe_->book1D("Total_Zeros", "Total zeros", 15, -0.5, 14.5);
179 
180  hE2OverE10Digi = dbe_->book1D("E2OverE10Digi", "E2/E10 of the highest digi in an HPD", 100, 0, 2);
181 
182  hE2OverE10Digi5 = dbe_->book1D("E2OverE10Digi5", "E2/E10 of the highest 5 digi in an HPD", 100, 0, 2);
183 
184  hE2OverE10RBX = dbe_->book1D("E2OverE10RBX", "E2/E10 of RBX", 100, 0, 2);
185 
186  hHPDHitCount = dbe_->book1D("HPDHitCount", "HPD hit count (1.5 GeV)", 19, -0.5, 18.5);
187 
188  hRBXHitCount = dbe_->book1D("RBXHitCount", "Number of hits in RBX", 74, -0.5, 73.5);
189 
190  hHcalNoiseCategory = dbe_->book1D("Hcal_noise_category", "Hcal noise category", 10, 0.5, 10.5);
191  hHcalNoiseCategory->setBinLabel(1, "RBX noise", 1);
192  hHcalNoiseCategory->setBinLabel(2, "RBX pedestal flatter", 1);
193  hHcalNoiseCategory->setBinLabel(3, "RBX pedestal sharper", 1);
194  hHcalNoiseCategory->setBinLabel(4, "RBX flash large hit count", 1);
195  hHcalNoiseCategory->setBinLabel(5, "RBX flash small hit count", 1);
196  hHcalNoiseCategory->setBinLabel(7, "HPD discharge", 1);
197  hHcalNoiseCategory->setBinLabel(8, "HPD ion feedback", 1);
198 
199  hBadZeroRBX = dbe_->book1D("BadZeroRBX", "RBX with bad ADC zero counts", 72, 0.5, 72.5);
200  hBadCountHPD = dbe_->book1D("BadCountHPD", "HPD with bad hit counts", 72 * 4, 0.5, 72 * 4 + 0.5);
201  hBadNoOtherCountHPD = dbe_->book1D("BadNoOtherCountHPD", "HPD with bad \"no other\" hit counts", 72 * 4, 0.5, 72 * 4 + 0.5);
202  hBadE2E10RBX = dbe_->book1D("BadE2E10RBX", "RBX with bad E2/E10 value", 72, 0.5, 72.5);
203  }
204 
205  ReadHcalPulse();
206 
207  return;
208 }
209 
210 
212 {
214  iEvent.getByLabel(edm::InputTag(hbheDigiLabel_),hHBHEDigis);
215 
216  edm::ESHandle<HcalDbService> hConditions;
217  iSetup.get<HcalDbRecord>().get(hConditions);
218 
220  iEvent.getByLabel(edm::InputTag(hbheRechitLabel_), hRecHits);
221 
223  iEvent.getByLabel(edm::InputTag(noiseLabel_),hRBXCollection);
224 
225  HcalBaseDQMonitor::analyze(iEvent, iSetup);
226 
227  if(dbe_ == NULL)
228  {
229  if(debug_ > 0)
230  std::cout << "HcalNoiseMonitor::processEvent DQMStore not instantiated!!!"<< std::endl;
231  return;
232  }
233 
234  // loop over digis
235  for(HBHEDigiCollection::const_iterator iter = hHBHEDigis->begin(); iter != hHBHEDigis->end(); iter++)
236  {
237  HcalDetId id = iter->id();
238  const HcalCalibrations &Calibrations = hConditions->getHcalCalibrations(id);
239  const HcalQIECoder *ChannelCoder = hConditions->getHcalCoder(id);
240  const HcalQIEShape *Shape = hConditions->getHcalShape(ChannelCoder);
241  HcalCoderDb Coder(*ChannelCoder, *Shape);
242  CaloSamples Tool;
243  Coder.adc2fC(*iter, Tool);
244 
245  // int ieta = id.ieta();
246  // int iphi = id.iphi();
247  // int depth = id.depth();
248 
249  double Charge[10] = {0};
250  for(int i = 0; i < iter->size(); i++)
251  Charge[i] = Tool[i] - Calibrations.pedestal(iter->sample(i).capid());
252 
253  double TotalCharge = 0;
254  for(int i = 0; i < 10; i++)
255  TotalCharge = TotalCharge + Charge[i];
256 
257  if(TotalCharge > 20)
258  {
259  double NominalChi2 = 10000000;
260  NominalChi2 = PerformNominalFit(Charge);
261 
262  double LinearChi2 = PerformLinearFit(Charge);
263  double RMS8Max = CalculateRMS8Max(Charge);
264  TriangleFitResult TriangleResult = PerformTriangleFit(Charge);
265 
266  double TS4LeftSlope = 100000;
267  double TS4RightSlope = 100000;
268 
269  if(TriangleResult.LeftSlope > 1e-5)
270  TS4LeftSlope = Charge[4] / fabs(TriangleResult.LeftSlope);
271  if(TriangleResult.RightSlope < -1e-5)
272  TS4RightSlope = Charge[4] / fabs(TriangleResult.RightSlope);
273 
274  if(TS4LeftSlope < -1000 || TS4LeftSlope > 1000)
275  TS4LeftSlope = 1000;
276  if(TS4RightSlope < -1000 || TS4RightSlope > 1000)
277  TS4RightSlope = 1000;
278 
279  hNominalChi2->Fill(NominalChi2);
280  hLinearChi2->Fill(LinearChi2);
281  hLinearTestStatistics->Fill(log(LinearChi2) - log(NominalChi2));
282  hRMS8OverMax->Fill(RMS8Max);
283  hRMS8OverMaxTestStatistics->Fill(log(RMS8Max) - log(NominalChi2));
284 
285  hLambdaLinearVsTotalCharge->Fill(log(LinearChi2) - log(NominalChi2), TotalCharge);
286  hLambdaRMS8MaxVsTotalCharge->Fill(log(RMS8Max) - log(NominalChi2), TotalCharge);
287  hTriangleLeftSlopeVsTS4->Fill(TS4LeftSlope, Charge[4]);
288  hTriangleRightSlopeVsTS4->Fill(TS4RightSlope, Charge[4]);
289  }
290 
291  if(Charge[4] + Charge[5] > 1e-5)
292  {
293  hTS4TS5RelativeDifference->Fill((Charge[4] - Charge[5]) / (Charge[4] + Charge[5]));
294  hTS4TS5RelativeDifferenceVsCharge->Fill(TotalCharge, (Charge[4] - Charge[5]) / (Charge[4] + Charge[5]));
295  }
296  }
297 
298  // loop over rechits - noise bits (fit-based, isolation)
299  for(HBHERecHitCollection::const_iterator iter = hRecHits->begin(); iter != hRecHits->end(); iter++)
300  {
301  HcalDetId id = iter->id();
302 
303  int ieta = id.ieta();
304  int iphi = id.iphi();
305  int depth = id.depth();
306 
307  if(iter->flagField(HcalCaloFlagLabels::HBHEFlatNoise) == 1)
308  hFailLinearEtaPhi.depth[depth-1]->Fill(ieta, iphi);
309 
310  if(iter->flagField(HcalCaloFlagLabels::HBHESpikeNoise) == 1)
311  hFailRMSMaxEtaPhi.depth[depth-1]->Fill(ieta, iphi);
312 
313  if(iter->flagField(HcalCaloFlagLabels::HBHETriangleNoise) == 1)
314  hFailTriangleEtaPhi.depth[depth-1]->Fill(ieta, iphi);
315 
316  if(iter->flagField(HcalCaloFlagLabels::HBHEIsolatedNoise) == 1)
317  hFailIsolationEtaPhi.depth[depth-1]->Fill(ieta, iphi);
318  }
319 
320  // Code analagous to Yifei's
321  for(reco::HcalNoiseRBXCollection::const_iterator rbx = hRBXCollection->begin();
322  rbx != hRBXCollection->end(); rbx++)
323  {
324  const reco::HcalNoiseRBX RBX = *rbx;
325 
326  int NumberRBXHits = RBX.numRecHits(1.5);
327  double RBXEnergy = RBX.recHitEnergy(1.5);
328  double RBXE2 = RBX.allChargeHighest2TS();
329  double RBXE10 = RBX.allChargeTotal();
330 
331  std::vector<reco::HcalNoiseHPD> HPDs = RBX.HPDs();
332 
333  int RBXID = RBX.idnumber();
334 
335  if(RBXEnergy > mTotalZeroMinEnergy && RBX.totalZeros() >= mMaxADCZeros)
336  hBadZeroRBX->Fill(RBXID);
337  if(RBXEnergy > mE2E10MinEnergy && RBXE10 > 1e-5 && (RBXE2 / RBXE10 > mMaxE2E10 || RBXE2 / RBXE10 < mMinE2E10))
338  hBadE2E10RBX->Fill(RBXID);
339  for(std::vector<reco::HcalNoiseHPD>::const_iterator hpd = HPDs.begin(); hpd != HPDs.end(); hpd++)
340  {
341  reco::HcalNoiseHPD HPD = *hpd;
342  int HPDHitCount = HPD.numRecHits(1.5);
343  if(HPDHitCount >= mMaxHPDHitCount)
344  hBadCountHPD->Fill(HPD.idnumber());
345  if(HPDHitCount == NumberRBXHits && HPDHitCount >= mMaxHPDNoOtherHitCount)
347  }
348 
349  if(NumberRBXHits == 0 || RBXEnergy <= 10)
350  continue;
351 
352  hRBXHitCount->Fill(NumberRBXHits);
353 
354  hMaxZeros->Fill(RBX.maxZeros());
355  hTotalZeros->Fill(RBX.totalZeros());
356 
357  double HighestHPDEnergy = 0;
358  int HighestHPDHits = 0;
359 
360  for(std::vector<reco::HcalNoiseHPD>::const_iterator hpd = HPDs.begin(); hpd != HPDs.end(); hpd++)
361  {
362  reco::HcalNoiseHPD HPD = *hpd;
363 
364  if(HPD.recHitEnergy(1.5) > HighestHPDEnergy)
365  {
366  HighestHPDEnergy = HPD.recHitEnergy(1.5);
367  HighestHPDHits = HPD.numRecHits(1.5);
368  }
369 
370  if(HPD.numRecHits(5) < 1)
371  continue;
372 
373  if(HPD.bigChargeTotal() > 1e-5)
375  if(HPD.big5ChargeTotal() > 1e-5)
377 
378  hHPDHitCount->Fill(HPD.numRecHits(1.5));
379  }
380 
381  int NoiseCategory = 0;
382  bool IsRBXNoise = false;
383  // bool IsHPDNoise = false;
384  // bool IsHPDIonFeedback = false;
385  // bool IsHPDDischarge = false;
386 
387  if(RBXEnergy > 1e-5 && HighestHPDEnergy / RBXEnergy > 0.98)
388  {
389  // IsHPDNoise = true;
390 
391  if(HighestHPDHits >= 9)
392  {
393  // IsHPDDischarge = true;
394  NoiseCategory = 7;
395  }
396  else
397  {
398  // IsHPDIonFeedback = true;
399  NoiseCategory = 8;
400  }
401  }
402  else
403  {
404  IsRBXNoise = true;
405  NoiseCategory = 1;
406 
407  if(RBXE10 > 1e-5)
408  {
409  if(RBXE2 / RBXE10 < 0.33)
410  NoiseCategory = 2;
411  else if(RBXE2 / RBXE10 < 0.8)
412  NoiseCategory = 3;
413  else if(RBXE2 / RBXE10 > 0.8 && NumberRBXHits > 10)
414  NoiseCategory = 4;
415  else if(RBXE2 / RBXE10 > 0.8 && NumberRBXHits < 10) // [hic]
416  NoiseCategory = 5;
417  }
418  }
419 
420  hHcalNoiseCategory->Fill(NoiseCategory);
421 
422  if(IsRBXNoise == true && RBXE10 > 1e-5)
423  hE2OverE10RBX->Fill(RBXE2 / RBXE10);
424  }
425 
426  return;
427 }
428 
429 double HcalNoiseMonitor::PerformNominalFit(double Charge[10])
430 {
431  //
432  // Performs a fit to the ideal pulse shape. Returns best chi2
433  //
434  // A scan over different timing offset (for the ideal pulse) is carried out,
435  // and for each offset setting a one-parameter fit is performed
436  //
437 
438  int DigiSize = 10;
439 
440  double MinimumChi2 = 100000;
441 
442  double F = 0;
443 
444  double SumF2 = 0;
445  double SumTF = 0;
446  double SumT2 = 0;
447 
448  for(int i = 0; i + 250 < (int)CumulativeIdealPulse.size(); i++)
449  {
451  continue;
452 
453  SumF2 = 0;
454  SumTF = 0;
455  SumT2 = 0;
456 
457  for(int j = 0; j < DigiSize; j++)
458  {
459  // get ideal pulse component for this time slice....
460  F = CumulativeIdealPulse[i+j*25+25] - CumulativeIdealPulse[i+j*25];
461 
462  double Error2 = Charge[j];
463  if(Error2 < 1)
464  Error2 = 1;
465 
466  // ...and increment various summations
467  SumF2 += F * F / Error2;
468  SumTF += F * Charge[j] / Error2;
469  SumT2 += Charge[j] * Charge[j] / Error2;
470  }
471 
472  /* chi2= sum((Charge[j]-aF)^2/|Charge[j]|
473  ( |Charge[j]| = assumed sigma^2 for Charge[j]; a bit wonky for Charge[j]<1 )
474  chi2 = sum(|Charge[j]|) - 2*sum(aF*Charge[j]/|Charge[j]|) +sum( a^2*F^2/|Charge[j]|)
475  chi2 minimimized when d(chi2)/da = 0:
476  a = sum(F*Charge[j])/sum(F^2)
477  ...
478  chi2= sum(|Q[j]|) - sum(Q[j]/|Q[j]|*F)*sum(Q[j]/|Q[j]|*F)/sum(F^2/|Q[j]|), where Q = Charge
479  chi2 = SumT2 - SumTF*SumTF/SumF2
480  */
481 
482  double Chi2 = SumT2 - SumTF * SumTF / SumF2;
483 
484  if(Chi2 < MinimumChi2)
485  MinimumChi2 = Chi2;
486  }
487 
488  // safety protection in case of perfect fit - don't want the log(...) to explode
489  if(MinimumChi2 < 1e-5)
490  MinimumChi2 = 1e-5;
491 
492  return MinimumChi2;
493 }
494 
496 {
497  //
498  // Perform dual nominal fit and returns the chi2
499  //
500  // In this function we do a scan over possible "distance" (number of time slices between two components)
501  // and overall offset for the two components; first coarse, then finer
502  // All the fitting is done in the DualNominalFitSingleTry function
503  //
504 
505  double OverallMinimumChi2 = 1000000;
506 
507  int AvailableDistance[] = {-100, -75, -50, 50, 75, 100};
508 
509  // loop over possible pulse distances between two components
510  for(int k = 0; k < 6; k++)
511  {
512  double SingleMinimumChi2 = 1000000;
513  int MinOffset = 0;
514 
515  // scan coarsely through different offsets and find the minimum
516  for(int i = 0; i + 250 < (int)CumulativeIdealPulse.size(); i += 10)
517  {
518  double Chi2 = DualNominalFitSingleTry(Charge, i, AvailableDistance[k]);
519 
520  if(Chi2 < SingleMinimumChi2)
521  {
522  SingleMinimumChi2 = Chi2;
523  MinOffset = i;
524  }
525  }
526 
527  // around the minimum, scan finer for better a better minimum
528  for(int i = MinOffset - 15; i + 250 < (int)CumulativeIdealPulse.size() && i < MinOffset + 15; i++)
529  {
530  double Chi2 = DualNominalFitSingleTry(Charge, i, AvailableDistance[k]);
531  if(Chi2 < SingleMinimumChi2)
532  SingleMinimumChi2 = Chi2;
533  }
534 
535  // update overall minimum chi2
536  if(SingleMinimumChi2 < OverallMinimumChi2)
537  OverallMinimumChi2 = SingleMinimumChi2;
538  }
539 
540  return OverallMinimumChi2;
541 }
542 
543 double HcalNoiseMonitor::DualNominalFitSingleTry(double Charge[10], int Offset, int Distance)
544 {
545  //
546  // Does a fit to dual signal pulse hypothesis given offset and distance of the two target pulses
547  //
548  // The only parameters to fit here are the two pulse heights of in-time and out-of-time components
549  // since offset is given
550  // The calculation here is based from writing down the Chi2 formula and minimize against the two parameters,
551  // ie., Chi2 = Sum{((T[i] - a1 * F1[i] - a2 * F2[i]) / (Sigma[i]))^2}, where T[i] is the input pulse shape,
552  // and F1[i], F2[i] are the two ideal pulse components
553  //
554 
555  int DigiSize = 10;
556 
557  if(Offset < 0 || Offset + 250 >= (int)CumulativeIdealPulse.size())
558  return 1000000;
559  if(CumulativeIdealPulse[Offset+250] - CumulativeIdealPulse[Offset] < 1e-5)
560  return 1000000;
561 
562  static std::vector<double> F1;
563  static std::vector<double> F2;
564 
565  F1.resize(DigiSize);
566  F2.resize(DigiSize);
567 
568  double SumF1F1 = 0;
569  double SumF1F2 = 0;
570  double SumF2F2 = 0;
571  double SumTF1 = 0;
572  double SumTF2 = 0;
573 
574  double Error = 0;
575 
576  for(int j = 0; j < DigiSize; j++)
577  {
578  // this is the TS value for in-time component - no problem we can do a subtraction directly
579  F1[j] = CumulativeIdealPulse[Offset+j*25+25] - CumulativeIdealPulse[Offset+j*25];
580 
581  // However for the out-of-time component the index might go out-of-bound.
582  // Let's protect against this.
583 
584  int OffsetTemp = Offset + j * 25 + Distance;
585 
586  double C1 = 0; // lower-indexed value in the cumulative pulse shape
587  double C2 = 0; // higher-indexed value in the cumulative pulse shape
588 
589  if(OffsetTemp + 25 < (int)CumulativeIdealPulse.size() && OffsetTemp + 25 >= 0)
590  C1 = CumulativeIdealPulse[OffsetTemp+25];
591  if(OffsetTemp + 25 >= (int)CumulativeIdealPulse.size())
592  C1 = CumulativeIdealPulse[CumulativeIdealPulse.size()-1];
593  if(OffsetTemp < (int)CumulativeIdealPulse.size() && OffsetTemp >= 0)
594  C2 = CumulativeIdealPulse[OffsetTemp];
595  if(OffsetTemp >= (int)CumulativeIdealPulse.size())
596  C2 = CumulativeIdealPulse[CumulativeIdealPulse.size()-1];
597  F2[j] = C1 - C2;
598 
599  Error = Charge[j];
600  if(Error < 1)
601  Error = 1;
602 
603  SumF1F1 += F1[j] * F1[j] / Error;
604  SumF1F2 += F1[j] * F2[j] / Error;
605  SumF2F2 += F2[j] * F2[j] / Error;
606  SumTF1 += F1[j] * Charge[j] / Error;
607  SumTF2 += F2[j] * Charge[j] / Error;
608  }
609 
610  double Height = (SumF1F2 * SumTF2 - SumF2F2 * SumTF1) / (SumF1F2 * SumF1F2 - SumF1F1 * SumF2F2);
611  double Height2 = (SumF1F2 * SumTF1 - SumF1F1 * SumTF2) / (SumF1F2 * SumF1F2 - SumF1F1 * SumF2F2);
612 
613  double Chi2 = 0;
614  for(int j = 0; j < DigiSize; j++)
615  {
616  double Error = Charge[j];
617  if(Error < 1)
618  Error = 1;
619 
620  double Residual = Height * F1[j] + Height2 * F2[j] - Charge[j];
621  Chi2 += Residual * Residual / Error;
622  }
623 
624  // Safety protection in case of zero
625  if(Chi2 < 1e-5)
626  Chi2 = 1e-5;
627 
628  return Chi2;
629 }
630 
631 double HcalNoiseMonitor::PerformLinearFit(double Charge[10])
632 {
633  //
634  // Performs a straight-line fit over all time slices, and returns the chi2 value
635  //
636  // The calculation here is based from writing down the formula for chi2 and minimize
637  // with respect to the parameters in the fit, ie., slope and intercept of the straight line
638  // By doing two differentiation, we will get two equations, and the best parameters are determined by these
639  //
640 
641  int DigiSize = 10;
642 
643  double SumTS2OverTi = 0;
644  double SumTSOverTi = 0;
645  double SumOverTi = 0;
646  double SumTiTS = 0;
647  double SumTi = 0;
648 
649  double Error2 = 0;
650  for(int i = 0; i < DigiSize; i++)
651  {
652  Error2 = Charge[i];
653  if(Charge[i] < 1)
654  Error2 = 1;
655 
656  SumTS2OverTi += 1.* i * i / Error2;
657  SumTSOverTi += 1.* i / Error2;
658  SumOverTi += 1. / Error2;
659  SumTiTS += Charge[i] * i / Error2;
660  SumTi += Charge[i] / Error2;
661  }
662 
663  double CM1 = SumTS2OverTi; // Coefficient in front of slope in equation 1
664  double CM2 = SumTSOverTi; // Coefficient in front of slope in equation 2
665  double CD1 = SumTSOverTi; // Coefficient in front of intercept in equation 1
666  double CD2 = SumOverTi; // Coefficient in front of intercept in equation 2
667  double C1 = SumTiTS; // Constant coefficient in equation 1
668  double C2 = SumTi; // Constant coefficient in equation 2
669 
670  double Slope = (C1 * CD2 - C2 * CD1) / (CM1 * CD2 - CM2 * CD1);
671  double Intercept = (C1 * CM2 - C2 * CM1) / (CD1 * CM2 - CD2 * CM1);
672 
673  // now that the best parameters are found, calculate chi2 from those
674  double Chi2 = 0;
675  for(int i = 0; i < DigiSize; i++)
676  {
677  double Deviation = Slope * i + Intercept - Charge[i];
678  double Error2 = Charge[i];
679  if(Charge[i] < 1)
680  Error2 = 1;
681  Chi2 += Deviation * Deviation / Error2;
682  }
683 
684  // safety protection in case of perfect fit
685  if(Chi2 < 1e-5)
686  Chi2 = 1e-5;
687 
688  return Chi2;
689 }
690 
691 double HcalNoiseMonitor::CalculateRMS8Max(double Charge[10])
692 {
693  //
694  // CalculateRMS8Max
695  //
696  // returns "RMS" divided by the largest charge in the time slices
697  // "RMS" is calculated using all but the two largest time slices.
698  // The "RMS" is not quite the actual RMS (see note below), but the value is only
699  // used for determining max values, and is not quoted as the actual RMS anywhere.
700  //
701 
702  int DigiSize = 10;
703 
704  // Copy Charge vector again, since we are passing references around
705  std::vector<double> TempCharge(Charge, Charge + 10);
706 
707  // Sort TempCharge vector from smallest to largest charge
708  sort(TempCharge.begin(), TempCharge.end());
709 
710  double Total = 0;
711  double Total2 = 0;
712  for(int i = 0; i < DigiSize - 2; i++)
713  {
714  Total = Total + TempCharge[i];
715  Total2 = Total2 + TempCharge[i] * TempCharge[i];
716  }
717 
718  // This isn't quite the RMS (both Total2 and Total*Total need to be
719  // divided by an extra (DigiSize-2) within the sqrt to get the RMS.)
720  // We're only using this value for relative comparisons, though; we
721  // aren't explicitly interpreting it as the RMS. It might be nice
722  // to either change the calculation or rename the variable in the future, though.
723 
724  double RMS = sqrt(Total2 - Total * Total / (DigiSize - 2));
725 
726  double RMS8Max = 99999;
727  if(TempCharge[DigiSize-1] > 1e-5)
728  RMS8Max = RMS / TempCharge[DigiSize-1];
729  if(RMS8Max < 1e-5) // protection against zero
730  RMS8Max = 1e-5;
731 
732  return RMS8Max;
733 }
734 
736 {
737  //
738  // Perform a "triangle fit", and extract the slopes
739  //
740  // Left-hand side and right-hand side are not correlated to each other - do them separately
741  //
742 
744  result.Chi2 = 0;
745  result.LeftSlope = 0;
746  result.RightSlope = 0;
747 
748  int DigiSize = 10;
749 
750  // right side, starting from TS4
751  double MinimumRightChi2 = 1000000;
752  double Numerator = 0;
753  double Denominator = 0;
754 
755  for(int iTS = mTrianglePeakTS + 2; iTS <= DigiSize; iTS++) // the place where first TS center in flat line
756  {
757  // fit a straight line to the triangle part
758  Numerator = 0;
759  Denominator = 0;
760 
761  for(int i = mTrianglePeakTS + 1; i < iTS; i++)
762  {
763  Numerator += (i - mTrianglePeakTS) * (Charge[i] - Charge[mTrianglePeakTS]);
764  Denominator += (i - mTrianglePeakTS) * (i - mTrianglePeakTS);
765  }
766 
767  double BestSlope = Numerator / Denominator;
768  if(BestSlope > 0)
769  BestSlope = 0;
770 
771  // check if the slope is reasonable
772  if(iTS != DigiSize)
773  {
774  if(BestSlope > -1 * Charge[mTrianglePeakTS] / (iTS - mTrianglePeakTS))
775  BestSlope = -1 * Charge[mTrianglePeakTS] / (iTS - mTrianglePeakTS);
776  if(BestSlope < -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS))
777  BestSlope = -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS);
778  }
779  else
780  {
781  if(BestSlope < -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS))
782  BestSlope = -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS);
783  }
784 
785  // calculate partial chi2
786 
787  // The shape I'm fitting is more like a tent than a triangle.
788  // After the end of triangle edge assume a flat line
789 
790  double Chi2 = 0;
791  for(int i = mTrianglePeakTS + 1; i < iTS; i++)
792  Chi2 += (Charge[mTrianglePeakTS] - Charge[i] + (i - mTrianglePeakTS) * BestSlope)
793  * (Charge[mTrianglePeakTS] - Charge[i] + (i - mTrianglePeakTS) * BestSlope);
794  for(int i = iTS; i < DigiSize; i++) // Assumes fit line = 0 for iTS > fit
795  Chi2 += Charge[i] * Charge[i];
796 
797  if(Chi2 < MinimumRightChi2)
798  {
799  MinimumRightChi2 = Chi2;
800  result.RightSlope = BestSlope;
801  }
802  } // end of right-hand side loop
803 
804  // left side
805  double MinimumLeftChi2 = 1000000;
806 
807  for(int iTS = 0; iTS < (int)mTrianglePeakTS; iTS++) // the first time after linear fit ends
808  {
809  // fit a straight line to the triangle part
810  Numerator = 0;
811  Denominator = 0;
812  for(int i = iTS; i < (int)mTrianglePeakTS; i++)
813  {
814  Numerator = Numerator + (i - mTrianglePeakTS) * (Charge[i] - Charge[mTrianglePeakTS]);
815  Denominator = Denominator + (i - mTrianglePeakTS) * (i - mTrianglePeakTS);
816  }
817 
818  double BestSlope = Numerator / Denominator;
819  if(BestSlope < 0)
820  BestSlope = 0;
821 
822  // check slope
823  if(iTS != 0)
824  {
825  if(BestSlope > Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS))
826  BestSlope = Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS);
827  if(BestSlope < Charge[mTrianglePeakTS] / (mTrianglePeakTS + 1 - iTS))
828  BestSlope = Charge[mTrianglePeakTS] / (mTrianglePeakTS + 1 - iTS);
829  }
830  else
831  {
832  if(BestSlope > Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS))
833  BestSlope = Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS);
834  }
835 
836  // calculate minimum chi2
837  double Chi2 = 0;
838  for(int i = 0; i < iTS; i++)
839  Chi2 += Charge[i] * Charge[i];
840  for(int i = iTS; i < (int)mTrianglePeakTS; i++)
841  Chi2 += (Charge[mTrianglePeakTS] - Charge[i] + (i - mTrianglePeakTS) * BestSlope)
842  * (Charge[mTrianglePeakTS] - Charge[i] + (i - mTrianglePeakTS) * BestSlope);
843 
844  if(MinimumLeftChi2 > Chi2)
845  {
846  MinimumLeftChi2 = Chi2;
847  result.LeftSlope = BestSlope;
848  }
849  } // end of left-hand side loop
850 
851  result.Chi2 = MinimumLeftChi2 + MinimumRightChi2;
852 
853  return result;
854 }
855 
857 {
858  std::vector<double> PulseShape;
859 
860  HcalPulseShapes Shapes;
861  HcalPulseShapes::Shape HPDShape = Shapes.hbShape();
862 
863  PulseShape.reserve(350);
864  for(int i = 0; i < 200; i++)
865  PulseShape.push_back(HPDShape.at(i));
866  PulseShape.insert(PulseShape.begin(), 150, 0); // Safety margin of a lot of zeros in the beginning
867 
868  CumulativeIdealPulse.reserve(350);
869  CumulativeIdealPulse.clear();
870  CumulativeIdealPulse.push_back(0);
871  for(unsigned int i = 1; i < PulseShape.size(); i++)
872  CumulativeIdealPulse.push_back(CumulativeIdealPulse[i-1] + PulseShape[i]);
873 }
874 
876 
MonitorElement * hBadCountHPD
MonitorElement * hE2OverE10Digi
T getUntrackedParameter(std::string const &, T const &) const
MonitorElement * hBadNoOtherCountHPD
MonitorElement * hTS4TS5RelativeDifferenceVsCharge
int i
Definition: DBlmapReader.cc:9
double PerformNominalFit(double Charge[10])
MonitorElement * hE2OverE10RBX
edm::InputTag noiseLabel_
float allChargeHighest2TS(unsigned int firstts=4) const
Definition: HcalNoiseRBX.cc:65
int idnumber(void) const
Definition: HcalNoiseHPD.cc:32
MonitorElement * hMaxZeros
virtual void analyze(const edm::Event &e, const edm::EventSetup &c)
MonitorElement * book1D(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1D histogram.
Definition: DQMStore.cc:722
int maxZeros(void) const
Definition: HcalNoiseRBX.cc:90
float at(double time) const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::vector< int > AllowedCalibTypes_
TriangleFitResult PerformTriangleFit(double Charge[10])
MonitorElement * hLambdaRMS8MaxVsTotalCharge
std::vector< T >::const_iterator const_iterator
double CalculateRMS8Max(double Charge[10])
void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
int numRecHits(double threshold=1.5) const
MonitorElement * hHcalNoiseCategory
#define NULL
Definition: scimark2.h:8
double pedestal(int fCapId) const
get pedestal for capid=0..3
MonitorElement * hNominalChi2
EtaPhiHists hFailRMSMaxEtaPhi
void Fill(long long x)
MonitorElement * hTotalZeros
edm::InputTag hbheDigiLabel_
MonitorElement * hLinearChi2
MonitorElement * hLinearTestStatistics
edm::InputTag hltresultsLabel_
int iEvent
Definition: GenABIO.cc:243
std::vector< MonitorElement * > depth
MonitorElement * hBadE2E10RBX
virtual void beginRun(const edm::Run &run, const edm::EventSetup &c)
void removeContents(void)
erase all monitoring elements in current directory (not including subfolders);
Definition: DQMStore.cc:2569
double recHitEnergy(double theshold=1.5) const
Definition: HcalNoiseRBX.cc:99
float allChargeTotal(void) const
Definition: HcalNoiseRBX.cc:57
EtaPhiHists hFailTriangleEtaPhi
float big5ChargeHighest2TS(unsigned int firstts=4) const
Definition: HcalNoiseHPD.cc:81
virtual void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const
Definition: HcalCoderDb.cc:46
T sqrt(T t)
Definition: SSEVec.h:48
int numRecHits(float threshold=1.5) const
MonitorElement * hBadZeroRBX
void beginRun(const edm::Run &run, const edm::EventSetup &c)
tuple result
Definition: query.py:137
MonitorElement * hTriangleRightSlopeVsTS4
float bigChargeHighest2TS(unsigned int firstts=4) const
Definition: HcalNoiseHPD.cc:51
int ieta() const
get the cell ieta
Definition: HcalDetId.h:38
MonitorElement * hRMS8OverMaxTestStatistics
int j
Definition: DBlmapReader.cc:9
MonitorElement * hTS4TS5RelativeDifference
double PerformDualNominalFit(double Charge[10])
float big5ChargeTotal(void) const
Definition: HcalNoiseHPD.cc:72
double DualNominalFitSingleTry(double Charge[10], int Offset, int Distance)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:361
int k[5][pyjets_maxn]
MonitorElement * hRBXHitCount
MonitorElement * hE2OverE10Digi5
int totalZeros(void) const
Definition: HcalNoiseRBX.cc:82
const T & get() const
Definition: EventSetup.h:55
MonitorElement * hRMS8OverMax
MonitorElement * hTriangleLeftSlopeVsTS4
const std::vector< HcalNoiseHPD > HPDs(void) const
Definition: HcalNoiseRBX.cc:33
void SetupEtaPhiHists(EtaPhiHists &hh, std::string Name, std::string Units)
std::vector< double > CumulativeIdealPulse
const Shape & hbShape() const
float recHitEnergy(float threshold=1.5) const
void analyze(edm::Event const &e, edm::EventSetup const &s)
int idnumber(void) const
Definition: HcalNoiseRBX.cc:28
tuple cout
Definition: gather_cfg.py:121
MonitorElement * hHPDHitCount
EtaPhiHists hFailIsolationEtaPhi
std::vector< std::string > triggers_
edm::InputTag hbheRechitLabel_
edm::InputTag rawdataLabel_
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
Definition: Chi2.h:17
MonitorElement * book2D(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Book 2D histogram.
Definition: DQMStore.cc:850
virtual void setup(void)
HcalNoiseMonitor(const edm::ParameterSet &ps)
MonitorElement * hLambdaLinearVsTotalCharge
void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)
float bigChargeTotal(void) const
Definition: HcalNoiseHPD.cc:42
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:434
Definition: Run.h:36
double PerformLinearFit(double Charge[10])
EtaPhiHists hFailLinearEtaPhi
Abstract Class of shape.
Definition: Shape.h:16