Belle II Software development
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
24using namespace std;
25using boost::format;
26
27namespace 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.
STL namespace.