3#if __cplusplus >= 201703L
9#include "TGTableLayout.h"
20TEfficiencyTab::TEfficiencyTab(TEfficiencyDatatypeTab* parent,
TNucleus* nucleus, std::tuple<TH1*, TH1*, TH2*> hists, TGCompositeFrame* frame)
21 : fFrame(frame), fNucleus(nucleus), fParent(parent),
22 fSingles(std::get<0>(hists)), fSummingOut(std::get<1>(hists)), fSummingIn(std::get<2>(hists))
26 std::cout <<
"Assigned singles, summing out, and summing in histograms (" << fSingles->GetName() <<
", " << fSummingOut->GetName() <<
", " << fSummingIn->GetName() <<
")" << std::endl;
31 std::cout <<
"======================================== Finding peaks in " << fSingles->GetName() <<
", " << fSummingOut->GetName() <<
", and " << fSummingIn->GetName() << std::endl;
36void TEfficiencyTab::BuildInterface()
39 fTopFrame =
new TGHorizontalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, 450);
40 fProjectionCanvas =
new TRootEmbeddedCanvas(
"ProjectionCanvas", fTopFrame, TEfficiencyCalibrator::WindowWidth() / 2, 400);
42 fTopFrame->AddFrame(fProjectionCanvas,
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandY | kLHintsExpandX, 2, 2, 2, 2));
44 fFrame->AddFrame(fTopFrame,
new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2));
46 fStatusBar =
new TGStatusBar(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, 50);
47 std::array<int, 5> parts = {35, 15, 20, 15, 15};
48 fStatusBar->SetParts(parts.data(), parts.size());
50 fFrame->AddFrame(fStatusBar,
new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2, 2, 2, 2));
51 if(TEfficiencyCalibrator::VerboseLevel() >
EVerbosity::kLoops) { std::cout <<
"Done with " << __PRETTY_FUNCTION__ << std::endl; }
54void TEfficiencyTab::FindPeaks()
59 std::cout << __PRETTY_FUNCTION__ << std::endl;
60 std::cout <<
"Using parent " << fParent <<
" and transition list " << fNucleus->GetTransitionListByEnergy() << std::endl;
61 fNucleus->GetTransitionListByEnergy()->Print();
62 std::cout <<
"Using parent " << fParent << std::flush <<
", trying to get peak type " << TEfficiencyCalibrator::PeakType() << std::endl;
64 fProjectionCanvas->GetCanvas()->cd();
69 for(
int t = 0; t < fNucleus->GetTransitionListByEnergy()->GetSize(); ++t) {
70 auto* transition =
static_cast<TTransition*
>(fNucleus->GetTransitionListByEnergy()->At(t));
72 if(energy > fSingles->GetXaxis()->GetXmax()) {
74 std::cout <<
"Skipping peak at " << energy <<
" keV of " << fNucleus->GetA() << fNucleus->GetSymbol() <<
", maximum range of histogram is " << fSingles->GetXaxis()->GetXmax() << std::endl;
78 std::cout <<
"Fitting peak at " << energy <<
" keV, using range " << energy - TEfficiencyCalibrator::Range() <<
", " << energy + TEfficiencyCalibrator::Range() <<
" peak type " << TEfficiencyCalibrator::PeakType() <<
" singles histogram " << fSingles->GetName() << std::endl;
80 fPeakFitter.RemoveAllPeaks();
81 fPeakFitter.ResetInitFlag();
82 fSummingOutPeakFitter.RemoveAllPeaks();
83 fSummingOutPeakFitter.ResetInitFlag();
85 std::vector<TSinglePeak*> peaks;
86 peaks.push_back(NewPeak(energy));
87 double lastEnergy = energy;
88 for(
int t2 = t + 1; t2 < fNucleus->GetTransitionListByEnergy()->GetSize(); ++t2) {
89 auto* transition2 =
static_cast<TTransition*
>(fNucleus->GetTransitionListByEnergy()->At(t2));
91 if(lastEnergy + TEfficiencyCalibrator::Range() > energy2 - TEfficiencyCalibrator::Range()) {
93 std::cout << t <<
". peak: Found " << peaks.size() <<
". overlapping peak for " << lastEnergy <<
", and " << energy2 <<
" with range " << TEfficiencyCalibrator::Range() << std::endl;
96 peaks.push_back(NewPeak(energy2));
102 std::cout << t <<
". peak: Found " << peaks.size() <<
". overlapping peaks, stopping here with " << lastEnergy <<
", and " << energy2 <<
" with range " << TEfficiencyCalibrator::Range() << std::endl;
108 fPeakFitter.SetRange(energy - TEfficiencyCalibrator::Range(), lastEnergy + TEfficiencyCalibrator::Range());
109 for(
auto& peak : peaks) {
110 fPeakFitter.AddPeak(peak);
112 std::cout <<
"---------------------------------------- Fitting peak(s) at " << energy <<
"/" << lastEnergy <<
" from " << energy - TEfficiencyCalibrator::Range() <<
" to " << energy + TEfficiencyCalibrator::Range() << std::endl;
114 fPeakFitter.PrintParameters();
115 fPeakFitter.Fit(fSingles,
"retryfit");
118 std::vector<TSinglePeak*> summingOutPeaks = peaks;
119 fSummingOutPeakFitter.SetRange(energy - TEfficiencyCalibrator::Range(), lastEnergy + TEfficiencyCalibrator::Range());
121 for(
auto& peak : summingOutPeaks) {
122 peak = NewPeak(peak);
123 fSummingOutPeakFitter.AddPeak(peak);
125 fSummingOutPeakFitter.Fit(fSummingOut,
"retryfit");
126 for(
size_t p = 0; p < peaks.size(); ++p) {
127 auto* peak = peaks[p];
129 std::cout <<
"================================================================================" << std::endl;
130 std::cout <<
"Got centroid " << peak->Centroid() <<
" +- " << peak->CentroidErr() <<
" (" << 100 * peak->CentroidErr() / peak->Centroid() <<
" %), area " << peak->Area() <<
" +- " << peak->AreaErr() <<
" (" << 100 * peak->AreaErr() / peak->Area() <<
" %), FWHM " << peak->FWHM() <<
", red. chi sq. " << peak->GetReducedChi2() << std::endl;
132 if(peak->Area() < TEfficiencyCalibrator::Threshold() || peak->CentroidErr() > peak->Centroid() || peak->AreaErr() > peak->Area() || std::isnan(peak->Centroid()) || std::isnan(peak->Area()) || std::isnan(peak->CentroidErr()) || std::isnan(peak->AreaErr())) {
134 std::cout <<
"Skipping peak at " << energy <<
" keV with centroid " << peak->Centroid() <<
" +- " << peak->CentroidErr() <<
" (" << 100 * peak->CentroidErr() / peak->Centroid() <<
" %), FWHM " << peak->FWHM() <<
", and area " << peak->Area() <<
" +- " << peak->AreaErr() <<
" (" << 100 * peak->AreaErr() / peak->Area() <<
" %)" << std::endl;
135 std::cout <<
"================================================================================" << std::endl;
137 fRemovedFitFunctions.push_back(fPeakFitter.GetFitFunction()->Clone(Form(
"removed_fit_%.1f", peak->Centroid())));
141 std::cout <<
"================================================================================" << std::endl;
144 fPeakFitter.GetFitFunction()->SetNpx(1000);
145 peak->GetPeakFunction()->SetNpx(1000);
146 double fwhm = peak->FWHM();
147 double centroid = peak->Centroid();
148 double centroidErr = peak->CentroidErr();
150 std::cout <<
"Got centroid " << centroid <<
" keV, FWHM " << fwhm <<
":" << std::endl;
153 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSingles->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
155 fSingles->Write(Form(
"%s_%.0fkeV", fSingles->GetName(), centroid), TObject::kOverwrite);
157 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSummingOut->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
159 fSummingOut->Write(Form(
"%s_%.0fkeV", fSummingOut->GetName(), centroid), TObject::kOverwrite);
161 fSummingInProj.push_back(fSummingIn->ProjectionY(Form(
"%s_%.0f_to_%.0f", fSummingIn->GetName(), centroid - fwhm / 2., centroid + fwhm / 2.), fSummingIn->GetXaxis()->FindBin(centroid - fwhm / 2.), fSummingIn->GetXaxis()->FindBin(centroid + fwhm / 2.)));
162 fSummingInProjBg.push_back(fSummingInProj.back()->ShowBackground(TEfficiencyCalibrator::BgParam()));
164 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSummingInProj.back()->GetName(), centroid) <<
"' and '" << Form(
"%s_%.0fkeV", fSummingInProjBg.back()->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
166 double summingIn = fSummingInProj.back()->Integral() - fSummingInProjBg.back()->Integral();
167 fSummingInProj.back()->Write(Form(
"%s_%.0fkeV", fSummingInProj.back()->GetName(), centroid), TObject::kOverwrite);
168 fSummingInProjBg.back()->Write(Form(
"%s_%.0fkeV", fSummingInProjBg.back()->GetName(), centroid), TObject::kOverwrite);
170 double summingOut = summingOutPeaks[p]->Area();
171 double correctedArea = peak->Area() - summingIn + summingOutPeaks[p]->AreaErr();
173 double correctedAreaErr = TMath::Sqrt(TMath::Power(peak->AreaErr(), 2) + summingIn + summingOut);
175 std::cout <<
"Got summingIn " << summingIn <<
", summingOut " << summingOut <<
", correctedArea " << correctedArea <<
" +- " << correctedAreaErr << std::endl;
177 fPeaks.emplace_back(transition, centroid, centroidErr, correctedArea, correctedAreaErr, peak->Area(), peak->AreaErr(), summingIn, summingOut);
178 fFitFunctions.push_back(fPeakFitter.GetFitFunction()->Clone(Form(
"fit_%.1f", centroid)));
184 std::cout <<
"Unsorted peak vector:";
185 for(
const auto& peak : fPeaks) { std::cout <<
" " << std::get<0>(peak)->GetEnergy(); }
186 std::cout << std::endl;
188 std::sort(fPeaks.begin(), fPeaks.end(), [](
const std::tuple<TTransition*, double, double, double, double, double, double, double, double>& lhs,
const std::tuple<TTransition*, double, double, double, double, double, double, double, double>& rhs) ->
bool { return std::get<0>(lhs)->GetEnergy() < std::get<0>(rhs)->GetEnergy(); });
190 std::cout <<
"Sorted peak vector:";
191 for(
auto& peak : fPeaks) { std::cout <<
" " << std::get<0>(peak)->GetEnergy(); }
192 std::cout << std::endl;
196TSinglePeak* TEfficiencyTab::NewPeak(
const double& energy)
198 switch(TEfficiencyCalibrator::PeakType()) {
209 return new TGauss(energy);
212 std::cerr <<
"Unknow peak type " << TEfficiencyCalibrator::PeakType() <<
", defaulting to TRWPeak!" << std::endl;
219 switch(TEfficiencyCalibrator::PeakType()) {
233 std::cerr <<
"Unknow peak type " << TEfficiencyCalibrator::PeakType() <<
", defaulting to TRWPeak!" << std::endl;
238void TEfficiencyTab::Redraw()
240 fProjectionCanvas->GetCanvas()->cd();
241 fSingles->GetListOfFunctions()->Clear();
242 for(
auto& fit : fFitFunctions) {
243 static_cast<TF1*
>(fit)->SetLineColor(2);
244 fSingles->GetListOfFunctions()->Add(fit);
246 if(TEfficiencyCalibrator::ShowRemovedFits()) {
247 for(
auto& fit : fRemovedFitFunctions) {
248 static_cast<TF1*
>(fit)->SetLineColor(15);
249 fSingles->GetListOfFunctions()->Add(fit);
253 fProjectionCanvas->GetCanvas()->Modified();
256void TEfficiencyTab::MakeConnections()
258 fProjectionCanvas->GetCanvas()->Connect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
"TEfficiencyTab",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
261void TEfficiencyTab::Disconnect()
263 fProjectionCanvas->GetCanvas()->Disconnect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
266void TEfficiencyTab::Status(Int_t, Int_t px, Int_t py, TObject* selected)
268 fStatusBar->SetText(selected->GetName(), 0);
269 fStatusBar->SetText(selected->GetObjectInfo(px, py), 1);
273TEfficiencyDatatypeTab::TEfficiencyDatatypeTab(TEfficiencyCalibrator* parent, std::vector<TNucleus*> nucleus, std::vector<std::tuple<TH1*, TH1*, TH2*>> hists, TGCompositeFrame* frame,
const std::string& dataType, TGHProgressBar* progressBar)
274 : fFrame(frame), fNucleus(std::move(nucleus)), fParent(parent), fDataType(dataType)
277 std::cout <<
"======================================== creating tab for data type " << dataType << std::endl;
280 fMainDirectory = gDirectory;
281 fSubDirectory = gDirectory->mkdir(dataType.c_str());
283 std::cout <<
"switching from gDirectory " << gDirectory->GetName() <<
" to sub directory " << fSubDirectory;
287 std::cout <<
" = " << fSubDirectory->GetName() <<
", main directory is " << fMainDirectory <<
" = " << (fMainDirectory == nullptr ?
"" : fMainDirectory->GetName()) << std::endl;
291 fLeftFrame =
new TGVerticalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, TEfficiencyCalibrator::WindowWidth() / 2);
293 fDataTab =
new TGTab(fLeftFrame, TEfficiencyCalibrator::WindowWidth() / 2, 500);
294 fEfficiencyTab.resize(hists.size(),
nullptr);
295 for(
size_t i = 0; i < hists.size(); ++i) {
296 if(TEfficiencyCalibrator::VerboseLevel() >
EVerbosity::kSubroutines) { std::cout << i <<
": Creating efficiency tab using " << fNucleus[i] <<
" = " << fNucleus[i]->GetName() <<
", " << std::get<0>(hists[i])->GetName() <<
", " << std::get<1>(hists[i])->GetName() <<
", " << std::get<2>(hists[i])->GetName() <<
", " << TEfficiencyCalibrator::Range() <<
", " << TEfficiencyCalibrator::Threshold() <<
", " << TEfficiencyCalibrator::BgParam() << std::endl; }
297 fEfficiencyTab[i] =
new TEfficiencyTab(
this, fNucleus[i], hists[i], fDataTab->AddTab(fNucleus[i]->GetName()));
298 progressBar->Increment(1);
301 fFittingParameterFrame =
new TGGroupFrame(fLeftFrame,
"Fitting Parameters", kHorizontalFrame);
302 fFittingParameterFrame->SetLayoutManager(
new TGTableLayout(fFittingParameterFrame, 2, 4,
false, 5));
303 fRangeLabel =
new TGLabel(fFittingParameterFrame,
"Range");
304 fRangeEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::Range(), 5, kRangeEntry, TGNumberFormat::EStyle::kNESRealTwo, TGNumberFormat::EAttribute::kNEAPositive);
305 fBgParamLabel =
new TGLabel(fFittingParameterFrame,
"BG Parameter");
306 fBgParamEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::BgParam(), 5, kBgParamEntry, TGNumberFormat::EStyle::kNESRealTwo, TGNumberFormat::EAttribute::kNEAPositive);
307 fThresholdLabel =
new TGLabel(fFittingParameterFrame,
"Threshold");
308 fThresholdEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::Threshold(), 5, kThresholdEntry, TGNumberFormat::EStyle::kNESRealThree, TGNumberFormat::EAttribute::kNEAPositive);
309 fPeakTypeBox =
new TGComboBox(fFittingParameterFrame, kPeakTypeBox);
310 fPeakTypeBox->AddEntry(
"Radware", TEfficiencyTab::EPeakType::kRWPeak);
311 fPeakTypeBox->AddEntry(
"Addback", TEfficiencyTab::EPeakType::kABPeak);
312 fPeakTypeBox->AddEntry(
"Addback3", TEfficiencyTab::EPeakType::kAB3Peak);
313 fPeakTypeBox->AddEntry(
"Gaussian", TEfficiencyTab::EPeakType::kGauss);
314 fPeakTypeBox->SetMinHeight(200);
315 fPeakTypeBox->Resize(100, TEfficiencyCalibrator::LineHeight());
316 fPeakTypeBox->Select(TEfficiencyCalibrator::PeakType());
317 fFittingControlGroup =
new TGHButtonGroup(fFittingParameterFrame,
"");
318 fRefitButton =
new TGTextButton(fFittingControlGroup,
"Refit this source");
319 fRefitAllButton =
new TGTextButton(fFittingControlGroup,
"Refit all sources");
321 fFittingParameterFrame->AddFrame(fRangeLabel,
new TGTableLayoutHints(0, 1, 0, 1));
322 fFittingParameterFrame->AddFrame(fRangeEntry,
new TGTableLayoutHints(1, 2, 0, 1));
323 fFittingParameterFrame->AddFrame(fBgParamLabel,
new TGTableLayoutHints(2, 3, 0, 1));
324 fFittingParameterFrame->AddFrame(fBgParamEntry,
new TGTableLayoutHints(3, 4, 0, 1));
325 fFittingParameterFrame->AddFrame(fThresholdLabel,
new TGTableLayoutHints(0, 1, 1, 2));
326 fFittingParameterFrame->AddFrame(fThresholdEntry,
new TGTableLayoutHints(1, 2, 1, 2));
327 fFittingParameterFrame->AddFrame(fPeakTypeBox,
new TGTableLayoutHints(2, 3, 1, 2));
328 fFittingParameterFrame->AddFrame(fFittingControlGroup,
new TGTableLayoutHints(3, 4, 1, 2));
330 fLeftFrame->AddFrame(fDataTab,
new TGLayoutHints(kLHintsTop | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
331 fLeftFrame->AddFrame(fFittingParameterFrame,
new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2, 2, 2, 2));
334 fRightFrame =
new TGVerticalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, TEfficiencyCalibrator::WindowWidth() / 2);
335 fEfficiencyCanvas =
new TRootEmbeddedCanvas(
"EfficiencyCanvas", fRightFrame, TEfficiencyCalibrator::WindowWidth() / 2, 450);
336 fStatusBar =
new TGStatusBar(fRightFrame, TEfficiencyCalibrator::WindowWidth() / 2, 50);
337 std::array<int, 2> parts = {35, 65};
338 fStatusBar->SetParts(parts.data(), parts.size());
339 fGraphParameterFrame =
new TGGroupFrame(fRightFrame,
"Graph Parameters", kHorizontalFrame);
340 fGraphParameterFrame->SetLayoutManager(
new TGTableLayout(fGraphParameterFrame, 3, 4,
false, 5));
341 fDegreeEntry =
new TGNumberEntry(fGraphParameterFrame, TEfficiencyCalibrator::Degree(), 2, kDegreeEntry, TGNumberFormat::EStyle::kNESInteger);
342 fDegreeLabel =
new TGLabel(fGraphParameterFrame,
"Type of efficiency curve");
343 fCalibrationUncertaintyLabel =
new TGLabel(fGraphParameterFrame,
"Calibration Uncertainty");
344 fCalibrationUncertaintyEntry =
new TGNumberEntry(fGraphParameterFrame, TEfficiencyCalibrator::CalibrationUncertainty(), 5, kCalibrationUncertaintyEntry, TGNumberFormat::EStyle::kNESRealOne, TGNumberFormat::EAttribute::kNEAPositive);
345 fPlotOptionFrame =
new TGGroupFrame(fGraphParameterFrame,
"Plot Selection", kHorizontalFrame);
346 fPlotOptionFrame->SetLayoutManager(
new TGTableLayout(fPlotOptionFrame, 2, 3,
false, 5));
347 fPlotEfficiencyCheck =
new TGCheckButton(fPlotOptionFrame,
"Efficiency", kPlotEfficiencyCheck);
348 fPlotEfficiencyCheck->SetState(kButtonDown);
349 fPlotUncorrEfficiencyCheck =
new TGCheckButton(fPlotOptionFrame,
"Uncorrected efficiency", kPlotUncorrEfficiencyCheck);
350 fPlotUncorrEfficiencyCheck->SetState(kButtonUp);
351 fPlotPeakAreaCheck =
new TGCheckButton(fPlotOptionFrame,
"Peak area", kPlotPeakAreaCheck);
352 fPlotPeakAreaCheck->SetState(kButtonUp);
353 fPlotSummingInCheck =
new TGCheckButton(fPlotOptionFrame,
"Summing in", kPlotSummingInCheck);
354 fPlotSummingInCheck->SetState(kButtonUp);
355 fPlotSummingOutCheck =
new TGCheckButton(fPlotOptionFrame,
"Summing out", kPlotSummingOutCheck);
356 fPlotSummingOutCheck->SetState(kButtonUp);
357 fPlotOptionFrame->AddFrame(fPlotEfficiencyCheck,
new TGTableLayoutHints(0, 1, 0, 1));
358 fPlotOptionFrame->AddFrame(fPlotUncorrEfficiencyCheck,
new TGTableLayoutHints(1, 3, 0, 1));
359 fPlotOptionFrame->AddFrame(fPlotPeakAreaCheck,
new TGTableLayoutHints(0, 1, 1, 2));
360 fPlotOptionFrame->AddFrame(fPlotSummingInCheck,
new TGTableLayoutHints(1, 2, 1, 2));
361 fPlotOptionFrame->AddFrame(fPlotSummingOutCheck,
new TGTableLayoutHints(2, 3, 1, 2));
362 fRecalculateButton =
new TGTextButton(fGraphParameterFrame,
"Recalculate graphs");
363 fGraphParameterFrame->AddFrame(fDegreeLabel,
new TGTableLayoutHints(0, 1, 0, 1));
364 fGraphParameterFrame->AddFrame(fDegreeEntry,
new TGTableLayoutHints(1, 2, 0, 1));
365 fGraphParameterFrame->AddFrame(fCalibrationUncertaintyLabel,
new TGTableLayoutHints(0, 1, 1, 2));
366 fGraphParameterFrame->AddFrame(fCalibrationUncertaintyEntry,
new TGTableLayoutHints(1, 2, 1, 2));
367 fGraphParameterFrame->AddFrame(fPlotOptionFrame,
new TGTableLayoutHints(2, 4, 0, 2));
368 fGraphParameterFrame->AddFrame(fRecalculateButton,
new TGTableLayoutHints(0, 4, 2, 3));
369 fRightFrame->AddFrame(fEfficiencyCanvas,
new TGLayoutHints(kLHintsExpandX));
370 fRightFrame->AddFrame(fStatusBar,
new TGLayoutHints(kLHintsExpandX));
371 fRightFrame->AddFrame(fGraphParameterFrame,
new TGLayoutHints(kLHintsExpandX));
373 fFrame->SetLayoutManager(
new TGHorizontalLayout(fFrame));
374 fFrame->AddFrame(fLeftFrame,
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandY, 2, 2, 2, 2));
375 fFrame->AddFrame(fRightFrame,
new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandY, 2, 2, 2, 2));
379 std::cout <<
"switching from sub directory " << gDirectory->GetName() <<
" to main directory " << fMainDirectory;
381 fMainDirectory->cd();
383 std::cout <<
" = " << fMainDirectory->GetName() <<
", sub directory is " << fSubDirectory <<
" = " << (fSubDirectory ==
nullptr ?
"" : fSubDirectory->GetName()) << std::endl;
386 std::cout <<
"======================================== done creating tab for data type " << dataType << std::endl;
390TEfficiencyDatatypeTab::~TEfficiencyDatatypeTab()
392 fMainDirectory->cd();
395void TEfficiencyDatatypeTab::MakeConnections()
397 fFittingControlGroup->Connect(
"Clicked(Int_t)",
"TEfficiencyDatatypeTab",
this,
"FittingControl(Int_t)");
398 fPlotEfficiencyCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
399 fPlotUncorrEfficiencyCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
400 fPlotPeakAreaCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
401 fPlotSummingInCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
402 fPlotSummingOutCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
403 fRecalculateButton->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
404 fEfficiencyCanvas->GetCanvas()->Connect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
"TEfficiencyDatatypeTab",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
405 for(
auto& tab : fEfficiencyTab) {
406 tab->MakeConnections();
408 fPeakTypeBox->Connect(
"Selected(Int_t)",
"TEfficiencyDatatypeTab",
this,
"UpdatePeakType()");
411void TEfficiencyDatatypeTab::Disconnect()
413 fFittingControlGroup->Disconnect(
"Clicked(Int_t)",
this,
"FittingControl(Int_t)");
414 fPlotEfficiencyCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
415 fPlotUncorrEfficiencyCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
416 fPlotPeakAreaCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
417 fPlotSummingInCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
418 fPlotSummingOutCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
419 fRecalculateButton->Disconnect(
"Clicked()",
this,
"DrawGraph()");
420 fEfficiencyCanvas->GetCanvas()->Disconnect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
421 for(
auto& tab : fEfficiencyTab) {
426void TEfficiencyDatatypeTab::Status(Int_t, Int_t px, Int_t py, TObject* selected)
428 fStatusBar->SetText(selected->GetName(), 0);
429 fStatusBar->SetText(selected->GetObjectInfo(px, py), 1);
432void TEfficiencyDatatypeTab::DrawGraph()
435 UpdateEfficiencyGraph();
437 if(fLegend ==
nullptr) {
438 fLegend =
new TLegend(0.8, 0.95 -
static_cast<double>(fNucleus.size()) * 0.05, 0.95, 0.95);
443 fEfficiencyCanvas->GetCanvas()->cd();
444 bool firstPlot =
true;
446 if(fPlotEfficiencyCheck->IsDown()) {
448 std::cout <<
"Drawing efficiency graph " << fEfficiencyGraph <<
":" << std::endl;
449 fEfficiencyGraph->Print(
"e");
451 for(
size_t g = 0; g < fEfficiencyGraph->NumberOfGraphs(); ++g) {
452 fEfficiencyGraph->SetColorStyle(g, color++);
454 fEfficiencyGraph->DrawCalibration(
"*", fLegend);
457 if(fPlotUncorrEfficiencyCheck->IsDown()) {
459 std::cout <<
"Drawing uncorrected efficiency graph " << fUncorrEfficiencyGraph <<
":" << std::endl;
460 fUncorrEfficiencyGraph->Print(
"e");
462 for(
size_t g = 0; g < fUncorrEfficiencyGraph->NumberOfGraphs(); ++g) {
463 fUncorrEfficiencyGraph->SetColorStyle(g, color++);
466 fUncorrEfficiencyGraph->DrawCalibration(
"*", fLegend);
468 fUncorrEfficiencyGraph->DrawCalibration(
"same*", fLegend);
472 if(fPlotPeakAreaCheck->IsDown()) {
474 fPeakAreaGraph->Print(
"");
476 for(
size_t g = 0; g < fPeakAreaGraph->NumberOfGraphs(); ++g) {
477 fPeakAreaGraph->SetColorStyle(g, color++);
480 fPeakAreaGraph->DrawCalibration(
"*", fLegend);
482 fPeakAreaGraph->DrawCalibration(
"same*", fLegend);
486 if(fPlotSummingInCheck->IsDown()) {
488 fSummingInGraph->Print(
"");
490 for(
size_t g = 0; g < fSummingInGraph->NumberOfGraphs(); ++g) {
491 fSummingInGraph->SetColorStyle(g, color++);
494 fSummingInGraph->DrawCalibration(
"*", fLegend);
496 fSummingInGraph->DrawCalibration(
"same*", fLegend);
500 if(fPlotSummingInCheck->IsDown()) {
502 fSummingOutGraph->Print(
"");
504 for(
size_t g = 0; g < fSummingOutGraph->NumberOfGraphs(); ++g) {
505 fSummingOutGraph->SetColorStyle(g, color++);
508 fSummingOutGraph->DrawCalibration(
"*", fLegend);
510 fSummingOutGraph->DrawCalibration(
"same*", fLegend);
515 fEfficiencyCanvas->GetCanvas()->Modified();
518void TEfficiencyDatatypeTab::UpdateEfficiencyGraph()
520 if(fMainDirectory ==
nullptr) {
521 std::cout <<
"No main directory open (" << fMainDirectory <<
"), sub directory is " << fSubDirectory <<
", gDirectory is " << gDirectory->GetName() << std::endl;
525 std::cout << __PRETTY_FUNCTION__ <<
": switching from gDirectory " << gDirectory->GetName() <<
" to main directory " << fMainDirectory <<
" = " << fMainDirectory->GetName() << std::endl;
527 fMainDirectory->cd();
539 delete fEfficiencyGraph;
541 delete fUncorrEfficiencyGraph;
543 delete fPeakAreaGraph;
545 delete fSummingInGraph;
547 delete fSummingOutGraph;
550 for(
auto& tab : fEfficiencyTab) {
553 auto peaks = tab->Peaks();
555 double centroid = 0.;
556 double centroidErr = 0.;
557 double correctedArea = 0.;
558 double correctedAreaErr = 0.;
559 double peakArea = 0.;
560 double peakAreaErr = 0.;
561 double summingIn = 0.;
562 double summingOut = 0.;
563 std::vector<double> energy;
564 std::vector<double> energyErr;
565 std::vector<double> efficiency;
566 std::vector<double> efficiencyErr;
567 std::vector<double> uncorrEfficiency;
568 std::vector<double> uncorrEfficiencyErr;
569 std::vector<double> peakAreaVec;
570 std::vector<double> peakAreaErrVec;
571 std::vector<double> summingInVec;
572 std::vector<double> summingOutVec;
574 for(
auto& peak : peaks) {
575 std::tie(transition, centroid, centroidErr, correctedArea, correctedAreaErr, peakArea, peakAreaErr, summingIn, summingOut) = peak;
576 if(std::abs(transition->
GetEnergy() - centroid) < transition->
GetEnergyUncertainty() + centroidErr + TEfficiencyCalibrator::CalibrationUncertainty()) {
577 energy.push_back(transition->
GetEnergy());
579 efficiency.push_back(correctedArea / transition->
GetIntensity());
581 uncorrEfficiency.push_back(peakArea / transition->
GetIntensity());
583 peakAreaVec.push_back(peakArea);
584 peakAreaErrVec.push_back(peakAreaErr);
585 summingInVec.push_back(summingIn);
586 summingOutVec.push_back(summingOut);
589 std::cout <<
"Rejecting centroid " << centroid <<
" +- " << centroidErr <<
" with area " << correctedArea <<
" +- " << correctedAreaErr <<
" for transition at " << transition->
GetEnergy() <<
" +- " << transition->
GetEnergyUncertainty() <<
" using calibration uncertainty " << TEfficiencyCalibrator::CalibrationUncertainty() <<
" (" << std::abs(transition->
GetEnergy() - centroid) <<
" >= " << transition->
GetEnergyUncertainty() + centroidErr + TEfficiencyCalibrator::CalibrationUncertainty() <<
")" << std::endl;
592 auto* effGraph =
new TGraphErrors(goodPeaks, energy.data(), efficiency.data(), energyErr.data(), efficiencyErr.data());
593 fEfficiencyGraph->Add(effGraph, tab->GetName());
594 auto* uncorrEffGraph =
new TGraphErrors(goodPeaks, energy.data(), uncorrEfficiency.data());
595 fUncorrEfficiencyGraph->Add(uncorrEffGraph, Form(
"%s uncorr. Eff.", tab->GetName()));
596 auto* peakAreaGraph =
new TGraphErrors(goodPeaks, energy.data(), peakAreaVec.data(), energyErr.data(), peakAreaErrVec.data());
597 fPeakAreaGraph->Add(peakAreaGraph, tab->GetName());
598 auto* summingInGraph =
new TGraphErrors(goodPeaks, energy.data(), summingInVec.data());
599 fSummingInGraph->Add(summingInGraph, Form(
"%s summing in", tab->GetName()));
600 auto* summingOutGraph =
new TGraphErrors(goodPeaks, energy.data(), summingOutVec.data());
601 fSummingOutGraph->Add(summingOutGraph, Form(
"%s summing out", tab->GetName()));
603 fEfficiencyGraph->Scale();
604 fUncorrEfficiencyGraph->Scale();
605 fEfficiencyGraph->SetAxisTitle(
"energy [keV];corrected efficiency [a.u.]");
606 fUncorrEfficiencyGraph->SetAxisTitle(
"energy [keV];uncorrected efficiency [a.u.]");
607 fPeakAreaGraph->SetAxisTitle(
"energy [keV];peak areas [a.u.]");
608 fSummingInGraph->SetAxisTitle(
"energy [keV];summing in corrections [a.u.]");
609 fSummingOutGraph->SetAxisTitle(
"energy [keV];summing out corrections [a.u.]");
610 fEfficiencyGraph->Write(Form(
"%s_efficiency", fDataType.c_str()), TObject::kOverwrite);
611 fUncorrEfficiencyGraph->Write(Form(
"%s_uncorr_efficiency", fDataType.c_str()), TObject::kOverwrite);
612 fPeakAreaGraph->Write(Form(
"%s_peak_area", fDataType.c_str()), TObject::kOverwrite);
613 fSummingInGraph->Write(Form(
"%s_summing_in", fDataType.c_str()), TObject::kOverwrite);
614 fSummingOutGraph->Write(Form(
"%s_summing_out", fDataType.c_str()), TObject::kOverwrite);
615 fMainDirectory->cd();
618void TEfficiencyDatatypeTab::UpdatePeakType()
620 if(fPeakTypeBox ==
nullptr) {
621 throw std::runtime_error(
"Failed to find peak type box, but got a signal it was selected?");
624 std::cout <<
"peak type box " << fPeakTypeBox << std::flush <<
", getting selected " << fPeakTypeBox->GetSelected() << std::endl;
627 TEfficiencyCalibrator::PeakType(
static_cast<TEfficiencyTab::EPeakType
>(fPeakTypeBox->GetSelected()));
630int TEfficiencyDatatypeTab::Degree()
632 if(fDegreeEntry !=
nullptr) {
633 TEfficiencyCalibrator::Degree(
static_cast<int>(fDegreeEntry->GetNumber()));
635 return TEfficiencyCalibrator::Degree();
644double TEfficiencyDatatypeTab::EfficiencyDebertin(
double* x,
double* par)
646 double eff = par[0] * TMath::Log(x[0]) + par[1] * TMath::Log(x[0]) / x[0] + par[2] * TMath::Power(TMath::Log(x[0]) / x[0], 2) + par[3] * TMath::Power(TMath::Log(x[0]) / x[0], 4) + par[4] * TMath::Power(TMath::Log(x[0]) / x[0], 5);
650double TEfficiencyDatatypeTab::EfficiencyRadware(
double* x,
double* par)
652 double logX = TMath::Log(x[0] / 100.);
653 double logY = TMath::Log(x[0] / 1000.);
654 double logEff = TMath::Power(par[0] + par[1] * logX + par[2] * logX * logX, -par[6]) + TMath::Power(par[3] + par[4] * logY + par[5] * logY * logY, -1. / par[6]);
655 return TMath::Exp(logEff);
658double TEfficiencyDatatypeTab::EfficiencyPolynomial(
double* x,
double* par)
662 for(
int i = 0; i < par[0]; ++i) {
663 logEff += par[i + 1] * TMath::Power(TMath::Log(x[0]), i);
665 return TMath::Exp(logEff);
668void TEfficiencyDatatypeTab::FitEfficiency()
673 switch(TEfficiencyCalibrator::Degree()) {
675 fEfficiency =
new TF1(
"EfficiencyDebertin", TEfficiencyDatatypeTab::EfficiencyDebertin, 0., 10000., 5);
678 fEfficiency =
new TF1(
"EfficiencyRadware", TEfficiencyDatatypeTab::EfficiencyRadware, 0., 10000., 7);
681 fEfficiency =
new TF1(
"EfficiencyPolynomial", TEfficiencyDatatypeTab::EfficiencyPolynomial, 0., 10000., TEfficiencyCalibrator::Degree() + 1);
682 fEfficiency->FixParameter(0, TEfficiencyCalibrator::Degree());
686 fEfficiencyGraph->Fit(fEfficiency);
689void TEfficiencyDatatypeTab::FittingControl(Int_t
id)
691 int currentTabId = fDataTab->GetCurrent();
692 if(TEfficiencyCalibrator::VerboseLevel() >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": id " <<
id <<
", current tab id " << currentTabId << std::endl; }
696 fEfficiencyTab[currentTabId]->FindPeaks();
697 UpdateEfficiencyGraph();
700 for(
auto& tab : fEfficiencyTab) {
703 UpdateEfficiencyGraph();
710void TEfficiencyDatatypeTab::ReadValues()
712 TEfficiencyCalibrator::Range(fRangeEntry->GetNumber());
713 TEfficiencyCalibrator::Threshold(fThresholdEntry->GetNumber());
714 TEfficiencyCalibrator::BgParam(fBgParamEntry->GetNumberEntry()->GetIntNumber());
715 TEfficiencyCalibrator::Degree(fDegreeEntry->GetNumberEntry()->GetIntNumber());
716 TEfficiencyCalibrator::CalibrationUncertainty(fCalibrationUncertaintyEntry->GetNumber());
722double TEfficiencyCalibrator::fRange = 20.;
723double TEfficiencyCalibrator::fThreshold = 100.;
724int TEfficiencyCalibrator::fBgParam = 20;
725TEfficiencyTab::EPeakType TEfficiencyCalibrator::fPeakType = TEfficiencyTab::EPeakType::kRWPeak;
726int TEfficiencyCalibrator::fDegree = 0;
727double TEfficiencyCalibrator::fCalibrationUncertainty = 1.;
728bool TEfficiencyCalibrator::fShowRemovedFits =
false;
730unsigned int TEfficiencyCalibrator::fLineHeight = 20;
731unsigned int TEfficiencyCalibrator::fWindowWidth = 1200;
733TEfficiencyCalibrator::TEfficiencyCalibrator(
int n...)
734 : TGMainFrame(nullptr, TEfficiencyCalibrator::WindowWidth() + 10, TEfficiencyCalibrator::WindowWidth() / 2)
737 std::remove(
"fitOutput.txt");
742 fHistograms.resize(5);
743 fDataType = {
"Unsuppressed Singles",
"Suppressed Singles",
"Unsuppressed Addback",
"Suppressed Addback",
"Single Crystal"};
747 bool allSourcesFound =
true;
748 for(
int i = 0; i < n; ++i) {
749 const char* name = va_arg(args,
const char*);
750 fFiles.push_back(
new TFile(name));
751 if(!fFiles.back()->IsOpen()) {
752 std::cerr <<
"Failed to open " << i + 1 <<
". file \"" << name <<
"\"" << std::endl;
756 bool goodFile =
false;
758 std::cout <<
"Checking file \"" << name <<
"\":";
760 if(fFiles.back()->FindKey(
"griffinE") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinEProj") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinESum") !=
nullptr) {
762 fHistograms[0].emplace_back(
763 static_cast<TH1*
>(fFiles.back()->Get(
"griffinE")),
764 static_cast<TH1*
>(fFiles.back()->Get(
"griffinGriffinEProj")),
765 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESum")));
768 std::cout <<
" found unsuppressed singles";
771 if(fFiles.back()->FindKey(
"griffinESupp") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinESuppProj") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinESuppSum") !=
nullptr) {
773 fHistograms[1].emplace_back(
774 static_cast<TH1*
>(fFiles.back()->Get(
"griffinESupp")),
775 static_cast<TH1*
>(fFiles.back()->Get(
"griffinGriffinESuppProj")),
776 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESuppSum")));
779 std::cout <<
" found suppressed singles";
782 if(fFiles.back()->FindKey(
"griffinEAddback") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinEAddbackProj") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinEAddbackSum") !=
nullptr) {
784 fHistograms[2].emplace_back(
785 static_cast<TH1*
>(fFiles.back()->Get(
"griffinEAddback")),
786 static_cast<TH1*
>(fFiles.back()->Get(
"griffinGriffinEAddbackProj")),
787 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEAddbackSum")));
790 std::cout <<
" found unsuppressed addback";
793 if(fFiles.back()->FindKey(
"griffinESuppAddback") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinESuppAddbackProj") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinESuppAddbackSum") !=
nullptr) {
795 fHistograms[3].emplace_back(
796 static_cast<TH1*
>(fFiles.back()->Get(
"griffinESuppAddback")),
797 static_cast<TH1*
>(fFiles.back()->Get(
"griffinGriffinESuppAddbackProj")),
798 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESuppAddbackSum")));
801 std::cout <<
" found suppressed addback";
804 if(fFiles.back()->FindKey(
"griffinESingleCrystal") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinESingleCrystalProj") !=
nullptr && fFiles.back()->FindKey(
"griffinGriffinESingleCrystalSum") !=
nullptr) {
806 fHistograms[4].emplace_back(
807 static_cast<TH1*
>(fFiles.back()->Get(
"griffinESingleCrystal")),
808 static_cast<TH1*
>(fFiles.back()->Get(
"griffinGriffinESingleCrystalProj")),
809 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESingleCrystalSum")));
812 std::cout <<
" found single crystal";
816 std::cout <<
": got " << fFiles.size() <<
" files, " << fHistograms[0].size() <<
" unsuppressed singles, " << fHistograms[1].size() <<
" suppressed singles, " << fHistograms[2].size() <<
" unsuppressed addback, " << fHistograms[3].size() <<
" suppressed addback" << std::endl;
819 std::cerr <<
"Failed to find any histogram in " << i + 1 <<
". file \"" << name <<
"\"" << std::endl;
823 fSources.push_back(
nullptr);
825 if(std::strstr(name,
"22Na") !=
nullptr) {
826 fSources.back() =
new TNucleus(
"22Na");
827 }
else if(std::strstr(name,
"56Co") !=
nullptr) {
828 fSources.back() =
new TNucleus(
"56Co");
829 }
else if(std::strstr(name,
"60Co") !=
nullptr) {
830 fSources.back() =
new TNucleus(
"60Co");
831 }
else if(std::strstr(name,
"133Ba") !=
nullptr) {
832 fSources.back() =
new TNucleus(
"133Ba");
833 }
else if(std::strstr(name,
"152Eu") !=
nullptr) {
834 fSources.back() =
new TNucleus(
"152Eu");
835 }
else if(std::strstr(name,
"241Am") !=
nullptr) {
836 fSources.back() =
new TNucleus(
"241Am");
838 allSourcesFound =
false;
844 auto type = fDataType.begin();
845 for(
auto it = fHistograms.begin(); it != fHistograms.end();) {
846 if(it->size() != fFiles.size()) {
848 std::cout << std::distance(fHistograms.begin(), it) <<
": found " << it->size() <<
" histograms for " << fFiles.size() <<
" files, removing this type" << std::endl;
850 it = fHistograms.erase(it);
851 type = fDataType.erase(type);
859 std::cout <<
"Read " << fFiles.size() <<
" files, got";
860 for(
auto& vec : fHistograms) {
861 std::cout <<
" " << vec.size();
863 std::cout <<
" histograms" << std::endl;
866 if(fHistograms.empty()) {
867 throw std::runtime_error(
"Unable to find any suitable histograms in the provided file(s)!");
871 if(fSources.size() != fFiles.size() || fHistograms[0].size() != fFiles.size() || fHistograms.size() != fDataType.size()) {
872 std::ostringstream error;
873 error <<
"Wrong sizes, from " << fFiles.size() <<
" file(s) we got " << fSources.size() <<
" source(s), and " << fHistograms[0].size() <<
" histogram(s), " << fDataType.size() <<
" data types, and " << fHistograms.size() <<
" data type histogram(s)!" << std::endl;
874 throw std::runtime_error(error.str());
877 fOutput =
new TFile(
"TEfficiencyCalibrator.root",
"recreate");
878 if(!fOutput->IsOpen()) {
879 throw std::runtime_error(
"Unable to open output file \"TEfficiencyCalibrator.root\"!");
883 if(!allSourcesFound) {
884 BuildFirstInterface();
885 MakeFirstConnections();
891 SetWindowName(
"EffiencyCalibrator");
897 Resize(GetDefaultSize());
905TEfficiencyCalibrator::~TEfficiencyCalibrator()
907 for(
auto& file : fFiles) {
910 if(fOutput !=
nullptr) { fOutput->Close(); }
913void TEfficiencyCalibrator::DeleteElement(TGFrame* element)
916 RemoveFrame(element);
921void TEfficiencyCalibrator::BuildFirstInterface()
925 auto* layoutManager =
new TGTableLayout(
this, fFiles.size() + 1, 2,
true, 5);
926 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout <<
"created table layout manager with 2 columns, " << fFiles.size() + 1 <<
" rows" << std::endl; }
927 SetLayoutManager(layoutManager);
931 for(i = 0; i < fFiles.size(); ++i) {
932 fSourceLabel.push_back(
new TGLabel(
this, fFiles[i]->GetName()));
933 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Text height " << fSourceLabel.back()->GetFont()->TextHeight() << std::endl; }
934 fSourceBox.push_back(
new TGComboBox(
this,
"Select source", kSourceBox + fSourceBox.size()));
935 if(fSources[i] !=
nullptr) {
936 fSourceBox.back()->AddEntry(fSources[i]->GetName(), i);
937 fSourceBox.back()->Select(0);
938 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Found source, setting entry to " << fSources[i]->GetName() <<
" and selecting " << fSourceBox.back()->GetSelected() << std::endl; }
940 fSourceBox.back()->AddEntry(
"22Na", k22Na);
941 fSourceBox.back()->AddEntry(
"56Co", k56Co);
942 fSourceBox.back()->AddEntry(
"60Co", k60Co);
943 fSourceBox.back()->AddEntry(
"133Ba", k133Ba);
944 fSourceBox.back()->AddEntry(
"152Eu", k152Eu);
945 fSourceBox.back()->AddEntry(
"241Am", k241Am);
946 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Didn't find source, created source box with " << fSourceBox.back()->GetNumberOfEntries() << std::endl; }
948 fSourceBox.back()->SetMinHeight(200);
949 fSourceBox.back()->Resize(100, LineHeight());
950 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Attaching " << i <<
". label to 0, 1, " << i <<
", " << i + 1 <<
", and box to 1, 2, " << i <<
", " << i + 1 << std::endl; }
951 AddFrame(fSourceLabel.back(),
new TGTableLayoutHints(0, 1, i, i + 1, kLHintsRight | kLHintsCenterY));
952 AddFrame(fSourceBox.back(),
new TGTableLayoutHints(1, 2, i, i + 1, kLHintsLeft | kLHintsCenterY));
956 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout <<
"Attaching start button to 0, 2, " << i <<
", " << i + 1 << std::endl; }
957 fStartButton =
new TGTextButton(
this,
"Accept && Continue", kStartButton);
959 AddFrame(fStartButton,
new TGTableLayoutHints(0, 2, i, i + 1, kLHintsCenterX | kLHintsCenterY));
963void TEfficiencyCalibrator::MakeFirstConnections()
968 for(
auto* box : fSourceBox) {
969 box->Connect(
"Selected(Int_t, Int_t)",
"TEfficiencyCalibrator",
this,
"SetSource(Int_t, Int_t)");
973 fStartButton->Connect(
"Clicked()",
"TEfficiencyCalibrator",
this,
"Start()");
976void TEfficiencyCalibrator::DisconnectFirst()
979 for(
auto* box : fSourceBox) {
980 box->Disconnect(
"Selected(Int_t, Int_t)",
this,
"SetSource(Int_t, Int_t)");
982 fStartButton->Disconnect(
"Clicked()",
this,
"Start()");
985void TEfficiencyCalibrator::DeleteFirst()
989 DeleteElement(fStartButton);
993void TEfficiencyCalibrator::SetSource(Int_t windowId, Int_t entryId)
995 int index = windowId - kSourceBox;
996 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": windowId " << windowId <<
", entryId " << entryId <<
" => " << index << std::endl; }
997 TNucleus* nucleus = fSources[index];
999 nucleus =
new TNucleus(fSourceBox[index]->GetListBox()->GetEntry(entryId)->GetTitle());
1000 fSources[index] = nucleus;
1003void TEfficiencyCalibrator::Start()
1005 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": fEmitter " << fEmitter <<
", fStartButton " << fStartButton << std::endl; }
1006 if(fEmitter ==
nullptr) {
1007 fEmitter = fStartButton;
1008 TTimer::SingleShot(100,
"TEfficiencyCalibrator",
this,
"HandleTimer()");
1012void TEfficiencyCalibrator::HandleTimer()
1014 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": fEmitter " << fEmitter <<
", fStartButton " << fStartButton << std::endl; }
1015 if(fEmitter == fStartButton) {
1025void TEfficiencyCalibrator::SecondWindow()
1029 for(
size_t i = 0; i < fSources.size(); ++i) {
1030 if(fSources[i] ==
nullptr) {
1031 std::cerr <<
"Source " << i <<
" not set!" << std::endl;
1035 std::cout << i <<
" - source " << fSources[i] <<
" = " << fSources[i]->GetName() << std::endl;
1039 for(
size_t i = 0; i < fSources.size(); ++i) {
1040 for(
size_t j = i + 1; j < fSources.size(); ++j) {
1041 if(*(fSources[i]) == *(fSources[j])) {
1042 std::cerr <<
"Duplicate sources: " << i <<
" - " << fSources[i]->GetName() <<
" and " << j <<
" - " << fSources[j]->GetName() << std::endl;
1048 SetLayoutManager(
new TGHorizontalLayout(
this));
1051 fProgressBar =
new TGHProgressBar(
this, TGProgressBar::kFancy, WindowWidth() / 2);
1052 int nofHistograms = 0;
1053 for(
auto& type : fHistograms) {
1054 nofHistograms += type.size();
1057 fProgressBar->SetRange(0.,
static_cast<Float_t
>(nofHistograms));
1058 fProgressBar->Percent(
true);
1059 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Set range of progress bar to 0. - " << fProgressBar->GetMax() <<
" = " << fFiles.size() << std::endl; }
1060 AddFrame(fProgressBar,
new TGLayoutHints(kLHintsCenterX | kLHintsCenterY | kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
1066 Resize(TGDimension(WindowWidth(), LineHeight()));
1073 BuildSecondInterface();
1074 MakeSecondConnections();
1077 DeleteElement(fProgressBar);
1083 Resize(TGDimension(WindowWidth(), WindowWidth() / 2));
1090void TEfficiencyCalibrator::BuildSecondInterface()
1092 SetLayoutManager(
new TGHorizontalLayout(
this));
1095 fDatatypeTab =
new TGTab(
this, WindowWidth(), WindowWidth() / 2);
1096 fEfficiencyDatatypeTab.resize(fHistograms.size());
1097 fEfficiencyGraph.resize(fHistograms.size());
1098 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout << __PRETTY_FUNCTION__ <<
" creating " << fHistograms.size() <<
" tabs" << std::endl; }
1099 for(
size_t i = 0; i < fHistograms.size(); ++i) {
1100 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout << i <<
": Creating efficiency source tab using " << fHistograms[i].size() <<
" histograms, and " << fSources.size() <<
" sources, " << fRange <<
", " << fThreshold <<
", " << fProgressBar << std::endl; }
1101 auto* frame = fDatatypeTab->AddTab(fDataType[i].c_str());
1102 std::replace(fDataType[i].begin(), fDataType[i].end(),
' ',
'_');
1103 fEfficiencyDatatypeTab[i] =
new TEfficiencyDatatypeTab(
this, fSources, fHistograms[i], frame, fDataType[i], fProgressBar);
1105 fEfficiencyGraph[i] = fEfficiencyDatatypeTab[i]->EfficiencyGraph();
1107 AddFrame(fDatatypeTab,
new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 0, 0, 0, 0));
1112void TEfficiencyCalibrator::MakeSecondConnections()
1116 for(
auto* sourceTab : fEfficiencyDatatypeTab) {
1117 sourceTab->MakeConnections();
1121void TEfficiencyCalibrator::DisconnectSecond()
1124 for(
auto* sourceTab : fEfficiencyDatatypeTab) {
1125 sourceTab->Disconnect();
void Draw(Option_t *opt="") override
double GetIntensityUncertainty() const
double GetIntensity() const
double GetEnergyUncertainty() const