42auto tupleSort = [](std::tuple<Float_t, Float_t, Bool_t> _a, std::tuple<Float_t, Float_t, Bool_t> _b) {
43 return std::get<0>(_a) < std::get<0>(_b);
56 const std::vector<Float_t> &mvaWeights)
59 assert(mvaValues.size() == mvaTargets.size());
60 assert(mvaValues.size() == mvaWeights.size());
62 for (
UInt_t i = 0; i < mvaValues.size(); i++) {
63 fMva.emplace_back(mvaValues[i], mvaWeights[i], mvaTargets[i]);
75 assert(mvaValues.size() == mvaTargets.size());
77 for (
UInt_t i = 0; i < mvaValues.size(); i++) {
78 fMva.emplace_back(mvaValues[i], 1, mvaTargets[i]);
90 for (
UInt_t i = 0; i < mvaSignal.size(); i++) {
91 fMva.emplace_back(mvaSignal[i], 1,
kTRUE);
94 for (
UInt_t i = 0; i < mvaBackground.size(); i++) {
95 fMva.emplace_back(mvaBackground[i], 1,
kFALSE);
105 const std::vector<Float_t> &mvaSignalWeights,
const std::vector<Float_t> &mvaBackgroundWeights)
108 assert(mvaSignal.size() == mvaSignalWeights.size());
109 assert(mvaBackground.size() == mvaBackgroundWeights.size());
111 for (
UInt_t i = 0; i < mvaSignal.size(); i++) {
112 fMva.emplace_back(mvaSignal[i], mvaSignalWeights[i],
kTRUE);
115 for (
UInt_t i = 0; i < mvaBackground.size(); i++) {
116 fMva.emplace_back(mvaBackground[i], mvaBackgroundWeights[i],
kFALSE);
127 if(fGraph)
delete fGraph;
142 if (num_points <= 2) {
146 std::vector<Double_t> specificity_vector;
147 std::vector<Double_t> true_negatives;
148 specificity_vector.reserve(fMva.size());
149 true_negatives.reserve(fMva.size());
152 for (
auto &ev : fMva) {
154 auto weight = std::get<1>(ev);
155 auto isSignal = std::get<2>(ev);
157 true_negatives_sum += weight * (!isSignal ? 1. : 0.);
158 true_negatives.push_back(true_negatives_sum);
161 specificity_vector.push_back(0.0);
162 Double_t total_background = true_negatives_sum;
163 for (
auto &tn : true_negatives) {
165 (total_background <= std::numeric_limits<Double_t>::min()) ? (0.0) : (tn / total_background);
166 specificity_vector.push_back(specificity);
168 specificity_vector.push_back(1.0);
170 return specificity_vector;
178 if (num_points <= 2) {
182 std::vector<Double_t> sensitivity_vector;
183 std::vector<Double_t> true_positives;
184 sensitivity_vector.reserve(fMva.size());
185 true_positives.reserve(fMva.size());
188 for (
auto it = fMva.rbegin(); it != fMva.rend(); ++it) {
190 auto weight = std::get<1>(*it);
191 auto isSignal = std::get<2>(*it);
193 true_positives_sum += weight * (isSignal);
194 true_positives.push_back(true_positives_sum);
196 std::reverse(true_positives.begin(), true_positives.end());
198 sensitivity_vector.push_back(1.0);
199 Double_t total_signal = true_positives_sum;
200 for (
auto &tp : true_positives) {
201 Double_t sensitivity = (total_signal <= std::numeric_limits<Double_t>::min()) ? (0.0) : (tp / total_signal);
202 sensitivity_vector.push_back(sensitivity);
204 sensitivity_vector.push_back(0.0);
206 return sensitivity_vector;
221 assert(0.0 <= effB && effB <= 1.0);
223 auto effS_vec = ComputeSensitivity(num_points);
224 auto effB_vec = ComputeSpecificity(num_points);
227 auto complement = [](
Double_t x) {
return 1 -
x; };
228 std::transform(effB_vec.begin(), effB_vec.end(), effB_vec.begin(), complement);
231 std::reverse(effS_vec.begin(), effS_vec.end());
232 std::reverse(effB_vec.begin(), effB_vec.end());
238 return rocSpline.
Eval(effB);
252 auto sensitivity = ComputeSensitivity(num_points);
253 auto specificity = ComputeSpecificity(num_points);
256 for (
UInt_t i = 0; i < sensitivity.size() - 1; i++) {
258 Double_t currFnr = 1 - sensitivity[i];
259 Double_t nextFnr = 1 - sensitivity[i + 1];
261 integral += 0.5 * (nextFnr - currFnr) * (specificity[i] + specificity[i + 1]);
278 if (fGraph !=
nullptr) {
282 auto sensitivity = ComputeSensitivity(num_points);
283 auto specificity = ComputeSpecificity(num_points);
285 fGraph =
new TGraph(sensitivity.size(), &sensitivity[0], &specificity[0]);
A TGraph is an object made of two arrays X and Y with npoints each.
ostringstream derivative to redirect and format output
std::vector< Double_t > ComputeSpecificity(const UInt_t num_points)
ROCCurve(const std::vector< std::tuple< Float_t, Float_t, Bool_t > > &mvas)
Double_t GetEffSForEffB(Double_t effB, const UInt_t num_points=41)
Calculate the signal efficiency (sensitivity) for a given background efficiency (sensitivity).
std::vector< Double_t > ComputeSensitivity(const UInt_t num_points)
Double_t GetROCIntegral(const UInt_t points=41)
Calculates the ROC integral (AUC)
MsgLogger & Log() const
message logger
std::vector< std::tuple< Float_t, Float_t, Bool_t > > fMva
TGraph * GetROCCurve(const UInt_t points=100)
Returns a new TGraph containing the ROC curve.
Linear interpolation of TGraph.
virtual Double_t Eval(Double_t x) const
returns linearly interpolated TGraph entry around x
create variable transformations
void mvas(TString dataset, TString fin="TMVA.root", HistType htype=kMVAType, Bool_t useTMVAStyle=kTRUE)