86 c->Divide(fDetIds.size(), fDetIds.size());
87 c->SetTitle(
"Time Walk Calibration Graphs");
90 for (
auto &idi : fDetIds) {
91 for (
auto &idj : fDetIds) {
96 c->cd(i * fDetIds.size() + j + 1);
99 for (
auto &dataset : fReference) {
100 auto datafn = dataset.first;
102 fGraphs[datafn][{idi, idj}]->Draw(
"AP");
105 fGraphs[datafn][{idi, idj}]->Draw(
"P SAME");
115 std::vector<Bool_t> equation(fDetIds.size());
119 for (
auto &idi : fDetIds) {
120 for (
auto &idj : fDetIds) {
126 c->cd(i * fDetIds.size() + i + 1);
127 TPaveText *pavetext =
new TPaveText(0.1, 0.1, 0.9, 0.9);
128 pavetext->SetTextFont(53);
129 pavetext->SetTextSize(12);
130 pavetext->SetTextAlign(11);
131 std::stringstream
ss;
133 ss <<
"Detector " << idi;
134 pavetext->AddText(
ss.str().c_str());
136 ss <<
"a_{" << idi <<
"} = " << fFitResults[{idi, 0}];
137 pavetext->AddText(
ss.str().c_str());
139 ss <<
"b_{" << idi <<
"} = " << fFitResults[{idi, 1}];
140 pavetext->AddText(
ss.str().c_str());
142 ss <<
"f_{" << idi <<
"} = " << fFitResults[{idi, 2}];
143 pavetext->AddText(
ss.str().c_str());
147 c->cd(i * fDetIds.size() + j + 1);
149 for (
auto &dataset : fReference) {
152 fFits[{idi, idj}]->GetRange(xmin, xmax);
153 xmin = fFitResults[{idj, 1}];
154 xmin = xmin < 0 ? -1 * xmin : 0;
155 fFits[{idi, idj}]->SetRange(xmin + 0.1, xmax);
156 fFits[{idi, idj}]->SetLineColorAlpha(1, 0.8);
157 fFits[{idi, idj}]->SetLineWidth(1);
158 fFits[{idi, idj}]->SetParameter(6, dataset.second->GetEnergy());
159 fFits[{idi, idj}]->DrawCopy(
"SAME");
169 if (!saveas.empty()) {
170 c->SaveAs(saveas.c_str());
214 TH1::SetDefaultSumw2(kTRUE);
215 TCanvas *c1 =
new TCanvas(
"canvas",
"First Order Moment", 1280, 720);
218 std::vector<Double_t> energy, tdiff, energyerr, tdifferr;
221 auto mcmean = [](TH1 *h, TRandom3 &rnd) {
222 int low = h->GetXaxis()->FindBin(h->GetMean() - 5 * h->GetStdDev());
223 int high = h->GetXaxis()->FindBin(h->GetMean() + 5 * h->GetStdDev());
224 h->GetXaxis()->SetRange(low, high);
226 for (
int order = 2; order <= 3; ++order) {
227 low = h->GetXaxis()->FindBin(h->GetMean() - order * 5 * h->GetStdDev());
228 high = h->GetXaxis()->FindBin(h->GetMean() + order * 5 * h->GetStdDev());
229 h->GetXaxis()->SetRange(low, high);
231 for (
int x = low; x <= high; ++x) {
232 Double_t error = h->GetBinError(x);
233 Double_t count = h->GetBinContent(x);
234 h->SetBinContent(x, rnd.Gaus(count, error));
235 h->SetBinError(x, 0);
237 double mean = h->GetMean();
240 h->GetQuantiles(1, &median, &q);
241 return std::pair<double, double>(median, mean);
245 for (
const auto &dataset : fReference) {
246 auto &datafn = dataset.first;
247 auto &refpeak = dataset.second;
248 TFile datafile(datafn.c_str());
250 Double_t width_refpk = refpeak->GetGate()->GetWidth();
251 Double_t width_refbg = refpeak->GetGateBG()->GetWidth();
252 std::stringstream
ss;
255 for (
auto &i : fDetIds) {
256 for (
auto &j : fDetIds) {
264 std::string pairing(std::to_string(i) +
"_" + std::to_string(j));
266 datafile.GetObject((
"P" + pairing).c_str(), pkhist);
267 datafile.GetObject((
"B" + pairing).c_str(), bghist);
269 std::cout <<
"Generating data points for pairing " << i <<
" " << j << std::endl;
270 for (
auto &relative : fRelative[dataset.first]) {
271 auto &photon = relative.first;
272 auto &correc = relative.second;
274 ss << pairing <<
"_" <<
static_cast<int>(photon.GetEnergy());
276 TH1D *pp = photon.GetGate()->ApplyX(pkhist,
ss.str().c_str());
277 TH1D *
bp = photon.GetGate()->ApplyX(bghist,
"bg_pk");
278 TH1D *pb = photon.GetGateBG()->ApplyX(pkhist,
"pk_bg");
279 TH1D *bb = photon.GetGateBG()->ApplyX(bghist,
"bg_bg");
281 Double_t width_pk = photon.GetGate()->GetWidth();
282 Double_t width_bg = photon.GetGateBG()->GetWidth();
285 pp->Add(pb, -1 * width_refpk / width_bg);
286 pp->Add(
bp, -1 * width_refbg / width_pk);
287 pp->Add(bb, +2 * width_refbg / width_bg);
290 if (pp->Integral() < 15) {
296 energy.push_back(photon.GetEnergy());
297 energyerr.push_back(0);
304 tdiff.push_back(mcresult->GetMean(1) - correc);
305 tdifferr.push_back(mcresult->GetStdDev(1));
308 std::cout <<
"Energy:\t" << energy.back();
309 std::cout <<
"\tTime:\t" << tdiff.back() <<
" +/- " << tdifferr.back();
310 std::cout << std::endl;
315 fGraphs[datafn][{i, j}] = std::make_unique<TGraphErrors>(energy.size(), energy.data(), tdiff.data(),
316 energyerr.data(), tdifferr.data());
319 ss <<
"TCG_" << pairing;
320 fGraphs[datafn][{i, j}]->SetName((
ss.str() +
"_" + datafn).c_str());
323 ss <<
" Time Walk Calibration E_{" << i <<
"}=" << refpeak->GetEnergy() <<
" [keV]";
324 ss <<
";Gamma Energy, E_{" << j <<
"} [keV]";
325 ss <<
";$\\Delta t = t_{" << i <<
"} - t_{" << j <<
"}$ [ps]";
326 fGraphs[datafn][{i, j}]->SetTitle(
ss.str().c_str());
330 fGraphs[datafn][{i, j}]->SetLineColorAlpha((colour % 9) + 40, 0.9);
331 fGraphs[datafn][{i, j}]->SetLineWidth(1);
332 fGraphs[datafn][{i, j}]->SetMarkerColorAlpha((colour % 9) + 40, 0.9);
333 fGraphs[datafn][{i, j}]->SetMarkerColor(kOpenSquare);
334 fGraphs[datafn][{i, j}]->SetMarkerSize(2);
341 this->
Draw(c1, kFALSE);
391 Int_t npars = 3 * fDetIds.size();
392 auto gMinuit =
new TMinuit(npars);
395 gMinuit->SetFCN(func.
minuit);
397 Double_t arglist[10];
401 gMinuit->mnexcm(
"SET ERR", arglist, 1, ierflg);
403 gMinuit->mnexcm(
"SET STR", arglist, 1, ierflg);
406 std::stringstream
ss;
413 for (
auto &detid : fDetIds) {
416 gMinuit->mnparm(parnum,
ss.str(), 2500, 1, -1e4, 1e4, ierflg);
422 gMinuit->mnparm(parnum,
ss.str(), -10, 0.01, -1e4, 1e4, ierflg);
428 gMinuit->mnparm(parnum,
ss.str(), 0, 0.1, -1e3, 1e3, ierflg);
437 gMinuit->FixParameter(2);
442 gMinuit->mnexcm(
"MINIGRAD", arglist, 2, ierflg);
444 gMinuit->mnexcm(
"HESSE", arglist, 2, ierflg);
445 gMinuit->mnexcm(
"MINOS", arglist, 2, ierflg);
447 TCanvas *c1 =
new TCanvas(
"cTCAL",
"Time Walk Calibration Fit Results", 1280, 720);
448 this->
Draw(c1, kTRUE);
451 std::cout <<
"\nFit Results\n";
453 for (
size_t i = 0; i < fDetIds.size(); ++i) {
454 std::cout << std::endl <<
"Detector " << fDetIds[i] << std::endl;
456 gMinuit->GetParameter(i * 3 + 0, param, err);
457 fFitResults[{fDetIds[i], 0}] = param;
458 std::cout <<
"(([1]+x)-((" << param <<
"+(y*" << err <<
"))";
461 gMinuit->GetParameter(i * 3 + 1, param, err);
462 fFitResults[{fDetIds[i], 1}] = param;
463 std::cout <<
"/sqrt([0]+(" << param <<
"+(y*" << err <<
")))";
470 gMinuit->GetParameter(i * 3 + 2, param, err);
471 fFitResults[{fDetIds[i], 2}] = param;
472 std::cout <<
"+(" << param <<
"+(y*" << err <<
"))))";
473 std::cout << std::endl;
476 std::cout <<
"All Done" << std::endl;