Belle II Software development
CDCDedxValidationAlgorithm.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 <cdc/calibration/CDCdEdx/CDCDedxValidationAlgorithm.h>
10#include <cdc/calibration/CDCdEdx/CDCDedxWireGainAlgorithm.h>
11
12#include <cdc/dbobjects/CDCDedxWireGain.h>
13#include <cdc/dbobjects/CDCDedxCosineCor.h>
14#include <cdc/dbobjects/CDCDedx1DCell.h>
15#include <cdc/dbobjects/CDCDedxRunGain.h>
16#include <cdc/dbobjects/CDCDedxBadWires.h>
17#include <framework/database/IntervalOfValidity.h>
18
19#include <framework/database/Database.h>
20#include <framework/database/DBStore.h>
21#include <framework/database/Configuration.h>
22
23#include <cmath>
24#include <TTree.h>
25#include <TMap.h>
26#include <TLegend.h>
27#include <TF1.h>
28
29
30using namespace Belle2;
31using namespace CDC;
32
33//-----------------------------------------------------------------
34// Implementation
35//-----------------------------------------------------------------
36
38 CalibrationAlgorithm("ElectronValCollector"),
39 m_sigmaR(2.0),
40 m_dedxBins(600),
41 m_dedxMin(0.0),
42 m_dedxMax(5.0),
43 m_cosBins(100),
44 m_cosMin(-1.0),
45 m_cosMax(1.0),
46 m_momBins(80),
47 m_momMin(0.0),
48 m_momMax(8.0),
49 m_eaBin(316),
50 m_eaMin(-TMath::Pi() / 2),
51 m_eaMax(+TMath::Pi() / 2),
52 m_suffix("")
53{
54 // Set module properties
55 setDescription("A validation algorithm for CDC dE/dx electron");
56}
57
58//-----------------------------------------------------------------
59// Run the calibration
60//-----------------------------------------------------------------
61
63{
64
66
67 std::vector<std::string> subdirs = {"run", "costh", "mom", "wire", "injection", "oneD"};
68 for (const auto& dir : subdirs) {
69 gSystem->Exec(Form("mkdir -p plots/%s", dir.c_str()));
70 }
71
72 // Get data objects
73 auto tBhabha = getObjectPtr<TTree>("tBhabha");
74
75 // require at least 100 tracks
76 if (tBhabha->GetEntries() < 100) return c_NotEnoughData;
77
78 // Get data objects
79 auto tRadee = getObjectPtr<TTree>("tRadee");
80
81 // require at least 100 tracks
82 if (tRadee->GetEntries() < 100) return c_NotEnoughData;
83
87
88 m_suffix.clear();
89
90 return c_OK;
91}
92
93//------------------------------------
95{
96
97 int cruns = 0;
98 for (auto expRun : getRunList()) {
99 if (cruns == 0) B2INFO("start exp " << expRun.first << " and run " << expRun.second << "");
100 cruns++;
101 }
102
103 const auto erStart = getRunList()[0];
104 int estart = erStart.first;
105 int rstart = erStart.second;
106
107 updateDBObjPtrs(1, rstart, estart);
108
109 if (m_suffix.length() > 0) m_suffix = Form("%s_e%d_r%d", m_suffix.data(), estart, rstart);
110 else m_suffix = Form("e%d_r%d", estart, rstart);
111}
112
113
115{
116 auto ttree = getObjectPtr<TTree>("tRadee");
117
118 double dedx, costh, p, injtime = 0.0, injring = 1.0;
119 int charge;
120
121 std::vector<double>* dedxhit = 0, *enta = 0;
122 std::vector<int>* layer = 0;
123
124 ttree->SetBranchAddress("dedx", &dedx);
125 ttree->SetBranchAddress("p", &p);
126 ttree->SetBranchAddress("costh", &costh);
127 ttree->SetBranchAddress("charge", &charge);
128 ttree->SetBranchAddress("injtime", &injtime);
129 ttree->SetBranchAddress("injring", &injring);
130 ttree->SetBranchAddress("dedxhit", &dedxhit);
131 ttree->SetBranchAddress("entaRS", &enta);
132 ttree->SetBranchAddress("layer", &layer);
133
134 std::vector<double> vtlocaledges;
135 defineTimeBins(vtlocaledges);
136 m_tbins = vtlocaledges.size() - 1;
137 m_tedges = &vtlocaledges[0];
138
139 std::array<std::array<std::vector<TH1D*>, 2>, 13> hdedx_mom;
140 std::array<std::vector<TH1D*>, 2> hdedx_mom_peaks, hdedx_inj, hdedx_inj_nocor, hdedx_oned;
141 TH1D* htimes = new TH1D(Form("htimes_%s", m_suffix.data()), "", m_tbins, m_tedges);
142
143 const double momBinWidth = (m_momMax - m_momMin) / m_momBins;
144 const double momBinW = (4.0 - m_momMin) / 4;
145
146 std::string scos[13] = {"acos", "cos#theta > 0.0", "cos#theta < 0.0", "cos#theta <= -0.8",
147 "cos#theta > -0.8 and cos#theta <= -0.6",
148 "cos#theta > -0.6 and cos#theta <= -0.4", "cos#theta > -0.4 and cos#theta <= -0.2",
149 "cos#theta > -0.2 and cos#theta <= 0", "cos#theta > 0 and cos#theta <= 0.2",
150 "cos#theta > 0.2 and cos#theta <= 0.4", "cos#theta > 0.4 and cos#theta <= 0.6",
151 "cos#theta > 0.6 and cos#theta <= 0.8", "cos#theta > 0.8"
152 };
153 std::string stype[2] = {"posi", "elec"};
154 std::string sLayer[2] = {"IL", "OL"};
155
156 // Define histograms for momentum bins and charge types
157 for (int ic = 0; ic < 13; ic++) {
158 for (int it = 0; it < 2; ++it) {
159 hdedx_mom[ic][it].resize(m_momBins);
160 defineHisto(hdedx_mom[ic][it], "mom", Form("%d_%s", ic, stype[it].data()));
161 }
162 }
163
164 // Define histograms for injection time bins and rings
165 for (unsigned int ir = 0; ir < 2; ir++) {
166 hdedx_inj[ir].resize(m_tbins);
167 hdedx_inj_nocor[ir].resize(m_tbins);
168 hdedx_mom_peaks[ir].resize(4);
169 hdedx_oned[ir].resize(m_eaBin);
170
171 defineHisto(hdedx_inj[ir], "inj", m_sring[ir].data());
172 defineHisto(hdedx_inj_nocor[ir], "inj", Form("nocor_%s", m_sring[ir].data()));
173 defineHisto(hdedx_mom_peaks[ir], "mom_peaks", Form("%s", stype[ir].data()));
174 defineHisto(hdedx_oned[ir], "oned", Form("%s", sLayer[ir].data()));
175 }
176
177 double eaBW = (m_eaMax - m_eaMin) / m_eaBin;
178 double icos[3] = {0, -1, -1};
179 double chgtype;
180
181 // Loop over all the entries in the tree
182 for (int i = 0; i < ttree->GetEntries(); ++i) {
183 ttree->GetEvent(i);
184
185 // Skip invalid events
186 if (dedx <= 0 || injtime < 0 || injring < 0) continue;
187
188 // Calculate momentum bin index for hdedx_mom
189 int binIndex = static_cast<int>((abs(p) - m_momMin) / momBinWidth);
190
191 // Determine cos(theta) category
192
193 icos[1] = (costh > 0) ? 1 : 2;
194 icos[2] = int((costh + 1.0) / 0.2) + 3;
195 if (icos[2] < 3) icos[2] = 3;
196 if (icos[2] > 12) icos[2] = 12;
197
198 // Determine charge type
199 chgtype = (charge > 0) ? 0 : 1;
200
201 // Fill momentum histograms (only if binIndex is valid)
202 if (binIndex >= 0 && binIndex < m_momBins) {
203 hdedx_mom[icos[0]][chgtype][binIndex]->Fill(dedx);
204 hdedx_mom[icos[1]][chgtype][binIndex]->Fill(dedx);
205 hdedx_mom[icos[2]][chgtype][binIndex]->Fill(dedx);
206 }
207
208 // Add larger times to the last bin
209 if (injtime > m_tedges[m_tbins]) injtime = m_tedges[m_tbins] - 10.0;
210
211 // Injection ring type
212 int wr = (injring > 0.5) ? 1 : 0;
213
214 double timeGain = m_DBInjectTime->getCorrection("mean", injring, injtime);
215
216 // Injection time bin
217 unsigned int tb = htimes->GetXaxis()->FindBin(injtime);
218 tb = std::min(tb, static_cast<unsigned int>(m_tbins)) - 1;
219
220 // Fill injection time and dE/dx histograms
221 htimes->Fill(injtime);
222 hdedx_inj[wr][tb]->Fill(dedx);
223 hdedx_inj_nocor[wr][tb]->Fill(dedx * timeGain);
224
225 // Fill hdedx_mom_peaks with its own binning
226 int binI = static_cast<int>((abs(p) - m_momMin) / momBinW);
227 if (binI >= 0 && binI < 4) {
228 hdedx_mom_peaks[chgtype][binI]->Fill(dedx);
229 }
230
231 // Fill dE/dx in enta bins from hits
232 for (unsigned int j = 0; j < dedxhit->size(); ++j) {
233 if (dedxhit->at(j) == 0) continue;
234
235 double entaval = enta->at(j);
236 int ibin = std::floor((entaval - m_eaMin) / eaBW);
237 if (ibin < 0 || ibin >= m_eaBin) continue;
238
239 int mL = (layer->at(j) < 8) ? 0 : 1;
240 hdedx_oned[mL][ibin]->Fill(dedxhit->at(j));
241 }
242 }
243
244
245 for (int ic = 0; ic < 13; ic++) {
246 for (int it = 0; it < 2; ++it) {
247 printCanvas(hdedx_mom[ic][it], Form("plots/mom/dedx_vs_mom_%d_%s_%s", ic, stype[it].data(), m_suffix.data()), "mom");
248 }
249 }
250 for (int it = 0; it < 2; ++it) {
251 printCanvas(hdedx_inj[it], Form("plots/injection/dedx_vs_inj_%s_%s", m_sring[it].data(), m_suffix.data()), "inj");
252 printCanvas(hdedx_inj_nocor[it], Form("plots/injection/dedx_vs_inj_nocor_%s_%s", m_sring[it].data(), m_suffix.data()), "inj");
253 printCanvas(hdedx_oned[it], Form("plots/oneD/dedx_vs_1D_%s_%s", sLayer[it].data(), m_suffix.data()), "oned");
254 }
255
256 printCanvasdEdx(hdedx_mom_peaks, Form("plots/mom/dedxpeaks_vs_mom_%s", m_suffix.data()), "mom");
257
258}
259
261{
262 auto ttree = getObjectPtr<TTree>("tBhabha");
263
264 double dedx, costh;
265 int run, charge;
266
267 std::vector<int>* wire = 0;
268 ttree->SetBranchAddress("wire", &wire);
269
270 std::vector<double>* dedxhit = 0;
271 ttree->SetBranchAddress("dedxhit", &dedxhit);
272
273 ttree->SetBranchAddress("dedx", &dedx);
274 ttree->SetBranchAddress("run", &run);
275 ttree->SetBranchAddress("charge", &charge);
276 ttree->SetBranchAddress("costh", &costh);
277
278 std::map<int, TH1D*> hdedx_run;
279 std::array<std::vector<TH1D*>, 3> hdedx_cos;
280 std::array<std::vector<TH1D*>, 2> hdedx_cos_peaks;
281 std::vector<TH1D*> hdedxhit(c_nSenseWires);
282
283 const double cosBinWidth = (m_cosMax - m_cosMin) / m_cosBins;
284 const double cosBinW = (m_cosMax - m_cosMin) / 4;
285
286 std::string stype[3] = {"all", "posi", "elec"};
287
288 for (int it = 0; it < 3; ++it) {
289 hdedx_cos[it].resize(m_cosBins);
290 defineHisto(hdedx_cos[it], "costh", stype[it]);
291 }
292
293 for (int ir = 0; ir < 2; ir++) {
294 hdedx_cos_peaks[ir].resize(4);
295 defineHisto(hdedx_cos_peaks[ir], "cos_peaks", Form("%s", stype[ir + 1].data()));
296 }
297
298 defineHisto(hdedxhit, "wire", "wire");
299
300 // Loop over all the entries in the tree
301 for (int i = 0; i < ttree->GetEntries(); ++i) {
302 ttree->GetEvent(i);
303 if (dedx <= 0) continue;
304
305 // Check if a dE/dx histogram for this run number already exists
306 if (hdedx_run.find(run) == hdedx_run.end()) {
307 std::string histName = Form("hist_dedx_run_%d", run);
308 std::string histTitle = Form("dE/dx Histogram for Run %d", run);
309 hdedx_run[run] = new TH1D(histName.data(), histTitle.data(), m_dedxBins, m_dedxMin, m_dedxMax);
310 }
311
312 // Fill run-specific histogram
313 hdedx_run[run]->Fill(dedx);
314
315 // Fill cos(theta) histograms (all charge + by charge sign)
316 int binIndex = static_cast<int>((costh - m_cosMin) / cosBinWidth);
317 if (binIndex >= 0 && binIndex < m_cosBins) {
318 hdedx_cos[0][binIndex]->Fill(dedx); // All charge
319
320 if (charge > 0)
321 hdedx_cos[1][binIndex]->Fill(dedx);
322 else if (charge < 0)
323 hdedx_cos[2][binIndex]->Fill(dedx);
324 }
325
326 // Fill dE/dx for each wire hit
327 for (unsigned int j = 0; j < wire->size(); ++j) {
328 int jwire = wire->at(j);
329 double jhitdedx = dedxhit->at(j);
330 hdedxhit[jwire]->Fill(jhitdedx);
331 }
332
333 // Fill cos(theta) peaks histograms
334 int binI = static_cast<int>((costh - m_cosMin) / cosBinW);
335 if (binI >= 0 && binI < 4) {
336 if (charge > 0)
337 hdedx_cos_peaks[0][binI]->Fill(dedx);
338 else if (charge < 0)
339 hdedx_cos_peaks[1][binI]->Fill(dedx);
340 }
341 }
342
343 printCanvasRun(hdedx_run, Form("plots/run/dedx_vs_run_%s", m_suffix.data()));
344 printCanvas(hdedx_cos[0], Form("plots/costh/dedx_vs_cos_all_%s", m_suffix.data()), "costh");
345 printCanvas(hdedx_cos[1], Form("plots/costh/dedx_vs_cos_positrons_%s", m_suffix.data()), "costh");
346 printCanvas(hdedx_cos[2], Form("plots/costh/dedx_vs_cos_electrons_%s", m_suffix.data()), "costh");
347 printCanvasdEdx(hdedx_cos_peaks, Form("plots/costh/dedxpeaks_vs_cos_%s", m_suffix.data()), "costh");
348 wireGain(hdedxhit);
349}
350
351//------------------------------------
352void CDCDedxValidationAlgorithm::defineHisto(std::vector<TH1D*>& htemp, std::string var, std::string stype)
353{
354 int xbins = 0;
355 double xmin = 0.0, xmax = 0.0;
356 double binWidth = 0.0;
357
358 if (var == "mom") {
359 xbins = m_momBins; xmin = m_momMin; xmax = m_momMax;
360 } else if (var == "oned") {
361 xbins = m_eaBin; xmin = m_eaMin; xmax = m_eaMax; m_dedxBins = 250;
362 } else if (var == "costh") {
363 xbins = m_cosBins; xmin = m_cosMin; xmax = m_cosMax;
364 } else if (var == "inj") {
365 xbins = m_tbins;
366 } else if (var == "mom_peaks") {
367 xbins = 4; xmin = m_momMin; xmax = 4.0;
368 } else if (var == "cos_peaks") {
369 xbins = 4; xmin = m_cosMin; xmax = m_cosMax;
370 } else {
371 xbins = c_nSenseWires; m_dedxBins = 250;
372 }
373
374 if (var == "costh" || var == "mom" || var == "mom_peaks" || var == "cos_peaks" || var == "oned") {
375 binWidth = (xmax - xmin) / xbins;
376 }
377
378 for (int ic = 0; ic < xbins; ic++) {
379 std::string title = Form("dedxhit-dist, wire:%d", ic);
380 std::string name = Form("hdedx_%s_%s_%d", m_suffix.data(), var.data(), ic);
381
382 if (var == "costh" || var == "mom" || var == "mom_peaks" || var == "cos_peaks" || var == "oned") {
383 double min = ic * binWidth + xmin;
384 double max = min + binWidth;
385 title = Form("%s: (%0.02f, %0.02f) %s", var.data(), min, max, stype.data());
386 name = Form("hdedx_%s_%s_%s_%d", m_suffix.data(), var.data(), stype.data(), ic);
387 } else if (var == "inj") {
388 std::string label = getTimeBinLabel(m_tedges[ic], ic);
389 title = Form("%s, time(%s)", stype.data(), label.data());
390 name = Form("h%s_%s_%s_t%d", var.data(), m_suffix.data(), stype.data(), ic);
391 }
392 htemp[ic] = new TH1D(name.data(), "", m_dedxBins, m_dedxMin, m_dedxMax);
393 htemp[ic]->SetTitle(Form("%s;dedx;entries", title.data()));
394 }
395}
396
397void CDCDedxValidationAlgorithm::printCanvasdEdx(std::array<std::vector<TH1D*>, 2>& htemp, std::string namesfx, std::string svar)
398{
399 int xbins = 4;
400 double xmin, xmax;
401
402 if (svar == "mom") {
403 xmin = m_momMin; xmax = 4.0;
404 } else if (svar == "costh") {
405 xmin = m_cosMin; xmax = m_cosMax;
406 } else {
407 B2FATAL("wrong input");
408 }
409 double binWidth = (xmax - xmin) / xbins;
410
411 // Set up the TCanvas with 2x2 grid
412 TCanvas* ctmp = new TCanvas("tmp", "tmp", 1200, 1200);
413 ctmp->Divide(2, 2); // Divide into 2x2 grid
414
415 // Prepare the PDF output
416 std::stringstream psname;
417 psname << Form("%s.pdf[", namesfx.data());
418 ctmp->Print(psname.str().c_str());
419 psname.str("");
420 psname << Form("%s.pdf", namesfx.data());
421
422 // Iterate through the histograms and plot them in the canvas
423 for (int i = 0; i < xbins; ++i) {
424
425 ctmp->cd(i % 4 + 1);
426
427 double emean, emeanErr, esigma, esigmaErr;
428 double pmean, pmeanErr, psigma, psigmaErr;
429
430 fit(htemp[0][i], emean, emeanErr, esigma, esigmaErr);
431 fit(htemp[1][i], pmean, pmeanErr, psigma, psigmaErr);
432
433 double min = i * binWidth + xmin;
434 double max = min + binWidth;
435
436 TPaveText pt(0.6, 0.63, 0.85, 0.89, "NBNDC");
437 setTextCosmetics(pt, kBlack);
438 pt.AddText("e+");
439 pt.AddText(Form("#mu_{fit}: %0.03f#pm%0.03f", emean, emeanErr));
440 pt.AddText(Form("#sigma_{fit}: %0.03f#pm%0.03f", esigma, esigmaErr));
441
442 pt.AddText("e-");
443 pt.AddText(Form("#mu_{fit}: %0.03f#pm%0.03f", pmean, pmeanErr));
444 pt.AddText(Form("#sigma_{fit}: %0.03f#pm%0.03f", psigma, psigmaErr));
445
446 htemp[0][i]->SetStats(0);
447 htemp[1][i]->SetStats(0);
448 htemp[0][i]->SetFillColor(0);
449 htemp[1][i]->SetFillColor(0);
450 htemp[0][i]->SetLineColor(8);
451 htemp[1][i]->SetLineColor(9);
452 htemp[0][i]->SetTitle(Form("%s: (%0.02f, %0.02f)", svar.data(), min, max));
453 if (htemp[0][i]->GetEntries() > 0)
454 htemp[0][i]->Scale(1.0 / htemp[0][i]->GetEntries());
455 if (htemp[1][i]->GetEntries() > 0)
456 htemp[1][i]->Scale(1.0 / htemp[1][i]->GetEntries());
457
458 if (htemp[1][i]->GetMaximum() > htemp[0][i]->GetMaximum())
459 htemp[0][i]->SetMaximum(htemp[1][i]->GetMaximum());
460
461 htemp[0][i]->DrawCopy("HIST");
462 htemp[1][i]->DrawCopy("same HIST");
463 pt.DrawClone("same");
464
465 TLegend* lego = new TLegend(0.15, 0.67, 0.3, 0.8);
466 lego->AddEntry(htemp[0][i], "e+", "l");
467 lego->AddEntry(htemp[1][i], "e-", "l");
468 lego->Draw("same");
469
470 if ((i + 1) % 4 == 0 || i == xbins - 1) {
471 ctmp->SetBatch(kTRUE);
472 ctmp->Print(psname.str().c_str());
473 if ((i + 1) % 4 == 0) ctmp->Clear("D");
474 }
475 }
476
477 psname.str("");
478 psname << Form("%s.pdf]", namesfx.data());
479 ctmp->Print(psname.str().c_str());
480
481 delete ctmp;
482}
483
484void CDCDedxValidationAlgorithm::printCanvas(std::vector<TH1D*>& htemp, std::string namesfx, std::string svar)
485{
486 int xbins = 0;
487 double xmin = 0.0, xmax = 0.0;
488
489 if (svar == "mom") {
490 xbins = m_momBins; xmin = m_momMin; xmax = m_momMax;
491 } else if (svar == "oned") {
492 xbins = m_eaBin; xmin = m_eaMin; xmax = m_eaMax;
493 } else if (svar == "costh") {
494 xbins = m_cosBins; xmin = m_cosMin; xmax = m_cosMax;
495 } else if (svar == "inj") {
496 xbins = m_tbins;
497 } else if (svar == "mom_peaks") {
498 xbins = 4; xmin = m_momMin; xmax = 4.0;
499 } else {
500 B2FATAL("wrong input");
501 }
502
503 // Set up the TCanvas with 4x4 grid
504 TCanvas* ctmp = new TCanvas("tmp", "tmp", 1200, 1200);
505 ctmp->Divide(4, 4); // Divide into 4x4 grid
506
507 // Prepare the PDF output
508 std::stringstream psname;
509 psname << Form("%s.pdf[", namesfx.data());
510 ctmp->Print(psname.str().c_str());
511 psname.str("");
512 psname << Form("%s.pdf", namesfx.data());
513
514 std::ofstream outFile;
515 outFile.open(Form("%s.txt", namesfx.data()));
517
518 // Iterate through the histograms and plot them in the canvas
519 for (int i = 0; i < xbins; ++i) {
520
521 ctmp->cd(i % 16 + 1);
522 TPaveText pt(0.6, 0.73, 0.85, 0.89, "NBNDC");
523 setTextCosmetics(pt, kBlack);
524
525 if (svar == "oned") {
526 unsigned int minbin, maxbin;
527 wireg.getTruncatedBins(htemp[i], minbin, maxbin);
528 htemp[i]->SetTitle(Form("dedxhit-dist, entabin: %d ;%d;%d", i, minbin, maxbin));
529
530 double dedxmean = wireg.getTruncationMean(htemp[i], minbin, maxbin);
531
532 const double binWidth = (xmax - xmin) / xbins;
533 double binCenter = xmin + (i + 0.5) * binWidth; // Calculate bin center for cos(theta) or mom
534
535 outFile << binCenter << " " << dedxmean << std::endl;
536 } else {
537 double mean, meanErr, sigma, sigmaErr;
538 fit(htemp[i], mean, meanErr, sigma, sigmaErr);
539
540 if (svar == "mom" || svar == "costh" || svar == "mom_peaks") {
541 const double binWidth = (xmax - xmin) / xbins;
542 double binCenter = xmin + (i + 0.5) * binWidth; // Calculate bin center for cos(theta) or mom
543
544 outFile << binCenter << " " << mean << " " << meanErr << " " << sigma << " " << sigmaErr << std::endl;
545 } else {
546 std::string label = getTimeBinLabel(m_tedges[i], i);
547 outFile << i << " " << label << " " << mean << " " << meanErr << " " << sigma << " " << sigmaErr << std::endl;
548 }
549
550 pt.AddText(Form("#mu_{fit}: %0.03f#pm%0.03f", mean, meanErr));
551 pt.AddText(Form("#sigma_{fit}: %0.03f#pm%0.03f", sigma, sigmaErr));
552 }
553 htemp[i]->SetStats(0);
554 htemp[i]->DrawCopy("");
555 pt.DrawClone("same");
556
557 if ((i + 1) % 16 == 0 || ((i + 1) == xbins)) {
558 ctmp->SetBatch(kTRUE);
559 ctmp->Print(psname.str().c_str());
560 ctmp->Clear("D");
561 }
562 }
563
564 // ctmp->Print(psname.str().c_str());
565 psname.str("");
566 psname << Form("%s.pdf]", namesfx.data());
567 ctmp->Print(psname.str().c_str());
568
569 outFile.close();
570
571 delete ctmp;
572}
573
574void CDCDedxValidationAlgorithm::fit(TH1D*& hist, double& mean, double& meanErr, double& sigma, double& sigmaErr)
575{
576
577 std::string status = "";
578
579 if (hist->Integral() > 100)
580 fitGaussianWRange(hist, status);
581
582 if (status != "fitOK") {
583 hist->SetFillColor(kOrange);
584 mean = 0.0, meanErr = 0.0, sigma = 0.0, sigmaErr = 0.0;
585 } else {
586 mean = hist->GetFunction("gaus")->GetParameter(1);
587 meanErr = hist->GetFunction("gaus")->GetParError(1);
588 sigma = hist->GetFunction("gaus")->GetParameter(2);
589 sigmaErr = hist->GetFunction("gaus")->GetParError(2);
590 hist->SetFillColor(kYellow);
591 }
592}
593
594void CDCDedxValidationAlgorithm::printCanvasRun(std::map<int, TH1D*>& htemp, std::string namesfx)
595{
596 // Set up the TCanvas with 4x4 grid
597 TCanvas* ctmp = new TCanvas("tmp", "tmp", 1200, 1200);
598 ctmp->Divide(4, 4); // Divide into 4x4 grid
599
600 // Prepare the PDF output
601 std::stringstream psname;
602 psname << Form("%s.pdf[", namesfx.data());
603 ctmp->Print(psname.str().c_str());
604 psname.str("");
605 psname << Form("%s.pdf", namesfx.data());
606
607 std::ofstream outFile;
608 outFile.open(Form("%s.txt", namesfx.data()));
609
610 // Iterate through the histograms and plot them in the canvas
611 int irun = 0;
612 for (const auto& entry : htemp) {
613 int run = entry.first;
614 TH1D* hist = entry.second;
615
616 ctmp->cd(irun % 16 + 1);
617
618 TPaveText pt(0.6, 0.73, 0.85, 0.89, "NBNDC");
619 setTextCosmetics(pt, kBlack);
620
621 double mean, meanErr, sigma, sigmaErr;
622 fit(hist, mean, meanErr, sigma, sigmaErr);
623
624 outFile << run << " " << mean << " " << meanErr << " " << sigma << " " << sigmaErr << std::endl;
625
626 pt.AddText(Form("#mu_{fit}: %0.03f#pm%0.03f", mean, meanErr));
627 pt.AddText(Form("#sigma_{fit}: %0.03f#pm%0.03f", sigma, sigmaErr));
628
629 hist->SetStats(0);
630 hist->DrawCopy("");
631 pt.DrawClone("same");
632
633 if ((irun + 1) % 16 == 0 || irun == int(htemp.size() - 1)) {
634 ctmp->SetBatch(kTRUE);
635 ctmp->Print(psname.str().c_str());
636 ctmp->Clear("D");
637 }
638 irun++;
639 }
640
641 ctmp->Print(psname.str().c_str());
642 psname.str("");
643 psname << Form("%s.pdf]", namesfx.data());
644 ctmp->Print(psname.str().c_str());
645
646 outFile.close();
647
648 delete ctmp;
649}
650
651//----------------------------------------
652void CDCDedxValidationAlgorithm::fitGaussianWRange(TH1D*& temphist, std::string& status)
653{
654 double histmean = temphist->GetMean();
655 double histrms = temphist->GetRMS();
656 temphist->GetXaxis()->SetRangeUser(histmean - 5.0 * histrms, histmean + 5.0 * histrms);
657
658 int fs = temphist->Fit("gaus", "Q0");
659 if (fs != 0) {
660 B2INFO(Form("\tFit (round 1) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
661 status = "fitFailed";
662 return;
663 } else {
664 double mean = temphist->GetFunction("gaus")->GetParameter(1);
665 double width = temphist->GetFunction("gaus")->GetParameter(2);
666 temphist->GetXaxis()->SetRangeUser(mean - 5.0 * width, mean + 5.0 * width);
667 fs = temphist->Fit("gaus", "QR", "", mean - m_sigmaR * width, mean + m_sigmaR * width);
668 if (fs != 0) {
669 B2INFO(Form("\tFit (round 2) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
670 status = "fitFailed";
671 return;
672 } else {
673 temphist->GetXaxis()->SetRangeUser(mean - 5.0 * width, mean + 5.0 * width);
674 B2INFO(Form("\tFit for hist (%s) successful (status = %d)", temphist->GetName(), fs));
675 status = "fitOK";
676 }
677 }
678}
679
680void CDCDedxValidationAlgorithm::wireGain(std::vector<TH1D*>& hdedxhit)
681{
682
683 std::vector<double> vdedx_means;
684 std::vector<double> layermean(c_maxNSenseLayers);
685 std::vector<double> lgmean(c_maxNSenseLayers);
686
687 std::ofstream outFile, outFileLayer, outFileAvg, outFilebdwire;
688 outFile.open(Form("plots/wire/dedx_mean_gwire_%s.txt", m_suffix.data()));
689 outFilebdwire.open(Form("plots/wire/dedx_mean_badwire_%s.txt", m_suffix.data()));
690 outFileLayer.open(Form("plots/wire/dedx_mean_layer_%s.txt", m_suffix.data()));
691 outFileAvg.open(Form("plots/wire/dedx_mean_layer_avg_%s.txt", m_suffix.data()));
692
693 int activelayers = 0;
694 double layeravg = 0.0;
695
698
700
701 int jwire = -1;
702 for (unsigned int il = 0; il < c_maxNSenseLayers; ++il) {
703
704 int activewires = 0, goodwires = 0;
705 layermean[il] = 0.0;
706 lgmean[il] = 0.0;
707
708 for (unsigned int iw = 0; iw < cdcgeo.nWiresInLayer(il); ++iw) {
709 jwire++;
710
711 unsigned int minbin, maxbin;
712 wireg.getTruncatedBins(hdedxhit[jwire], minbin, maxbin);
713 hdedxhit[jwire]->SetTitle(Form("dedxhit-dist, wire: %d ;%d;%d", jwire, minbin, maxbin));
714
715 double dedxmean = wireg.getTruncationMean(hdedxhit[jwire], minbin, maxbin);
716 vdedx_means.push_back(dedxmean);
717
718 if (Badwire->getBadWireStatus(jwire) == kTRUE)
719 outFilebdwire << jwire << " " << dedxmean << std::endl;
720 else
721 outFile << jwire << " " << dedxmean << std::endl;
722
723 if (vdedx_means.at(jwire) > 0) {
724 layermean[il] += vdedx_means.at(jwire);
725 activewires++;
726 if (Badwire->getBadWireStatus(jwire) != kTRUE) {
727 lgmean[il] += vdedx_means.at(jwire);
728 goodwires++;
729 }
730 }
731 }
732
733 if (activewires > 0) layermean[il] /= activewires;
734 else layermean[il] = 1.0;
735
736 if (goodwires > 0) lgmean[il] /= goodwires;
737 else lgmean[il] = 1.0;
738
739 outFileLayer << il << " " << layermean[il] << " " << lgmean[il] << std::endl;
740
741 //calculate outer layer average for active layer
742 if (il >= 8 && layermean[il] > 0) {
743 layeravg += layermean[il];
744 activelayers++;
745 }
746 }
747
748 //normalisation of wiregains to get outergain ~1.0
749 if (activelayers > 0) layeravg /= activelayers;
750 outFileAvg << layeravg << std::endl;
751
752 outFile.close();
753 outFilebdwire.close();
754 outFileLayer.close();
755 outFileAvg.close();
756 printCanvasWire(hdedxhit, Form("plots/wire/dedx_vs_wire_%s", m_suffix.data()), vdedx_means);
757}
758
759void CDCDedxValidationAlgorithm::printCanvasWire(std::vector<TH1D*> temp, std::string namesfx,
760 const std::vector<double>& vdedx_mean)
761{
762 TCanvas* ctmp = new TCanvas("tmp", "tmp", 900, 900);
763 ctmp->Divide(4, 4);
764
765 std::stringstream psname;
766 psname << Form("%s.pdf[", namesfx.data());
767 ctmp->Print(psname.str().c_str());
768 psname.str("");
769 psname << Form("%s.pdf", namesfx.data());
770
771 for (unsigned int ip = 0; ip < c_nwireCDC; ip++) {
772 int minbin = std::stoi(temp[ip]->GetXaxis()->GetTitle());
773 int maxbin = std::stoi(temp[ip]->GetYaxis()->GetTitle());
774 temp[ip]->SetFillColor(kYellow - 9);
775 temp[ip]->SetTitle(Form("%s, #mu_{trunc} %0.03f;dedxhit;entries", temp[ip]->GetTitle(), vdedx_mean.at(ip)));
776
777 ctmp->cd(ip % 16 + 1);
778 gPad->cd();
779 temp[ip]->DrawCopy("hist");
780 TH1D* hdedxhitC = (TH1D*)temp[ip]->Clone(Form("%sC", temp[ip]->GetName()));
781 hdedxhitC->GetXaxis()->SetRange(minbin, maxbin);
782 hdedxhitC->SetFillColor(kAzure + 1);
783 hdedxhitC->DrawCopy("same histo");
784
785 if ((ip + 1) % 16 == 0) {
786 ctmp->SetBatch(kTRUE);
787 ctmp->Print(psname.str().c_str());
788 ctmp->Clear("D");
789 }
790 delete temp[ip];
791 delete hdedxhitC;
792
793 }
794
795 psname.str("");
796 psname << Form("%s.pdf]", namesfx.data());
797 ctmp->Print(psname.str().c_str());
798 delete ctmp;
799}
800
801void CDCDedxValidationAlgorithm::defineTimeBins(std::vector<double>& vtlocaledges)
802{
803 double fixedges[69];
804 for (int ib = 0; ib < 69; ib++) {
805 fixedges[ib] = ib * 0.5 * 1e3;
806 if (ib > 40 && ib <= 60) fixedges[ib] = fixedges[ib - 1] + 1.0 * 1e3;
807 else if (ib > 60 && ib <= 64) fixedges[ib] = fixedges[ib - 1] + 10.0 * 1e3;
808 else if (ib > 64 && ib <= 65) fixedges[ib] = fixedges[ib - 1] + 420.0 * 1e3;
809 else if (ib > 65 && ib <= 66) fixedges[ib] = fixedges[ib - 1] + 500.0 * 1e3;
810 else if (ib > 66) fixedges[ib] = fixedges[ib - 1] + 2e6;
811 vtlocaledges.push_back(fixedges[ib]);
812 }
813}
814
815//--------------------------
817{
818
819 TCanvas cstats("cstats", "cstats", 800, 400);
820 cstats.SetBatch(kTRUE);
821 cstats.Divide(2, 1);
822
823 cstats.cd(1);
824 auto hestats = getObjectPtr<TH1I>("hestats");
825 if (hestats) {
826 hestats->SetName(Form("hestats_%s", m_suffix.data()));
827 hestats->SetStats(0);
828 hestats->DrawCopy("");
829 }
830
831 cstats.cd(2);
832 auto htstats = getObjectPtr<TH1I>("htstats");
833 if (htstats) {
834 htstats->SetName(Form("htstats_%s", m_suffix.data()));
835 htstats->SetStats(0);
836 htstats->DrawCopy("");
837 }
838
839 cstats.Print(Form("cdcdedx_stats_%s.pdf", m_suffix.data()));
840}
841
842void CDCDedxValidationAlgorithm::DatabaseIN(int experiment, int run)
843{
844 if (m_EventMetaData.isValid()) {
845 m_EventMetaData->setExperiment(experiment);
846 m_EventMetaData->setRun(run);
847 }
848
849 auto& dbConfiguration = Conditions::Configuration::getInstance();
850 dbConfiguration.overrideGlobalTags();
851 dbConfiguration.setGlobalTags({"online"});
852 if (!m_testingPayloadName.empty() && m_GlobalTagName.empty()) {
853 dbConfiguration.prependTestingPayloadLocation(m_testingPayloadName);
854 } else if (m_testingPayloadName.empty() && !m_GlobalTagName.empty()) {
855 dbConfiguration.prependGlobalTag(m_GlobalTagName);
856 } else
857 B2FATAL("Setting both testing payload and Global Tag or setting no one of them.");
858
859 /* Mimic a module initialization. */
861 m_EventMetaData.registerInDataStore();
863 if (!m_EventMetaData.isValid())
864 m_EventMetaData.construct(1, run, experiment);
865
866 /* Database instance and configuration. */
867 DBStore& dbStore = DBStore::Instance();
868 dbStore.update();
869 dbStore.updateEvent();
870}
871
873{
874
875 DatabaseIN(experiment, run);
876
877 std::vector<double> wiregain;
878 std::vector<double> layermean(c_maxNSenseLayers);
879
880 DBObjPtr<CDCDedxWireGain> DBWireGains;
881 if (!DBWireGains.isValid()) B2FATAL("Wire gain data are not valid.");
882
884
885 int jwire = -1;
886 for (unsigned int il = 0; il < c_maxNSenseLayers; ++il) {
887
888 int activewires = 0;
889 layermean[il] = 0.0;
890
891 for (unsigned int iw = 0; iw < cdcgeo.nWiresInLayer(il); ++iw) {
892 jwire++;
893
894 wiregain.push_back(DBWireGains->getWireGain(jwire));
895
896 if (wiregain.at(jwire) > 0) {
897 layermean[il] += wiregain.at(jwire);
898 activewires++;
899 }
900 }
901
902 if (activewires > 0) layermean[il] /= activewires;
903 else layermean[il] = 1.0;
904 }
905
907 return { wiregain, layermean };
908}
909
911{
912
913 DatabaseIN(experiment, run);
914
915 std::vector<double> cosgain, cos;
916
917 DBObjPtr<CDCDedxCosineCor> DBCosineCor;
918 if (!DBCosineCor.isValid()) B2FATAL("Cosine gain data are not valid.");
919
920 unsigned int nCosBins = DBCosineCor->getSize();
921
922 for (unsigned int il = 0; il < nCosBins; ++il) {
923 double costh = -1.0 + (il + 0.5) * 2.0 / nCosBins;
924 costh += .000001;
925 cosgain.push_back(DBCosineCor->getMean(il));
926 cos.push_back(costh);
927 }
928
930 return {cosgain, cos};
931}
932
934{
935
936 DatabaseIN(experiment, run);
937
938 std::vector<double> inner1D, outer1D, Enta;
939
940 DBObjPtr<CDCDedx1DCell> DBOneDCell;
941 if (!DBOneDCell.isValid()) B2FATAL("OneD cell gain data are not valid.");
942
943 for (int i = 0; i < 2; i++) {
944
945 unsigned int nBins = DBOneDCell->getNBins(i);
946 double binSize = TMath::Pi() / nBins;
947
948 for (unsigned int nbin = 0; nbin < nBins; nbin++) {
949
950 double enta = (-1 * TMath::Pi() / 2.0) + binSize * nbin;
951 if (i == 0) {
952 Enta.push_back(enta);
953 inner1D.push_back(DBOneDCell->getMean(0, nbin));
954 } else
955 outer1D.push_back(DBOneDCell->getMean(17, nbin));
956 }
957 }
959 return {inner1D, outer1D, Enta};
960
961}
962
963double CDCDedxValidationAlgorithm::getrungain(int experiment, int run)
964{
965
966 DatabaseIN(experiment, run);
967
969 if (!RunGain.isValid()) B2FATAL("Run gain data are not valid.");
970 double gain = RunGain->getRunGain();
971 return gain;
972}
973
975{
976 /* Reset both DataStore and Database. */
978 Database::Instance().reset(false);
979 DBStore::Instance().reset(false);
980}
void bhabhaValidation()
Validate dE/dx using bhabha sample (vs run, cosine)
double m_eaMax
upper edge of entrance angle
void resetDatabase()
Clear current DB pointers and state.
void wireGain(std::vector< TH1D * > &hdedxhit)
Validate wire gain data using dE/dx histograms.
void printCanvasdEdx(std::array< std::vector< TH1D * >, 2 > &htemp, std::string namesfx, std::string svar)
Draw dE/dx histograms for momentum and cosine bins.
void printCanvasRun(std::map< int, TH1D * > &htemp, std::string namesfx)
Draw dE/dx per run histogram canvas.
void radeeValidation()
Validate dE/dx using radee sample (vs momentum, injection time)
double m_sigmaR
fit dedx dist in sigma range
void setTextCosmetics(TPaveText pt, Color_t color)
Set text cosmetics for TPaveText.
WireGainData getwiregain(int experiment, int run)
Retrieve wire gain data from DB.
void getExpRunInfo()
function to get extract calibration run/exp
OnedData getonedgain(int experiment, int run)
Retrieve 1D gain data from DB.
double * m_tedges
internal time array (copy of vtlocaledges)
void DatabaseIN(int experiment, int run)
Load database payload for given run.
void defineTimeBins(std::vector< double > &vtlocaledges)
Set bin edges for injection time.
std::array< std::string, 2 > m_sring
injection ring name
CosGainData getcosgain(int experiment, int run)
Retrieve cosine gain data from DB.
void printCanvasWire(std::vector< TH1D * > temp, std::string namesfx, const std::vector< double > &vdedx_mean)
Plot dE/dx vs wire number.
std::string m_testingPayloadName
Testing payload location.
std::string m_suffix
suffix string to separate plots
DBObjPtr< CDCGeometry > m_cdcGeo
Geometry of CDC.
CDCDedxValidationAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
double getrungain(int experiment, int run)
Retrieve run gain data from DB.
void fitGaussianWRange(TH1D *&temphist, std::string &status)
Perform Gaussian fit with range on a histogram.
void plotEventStats()
Plot summary statistics of selected events.
virtual EResult calibrate() override
Main calibration method.
void printCanvas(std::vector< TH1D * > &htemp, std::string namesfx, std::string svar)
Draw dE/dx histograms across bins.
DBObjPtr< CDCDedxInjectionTime > m_DBInjectTime
Injection time DB object.
StoreObjPtr< EventMetaData > m_EventMetaData
Event metadata.
void defineHisto(std::vector< TH1D * > &htemp, std::string var, std::string stype)
Define dE/dx histograms for plotting.
std::string getTimeBinLabel(const double &tedges, const int &it)
Get time bin label string.
void fit(TH1D *&hist, double &mean, double &meanErr, double &sigma, double &sigmaErr)
Perform full Gaussian fit and extract parameters.
double m_eaMin
lower edge of entrance angle
A calibration algorithm for CDC dE/dx wire gains.
void getTruncatedBins(TH1D *hdedxhit, unsigned int &binlow, unsigned int &binhigh)
function to get bins of truncation from histogram
double getTruncationMean(TH1D *hdedxhit, int binlow, int binhigh)
function to get mean of truncation from histogram
The Class for CDC Geometry Parameters.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
static void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
static Configuration & getInstance()
Get a reference to the instance which will be used when the Database is initialized.
bool isValid() const
Check whether a valid object was obtained from the database.
Class for accessing objects in the database.
Definition DBObjPtr.h:21
Singleton class to cache database objects.
Definition DBStore.h:31
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition DataStore.cc:85
std::shared_ptr< T > getObjectPtr(const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
Get calibration data object by name and list of runs, the Merge function will be called to generate t...
void reset(bool keepEntries=false)
Invalidate all payloads.
Definition DBStore.cc:175
static Database & Instance()
Instance of a singleton Database.
Definition Database.cc:41
static DBStore & Instance()
Instance of a singleton DBStore.
Definition DBStore.cc:26
void updateEvent()
Updates all intra-run dependent objects.
Definition DBStore.cc:140
void update()
Updates all objects that are outside their interval of validity.
Definition DBStore.cc:77
static void reset(bool keepConfig=false)
Reset the database instance.
Definition Database.cc:49
Abstract base class for different kinds of events.
Container for cosine gain data.
Container for 1D gain data.
Container for wire gain data.