Belle II Software  release-08-01-10
TOPFillPatternOffsetAlgorithm.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <top/calibration/TOPFillPatternOffsetAlgorithm.h>
10 #include <top/dbobjects/TOPCalFillPatternOffset.h>
11 #include <string>
12 #include <TROOT.h>
13 #include <cmath>
14 
15 using namespace std;
16 
17 namespace Belle2 {
22  namespace TOP {
23 
24  TOPFillPatternOffsetAlgorithm::TOPFillPatternOffsetAlgorithm():
25  CalibrationAlgorithm("TOPOffsetCollector")
26  {
27  setDescription("Calibration algorithm for fill pattern offset");
28  }
29 
31  {
32  gROOT->SetBatch();
33 
34  // construct file name and open output root file
35 
36  const auto& expRun = getRunList();
37  string expNo = to_string(expRun[0].first);
38  while (expNo.length() < 4) expNo.insert(0, "0");
39  string runNo = to_string(expRun[0].second);
40  while (runNo.length() < 5) runNo.insert(0, "0");
41  string outputFileName = "fillPatternOffset-e" + expNo + "-r" + runNo + ".root";
42  auto* file = TFile::Open(outputFileName.c_str(), "recreate");
43 
44  auto fillPattern = getObjectPtr<TH1F>("fillPattern");
45  if (fillPattern) fillPattern->Write();
46  auto recBuckets = getObjectPtr<TH1F>("recBuckets");
47  if (recBuckets) recBuckets->Write();
48 
49  // object to store the results
50 
51  auto* fillPatternOffset = new TOPCalFillPatternOffset();
52 
53  // find offset
54 
55  if (fillPattern and recBuckets and recBuckets->GetEntries() > m_minEntries) {
56  auto* chi2 = getChi2Histogram(recBuckets.get(), fillPattern.get());
57  int offset = chi2->GetMinimumBin() - 1;
58  double fract = getFraction(recBuckets.get(), fillPattern.get(), offset);
59  fillPatternOffset->set(offset, fract);
60  if (fract < m_minFract) {
61  fillPatternOffset->setUnusable();
62  }
63  }
64 
65  file->Write();
66  file->Close();
67 
68  // save the object in any case (very important!)
69 
70  saveCalibration(fillPatternOffset);
71 
72  return c_OK;
73  }
74 
75 
76  double TOPFillPatternOffsetAlgorithm::Chi2(TH1F* recBuckets, TH1F* fillPattern, int i0)
77  {
78  double chi2 = 0;
79  int RFBuckets = fillPattern->GetNbinsX();
80  auto* a = recBuckets->GetArray();
81  auto* a0 = fillPattern->GetArray();
82  for (int i = 0; i < RFBuckets; i++) {
83  int k = (i + i0) % RFBuckets;
84  chi2 += a[k] * log(m_p * a0[i] + 1 - m_p);
85  }
86  return -2 * chi2;
87  }
88 
89 
90  TH1F* TOPFillPatternOffsetAlgorithm::getChi2Histogram(TH1F* recBuckets, TH1F* fillPattern)
91  {
92  int RFBuckets = fillPattern->GetNbinsX();
93  for (int i = 0; i < RFBuckets; i++) {
94  if (fillPattern->GetBinContent(i + 1) > 0) fillPattern->SetBinContent(i + 1, 1);
95  }
96  auto* h_chi2 = new TH1F("chi2", "#chi^{2} vs. circular shift; circular shift; #chi^{2}", RFBuckets, 0, RFBuckets);
97  for (int i = 0; i < RFBuckets; i++) {
98  h_chi2->SetBinContent(i + 1, Chi2(recBuckets, fillPattern, i));
99  }
100  return h_chi2;
101  }
102 
103 
104  double TOPFillPatternOffsetAlgorithm::getFraction(TH1F* recBuckets, TH1F* fillPattern, int offset)
105  {
106  double n = 0;
107  double n0 = 0;
108  int RFBuckets = fillPattern->GetNbinsX();
109  auto* corrBuckets = new TH1F("corrBuckets", "Offset corrected reconstructed buckets; bucket number",
110  RFBuckets, 0, RFBuckets);
111  auto* a = recBuckets->GetArray();
112  auto* a0 = fillPattern->GetArray();
113  for (int i = 0; i < RFBuckets; i++) {
114  int k = (i + offset) % RFBuckets;
115  corrBuckets->SetBinContent(i + 1, a[k]);
116  if (a0[i] > 0) n += a[k];
117  n0 += a[k];
118  }
119  double fract = n / n0;
120  double err = sqrt(fract * (1 - fract) / n0);
121 
122  auto* h_fract = new TH1F("fractions", "Fractions of matched buckets; ; fraction", 2, 0, 2);
123  h_fract->GetXaxis()->SetBinLabel(1, "not matched");
124  h_fract->GetXaxis()->SetBinLabel(2, "matched");
125  h_fract->GetXaxis()->SetLabelSize(0.06);
126  h_fract->GetXaxis()->SetAlphanumeric();
127  h_fract->SetBinContent(1, 1 - fract);
128  h_fract->SetBinContent(2, fract);
129  h_fract->SetBinError(1, err);
130  h_fract->SetBinError(2, err);
131  h_fract->SetMarkerStyle(24);
132 
133  return fract;
134  }
135 
136 
137  } // end namespace TOP
139 } // end namespace Belle2
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
Class to store the offset of reconstructed fill pattern.
int m_minEntries
minimal number of entries to perform calibration
double Chi2(TH1F *recBuckets, TH1F *fillPattern, int i0)
Returns chi2 = -2 logL of circularly shifted pattern at a give shift i0.
double m_p
signal fraction for PDF definition
virtual EResult calibrate() final
algorithm implementation
double getFraction(TH1F *recBuckets, TH1F *fillPattern, int offset)
Returns fraction of reconstructed buckets matched with filled buckets after accounting for the offset...
double m_minFract
minimal fraction of matched buckets to save calibration
TH1F * getChi2Histogram(TH1F *recBuckets, TH1F *fillPattern)
Returns chi2 values at all possible circular shifts.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.