3#if __cplusplus >= 201703L
9#include "TGTableLayout.h"
19TEfficiencyTab::TEfficiencyTab(TEfficiencyDatatypeTab* parent,
TNucleus* nucleus, std::tuple<TH1*, TH2*, TH2*> hists, TGCompositeFrame* frame)
20 : fFrame(frame), fNucleus(nucleus), fParent(parent),
21 fSingles(std::get<0>(hists)), fSummingOut(std::get<1>(hists)), fSummingIn(std::get<2>(hists))
25 std::cout <<
"Assigned singles, summing out, and summing in histograms (" << fSingles->GetName() <<
", " << fSummingOut->GetName() <<
", " << fSummingIn->GetName() <<
")" << std::endl;
30 std::cout <<
"======================================== Finding peaks in " << fSingles->GetName() <<
", " << fSummingOut->GetName() <<
", and " << fSummingIn->GetName() << std::endl;
35void TEfficiencyTab::BuildInterface()
38 fTopFrame =
new TGHorizontalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, 450);
39 fProjectionCanvas =
new TRootEmbeddedCanvas(
"ProjectionCanvas", fTopFrame, TEfficiencyCalibrator::WindowWidth() / 2, 400);
41 fTopFrame->AddFrame(fProjectionCanvas,
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandY | kLHintsExpandX, 2, 2, 2, 2));
43 fFrame->AddFrame(fTopFrame,
new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2));
45 fStatusBar =
new TGStatusBar(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, 50);
46 std::array<int, 5> parts = {35, 15, 20, 15, 15};
47 fStatusBar->SetParts(parts.data(), parts.size());
49 fFrame->AddFrame(fStatusBar,
new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2, 2, 2, 2));
50 if(TEfficiencyCalibrator::VerboseLevel() >
EVerbosity::kLoops) { std::cout <<
"Done with " << __PRETTY_FUNCTION__ << std::endl; }
53void TEfficiencyTab::FindPeaks()
58 std::cout << __PRETTY_FUNCTION__ << std::endl;
59 std::cout <<
"Using parent " << fParent <<
" and transition list " << fNucleus->GetTransitionListByEnergy() << std::endl;
60 fNucleus->GetTransitionListByEnergy()->Print();
61 std::cout <<
"Using parent " << fParent << std::flush <<
", trying to get peak type " << TEfficiencyCalibrator::PeakType() << std::endl;
63 fProjectionCanvas->GetCanvas()->cd();
65 std::cout <<
"Got peak type " << TEfficiencyCalibrator::PeakType() <<
", getting projection from " << fSummingOut->GetName() << std::endl;
67 fSummingOutTotalProj = fSummingOut->ProjectionY();
69 std::cout <<
"Writing '" << fSummingOutTotalProj->GetName() <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
71 fSummingOutTotalProj->Write(
nullptr, TObject::kOverwrite);
73 std::cout <<
"Got projection " << fSummingOutTotalProj <<
", getting background from " << fSummingOutTotalProj->GetName() << std::endl;
75 fSummingOutTotalProjBg = fSummingOutTotalProj->ShowBackground(TEfficiencyCalibrator::BgParam());
77 std::cout <<
"Writing '" << fSummingOutTotalProjBg->GetName() <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
79 fSummingOutTotalProjBg->Write(
nullptr, TObject::kOverwrite);
84 for(
int t = 0; t < fNucleus->GetTransitionListByEnergy()->GetSize(); ++t) {
85 auto* transition =
static_cast<TTransition*
>(fNucleus->GetTransitionListByEnergy()->At(t));
87 if(energy > fSingles->GetXaxis()->GetXmax()) {
89 std::cout <<
"Skipping peak at " << energy <<
" keV of " << fNucleus->GetA() << fNucleus->GetSymbol() <<
", maximum range of histogram is " << fSingles->GetXaxis()->GetXmax() << std::endl;
93 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;
95 fPeakFitter.RemoveAllPeaks();
96 fPeakFitter.ResetInitFlag();
98 std::vector<TSinglePeak*> peaks;
99 peaks.push_back(NewPeak(energy));
100 double lastEnergy = energy;
101 for(
int t2 = t + 1; t2 < fNucleus->GetTransitionListByEnergy()->GetSize(); ++t2) {
102 auto* transition2 =
static_cast<TTransition*
>(fNucleus->GetTransitionListByEnergy()->At(t2));
104 if(lastEnergy + TEfficiencyCalibrator::Range() > energy2 - TEfficiencyCalibrator::Range()) {
106 std::cout << t <<
". peak: Found " << peaks.size() <<
". overlapping peak for " << lastEnergy <<
", and " << energy2 <<
" with range " << TEfficiencyCalibrator::Range() << std::endl;
109 peaks.push_back(NewPeak(energy2));
111 lastEnergy = energy2;
115 std::cout << t <<
". peak: Found " << peaks.size() <<
". overlapping peaks, stopping here with " << lastEnergy <<
", and " << energy2 <<
" with range " << TEfficiencyCalibrator::Range() << std::endl;
121 fPeakFitter.SetRange(energy - TEfficiencyCalibrator::Range(), lastEnergy + TEfficiencyCalibrator::Range());
122 for(
auto& peak : peaks) {
123 fPeakFitter.AddPeak(peak);
125 std::cout <<
"---------------------------------------- Fitting peak(s) at " << energy <<
"/" << lastEnergy <<
" from " << energy - TEfficiencyCalibrator::Range() <<
" to " << energy + TEfficiencyCalibrator::Range() << std::endl;
127 fPeakFitter.PrintParameters();
128 fPeakFitter.Fit(fSingles,
"retryfit");
129 for(
auto& peak : peaks) {
131 std::cout <<
"================================================================================" << std::endl;
132 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;
134 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())) {
136 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;
137 std::cout <<
"================================================================================" << std::endl;
139 fRemovedFitFunctions.push_back(fPeakFitter.GetFitFunction()->Clone(Form(
"removed_fit_%.1f", peak->Centroid())));
143 std::cout <<
"================================================================================" << std::endl;
146 fPeakFitter.GetFitFunction()->SetNpx(1000);
147 peak->GetPeakFunction()->SetNpx(1000);
148 double fwhm = peak->FWHM();
149 double centroid = peak->Centroid();
150 double centroidErr = peak->CentroidErr();
152 std::cout <<
"Got centroid " << centroid <<
" keV, FWHM " << fwhm <<
":" << std::endl;
155 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSingles->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
157 fSingles->Write(Form(
"%s_%.0fkeV", fSingles->GetName(), centroid), TObject::kOverwrite);
159 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.)));
160 fSummingInProjBg.push_back(fSummingInProj.back()->ShowBackground(TEfficiencyCalibrator::BgParam()));
162 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSummingInProj.back()->GetName(), centroid) <<
"' and '" << Form(
"%s_%.0fkeV", fSummingInProjBg.back()->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
164 double summingIn = fSummingInProj.back()->Integral() - fSummingInProjBg.back()->Integral();
165 fSummingInProj.back()->Write(Form(
"%s_%.0fkeV", fSummingInProj.back()->GetName(), centroid), TObject::kOverwrite);
166 fSummingInProjBg.back()->Write(Form(
"%s_%.0fkeV", fSummingInProjBg.back()->GetName(), centroid), TObject::kOverwrite);
168 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.)));
169 double ratio = fSummingOutTotalProjBg->Integral(fSummingOutTotalProjBg->GetXaxis()->FindBin(centroid - fwhm / 2.), fSummingOutTotalProjBg->GetXaxis()->FindBin(centroid + fwhm / 2.)) / fSummingOutTotalProjBg->Integral();
170 double summingOut = fSummingOutProj.back()->Integral() - fSummingOutTotalProj->Integral() * ratio;
172 std::cout <<
"Writing '" << Form(
"%s_%.0fkeV", fSummingOutProj.back()->GetName(), centroid) <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
174 fSummingOutProj.back()->Write(Form(
"%s_%.0fkeV", fSummingOutProj.back()->GetName(), centroid), TObject::kOverwrite);
175 auto*
hist =
static_cast<TH1*
>(fSummingOutProj.back()->Clone(Form(
"%s_subtracted_%.0f", fSummingOutProj.back()->GetName(), 1000000 * ratio)));
176 hist->Add(fSummingOutTotalProj, -ratio);
178 std::cout <<
"Writing '" <<
hist->GetName() <<
"' to '" << gDirectory->GetName() <<
"'" << std::endl;
180 hist->Write(
nullptr, TObject::kOverwrite);
182 double correctedArea = peak->Area() - summingIn + summingOut;
184 double correctedAreaErr = TMath::Sqrt(TMath::Power(peak->AreaErr(), 2) + summingIn + summingOut);
186 std::cout <<
"Got summingIn " << summingIn <<
", ratio " << ratio <<
", summingOut " << summingOut <<
", correctedArea " << correctedArea <<
" +- " << correctedAreaErr << std::endl;
188 fPeaks.emplace_back(transition, centroid, centroidErr, correctedArea, correctedAreaErr, peak->Area(), peak->AreaErr(), summingIn, summingOut);
189 fFitFunctions.push_back(fPeakFitter.GetFitFunction()->Clone(Form(
"fit_%.1f", centroid)));
195 std::cout <<
"Unsorted peak vector:";
196 for(
const auto& peak : fPeaks) { std::cout <<
" " << std::get<0>(peak)->GetEnergy(); }
197 std::cout << std::endl;
199 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(); });
201 std::cout <<
"Sorted peak vector:";
202 for(
auto& peak : fPeaks) { std::cout <<
" " << std::get<0>(peak)->GetEnergy(); }
203 std::cout << std::endl;
207TSinglePeak* TEfficiencyTab::NewPeak(
const double& energy)
209 switch(TEfficiencyCalibrator::PeakType()) {
220 return new TGauss(energy);
223 std::cerr <<
"Unknow peak type " << TEfficiencyCalibrator::PeakType() <<
", defaulting to TRWPeak!" << std::endl;
228void TEfficiencyTab::Redraw()
230 fProjectionCanvas->GetCanvas()->cd();
231 fSingles->GetListOfFunctions()->Clear();
232 for(
auto& fit : fFitFunctions) {
233 static_cast<TF1*
>(fit)->SetLineColor(2);
234 fSingles->GetListOfFunctions()->Add(fit);
236 if(TEfficiencyCalibrator::ShowRemovedFits()) {
237 for(
auto& fit : fRemovedFitFunctions) {
238 static_cast<TF1*
>(fit)->SetLineColor(15);
239 fSingles->GetListOfFunctions()->Add(fit);
243 fProjectionCanvas->GetCanvas()->Modified();
246void TEfficiencyTab::MakeConnections()
248 fProjectionCanvas->GetCanvas()->Connect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
"TEfficiencyTab",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
251void TEfficiencyTab::Disconnect()
253 fProjectionCanvas->GetCanvas()->Disconnect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
256void TEfficiencyTab::Status(Int_t, Int_t px, Int_t py, TObject* selected)
258 fStatusBar->SetText(selected->GetName(), 0);
259 fStatusBar->SetText(selected->GetObjectInfo(px, py), 1);
263TEfficiencyDatatypeTab::TEfficiencyDatatypeTab(TEfficiencyCalibrator* parent, std::vector<TNucleus*> nucleus, std::vector<std::tuple<TH1*, TH2*, TH2*>> hists, TGCompositeFrame* frame,
const std::string& dataType, TGHProgressBar* progressBar)
264 : fFrame(frame), fNucleus(std::move(nucleus)), fParent(parent), fDataType(dataType)
267 std::cout <<
"======================================== creating tab for data type " << dataType << std::endl;
270 fMainDirectory = gDirectory;
271 fSubDirectory = gDirectory->mkdir(dataType.c_str());
273 std::cout <<
"switching from gDirectory " << gDirectory->GetName() <<
" to sub directory " << fSubDirectory;
277 std::cout <<
" = " << fSubDirectory->GetName() <<
", main directory is " << fMainDirectory <<
" = " << (fMainDirectory == nullptr ?
"" : fMainDirectory->GetName()) << std::endl;
281 fLeftFrame =
new TGVerticalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, TEfficiencyCalibrator::WindowWidth() / 2);
283 fDataTab =
new TGTab(fLeftFrame, TEfficiencyCalibrator::WindowWidth() / 2, 500);
284 fEfficiencyTab.resize(hists.size(),
nullptr);
285 for(
size_t i = 0; i < hists.size(); ++i) {
286 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; }
287 fEfficiencyTab[i] =
new TEfficiencyTab(
this, fNucleus[i], hists[i], fDataTab->AddTab(fNucleus[i]->GetName()));
288 progressBar->Increment(1);
291 fFittingParameterFrame =
new TGGroupFrame(fLeftFrame,
"Fitting Parameters", kHorizontalFrame);
292 fFittingParameterFrame->SetLayoutManager(
new TGTableLayout(fFittingParameterFrame, 2, 4,
false, 5));
293 fRangeLabel =
new TGLabel(fFittingParameterFrame,
"Range");
294 fRangeEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::Range(), 5, kRangeEntry, TGNumberFormat::EStyle::kNESRealTwo, TGNumberFormat::EAttribute::kNEAPositive);
295 fBgParamLabel =
new TGLabel(fFittingParameterFrame,
"BG Parameter");
296 fBgParamEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::BgParam(), 5, kBgParamEntry, TGNumberFormat::EStyle::kNESRealTwo, TGNumberFormat::EAttribute::kNEAPositive);
297 fThresholdLabel =
new TGLabel(fFittingParameterFrame,
"Threshold");
298 fThresholdEntry =
new TGNumberEntry(fFittingParameterFrame, TEfficiencyCalibrator::Threshold(), 5, kThresholdEntry, TGNumberFormat::EStyle::kNESRealThree, TGNumberFormat::EAttribute::kNEAPositive);
299 fPeakTypeBox =
new TGComboBox(fFittingParameterFrame, kPeakTypeBox);
300 fPeakTypeBox->AddEntry(
"Radware", TEfficiencyTab::EPeakType::kRWPeak);
301 fPeakTypeBox->AddEntry(
"Addback", TEfficiencyTab::EPeakType::kABPeak);
302 fPeakTypeBox->AddEntry(
"Addback3", TEfficiencyTab::EPeakType::kAB3Peak);
303 fPeakTypeBox->AddEntry(
"Gaussian", TEfficiencyTab::EPeakType::kGauss);
304 fPeakTypeBox->SetMinHeight(200);
305 fPeakTypeBox->Resize(100, TEfficiencyCalibrator::LineHeight());
306 fPeakTypeBox->Select(TEfficiencyCalibrator::PeakType());
307 fFittingControlGroup =
new TGHButtonGroup(fFittingParameterFrame,
"");
308 fRefitButton =
new TGTextButton(fFittingControlGroup,
"Refit this source");
309 fRefitAllButton =
new TGTextButton(fFittingControlGroup,
"Refit all sources");
311 fFittingParameterFrame->AddFrame(fRangeLabel,
new TGTableLayoutHints(0, 1, 0, 1));
312 fFittingParameterFrame->AddFrame(fRangeEntry,
new TGTableLayoutHints(1, 2, 0, 1));
313 fFittingParameterFrame->AddFrame(fBgParamLabel,
new TGTableLayoutHints(2, 3, 0, 1));
314 fFittingParameterFrame->AddFrame(fBgParamEntry,
new TGTableLayoutHints(3, 4, 0, 1));
315 fFittingParameterFrame->AddFrame(fThresholdLabel,
new TGTableLayoutHints(0, 1, 1, 2));
316 fFittingParameterFrame->AddFrame(fThresholdEntry,
new TGTableLayoutHints(1, 2, 1, 2));
317 fFittingParameterFrame->AddFrame(fPeakTypeBox,
new TGTableLayoutHints(2, 3, 1, 2));
318 fFittingParameterFrame->AddFrame(fFittingControlGroup,
new TGTableLayoutHints(3, 4, 1, 2));
320 fLeftFrame->AddFrame(fDataTab,
new TGLayoutHints(kLHintsTop | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
321 fLeftFrame->AddFrame(fFittingParameterFrame,
new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2, 2, 2, 2));
324 fRightFrame =
new TGVerticalFrame(fFrame, TEfficiencyCalibrator::WindowWidth() / 2, TEfficiencyCalibrator::WindowWidth() / 2);
325 fEfficiencyCanvas =
new TRootEmbeddedCanvas(
"EfficiencyCanvas", fRightFrame, TEfficiencyCalibrator::WindowWidth() / 2, 450);
326 fStatusBar =
new TGStatusBar(fRightFrame, TEfficiencyCalibrator::WindowWidth() / 2, 50);
327 std::array<int, 2> parts = {35, 65};
328 fStatusBar->SetParts(parts.data(), parts.size());
329 fGraphParameterFrame =
new TGGroupFrame(fRightFrame,
"Graph Parameters", kHorizontalFrame);
330 fGraphParameterFrame->SetLayoutManager(
new TGTableLayout(fGraphParameterFrame, 3, 4,
false, 5));
331 fDegreeEntry =
new TGNumberEntry(fGraphParameterFrame, TEfficiencyCalibrator::Degree(), 2, kDegreeEntry, TGNumberFormat::EStyle::kNESInteger);
332 fDegreeLabel =
new TGLabel(fGraphParameterFrame,
"Type of efficiency curve");
333 fCalibrationUncertaintyLabel =
new TGLabel(fGraphParameterFrame,
"Calibration Uncertainty");
334 fCalibrationUncertaintyEntry =
new TGNumberEntry(fGraphParameterFrame, TEfficiencyCalibrator::CalibrationUncertainty(), 5, kCalibrationUncertaintyEntry, TGNumberFormat::EStyle::kNESRealOne, TGNumberFormat::EAttribute::kNEAPositive);
335 fPlotOptionFrame =
new TGGroupFrame(fGraphParameterFrame,
"Plot Selection", kHorizontalFrame);
336 fPlotOptionFrame->SetLayoutManager(
new TGTableLayout(fPlotOptionFrame, 2, 3,
false, 5));
337 fPlotEfficiencyCheck =
new TGCheckButton(fPlotOptionFrame,
"Efficiency", kPlotEfficiencyCheck);
338 fPlotEfficiencyCheck->SetState(kButtonDown);
339 fPlotUncorrEfficiencyCheck =
new TGCheckButton(fPlotOptionFrame,
"Uncorrected efficiency", kPlotUncorrEfficiencyCheck);
340 fPlotUncorrEfficiencyCheck->SetState(kButtonUp);
341 fPlotPeakAreaCheck =
new TGCheckButton(fPlotOptionFrame,
"Peak area", kPlotPeakAreaCheck);
342 fPlotPeakAreaCheck->SetState(kButtonUp);
343 fPlotSummingInCheck =
new TGCheckButton(fPlotOptionFrame,
"Summing in", kPlotSummingInCheck);
344 fPlotSummingInCheck->SetState(kButtonUp);
345 fPlotSummingOutCheck =
new TGCheckButton(fPlotOptionFrame,
"Summing out", kPlotSummingOutCheck);
346 fPlotSummingOutCheck->SetState(kButtonUp);
347 fPlotOptionFrame->AddFrame(fPlotEfficiencyCheck,
new TGTableLayoutHints(0, 1, 0, 1));
348 fPlotOptionFrame->AddFrame(fPlotUncorrEfficiencyCheck,
new TGTableLayoutHints(1, 3, 0, 1));
349 fPlotOptionFrame->AddFrame(fPlotPeakAreaCheck,
new TGTableLayoutHints(0, 1, 1, 2));
350 fPlotOptionFrame->AddFrame(fPlotSummingInCheck,
new TGTableLayoutHints(1, 2, 1, 2));
351 fPlotOptionFrame->AddFrame(fPlotSummingOutCheck,
new TGTableLayoutHints(2, 3, 1, 2));
352 fRecalculateButton =
new TGTextButton(fGraphParameterFrame,
"Recalculate graphs");
353 fGraphParameterFrame->AddFrame(fDegreeLabel,
new TGTableLayoutHints(0, 1, 0, 1));
354 fGraphParameterFrame->AddFrame(fDegreeEntry,
new TGTableLayoutHints(1, 2, 0, 1));
355 fGraphParameterFrame->AddFrame(fCalibrationUncertaintyLabel,
new TGTableLayoutHints(0, 1, 1, 2));
356 fGraphParameterFrame->AddFrame(fCalibrationUncertaintyEntry,
new TGTableLayoutHints(1, 2, 1, 2));
357 fGraphParameterFrame->AddFrame(fPlotOptionFrame,
new TGTableLayoutHints(2, 4, 0, 2));
358 fGraphParameterFrame->AddFrame(fRecalculateButton,
new TGTableLayoutHints(0, 4, 2, 3));
359 fRightFrame->AddFrame(fEfficiencyCanvas,
new TGLayoutHints(kLHintsExpandX));
360 fRightFrame->AddFrame(fStatusBar,
new TGLayoutHints(kLHintsExpandX));
361 fRightFrame->AddFrame(fGraphParameterFrame,
new TGLayoutHints(kLHintsExpandX));
363 fFrame->SetLayoutManager(
new TGHorizontalLayout(fFrame));
364 fFrame->AddFrame(fLeftFrame,
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandY, 2, 2, 2, 2));
365 fFrame->AddFrame(fRightFrame,
new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandY, 2, 2, 2, 2));
369 std::cout <<
"switching from sub directory " << gDirectory->GetName() <<
" to main directory " << fMainDirectory;
371 fMainDirectory->cd();
373 std::cout <<
" = " << fMainDirectory->GetName() <<
", sub directory is " << fSubDirectory <<
" = " << (fSubDirectory ==
nullptr ?
"" : fSubDirectory->GetName()) << std::endl;
376 std::cout <<
"======================================== done creating tab for data type " << dataType << std::endl;
380TEfficiencyDatatypeTab::~TEfficiencyDatatypeTab()
382 fMainDirectory->cd();
385void TEfficiencyDatatypeTab::MakeConnections()
387 fFittingControlGroup->Connect(
"Clicked(Int_t)",
"TEfficiencyDatatypeTab",
this,
"FittingControl(Int_t)");
388 fPlotEfficiencyCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
389 fPlotUncorrEfficiencyCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
390 fPlotPeakAreaCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
391 fPlotSummingInCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
392 fPlotSummingOutCheck->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
393 fRecalculateButton->Connect(
"Clicked()",
"TEfficiencyDatatypeTab",
this,
"DrawGraph()");
394 fEfficiencyCanvas->GetCanvas()->Connect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
"TEfficiencyDatatypeTab",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
395 for(
auto& tab : fEfficiencyTab) {
396 tab->MakeConnections();
398 fPeakTypeBox->Connect(
"Selected(Int_t)",
"TEfficiencyDatatypeTab",
this,
"UpdatePeakType()");
401void TEfficiencyDatatypeTab::Disconnect()
403 fFittingControlGroup->Disconnect(
"Clicked(Int_t)",
this,
"FittingControl(Int_t)");
404 fPlotEfficiencyCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
405 fPlotUncorrEfficiencyCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
406 fPlotPeakAreaCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
407 fPlotSummingInCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
408 fPlotSummingOutCheck->Disconnect(
"Clicked()",
this,
"DrawGraph()");
409 fRecalculateButton->Disconnect(
"Clicked()",
this,
"DrawGraph()");
410 fEfficiencyCanvas->GetCanvas()->Disconnect(
"ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
this,
"Status(Int_t, Int_t, Int_t, TObject*)");
411 for(
auto& tab : fEfficiencyTab) {
416void TEfficiencyDatatypeTab::Status(Int_t, Int_t px, Int_t py, TObject* selected)
418 fStatusBar->SetText(selected->GetName(), 0);
419 fStatusBar->SetText(selected->GetObjectInfo(px, py), 1);
422void TEfficiencyDatatypeTab::DrawGraph()
425 UpdateEfficiencyGraph();
427 if(fLegend ==
nullptr) {
428 fLegend =
new TLegend(0.8, 0.95 -
static_cast<double>(fNucleus.size()) * 0.05, 0.95, 0.95);
433 fEfficiencyCanvas->GetCanvas()->cd();
434 bool firstPlot =
true;
436 if(fPlotEfficiencyCheck->IsDown()) {
438 std::cout <<
"Drawing efficiency graph " << fEfficiencyGraph <<
":" << std::endl;
439 fEfficiencyGraph->Print(
"e");
441 for(
size_t g = 0; g < fEfficiencyGraph->NumberOfGraphs(); ++g) {
442 fEfficiencyGraph->SetColorStyle(g, color++);
444 fEfficiencyGraph->DrawCalibration(
"*", fLegend);
447 if(fPlotUncorrEfficiencyCheck->IsDown()) {
449 std::cout <<
"Drawing uncorrected efficiency graph " << fUncorrEfficiencyGraph <<
":" << std::endl;
450 fUncorrEfficiencyGraph->Print(
"e");
452 for(
size_t g = 0; g < fUncorrEfficiencyGraph->NumberOfGraphs(); ++g) {
453 fUncorrEfficiencyGraph->SetColorStyle(g, color++);
456 fUncorrEfficiencyGraph->DrawCalibration(
"*", fLegend);
458 fUncorrEfficiencyGraph->DrawCalibration(
"same*", fLegend);
462 if(fPlotPeakAreaCheck->IsDown()) {
464 fPeakAreaGraph->Print(
"");
466 for(
size_t g = 0; g < fPeakAreaGraph->NumberOfGraphs(); ++g) {
467 fPeakAreaGraph->SetColorStyle(g, color++);
470 fPeakAreaGraph->DrawCalibration(
"*", fLegend);
472 fPeakAreaGraph->DrawCalibration(
"same*", fLegend);
476 if(fPlotSummingInCheck->IsDown()) {
478 fSummingInGraph->Print(
"");
480 for(
size_t g = 0; g < fSummingInGraph->NumberOfGraphs(); ++g) {
481 fSummingInGraph->SetColorStyle(g, color++);
484 fSummingInGraph->DrawCalibration(
"*", fLegend);
486 fSummingInGraph->DrawCalibration(
"same*", fLegend);
490 if(fPlotSummingInCheck->IsDown()) {
492 fSummingOutGraph->Print(
"");
494 for(
size_t g = 0; g < fSummingOutGraph->NumberOfGraphs(); ++g) {
495 fSummingOutGraph->SetColorStyle(g, color++);
498 fSummingOutGraph->DrawCalibration(
"*", fLegend);
500 fSummingOutGraph->DrawCalibration(
"same*", fLegend);
505 fEfficiencyCanvas->GetCanvas()->Modified();
508void TEfficiencyDatatypeTab::UpdateEfficiencyGraph()
510 if(fMainDirectory ==
nullptr) {
511 std::cout <<
"No main directory open (" << fMainDirectory <<
"), sub directory is " << fSubDirectory <<
", gDirectory is " << gDirectory->GetName() << std::endl;
515 std::cout << __PRETTY_FUNCTION__ <<
": switching from gDirectory " << gDirectory->GetName() <<
" to main directory " << fMainDirectory <<
" = " << fMainDirectory->GetName() << std::endl;
517 fMainDirectory->cd();
518 if(fSubDirectory ==
nullptr) {
519 std::cout <<
"No subdirectory open (" << fSubDirectory <<
"), main directory is " << fMainDirectory <<
", gDirectory is " << gDirectory->GetName() << std::endl;
522 std::cout << __PRETTY_FUNCTION__ <<
": switching from gDirectory " << gDirectory->GetName() <<
" to sub directory " << fSubDirectory;
526 std::cout <<
" = " << fSubDirectory->GetName() <<
", main directory is " << fMainDirectory <<
" = " << (fMainDirectory ==
nullptr ?
"" : fMainDirectory->GetName()) << std::endl;
529 delete fEfficiencyGraph;
531 delete fUncorrEfficiencyGraph;
533 delete fPeakAreaGraph;
535 delete fSummingInGraph;
537 delete fSummingOutGraph;
540 for(
auto& tab : fEfficiencyTab) {
543 auto peaks = tab->Peaks();
545 double centroid = 0.;
546 double centroidErr = 0.;
547 double correctedArea = 0.;
548 double correctedAreaErr = 0.;
549 double peakArea = 0.;
550 double peakAreaErr = 0.;
551 double summingIn = 0.;
552 double summingOut = 0.;
553 std::vector<double> energy;
554 std::vector<double> energyErr;
555 std::vector<double> efficiency;
556 std::vector<double> efficiencyErr;
557 std::vector<double> uncorrEfficiency;
558 std::vector<double> uncorrEfficiencyErr;
559 std::vector<double> peakAreaVec;
560 std::vector<double> peakAreaErrVec;
561 std::vector<double> summingInVec;
562 std::vector<double> summingOutVec;
564 for(
auto& peak : peaks) {
565 std::tie(transition, centroid, centroidErr, correctedArea, correctedAreaErr, peakArea, peakAreaErr, summingIn, summingOut) = peak;
566 if(std::abs(transition->
GetEnergy() - centroid) < transition->
GetEnergyUncertainty() + centroidErr + TEfficiencyCalibrator::CalibrationUncertainty()) {
567 energy.push_back(transition->
GetEnergy());
569 efficiency.push_back(correctedArea / transition->
GetIntensity());
571 uncorrEfficiency.push_back(peakArea / transition->
GetIntensity());
573 peakAreaVec.push_back(peakArea);
574 peakAreaErrVec.push_back(peakAreaErr);
575 summingInVec.push_back(summingIn);
576 summingOutVec.push_back(summingOut);
579 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;
582 auto* effGraph =
new TGraphErrors(goodPeaks, energy.data(), efficiency.data(), energyErr.data(), efficiencyErr.data());
583 fEfficiencyGraph->Add(effGraph, tab->GetName());
584 auto* uncorrEffGraph =
new TGraphErrors(goodPeaks, energy.data(), uncorrEfficiency.data());
585 fUncorrEfficiencyGraph->Add(uncorrEffGraph, Form(
"%s uncorr. Eff.", tab->GetName()));
586 auto* peakAreaGraph =
new TGraphErrors(goodPeaks, energy.data(), peakAreaVec.data(), energyErr.data(), peakAreaErrVec.data());
587 fPeakAreaGraph->Add(peakAreaGraph, tab->GetName());
588 auto* summingInGraph =
new TGraphErrors(goodPeaks, energy.data(), summingInVec.data());
589 fSummingInGraph->Add(summingInGraph, Form(
"%s summing in", tab->GetName()));
590 auto* summingOutGraph =
new TGraphErrors(goodPeaks, energy.data(), summingOutVec.data());
591 fSummingOutGraph->Add(summingOutGraph, Form(
"%s summing out", tab->GetName()));
593 fEfficiencyGraph->Scale();
594 fUncorrEfficiencyGraph->Scale();
595 fEfficiencyGraph->SetAxisTitle(
"energy [keV];corrected efficiency [a.u.]");
596 fUncorrEfficiencyGraph->SetAxisTitle(
"energy [keV];uncorrected efficiency [a.u.]");
597 fPeakAreaGraph->SetAxisTitle(
"energy [keV];peak areas [a.u.]");
598 fSummingInGraph->SetAxisTitle(
"energy [keV];summing in corrections [a.u.]");
599 fSummingOutGraph->SetAxisTitle(
"energy [keV];summing out corrections [a.u.]");
600 fEfficiencyGraph->Write(Form(
"%s_efficiency", fDataType.c_str()), TObject::kOverwrite);
601 fUncorrEfficiencyGraph->Write(Form(
"%s_uncorr_efficiency", fDataType.c_str()), TObject::kOverwrite);
602 fPeakAreaGraph->Write(Form(
"%s_peak_area", fDataType.c_str()), TObject::kOverwrite);
603 fSummingInGraph->Write(Form(
"%s_summing_in", fDataType.c_str()), TObject::kOverwrite);
604 fSummingOutGraph->Write(Form(
"%s_summing_out", fDataType.c_str()), TObject::kOverwrite);
605 fMainDirectory->cd();
608void TEfficiencyDatatypeTab::UpdatePeakType()
610 if(fPeakTypeBox ==
nullptr) {
611 throw std::runtime_error(
"Failed to find peak type box, but got a signal it was selected?");
614 std::cout <<
"peak type box " << fPeakTypeBox << std::flush <<
", getting selected " << fPeakTypeBox->GetSelected() << std::endl;
617 TEfficiencyCalibrator::PeakType(
static_cast<TEfficiencyTab::EPeakType
>(fPeakTypeBox->GetSelected()));
620int TEfficiencyDatatypeTab::Degree()
622 if(fDegreeEntry !=
nullptr) {
623 TEfficiencyCalibrator::Degree(
static_cast<int>(fDegreeEntry->GetNumber()));
625 return TEfficiencyCalibrator::Degree();
634double TEfficiencyDatatypeTab::EfficiencyDebertin(
double* x,
double* par)
636 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);
640double TEfficiencyDatatypeTab::EfficiencyRadware(
double* x,
double* par)
642 double logX = TMath::Log(x[0] / 100.);
643 double logY = TMath::Log(x[0] / 1000.);
644 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]);
645 return TMath::Exp(logEff);
648double TEfficiencyDatatypeTab::EfficiencyPolynomial(
double* x,
double* par)
652 for(
int i = 0; i < par[0]; ++i) {
653 logEff += par[i + 1] * TMath::Power(TMath::Log(x[0]), i);
655 return TMath::Exp(logEff);
658void TEfficiencyDatatypeTab::FitEfficiency()
663 switch(TEfficiencyCalibrator::Degree()) {
665 fEfficiency =
new TF1(
"EfficiencyDebertin", TEfficiencyDatatypeTab::EfficiencyDebertin, 0., 10000., 5);
668 fEfficiency =
new TF1(
"EfficiencyRadware", TEfficiencyDatatypeTab::EfficiencyRadware, 0., 10000., 7);
671 fEfficiency =
new TF1(
"EfficiencyPolynomial", TEfficiencyDatatypeTab::EfficiencyPolynomial, 0., 10000., TEfficiencyCalibrator::Degree() + 1);
672 fEfficiency->FixParameter(0, TEfficiencyCalibrator::Degree());
676 fEfficiencyGraph->Fit(fEfficiency);
679void TEfficiencyDatatypeTab::FittingControl(Int_t
id)
681 int currentTabId = fDataTab->GetCurrent();
682 if(TEfficiencyCalibrator::VerboseLevel() >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": id " <<
id <<
", current tab id " << currentTabId << std::endl; }
686 fEfficiencyTab[currentTabId]->FindPeaks();
687 UpdateEfficiencyGraph();
690 for(
auto& tab : fEfficiencyTab) {
693 UpdateEfficiencyGraph();
700void TEfficiencyDatatypeTab::ReadValues()
702 TEfficiencyCalibrator::Range(fRangeEntry->GetNumber());
703 TEfficiencyCalibrator::Threshold(fThresholdEntry->GetNumber());
704 TEfficiencyCalibrator::BgParam(fBgParamEntry->GetNumberEntry()->GetIntNumber());
705 TEfficiencyCalibrator::Degree(fDegreeEntry->GetNumberEntry()->GetIntNumber());
706 TEfficiencyCalibrator::CalibrationUncertainty(fCalibrationUncertaintyEntry->GetNumber());
712double TEfficiencyCalibrator::fRange = 20.;
713double TEfficiencyCalibrator::fThreshold = 100.;
714int TEfficiencyCalibrator::fBgParam = 20;
715TEfficiencyTab::EPeakType TEfficiencyCalibrator::fPeakType = TEfficiencyTab::EPeakType::kRWPeak;
716int TEfficiencyCalibrator::fDegree = 0;
717double TEfficiencyCalibrator::fCalibrationUncertainty = 1.;
718bool TEfficiencyCalibrator::fShowRemovedFits =
false;
720unsigned int TEfficiencyCalibrator::fLineHeight = 20;
721unsigned int TEfficiencyCalibrator::fWindowWidth = 1200;
723TEfficiencyCalibrator::TEfficiencyCalibrator(
int n...)
724 : TGMainFrame(nullptr, TEfficiencyCalibrator::WindowWidth() + 10, TEfficiencyCalibrator::WindowWidth() / 2)
727 std::remove(
"fitOutput.txt");
732 fHistograms.resize(4);
733 fDataType = {
"Unsuppressed Singles",
"Suppressed Singles",
"Unsuppressed Addback",
"Suppressed Addback"};
737 bool allSourcesFound =
true;
738 for(
int i = 0; i < n; ++i) {
739 const char* name = va_arg(args,
const char*);
740 fFiles.push_back(
new TFile(name));
741 if(!fFiles.back()->IsOpen()) {
742 std::cerr <<
"Failed to open " << i + 1 <<
". file \"" << name <<
"\"" << std::endl;
746 bool goodFile =
false;
748 std::cout <<
"Checking file \"" << name <<
"\":";
750 if(fFiles.back()->FindKey(
"griffinE") !=
nullptr) {
752 fHistograms[0].push_back(std::make_tuple(
753 static_cast<TH1*
>(fFiles.back()->Get(
"griffinE")),
754 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinE180Corr")),
755 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESum180Corr"))));
758 std::cout <<
" found unsuppressed singles";
761 if(fFiles.back()->FindKey(
"griffinESupp") !=
nullptr) {
763 fHistograms[1].push_back(std::make_tuple(
764 static_cast<TH1*
>(fFiles.back()->Get(
"griffinESupp")),
765 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEMixed180Corr")),
766 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESuppSum180Corr"))));
769 std::cout <<
" found suppressed singles";
772 if(fFiles.back()->FindKey(
"griffinEAddback") !=
nullptr) {
774 fHistograms[2].push_back(std::make_tuple(
775 static_cast<TH1*
>(fFiles.back()->Get(
"griffinEAddback")),
776 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEAddback180Corr")),
777 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEAddbackSum180Corr"))));
780 std::cout <<
" found unsuppressed addback";
783 if(fFiles.back()->FindKey(
"griffinESuppAddback") !=
nullptr) {
785 fHistograms[3].push_back(std::make_tuple(
786 static_cast<TH1*
>(fFiles.back()->Get(
"griffinESuppAddback")),
787 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinEMixedAddback180Corr")),
788 static_cast<TH2*
>(fFiles.back()->Get(
"griffinGriffinESuppAddbackSum180Corr"))));
791 std::cout <<
" found suppressed addback";
795 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;
798 std::cerr <<
"Failed to find any histogram in " << i + 1 <<
". file \"" << name <<
"\"" << std::endl;
802 fSources.push_back(
nullptr);
804 if(std::strstr(name,
"22Na") !=
nullptr) {
805 fSources.back() =
new TNucleus(
"22Na");
806 }
else if(std::strstr(name,
"56Co") !=
nullptr) {
807 fSources.back() =
new TNucleus(
"56Co");
808 }
else if(std::strstr(name,
"60Co") !=
nullptr) {
809 fSources.back() =
new TNucleus(
"60Co");
810 }
else if(std::strstr(name,
"133Ba") !=
nullptr) {
811 fSources.back() =
new TNucleus(
"133Ba");
812 }
else if(std::strstr(name,
"152Eu") !=
nullptr) {
813 fSources.back() =
new TNucleus(
"152Eu");
814 }
else if(std::strstr(name,
"241Am") !=
nullptr) {
815 fSources.back() =
new TNucleus(
"241Am");
817 allSourcesFound =
false;
823 auto type = fDataType.begin();
824 for(
auto it = fHistograms.begin(); it != fHistograms.end();) {
825 if(it->size() != fFiles.size()) {
827 std::cout << std::distance(fHistograms.begin(), it) <<
": found " << it->size() <<
" histograms for " << fFiles.size() <<
" files, removing this type" << std::endl;
829 it = fHistograms.erase(it);
830 type = fDataType.erase(type);
838 std::cout <<
"Read " << fFiles.size() <<
" files, got";
839 for(
auto& vec : fHistograms) {
840 std::cout <<
" " << vec.size();
842 std::cout <<
" histograms" << std::endl;
845 if(fHistograms.empty()) {
846 throw std::runtime_error(
"Unable to find any suitable histograms in the provided file(s)!");
850 if(fSources.size() != fFiles.size() || fHistograms[0].size() != fFiles.size() || fHistograms.size() != fDataType.size()) {
851 std::ostringstream error;
852 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;
853 throw std::runtime_error(error.str());
856 fOutput =
new TFile(
"TEfficiencyCalibrator.root",
"recreate");
857 if(!fOutput->IsOpen()) {
858 throw std::runtime_error(
"Unable to open output file \"TEfficiencyCalibrator.root\"!");
862 if(!allSourcesFound) {
863 BuildFirstInterface();
864 MakeFirstConnections();
870 SetWindowName(
"EffiencyCalibrator");
876 Resize(GetDefaultSize());
884TEfficiencyCalibrator::~TEfficiencyCalibrator()
886 for(
auto& file : fFiles) {
889 if(fOutput !=
nullptr) { fOutput->Close(); }
892void TEfficiencyCalibrator::DeleteElement(TGFrame* element)
895 RemoveFrame(element);
900void TEfficiencyCalibrator::BuildFirstInterface()
904 auto* layoutManager =
new TGTableLayout(
this, fFiles.size() + 1, 2,
true, 5);
905 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout <<
"created table layout manager with 2 columns, " << fFiles.size() + 1 <<
" rows" << std::endl; }
906 SetLayoutManager(layoutManager);
910 for(i = 0; i < fFiles.size(); ++i) {
911 fSourceLabel.push_back(
new TGLabel(
this, fFiles[i]->GetName()));
912 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Text height " << fSourceLabel.back()->GetFont()->TextHeight() << std::endl; }
913 fSourceBox.push_back(
new TGComboBox(
this,
"Select source", kSourceBox + fSourceBox.size()));
914 if(fSources[i] !=
nullptr) {
915 fSourceBox.back()->AddEntry(fSources[i]->GetName(), i);
916 fSourceBox.back()->Select(0);
917 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Found source, setting entry to " << fSources[i]->GetName() <<
" and selecting " << fSourceBox.back()->GetSelected() << std::endl; }
919 fSourceBox.back()->AddEntry(
"22Na", k22Na);
920 fSourceBox.back()->AddEntry(
"56Co", k56Co);
921 fSourceBox.back()->AddEntry(
"60Co", k60Co);
922 fSourceBox.back()->AddEntry(
"133Ba", k133Ba);
923 fSourceBox.back()->AddEntry(
"152Eu", k152Eu);
924 fSourceBox.back()->AddEntry(
"241Am", k241Am);
925 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Didn't find source, created source box with " << fSourceBox.back()->GetNumberOfEntries() << std::endl; }
927 fSourceBox.back()->SetMinHeight(200);
928 fSourceBox.back()->Resize(100, LineHeight());
929 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; }
930 AddFrame(fSourceLabel.back(),
new TGTableLayoutHints(0, 1, i, i + 1, kLHintsRight | kLHintsCenterY));
931 AddFrame(fSourceBox.back(),
new TGTableLayoutHints(1, 2, i, i + 1, kLHintsLeft | kLHintsCenterY));
935 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout <<
"Attaching start button to 0, 2, " << i <<
", " << i + 1 << std::endl; }
936 fStartButton =
new TGTextButton(
this,
"Accept && Continue", kStartButton);
938 AddFrame(fStartButton,
new TGTableLayoutHints(0, 2, i, i + 1, kLHintsCenterX | kLHintsCenterY));
942void TEfficiencyCalibrator::MakeFirstConnections()
947 for(
auto* box : fSourceBox) {
948 box->Connect(
"Selected(Int_t, Int_t)",
"TEfficiencyCalibrator",
this,
"SetSource(Int_t, Int_t)");
952 fStartButton->Connect(
"Clicked()",
"TEfficiencyCalibrator",
this,
"Start()");
955void TEfficiencyCalibrator::DisconnectFirst()
958 for(
auto* box : fSourceBox) {
959 box->Disconnect(
"Selected(Int_t, Int_t)",
this,
"SetSource(Int_t, Int_t)");
961 fStartButton->Disconnect(
"Clicked()",
this,
"Start()");
964void TEfficiencyCalibrator::DeleteFirst()
968 DeleteElement(fStartButton);
972void TEfficiencyCalibrator::SetSource(Int_t windowId, Int_t entryId)
974 int index = windowId - kSourceBox;
975 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": windowId " << windowId <<
", entryId " << entryId <<
" => " << index << std::endl; }
976 TNucleus* nucleus = fSources[index];
978 nucleus =
new TNucleus(fSourceBox[index]->GetListBox()->GetEntry(entryId)->GetTitle());
979 fSources[index] = nucleus;
982void TEfficiencyCalibrator::Start()
984 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": fEmitter " << fEmitter <<
", fStartButton " << fStartButton << std::endl; }
985 if(fEmitter ==
nullptr) {
986 fEmitter = fStartButton;
987 TTimer::SingleShot(100,
"TEfficiencyCalibrator",
this,
"HandleTimer()");
991void TEfficiencyCalibrator::HandleTimer()
993 if(fVerboseLevel >
EVerbosity::kBasicFlow) { std::cout << __PRETTY_FUNCTION__ <<
": fEmitter " << fEmitter <<
", fStartButton " << fStartButton << std::endl; }
994 if(fEmitter == fStartButton) {
1004void TEfficiencyCalibrator::SecondWindow()
1008 for(
size_t i = 0; i < fSources.size(); ++i) {
1009 if(fSources[i] ==
nullptr) {
1010 std::cerr <<
"Source " << i <<
" not set!" << std::endl;
1014 std::cout << i <<
" - source " << fSources[i] <<
" = " << fSources[i]->GetName() << std::endl;
1018 for(
size_t i = 0; i < fSources.size(); ++i) {
1019 for(
size_t j = i + 1; j < fSources.size(); ++j) {
1020 if(*(fSources[i]) == *(fSources[j])) {
1021 std::cerr <<
"Duplicate sources: " << i <<
" - " << fSources[i]->GetName() <<
" and " << j <<
" - " << fSources[j]->GetName() << std::endl;
1027 SetLayoutManager(
new TGHorizontalLayout(
this));
1030 fProgressBar =
new TGHProgressBar(
this, TGProgressBar::kFancy, WindowWidth() / 2);
1031 int nofHistograms = 0;
1032 for(
auto& type : fHistograms) {
1033 nofHistograms += type.size();
1036 fProgressBar->SetRange(0.,
static_cast<Float_t
>(nofHistograms));
1037 fProgressBar->Percent(
true);
1038 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout <<
"Set range of progress bar to 0. - " << fProgressBar->GetMax() <<
" = " << fFiles.size() << std::endl; }
1039 AddFrame(fProgressBar,
new TGLayoutHints(kLHintsCenterX | kLHintsCenterY | kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
1045 Resize(TGDimension(WindowWidth(), LineHeight()));
1052 BuildSecondInterface();
1053 MakeSecondConnections();
1056 DeleteElement(fProgressBar);
1062 Resize(TGDimension(WindowWidth(), WindowWidth() / 2));
1069void TEfficiencyCalibrator::BuildSecondInterface()
1071 SetLayoutManager(
new TGHorizontalLayout(
this));
1074 fDatatypeTab =
new TGTab(
this, WindowWidth(), WindowWidth() / 2);
1075 fEfficiencyDatatypeTab.resize(fHistograms.size());
1076 fEfficiencyGraph.resize(fHistograms.size());
1077 if(fVerboseLevel >
EVerbosity::kSubroutines) { std::cout << __PRETTY_FUNCTION__ <<
" creating " << fHistograms.size() <<
" tabs" << std::endl; }
1078 for(
size_t i = 0; i < fHistograms.size(); ++i) {
1079 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; }
1080 auto* frame = fDatatypeTab->AddTab(fDataType[i].c_str());
1081 std::replace(fDataType[i].begin(), fDataType[i].end(),
' ',
'_');
1082 fEfficiencyDatatypeTab[i] =
new TEfficiencyDatatypeTab(
this, fSources, fHistograms[i], frame, fDataType[i], fProgressBar);
1084 fEfficiencyGraph[i] = fEfficiencyDatatypeTab[i]->EfficiencyGraph();
1086 AddFrame(fDatatypeTab,
new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 0, 0, 0, 0));
1091void TEfficiencyCalibrator::MakeSecondConnections()
1095 for(
auto* sourceTab : fEfficiencyDatatypeTab) {
1096 sourceTab->MakeConnections();
1100void TEfficiencyCalibrator::DisconnectSecond()
1103 for(
auto* sourceTab : fEfficiencyDatatypeTab) {
1104 sourceTab->Disconnect();
void Draw(Option_t *opt="") override
double GetIntensityUncertainty() const
double GetIntensity() const
double GetEnergyUncertainty() const