13 const std::vector<HistAxis>& axes,
14 const std::vector<double>& cut_pos,
15 std::vector<Spectrum>& sigs,
16 std::vector<Spectrum>& bkgs)
18 assert(cut_pos.size() == axes.size());
20 sigs.reserve(axes.size());
21 bkgs.reserve(axes.size());
23 for(
unsigned int i = 0; i < axes.size(); ++i){
24 Cut nminusone = presel;
25 for(
unsigned j = 0; j < axes.size(); ++j){
28 nminusone = nminusone && axes[j].GetVars()[0] > cut_pos[j];
31 sigs.emplace_back(loader, axes[i], nminusone && sigcut);
32 bkgs.emplace_back(loader, axes[i], nminusone && !sigcut);
44 for(
int binIdx = hsig->GetNbinsX()+1; binIdx >= 0; --binIdx){
45 nsig += hsig->GetBinContent(binIdx);
46 nbkg += hbkg->GetBinContent(binIdx);
47 const double fom = nsig ? nsig/sqrt(nsig+nbkg) : 0;
50 best_cut = hsig->GetXaxis()->GetBinLowEdge(binIdx);
62 const std::vector<HistAxis>& axes,
63 std::vector<double>& cut_pos)
66 std::vector<Spectrum> sigs, bkgs;
74 for(
unsigned int cutIdx = 0; cutIdx < axes.size(); ++cutIdx){
75 TH1* hsig = sigs[cutIdx].ToTH1(pot, kRed);
76 TH1* hbkg = bkgs[cutIdx].ToTH1(pot, kBlue);
91 std::cout <<
"Updated cut on '" << axes[best_idx].GetLabels()[0] <<
"' to " << best_cut <<
". FOM now " << best_fom << std::endl;
94 cut_pos[best_idx] = best_cut;
103 const std::vector<HistAxis>& axes,
104 std::vector<double>& cut_pos)
106 std::cout <<
"Initial cuts:" << std::endl;
107 for(
unsigned int i = 0; i < axes.size(); ++i){
108 std::cout <<
" " << axes[i].GetLabels()[0] <<
" > " << cut_pos[i] << std::endl;
113 const double new_fom =
OptimizeOneCut(wildcard, pot, sigcut, presel, axes, cut_pos);
115 if(new_fom < fom*1.01)
break;
119 std::cout <<
"Final optimized cuts:" << std::endl;
120 for(
unsigned int i = 0; i < axes.size(); ++i){
121 std::cout <<
" " << axes[i].GetLabels()[0] <<
" > " << cut_pos[i] << std::endl;
void OptimizeCuts(const std::string &wildcard, double pot, const Cut &sigcut, const Cut &presel, const std::vector< HistAxis > &axes, std::vector< double > &cut_pos)
Repeatedly invoke OptimizeOneCut until the FOM increase becomes small.
void MakeNMinusOneSpectra(SpectrumLoader &loader, const Cut &sigcut, const Cut &presel, const std::vector< HistAxis > &axes, const std::vector< double > &cut_pos, std::vector< Spectrum > &sigs, std::vector< Spectrum > &bkgs)
Make a series of spectra leaving out one cut in turn.
process_name opflashCryoW ana
double FindOptimumCut(TH1 *hsig, TH1 *hbkg, double &best_fom)
Search for optimum cut position given signal and background histograms.
virtual void Go() override
Load all the registered spectra.
Collaborates with Spectrum and OscillatableSpectrum to fill spectra from CAF files.
Template for Cut and SpillCut.
BEGIN_PROLOG could also be cout
double OptimizeOneCut(const std::string &wildcard, double pot, const Cut &sigcut, const Cut &presel, const std::vector< HistAxis > &axes, std::vector< double > &cut_pos)
Scan all cuts and update the one giving the largest FOM gain.