Belle II Software  release-05-02-19
SVD3SampleELSTimeCalibrationAlgorithm.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2017 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Luigi Corona, Giulia Casarosa *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <svd/calibration/SVD3SampleELSTimeCalibrationAlgorithm.h>
11 
12 #include <svd/dbobjects/SVDCoGCalibrationFunction.h>
13 #include <svd/calibration/SVD3SampleELSTimeCalibrations.h>
14 
15 #include <TF1.h>
16 #include <TProfile.h>
17 #include <TH2F.h>
18 #include <framework/logging/Logger.h>
19 #include <iostream>
20 #include <TString.h>
21 #include <TFitResult.h>
22 
23 using namespace std;
24 using namespace Belle2;
25 
26 SVD3SampleELSTimeCalibrationAlgorithm::SVD3SampleELSTimeCalibrationAlgorithm(const std::string& str) :
27  CalibrationAlgorithm("SVDTimeCalibrationCollector")
28 {
29  setDescription("SVD3SampleELSTimeCalibration calibration algorithm");
30  m_id = str;
31 }
32 
34 {
35 
36  gROOT->SetBatch(true);
37 
38  int ladderOfLayer[4] = {7, 10, 12, 16};
39  int sensorOnLayer[4] = {2, 3, 4, 5};
40 
41  auto timeCal = new Belle2::SVDCoGCalibrationFunction();
42  auto payload = new Belle2::SVD3SampleELSTimeCalibrations::t_payload(*timeCal, m_id);
43 
44  std::unique_ptr<TF1> pol1pole(new TF1("pol1pole", "[0] + [1]*x + [2]/(x - [3])", -60,
45  0)); // In the local study, Y. Uematsu tuned the range to (-21.5,0). Original value is (-10,80).
46  pol1pole->SetParameter(1, 0.6);
47  pol1pole->SetParameter(2, -150);
48  pol1pole->SetParLimits(1, 0, 1);
49  pol1pole->SetParLimits(2, -300, 0);
50 
51  FileStat_t info;
52  int cal_rev = 1;
53  while (gSystem->GetPathInfo(Form("algorithm_3SampleELS_output_rev_%d.root", cal_rev), info) == 0)
54  cal_rev++;
55  std::unique_ptr<TFile> f(new TFile(Form("algorithm_3SampleELS_output_rev_%d.root", cal_rev), "RECREATE"));
56 
57  auto m_tree = new TTree(Form("rev_%d", cal_rev), "RECREATE");
58  int layer_num, ladder_num, sensor_num, view, ndf;
59  float a, b, c, d, a_err, b_err, c_err, d_err, chi2, p;
60  m_tree->Branch("layer", &layer_num, "layer/I");
61  m_tree->Branch("ladder", &ladder_num, "ladder/I");
62  m_tree->Branch("sensor", &sensor_num, "sensor/I");
63  m_tree->Branch("isU", &view, "isU/I");
64  m_tree->Branch("a", &a, "a/F");
65  m_tree->Branch("b", &b, "b/F");
66  m_tree->Branch("c", &c, "c/F");
67  m_tree->Branch("d", &d, "d/F");
68  m_tree->Branch("a_err", &a_err, "a_err/F");
69  m_tree->Branch("b_err", &b_err, "b_err/F");
70  m_tree->Branch("c_err", &c_err, "c_err/F");
71  m_tree->Branch("d_err", &d_err, "d_err/F");
72  m_tree->Branch("chi2", &chi2, "chi2/F");
73  m_tree->Branch("ndf", &ndf, "ndf/I");
74  m_tree->Branch("p", &p, "p/F");
75 
76  for (int layer = 0; layer < 4; layer++) {
77  layer_num = layer + 3;
78  for (int ladder = 0; ladder < (int)ladderOfLayer[layer]; ladder++) {
79  ladder_num = ladder + 1;
80  for (int sensor = 0; sensor < (int)sensorOnLayer[layer]; sensor++) {
81  sensor_num = sensor + 1;
82  for (view = 1; view > -1; view--) {
83  char side = 'U';
84  if (view == 0)
85  side = 'V';
86  auto hEventT0vsELS = getObjectPtr<TH2F>(Form("eventT0vsCoG__L%dL%dS%d%c", layer_num, ladder_num, sensor_num, side));
87  auto hEventT0 = getObjectPtr<TH1F>(Form("eventT0__L%dL%dS%d%c", layer_num, ladder_num, sensor_num, side));
88  auto hEventT0nosync = getObjectPtr<TH1F>(Form("eventT0nosync__L%dL%dS%d%c", layer_num, ladder_num, sensor_num, side));
89  B2INFO("Histogram: " << hEventT0vsELS->GetName() <<
90  " Entries (n. clusters): " << hEventT0vsELS->GetEntries());
91  if (layer_num == 3 && hEventT0vsELS->GetEntries() < m_minEntries) {
92  B2INFO("Histogram: " << hEventT0vsELS->GetName() <<
93  " Entries (n. clusters): " << hEventT0vsELS->GetEntries() <<
94  " Entries required: " << m_minEntries);
95  B2WARNING("Not enough data, adding one run to the collector");
96  f->Close();
97  gSystem->Unlink(Form("algorithm_3SampleELS_output_rev_%d.root", cal_rev));
98  return c_NotEnoughData;
99  }
100  for (int i = 1; i <= hEventT0vsELS->GetNbinsX(); i++) {
101  for (int j = 1; j <= hEventT0vsELS->GetNbinsY(); j++) {
102  if (hEventT0vsELS->GetBinContent(i, j) < max(2, int(hEventT0vsELS->GetEntries() * 0.001))) {
103  hEventT0vsELS->SetBinContent(i, j, 0);
104  }
105  }
106  }
107  TProfile* pfx = hEventT0vsELS->ProfileX();
108  std::string name = "pfx_" + std::string(hEventT0vsELS->GetName());
109  pfx->SetName(name.c_str());
110  // Remove non-liniarity from the fit by fixing the pole position
111  pol1pole->FixParameter(3, 7);
112  pfx->Fit("pol1pole", "QMRS");
113  pol1pole->SetParLimits(3, 0, 15);
114  TFitResultPtr tfr = pfx->Fit("pol1pole", "QMRS");
115  // There is small possibility that the chi2 minimization ends at the parameter boundary.
116  // In such case, we may get a completely wrong fit function, thus we refit w/o boundaries.
117  // if (tfr->Chi2() > 500) {
118  // B2WARNING("Correlation fit Chi2 is too large, refit with very wide parameter boundaries.");
119  // pol1pole->SetParLimits(1, 0, 0);
120  // pol1pole->SetParLimits(2, 0, 0);
121  // pol1pole->SetParLimits(3, 0, 0);
122  // tfr = pfx->Fit("pol1pole", "QMRS");
123  // pol1pole->SetParLimits(1, 0, 1);
124  // pol1pole->SetParLimits(2, -300, 0);
125  // }
126  double par[4];
127  pol1pole->GetParameters(par);
128  // double meanT0 = hEventT0->GetMean();
129  // double meanT0NoSync = hEventT0nosync->GetMean();
130  timeCal->set_current(3);
131  timeCal->set_elsparameters(par[0], par[1], par[2], par[3]);
132  payload->set(layer_num, ladder_num, sensor_num, bool(view), 1, *timeCal);
133  f->cd();
134  hEventT0->Write();
135  hEventT0vsELS->Write();
136  hEventT0nosync->Write();
137  pfx->Write();
138 
139  a = par[0]; b = par[1]; c = par[2]; d = par[3];
140  a_err = tfr->ParError(0); b_err = tfr->ParError(1); c_err = tfr->ParError(2); d_err = tfr->ParError(3);
141  chi2 = tfr->Chi2();
142  ndf = tfr->Ndf();
143  p = tfr->Prob();
144  m_tree->Fill();
145 
146  }
147  }
148  }
149  }
150  m_tree->Write();
151  f->Close();
152  saveCalibration(payload, "SVD3SampleELSTimeCalibrations");
153 
154  //delete f;
155 
156  // probably not needed - would trigger re-doing the collection
157  // if ( ... too large corrections ... ) return c_Iterate;
158  return c_OK;
159 }
160 
161 bool SVD3SampleELSTimeCalibrationAlgorithm::isBoundaryRequired(const Calibration::ExpRun& currentRun)
162 {
163  float meanRawTimeL3V = 0;
164  // auto eventT0Hist = getObjectPtr<TH1F>("hEventT0FromCDC");
165  auto rawTimeL3V = getObjectPtr<TH1F>("hRawTimeL3V");
166  // float meanEventT0 = eventT0Hist->GetMean();
167  if (!rawTimeL3V) {
169  meanRawTimeL3V = m_previousRawTimeMeanL3V.value();
170  } else {
171  if (rawTimeL3V->GetEntries() > m_minEntries)
172  meanRawTimeL3V = rawTimeL3V->GetMean();
173  else {
175  meanRawTimeL3V = m_previousRawTimeMeanL3V.value();
176  }
177  }
179  B2INFO("Setting start payload boundary to be the first run ("
180  << currentRun.first << "," << currentRun.second << ")");
181  m_previousRawTimeMeanL3V.emplace(meanRawTimeL3V);
182 
183  return true;
184  } else if (abs(meanRawTimeL3V - m_previousRawTimeMeanL3V.value()) > m_allowedTimeShift) {
185  B2INFO("Histogram mean has shifted from " << m_previousRawTimeMeanL3V.value()
186  << " to " << meanRawTimeL3V << ". We are requesting a new payload boundary for ("
187  << currentRun.first << "," << currentRun.second << ")");
188  m_previousRawTimeMeanL3V.emplace(meanRawTimeL3V);
189  return true;
190  } else {
191  return false;
192  }
193 }
Belle2::SVD3SampleELSTimeCalibrationAlgorithm::m_previousRawTimeMeanL3V
std::optional< float > m_previousRawTimeMeanL3V
Raw CoG of the previous run.
Definition: SVD3SampleELSTimeCalibrationAlgorithm.h:73
Belle2::CalibrationAlgorithm::saveCalibration
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
Definition: CalibrationAlgorithm.cc:290
Belle2::SVD3SampleELSTimeCalibrationAlgorithm::m_allowedTimeShift
float m_allowedTimeShift
Allowed Raw CoGshift.
Definition: SVD3SampleELSTimeCalibrationAlgorithm.h:74
Belle2::CalibrationAlgorithm::c_OK
@ c_OK
Finished successfuly =0 in Python.
Definition: CalibrationAlgorithm.h:51
Belle2::SVD3SampleELSTimeCalibrationAlgorithm::calibrate
virtual EResult calibrate() override
Run algo on data.
Definition: SVD3SampleELSTimeCalibrationAlgorithm.cc:33
Belle2::CalibrationAlgorithm::setDescription
void setDescription(const std::string &description)
Set algorithm description (in constructor)
Definition: CalibrationAlgorithm.h:331
Belle2::SVD3SampleELSTimeCalibrationAlgorithm::m_minEntries
float m_minEntries
Set the minimun number of entries required in the histograms of layer 3.
Definition: SVD3SampleELSTimeCalibrationAlgorithm.h:75
Belle2::SVD3SampleELSTimeCalibrationAlgorithm::isBoundaryRequired
virtual bool isBoundaryRequired(const Calibration::ExpRun &currentRun) override
If the event T0 changes significantly return true.
Definition: SVD3SampleELSTimeCalibrationAlgorithm.cc:161
Belle2::SVD3SampleELSTimeCalibrationAlgorithm::m_id
std::string m_id
Parameter given to set the UniqueID of the payload.
Definition: SVD3SampleELSTimeCalibrationAlgorithm.h:72
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::CalibrationAlgorithm::EResult
EResult
The result of calibration.
Definition: CalibrationAlgorithm.h:50
Belle2::CalibrationAlgorithm::c_NotEnoughData
@ c_NotEnoughData
Needs more data =2 in Python.
Definition: CalibrationAlgorithm.h:53
Belle2::SVD3SampleELSTimeCalibrations::t_payload
SVDCalibrationsBase< SVDCalibrationsScalar< SVDCoGCalibrationFunction > > t_payload
typedef for the SVDCoGCalibrationFunction payload of all SVD sensors
Definition: SVD3SampleELSTimeCalibrations.h:45
Belle2::CalibrationAlgorithm
Base class for calibration algorithms.
Definition: CalibrationAlgorithm.h:47
Belle2::SVDCoGCalibrationFunction
class to contain the CoG Time calibrations
Definition: SVDCoGCalibrationFunction.h:33