Belle II Software  release-08-01-10
PXDCalibrationUtilities.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 <framework/logging/Logger.h>
10 #include <pxd/calibration/PXDCalibrationUtilities.h>
11 #include <vxd/dataobjects/VxdID.h>
12 
13 #include <string>
14 #include <algorithm>
15 #include <set>
16 
17 #include <sstream>
18 #include <iostream>
19 
20 #include <boost/format.hpp>
21 
22 #include <TF1.h>
23 
24 using namespace std;
25 using boost::format;
26 
27 namespace Belle2 {
32  namespace PXD {
33 
35  void getNumberOfBins(const std::shared_ptr<TH1I>& histo_ptr, unsigned short& nBinsU, unsigned short& nBinsV)
36  {
37  set<unsigned short> uBinSet;
38  set<unsigned short> vBinSet;
39 
40  // Loop over all bins of input histo
41  for (auto histoBin = 1; histoBin <= histo_ptr->GetXaxis()->GetNbins(); histoBin++) {
42  // The bin label contains the vxdid, uBin and vBin
43  string label = histo_ptr->GetXaxis()->GetBinLabel(histoBin);
44 
45  // Parse label string format to read sensorID, uBin and vBin
46  istringstream stream(label);
47  string token;
48  getline(stream, token, '_');
49  getline(stream, token, '_');
50  unsigned short uBin = std::stoi(token);
51 
52  getline(stream, token, '_');
53  unsigned short vBin = std::stoi(token);
54 
55  uBinSet.insert(uBin);
56  vBinSet.insert(vBin);
57  }
58 
59  if (uBinSet.empty() || vBinSet.empty()) {
60  B2FATAL("Not able to determine the grid size. Something is wrong with collected data.");
61  } else {
62  nBinsU = *uBinSet.rbegin() + 1;
63  nBinsV = *vBinSet.rbegin() + 1;
64  }
65  }
66 
68  unsigned short getNumberOfSensors(const std::shared_ptr<TH1I>& histo_ptr)
69  {
70  set<unsigned short> sensorSet;
71 
72  // Loop over all bins of input histo
73  for (auto histoBin = 1; histoBin <= histo_ptr->GetXaxis()->GetNbins(); histoBin++) {
74  // The bin label contains the vxdid, uBin and vBin
75  string label = histo_ptr->GetXaxis()->GetBinLabel(histoBin);
76 
77  // Parse label string format to read sensorID, uBin and vBin
78  istringstream stream(label);
79  string token;
80  getline(stream, token, '_');
81  VxdID sensorID(token);
82  sensorSet.insert(sensorID.getID());
83  }
84  return sensorSet.size();
85  }
86 
88  double CalculateMedian(std::vector<double>& signals)
89  {
90  auto size = signals.size();
91 
92  if (size == 0) {
93  return 0.0; // Undefined, really.
94  } else if (size <= 100) {
95  // sort() or partial_sort is in O(NlogN)
96  sort(signals.begin(), signals.end());
97  if (size % 2 == 0) {
98  return (signals[size / 2 - 1] + signals[size / 2]) / 2;
99  } else {
100  return signals[size / 2];
101  }
102  } else {
103  // nth_element or max_element in O(N) only
104  // All elements before the nth are guanranteed smaller
105  auto n = size / 2;
106  nth_element(signals.begin(), signals.begin() + n, signals.end());
107  auto med = signals[n];
108  if (!(size & 1)) { // if size is even
109  auto max_it = max_element(signals.begin(), signals.begin() + n);
110  med = (*max_it + med) / 2.0;
111  }
112  return med;
113  }
114  }
116  double CalculateMedian(TH1* hist)
117  {
118  double quantiles[1]; // One element just for median
119  double probSums[1] = {0.5}; // median definiton
120  hist->GetQuantiles(1, quantiles, probSums);
121  return quantiles[0];
122  }
123 
125  double FitLandau(TH1* hist)
126  {
127  auto size = hist->GetEntries();
128  if (size == 0) return 0.0; // Undefined.
129 
130  int max = hist->GetBinLowEdge(hist->GetNbinsX() + 1);
131  int min = hist->GetBinLowEdge(1);
132 
133  // create fit function
134  TF1* landau = new TF1("landau", "TMath::Landau(x,[0],[1])*[2]", min, max);
135  landau->SetParNames("MPV", "sigma", "scale");
136  landau->SetParameters(1., 0.1, 1000);
137  landau->SetParLimits(0, 0., 3.);
138 
139  Int_t status = hist->Fit("landau", "Lq", "", min, max);
140  double MPV = landau->GetParameter("MPV");
141 
142  B2INFO("Fit result: " << status << " MPV " << MPV << " sigma " << landau->GetParameter("sigma")
143  << " scale " << landau->GetParameter("scale") << " chi2 " << landau->GetChisquare());
144 
145  // clean up
146  delete landau;
147 
148  // check fit status
149  if (status == 0) return MPV;
150  else {
151  B2WARNING("Fit failed!. using default value.");
152  return 0.0;
153  }
154  }
155 
157  double FitLandau(std::vector<double>& signals)
158  {
159  auto size = signals.size();
160  if (size == 0) return 0.0; // Undefined, really.
161 
162  // get max and min values of signal vector
163  double max = *max_element(signals.begin(), signals.end());
164  double min = *min_element(signals.begin(), signals.end());
165 
166  // create histogram to hold signals and fill it
167  TH1D* hist_signals = new TH1D("", "", max - min, min, max);
168  for (auto it = signals.begin(); it != signals.end(); ++it) {
169  hist_signals->Fill(*it);
170  }
171 
172  double MPV = FitLandau(hist_signals);
173  delete hist_signals;
174 
175  return MPV;
176  }
177  }// namespace PXD
179 } // namespace Belle2
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getID() const
Get the unique id.
Definition: VxdID.h:94
unsigned short getNumberOfSensors(const std::shared_ptr< TH1I > &histo_ptr)
Helper function to extract number of sensors from counter histogram labels.
void getNumberOfBins(const std::shared_ptr< TH1I > &histo_ptr, unsigned short &nBinsU, unsigned short &nBinsV)
Helper function to extract number of bins along u side and v side from counter histogram labels.
double CalculateMedian(std::vector< double > &signals)
Helper function to calculate a median from unsorted signal vector.
double FitLandau(TH1 *hist)
Helper function to estimate MPV from 1D histogram.
Abstract base class for different kinds of events.