9#include <top/calibration/TOPValidationAlgorithm.h>
10#include <top/utilities/Chi2MinimumFinder1D.h>
35 setDescription(
"Calibration algorithm for automatic validation of the calibration");
43 auto* file = TFile::Open(
"TOPCalValidation.root",
"recreate");
47 B2INFO(
"TOPValidationAlgorithm: get basic histograms");
49 double scaleFactor = 1;
50 auto h1 = getObjectPtr<TH1F>(
"moduleT0_pulls");
52 if (h1->GetEntries() > 1) scaleFactor = h1->GetRMS();
56 std::vector<string> slotNames;
57 for (
unsigned slot = 1; slot <= c_numModules; slot++) {
58 string slotName =
"slot";
59 if (slot < 10) slotName +=
"0";
60 slotName += to_string(slot);
61 slotNames.push_back(slotName);
64 for (
unsigned slot = 0; slot < c_numModules; slot++) {
65 string name =
"hits_" + slotNames[slot];
66 auto h = getObjectPtr<TH2F>(name);
72 B2INFO(
"TOPValidationAlgorithm: determine channel T0 residuals");
74 for (
unsigned slot = 0; slot < c_numModules; slot++) {
75 string name =
"chi2_" + slotNames[slot];
76 auto h = getObjectPtr<TH2F>(name);
79 int nx = h->GetNbinsX();
80 string nameOut =
"channelT0_" + slotNames[slot];
81 string title =
"ChannelT0, " + slotNames[slot] +
"; channel; residuals [ns]";
82 auto* h0 =
new TH1F(nameOut.c_str(), title.c_str(), nx, 0, nx);
84 for (
int ibin = 1; ibin <= nx; ibin++) {
86 const auto& minimum = finder.getMinimum();
87 if (not minimum.valid)
continue;
88 h0->SetBinContent(ibin, minimum.position);
89 h0->SetBinError(ibin, minimum.error);
95 B2INFO(
"TOPValidationAlgorithm: get input tree");
97 auto inputTree = getObjectPtr<TTree>(
"tree");
99 B2ERROR(
"TOPValidationAlgorithm: input tree not found");
126 B2INFO(
"TOPValidationAlgorithm: sort input tree entries");
128 std::multimap<int, ValidationTreeStruct> sortedEntries;
129 std::set<int> sortedRuns;
130 for (
int iev = 0; iev < inputTree->GetEntries(); iev++) {
131 inputTree->GetEntry(iev);
134 sortedRuns.insert(expRun);
139 B2INFO(
"TOPValidationAlgorithm: merge input tree entries");
141 std::vector<ValidationTreeStruct> mergedEntries;
142 for (
auto expRun : sortedRuns) {
144 const auto range = sortedEntries.equal_range(expRun);
145 for (
auto it = range.first; it != range.second; ++it) {
146 mergedEntry.
merge(it->second);
149 mergedEntries.push_back(mergedEntry);
154 int nx = mergedEntries.size();
156 B2ERROR(
"TOPValidationAlgorithm: input tree is empty");
164 std::set<int> sortedExps;
165 for (
auto& entry : mergedEntries) sortedExps.insert(entry.expNo);
166 std::string titleIndex =
"Experiment";
167 if (sortedExps.size() > 1) titleIndex +=
"s";
168 for (
auto expNo : sortedExps) titleIndex +=
" " + to_string(expNo) +
",";
169 titleIndex.pop_back();
170 auto* h_index =
new TH1F(
"runIndex", (titleIndex +
"; run index; run number").c_str(), nx, 0, nx);
171 for (
int i = 0; i < nx; i++) {
172 h_index->SetBinContent(i + 1, mergedEntries[i].runNo);
175 auto* h_numTracks =
new TH1F(
"numTracks",
"Number of tracks; run index; number of tracks", nx, 0, nx);
176 for (
int i = 0; i < nx; i++) {
177 h_numTracks->SetBinContent(i + 1, mergedEntries[i].numTracks);
180 auto* h_numMerged =
new TH1F(
"numMerged",
"Number of merged entries; run index; number of merged", nx, 0, nx);
181 for (
int i = 0; i < nx; i++) {
182 h_numMerged->SetBinContent(i + 1, mergedEntries[i].numMerged);
185 auto* h_commonT0 =
new TH1F(
"commonT0",
"commonT0; run index; residuals [ns]", nx, 0, nx);
186 for (
int i = 0; i < nx; i++) {
187 h_commonT0->SetBinContent(i + 1, mergedEntries[i].commonT0);
188 h_commonT0->SetBinError(i + 1, mergedEntries[i].commonT0Err);
191 for (
unsigned slot = 0; slot < c_numModules; slot++) {
192 string name =
"moduleT0_" + slotNames[slot];
193 string title =
"moduleT0, " + slotNames[slot] +
"; run index; residuals [ns]";
194 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
195 for (
int i = 0; i < nx; i++) {
196 h->SetBinContent(i + 1, mergedEntries[i].moduleT0[slot]);
197 h->SetBinError(i + 1, mergedEntries[i].moduleT0Err[slot]);
201 for (
unsigned slot = 0; slot < c_numModules; slot++) {
202 string name =
"numTBCalibrated_" + slotNames[slot];
203 string title =
"Time base calibrated, " + slotNames[slot] +
"; run index; fraction";
204 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
205 for (
int i = 0; i < nx; i++) {
206 h->SetBinContent(i + 1, mergedEntries[i].numTBCalibrated[slot] / 512.0);
210 for (
unsigned slot = 0; slot < c_numModules; slot++) {
211 string name =
"numT0Calibrated_" + slotNames[slot];
212 string title =
"channel T0 calibrated, " + slotNames[slot] +
"; run index; fraction";
213 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
214 for (
int i = 0; i < nx; i++) {
215 h->SetBinContent(i + 1, mergedEntries[i].numT0Calibrated[slot] / 512.0);
219 for (
unsigned slot = 0; slot < c_numModules; slot++) {
220 string name =
"numActive_" + slotNames[slot];
221 string title =
"Active, " + slotNames[slot] +
"; run index; fraction";
222 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
223 for (
int i = 0; i < nx; i++) {
224 h->SetBinContent(i + 1, mergedEntries[i].numActive[slot] / 512.0);
228 for (
unsigned slot = 0; slot < c_numModules; slot++) {
229 string name =
"numActiveCalibrated_" + slotNames[slot];
230 string title =
"Active and calibrated, " + slotNames[slot] +
"; run index; fraction";
231 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
232 for (
int i = 0; i < nx; i++) {
233 h->SetBinContent(i + 1, mergedEntries[i].numActiveCalibrated[slot] / 512.0);
237 for (
unsigned slot = 0; slot < c_numModules; slot++) {
238 string name =
"thrEffi_" + slotNames[slot];
239 string title =
"Threshold efficiency, " + slotNames[slot] +
"; run index; efficiency";
240 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
241 for (
int i = 0; i < nx; i++) {
242 h->SetBinContent(i + 1, mergedEntries[i].thrEffi[slot]);
246 for (
unsigned carrier = 0; carrier < 4; carrier++) {
247 string name =
"asicShifts_" + to_string(carrier);
248 string title =
"BS13d, carrier " + to_string(carrier) +
"; run index; shift [ns]";
249 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
250 for (
int i = 0; i < nx; i++) {
251 auto y = mergedEntries[i].asicShifts[carrier];
253 h->SetBinError(i + 1, 0);
255 h->SetBinContent(i + 1, y);
256 h->SetBinError(i + 1, 0.001);
261 auto* h_svdOffset =
new TH1F(
"svdOffset",
"Event T0 offset w.r.t TOP; run index; offset [ns]", nx, 0, nx);
262 auto* h_svdSigma =
new TH1F(
"svdSigma",
"Event T0 resolution; run index; sigma [ns]", nx, 0, nx);
263 for (
int i = 0; i < nx; i++) {
264 h_svdOffset->SetBinContent(i + 1, mergedEntries[i].svdOffset);
265 h_svdOffset->SetBinError(i + 1, mergedEntries[i].svdSigma / 1000);
266 h_svdSigma->SetBinContent(i + 1, mergedEntries[i].svdSigma);
267 h_svdSigma->SetBinError(i + 1, 0.001);
270 auto* h_cdcOffset =
new TH1F(
"cdcOffset",
"Event T0 offset w.r.t TOP; run index; offset [ns]", nx, 0, nx);
271 auto* h_cdcSigma =
new TH1F(
"cdcSigma",
"Event T0 resolution; run index; sigma [ns]", nx, 0, nx);
272 for (
int i = 0; i < nx; i++) {
273 h_cdcOffset->SetBinContent(i + 1, mergedEntries[i].cdcOffset);
274 h_cdcOffset->SetBinError(i + 1, mergedEntries[i].cdcSigma / 1000);
275 h_cdcSigma->SetBinContent(i + 1, mergedEntries[i].cdcSigma);
276 h_cdcSigma->SetBinError(i + 1, 0.001);
279 auto* h_fillPatternOffset =
new TH1F(
"fillPatternOffset",
"Fill pattern offset; run index; offset [RF clk]", nx, 0, nx);
280 auto* h_fillPatternFract =
new TH1F(
"fillPatternFract",
281 "Fraction of buckets matched with filled ones; run index; fraction", nx, 0, nx);
282 for (
int i = 0; i < nx; i++) {
283 if (isnan(mergedEntries[i].fillPatternOffset)) {
284 h_fillPatternOffset->SetBinError(i + 1, 0);
286 h_fillPatternOffset->SetBinContent(i + 1, mergedEntries[i].fillPatternOffset);
287 h_fillPatternOffset->SetBinError(i + 1, 0.01);
289 h_fillPatternFract->SetBinContent(i + 1, mergedEntries[i].fillPatternFraction);
294 B2INFO(
"TOPValidationAlgorithm: write the results");
Base class for calibration algorithms.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_Failure
Failed =3 in Python.
Minimum finder using tabulated chi^2 values in one dimension.
TOPValidationAlgorithm()
Constructor.
virtual EResult calibrate() final
algorithm implementation
ValidationTreeStruct m_treeEntry
input tree entry
Abstract base class for different kinds of events.
Calibration validation tree structure.
int numTBCalibrated[c_numModules]
number of timebase calibrated channels, index = slot - 1
void rescaleErrors(double scaleFactor)
Rescale errors.
int numTracks
number of selected tracks
int numActive[c_numModules]
number of active channels, index = slot - 1
float svdOffset
SVD event T0 offset.
float svdSigma
SVD event T0 resolution.
float fillPatternFraction
fraction of reconstructed buckets matched with filled ones
void merge(const ValidationTreeStruct &other)
Merge two structures.
float fillPatternOffset
fill pattern offset
float commonT0
common T0 residual
float commonT0Err
common T0 uncertainty (not scaled)
float thrEffi[c_numModules]
threshold efficiency: average over active calibrated channels, index = slot - 1
float moduleT0[c_numModules]
module T0 residuals, index = slot - 1
int numActiveCalibrated[c_numModules]
number of active calibrated channels, index = slot - 1
int expNo
experiment number
float cdcSigma
CDC event T0 resolution.
float cdcOffset
CDC event T0 offset.
float moduleT0Err[c_numModules]
module T0 uncertainties (not scaled), index = slot - 1
float asicShifts[4]
carrier shifts of BS13d, index = carrier number
int numT0Calibrated[c_numModules]
number of channel T0 calibrated channels, index = slot - 1