diff --git a/NanoCORE/ElectronSelections.cc b/NanoCORE/ElectronSelections.cc index 8e1f436..0890ac1 100644 --- a/NanoCORE/ElectronSelections.cc +++ b/NanoCORE/ElectronSelections.cc @@ -4,6 +4,10 @@ using namespace tas; +namespace WWZ { + std::shared_ptr electron_mvareader_map; +} + bool SS::electronID(int idx, SS::IDLevel id_level, int year) { // Common (across years and ID levels) checks if (Electron_pt().at(idx) < 7.) { return false; } @@ -349,17 +353,101 @@ bool ttH::isTriggerSafeNoIso(int idx) { return true; } +void WWZ::electronLoadMVA(std::string fname) +{ + + if (electron_mvareader_map) + { + std::cout << "WARNING: XGBoost already loaded, but is trying to load again!" << std::endl; + return; + } + + std::cout << "electronLoadMVA(): Loading XGBoost binary file = " << fname << std::endl; + + std::vector varnames; + varnames = std::vector{ + "pt", + "eta", + "jetNDauCharged", + "miniPFRelIso_chg", + "miniPFRelIso_diff_all_chg", // = miniPFRelIso_all - miniPFRelIso_chg + "jetPtRelv2", + "jetPtRatio", // = 1/(jetRelIso+1) + "pfRelIso03_all", + "ak4jet:btagDeepFlavB", // B tagging discriminant score + "sip3d", + "log_abs_dxy", + "log_abs_dz", + }; + varnames.push_back("mvaFall17V2noIso"); + float missing_entry_val = std::numeric_limits::quiet_NaN(); + electron_mvareader_map = std::make_shared(); + electron_mvareader_map->build(fname, varnames, missing_entry_val); +} + +float WWZ::computeElectronTopMVAScore(unsigned int idx) +{ + + float res = -999; + std::unordered_map input_vars; + + auto const &vnames = electron_mvareader_map->getVariableNames(); + for (auto const &vname : vnames) + { + if (vname == "pt") + input_vars[vname] = static_cast(tas::Electron_pt().at(idx)); + else if (vname == "eta") + input_vars[vname] = static_cast(tas::Electron_eta().at(idx)); + else if (vname == "miniPFRelIso_diff_all_chg") + input_vars[vname] = static_cast(tas::Electron_miniPFRelIso_all().at(idx) - tas::Electron_miniPFRelIso_chg().at(idx)); + else if (vname == "jetPtRatio") + input_vars[vname] = static_cast(1. / (tas::Electron_jetRelIso().at(idx) + 1.)); + else if (vname == "log_abs_dxy") + input_vars[vname] = static_cast(std::log(std::abs(tas::Electron_dxy().at(idx)))); + else if (vname == "log_abs_dz") + input_vars[vname] = static_cast(std::log(std::abs(tas::Electron_dz().at(idx)))); + else if (vname == "sip3d") + input_vars[vname] = static_cast(tas::Electron_sip3d().at(idx)); + else if (vname == "miniPFRelIso_chg") + input_vars[vname] = static_cast(tas::Electron_miniPFRelIso_chg().at(idx)); + else if (vname == "jetPtRelv2") + input_vars[vname] = static_cast(tas::Electron_jetPtRelv2().at(idx)); + else if (vname == "jetNDauCharged") + input_vars[vname] = static_cast(tas::Electron_jetNDauCharged().at(idx)); + else if (vname == "pfRelIso03_all") + input_vars[vname] = static_cast(tas::Electron_pfRelIso03_all().at(idx)); + else if (vname == "mvaFall17V2noIso") + input_vars[vname] = static_cast(tas::Electron_mvaFall17V2noIso().at(idx)); + else if (vname == "ak4jet:btagDeepFlavB") + { + input_vars[vname] = float(0); + if (tas::Electron_jetIdx().at(idx) == -1) input_vars[vname] = static_cast(0.); + if (tas::Electron_jetIdx().at(idx) != -1) input_vars[vname] = static_cast(tas::Jet_btagDeepFlavB().at(tas::Electron_jetIdx().at(idx))); + } + else + { + std::cerr << "WWZ::computeElectronTopMVAScore: Input variable name " << vname << " does not match to a corresponding variable" << endl; + std::cerr << "Have you loaded the XGBoost binary? i.e. did you call muonLoadMVA()?" << std::endl; + assert(0); + } + } + + electron_mvareader_map->eval(input_vars, res); + + return res; +} + bool WWZ::electronID(int idx, WWZ::IDLevel id_level, int year) { // Year-specific checks switch (year) { case (2016): - return WWZ::electron2016ID(idx, id_level); + return WWZ::electronRun2ID(idx); break; case (2017): - return WWZ::electron2017ID(idx, id_level); + return WWZ::electronRun2ID(idx); break; case (2018): - return WWZ::electron2018ID(idx, id_level); + return WWZ::electronRun2ID(idx); break; case (2022): return WWZ::electron2022ID(idx, id_level); @@ -371,33 +459,17 @@ bool WWZ::electronID(int idx, WWZ::IDLevel id_level, int year) { } } -bool WWZ::electron2016ID(int idx, WWZ::IDLevel id_level) { - if (not (fabs(Electron_eta().at(idx) + Electron_deltaEtaSC().at(idx)) < 2.5)) return false; - if (not (Electron_pt().at(idx) > 10. )) return false; - if (not (fabs(Electron_dxy().at(idx)) < 0.05 )) return false; - if (not (fabs(Electron_dz().at(idx)) < 0.1 )) return false; - if (not (fabs(Electron_sip3d().at(idx)) < 8 )) return false; - if (not (Electron_miniPFRelIso_all().at(idx) < 0.4 )) return false; - return true; -} - -bool WWZ::electron2017ID(int idx, WWZ::IDLevel id_level) { - if (not (fabs(Electron_eta().at(idx) + Electron_deltaEtaSC().at(idx)) < 2.5)) return false; - if (not (Electron_pt().at(idx) > 10. )) return false; - if (not (fabs(Electron_dxy().at(idx)) < 0.05 )) return false; - if (not (fabs(Electron_dz().at(idx)) < 0.1 )) return false; - if (not (fabs(Electron_sip3d().at(idx)) < 8 )) return false; - if (not (Electron_miniPFRelIso_all().at(idx) < 0.4 )) return false; - return true; -} - -bool WWZ::electron2018ID(int idx, WWZ::IDLevel id_level) { - if (not (fabs(Electron_eta().at(idx) + Electron_deltaEtaSC().at(idx)) < 2.5)) return false; - if (not (Electron_pt().at(idx) > 10. )) return false; - if (not (fabs(Electron_dxy().at(idx)) < 0.05 )) return false; - if (not (fabs(Electron_dz().at(idx)) < 0.1 )) return false; - if (not (fabs(Electron_sip3d().at(idx)) < 8 )) return false; - if (not (Electron_miniPFRelIso_all().at(idx) < 0.4 )) return false; +bool WWZ::electronRun2ID(int idx) { + if (not (tas::Electron_pt().at(idx) > 10. )) return false; + if (not (fabs(tas::Electron_eta().at(idx)) < 2.5 )) return false; + if (not (fabs(tas::Electron_dxy().at(idx)) < 0.05)) return false; + if (not (fabs(tas::Electron_dz().at(idx)) < 0.1 )) return false; + if (not (fabs(tas::Electron_sip3d().at(idx)) < 8 )) return false; + if (not (tas::Electron_miniPFRelIso_all().at(idx) < 0.4 )) return false; + if (not (tas::Electron_lostHits().at(idx) <= 1 )) return false; + if (not (tas::Electron_convVeto().at(idx) )) return false; + if (not (tas::Electron_tightCharge().at(idx) == 2 )) return false; + if (not (computeElectronTopMVAScore(idx) > 0.81 )) return false; return true; } diff --git a/NanoCORE/ElectronSelections.h b/NanoCORE/ElectronSelections.h index cb92149..9306665 100644 --- a/NanoCORE/ElectronSelections.h +++ b/NanoCORE/ElectronSelections.h @@ -2,6 +2,7 @@ #define ELECTRONSELECTIONS_H #include "Base.h" #include "Nano.h" +#include "Tools/xgboost/XGBoostInterface.h" namespace SS { enum ElectronMVAIDLevel { @@ -31,10 +32,11 @@ namespace ttH { } namespace WWZ { + extern std::shared_ptr electron_mvareader_map; + void electronLoadMVA(std::string fname); + float computeElectronTopMVAScore(unsigned int idx); bool electronID(int idx, WWZ::IDLevel id_level, int year); - bool electron2016ID(int idx, WWZ::IDLevel id_level); - bool electron2017ID(int idx, WWZ::IDLevel id_level); - bool electron2018ID(int idx, WWZ::IDLevel id_level); + bool electronRun2ID(int idx); bool electron2022ID(int idx, WWZ::IDLevel id_level); } diff --git a/NanoCORE/Makefile b/NanoCORE/Makefile index bd7465c..cdb161c 100755 --- a/NanoCORE/Makefile +++ b/NanoCORE/Makefile @@ -4,12 +4,19 @@ SOURCES=$(wildcard *.cc) $(wildcard Tools/*.cc) $(wildcard Tools/btagsf/*.cc) $( OBJECTS=$(SOURCES:.cc=.o) LIB=NANO_CORE.so +# XGBOOST essentials +XGBOOSTLIBDIR = ${XGBOOST_PATH}/lib/ +XGBOOSTINCDIR = ${XGBOOSTLIBDIR}../include/ +RABITINCDIR = ${XGBOOSTLIBDIR}../rabit/include/ +XGBOOSTCXXFLAGS = -I$(XGBOOSTINCDIR) -I$(RABITINCDIR) -L$(XGBOOSTLIBDIR) +XGBOOSTLIBS = -lxgboost -L$(XGBOOSTLIBDIR) + $(LIB): $(OBJECTS) - $(LD) $(LDFLAGS) $(SOFLAGS) $(OBJECTS) $(ROOTLIBS) -lTMVA -lEG -lGenVector -lXMLIO -lMLP -lTreePlayer -o $@ + $(LD) $(LDFLAGS) $(SOFLAGS) $(OBJECTS) $(XGBOOSTLIBS) $(ROOTLIBS) -lTMVA -lEG -lGenVector -lXMLIO -lMLP -lTreePlayer -o $@ ln -sf $(LIB) lib$(LIB) %.o: %.cc - $(CXX) $(CXXFLAGS) -I${CMSSW_BASE}/../../../external/boost/1.67.0/include -I${CMSSW_BASE}/src -c $< -o $@ -fno-var-tracking + $(CXX) $(CXXFLAGS) $(XGBOOSTCXXFLAGS) -I${CMSSW_BASE}/../../../external/boost/1.67.0/include -I${CMSSW_BASE}/src -c $< -o $@ -fno-var-tracking test: all python Tools/unit_tests/tests.py diff --git a/NanoCORE/MuonSelections.cc b/NanoCORE/MuonSelections.cc index 6e0efb8..91f3536 100644 --- a/NanoCORE/MuonSelections.cc +++ b/NanoCORE/MuonSelections.cc @@ -4,6 +4,10 @@ using namespace tas; +namespace WWZ { + std::shared_ptr muon_mvareader_map; +} + bool SS::muonID(unsigned int idx, SS::IDLevel id_level, int year) { // Common (across years and ID levels) checks if (Muon_pt().at(idx) < 5.) { return false; } @@ -131,17 +135,100 @@ bool ttH::muonID(unsigned int idx, ttH::IDLevel id_level, int year) { return true; } +void WWZ::muonLoadMVA(std::string fname) +{ + + if (muon_mvareader_map) + { + std::cout << "WARNING: XGBoost already loaded, but is trying to load again!" << std::endl; + return; + } + + std::cout << "muonLoadMVA(): Loading XGBoost binary file = " << fname << std::endl; + + std::vector varnames; + varnames = std::vector{ + "pt", + "eta", + "jetNDauCharged", + "miniPFRelIso_chg", + "miniPFRelIso_diff_all_chg", // = miniPFRelIso_all - miniPFRelIso_chg + "jetPtRelv2", + "jetPtRatio", // = 1/(jetRelIso+1) + "pfRelIso03_all", + "ak4jet:btagDeepFlavB", // B tagging discriminant score + "sip3d", + "log_abs_dxy", + "log_abs_dz", + "segmentComp", + }; + float missing_entry_val = std::numeric_limits::quiet_NaN(); + muon_mvareader_map = std::make_shared(); + muon_mvareader_map->build(fname, varnames, missing_entry_val); +} + +float WWZ::computeMuonTopMVAScore(unsigned int idx) +{ + + float res = -999; + std::unordered_map input_vars; + + auto const &vnames = muon_mvareader_map->getVariableNames(); + for (auto const &vname : vnames) + { + if (vname == "pt") + input_vars[vname] = static_cast(tas::Muon_pt().at(idx)); + else if (vname == "eta") + input_vars[vname] = static_cast(tas::Muon_eta().at(idx)); + else if (vname == "miniPFRelIso_diff_all_chg") + input_vars[vname] = static_cast(tas::Muon_miniPFRelIso_all().at(idx) - tas::Muon_miniPFRelIso_chg().at(idx)); + else if (vname == "jetPtRatio") + input_vars[vname] = static_cast(1. / (tas::Muon_jetRelIso().at(idx) + 1.)); + else if (vname == "log_abs_dxy") + input_vars[vname] = static_cast(std::log(std::abs(tas::Muon_dxy().at(idx)))); + else if (vname == "log_abs_dz") + input_vars[vname] = static_cast(std::log(std::abs(tas::Muon_dz().at(idx)))); + else if (vname == "sip3d") + input_vars[vname] = static_cast(tas::Muon_sip3d().at(idx)); + else if (vname == "segmentComp") + input_vars[vname] = static_cast(tas::Muon_segmentComp().at(idx)); + else if (vname == "miniPFRelIso_chg") + input_vars[vname] = static_cast(tas::Muon_miniPFRelIso_chg().at(idx)); + else if (vname == "jetPtRelv2") + input_vars[vname] = static_cast(tas::Muon_jetPtRelv2().at(idx)); + else if (vname == "jetNDauCharged") + input_vars[vname] = static_cast(tas::Muon_jetNDauCharged().at(idx)); + else if (vname == "pfRelIso03_all") + input_vars[vname] = static_cast(tas::Muon_pfRelIso03_all().at(idx)); + else if (vname == "ak4jet:btagDeepFlavB") + { + if (tas::Muon_jetIdx().at(idx) == -1) input_vars[vname] = static_cast(0.); + if (tas::Muon_jetIdx().at(idx) != -1) input_vars[vname] = static_cast(tas::Jet_btagDeepFlavB().at(tas::Muon_jetIdx().at(idx))); + } + else + { + std::cerr << "WWZ::computeMuonTopMVAScore: Input variable name " << vname << " does not match to a corresponding variable" << endl; + std::cerr << "Have you loaded the XGBoost binary? i.e. did you call muonLoadMVA()?" << std::endl; + assert(0); + } + } + + muon_mvareader_map->eval(input_vars, res); + + return res; +} + bool WWZ::muonID(int idx, WWZ::IDLevel id_level, int year) { // Year-specific checks switch (year) { case (2016): - return WWZ::muon2016ID(idx, id_level); + return WWZ::muonRun2ID(idx); break; case (2017): - return WWZ::muon2017ID(idx, id_level); + return WWZ::muonRun2ID(idx); break; case (2018): - return WWZ::muon2018ID(idx, id_level); + return WWZ::muonRun2ID(idx); break; case (2022): return WWZ::muon2022ID(idx, id_level); @@ -153,36 +240,16 @@ bool WWZ::muonID(int idx, WWZ::IDLevel id_level, int year) { } } -bool WWZ::muon2016ID(unsigned int idx, WWZ::IDLevel id_level) { - if (not (Muon_pt().at(idx) > 10. )) return false; - if (not (fabs(Muon_eta().at(idx)) < 2.4 )) return false; - if (not (fabs(Muon_dxy().at(idx)) < 0.05 )) return false; - if (not (fabs(Muon_dz().at(idx)) < 0.1 )) return false; - if (not (fabs(Muon_sip3d().at(idx)) < 8 )) return false; - if (not (Muon_miniPFRelIso_all().at(idx) < 0.4 )) return false; - if (not (Muon_looseId().at(idx) )) return false; - return true; -} - -bool WWZ::muon2017ID(unsigned int idx, WWZ::IDLevel id_level) { - if (not (Muon_pt().at(idx) > 10. )) return false; - if (not (fabs(Muon_eta().at(idx)) < 2.4 )) return false; - if (not (fabs(Muon_dxy().at(idx)) < 0.05 )) return false; - if (not (fabs(Muon_dz().at(idx)) < 0.1 )) return false; - if (not (fabs(Muon_sip3d().at(idx)) < 8 )) return false; - if (not (Muon_miniPFRelIso_all().at(idx) < 0.4 )) return false; - if (not (Muon_looseId().at(idx) )) return false; - return true; -} - -bool WWZ::muon2018ID(unsigned int idx, WWZ::IDLevel id_level) { - if (not (Muon_pt().at(idx) > 10. )) return false; - if (not (fabs(Muon_eta().at(idx)) < 2.4 )) return false; - if (not (fabs(Muon_dxy().at(idx)) < 0.05 )) return false; - if (not (fabs(Muon_dz().at(idx)) < 0.1 )) return false; - if (not (fabs(Muon_sip3d().at(idx)) < 8 )) return false; - if (not (Muon_miniPFRelIso_all().at(idx) < 0.4 )) return false; - if (not (Muon_looseId().at(idx) )) return false; +bool WWZ::muonRun2ID(unsigned int idx) { + // These cuts are common for all ID levels of Muon + if (not (tas::Muon_pt().at(idx) > 10. )) return false; + if (not (fabs(tas::Muon_eta().at(idx)) < 2.4 )) return false; + if (not (fabs(tas::Muon_dxy().at(idx)) < 0.05 )) return false; + if (not (fabs(tas::Muon_dz().at(idx)) < 0.1 )) return false; + if (not (fabs(tas::Muon_sip3d().at(idx)) < 8 )) return false; + if (not (tas::Muon_miniPFRelIso_all().at(idx) < 0.4 )) return false; + if (not (tas::Muon_mediumId().at(idx) )) return false; + if (not (computeMuonTopMVAScore(idx) > 0.64 )) return false; return true; } diff --git a/NanoCORE/MuonSelections.h b/NanoCORE/MuonSelections.h index 871d994..c8c89f2 100644 --- a/NanoCORE/MuonSelections.h +++ b/NanoCORE/MuonSelections.h @@ -2,6 +2,7 @@ #define MUONSELECTIONS_H #include "Nano.h" #include "Base.h" +#include "Tools/xgboost/XGBoostInterface.h" namespace SS { bool muonID(unsigned int idx, SS::IDLevel id_level, int year); @@ -15,10 +16,11 @@ namespace ttH { } namespace WWZ { + extern std::shared_ptr muon_mvareader_map; + void muonLoadMVA(std::string fname); + float computeMuonTopMVAScore(unsigned int idx); bool muonID(int idx, WWZ::IDLevel id_level, int year); - bool muon2016ID(unsigned int idx, WWZ::IDLevel id_level); - bool muon2017ID(unsigned int idx, WWZ::IDLevel id_level); - bool muon2018ID(unsigned int idx, WWZ::IDLevel id_level); + bool muonRun2ID(unsigned int idx); bool muon2022ID(unsigned int idx, WWZ::IDLevel id_level); } diff --git a/NanoCORE/Tools/xgboost/MLWrapper.h b/NanoCORE/Tools/xgboost/MLWrapper.h new file mode 100644 index 0000000..57ff319 --- /dev/null +++ b/NanoCORE/Tools/xgboost/MLWrapper.h @@ -0,0 +1,17 @@ +#ifndef MLWRAPPER_H +#define MLWRAPPER_H + +#include +#include + +class MLWrapper{ +public: + + MLWrapper(){}; + virtual ~MLWrapper(){}; + + virtual bool build(std::string fname, std::vector const& varnames, float missing_entry_val) = 0; + +}; + +#endif diff --git a/NanoCORE/Tools/xgboost/XGBoostInterface.cc b/NanoCORE/Tools/xgboost/XGBoostInterface.cc new file mode 100644 index 0000000..f2a1e12 --- /dev/null +++ b/NanoCORE/Tools/xgboost/XGBoostInterface.cc @@ -0,0 +1,41 @@ +#include +#include +#include +//#include +//#include "/cvmfs/cms.cern.ch/slc7_amd64_gcc900/external/py3-xgboost/0.90-ghbfee2/lib/python3.8/site-packages/xgboost/include/xgboost/c_api.h" +#include "XGBoostInterface.hpp" + +XGBoostInterface::XGBoostInterface() : MLWrapper(), booster(nullptr), defval(0) {} + +XGBoostInterface::~XGBoostInterface() +{ + SAFE_XGBOOST(XGBoosterFree(*booster)); + delete booster; +} + +bool XGBoostInterface::build(std::string fname, std::vector const &varnames, float missing_entry_val) +{ + + if (booster) + { + std::cerr << "XGBoostInterface::build: The booster is already built." << endl; + return false; + } + if (fname == "") + { + std::cerr << "XGBoostInterface::build: The file name is an empty string. This function should be called to load models from a file." << endl; + assert(0); + } + + defval = missing_entry_val; + variable_names = varnames; + + booster = new BoosterHandle; + SAFE_XGBOOST(XGBoosterCreate(nullptr, 0, booster)); + + // std::cout << "XGBoostInterface::build: A new xgboost is created. Loading the model in " << fname << "..." << endl; + + SAFE_XGBOOST(XGBoosterLoadModel(*booster, fname.data())); + + return true; +} diff --git a/NanoCORE/Tools/xgboost/XGBoostInterface.h b/NanoCORE/Tools/xgboost/XGBoostInterface.h new file mode 100644 index 0000000..8000627 --- /dev/null +++ b/NanoCORE/Tools/xgboost/XGBoostInterface.h @@ -0,0 +1,31 @@ +#ifndef XGBOOSTINTERFACE_H +#define XGBOOSTINTERFACE_H + +#include +//#include "${XGBOOST_PATH}/include/xgboost/c_api.h" +//#include "/cvmfs/cms.cern.ch/slc7_amd64_gcc900/external/py3-xgboost/0.90-ghbfee2/lib/python3.8/site-packages/xgboost/include/xgboost/c_api.h" +#include "MLWrapper.h" + +class XGBoostInterface : public MLWrapper +{ + protected: + BoosterHandle *booster; + float defval; + std::vector variable_names; + + public: + XGBoostInterface(); + virtual ~XGBoostInterface(); + + bool build(std::string fname, std::vector const &varnames, float missing_entry_val); + + std::vector const &getVariableNames() const { return variable_names; } + + BoosterHandle *const &getBooster() const { return booster; } + + template bool eval(std::unordered_map const &vars, std::vector &res); + template bool eval(std::unordered_map const &vars, T &res); +}; + +#endif + diff --git a/NanoCORE/Tools/xgboost/XGBoostInterface.hpp b/NanoCORE/Tools/xgboost/XGBoostInterface.hpp new file mode 100644 index 0000000..682bf70 --- /dev/null +++ b/NanoCORE/Tools/xgboost/XGBoostInterface.hpp @@ -0,0 +1,59 @@ +#ifndef XGBOOSTINTERFACE_HPP +#define XGBOOSTINTERFACE_HPP + +#include +//#include "/cvmfs/cms.cern.ch/slc7_amd64_gcc900/external/py3-xgboost/0.90-ghbfee2/lib/python3.8/site-packages/xgboost/include/xgboost/c_api.h" +#include "XGBoostInterface.h" + +using namespace std; + +#define SAFE_XGBOOST(CALL) \ +{ int err_call = (CALL); if (err_call!=0){ std::cout << "Call '" << #CALL << "' returned error code " << err_call << ". XGBoost last error: " << XGBGetLastError() << std::endl; } } + +template bool XGBoostInterface::eval(std::unordered_map const& vars, std::vector& res){ + + res.clear(); + + constexpr unsigned long long nSample = 1; + const unsigned long long nFeatures = variable_names.size(); + float* data_arr = new float[nFeatures]; // array containing the data values input into XGBoost + float* data_arr_ptr = &(data_arr[0]); + for (auto& vv:variable_names){ + auto it_vars = vars.find(vv); + if (it_vars==vars.end()) *data_arr_ptr = defval; + else *data_arr_ptr = it_vars->second; + data_arr_ptr++; + }; + + bst_ulong nout = 0; + const float* score; + DMatrixHandle dvalues; + SAFE_XGBOOST(XGDMatrixCreateFromMat(data_arr, nSample, nFeatures, defval, &dvalues)); + SAFE_XGBOOST(XGBoosterPredict(*booster, dvalues, 0, 0, &nout, &score)); + SAFE_XGBOOST(XGDMatrixFree(dvalues)); + + res.clear(); + res.reserve(nout); + for (bst_ulong rr=0; rr(score[rr])); + + delete[] data_arr; + return true; +} + +template bool XGBoostInterface::eval(std::unordered_map const& vars, T& res){ + std::vector vres; + bool success = this->eval(vars, vres); + if (vres.empty() || vres.size()!=1){ + std::cout << "XGBoostInterface::eval: The vector of results has size = " << vres.size() << " != 1." << std::endl; + assert(0); + success = false; + } + + res = vres.front(); + return success; +} + +template bool XGBoostInterface::eval(std::unordered_map const& vars, float& res); +template bool XGBoostInterface::eval(std::unordered_map const& vars, double& res); + +#endif diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPUL16APV_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPUL16APV_XGB.weights.bin new file mode 100644 index 0000000..de9dfeb Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPUL16APV_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPUL16_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPUL16_XGB.weights.bin new file mode 100644 index 0000000..a11a747 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPUL16_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPUL17_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPUL17_XGB.weights.bin new file mode 100644 index 0000000..5be35b6 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPUL17_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPUL18_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPUL18_XGB.weights.bin new file mode 100644 index 0000000..125444d Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPUL18_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPv2UL16APV_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL16APV_XGB.weights.bin new file mode 100644 index 0000000..90efca3 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL16APV_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPv2UL16_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL16_XGB.weights.bin new file mode 100644 index 0000000..bf28234 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL16_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPv2UL17_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL17_XGB.weights.bin new file mode 100644 index 0000000..85df15f Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL17_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/el_TOPv2UL18_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL18_XGB.weights.bin new file mode 100644 index 0000000..43547dd Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/el_TOPv2UL18_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPUL16APV_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPUL16APV_XGB.weights.bin new file mode 100644 index 0000000..75c8762 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPUL16APV_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPUL16_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPUL16_XGB.weights.bin new file mode 100644 index 0000000..62ab32c Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPUL16_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPUL17_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPUL17_XGB.weights.bin new file mode 100644 index 0000000..8dbfff3 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPUL17_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPUL18_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPUL18_XGB.weights.bin new file mode 100644 index 0000000..4f16087 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPUL18_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL16APV_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL16APV_XGB.weights.bin new file mode 100644 index 0000000..358a2c0 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL16APV_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL16_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL16_XGB.weights.bin new file mode 100644 index 0000000..511c411 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL16_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL17_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL17_XGB.weights.bin new file mode 100644 index 0000000..391a250 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL17_XGB.weights.bin differ diff --git a/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL18_XGB.weights.bin b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL18_XGB.weights.bin new file mode 100644 index 0000000..db25401 Binary files /dev/null and b/NanoCORE/data/TopLeptonMVA/mu_TOPv2UL18_XGB.weights.bin differ diff --git a/README.md b/README.md index b9cc1a0..ab65f04 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ git clone https://github.com/cmstas/NanoTools cd NanoTools/ source /cvmfs/cms.cern.ch/cmsset_default.sh -cd /cvmfs/cms.cern.ch/slc7_amd64_gcc700/cms/cmssw/CMSSW_10_2_13/ ; cmsenv ; cd - +cd /cvmfs/cms.cern.ch/slc7_amd64_gcc900/cms/cmssw/CMSSW_11_2_0_pre5/ ; cmsenv ; cd - cd NanoCORE make test -j12 cd .. @@ -27,7 +27,7 @@ cd workarea/skimtest git clone https://github.com/cmstas/NanoTools cd NanoTools/ source /cvmfs/cms.cern.ch/cmsset_default.sh -cd /cvmfs/cms.cern.ch/slc7_amd64_gcc700/cms/cmssw/CMSSW_10_2_13/ ; cmsenv ; cd - +cd /cvmfs/cms.cern.ch/slc7_amd64_gcc900/cms/cmssw/CMSSW_11_2_0_pre5/ ; cmsenv ; cd - cd NanoCORE make test -j12 cd .. diff --git a/skimmer/Makefile b/skimmer/Makefile index e7afdac..62bde87 100755 --- a/skimmer/Makefile +++ b/skimmer/Makefile @@ -2,10 +2,17 @@ EXE=skim -SOURCES=$(wildcard *.cc) $(wildcard ../rapido/src/*.cc) ../NanoCORE/Nano.cc ../NanoCORE/ElectronSelections.cc ../NanoCORE/MuonSelections.cc ../NanoCORE/Config.cc ../NanoCORE/IsolationTools.cc ../NanoCORE/MCTools.cc +SOURCES=$(wildcard *.cc) $(wildcard ../rapido/src/*.cc) ../NanoCORE/Nano.cc ../NanoCORE/ElectronSelections.cc ../NanoCORE/MuonSelections.cc ../NanoCORE/Config.cc ../NanoCORE/IsolationTools.cc ../NanoCORE/MCTools.cc ../NanoCORE/Tools/xgboost/XGBoostInterface.cc OBJECTS=$(SOURCES:.cc=.o) HEADERS=$(SOURCES:.cc=.h) +# XGBOOST essentials +XGBOOSTLIBDIR = ${XGBOOST_PATH}/lib/ +XGBOOSTINCDIR = ${XGBOOSTLIBDIR}../include/ +RABITINCDIR = ${XGBOOSTLIBDIR}../rabit/include/ +XGBOOSTCXXFLAGS = -I$(XGBOOSTINCDIR) -I$(RABITINCDIR) -L$(XGBOOSTLIBDIR) +XGBOOSTLIBS = -lxgboost -L$(XGBOOSTLIBDIR) + CC = g++ CXX = g++ CXXFLAGS = -g -O2 -Wall -fPIC -Wshadow -Woverloaded-virtual @@ -16,10 +23,10 @@ CXXFLAGS = -g -O2 -Wall -fPIC -Wshadow -Woverloaded-virtual LDFLAGS = -g -O2 ROOTLIBS = $(shell root-config --libs) ROOTCFLAGS = $(shell root-config --cflags) -CXXFLAGS += $(ROOTCFLAGS) -CFLAGS = $(ROOTCFLAGS) -Wall -Wno-unused-function -g -O2 -fPIC -fno-var-tracking -DLorentzVectorPtEtaPhiM4D +CXXFLAGS += $(ROOTCFLAGS) $(XGBOOSTCXXFLAGS) +CFLAGS = $(ROOTCFLAGS) -Wall -Wno-unused-function -g -O2 -fPIC -fno-var-tracking -DLorentzVectorPtEtaPhiM4D $(XGBOOSTCXXFLAGS) EXTRACFLAGS = -I../NanoCORE -I../rapido/src -I../NanoCORE/Tools -I${CMSSW_BASE}/../../../external/boost/1.67.0/include -I${CMSSW_BASE}/src -EXTRAFLAGS = -fPIC -ITMultiDrawTreePlayer -Wunused-variable -lTMVA -lEG -lGenVector -lXMLIO -lMLP -lTreePlayer +EXTRAFLAGS = -fPIC -ITMultiDrawTreePlayer -Wunused-variable -lTMVA -lEG -lGenVector -lXMLIO -lMLP -lTreePlayer $(XGBOOSTLIBS) all: $(EXE) diff --git a/skimmer/condor/submit.py b/skimmer/condor/submit.py index 7eb088e..e7e34a6 100644 --- a/skimmer/condor/submit.py +++ b/skimmer/condor/submit.py @@ -75,8 +75,8 @@ def njobs_to_process(dsname): ] }, max_jobs = njobs_to_process(ds.get_datasetname()), - cmssw_version = "CMSSW_10_2_13", - scram_arch = "slc7_amd64_gcc700", + cmssw_version = "CMSSW_11_2_0_pre5", + scram_arch = "slc7_amd64_gcc900", input_executable = "{}/condor_executable_metis.sh".format(condorpath), # your condor executable here tarfile = "{}/package.tar.xz".format(condorpath), # your tarfile with assorted goodies here special_dir = "skim/{}".format(tag), # output files into /hadoop/cms/store// diff --git a/skimmer/setup.sh b/skimmer/setup.sh index f061acd..9fe600d 100755 --- a/skimmer/setup.sh +++ b/skimmer/setup.sh @@ -3,8 +3,8 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #echo "Setting up ROOT" -export SCRAM_ARCH=slc7_amd64_gcc700 # or whatever scram_arch you need for your desired CMSSW release -export CMSSW_VERSION=CMSSW_10_2_13 +export SCRAM_ARCH=slc7_amd64_gcc900 # or whatever scram_arch you need for your desired CMSSW release +export CMSSW_VERSION=CMSSW_11_2_0_pre5 source /cvmfs/cms.cern.ch/cmsset_default.sh cd /cvmfs/cms.cern.ch/$SCRAM_ARCH/cms/cmssw/$CMSSW_VERSION/src eval `scramv1 runtime -sh` @@ -13,4 +13,12 @@ cd - > /dev/null echo 'Setup following ROOT' which root +xgboost_cfg=${CMSSW_BASE}/config/toolbox/${SCRAM_ARCH}/tools/selected/py3-xgboost.xml +xgboost_version="$(grep -e 'tool name' ${xgboost_cfg} | grep 'py3-xgboost')" +xgboost_version="${xgboost_version##*=\"}" +xgboost_version="${xgboost_version%%\"*}" +xgboost_path="/cvmfs/cms.cern.ch/${SCRAM_ARCH}/external/py3-xgboost/${xgboost_version}/lib/python3.8/site-packages/xgboost" +export LD_LIBRARY_PATH=${xgboost_path}/lib:$LD_LIBRARY_PATH +export XGBOOST_PATH=${xgboost_path} + #eof