Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-19 23:20:30

0001 #include "anautil.h"
0002 
0003 bool PASS() { return true; }
0004 float UNITY() { return 1; }
0005 
0006 //_______________________________________________________________________________________________________
0007 RooUtil::Cutflow::Cutflow()
0008     : cuttree("Root"),
0009       last_active_cut(0),
0010       ofile(0),
0011       t(0),
0012       tx(0),
0013       iseventlistbooked(false),
0014       seterrorcount(0),
0015       doskipsysthist(0),
0016       dosavettreex(0),
0017       cutflow_booked(false) {
0018   cuttreemap["Root"] = &cuttree;
0019 }
0020 
0021 //_______________________________________________________________________________________________________
0022 RooUtil::Cutflow::Cutflow(TFile* o)
0023     : cuttree("Root"),
0024       last_active_cut(0),
0025       ofile(o),
0026       t(0),
0027       tx(0),
0028       iseventlistbooked(false),
0029       seterrorcount(0),
0030       doskipsysthist(0),
0031       dosavettreex(0),
0032       cutflow_booked(false) {
0033   cuttreemap["Root"] = &cuttree;
0034 }
0035 
0036 //_______________________________________________________________________________________________________
0037 RooUtil::Cutflow::~Cutflow() {
0038   if (booked_histograms.size() > 0) {
0039     for (auto& [k, v] : booked_histograms) {
0040       delete v;
0041     }
0042   }
0043   if (booked_2dhistograms.size() > 0) {
0044     for (auto& [k, v] : booked_2dhistograms) {
0045       delete v;
0046     }
0047   }
0048 }
0049 
0050 //_______________________________________________________________________________________________________
0051 void RooUtil::Cutflow::addToCutTreeMap(TString n) {
0052   if (cuttreemap.find(n.Data()) == cuttreemap.end())
0053     cuttreemap[n.Data()] = cuttree.getCutPointer(n);
0054   else
0055     error(TString::Format("Cut %s already exists! no duplicate cut names allowed!", n.Data()));
0056 }
0057 
0058 //_______________________________________________________________________________________________________
0059 void RooUtil::Cutflow::setLastActiveCut(TString n) { last_active_cut = cuttree.getCutPointer(n); }
0060 
0061 //_______________________________________________________________________________________________________
0062 void RooUtil::Cutflow::printCuts() { cuttree.printCuts(); }
0063 
0064 //_______________________________________________________________________________________________________
0065 RooUtil::CutTree& RooUtil::Cutflow::getCut(TString n) {
0066   RooUtil::CutTree& c = cuttree.getCut(n);
0067   setLastActiveCut(n);
0068   return c;
0069 }
0070 
0071 #ifdef USE_CUTLAMBDA
0072 //_______________________________________________________________________________________________________
0073 void RooUtil::Cutflow::addCut(TString n, std::function<bool()> cut, std::function<float()> weight) {
0074   cuttree.addCut(n);
0075   addToCutTreeMap(n);
0076   setLastActiveCut(n);
0077   setCut(n, cut, weight);
0078 }
0079 
0080 //_______________________________________________________________________________________________________
0081 void RooUtil::Cutflow::addCutToLastActiveCut(TString n, std::function<bool()> cut, std::function<float()> weight) {
0082   last_active_cut->addCut(n);
0083   addToCutTreeMap(n);
0084   setLastActiveCut(n);
0085   setCut(n, cut, weight);
0086 }
0087 
0088 #else
0089 
0090 //_______________________________________________________________________________________________________
0091 void RooUtil::Cutflow::addCut(TString n) {
0092   cuttree.addCut(n);
0093   addToCutTreeMap(n);
0094   setLastActiveCut(n);
0095 }
0096 
0097 //_______________________________________________________________________________________________________
0098 void RooUtil::Cutflow::addCutToLastActiveCut(TString n) {
0099   last_active_cut->addCut(n);
0100   addToCutTreeMap(n);
0101   setLastActiveCut(n);
0102 }
0103 
0104 #endif
0105 
0106 //_______________________________________________________________________________________________________
0107 void RooUtil::Cutflow::removeCut(TString n) {
0108   RooUtil::CutTree* c = cuttree.getCutPointer(n);
0109   c->parent->children.erase(std::find(c->parent->children.begin(), c->parent->children.end(), c));
0110   cuttreemap.erase(cuttreemap.find(n.Data()));
0111 }
0112 
0113 //_______________________________________________________________________________________________________
0114 void RooUtil::Cutflow::filterCuts(std::vector<TString> ns) {
0115   //
0116   std::vector<TString> to_not_remove;
0117   for (auto& n : ns) {
0118     std::vector<TString> cutlist = cuttree.getCutList(n);
0119     for (auto& cut : cutlist) {
0120       to_not_remove.push_back(cut);
0121     }
0122   }
0123 
0124   for (auto& n : ns) {
0125     std::vector<TString> cutlist = cuttree.getCutList(n);
0126     for (unsigned int i = 0; i < cutlist.size() - 1; ++i) {
0127       RooUtil::CutTree* cut = cuttree.getCutPointer(cutlist[i]);
0128       std::vector<RooUtil::CutTree*> toremove;
0129       for (auto& child : cut->children) {
0130         if (not child->name.EqualTo(cutlist[i + 1])) {
0131           if (std::find(to_not_remove.begin(), to_not_remove.end(), child->name) == to_not_remove.end())
0132             toremove.push_back(child);
0133         }
0134       }
0135       for (auto& child : toremove) {
0136         cut->children.erase(std::find(cut->children.begin(), cut->children.end(), child));
0137         cuttreemap.erase(cuttreemap.find(child->name.Data()));
0138       }
0139     }
0140   }
0141 }
0142 
0143 //_______________________________________________________________________________________________________
0144 void RooUtil::Cutflow::setCutLists(std::vector<TString> regions) {
0145   for (auto& region : regions) {
0146     cutlists[region] = cuttree.getCutList(region);
0147     //        std::cout << region << std::endl;
0148     //        for (auto& cutname : cutlists[region])
0149     //            std::cout << cutname << std::endl;
0150   }
0151   for (auto& region : regions) {
0152     for (auto& cutname : cutlists[region]) {
0153       cuttreelists[region].push_back(cuttreemap[cutname.Data()]);
0154     }
0155   }
0156 }
0157 
0158 //_______________________________________________________________________________________________________
0159 void RooUtil::Cutflow::addCutToSkipCutflowList(TString n) {
0160   if (std::find(cutflow_nofill_cut_list.begin(), cutflow_nofill_cut_list.end(), n) == cutflow_nofill_cut_list.end())
0161     cutflow_nofill_cut_list.push_back(n);
0162 }
0163 
0164 //_______________________________________________________________________________________________________
0165 void RooUtil::Cutflow::bookCutflowTree() {
0166   if (!t) {
0167     ofile->cd();
0168     t = new TTree("cut_tree", "cut_tree");
0169     t->SetDirectory(0);
0170   }
0171   if (!tx) {
0172     ofile->cd();
0173     tx = new TTreeX(t);
0174   }
0175   RooUtil::CutflowUtil::createCutflowBranches(cutlists, *tx);
0176   createWgtSystBranches();
0177   //    t->Print();
0178 }
0179 
0180 //_______________________________________________________________________________________________________
0181 void RooUtil::Cutflow::bookCutflowHistograms() {
0182   if (cutflow_booked) {
0183     error("bookCutflowHistograms():: cutflows already booked! yet you called again to book it! Check your user code!");
0184   }
0185   cutflow_booked = true;
0186   bookCutflowHistograms_v1();
0187 }
0188 
0189 //_______________________________________________________________________________________________________
0190 void RooUtil::Cutflow::bookCutflowHistograms_v2() {
0191   ofile->cd();
0192 
0193   // Nominal
0194   for (auto& cuttreelist : cuttreelists) {
0195     THist* h = new THist(cuttreelist.first + "_cutflow", "", cuttreelist.second.size(), 0, cuttreelist.second.size());
0196     THist* h_raw =
0197         new THist(cuttreelist.first + "_rawcutflow", "", cuttreelist.second.size(), 0, cuttreelist.second.size());
0198     h->Sumw2();
0199     h_raw->Sumw2();
0200     h->SetDirectory(0);
0201     h_raw->SetDirectory(0);
0202     std::vector<int*> passes;
0203     std::vector<float*> weights;
0204     for (auto& ct : cuttreelist.second) {
0205       passes.push_back(&(ct->pass));
0206       weights.push_back(&(ct->weight));
0207     }
0208     cutflow_histograms_v2.push_back(std::make_tuple(h, passes, weights, UNITY));
0209     rawcutflow_histograms_v2.push_back(std::make_tuple(h_raw, passes));
0210   }
0211 
0212   // Wgt varying systematic cutflow
0213   for (auto& syst : systs) {
0214     for (auto& cuttreelist : cuttreelists) {
0215       THist* h =
0216           new THist(cuttreelist.first + syst + "_cutflow", "", cuttreelist.second.size(), 0, cuttreelist.second.size());
0217       THist* h_raw = new THist(
0218           cuttreelist.first + syst + "_rawcutflow", "", cuttreelist.second.size(), 0, cuttreelist.second.size());
0219       h->Sumw2();
0220       h_raw->Sumw2();
0221       h->SetDirectory(0);
0222       h_raw->SetDirectory(0);
0223       std::vector<int*> passes;
0224       std::vector<float*> weights;
0225       for (auto& ct : cuttreelist.second) {
0226         passes.push_back(&(ct->pass));
0227         weights.push_back(&(ct->weight));
0228       }
0229       cutflow_histograms_v2.push_back(std::make_tuple(h, passes, weights, systs_funcs[syst]));
0230       rawcutflow_histograms_v2.push_back(std::make_tuple(h_raw, passes));
0231     }
0232   }
0233 
0234   // Nominal
0235   for (unsigned int i = 0; i < cutsysts.size(); ++i) {
0236     TString cutsyst = cutsysts[i];
0237     for (auto& cuttreelist : cuttreelists) {
0238       THist* h = new THist(
0239           cuttreelist.first + cutsyst + "_cutflow", "", cuttreelist.second.size(), 0, cuttreelist.second.size());
0240       THist* h_raw = new THist(
0241           cuttreelist.first + cutsyst + "_rawcutflow", "", cuttreelist.second.size(), 0, cuttreelist.second.size());
0242       h->Sumw2();
0243       h_raw->Sumw2();
0244       h->SetDirectory(0);
0245       h_raw->SetDirectory(0);
0246       std::vector<int*> passes;
0247       std::vector<float*> weights;
0248       for (auto& ct : cuttreelist.second) {
0249         passes.push_back(&(ct->systpasses[i]));
0250         weights.push_back(&(ct->systweights[i]));
0251       }
0252       cutflow_histograms_v2.push_back(std::make_tuple(h, passes, weights, UNITY));
0253       rawcutflow_histograms_v2.push_back(std::make_tuple(h_raw, passes));
0254     }
0255   }
0256 }
0257 
0258 //_______________________________________________________________________________________________________
0259 void RooUtil::Cutflow::bookCutflowHistograms_v1() {
0260   ofile->cd();
0261 
0262   std::tie(cutflow_histograms, rawcutflow_histograms) = RooUtil::CutflowUtil::createCutflowHistograms(cutlists);
0263 
0264   for (auto& syst : systs) {
0265     std::map<CUTFLOWMAPSTRING, THist*> cutflow_histograms_tmp;
0266     std::map<CUTFLOWMAPSTRING, THist*> rawcutflow_histograms_tmp;
0267     std::tie(cutflow_histograms_tmp, rawcutflow_histograms_tmp) =
0268         RooUtil::CutflowUtil::createCutflowHistograms(cutlists, syst);
0269     cutflow_histograms.insert(cutflow_histograms_tmp.begin(), cutflow_histograms_tmp.end());
0270     rawcutflow_histograms.insert(rawcutflow_histograms_tmp.begin(), rawcutflow_histograms_tmp.end());
0271   }
0272 
0273   for (auto& cutsyst : cutsysts) {
0274     std::map<CUTFLOWMAPSTRING, THist*> cutflow_histograms_tmp;
0275     std::map<CUTFLOWMAPSTRING, THist*> rawcutflow_histograms_tmp;
0276     std::tie(cutflow_histograms_tmp, rawcutflow_histograms_tmp) =
0277         RooUtil::CutflowUtil::createCutflowHistograms(cutlists, cutsyst);
0278     cutflow_histograms.insert(cutflow_histograms_tmp.begin(), cutflow_histograms_tmp.end());
0279     rawcutflow_histograms.insert(rawcutflow_histograms_tmp.begin(), rawcutflow_histograms_tmp.end());
0280   }
0281 
0282   for (auto& cutflow_histogram : cutflow_histograms) {
0283     TString msg = "Booked cutflow histogram for cut = " + cutflow_histogram.first;
0284     print(msg);
0285   }
0286   for (auto& rawcutflow_histogram : rawcutflow_histograms) {
0287     TString msg = "Booked rawcutflow histogram for cut = " + rawcutflow_histogram.first;
0288     print(msg);
0289   }
0290 }
0291 
0292 //_______________________________________________________________________________________________________
0293 void RooUtil::Cutflow::bookCutflowsForRegions(std::vector<TString> regions) {
0294   setCutLists(regions);
0295   bookCutflowTree();
0296   bookCutflowHistograms();
0297 }
0298 
0299 //_______________________________________________________________________________________________________
0300 void RooUtil::Cutflow::bookCutflows() {
0301   std::vector<TString> regions = cuttree.getEndCuts();
0302   setCutLists(regions);
0303   bookCutflowTree();
0304   bookCutflowHistograms();
0305 }
0306 
0307 //_______________________________________________________________________________________________________
0308 void RooUtil::Cutflow::saveOutput() {
0309   saveCutflows();
0310   saveHistograms();
0311   saveTTreeX();
0312   TString filename = ofile->GetName();
0313   TString msg = "Wrote output to " + filename;
0314   print(msg);
0315 }
0316 
0317 //_______________________________________________________________________________________________________
0318 void RooUtil::Cutflow::saveCutflows() {
0319   // Save cutflow histograms
0320   ofile->cd();
0321   RooUtil::CutflowUtil::saveCutflowHistograms(cutflow_histograms, rawcutflow_histograms);
0322 }
0323 
0324 //_______________________________________________________________________________________________________
0325 void RooUtil::Cutflow::saveHistograms() {
0326   ofile->cd();
0327   for (auto& pair : booked_histograms)
0328     pair.second->Write();
0329   for (auto& pair : booked_2dhistograms)
0330     pair.second->Write();
0331 }
0332 
0333 //_______________________________________________________________________________________________________
0334 void RooUtil::Cutflow::saveTTreeX() {
0335   if (dosavettreex) {
0336     ofile->cd();
0337     tx->save(ofile);
0338   }
0339 }
0340 
0341 #ifdef USE_CUTLAMBDA
0342 //_______________________________________________________________________________________________________
0343 void RooUtil::Cutflow::setCut(TString cutname, std::function<bool()> pass, std::function<float()> weight) {
0344   cuttreemap[cutname.Data()]->pass_this_cut_func = pass;
0345   cuttreemap[cutname.Data()]->weight_this_cut_func = weight;
0346 }
0347 
0348 //_______________________________________________________________________________________________________
0349 void RooUtil::Cutflow::setCutSyst(TString cutname,
0350                                   TString syst,
0351                                   std::function<bool()> pass,
0352                                   std::function<float()> weight) {
0353   if (cuttreemap[cutname.Data()]->systs.find(syst) == cuttreemap[cutname.Data()]->systs.end()) {
0354     error(
0355         TString::Format("setCutSyst():: Did not find syst=%s from the cut=%s! Did you actually book this syst for the "
0356                         "cut properly using addCutSyst() ?",
0357                         syst.Data(),
0358                         cutname.Data()));
0359   }
0360   cuttreemap[cutname.Data()]->systs[syst]->pass_this_cut_func = pass;
0361   cuttreemap[cutname.Data()]->systs[syst]->weight_this_cut_func = weight;
0362 }
0363 
0364 #else
0365 
0366 //_______________________________________________________________________________________________________
0367 void RooUtil::Cutflow::setCut(TString cutname, bool pass, float weight) {
0368   if (!tx) {
0369     TString msg = "No TTreeX object set, setCut() for " + cutname;
0370     printSetFunctionError(msg);
0371     return;
0372   }
0373 
0374 #ifdef USE_TTREEX
0375   tx->setBranch<bool>(cutname, pass, false, true);
0376   tx->setBranch<float>(cutname + "_weight", weight, false, true);
0377 #else
0378   cuttreemap[cutname.Data()]->pass_this_cut = pass;
0379   cuttreemap[cutname.Data()]->weight_this_cut = weight;
0380 #endif
0381 }
0382 
0383 //_______________________________________________________________________________________________________
0384 void RooUtil::Cutflow::setCutSyst(TString cutname, TString syst, bool pass, float weight) {
0385   if (!tx) {
0386     TString msg = "No TTreeX object set, setCutSyst() for " + cutname + ", " + syst;
0387     printSetFunctionError(msg);
0388     return;
0389   }
0390 #ifdef USE_TTREEX
0391   tx->setBranch<bool>(cutname + syst, pass, false, true);
0392   tx->setBranch<float>(cutname + syst + "_weight", weight, false, true);
0393 #else
0394   cuttreemap[cutname.Data()]->systs[syst]->pass_this_cut = pass;
0395   cuttreemap[cutname.Data()]->systs[syst]->weight_this_cut = weight;
0396 #endif
0397 }
0398 
0399 #endif  // USE_CUTLAMBDA
0400 
0401 //_______________________________________________________________________________________________________
0402 void RooUtil::Cutflow::setWgtSyst(TString syst, float weight) {
0403   if (!tx) {
0404     TString msg = "No TTreeX object set, setWgtSyst() for " + syst;
0405     printSetFunctionError(msg);
0406     return;
0407   }
0408   tx->setBranch<float>(syst, weight, false, true);
0409 }
0410 
0411 //_______________________________________________________________________________________________________
0412 void RooUtil::Cutflow::addCutSyst(TString syst, std::vector<TString> pattern, std::vector<TString> vetopattern) {
0413   cutsysts.push_back(syst);
0414   cuttree.addSyst(syst, pattern, vetopattern);
0415 }
0416 
0417 #ifdef USE_CUTLAMBDA
0418 //_______________________________________________________________________________________________________
0419 void RooUtil::Cutflow::addWgtSyst(TString syst, std::function<float()> weight) {
0420   systs.push_back(syst);
0421   systs_funcs[syst] = weight;
0422 }
0423 #else
0424 //_______________________________________________________________________________________________________
0425 void RooUtil::Cutflow::addWgtSyst(TString syst) { systs.push_back(syst); }
0426 #endif
0427 
0428 //_______________________________________________________________________________________________________
0429 void RooUtil::Cutflow::createWgtSystBranches() {
0430   for (auto& syst : systs) {
0431     if (!tx->hasBranch<float>(syst))
0432       tx->createBranch<float>(syst);
0433   }
0434 }
0435 
0436 //_______________________________________________________________________________________________________
0437 void RooUtil::Cutflow::setVariable(TString varname, float val) {
0438   if (!tx) {
0439     TString msg = "No TTreeX object set, setVariable() for " + varname;
0440     printSetFunctionError(msg);
0441     return;
0442   }
0443   tx->setBranch<float>(varname, val, false, true);
0444 }
0445 
0446 //_______________________________________________________________________________________________________
0447 void RooUtil::Cutflow::setEventID(int run, int lumi, unsigned long long evt) {
0448   if (!tx) {
0449     TString msg = "No TTreeX object set, setEventID()";
0450     printSetFunctionError(msg);
0451     return;
0452   }
0453   tx->setBranch<int>("run", run, false, true);
0454   tx->setBranch<int>("lumi", lumi, false, true);
0455   tx->setBranch<unsigned long long>("evt", evt, false, true);
0456 }
0457 
0458 //_______________________________________________________________________________________________________
0459 void RooUtil::Cutflow::bookEventLists() {
0460   if (!tx)
0461     error("bookEventLists():: No TTreeX has been set. Forgot to call bookCutflows()?");
0462   if (!tx->hasBranch<int>("run"))
0463     tx->createBranch<int>("run");
0464   if (!tx->hasBranch<int>("lumi"))
0465     tx->createBranch<int>("lumi");
0466   if (!tx->hasBranch<unsigned long long>("evt"))
0467     tx->createBranch<unsigned long long>("evt");
0468   iseventlistbooked = true;
0469 }
0470 
0471 //_______________________________________________________________________________________________________
0472 void RooUtil::Cutflow::fill() {
0473 #ifdef USE_TTREEX
0474   if (!tx) {
0475     TString msg = "No TTreeX object set, fill()";
0476     printSetFunctionError(msg);
0477     return;
0478   }
0479   tx->setBranch<bool>("Root", 1);          // Root is internally set
0480   tx->setBranch<float>("Root_weight", 1);  // Root is internally set
0481 #else
0482   cuttreemap["Root"]->pass_this_cut = 1;
0483   cuttreemap["Root"]->weight_this_cut = 1;
0484 #endif
0485 
0486   // Evaluate nominal selection cutflows (the non cut varying selections)
0487   cuttree.evaluate(*tx, "", iseventlistbooked);
0488 
0489   // Nominal cutflow
0490   fillCutflows();
0491 
0492   // Wgt systematic variations
0493   for (auto& syst : systs)
0494     fillCutflows(syst);
0495 
0496   // Fill nominal histograms
0497   fillHistograms();
0498 
0499   if (not doskipsysthist) {
0500     // Wgt systematic variations
0501     for (auto& syst : systs)
0502       fillHistograms(syst);
0503   }
0504 
0505   for (auto& cutsyst : cutsysts) {
0506     cuttree.evaluate(*tx, cutsyst, iseventlistbooked);
0507     fillCutflows(cutsyst, false);
0508     if (not doskipsysthist)
0509       fillHistograms(cutsyst, false);
0510   }
0511 
0512   if (tx) {
0513     if (dosavettreex)
0514       tx->fill();
0515 
0516     tx->clear();
0517   }
0518 }
0519 
0520 #ifdef USE_CUTLAMBDA
0521 //_______________________________________________________________________________________________________
0522 void RooUtil::Cutflow::fillCutflows(TString syst, bool iswgtsyst) { fillCutflows_v2(syst, iswgtsyst); }
0523 
0524 //_______________________________________________________________________________________________________
0525 void RooUtil::Cutflow::fillCutflows_v1(TString syst, bool iswgtsyst) {
0526   for (auto& pair : cutlists) {
0527     const TString& region_name = pair.first;
0528     std::vector<TString>& cutlist = pair.second;
0529     float wgtsyst = (!syst.IsNull() and iswgtsyst) ? systs_funcs[syst]() : 1;
0530     fillCutflow(cutlist,
0531                 cutflow_histograms[(region_name + syst).Data()],
0532                 rawcutflow_histograms[(region_name + syst).Data()],
0533                 wgtsyst);
0534   }
0535 }
0536 
0537 //_______________________________________________________________________________________________________
0538 void RooUtil::Cutflow::fillCutflows_v2(TString syst, bool iswgtsyst) {
0539   for (auto& pair : cuttreelists) {
0540     const TString& region_name = pair.first;
0541     std::vector<RooUtil::CutTree*>& cuttreelist = pair.second;
0542     float wgtsyst = (!syst.IsNull() and iswgtsyst) ? systs_funcs[syst]() : 1;
0543     fillCutflow_v2(cuttreelist,
0544                    cutflow_histograms[(region_name + syst).Data()],
0545                    rawcutflow_histograms[(region_name + syst).Data()],
0546                    wgtsyst);
0547   }
0548 }
0549 #else
0550 //_______________________________________________________________________________________________________
0551 void RooUtil::Cutflow::fillCutflows(TString syst, bool iswgtsyst) {
0552   for (auto& pair : cutlists) {
0553     const TString& region_name = pair.first;
0554     std::vector<TString>& cutlist = pair.second;
0555     float wgtsyst = (!syst.IsNull() and iswgtsyst) ? tx->getBranch<float>(syst) : 1;
0556     fillCutflow(cutlist,
0557                 cutflow_histograms[(region_name + syst).Data()],
0558                 rawcutflow_histograms[(region_name + syst).Data()],
0559                 wgtsyst);
0560   }
0561 }
0562 #endif
0563 
0564 //_______________________________________________________________________________________________________
0565 void RooUtil::Cutflow::fillCutflow(std::vector<TString>& cutlist, THist* h, THist* hraw, float wgtsyst) {
0566   for (unsigned int i = 0; i < cutlist.size(); ++i) {
0567     int& pass = cuttreemap[cutlist[i].Data()]->pass;
0568     if (pass) {
0569       float& weight = cuttreemap[cutlist[i].Data()]->weight;
0570       h->Fill(i, weight * wgtsyst);
0571       hraw->Fill(i, 1);
0572     } else {
0573       return;
0574     }
0575   }
0576 }
0577 
0578 //_______________________________________________________________________________________________________
0579 void RooUtil::Cutflow::fillCutflow_v2(std::vector<RooUtil::CutTree*>& cuttreelist,
0580                                       THist* h,
0581                                       THist* hraw,
0582                                       float wgtsyst) {
0583   for (unsigned int i = 0; i < cuttreelist.size(); ++i) {
0584     RooUtil::CutTree* ct = cuttreelist[i];
0585     // if (std::find(cutflow_nofill_cut_list.begin(), cutflow_nofill_cut_list.end(), ct->name) != cutflow_nofill_cut_list.end())
0586     //     continue;
0587     int& pass = ct->pass;
0588     if (pass) {
0589       float& weight = ct->weight;
0590       h->Fill(i, weight * wgtsyst);
0591       hraw->Fill(i, 1);
0592     } else {
0593       return;
0594     }
0595   }
0596 }
0597 
0598 //_______________________________________________________________________________________________________
0599 void RooUtil::Cutflow::fillHistograms(TString syst, bool iswgtsyst) {
0600 #ifdef USE_CUTLAMBDA
0601   float wgtsyst = (!syst.IsNull() and iswgtsyst) ? systs_funcs[syst]() : 1;
0602   cuttree.fillHistograms(syst, wgtsyst);
0603 #else
0604   float wgtsyst = (!syst.IsNull() and iswgtsyst) ? tx->getBranch<float>(syst) : 1.;
0605   cuttree.fillHistograms(*tx, syst, wgtsyst);
0606 #endif
0607 
0608   //    for (auto& key1d : booked_histograms_nominal_keys)
0609   //    {
0610   //        TString cutname = std::get<0>(key1d);
0611   //        std::get<1>(key1d) = syst;
0612   //        TString varname = std::get<2>(key1d);
0613   //        bool& passed = cuttreemap[cutname.Data()]->pass;
0614   //        if (!passed)
0615   //            continue;
0616   //        float& weight = cuttreemap[cutname.Data()]->weight;
0617   //        float wgtsyst = (!syst.IsNull() and iswgtsyst)? tx->getBranch<float>(syst) : 1.;
0618   //        THist* h = booked_histograms[key1d];
0619   //        h->Fill(tx->getBranch<float>(varname), weight * wgtsyst);
0620   //    }
0621   //
0622   //    for (auto& key2d : booked_2dhistograms_nominal_keys)
0623   //    {
0624   //        TString cutname = std::get<0>(key2d);
0625   //        std::get<1>(key2d) = syst;
0626   //        TString varname = std::get<2>(key2d);
0627   //        TString varnamey = std::get<3>(key2d);
0628   //        bool& passed = cuttreemap[cutname.Data()]->pass;
0629   //        if (!passed)
0630   //            continue;
0631   //        float& weight = cuttreemap[cutname.Data()]->weight;
0632   //        float wgtsyst = (!syst.IsNull() and iswgtsyst)? tx->getBranch<float>(syst) : 1.;
0633   //        TH2F* h = booked_2dhistograms[key2d];
0634   //        h->Fill(tx->getBranch<float>(varname), tx->getBranch<float>(varnamey), weight * wgtsyst);
0635   //    }
0636 
0637   //    for (auto& pair : booked_histograms)
0638   //    {
0639   //        TString cutname = std::get<0>(pair.first);
0640   //        TString sysname = std::get<1>(pair.first);
0641   //        TString varname = std::get<2>(pair.first);
0642   //        THist* h = pair.second;
0643   //        bool& passed = cuttreemap[cutname.DATA()]->pass;
0644   //        float& weight = cuttreemap[cutname.DATA()]->weight;
0645   //        float wgtsyst = sysname.IsNull() ? 1. : tx->getBranch<float>(sysname);
0646   //        if (passed)
0647   //            h->Fill(tx->getBranch<float>(varname), weight * wgtsyst);
0648   //    }
0649   //
0650   //    for (auto& pair : booked_2dhistograms)
0651   //    {
0652   //        TString cutname = std::get<0>(pair.first);
0653   //        TString sysname = std::get<1>(pair.first);
0654   //        TString varname = std::get<2>(pair.first);
0655   //        TString varnamey = std::get<3>(pair.first);
0656   //        TH2F* h = pair.second;
0657   //        bool& passed = cuttreemap[cutname.DATA()]->pass;
0658   //        float& weight = cuttreemap[cutname.DATA()]->weight;
0659   //        float wgtsyst = sysname.IsNull() ? 1. : tx->getBranch<float>(sysname);
0660   //        if (passed)
0661   //            h->Fill(tx->getBranch<float>(varname), tx->getBranch<float>(varnamey), weight * wgtsyst);
0662   //    }
0663 }
0664 
0665 //_______________________________________________________________________________________________________
0666 void RooUtil::Cutflow::bookHistograms(Histograms& histograms) {
0667   std::vector<TString> regions = cuttree.getEndCuts();
0668   for (auto& region : regions) {
0669     std::vector<TString> cutlist = cuttree.getCutList(region);
0670     bookHistograms(histograms, cutlist);
0671   }
0672 }
0673 
0674 //_______________________________________________________________________________________________________
0675 void RooUtil::Cutflow::bookHistograms(Histograms& histograms, std::vector<TString> cutlist) {
0676   for (auto& cut : cutlist) {
0677     bookHistogramsForCut(histograms, cut);
0678   }
0679 }
0680 
0681 #ifdef USE_CUTLAMBDA
0682 //_______________________________________________________________________________________________________
0683 void RooUtil::Cutflow::bookHistogram(TString cut,
0684                                      std::pair<TString, std::tuple<unsigned, float, float, std::function<float()>>> key,
0685                                      TString syst) {
0686   TString varname = key.first;
0687   unsigned int nbin = std::get<0>(key.second);
0688   float min = std::get<1>(key.second);
0689   float max = std::get<2>(key.second);
0690   std::function<float()> vardef = std::get<3>(key.second);
0691   TString histname = cut + syst + "__" + varname;
0692   if (booked_histograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data())) == booked_histograms.end()) {
0693     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())] =
0694         new THist(histname, "", nbin, min, max);
0695     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->SetDirectory(0);
0696     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->Sumw2();
0697     if (syst.IsNull()) {
0698       booked_histograms_nominal_keys.push_back(std::make_tuple(cut.Data(), syst.Data(), varname.Data()));
0699     }
0700     cuttreemap[cut.Data()]->addHist1D(
0701         booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())], vardef, syst);
0702   }
0703 }
0704 
0705 //_______________________________________________________________________________________________________
0706 void RooUtil::Cutflow::bookVecHistogram(
0707     TString cut,
0708     std::pair<
0709         TString,
0710         std::tuple<unsigned, float, float, std::function<std::vector<float>()>, std::function<std::vector<float>()>>>
0711         key,
0712     TString syst) {
0713   TString varname = key.first;
0714   unsigned int nbin = std::get<0>(key.second);
0715   float min = std::get<1>(key.second);
0716   float max = std::get<2>(key.second);
0717   std::function<std::vector<float>()> vardef = std::get<3>(key.second);
0718   std::function<std::vector<float>()> wgtdef = std::get<4>(key.second);
0719   TString histname = cut + syst + "__" + varname;
0720   if (booked_histograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data())) == booked_histograms.end()) {
0721     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())] =
0722         new THist(histname, "", nbin, min, max);
0723     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->SetDirectory(0);
0724     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->Sumw2();
0725     if (syst.IsNull()) {
0726       booked_histograms_nominal_keys.push_back(std::make_tuple(cut.Data(), syst.Data(), varname.Data()));
0727     }
0728     cuttreemap[cut.Data()]->addHist1DVec(
0729         booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())], vardef, wgtdef, syst);
0730   }
0731 }
0732 
0733 //_______________________________________________________________________________________________________
0734 void RooUtil::Cutflow::bookHistogram(TString cut,
0735                                      std::pair<TString, std::tuple<std::vector<float>, std::function<float()>>> key,
0736                                      TString syst) {
0737   TString varname = key.first;
0738   std::vector<float> boundaries = std::get<0>(key.second);
0739   std::function<float()> vardef = std::get<1>(key.second);
0740   TString histname = cut + syst + "__" + varname;
0741   if (booked_histograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data())) == booked_histograms.end()) {
0742     Float_t bounds[boundaries.size()];
0743     for (unsigned int i = 0; i < boundaries.size(); ++i)
0744       bounds[i] = boundaries[i];
0745     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())] =
0746         new THist(histname, "", boundaries.size() - 1, bounds);
0747     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->SetDirectory(0);
0748     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->Sumw2();
0749     if (syst.IsNull()) {
0750       booked_histograms_nominal_keys.push_back(std::make_tuple(cut.Data(), syst.Data(), varname.Data()));
0751     }
0752     cuttreemap[cut.Data()]->addHist1D(
0753         booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())], vardef, syst);
0754   }
0755 }
0756 
0757 //_______________________________________________________________________________________________________
0758 void RooUtil::Cutflow::bookVecHistogram(
0759     TString cut,
0760     std::pair<TString,
0761               std::tuple<std::vector<float>, std::function<std::vector<float>()>, std::function<std::vector<float>()>>>
0762         key,
0763     TString syst) {
0764   TString varname = key.first;
0765   std::vector<float> boundaries = std::get<0>(key.second);
0766   std::function<std::vector<float>()> vardef = std::get<1>(key.second);
0767   std::function<std::vector<float>()> wgtdef = std::get<2>(key.second);
0768   TString histname = cut + syst + "__" + varname;
0769   if (booked_histograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data())) == booked_histograms.end()) {
0770     Float_t bounds[boundaries.size()];
0771     for (unsigned int i = 0; i < boundaries.size(); ++i)
0772       bounds[i] = boundaries[i];
0773     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())] =
0774         new THist(histname, "", boundaries.size() - 1, bounds);
0775     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->SetDirectory(0);
0776     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->Sumw2();
0777     if (syst.IsNull()) {
0778       booked_histograms_nominal_keys.push_back(std::make_tuple(cut.Data(), syst.Data(), varname.Data()));
0779     }
0780     cuttreemap[cut.Data()]->addHist1DVec(
0781         booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())], vardef, wgtdef, syst);
0782   }
0783 }
0784 
0785 //_______________________________________________________________________________________________________
0786 void RooUtil::Cutflow::book2DHistogram(
0787     TString cut,
0788     std::pair<std::pair<TString, TString>,
0789               std::tuple<unsigned, float, float, unsigned, float, float, std::function<float()>, std::function<float()>>>
0790         key,
0791     TString syst) {
0792   TString varname = key.first.first;
0793   TString varnamey = key.first.second;
0794   unsigned int nbin = std::get<0>(key.second);
0795   float min = std::get<1>(key.second);
0796   float max = std::get<2>(key.second);
0797   unsigned int nbiny = std::get<3>(key.second);
0798   float miny = std::get<4>(key.second);
0799   float maxy = std::get<5>(key.second);
0800   std::function<float()> varxdef = std::get<6>(key.second);
0801   std::function<float()> varydef = std::get<7>(key.second);
0802   TString histname = cut + syst + "__" + varname + "_v_" + varnamey;
0803   if (booked_2dhistograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())) ==
0804       booked_2dhistograms.end()) {
0805     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())] =
0806         new TH2F(histname, "", nbin, min, max, nbiny, miny, maxy);
0807     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->SetDirectory(0);
0808     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->Sumw2();
0809     if (syst.IsNull()) {
0810       booked_2dhistograms_nominal_keys.push_back(
0811           std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data()));
0812     }
0813     cuttreemap[cut.Data()]->addHist2D(
0814         booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())],
0815         varxdef,
0816         varydef,
0817         syst);
0818   }
0819 }
0820 
0821 //_______________________________________________________________________________________________________
0822 void RooUtil::Cutflow::book2DVecHistogram(TString cut,
0823                                           std::pair<std::pair<TString, TString>,
0824                                                     std::tuple<unsigned,
0825                                                                float,
0826                                                                float,
0827                                                                unsigned,
0828                                                                float,
0829                                                                float,
0830                                                                std::function<std::vector<float>()>,
0831                                                                std::function<std::vector<float>()>,
0832                                                                std::function<std::vector<float>()>>> key,
0833                                           TString syst) {
0834   TString varname = key.first.first;
0835   TString varnamey = key.first.second;
0836   unsigned int nbin = std::get<0>(key.second);
0837   float min = std::get<1>(key.second);
0838   float max = std::get<2>(key.second);
0839   unsigned int nbiny = std::get<3>(key.second);
0840   float miny = std::get<4>(key.second);
0841   float maxy = std::get<5>(key.second);
0842   std::function<std::vector<float>()> varxdef = std::get<6>(key.second);
0843   std::function<std::vector<float>()> varydef = std::get<7>(key.second);
0844   std::function<std::vector<float>()> elemwgt = std::get<8>(key.second);
0845   TString histname = cut + syst + "__" + varname + "_v_" + varnamey;
0846   if (booked_2dhistograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())) ==
0847       booked_2dhistograms.end()) {
0848     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())] =
0849         new TH2F(histname, "", nbin, min, max, nbiny, miny, maxy);
0850     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->SetDirectory(0);
0851     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->Sumw2();
0852     if (syst.IsNull()) {
0853       booked_2dhistograms_nominal_keys.push_back(
0854           std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data()));
0855     }
0856     cuttreemap[cut.Data()]->addHist2DVec(
0857         booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())],
0858         varxdef,
0859         varydef,
0860         elemwgt,
0861         syst);
0862   }
0863 }
0864 //_______________________________________________________________________________________________________
0865 void RooUtil::Cutflow::book2DVecHistogram(TString cut,
0866                                           std::pair<std::pair<TString, TString>,
0867                                                     std::tuple<std::vector<float>,
0868                                                                unsigned,
0869                                                                float,
0870                                                                float,
0871                                                                std::function<std::vector<float>()>,
0872                                                                std::function<std::vector<float>()>,
0873                                                                std::function<std::vector<float>()>>> key,
0874                                           TString syst) {
0875   TString varname = key.first.first;
0876   TString varnamey = key.first.second;
0877   std::vector<float> xboundaries = std::get<0>(key.second);
0878   unsigned int nbiny = std::get<1>(key.second);
0879   float miny = std::get<2>(key.second);
0880   float maxy = std::get<3>(key.second);
0881   std::function<std::vector<float>()> varxdef = std::get<4>(key.second);
0882   std::function<std::vector<float>()> varydef = std::get<5>(key.second);
0883   std::function<std::vector<float>()> elemwgt = std::get<6>(key.second);
0884   TString histname = cut + syst + "__" + varname + "_v_" + varnamey;
0885   if (booked_2dhistograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())) ==
0886       booked_2dhistograms.end()) {
0887     Double_t xbounds[xboundaries.size()];
0888     for (unsigned int i = 0; i < xboundaries.size(); ++i)
0889       xbounds[i] = xboundaries[i];
0890     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())] =
0891         new TH2F(histname, "", xboundaries.size() - 1, xbounds, nbiny, miny, maxy);
0892     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->SetDirectory(0);
0893     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->Sumw2();
0894     if (syst.IsNull()) {
0895       booked_2dhistograms_nominal_keys.push_back(
0896           std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data()));
0897     }
0898     cuttreemap[cut.Data()]->addHist2DVec(
0899         booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())],
0900         varxdef,
0901         varydef,
0902         elemwgt,
0903         syst);
0904   }
0905 }
0906 #else
0907 //_______________________________________________________________________________________________________
0908 void RooUtil::Cutflow::bookHistogram(TString cut,
0909                                      std::pair<TString, std::tuple<unsigned, float, float>> key,
0910                                      TString syst) {
0911   TString varname = key.first;
0912   unsigned int nbin = std::get<0>(key.second);
0913   float min = std::get<1>(key.second);
0914   float max = std::get<2>(key.second);
0915   TString histname = cut + syst + "__" + varname;
0916   if (booked_histograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data())) == booked_histograms.end()) {
0917     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())] =
0918         new THist(histname, "", nbin, min, max);
0919     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->SetDirectory(0);
0920     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->Sumw2();
0921     if (syst.IsNull()) {
0922       booked_histograms_nominal_keys.push_back(std::make_tuple(cut.Data(), syst.Data(), varname.Data()));
0923     }
0924     if (!tx)
0925       error("bookHistogram():: No TTreeX has been set. Forgot to call bookCutflows()?");
0926     if (!tx->hasBranch<float>(varname))
0927       tx->createBranch<float>(varname);
0928     cuttreemap[cut.Data()]->addHist1D(
0929         booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())], varname, syst);
0930   }
0931 }
0932 
0933 //_______________________________________________________________________________________________________
0934 void RooUtil::Cutflow::bookHistogram(TString cut, std::pair<TString, std::vector<float>> key, TString syst) {
0935   TString varname = key.first;
0936   std::vector<float> boundaries = key.second;
0937   TString histname = cut + syst + "__" + varname;
0938   if (booked_histograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data())) == booked_histograms.end()) {
0939     Float_t bounds[boundaries.size()];
0940     for (unsigned int i = 0; i < boundaries.size(); ++i)
0941       bounds[i] = boundaries[i];
0942     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())] =
0943         new THist(histname, "", boundaries.size() - 1, bounds);
0944     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->SetDirectory(0);
0945     booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())]->Sumw2();
0946     if (syst.IsNull()) {
0947       booked_histograms_nominal_keys.push_back(std::make_tuple(cut.Data(), syst.Data(), varname.Data()));
0948     }
0949     if (!tx)
0950       error("bookHistogram():: No TTreeX has been set. Forgot to call bookCutflows()?");
0951     if (!tx->hasBranch<float>(varname))
0952       tx->createBranch<float>(varname);
0953     cuttreemap[cut.Data()]->addHist1D(
0954         booked_histograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data())], varname, syst);
0955   }
0956 }
0957 
0958 //_______________________________________________________________________________________________________
0959 void RooUtil::Cutflow::book2DHistogram(
0960     TString cut,
0961     std::pair<std::pair<TString, TString>, std::tuple<unsigned, float, float, unsigned, float, float>> key,
0962     TString syst) {
0963   TString varname = key.first.first;
0964   TString varnamey = key.first.second;
0965   unsigned int nbin = std::get<0>(key.second);
0966   float min = std::get<1>(key.second);
0967   float max = std::get<2>(key.second);
0968   unsigned int nbiny = std::get<0>(key.second);
0969   float miny = std::get<1>(key.second);
0970   float maxy = std::get<2>(key.second);
0971   TString histname = cut + syst + "__" + varname + "_v_" + varnamey;
0972   if (booked_2dhistograms.find(std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())) ==
0973       booked_2dhistograms.end()) {
0974     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())] =
0975         new TH2F(histname, "", nbin, min, max, nbiny, miny, maxy);
0976     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->SetDirectory(0);
0977     booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())]->Sumw2();
0978     if (syst.IsNull()) {
0979       booked_2dhistograms_nominal_keys.push_back(
0980           std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data()));
0981     }
0982     if (!tx)
0983       error("book2DHistogram():: No TTreeX has been set. Forgot to call bookCutflows()?");
0984     if (!tx->hasBranch<float>(varname))
0985       tx->createBranch<float>(varname);
0986     if (!tx->hasBranch<float>(varnamey))
0987       tx->createBranch<float>(varnamey);
0988     cuttreemap[cut.Data()]->addHist2D(
0989         booked_2dhistograms[std::make_tuple(cut.Data(), syst.Data(), varname.Data(), varnamey.Data())],
0990         varname,
0991         varnamey,
0992         syst);
0993   }
0994 }
0995 #endif
0996 
0997 //_______________________________________________________________________________________________________
0998 void RooUtil::Cutflow::bookHistogramsForCut(Histograms& histograms, TString cut) {
0999   for (auto& key : histograms.th1fs)
1000     bookHistogram(cut, key);
1001   for (auto& key : histograms.th1fs_varbin)
1002     bookHistogram(cut, key);
1003   for (auto& key : histograms.th1vecfs)
1004     bookVecHistogram(cut, key);
1005   for (auto& key : histograms.th1vecfs_varbin)
1006     bookVecHistogram(cut, key);
1007   for (auto& key : histograms.th2fs)
1008     book2DHistogram(cut, key);
1009   for (auto& key : histograms.th2vecfs)
1010     book2DVecHistogram(cut, key);
1011   for (auto& key : histograms.th2vecfs_xvarbin)
1012     book2DVecHistogram(cut, key);
1013   if (not doskipsysthist) {
1014     for (auto& syst : systs) {
1015       for (auto& key : histograms.th1fs)
1016         bookHistogram(cut, key, syst);
1017       for (auto& key : histograms.th1fs_varbin)
1018         bookHistogram(cut, key, syst);
1019       for (auto& key : histograms.th1vecfs)
1020         bookVecHistogram(cut, key, syst);
1021       for (auto& key : histograms.th1vecfs_varbin)
1022         bookVecHistogram(cut, key, syst);
1023       for (auto& key : histograms.th2fs)
1024         book2DHistogram(cut, key, syst);
1025       for (auto& key : histograms.th2vecfs)
1026         book2DVecHistogram(cut, key, syst);
1027       for (auto& key : histograms.th2vecfs_xvarbin)
1028         book2DVecHistogram(cut, key, syst);
1029     }
1030     for (auto& cutsyst : cutsysts) {
1031       for (auto& key : histograms.th1fs)
1032         bookHistogram(cut, key, cutsyst);
1033       for (auto& key : histograms.th1fs_varbin)
1034         bookHistogram(cut, key, cutsyst);
1035       for (auto& key : histograms.th1vecfs)
1036         bookVecHistogram(cut, key, cutsyst);
1037       for (auto& key : histograms.th1vecfs_varbin)
1038         bookVecHistogram(cut, key, cutsyst);
1039       for (auto& key : histograms.th2fs)
1040         book2DHistogram(cut, key, cutsyst);
1041       for (auto& key : histograms.th2vecfs)
1042         book2DVecHistogram(cut, key, cutsyst);
1043       for (auto& key : histograms.th2vecfs_xvarbin)
1044         book2DVecHistogram(cut, key, cutsyst);
1045     }
1046   }
1047 }
1048 
1049 //_______________________________________________________________________________________________________
1050 void RooUtil::Cutflow::bookHistogramsForCutAndBelow(Histograms& histograms, TString cut) {
1051   std::vector<TString> cutlist = cuttree.getCutListBelow(cut);
1052   for (auto& c : cutlist) {
1053     bookHistogramsForCut(histograms, c);
1054   }
1055 }
1056 
1057 //_______________________________________________________________________________________________________
1058 void RooUtil::Cutflow::bookHistogramsForCutAndAbove(Histograms& histograms, TString cut) {
1059   error("bookHistogramsForCutAndAbove not yet implemented");
1060 }
1061 
1062 //_______________________________________________________________________________________________________
1063 void RooUtil::Cutflow::bookHistogramsForEndCuts(Histograms& histograms) {
1064   std::vector<TString> regions = cuttree.getEndCuts();
1065   for (auto& region : regions) {
1066     bookHistogramsForCut(histograms, region);
1067   }
1068 }
1069 
1070 //_______________________________________________________________________________________________________
1071 void RooUtil::Cutflow::setSkipSystematicHistograms(bool v) { doskipsysthist = v; }
1072 
1073 //_______________________________________________________________________________________________________
1074 void RooUtil::Cutflow::setSaveTTreeX(bool v) { dosavettreex = v; }
1075 
1076 //_______________________________________________________________________________________________________
1077 void RooUtil::Cutflow::printSetFunctionError(TString msg) {
1078   if (seterrorcount < 100) {
1079     print(msg);
1080     seterrorcount++;
1081   } else if (seterrorcount == 100) {
1082     print(msg);
1083     print("Suppressing Cutflow::set\"Func\"() errors ... ");
1084     seterrorcount++;
1085   } else {
1086     return;
1087   }
1088 }
1089 
1090 //_______________________________________________________________________________________________________
1091 void RooUtil::Cutflow::setHistsAxesExtendable() {
1092   for (auto& pair : booked_histograms)
1093     pair.second->SetCanExtend(TH1::kAllAxes);
1094 }
1095 
1096 //_______________________________________________________________________________________________________
1097 RooUtil::Histograms::Histograms() {}
1098 
1099 //_______________________________________________________________________________________________________
1100 RooUtil::Histograms::~Histograms() {}
1101 
1102 #ifdef USE_CUTLAMBDA
1103 //_______________________________________________________________________________________________________
1104 void RooUtil::Histograms::addHistogram(
1105     TString name, unsigned int n, float min, float max, std::function<float()> vardef) {
1106   if (th1fs.find(name) == th1fs.end()) {
1107     th1fs[name] = std::make_tuple(n, min, max, vardef);
1108   } else {
1109     error(TString::Format("histogram already exists name = %s", name.Data()));
1110   }
1111 }
1112 
1113 //_______________________________________________________________________________________________________
1114 void RooUtil::Histograms::addVecHistogram(TString name,
1115                                           unsigned int n,
1116                                           float min,
1117                                           float max,
1118                                           std::function<std::vector<float>()> vardef,
1119                                           std::function<std::vector<float>()> wgt) {
1120   if (th1vecfs.find(name) == th1vecfs.end()) {
1121     th1vecfs[name] = std::make_tuple(n, min, max, vardef, wgt);
1122   } else {
1123     error(TString::Format("histogram already exists name = %s", name.Data()));
1124   }
1125 }
1126 
1127 //_______________________________________________________________________________________________________
1128 void RooUtil::Histograms::addHistogram(TString name, std::vector<float> boundaries, std::function<float()> vardef) {
1129   if (th1fs_varbin.find(name) == th1fs_varbin.end()) {
1130     th1fs_varbin[name] = std::make_tuple(boundaries, vardef);
1131   } else {
1132     error(TString::Format("histogram already exists name = %s", name.Data()));
1133   }
1134 }
1135 
1136 //_______________________________________________________________________________________________________
1137 void RooUtil::Histograms::addVecHistogram(TString name,
1138                                           std::vector<float> boundaries,
1139                                           std::function<std::vector<float>()> vardef,
1140                                           std::function<std::vector<float>()> wgt) {
1141   if (th1vecfs_varbin.find(name) == th1vecfs_varbin.end()) {
1142     th1vecfs_varbin[name] = std::make_tuple(boundaries, vardef, wgt);
1143   } else {
1144     error(TString::Format("histogram already exists name = %s", name.Data()));
1145   }
1146 }
1147 
1148 //_______________________________________________________________________________________________________
1149 void RooUtil::Histograms::add2DHistogram(TString name,
1150                                          unsigned int n,
1151                                          float min,
1152                                          float max,
1153                                          TString namey,
1154                                          unsigned int ny,
1155                                          float miny,
1156                                          float maxy,
1157                                          std::function<float()> varxdef,
1158                                          std::function<float()> varydef) {
1159   if (th2fs.find(std::make_pair(name, namey)) == th2fs.end()) {
1160     th2fs[std::make_pair(name, namey)] = std::make_tuple(n, min, max, ny, miny, maxy, varxdef, varydef);
1161   } else {
1162     error(TString::Format("histogram already exists name = %s", (name + "_v_" + namey).Data()));
1163   }
1164 }
1165 
1166 //_______________________________________________________________________________________________________
1167 void RooUtil::Histograms::add2DVecHistogram(TString name,
1168                                             unsigned int n,
1169                                             float min,
1170                                             float max,
1171                                             TString namey,
1172                                             unsigned int ny,
1173                                             float miny,
1174                                             float maxy,
1175                                             std::function<std::vector<float>()> varxdef,
1176                                             std::function<std::vector<float>()> varydef,
1177                                             std::function<std::vector<float>()> elem_wgt) {
1178   if (th2vecfs.find(std::make_pair(name, namey)) == th2vecfs.end()) {
1179     th2vecfs[std::make_pair(name, namey)] = std::make_tuple(n, min, max, ny, miny, maxy, varxdef, varydef, elem_wgt);
1180   } else {
1181     error(TString::Format("histogram already exists name = %s", (name + "_v_" + namey).Data()));
1182   }
1183 }
1184 
1185 //_______________________________________________________________________________________________________
1186 void RooUtil::Histograms::add2DVecHistogram(TString name,
1187                                             std::vector<float> xboundaries,
1188                                             TString namey,
1189                                             unsigned int ny,
1190                                             float miny,
1191                                             float maxy,
1192                                             std::function<std::vector<float>()> varxdef,
1193                                             std::function<std::vector<float>()> varydef,
1194                                             std::function<std::vector<float>()> elem_wgt) {
1195   if (th2vecfs_xvarbin.find(std::make_pair(name, namey)) == th2vecfs_xvarbin.end()) {
1196     th2vecfs_xvarbin[std::make_pair(name, namey)] =
1197         std::make_tuple(xboundaries, ny, miny, maxy, varxdef, varydef, elem_wgt);
1198   } else {
1199     error(TString::Format("histogram already exists name = %s", (name + "_v_" + namey).Data()));
1200   }
1201 }
1202 #else
1203 //_______________________________________________________________________________________________________
1204 void RooUtil::Histograms::addHistogram(TString name, unsigned int n, float min, float max) {
1205   if (th1fs.find(name) == th1fs.end())
1206     th1fs[name] = std::make_tuple(n, min, max);
1207   else
1208     error(TString::Format("histogram already exists name = %s", name.Data()));
1209 }
1210 
1211 //_______________________________________________________________________________________________________
1212 void RooUtil::Histograms::addHistogram(TString name, std::vector<float> boundaries) {
1213   if (th1fs_varbin.find(name) == th1fs_varbin.end())
1214     th1fs_varbin[name] = boundaries;
1215   else
1216     error(TString::Format("histogram already exists name = %s", name.Data()));
1217 }
1218 
1219 //_______________________________________________________________________________________________________
1220 void RooUtil::Histograms::add2DHistogram(
1221     TString name, unsigned int n, float min, float max, TString namey, unsigned int ny, float miny, float maxy) {
1222   if (th2fs.find(std::make_pair(name, namey)) == th2fs.end())
1223     th2fs[std::make_pair(name, namey)] = std::make_tuple(n, min, max, ny, miny, maxy);
1224   else
1225     error(TString::Format("histogram already exists name = %s", (name + "_v_" + namey).Data()));
1226 }
1227 #endif