45 auto* file = TFile::Open(
"TOPCalValidation.root",
"recreate");
49 B2INFO(
"TOPValidationAlgorithm: get basic histograms");
51 double scaleFactor = 1;
54 if (h1->GetEntries() > 1) scaleFactor = h1->GetRMS();
58 std::vector<string> slotNames;
59 for (
unsigned slot = 1; slot <= c_numModules; slot++) {
60 string slotName =
"slot";
61 if (slot < 10) slotName +=
"0";
62 slotName += to_string(slot);
63 slotNames.push_back(slotName);
66 for (
unsigned slot = 0; slot < c_numModules; slot++) {
67 string name =
"hits_" + slotNames[slot];
74 B2INFO(
"TOPValidationAlgorithm: determine channel T0 residuals");
76 auto* h_profile =
new TProfile(
"calPrecision",
"calibration precision; slot; residuals [ns]", 16, 0.5, 16.5, -1, 1,
"S");
77 for (
unsigned slot = 0; slot < c_numModules; slot++) {
78 string name =
"chi2_" + slotNames[slot];
82 int nx = h->GetNbinsX();
83 string nameOut =
"channelT0_" + slotNames[slot];
84 string title =
"ChannelT0, " + slotNames[slot] +
"; channel; residuals [ns]";
85 auto* h0 =
new TH1F(nameOut.c_str(), title.c_str(), nx, 0, nx);
87 for (
int ibin = 1; ibin <= nx; ibin++) {
89 const auto& minimum = finder.getMinimum();
90 if (not minimum.valid)
continue;
91 h0->SetBinContent(ibin, minimum.position);
92 h0->SetBinError(ibin, minimum.error);
93 h_profile->Fill(slot + 1, minimum.position);
97 calPrecision->set(h_profile);
102 B2INFO(
"TOPValidationAlgorithm: get input tree");
106 B2ERROR(
"TOPValidationAlgorithm: input tree not found");
111 inputTree->SetBranchAddress(
"expNo", &
m_treeEntry.expNo);
112 inputTree->SetBranchAddress(
"runNo", &
m_treeEntry.runNo);
113 inputTree->SetBranchAddress(
"numTracks", &
m_treeEntry.numTracks);
114 inputTree->SetBranchAddress(
"commonT0", &
m_treeEntry.commonT0);
115 inputTree->SetBranchAddress(
"commonT0Err", &
m_treeEntry.commonT0Err);
116 inputTree->SetBranchAddress(
"moduleT0", &
m_treeEntry.moduleT0);
117 inputTree->SetBranchAddress(
"moduleT0Err", &
m_treeEntry.moduleT0Err);
118 inputTree->SetBranchAddress(
"numTBCalibrated", &
m_treeEntry.numTBCalibrated);
119 inputTree->SetBranchAddress(
"numT0Calibrated", &
m_treeEntry.numT0Calibrated);
120 inputTree->SetBranchAddress(
"numActive", &
m_treeEntry.numActive);
121 inputTree->SetBranchAddress(
"numActiveCalibrated", &
m_treeEntry.numActiveCalibrated);
122 inputTree->SetBranchAddress(
"thrEffi", &
m_treeEntry.thrEffi);
123 inputTree->SetBranchAddress(
"asicShifts", &
m_treeEntry.asicShifts);
124 inputTree->SetBranchAddress(
"svdOffset", &
m_treeEntry.svdOffset);
125 inputTree->SetBranchAddress(
"svdSigma", &
m_treeEntry.svdSigma);
126 inputTree->SetBranchAddress(
"cdcOffset", &
m_treeEntry.cdcOffset);
127 inputTree->SetBranchAddress(
"cdcSigma", &
m_treeEntry.cdcSigma);
128 inputTree->SetBranchAddress(
"fillPatternOffset", &
m_treeEntry.fillPatternOffset);
129 inputTree->SetBranchAddress(
"fillPatternFraction", &
m_treeEntry.fillPatternFraction);
133 B2INFO(
"TOPValidationAlgorithm: sort input tree entries");
135 std::multimap<int, ValidationTreeStruct> sortedEntries;
136 std::set<int> sortedRuns;
137 for (
int iev = 0; iev < inputTree->GetEntries(); iev++) {
138 inputTree->GetEntry(iev);
141 sortedRuns.insert(expRun);
146 B2INFO(
"TOPValidationAlgorithm: merge input tree entries");
148 std::vector<ValidationTreeStruct> mergedEntries;
149 for (
auto expRun : sortedRuns) {
151 const auto range = sortedEntries.equal_range(expRun);
152 for (
auto it = range.first; it != range.second; ++it) {
153 mergedEntry.
merge(it->second);
156 mergedEntries.push_back(mergedEntry);
161 int nx = mergedEntries.size();
163 B2ERROR(
"TOPValidationAlgorithm: input tree is empty");
171 std::set<int> sortedExps;
172 for (
auto& entry : mergedEntries) sortedExps.insert(entry.expNo);
173 std::string titleIndex =
"Experiment";
174 if (sortedExps.size() > 1) titleIndex +=
"s";
175 for (
auto expNo : sortedExps) titleIndex +=
" " + to_string(expNo) +
",";
176 titleIndex.pop_back();
177 auto* h_index =
new TH1F(
"runIndex", (titleIndex +
"; run index; run number").c_str(), nx, 0, nx);
178 for (
int i = 0; i < nx; i++) {
179 h_index->SetBinContent(i + 1, mergedEntries[i].runNo);
182 auto* h_numTracks =
new TH1F(
"numTracks",
"Number of tracks; run index; number of tracks", nx, 0, nx);
183 for (
int i = 0; i < nx; i++) {
184 h_numTracks->SetBinContent(i + 1, mergedEntries[i].numTracks);
187 auto* h_numMerged =
new TH1F(
"numMerged",
"Number of merged entries; run index; number of merged", nx, 0, nx);
188 for (
int i = 0; i < nx; i++) {
189 h_numMerged->SetBinContent(i + 1, mergedEntries[i].numMerged);
192 auto* h_commonT0 =
new TH1F(
"commonT0",
"commonT0; run index; residuals [ns]", nx, 0, nx);
193 for (
int i = 0; i < nx; i++) {
194 h_commonT0->SetBinContent(i + 1, mergedEntries[i].commonT0);
195 h_commonT0->SetBinError(i + 1, mergedEntries[i].commonT0Err);
198 for (
unsigned slot = 0; slot < c_numModules; slot++) {
199 string name =
"moduleT0_" + slotNames[slot];
200 string title =
"moduleT0, " + slotNames[slot] +
"; run index; residuals [ns]";
201 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
202 for (
int i = 0; i < nx; i++) {
203 h->SetBinContent(i + 1, mergedEntries[i].moduleT0[slot]);
204 h->SetBinError(i + 1, mergedEntries[i].moduleT0Err[slot]);
208 for (
unsigned slot = 0; slot < c_numModules; slot++) {
209 string name =
"numTBCalibrated_" + slotNames[slot];
210 string title =
"Time base calibrated, " + slotNames[slot] +
"; run index; fraction";
211 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
212 for (
int i = 0; i < nx; i++) {
213 h->SetBinContent(i + 1, mergedEntries[i].numTBCalibrated[slot] / 512.0);
217 for (
unsigned slot = 0; slot < c_numModules; slot++) {
218 string name =
"numT0Calibrated_" + slotNames[slot];
219 string title =
"channel T0 calibrated, " + slotNames[slot] +
"; run index; fraction";
220 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
221 for (
int i = 0; i < nx; i++) {
222 h->SetBinContent(i + 1, mergedEntries[i].numT0Calibrated[slot] / 512.0);
226 for (
unsigned slot = 0; slot < c_numModules; slot++) {
227 string name =
"numActive_" + slotNames[slot];
228 string title =
"Active, " + slotNames[slot] +
"; run index; fraction";
229 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
230 for (
int i = 0; i < nx; i++) {
231 h->SetBinContent(i + 1, mergedEntries[i].numActive[slot] / 512.0);
235 for (
unsigned slot = 0; slot < c_numModules; slot++) {
236 string name =
"numActiveCalibrated_" + slotNames[slot];
237 string title =
"Active and calibrated, " + slotNames[slot] +
"; run index; fraction";
238 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
239 for (
int i = 0; i < nx; i++) {
240 h->SetBinContent(i + 1, mergedEntries[i].numActiveCalibrated[slot] / 512.0);
244 for (
unsigned slot = 0; slot < c_numModules; slot++) {
245 string name =
"thrEffi_" + slotNames[slot];
246 string title =
"Threshold efficiency, " + slotNames[slot] +
"; run index; efficiency";
247 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
248 for (
int i = 0; i < nx; i++) {
249 h->SetBinContent(i + 1, mergedEntries[i].thrEffi[slot]);
253 for (
unsigned carrier = 0; carrier < 4; carrier++) {
254 string name =
"asicShifts_" + to_string(carrier);
255 string title =
"BS13d, carrier " + to_string(carrier) +
"; run index; shift [ns]";
256 auto* h =
new TH1F(name.c_str(), title.c_str(), nx, 0, nx);
257 for (
int i = 0; i < nx; i++) {
258 auto y = mergedEntries[i].asicShifts[carrier];
260 h->SetBinError(i + 1, 0);
262 h->SetBinContent(i + 1, y);
263 h->SetBinError(i + 1, 0.001);
268 auto* h_svdOffset =
new TH1F(
"svdOffset",
"Event T0 offset w.r.t TOP; run index; offset [ns]", nx, 0, nx);
269 auto* h_svdSigma =
new TH1F(
"svdSigma",
"Event T0 resolution; run index; sigma [ns]", nx, 0, nx);
270 for (
int i = 0; i < nx; i++) {
271 h_svdOffset->SetBinContent(i + 1, mergedEntries[i].svdOffset);
272 h_svdOffset->SetBinError(i + 1, mergedEntries[i].svdSigma / 1000);
273 h_svdSigma->SetBinContent(i + 1, mergedEntries[i].svdSigma);
274 h_svdSigma->SetBinError(i + 1, 0.001);
277 auto* h_cdcOffset =
new TH1F(
"cdcOffset",
"Event T0 offset w.r.t TOP; run index; offset [ns]", nx, 0, nx);
278 auto* h_cdcSigma =
new TH1F(
"cdcSigma",
"Event T0 resolution; run index; sigma [ns]", nx, 0, nx);
279 for (
int i = 0; i < nx; i++) {
280 h_cdcOffset->SetBinContent(i + 1, mergedEntries[i].cdcOffset);
281 h_cdcOffset->SetBinError(i + 1, mergedEntries[i].cdcSigma / 1000);
282 h_cdcSigma->SetBinContent(i + 1, mergedEntries[i].cdcSigma);
283 h_cdcSigma->SetBinError(i + 1, 0.001);
286 auto* h_fillPatternOffset =
new TH1F(
"fillPatternOffset",
"Fill pattern offset; run index; offset [RF clk]", nx, 0, nx);
287 auto* h_fillPatternFract =
new TH1F(
"fillPatternFract",
288 "Fraction of buckets matched with filled ones; run index; fraction", nx, 0, nx);
289 for (
int i = 0; i < nx; i++) {
290 if (isnan(mergedEntries[i].fillPatternOffset)) {
291 h_fillPatternOffset->SetBinError(i + 1, 0);
293 h_fillPatternOffset->SetBinContent(i + 1, mergedEntries[i].fillPatternOffset);
294 h_fillPatternOffset->SetBinError(i + 1, 0.01);
296 h_fillPatternFract->SetBinContent(i + 1, mergedEntries[i].fillPatternFraction);
301 B2INFO(
"TOPValidationAlgorithm: write the results");