3#if __cplusplus >= 201703L
9#include "TGTableLayout.h"
20TEfficiencyTab::TEfficiencyTab(TEfficiencyDatatypeTab* parent,
TNucleus* nucleus, std::tuple<TH1*, TH2*, 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();
66 std::cout <<
"Got peak type " << TEfficiencyCalibrator::PeakType() <<
", getting projection from " << fSummingOut->GetName() << std::endl;
68 fSummingOutTotalProj = fSummingOut->ProjectionY();
70 std::cout <<
"Writing '" << fSummingOutTotalProj->GetName() <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
72 fSummingOutTotalProj->Write(
nullptr, TObject::kOverwrite);
74 std::cout <<
"Got projection " << fSummingOutTotalProj <<
", getting background from " << fSummingOutTotalProj->GetName() << std::endl;
76 fSummingOutTotalProjBg = fSummingOutTotalProj->ShowBackground(TEfficiencyCalibrator::BgParam());
78 std::cout <<
"Writing '" << fSummingOutTotalProjBg->GetName() <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
80 fSummingOutTotalProjBg->Write(
nullptr, TObject::kOverwrite);
85 for(
int t = 0; t < fNucleus->GetTransitionListByEnergy()->GetSize(); ++t) {
86 auto* transition =
static_cast<TTransition*
>(fNucleus->GetTransitionListByEnergy()->At(t));
88 if(energy > fSingles->GetXaxis()->GetXmax()) {
90 std::cout <<
"Skipping peak at " << energy <<
" keV of " << fNucleus->GetA() << fNucleus->GetSymbol() <<
", maximum range of histogram is " << fSingles->GetXaxis()->GetXmax() << std::endl;
94 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;
96 fPeakFitter.RemoveAllPeaks();
97 fPeakFitter.ResetInitFlag();
99 std::vector<TSinglePeak*> peaks;
100 peaks.push_back(NewPeak(energy));
101 double lastEnergy = energy;
102 for(
int t2 = t + 1; t2 < fNucleus->GetTransitionListByEnergy()->GetSize(); ++t2) {
103 auto* transition2 =
static_cast<TTransition*
>(fNucleus->GetTransitionListByEnergy()->At(t2));
105 if(lastEnergy + TEfficiencyCalibrator::Range() > energy2 - TEfficiencyCalibrator::Range()) {
107 std::cout << t <<
". peak: Found " << peaks.size() <<
". overlapping peak for " << lastEnergy <<
", and " << energy2 <<
" with range " << TEfficiencyCalibrator::Range() << std::endl;
110 peaks.push_back(NewPeak(energy2));
112 lastEnergy = energy2;
116 std::cout << t <<
". peak: Found " << peaks.size() <<
". overlapping peaks, stopping here with " << lastEnergy <<
", and " << energy2 <<
" with range " << TEfficiencyCalibrator::Range() << std::endl;
122 fPeakFitter.SetRange(energy - TEfficiencyCalibrator::Range(), lastEnergy + TEfficiencyCalibrator::Range());
123 for(
auto& peak : peaks) {
124 fPeakFitter.AddPeak(peak);
126 std::cout <<
"---------------------------------------- Fitting peak(s) at " << energy <<
"/" << lastEnergy <<
" from " << energy - TEfficiencyCalibrator::Range() <<
" to " << energy + TEfficiencyCalibrator::Range() << std::endl;
128 fPeakFitter.PrintParameters();
129 fPeakFitter.Fit(fSingles,
"retryfit");
130 for(
auto& peak : peaks) {
132 std::cout <<
"================================================================================" << std::endl;
133 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;
135 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())) {
137 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;
138 std::cout <<
"================================================================================" << std::endl;
140 fRemovedFitFunctions.push_back(fPeakFitter.GetFitFunction()->Clone(Form(
"removed_fit_%.1f", peak->Centroid())));
144 std::cout <<
"================================================================================" << std::endl;
147 fPeakFitter.GetFitFunction()->SetNpx(1000);
148 peak->GetPeakFunction()->SetNpx(1000);
149 double fwhm = peak->FWHM();
150 double centroid = peak->Centroid();
151 double centroidErr = peak->CentroidErr();
153 std::cout <<
"Got centroid " << centroid <<
" keV, FWHM " << fwhm <<
":" << std::endl;
156 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSingles->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
158 fSingles->Write(Form(
"%s_%.0fkeV", fSingles->GetName(), centroid), TObject::kOverwrite);
160 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.)));
161 fSummingInProjBg.push_back(fSummingInProj.back()->ShowBackground(TEfficiencyCalibrator::BgParam()));
163 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSummingInProj.back()->GetName(), centroid) <<
"' and '" << Form(
"%s_%.0fkeV", fSummingInProjBg.back()->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
165 double summingIn = fSummingInProj.back()->Integral() - fSummingInProjBg.back()->Integral();
166 fSummingInProj.back()->Write(Form(
"%s_%.0fkeV", fSummingInProj.back()->GetName(), centroid), TObject::kOverwrite);
167 fSummingInProjBg.back()->Write(Form(
"%s_%.0fkeV", fSummingInProjBg.back()->GetName(), centroid), TObject::kOverwrite);
169 fSummingOutProj.push_back(fSummingOut->ProjectionY(Form(
"%s_%.0f_to_%.0f", fSummingOut->GetName(), centroid - fwhm / 2., centroid + fwhm / 2.), fSummingOut->GetXaxis()->FindBin(centroid - fwhm / 2.), fSummingOut->GetXaxis()->FindBin(centroid + fwhm / 2.)));
170 double ratio = fSummingOutTotalProjBg->Integral(fSummingOutTotalProjBg->GetXaxis()->FindBin(centroid - fwhm / 2.), fSummingOutTotalProjBg->GetXaxis()->FindBin(centroid + fwhm / 2.)) / fSummingOutTotalProjBg->Integral();
171 double summingOut = fSummingOutProj.back()->Integral() - fSummingOutTotalProj->Integral() * ratio;
173 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSummingOutProj.back()->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
175 fSummingOutProj.back()->Write(Form(
"%s_%.0fkeV", fSummingOutProj.back()->GetName(), centroid), TObject::kOverwrite);
176 auto*
hist =
static_cast<TH1*
>(fSummingOutProj.back()->Clone(Form(
"%s_subtracted_%.0f", fSummingOutProj.back()->GetName(), 1000000 * ratio)));
177 hist->Add(fSummingOutTotalProj, -ratio);
179 std::cout <<
"Writing '" <<
hist->GetName() <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
181 hist->Write(
nullptr, TObject::kOverwrite);
183 double correctedArea = peak->Area() - summingIn + summingOut;
185 double correctedAreaErr = TMath::Sqrt(TMath::Power(peak->AreaErr(), 2) + summingIn + summingOut);
187 std::cout <<
"Got summingIn " << summingIn <<
", ratio " << ratio <<
", summingOut " << summingOut <<
", correctedArea " << correctedArea <<
" +- " << correctedAreaErr << std::endl;
189 fPeaks.emplace_back(transition, centroid, centroidErr, correctedArea, correctedAreaErr, peak->Area(), peak->AreaErr(), summingIn, summingOut);
190 fFitFunctions.push_back(fPeakFitter.GetFitFunction()->Clone(Form(
"fit_%.1f", centroid)));
196 std::cout <<
"Unsorted peak vector:";
197 for(
const auto& peak : fPeaks) { std::cout <<
" " << std::get<0>(peak)->GetEnergy(); }
198 std::cout << std::endl;
200 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(); });
202 std::cout <<
"Sorted peak vector:";
203 for(
auto& peak : fPeaks) { std::cout <<
" " << std::get<0>(peak)->GetEnergy(); }
204 std::cout << std::endl;
208TSinglePeak* TEfficiencyTab::NewPeak(
const double& energy)
210 switch(TEfficiencyCalibrator::PeakType()) {
221 return new TGauss(energy);
224 std::cerr <<
"Unknow peak type " << TEfficiencyCalibrator::PeakType() <<
", defaulting to TRWPeak!" << std::endl;
229void TEfficiencyTab::Redraw()
231 fProjectionCanvas->GetCanvas()->cd();
232 fSingles->GetListOfFunctions()->Clear();
233 for(
auto& fit : fFitFunctions) {
234 static_cast<TF1*
>(fit)->SetLineColor(2);
235 fSingles->GetListOfFunctions()->Add(fit);
237 if(TEfficiencyCalibrator::ShowRemovedFits()) {
238 for(
auto& fit : fRemovedFitFunctions) {
239 static_cast<TF1*
>(fit)->SetLineColor(15);
240 fSingles->GetListOfFunctions()->Add(fit);
244 fProjectionCanvas->GetCanvas()->Modified();
247void TEfficiencyTab::MakeConnections()
249 fProjectionCanvas->GetCanvas()->Connect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
"TEfficiencyTab",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
252void TEfficiencyTab::Disconnect()
254 fProjectionCanvas->GetCanvas()->Disconnect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
257void TEfficiencyTab::Status(Int_t, Int_t px, Int_t py, TObject* selected)
259 fStatusBar->SetText(selected->GetName(), 0);
260 fStatusBar->SetText(selected->GetObjectInfo(px, py), 1);
264TEfficiencyDatatypeTab::TEfficiencyDatatypeTab(TEfficiencyCalibrator* parent, std::vector<TNucleus*> nucleus, std::vector<std::tuple<TH1*, TH2*, TH2*>> hists, TGCompositeFrame* frame,
const std::string& dataType, TGHProgressBar* progressBar)
265 : fFrame(frame), fNucleus(std::move(nucleus)), fParent(parent), fDataType(dataType)
268 std::cout <<
"======================================== creating tab for data type " << dataType << std::endl;
271 fMainDirectory = gDirectory;
272 fSubDirectory = gDirectory->mkdir(dataType.c_str());
274 std::cout <<
"switching from gDirectory " << gDirectory->GetName() <<
" to sub directory " << fSubDirectory;
278 std::cout <<
" = " << fSubDirectory->GetName() <<
", main directory is " << fMainDirectory <<
" = " << (fMainDirectory == nullptr ?
"" : fMainDirectory->GetName()) << std::endl;
282 fLeftFrame =
new TGVerticalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, TEfficiencyCalibrator::WindowWidth() / 2);
284 fDataTab =
new TGTab(fLeftFrame, TEfficiencyCalibrator::WindowWidth() / 2, 500);
285 fEfficiencyTab.resize(hists.size(),
nullptr);
286 for(
size_t i = 0; i < hists.size(); ++i) {
287 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; }
288 fEfficiencyTab[i] =
new TEfficiencyTab(
this, fNucleus[i], hists[i], fDataTab->AddTab(fNucleus[i]->GetName()));
289 progressBar->Increment(1);
292 fFittingParameterFrame =
new TGGroupFrame(fLeftFrame,
"Fitting Parameters", kHorizontalFrame);
293 fFittingParameterFrame->SetLayoutManager(
new TGTableLayout(fFittingParameterFrame, 2, 4,
false, 5));
294 fRangeLabel =
new TGLabel(fFittingParameterFrame,
"Range");
295 fRangeEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::Range(), 5, kRangeEntry, TGNumberFormat::EStyle::kNESRealTwo, TGNumberFormat::EAttribute::kNEAPositive);
296 fBgParamLabel =
new TGLabel(fFittingParameterFrame,
"BG Parameter");
297 fBgParamEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::BgParam(), 5, kBgParamEntry, TGNumberFormat::EStyle::kNESRealTwo, TGNumberFormat::EAttribute::kNEAPositive);
298 fThresholdLabel =
new TGLabel(fFittingParameterFrame,
"Threshold");
299 fThresholdEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::Threshold(), 5, kThresholdEntry, TGNumberFormat::EStyle::kNESRealThree, TGNumberFormat::EAttribute::kNEAPositive);
300 fPeakTypeBox =
new TGComboBox(fFittingParameterFrame, kPeakTypeBox);
301 fPeakTypeBox->AddEntry(
"Radware", TEfficiencyTab::EPeakType::kRWPeak);
302 fPeakTypeBox->AddEntry(
"Addback", TEfficiencyTab::EPeakType::kABPeak);
303 fPeakTypeBox->AddEntry(
"Addback3", TEfficiencyTab::EPeakType::kAB3Peak);
304 fPeakTypeBox->AddEntry(
"Gaussian", TEfficiencyTab::EPeakType::kGauss);
305 fPeakTypeBox->SetMinHeight(200);
306 fPeakTypeBox->Resize(100, TEfficiencyCalibrator::LineHeight());
307 fPeakTypeBox->Select(TEfficiencyCalibrator::PeakType());
308 fFittingControlGroup =
new TGHButtonGroup(fFittingParameterFrame,
"");
309 fRefitButton =
new TGTextButton(fFittingControlGroup,
"Refit this source");
310 fRefitAllButton =
new TGTextButton(fFittingControlGroup,
"Refit all sources");
312 fFittingParameterFrame->AddFrame(fRangeLabel,
new TGTableLayoutHints(0, 1, 0, 1));
313 fFittingParameterFrame->AddFrame(fRangeEntry,
new TGTableLayoutHints(1, 2, 0, 1));
314 fFittingParameterFrame->AddFrame(fBgParamLabel,
new TGTableLayoutHints(2, 3, 0, 1));
315 fFittingParameterFrame->AddFrame(fBgParamEntry,
new TGTableLayoutHints(3, 4, 0, 1));
316 fFittingParameterFrame->AddFrame(fThresholdLabel,
new TGTableLayoutHints(0, 1, 1, 2));
317 fFittingParameterFrame->AddFrame(fThresholdEntry,
new TGTableLayoutHints(1, 2, 1, 2));
318 fFittingParameterFrame->AddFrame(fPeakTypeBox,
new TGTableLayoutHints(2, 3, 1, 2));
319 fFittingParameterFrame->AddFrame(fFittingControlGroup,
new TGTableLayoutHints(3, 4, 1, 2));
321 fLeftFrame->AddFrame(fDataTab,
new TGLayoutHints(kLHintsTop | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
322 fLeftFrame->AddFrame(fFittingParameterFrame,
new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2, 2, 2, 2));
325 fRightFrame =
new TGVerticalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, TEfficiencyCalibrator::WindowWidth() / 2);
326 fEfficiencyCanvas =
new TRootEmbeddedCanvas(
"EfficiencyCanvas", fRightFrame, TEfficiencyCalibrator::WindowWidth() / 2, 450);
327 fStatusBar =
new TGStatusBar(fRightFrame, TEfficiencyCalibrator::WindowWidth() / 2, 50);
328 std::array<int, 2> parts = {35, 65};
329 fStatusBar->SetParts(parts.data(), parts.size());
330 fGraphParameterFrame =
new TGGroupFrame(fRightFrame,
"Graph Parameters", kHorizontalFrame);
331 fGraphParameterFrame->SetLayoutManager(
new TGTableLayout(fGraphParameterFrame, 3, 4,
false, 5));
332 fDegreeEntry =
new TGNumberEntry(fGraphParameterFrame, TEfficiencyCalibrator::Degree(), 2, kDegreeEntry, TGNumberFormat::EStyle::kNESInteger);
333 fDegreeLabel =
new TGLabel(fGraphParameterFrame,
"Type of efficiency curve");
334 fCalibrationUncertaintyLabel =
new TGLabel(fGraphParameterFrame,
"Calibration Uncertainty");
335 fCalibrationUncertaintyEntry =
new TGNumberEntry(fGraphParameterFrame, TEfficiencyCalibrator::CalibrationUncertainty(), 5, kCalibrationUncertaintyEntry, TGNumberFormat::EStyle::kNESRealOne, TGNumberFormat::EAttribute::kNEAPositive);
336 fPlotOptionFrame =
new TGGroupFrame(fGraphParameterFrame,
"Plot Selection", kHorizontalFrame);
337 fPlotOptionFrame->SetLayoutManager(
new TGTableLayout(fPlotOptionFrame, 2, 3,
false, 5));
338 fPlotEfficiencyCheck =
new TGCheckButton(fPlotOptionFrame,
"Efficiency", kPlotEfficiencyCheck);
339 fPlotEfficiencyCheck->SetState(kButtonDown);
340 fPlotUncorrEfficiencyCheck =
new TGCheckButton(fPlotOptionFrame,
"Uncorrected efficiency", kPlotUncorrEfficiencyCheck);
341 fPlotUncorrEfficiencyCheck->SetState(kButtonUp);
342 fPlotPeakAreaCheck =
new TGCheckButton(fPlotOptionFrame,
"Peak area", kPlotPeakAreaCheck);
343 fPlotPeakAreaCheck->SetState(kButtonUp);
344 fPlotSummingInCheck =
new TGCheckButton(fPlotOptionFrame,
"Summing in", kPlotSummingInCheck);
345 fPlotSummingInCheck->SetState(kButtonUp);
346 fPlotSummingOutCheck =
new TGCheckButton(fPlotOptionFrame,
"Summing out", kPlotSummingOutCheck);
347 fPlotSummingOutCheck->SetState(kButtonUp);
348 fPlotOptionFrame->AddFrame(fPlotEfficiencyCheck,
new TGTableLayoutHints(0, 1, 0, 1));
349 fPlotOptionFrame->AddFrame(fPlotUncorrEfficiencyCheck,
new TGTableLayoutHints(1, 3, 0, 1));
350 fPlotOptionFrame->AddFrame(fPlotPeakAreaCheck,
new TGTableLayoutHints(0, 1, 1, 2));
351 fPlotOptionFrame->AddFrame(fPlotSummingInCheck,
new TGTableLayoutHints(1, 2, 1, 2));
352 fPlotOptionFrame->AddFrame(fPlotSummingOutCheck,
new TGTableLayoutHints(2, 3, 1, 2));
353 fRecalculateButton =
new TGTextButton(fGraphParameterFrame,
"Recalculate graphs");
354 fGraphParameterFrame->AddFrame(fDegreeLabel,
new TGTableLayoutHints(0, 1, 0, 1));
355 fGraphParameterFrame->AddFrame(fDegreeEntry,
new TGTableLayoutHints(1, 2, 0, 1));
356 fGraphParameterFrame->AddFrame(fCalibrationUncertaintyLabel,
new TGTableLayoutHints(0, 1, 1, 2));
357 fGraphParameterFrame->AddFrame(fCalibrationUncertaintyEntry,
new TGTableLayoutHints(1, 2, 1, 2));
358 fGraphParameterFrame->AddFrame(fPlotOptionFrame,
new TGTableLayoutHints(2, 4, 0, 2));
359 fGraphParameterFrame->AddFrame(fRecalculateButton,
new TGTableLayoutHints(0, 4, 2, 3));
360 fRightFrame->AddFrame(fEfficiencyCanvas,
new TGLayoutHints(kLHintsExpandX));
361 fRightFrame->AddFrame(fStatusBar,
new TGLayoutHints(kLHintsExpandX));
362 fRightFrame->AddFrame(fGraphParameterFrame,
new TGLayoutHints(kLHintsExpandX));
364 fFrame->SetLayoutManager(
new TGHorizontalLayout(fFrame));
365 fFrame->AddFrame(fLeftFrame,
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandY, 2, 2, 2, 2));
366 fFrame->AddFrame(fRightFrame,
new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandY, 2, 2, 2, 2));
370 std::cout <<
"switching from sub directory " << gDirectory->GetName() <<
" to main directory " << fMainDirectory;
372 fMainDirectory->cd();
374 std::cout <<
" = " << fMainDirectory->GetName() <<
", sub directory is " << fSubDirectory <<
" = " << (fSubDirectory ==
nullptr ?
"" : fSubDirectory->GetName()) << std::endl;
377 std::cout <<
"======================================== done creating tab for data type " << dataType << std::endl;
381TEfficiencyDatatypeTab::~TEfficiencyDatatypeTab()
383 fMainDirectory->cd();
386void TEfficiencyDatatypeTab::MakeConnections()
388 fFittingControlGroup->Connect(
"Clicked(Int_t)",
"TEfficiencyDatatypeTab",
this,
"FittingControl(Int_t)");
389 fPlotEfficiencyCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
390 fPlotUncorrEfficiencyCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
391 fPlotPeakAreaCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
392 fPlotSummingInCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
393 fPlotSummingOutCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
394 fRecalculateButton->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
395 fEfficiencyCanvas->GetCanvas()->Connect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
"TEfficiencyDatatypeTab",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
396 for(
auto& tab : fEfficiencyTab) {
397 tab->MakeConnections();
399 fPeakTypeBox->Connect(
"Selected(Int_t)",
"TEfficiencyDatatypeTab",
this,
"UpdatePeakType()");
402void TEfficiencyDatatypeTab::Disconnect()
404 fFittingControlGroup->Disconnect(
"Clicked(Int_t)",
this,
"FittingControl(Int_t)");
405 fPlotEfficiencyCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
406 fPlotUncorrEfficiencyCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
407 fPlotPeakAreaCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
408 fPlotSummingInCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
409 fPlotSummingOutCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
410 fRecalculateButton->Disconnect(
"Clicked()",
this,
"DrawGraph()");
411 fEfficiencyCanvas->GetCanvas()->Disconnect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
412 for(
auto& tab : fEfficiencyTab) {
417void TEfficiencyDatatypeTab::Status(Int_t, Int_t px, Int_t py, TObject* selected)
419 fStatusBar->SetText(selected->GetName(), 0);
420 fStatusBar->SetText(selected->GetObjectInfo(px, py), 1);
423void TEfficiencyDatatypeTab::DrawGraph()
426 UpdateEfficiencyGraph();
428 if(fLegend ==
nullptr) {
429 fLegend =
new TLegend(0.8, 0.95 -
static_cast<double>(fNucleus.size()) * 0.05, 0.95, 0.95);
434 fEfficiencyCanvas->GetCanvas()->cd();
435 bool firstPlot =
true;
437 if(fPlotEfficiencyCheck->IsDown()) {
439 std::cout <<
"Drawing efficiency graph " << fEfficiencyGraph <<
":" << std::endl;
440 fEfficiencyGraph->Print(
"e");
442 for(
size_t g = 0; g < fEfficiencyGraph->NumberOfGraphs(); ++g) {
443 fEfficiencyGraph->SetColorStyle(g, color++);
445 fEfficiencyGraph->DrawCalibration(
"*", fLegend);
448 if(fPlotUncorrEfficiencyCheck->IsDown()) {
450 std::cout <<
"Drawing uncorrected efficiency graph " << fUncorrEfficiencyGraph <<
":" << std::endl;
451 fUncorrEfficiencyGraph->Print(
"e");
453 for(
size_t g = 0; g < fUncorrEfficiencyGraph->NumberOfGraphs(); ++g) {
454 fUncorrEfficiencyGraph->SetColorStyle(g, color++);
457 fUncorrEfficiencyGraph->DrawCalibration(
"*", fLegend);
459 fUncorrEfficiencyGraph->DrawCalibration(
"same*", fLegend);
463 if(fPlotPeakAreaCheck->IsDown()) {
465 fPeakAreaGraph->Print(
"");
467 for(
size_t g = 0; g < fPeakAreaGraph->NumberOfGraphs(); ++g) {
468 fPeakAreaGraph->SetColorStyle(g, color++);
471 fPeakAreaGraph->DrawCalibration(
"*", fLegend);
473 fPeakAreaGraph->DrawCalibration(
"same*", fLegend);
477 if(fPlotSummingInCheck->IsDown()) {
479 fSummingInGraph->Print(
"");
481 for(
size_t g = 0; g < fSummingInGraph->NumberOfGraphs(); ++g) {
482 fSummingInGraph->SetColorStyle(g, color++);
485 fSummingInGraph->DrawCalibration(
"*", fLegend);
487 fSummingInGraph->DrawCalibration(
"same*", fLegend);
491 if(fPlotSummingInCheck->IsDown()) {
493 fSummingOutGraph->Print(
"");
495 for(
size_t g = 0; g < fSummingOutGraph->NumberOfGraphs(); ++g) {
496 fSummingOutGraph->SetColorStyle(g, color++);
499 fSummingOutGraph->DrawCalibration(
"*", fLegend);
501 fSummingOutGraph->DrawCalibration(
"same*", fLegend);
506 fEfficiencyCanvas->GetCanvas()->Modified();
509void TEfficiencyDatatypeTab::UpdateEfficiencyGraph()
511 if(fMainDirectory ==
nullptr) {
512 std::cout <<
"No main directory open (" << fMainDirectory <<
"), sub directory is " << fSubDirectory <<
", gDirectory is " << gDirectory->GetName() << std::endl;
516 std::cout << __PRETTY_FUNCTION__ <<
": switching from gDirectory " << gDirectory->GetName() <<
" to main directory " << fMainDirectory <<
" = " << fMainDirectory->GetName() << std::endl;
518 fMainDirectory->cd();
519 if(fSubDirectory ==
nullptr) {
520 std::cout <<
"No subdirectory open (" << fSubDirectory <<
"), main directory is " << fMainDirectory <<
", gDirectory is " << gDirectory->GetName() << std::endl;
523 std::cout << __PRETTY_FUNCTION__ <<
": switching from gDirectory " << gDirectory->GetName() <<
" to sub directory " << fSubDirectory;
527 std::cout <<
" = " << fSubDirectory->GetName() <<
", main directory is " << fMainDirectory <<
" = " << (fMainDirectory ==
nullptr ?
"" : fMainDirectory->GetName()) << std::endl;
530 delete fEfficiencyGraph;
532 delete fUncorrEfficiencyGraph;
534 delete fPeakAreaGraph;
536 delete fSummingInGraph;
538 delete fSummingOutGraph;
541 for(
auto& tab : fEfficiencyTab) {
544 auto peaks = tab->Peaks();
546 double centroid = 0.;
547 double centroidErr = 0.;
548 double correctedArea = 0.;
549 double correctedAreaErr = 0.;
550 double peakArea = 0.;
551 double peakAreaErr = 0.;
552 double summingIn = 0.;
553 double summingOut = 0.;
554 std::vector<double> energy;
555 std::vector<double> energyErr;
556 std::vector<double> efficiency;
557 std::vector<double> efficiencyErr;
558 std::vector<double> uncorrEfficiency;
559 std::vector<double> uncorrEfficiencyErr;
560 std::vector<double> peakAreaVec;
561 std::vector<double> peakAreaErrVec;
562 std::vector<double> summingInVec;
563 std::vector<double> summingOutVec;
565 for(
auto& peak : peaks) {
566 std::tie(transition, centroid, centroidErr, correctedArea, correctedAreaErr, peakArea, peakAreaErr, summingIn, summingOut) = peak;
567 if(std::abs(transition->
GetEnergy() - centroid) < transition->
GetEnergyUncertainty() + centroidErr + TEfficiencyCalibrator::CalibrationUncertainty()) {
568 energy.push_back(transition->
GetEnergy());
570 efficiency.push_back(correctedArea / transition->
GetIntensity());
572 uncorrEfficiency.push_back(peakArea / transition->
GetIntensity());
574 peakAreaVec.push_back(peakArea);
575 peakAreaErrVec.push_back(peakAreaErr);
576 summingInVec.push_back(summingIn);
577 summingOutVec.push_back(summingOut);
580 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;
583 auto* effGraph =
new TGraphErrors(goodPeaks, energy.data(), efficiency.data(), energyErr.data(), efficiencyErr.data());
584 fEfficiencyGraph->Add(effGraph, tab->GetName());
585 auto* uncorrEffGraph =
new TGraphErrors(goodPeaks, energy.data(), uncorrEfficiency.data());
586 fUncorrEfficiencyGraph->Add(uncorrEffGraph, Form(
"%s uncorr. Eff.", tab->GetName()));
587 auto* peakAreaGraph =
new TGraphErrors(goodPeaks, energy.data(), peakAreaVec.data(), energyErr.data(), peakAreaErrVec.data());
588 fPeakAreaGraph->Add(peakAreaGraph, tab->GetName());
589 auto* summingInGraph =
new TGraphErrors(goodPeaks, energy.data(), summingInVec.data());
590 fSummingInGraph->Add(summingInGraph, Form(
"%s summing in", tab->GetName()));
591 auto* summingOutGraph =
new TGraphErrors(goodPeaks, energy.data(), summingOutVec.data());
592 fSummingOutGraph->Add(summingOutGraph, Form(
"%s summing out", tab->GetName()));
594 fEfficiencyGraph->Scale();
595 fUncorrEfficiencyGraph->Scale();
596 fEfficiencyGraph->SetAxisTitle(
"energy [keV];corrected efficiency [a.u.]");
597 fUncorrEfficiencyGraph->SetAxisTitle(
"energy [keV];uncorrected efficiency [a.u.]");
598 fPeakAreaGraph->SetAxisTitle(
"energy [keV];peak areas [a.u.]");
599 fSummingInGraph->SetAxisTitle(
"energy [keV];summing in corrections [a.u.]");
600 fSummingOutGraph->SetAxisTitle(
"energy [keV];summing out corrections [a.u.]");
601 fEfficiencyGraph->Write(Form(
"%s_efficiency", fDataType.c_str()), TObject::kOverwrite);
602 fUncorrEfficiencyGraph->Write(Form(
"%s_uncorr_efficiency", fDataType.c_str()), TObject::kOverwrite);
603 fPeakAreaGraph->Write(Form(
"%s_peak_area", fDataType.c_str()), TObject::kOverwrite);
604 fSummingInGraph->Write(Form(
"%s_summing_in", fDataType.c_str()), TObject::kOverwrite);
605 fSummingOutGraph->Write(Form(
"%s_summing_out", fDataType.c_str()), TObject::kOverwrite);
606 fMainDirectory->cd();
609void TEfficiencyDatatypeTab::UpdatePeakType()
611 if(fPeakTypeBox ==
nullptr) {
612 throw std::runtime_error(
"Failed to find peak type box, but got a signal it was selected?");
615 std::cout <<
"peak type box " << fPeakTypeBox << std::flush <<
", getting selected " << fPeakTypeBox->GetSelected() << std::endl;
618 TEfficiencyCalibrator::PeakType(
static_cast<TEfficiencyTab::EPeakType
>(fPeakTypeBox->GetSelected()));
621int TEfficiencyDatatypeTab::Degree()
623 if(fDegreeEntry !=
nullptr) {
624 TEfficiencyCalibrator::Degree(
static_cast<int>(fDegreeEntry->GetNumber()));
626 return TEfficiencyCalibrator::Degree();
635double TEfficiencyDatatypeTab::EfficiencyDebertin(
double* x,
double* par)
637 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);
641double TEfficiencyDatatypeTab::EfficiencyRadware(
double* x,
double* par)
643 double logX = TMath::Log(x[0] / 100.);
644 double logY = TMath::Log(x[0] / 1000.);
645 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]);
646 return TMath::Exp(logEff);
649double TEfficiencyDatatypeTab::EfficiencyPolynomial(
double* x,
double* par)
653 for(
int i = 0; i < par[0]; ++i) {
654 logEff += par[i + 1] * TMath::Power(TMath::Log(x[0]), i);
656 return TMath::Exp(logEff);
659void TEfficiencyDatatypeTab::FitEfficiency()
664 switch(TEfficiencyCalibrator::Degree()) {
666 fEfficiency =
new TF1(
"EfficiencyDebertin", TEfficiencyDatatypeTab::EfficiencyDebertin, 0., 10000., 5);
669 fEfficiency =
new TF1(
"EfficiencyRadware", TEfficiencyDatatypeTab::EfficiencyRadware, 0., 10000., 7);
672 fEfficiency =
new TF1(
"EfficiencyPolynomial", TEfficiencyDatatypeTab::EfficiencyPolynomial, 0., 10000., TEfficiencyCalibrator::Degree() + 1);
673 fEfficiency->FixParameter(0, TEfficiencyCalibrator::Degree());
677 fEfficiencyGraph->Fit(fEfficiency);
680void TEfficiencyDatatypeTab::FittingControl(Int_t
id)
682 int currentTabId = fDataTab->GetCurrent();
683 if(TEfficiencyCalibrator::VerboseLevel() >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": id " <<
id <<
", current tab id " << currentTabId << std::endl; }
687 fEfficiencyTab[currentTabId]->FindPeaks();
688 UpdateEfficiencyGraph();
691 for(
auto& tab : fEfficiencyTab) {
694 UpdateEfficiencyGraph();
701void TEfficiencyDatatypeTab::ReadValues()
703 TEfficiencyCalibrator::Range(fRangeEntry->GetNumber());
704 TEfficiencyCalibrator::Threshold(fThresholdEntry->GetNumber());
705 TEfficiencyCalibrator::BgParam(fBgParamEntry->GetNumberEntry()->GetIntNumber());
706 TEfficiencyCalibrator::Degree(fDegreeEntry->GetNumberEntry()->GetIntNumber());
707 TEfficiencyCalibrator::CalibrationUncertainty(fCalibrationUncertaintyEntry->GetNumber());
713double TEfficiencyCalibrator::fRange = 20.;
714double TEfficiencyCalibrator::fThreshold = 100.;
715int TEfficiencyCalibrator::fBgParam = 20;
716TEfficiencyTab::EPeakType TEfficiencyCalibrator::fPeakType = TEfficiencyTab::EPeakType::kRWPeak;
717int TEfficiencyCalibrator::fDegree = 0;
718double TEfficiencyCalibrator::fCalibrationUncertainty = 1.;
719bool TEfficiencyCalibrator::fShowRemovedFits =
false;
721unsigned int TEfficiencyCalibrator::fLineHeight = 20;
722unsigned int TEfficiencyCalibrator::fWindowWidth = 1200;
724TEfficiencyCalibrator::TEfficiencyCalibrator(
int n...)
725 : TGMainFrame(nullptr, TEfficiencyCalibrator::WindowWidth() + 10, TEfficiencyCalibrator::WindowWidth() / 2)
728 std::remove(
"fitOutput.txt");
733 fHistograms.resize(4);
734 fDataType = {
"Unsuppressed Singles",
"Suppressed Singles",
"Unsuppressed Addback",
"Suppressed Addback"};
738 bool allSourcesFound =
true;
739 for(
int i = 0; i < n; ++i) {
740 const char* name = va_arg(args,
const char*);
741 fFiles.push_back(
new TFile(name));
742 if(!fFiles.back()->IsOpen()) {
743 std::cerr <<
"Failed to open " << i + 1 <<
". file \"" << name <<
"\"" << std::endl;
747 bool goodFile =
false;
749 std::cout <<
"Checking file \"" << name <<
"\":";
751 if(fFiles.back()->FindKey(
"griffinE") !=
nullptr) {
753 fHistograms[0].emplace_back(
754 static_cast<TH1*
>(fFiles.back()->Get(
"griffinE")),
755 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinE180Corr")),
756 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESum180Corr")));
759 std::cout <<
" found unsuppressed singles";
762 if(fFiles.back()->FindKey(
"griffinESupp") !=
nullptr) {
764 fHistograms[1].emplace_back(
765 static_cast<TH1*
>(fFiles.back()->Get(
"griffinESupp")),
766 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEMixed180Corr")),
767 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESuppSum180Corr")));
770 std::cout <<
" found suppressed singles";
773 if(fFiles.back()->FindKey(
"griffinEAddback") !=
nullptr) {
775 fHistograms[2].emplace_back(
776 static_cast<TH1*
>(fFiles.back()->Get(
"griffinEAddback")),
777 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEAddback180Corr")),
778 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEAddbackSum180Corr")));
781 std::cout <<
" found unsuppressed addback";
784 if(fFiles.back()->FindKey(
"griffinESuppAddback") !=
nullptr) {
786 fHistograms[3].emplace_back(
787 static_cast<TH1*
>(fFiles.back()->Get(
"griffinESuppAddback")),
788 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEMixedAddback180Corr")),
789 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESuppAddbackSum180Corr")));
792 std::cout <<
" found suppressed addback";
796 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;
799 std::cerr <<
"Failed to find any histogram in " << i + 1 <<
". file \"" << name <<
"\"" << std::endl;
803 fSources.push_back(
nullptr);
805 if(std::strstr(name,
"22Na") !=
nullptr) {
806 fSources.back() =
new TNucleus(
"22Na");
807 }
else if(std::strstr(name,
"56Co") !=
nullptr) {
808 fSources.back() =
new TNucleus(
"56Co");
809 }
else if(std::strstr(name,
"60Co") !=
nullptr) {
810 fSources.back() =
new TNucleus(
"60Co");
811 }
else if(std::strstr(name,
"133Ba") !=
nullptr) {
812 fSources.back() =
new TNucleus(
"133Ba");
813 }
else if(std::strstr(name,
"152Eu") !=
nullptr) {
814 fSources.back() =
new TNucleus(
"152Eu");
815 }
else if(std::strstr(name,
"241Am") !=
nullptr) {
816 fSources.back() =
new TNucleus(
"241Am");
818 allSourcesFound =
false;
824 auto type = fDataType.begin();
825 for(
auto it = fHistograms.begin(); it != fHistograms.end();) {
826 if(it->size() != fFiles.size()) {
828 std::cout << std::distance(fHistograms.begin(), it) <<
": found " << it->size() <<
" histograms for " << fFiles.size() <<
" files, removing this type" << std::endl;
830 it = fHistograms.erase(it);
831 type = fDataType.erase(type);
839 std::cout <<
"Read " << fFiles.size() <<
" files, got";
840 for(
auto& vec : fHistograms) {
841 std::cout <<
" " << vec.size();
843 std::cout <<
" histograms" << std::endl;
846 if(fHistograms.empty()) {
847 throw std::runtime_error(
"Unable to find any suitable histograms in the provided file(s)!");
851 if(fSources.size() != fFiles.size() || fHistograms[0].size() != fFiles.size() || fHistograms.size() != fDataType.size()) {
852 std::ostringstream error;
853 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;
854 throw std::runtime_error(error.str());
857 fOutput =
new TFile(
"TEfficiencyCalibrator.root",
"recreate");
858 if(!fOutput->IsOpen()) {
859 throw std::runtime_error(
"Unable to open output file \"TEfficiencyCalibrator.root\"!");
863 if(!allSourcesFound) {
864 BuildFirstInterface();
865 MakeFirstConnections();
871 SetWindowName(
"EffiencyCalibrator");
877 Resize(GetDefaultSize());
885TEfficiencyCalibrator::~TEfficiencyCalibrator()
887 for(
auto& file : fFiles) {
890 if(fOutput !=
nullptr) { fOutput->Close(); }
893void TEfficiencyCalibrator::DeleteElement(TGFrame* element)
896 RemoveFrame(element);
901void TEfficiencyCalibrator::BuildFirstInterface()
905 auto* layoutManager =
new TGTableLayout(
this, fFiles.size() + 1, 2,
true, 5);
906 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout <<
"created table layout manager with 2 columns, " << fFiles.size() + 1 <<
" rows" << std::endl; }
907 SetLayoutManager(layoutManager);
911 for(i = 0; i < fFiles.size(); ++i) {
912 fSourceLabel.push_back(
new TGLabel(
this, fFiles[i]->GetName()));
913 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Text height " << fSourceLabel.back()->GetFont()->TextHeight() << std::endl; }
914 fSourceBox.push_back(
new TGComboBox(
this,
"Select source", kSourceBox + fSourceBox.size()));
915 if(fSources[i] !=
nullptr) {
916 fSourceBox.back()->AddEntry(fSources[i]->GetName(), i);
917 fSourceBox.back()->Select(0);
918 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Found source, setting entry to " << fSources[i]->GetName() <<
" and selecting " << fSourceBox.back()->GetSelected() << std::endl; }
920 fSourceBox.back()->AddEntry(
"22Na", k22Na);
921 fSourceBox.back()->AddEntry(
"56Co", k56Co);
922 fSourceBox.back()->AddEntry(
"60Co", k60Co);
923 fSourceBox.back()->AddEntry(
"133Ba", k133Ba);
924 fSourceBox.back()->AddEntry(
"152Eu", k152Eu);
925 fSourceBox.back()->AddEntry(
"241Am", k241Am);
926 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Didn't find source, created source box with " << fSourceBox.back()->GetNumberOfEntries() << std::endl; }
928 fSourceBox.back()->SetMinHeight(200);
929 fSourceBox.back()->Resize(100, LineHeight());
930 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; }
931 AddFrame(fSourceLabel.back(),
new TGTableLayoutHints(0, 1, i, i + 1, kLHintsRight | kLHintsCenterY));
932 AddFrame(fSourceBox.back(),
new TGTableLayoutHints(1, 2, i, i + 1, kLHintsLeft | kLHintsCenterY));
936 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout <<
"Attaching start button to 0, 2, " << i <<
", " << i + 1 << std::endl; }
937 fStartButton =
new TGTextButton(
this,
"Accept && Continue", kStartButton);
939 AddFrame(fStartButton,
new TGTableLayoutHints(0, 2, i, i + 1, kLHintsCenterX | kLHintsCenterY));
943void TEfficiencyCalibrator::MakeFirstConnections()
948 for(
auto* box : fSourceBox) {
949 box->Connect(
"Selected(Int_t, Int_t)",
"TEfficiencyCalibrator",
this,
"SetSource(Int_t, Int_t)");
953 fStartButton->Connect(
"Clicked()",
"TEfficiencyCalibrator",
this,
"Start()");
956void TEfficiencyCalibrator::DisconnectFirst()
959 for(
auto* box : fSourceBox) {
960 box->Disconnect(
"Selected(Int_t, Int_t)",
this,
"SetSource(Int_t, Int_t)");
962 fStartButton->Disconnect(
"Clicked()",
this,
"Start()");
965void TEfficiencyCalibrator::DeleteFirst()
969 DeleteElement(fStartButton);
973void TEfficiencyCalibrator::SetSource(Int_t windowId, Int_t entryId)
975 int index = windowId - kSourceBox;
976 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": windowId " << windowId <<
", entryId " << entryId <<
" => " << index << std::endl; }
977 TNucleus* nucleus = fSources[index];
979 nucleus =
new TNucleus(fSourceBox[index]->GetListBox()->GetEntry(entryId)->GetTitle());
980 fSources[index] = nucleus;
983void TEfficiencyCalibrator::Start()
985 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": fEmitter " << fEmitter <<
", fStartButton " << fStartButton << std::endl; }
986 if(fEmitter ==
nullptr) {
987 fEmitter = fStartButton;
988 TTimer::SingleShot(100,
"TEfficiencyCalibrator",
this,
"HandleTimer()");
992void TEfficiencyCalibrator::HandleTimer()
994 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": fEmitter " << fEmitter <<
", fStartButton " << fStartButton << std::endl; }
995 if(fEmitter == fStartButton) {
1005void TEfficiencyCalibrator::SecondWindow()
1009 for(
size_t i = 0; i < fSources.size(); ++i) {
1010 if(fSources[i] ==
nullptr) {
1011 std::cerr <<
"Source " << i <<
" not set!" << std::endl;
1015 std::cout << i <<
" - source " << fSources[i] <<
" = " << fSources[i]->GetName() << std::endl;
1019 for(
size_t i = 0; i < fSources.size(); ++i) {
1020 for(
size_t j = i + 1; j < fSources.size(); ++j) {
1021 if(*(fSources[i]) == *(fSources[j])) {
1022 std::cerr <<
"Duplicate sources: " << i <<
" - " << fSources[i]->GetName() <<
" and " << j <<
" - " << fSources[j]->GetName() << std::endl;
1028 SetLayoutManager(
new TGHorizontalLayout(
this));
1031 fProgressBar =
new TGHProgressBar(
this, TGProgressBar::kFancy, WindowWidth() / 2);
1032 int nofHistograms = 0;
1033 for(
auto& type : fHistograms) {
1034 nofHistograms += type.size();
1037 fProgressBar->SetRange(0.,
static_cast<Float_t
>(nofHistograms));
1038 fProgressBar->Percent(
true);
1039 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Set range of progress bar to 0. - " << fProgressBar->GetMax() <<
" = " << fFiles.size() << std::endl; }
1040 AddFrame(fProgressBar,
new TGLayoutHints(kLHintsCenterX | kLHintsCenterY | kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
1046 Resize(TGDimension(WindowWidth(), LineHeight()));
1053 BuildSecondInterface();
1054 MakeSecondConnections();
1057 DeleteElement(fProgressBar);
1063 Resize(TGDimension(WindowWidth(), WindowWidth() / 2));
1070void TEfficiencyCalibrator::BuildSecondInterface()
1072 SetLayoutManager(
new TGHorizontalLayout(
this));
1075 fDatatypeTab =
new TGTab(
this, WindowWidth(), WindowWidth() / 2);
1076 fEfficiencyDatatypeTab.resize(fHistograms.size());
1077 fEfficiencyGraph.resize(fHistograms.size());
1078 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout << __PRETTY_FUNCTION__ <<
" creating " << fHistograms.size() <<
" tabs" << std::endl; }
1079 for(
size_t i = 0; i < fHistograms.size(); ++i) {
1080 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; }
1081 auto* frame = fDatatypeTab->AddTab(fDataType[i].c_str());
1082 std::replace(fDataType[i].begin(), fDataType[i].end(),
' ',
'_');
1083 fEfficiencyDatatypeTab[i] =
new TEfficiencyDatatypeTab(
this, fSources, fHistograms[i], frame, fDataType[i], fProgressBar);
1085 fEfficiencyGraph[i] = fEfficiencyDatatypeTab[i]->EfficiencyGraph();
1087 AddFrame(fDatatypeTab,
new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 0, 0, 0, 0));
1092void TEfficiencyCalibrator::MakeSecondConnections()
1096 for(
auto* sourceTab : fEfficiencyDatatypeTab) {
1097 sourceTab->MakeConnections();
1101void TEfficiencyCalibrator::DisconnectSecond()
1104 for(
auto* sourceTab : fEfficiencyDatatypeTab) {
1105 sourceTab->Disconnect();
void Draw(Option_t *opt="") override
double GetIntensityUncertainty() const
double GetIntensity() const
double GetEnergyUncertainty() const