22Int_t
GainMatchEnergy(TH1 *spec1, TH1 *spec2, std::vector<Double_t> &pars,
bool draw, UInt_t target, std::string outfn,
23 Double_t step, TCanvas *c1)
26 std::cout <<
"ERROR: parameter vector should have some size. use resize(n)." << std::endl;
29 if (step > 1 || step < 0) {
30 std::cout <<
"ERROR: step should be between 0 and 1" << std::endl;
34 c1 =
new TCanvas(
"gainmatchenergy",
"Gain Match: Energy", 1280, 720);
37 auto UpdateCanvas = [&]() {
41 gSystem->ProcessEvents();
52 TPad *padspec1 =
new TPad(
"padspec1",
"Spectrum 1", 0.0, 0.5, 0.6, 1.0);
55 TPad *padspec2 =
new TPad(
"padspec2",
"Spectrum 2", 0.0, 0.0, 0.6, 0.5);
58 TPad *padgraph =
new TPad(
"padgraph",
"Peak Correlation", 0.6, 0.3, 1.0, 1.0);
61 padgraph->SetLeftMargin(0.15);
62 TPad *padtext =
new TPad(
"padtext",
"Fit Results", 0.6, 0.0, 1.0, 0.3);
67 Double_t thresh1 = 0.05;
69 Double_t thresh2 = 0.05;
73 std::vector<Double_t> peaks1(target);
74 std::vector<Double_t> peaks2(target);
77 TGraph graph((nspec1 > nspec2) ? nspec2 : nspec1, peaks1.data(), peaks2.data());
78 graph.SetMarkerStyle(21);
79 graph.SetTitle(
"Peak positions");
80 graph.GetXaxis()->SetTitle(spec1->GetTitle());
81 graph.GetYaxis()->SetTitle(spec2->GetTitle());
84 while (nspec1 != target or nspec2 != target) {
85 if (nspec1 < target) {
87 }
else if (nspec1 > target) {
88 thresh1 *= (1 + step);
90 if (nspec2 < target) {
92 }
else if (nspec2 > target) {
93 thresh2 *= (1 + step);
94 thresh2 = (nspec2 > nspec1) ? thresh2 : (1 + step) * thresh2;
97 if (thresh1 < 0.002 || thresh2 < 0.002) {
98 std::cout <<
"hit threshold limit (0.002) on search, try lower target." << std::endl;
104 nspec1 = analyser.Search(spec1, nsigma1,
"nodraw", thresh1);
105 if (nspec1 != peaks1.size() || !steps) {
107 peaks1.insert(peaks1.begin(), analyser.GetPositionX(), analyser.GetPositionX() + nspec1);
108 std::sort(peaks1.begin(), peaks1.end());
112 nspec2 = analyser.Search(spec2, nsigma2,
"nodraw", thresh2);
113 if (nspec2 != peaks2.size() || !steps) {
115 peaks2.insert(peaks2.begin(), analyser.GetPositionX(), analyser.GetPositionX() + nspec2);
116 std::sort(peaks2.begin(), peaks2.end());
120 if (update || !steps) {
122 nspec1 = analyser.Search(spec1, nsigma1,
"", thresh1);
125 nspec2 = analyser.Search(spec2, nsigma2,
"", thresh2);
128 graph.DrawGraph((nspec1 > nspec2) ? nspec2 : nspec1, peaks1.data(), peaks2.data(),
"AP");
134 if (nspec1 != nspec2) {
135 std::cout <<
"num peaks found in spec1 != spec2 ... " << nspec1 <<
"!=" << nspec2 << std::endl;
141 auto MakeCalibration = [&pars, &padgraph, &spec1, &spec2](std::vector<double> uncal, std::vector<double> cal) {
143 auto maxn = uncal.size() > cal.size() ? uncal.size() : cal.size();
144 TGraph *calgr =
new TGraph(maxn, uncal.data(), cal.data());
146 TF1 *calfunc =
new TF1(
"cal", (
"pol" + std::to_string(pars.size() - 1)).c_str(), 0, 1.1 * uncal.back());
148 pars.assign(calfunc->GetParameters(), calfunc->GetParameters() + pars.size());
152 calgr->SetMarkerStyle(21);
153 calgr->SetTitle(
"Peak positions");
154 calgr->GetXaxis()->SetTitle(spec1->GetTitle());
155 calgr->GetYaxis()->SetTitle(spec2->GetTitle());
158 calfunc->Draw(
"SAME");
161 auto UpdateFitText = [&]() {
165 TPaveText *pavetext =
new TPaveText(0.1, 0.1, 0.9, 0.9);
166 pavetext->SetTextFont(53);
167 pavetext->SetTextSize(18);
168 std::stringstream
ss;
169 ss <<
"Polynomial order " << pars.size() - 1;
170 pavetext->AddText(
ss.str().c_str());
171 for (
size_t i = 0; i < pars.size(); ++i) {
173 ss <<
"p_{" << i <<
"} = " << pars[i];
174 pavetext->AddText(
ss.str().c_str());
179 MakeCalibration(peaks1, peaks2);
185 std::string input(
"");
187 std::cout << std::endl <<
"Proceed manually? [y/n] ";
188 std::getline(std::cin, input);
194 c1->SaveAs(outfn.c_str());
198 std::cout <<
"Please answer y or n" << std::endl;
202 auto PrintVector = [](std::vector<double> vec) {
204 std::cout << i <<
", ";
205 std::cout << std::endl;
209 std::vector<Double_t> accepted_uncal;
210 std::vector<std::unique_ptr<TH1>> accepted_uncal_hists;
212 std::vector<Double_t> accepted_cal;
213 std::vector<std::unique_ptr<TH1>> accepted_cal_hists;
221 for (
size_t n = 0; n < peaks1.size();) {
226 auto highlighter = std::unique_ptr<TH1>(
static_cast<TH1 *
>(spec1->Clone()));
227 highlighter->SetFillColor(kMagenta);
228 highlighter->GetXaxis()->SetRangeUser(X - window, X + window);
229 highlighter->Draw(
"SAME");
231 auto zoomed = std::unique_ptr<TH1>(
static_cast<TH1 *
>(spec1->Clone()));
232 zoomed->SetFillColor(kBlue);
233 zoomed->SetFillStyle(3001);
234 zoomed->GetXaxis()->SetRangeUser(X - 20 * window, X + 20 * window);
235 zoomed->Draw(
"SAME");
239 highlighter->Draw(
"SAME");
242 accepted_uncal_hists.push_back(std::unique_ptr<TH1>(
static_cast<TH1 *
>(spec1->Clone(
""))));
248 std::cout <<
"Accept peak at " << X <<
" [y/n/z/u/p] ";
249 std::getline(std::cin, input);
252 std::cout <<
"Raw Histogram: " << accepted_uncal.size() << std::endl;
253 PrintVector(accepted_uncal);
254 std::cout <<
" Calibrated: " << accepted_cal.size() << std::endl;
255 PrintVector(accepted_cal);
257 }
else if (input ==
"u") {
259 accepted_uncal.pop_back();
260 accepted_uncal_hists.pop_back();
261 accepted_uncal_hists.pop_back();
262 std::cout <<
"UNDO!" << std::endl;
266 }
else if (input ==
"z") {
270 highlighter->GetXaxis()->SetRangeUser(X - window, X + window);
271 zoomed->GetXaxis()->SetRangeUser(X - 15 * window, X + 15 * window);
273 highlighter->Draw(
"SAME");
275 }
else if (input ==
"y") {
276 accepted_uncal.push_back(X);
278 auto &accepted = accepted_uncal_hists.back();
279 accepted->SetFillColor(kGreen);
280 accepted->GetXaxis()->SetRangeUser(X - window, X + window);
281 accepted->Draw(
"SAME");
285 }
else if (input ==
"n") {
289 std::cout <<
"Please answer y or n" << std::endl;
300 for (
size_t n = 0; n < peaks2.size();) {
305 auto highlighter = std::unique_ptr<TH1>(
static_cast<TH1 *
>(spec2->Clone()));
306 highlighter->SetFillColor(kMagenta);
307 highlighter->GetXaxis()->SetRangeUser(X - window, X + window);
308 highlighter->Draw(
"SAME");
310 auto zoomed = std::unique_ptr<TH1>(
static_cast<TH1 *
>(spec2->Clone()));
311 zoomed->SetFillColor(kBlue);
312 zoomed->SetFillStyle(3001);
313 zoomed->GetXaxis()->SetRangeUser(X - 20 * window, X + 20 * window);
314 zoomed->Draw(
"SAME");
318 highlighter->Draw(
"SAME");
321 accepted_cal_hists.push_back(std::unique_ptr<TH1>(
static_cast<TH1 *
>(spec2->Clone(
""))));
326 std::cout <<
"Accept peak at " << X <<
" [y/n/z/u/p] ";
327 std::getline(std::cin, input);
330 std::cout <<
"Raw Histogram: " << accepted_uncal.size() << std::endl;
331 PrintVector(accepted_uncal);
332 std::cout <<
" Calibrated: " << accepted_cal.size() << std::endl;
333 PrintVector(accepted_cal);
335 }
else if (input ==
"u") {
337 accepted_cal.pop_back();
338 accepted_cal_hists.pop_back();
339 accepted_cal_hists.pop_back();
340 std::cout <<
"UNDO!" << std::endl;
344 }
else if (input ==
"z") {
348 highlighter->GetXaxis()->SetRangeUser(X - window, X + window);
349 zoomed->GetXaxis()->SetRangeUser(X - 15 * window, X + 15 * window);
351 highlighter->Draw(
"SAME");
353 }
else if (input ==
"y") {
354 accepted_cal.push_back(X);
356 auto &accepted = accepted_cal_hists.back();
357 accepted->SetFillColor(kGreen);
358 accepted->GetXaxis()->SetRangeUser(X - window, X + window);
359 accepted->Draw(
"SAME");
363 }
else if (input ==
"n") {
367 std::cout <<
"Please answer y or n" << std::endl;
374 MakeCalibration(accepted_uncal, accepted_cal);
378 std::cout <<
"Raw Histogram: ";
379 PrintVector(accepted_uncal);
380 std::cout <<
" Calibrated: ";
381 PrintVector(accepted_cal);
383 std::cout << std::endl <<
"Restart? [y/n] ";
384 std::getline(std::cin, input);
388 else if (input ==
"n") {
390 c1->SaveAs(outfn.c_str());
397 c1->SaveAs(outfn.c_str());