diff --git a/README.md b/README.md index 2aa210d467c..6543979711e 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ For recent instruction please visit: https://twiki.cern.ch/twiki/bin/view/CMS/Mi git cms-init git cms-addpkg RecoMET/METFilters - git clone https://github.com/didukhle/MetScanning.git - scram b -j9 + git clone https://github.com/cms-met/MetScanning + scram b -j $(nproc) ``` You might need to run the following command if you want to access files via XROOT: ``` diff --git a/scan/README.md b/scan/README.md new file mode 100644 index 00000000000..90e92b48f7b --- /dev/null +++ b/scan/README.md @@ -0,0 +1,65 @@ +# METScanning + +This framework aims to centralize the MET scanners analysis in a more efficient framework. +For more details see the [Wiki page](https://gitlab.cern.ch/mmahdavi/metscanning/-/wikis/home). + + +# Mannual + +1. Set the environment and bBuild the executable file if needed. +``` +cmsenv +scram b -j $(nproc) +``` +
+ +2. Run the analysis +``` +runAnalysis INPUT_FILE1 [INPUT_FILE2 [...]] --output output.root --dataset DATASET --year YYYY --pass-rec [ON/off] --cross-check [on/OFF] +``` +***`--cross-check ON` option will allow you to have cross-check histograms in NFR*** + +- One can also run ```runAnalysis --help``` or ```runAnalysis -h``` for more detailed help message. +- One may need to modify the configuration files stored in [`config`](https://github.com/cms-met/MetScanning/tree/master/scan/config) directory based on her/his analysis, such as different years, scenarios and etc. +- If one is interested in old-analysis strategy i.e. without BER and NFR control region, it is possible by passing the `--old-analysis` option to the program. Hence the obtained efficencies are with out any cut or ID applied. +
+ +# Plotting Mannual +For running plot scripts, you need to logout and login again if you have set `CMSSW` environment i.e. `cmsenv`. Then you need to set the proper environment, +``` +cd plot +. ./env +cd - +``` +There are two different python scripts which provide `efficiencies` and `occupancy maps` plots such as [plot_efficencies](https://github.com/cms-met/MetScanning/tree/master/scan/plot/plot_efficiencies) and [plot_occupancy_maps](https://github.com/cms-met/MetScanning/tree/master/scan/plot/plot_occupancy_maps) respectively. They are mentioned below separately. + +Before using the scripts, please make sure that the environment has been set up as mention above. + +- **Occupancy maps:** +``` +plot_occupancy_maps [list of output root-files separated by space] --dataset [list of datasets w.r.t provided output root-files separated by space] --year YYYY +``` +
+ +- **Efficiency plots:** + +For full plots, i.e all filters plots individually and merged plots for each provided dataset, `--all` option is needed like below. +``` +plot_efficencies [list of output root-files separated by space] --dataset [list of datasets w.r.t provided output root-files separated by space] --year 2018 --all +``` + +If one needs also to obtain the actual final merged plot, all datasets must be provided. In this case the `--all` option is optional, for example, below command will plot all kind of plots and the actual final merged plot as well. +``` +plot_efficencies jetht_output.root singlemuon_output.root egamma_output.root --dataset jetht singlemuon egamma --year 2018 --all +``` +
+ +- **Plots Configurations:** + +The `plot_efficencies` script uses `yaml` configuration files which contain `binning` settings according to regions (`BER` and `NFR`) variables and/or datasets, for each filter separately. + +The configuration files are provided in the [config](https://github.com/cms-met/MetScanning/tree/master/scan/config) directory. One may need to modify theses configuration files to obtian the proper plots. +
+
+ +- *One can also run* ```plot_efficencies [--help, -h]``` or ```plot_occupancy_maps [--help, -h]``` for more detailed help messages. diff --git a/scan/bin/BERegion.cc b/scan/bin/BERegion.cc new file mode 100644 index 00000000000..c4e9d607b13 --- /dev/null +++ b/scan/bin/BERegion.cc @@ -0,0 +1,178 @@ +#include "BERegion.h" + +#include + + +BERegion::BERegion(TTreeReader &reader, const std::string berCat) + : Tree(reader), + berCat_{berCat} { + cfg_ = YAML::LoadFile("config/BER.yaml"); + minPfMet_ = Get("min_pfmet"); + + if (berCat == "BadChCand") { + isBER = &BERegion::isBadChCandBER; + minDPhi_ = Get("min_dphi"); + pfCanMinPt_ = Get("min_pfcandid_pt"); + pfCanPdgId_ = Get("abs_pfcand_pdgid"); + } + + else if (berCat == "GlbSTightHalo") { + isBER = &BERegion::isGlbSTHaloBER; + maxPfMetPhi_ = Get("max_abs_pfmet_phi"); + minPfMetPhi_ = Get("min_abs_pfmet_phi"); + minJetPt_ = Get("min_jet_pt"); + maxJetEta_ = Get("max_abs_jet_eta"); + maxJetChef_ = Get("max_jet_chef"); + jetPtGt25Num_ = Get("num_jets_ptgt25"); + jetPtGt200Num_ = Get("num_jets_ptgt200"); + } + + else if (berCat == "BadPFMuon") { + isBER = &BERegion::isBadPFMuonBER; + minDPhi_ = Get("min_dphi"); + minMuPt_ = Get("min_muon_pt"); + maxAddMuPt_ = Get("max_additional_muon_pt"); + minDeltaR_ = Get("min_delta_r"); + jetPtGt25Num_ = Get("num_jets_ptgt25"); + jetPtGt200Num_ = Get("num_jets_ptgt200"); + minMuNum_ = Get("min_num_muon"); + } + + else if (berCat == "EcalBadCal_U") { + isBER = &BERegion::isEcalBadCalBER; + minDPhi_ = Get("min_dphi"); + minJetPt_ = Get("min_jet_pt"); + maxJetEta_ = Get("max_abs_jet_eta"); + minJetEta_ = Get("min_abs_jet_eta"); + minJetNeef_ = Get("min_jet_neef"); + jetPtGt25Num_ = Get("num_jets_ptgt25"); + jetPtGt200Num_ = Get("num_jets_ptgt200"); + } + + else if (berCat == "HBHENoise") { + isBER = &BERegion::isHBHENoiseBER; + minDPhi_ = Get("min_dphi"); + minJetPt_ = Get("min_jet_pt"); + maxJetEta_ = Get("max_abs_jet_eta"); + minJetNhef_ = Get("min_jet_nhef"); + jetPtGt25Num_ = Get("num_jets_ptgt25"); + jetPtGt200Num_ = Get("num_jets_ptgt200"); + } + + else + isBER = &BERegion::isOthersBER; + +} + + +bool BERegion::operator()() { + return (this->*isBER)(); +} + + +bool BERegion::isBadChCandBER() { + int i = 0; + if (*pfmet > minPfMet_) { + for (long unsigned int j = 0; j < (*pfCandPt).size(); j++) + if ((*pfCandPt)[j] > pfCanMinPt_ and + std::abs((*pfCandPdgId)[j]) == pfCanPdgId_ and + std::fabs( + TVector2::Phi_mpi_pi(*pfmetPhi-(*pfCandPhi)[j])) > minDPhi_) + i++; + } + + return (i >= 1); +} + + +bool BERegion::isGlbSTHaloBER() { + if (*pfmet > minPfMet_ and + (*jetPt).size() == 1 and + (*numJetsPt25) == 1 and + (std::fabs(TVector2::Phi_mpi_pi(*pfmetPhi)) < maxPfMetPhi_ or + std::fabs(TVector2::Phi_mpi_pi(*pfmetPhi)) > minPfMetPhi_) and + (*jetPt)[0] > minJetPt_ and + std::fabs((*jetEta)[0]) < maxJetEta_ and + (*jetCHEF)[0] < maxJetChef_) + return true; + + return false; +} + + +bool BERegion::isBadPFMuonBER() { + if (*pfmet > minPfMet_ and + (*jetPt).size() == jetPtGt200Num_ and + (*numJetsPt25) == jetPtGt25Num_ and + (*muonPt).size() >= minMuNum_ and + (*muonPt)[0] > minMuPt_ and + std::fabs( + TVector2::Phi_mpi_pi(*pfmetPhi - (*muonPhi)[0])) >= minDPhi_ and + (((*muonPt).size() > minMuNum_) ? ((*muonPt)[1] < maxAddMuPt_) : true) + ) { + int k = 0; + for (long unsigned int j = 0; j < (*jetPt).size(); j++) { + // To be sure that the jets are not comming from muon jet cone + // by requiring DR < 0.4 + float const deltaR = std::sqrt( + std::pow((*muonEta)[0] - (*jetEta)[j], 2) + + std::pow((*muonPhi)[0] - (*jetPhi)[j], 2)); + if (deltaR < minDeltaR_) + continue; + k++; + break; + } + + return (k == 0); + } + + return false; +} + + +bool BERegion::isEcalBadCalBER() { + if (*pfmet > minPfMet_ and + (*jetPt).size() == jetPtGt200Num_ and + (*numJetsPt25) == jetPtGt25Num_ and + (*jetPt)[0] > minJetPt_ and + std::fabs((*jetEta)[0]) > minJetEta_ and + std::fabs((*jetEta)[0]) < maxJetEta_ and + (*jetNEEF)[0] > minJetNeef_ and + std::fabs(TVector2::Phi_mpi_pi(*pfmetPhi - (*jetPhi)[0])) > minDPhi_) + return true; + + return false; +} + + +bool BERegion::isHBHENoiseBER() { + if (*pfmet > minPfMet_ and + (*jetPt).size() == jetPtGt200Num_ and + (*numJetsPt25) == jetPtGt25Num_ and + (*jetPt)[0] > minJetPt_ and + std::fabs((*jetEta)[0]) < maxJetEta_ and + (*jetNHEF)[0] > minJetNhef_ and + std::fabs(TVector2::Phi_mpi_pi(*pfmetPhi - (*jetPhi)[0])) > minDPhi_) + return true; + + return false; +} + + +bool BERegion::isOthersBER() { + return (*pfmet > minPfMet_); +} + + +template +T BERegion::Get(std::string const field) { + if (cfg_[berCat_][field]) + return cfg_[berCat_][field].as(); + else { + std::ostringstream message; + message << "BER configuration of " << berCat_ + << " doesn't contain [" << field << "] field."; + throw std::runtime_error(message.str()); + } +} + diff --git a/scan/bin/BERegion.h b/scan/bin/BERegion.h new file mode 100644 index 00000000000..0bf9f258a2e --- /dev/null +++ b/scan/bin/BERegion.h @@ -0,0 +1,56 @@ +#ifndef BEREGION_H +#define BEREGION_H + +#include + +#include "Tree.h" + + +class BERegion final : private Tree { + public: + // Constructor + BERegion(TTreeReader &reader, const std::string="Others"); + bool operator()(); + + private: + std::string berCat_; + + // BER configuration. + YAML::Node cfg_; + + // All BER parameters + float minPfMet_, minDPhi_, maxPfMetPhi_, minPfMetPhi_, minJetPt_, maxJetEta_, + minJetEta_, maxJetChef_, minJetNeef_, minJetNhef_, minMuPt_, + maxAddMuPt_, minDeltaR_, pfCanMinPt_; + + int pfCanPdgId_, jetPtGt25Num_; + + long unsigned int jetPtGt200Num_, minMuNum_; + + // Check whether the event is in BER of BadChCand filters. + bool isBadChCandBER(); + + // Check whether the event is in BER of GlbSTHalo and GlbTHalo filters. + bool isGlbSTHaloBER(); + + // Check whether the event is in BER of BadPFMuon filters. + bool isBadPFMuonBER(); + + // Check whether the event is in BER of EcalBadCal filters. + bool isEcalBadCalBER(); + + // Check whether the event is in BER of HBHENoise and HBHEIsoNoise filters. + bool isHBHENoiseBER(); + + // Check whether the event is in BER of other filters. + bool isOthersBER(); + + // A pointer to one of functions checking whether the event is in BER or not. + bool (BERegion::*isBER)(); + + // Return the value of given field from configuration file. + template + T Get(std::string const field); +}; + +#endif diff --git a/scan/bin/BuildFile.xml b/scan/bin/BuildFile.xml new file mode 100644 index 00000000000..60a693b7ed6 --- /dev/null +++ b/scan/bin/BuildFile.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/scan/bin/MetFilter.cc b/scan/bin/MetFilter.cc new file mode 100644 index 00000000000..f8f657b2289 --- /dev/null +++ b/scan/bin/MetFilter.cc @@ -0,0 +1,122 @@ +#include "MetFilter.h" + + +MetFilter::MetFilter(TString const &dataset, TTreeReader &reader, + TString const &name, TString const &flag, bool const isRecmnded, + int const &N_1Key, bool const isOldAnlz) + : name_{name}, + flag_{flag}, + isPassed_{reader, flag}, + isRecmnded_{isRecmnded}, + passRecKey_{N_1Key}, + isOldAnlz_{isOldAnlz} { + + int min = 0, max = 5000, nbins = max - min; + unsigned short int i = 0, j = 0; + for(auto const ®ion : regions) { + if ((isOldAnlz) ? region.first != "AR" : region.first == "AR") + continue; + TString tempTitle = name_ + ", " + dataset + ", " + region.second; + TString occTitleF = "Jets Occupancy Map [pt > 200] for events failing "; + TString occTitleP = "Jets Occupancy Map [pt > 200] for events passing "; + TString fullNameF = "occMap_failed_" + name_ + "_" + region.first; + TString fullNameP = "occMap_passed_" + name_ + "_" + region.first; + TString titleF = occTitleF + tempTitle + ";#eta;#phi;Events"; + TString titleP = occTitleP + tempTitle + ";#eta;#phi;Events"; + failedOccupancyMap_.emplace_back(fullNameF, titleF, + 1000, -5, 5, 314, -3.1416, 3.1416); + passedOccupancyMap_.emplace_back(fullNameP, titleP, + 1000, -5, 5, 314, -3.1416, 3.1416); + occMapIndex_[region.first] = i++; + + for(auto const &var : vars) { + TString tempName = name_+ "_" + region.first + "_" + var; + TString fullName = "eff_" + tempName; + TString title = tempTitle + ";" + var + + ((region.first != "BER") ? ";Efficiency" : ";NoiseRejectionFraction"); + + auto fullNameDen = "den_" + tempName; + auto fullNameNum = "num_" + tempName; + auto numTitle = tempTitle + ", numerator" + ";" + var + ";Events"; + auto denTitle = tempTitle + ", denominator" + ";" + var + ";Events"; + + efficiency_.emplace_back(fullName, title, nbins, min, max); + denominator_.emplace_back(fullNameDen, denTitle, nbins, min, max); + numerator_.emplace_back(fullNameNum, numTitle, nbins, min, max); + effIndex_[region.first][var] = j++; + } + } +} + + +const std::array, 3> MetFilter::regions = { + {{"NFR", "Noise Free Region"}, {"BER", "Background Enriched Region"}, + {"AR", "All Regions"}}}; + + +const std::array MetFilter::vars = {{"pfMet", "puppiMet", + "leadingJetPt", "nPVx"}}; + + +MetFilter::~MetFilter() noexcept {} + + +void MetFilter::Fill(double const &x, std::array const &info, + int const &passRecStatus) { + if (passRecStatus == passRecKey_ or passRecStatus == 255 or + passRecStatus == -1) { + TString const ®ion = info[0]; + TString const &var = info[1]; + auto &i = effIndex_[region][var]; + efficiency_[i].Fill((region != "BER") ? *isPassed_ : not(*isPassed_), x); + denominator_[i].Fill(x); + if ((*isPassed_ and region != "BER") or + (not(*isPassed_) and region == "BER")) + numerator_[i].Fill(x); + } +} + + +void MetFilter::Fill( + doubleVectorReader &etaVec, doubleVectorReader &phiVec, + TString const ®ion, int const &passRecStatus) { + if (passRecStatus == passRecKey_ or passRecStatus == 255 or + passRecStatus == -1) { + auto &i = occMapIndex_[region]; + + if (!(*isPassed_)) + for (long unsigned int j = 0; j < (*etaVec).size(); j++) + failedOccupancyMap_[i].Fill((*etaVec)[j], (*phiVec)[j]); + + if (*isPassed_) + for (long unsigned int j = 0; j < (*etaVec).size(); j++) + passedOccupancyMap_[i].Fill((*etaVec)[j], (*phiVec)[j]); + } +} + + +void MetFilter::SetDirectory(TFile &outputRootFile) { + for (long unsigned int i = 0; i < efficiency_.size(); i++) + efficiency_[i].SetDirectory(&outputRootFile); +} + + +bool MetFilter::IsPassed() { + return *isPassed_; +} + + +bool MetFilter::IsRecommeded() const { + return isRecmnded_; +} + + +TString MetFilter::GetName() const { + return name_; +} + + +TString MetFilter::GetFlag() const { + return flag_; +} + diff --git a/scan/bin/MetFilter.h b/scan/bin/MetFilter.h new file mode 100644 index 00000000000..3f1ecfc6866 --- /dev/null +++ b/scan/bin/MetFilter.h @@ -0,0 +1,93 @@ +#ifndef METFILTER_H +#define METFILTER_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +typedef TTreeReaderValue> doubleVectorReader; + + +class MetFilter { + public: + // COnstructor + MetFilter(TString const &dataset, TTreeReader &reader, TString const &name, + TString const &flag, bool const isRecmnded, int const &N_1Key, + bool const isOldAnlz=false); + // Destructor + ~MetFilter() noexcept; + + // A method for filling filters efficiencies + void Fill(double const &x, std::array const &info, + int const &passRecStatus); + + // A method for filling filters occupancy maps + void Fill(doubleVectorReader &etaVec, doubleVectorReader &phiVec, + TString const ®ion, int const &passRecStatus); + + // Setting directory of output root file + void SetDirectory(TFile &outputRootFile); + + // Checkes whether the events id passed the filter or not. + bool IsPassed(); + + // Checks whether the filter is a recommended MET filters or not. + bool IsRecommeded() const; + + // Retruns the filter name + TString GetName() const; + + // Retruns the filter flag + TString GetFlag() const; + + // A dictionary for different regions which the abbreviations are the keys. + static const std::array, 3> regions; + + // Variables array + static const std::array vars; + + enum Filters{GoodVertices, GlbSTightHalo, HBHENoise, HBHEIsoNoise, + EcalTP, EEBadSc, EcalBadCal_U, BadPFMuon, BadPFMuon_U, BadPFMuon_DzU, + EcalDCBE, EcalDCBE_U, GlbTightHalo, BadChCand, BadChCand_U, Others}; + + private: + // Filter's name. + TString const name_; + + // Filter's flag for accesing the filter's branch. + TString const flag_; + + // Event's status w.r.t. the filter's respond. + TTreeReaderValue isPassed_; + + // Indicates whether the filters is a recommended MET filter or not. + bool const isRecmnded_; + + // Indicates whether other filters are passed recommended filters. + int passRecKey_; + + // Indicates whether the analysis is based on old strategy or not. + // Old strategy means without applying NFR and BER constraints. + bool const isOldAnlz_; + + std::vector efficiency_; + + std::vector numerator_, denominator_; + + std::vector failedOccupancyMap_, passedOccupancyMap_; + + std::map> effIndex_; + + std::map occMapIndex_; +}; + +#endif diff --git a/scan/bin/NFRegion.cc b/scan/bin/NFRegion.cc new file mode 100644 index 00000000000..f2f97137508 --- /dev/null +++ b/scan/bin/NFRegion.cc @@ -0,0 +1,354 @@ +#include "NFRegion.h" + +#include +#include + + +enum {pt, eta, phi, mass, ptr}; + +NFRegion::NFRegion(TTreeReader &reader, TString dataset, TString year, + bool fillMore) + : Tree(reader), + fillMore_{fillMore} { + + if (dataset == "jetht") { + isNFR = &NFRegion::isJetHtNFR; + if (fillMore_) { + ptDist_.emplace_back("jet0_pt", "jet0;pt;events", 1000, 0., 1000.); + ptDist_.emplace_back("jet1_pt", "jet1;pt;events", 1000, 0., 1000.); + etaDist_.emplace_back("jet0_eta", "jet0;eta;events", 100, -5, 5); + etaDist_.emplace_back("jet1_eta", "jet1;eta;events", 100, -5, 5); + phiDist_.emplace_back("jet0_phi", "jet0;phi;events", 100, -3.5, 3.5); + phiDist_.emplace_back("jet1_phi", "jet1;phi;events", 100, -3.5, 3.5); + ptRatioDist_ = TH1F("pt_ratio", "pt0/pt1;ratio;events", 100, 0.9, 1.3); + massDist_ = TH1F("diJet_mass", "dijet mass;mass;events", 1000, 0, 5000); + } + } + + else if (dataset == "doublemuon") { + isNFR = &NFRegion::isDMuonNFR; + if (fillMore_) { + ptDist_.emplace_back("muon0_pt", "muon0;pt;events", 1000, 0., 1000.); + ptDist_.emplace_back("muon1_pt", "muon1;pt;events", 1000, 0., 1000.); + etaDist_.emplace_back("muon0_eta", "muon0;eta;events", 100, -5, 5); + etaDist_.emplace_back("muon1_eta", "muon1;eta;events", 100, -5, 5); + phiDist_.emplace_back("muon0_phi", "muon0;phi;events", 90, -3.5, 3.5); + phiDist_.emplace_back("muon1_phi", "muon1;phi;events", 90, -3.5, 3.5); + massDist_ = TH1F("Z_mass", "", 1000, 0, 1000); + } + } + + else if (dataset == "egamma" or dataset == "singleelectron") { + isNFR = &NFRegion::isEGammaNFR; + if (fillMore_) { + ptDist_.emplace_back("ele0_pt", "ele0;pt;events", 1000, 0., 1000.); + ptDist_.emplace_back("ele1_pt", "ele1;pt;events", 1000, 0., 1000.); + etaDist_.emplace_back("ele0_eta", "ele0;eta;events", 100, -5, 5); + etaDist_.emplace_back("ele1_eta", "ele1;eta;events", 100, -5, 5); + phiDist_.emplace_back("ele0_phi", "ele0;phi;events", 90, -3.5, 3.5); + phiDist_.emplace_back("ele1_phi", "ele1;phi;events", 90, -3.5, 3.5); + massDist_ = TH1F("Z_mass", "", 1000, 0, 1000); + } + } + + else if (dataset == "singlemuon") { + isNFR = &NFRegion::isSMuonNFR; + if (fillMore_) { + ptDist_.emplace_back("muon0_pt", "muon0;pt;events", 1000, 0., 1000.); + etaDist_.emplace_back("muon0_eta", "muon0;eta;events", 100, -5, 5); + phiDist_.emplace_back("muon0_phi", "muon0;phi;events", 90, -3.5, 3.5); + phiDist_.emplace_back("pfmetPhi", "PF MET;phi;events", 90, -3.5, 3.5); + massDist_ = TH1F("mt", "mt of muon+pfmet;m_t;events", 1000, 0, 1000); + } + } + + else if (dataset == "mc") { + isNFR = &NFRegion::isSimNFR; + } + + + if (year == "2018") + passJetId = &NFRegion::passJetId_2018; + else if (year == "2017") + passJetId = &NFRegion::passJetId_2017; + else if (year == "2016") + passJetId = &NFRegion::passJetId_2016; + +} + + +bool NFRegion::operator()() { + favoredCandIdx_.clear(); + return (this->*isNFR)(); +} + + +bool NFRegion::passJetId_2018(int i) { + if (std::fabs((*jetEta)[i]) <= 2.6) { + return ((*jetNHEF)[i] < 0.9 and (*jetNEEF)[i] < 0.9 and + ((*jetChM)[i] + (*jetNM)[i]) > 1 and (*jetMuEF)[i] < 0.8 and + (*jetCHEF)[i] > 0 and (*jetChM)[i] > 0 and (*jetCEEF)[i] < 0.8); + } + + else if (std::fabs((*jetEta)[i]) <= 2.7) { + return ((*jetNHEF)[i] < 0.9 and (*jetNEEF)[i] < 0.99 and + (*jetMuEF)[i] < 0.8 and (*jetChM)[i] > 0 and (*jetCEEF)[i] < 0.8); + } + + else if (std::fabs((*jetEta)[i]) <= 3.0) { + return (*jetNEEF)[i] > 0.02 and (*jetNEEF)[i] < 0.99 and (*jetNM)[i] > 2; + } + + else if (std::fabs((*jetEta)[i]) <= 5.0) { + return (*jetNHEF)[i] > 0.2 and (*jetNEEF)[i] < 0.9 and (*jetNM)[i] > 10; + } + + return false; +} + + +bool NFRegion::passJetId_2017(int i) { + if (std::fabs((*jetEta)[i]) <= 2.7) { + return ((*jetNHEF)[i] < 0.9 and (*jetNEEF)[i] < 0.9 and + ((*jetChM)[i] + (*jetNM)[i]) > 1 and (*jetMuEF)[i] < 0.8 and + // Applying additional constraints for abs(eta) <= 2.4 + ((std::fabs((*jetEta)[i]) <= 2.4) ? + (*jetCHEF)[i] > 0 and (*jetChM)[i] > 0 and (*jetCEEF)[i] < 0.8 : true)); + } + + else if (std::fabs((*jetEta)[i]) <= 3.0) { + return (*jetNEEF)[i] > 0.02 and (*jetNEEF)[i] < 0.99 and (*jetNM)[i] > 2; + } + + else if (std::fabs((*jetEta)[i]) > 3.0) { + return (*jetNHEF)[i] > 0.02 and (*jetNEEF)[i] < 0.9 and (*jetNM)[i] > 10; + } + + return false; +} + + +bool NFRegion::passJetId_2016(int i) { + if (std::fabs((*jetEta)[i]) <= 2.7) { + return (*jetNHEF)[i] < 0.99 and + (*jetNEEF)[i] < 0.99 and + ((*jetChM)[i] + (*jetNM)[i]) > 1 and + // Applyimg additional constraints for abs(eta) <= 2.4 + ((std::fabs((*jetEta)[i]) <= 2.4) ? + ((*jetCHEF)[i] > 0 and (*jetChM)[i] > 0 and (*jetCEEF)[i] < 0.99) + : true); + } + + else if (std::fabs((*jetEta)[i]) <= 3.0) { + return (*jetNEEF)[i] > 0.01 and + (*jetNHEF)[i] < 0.98 and + (*jetNM)[i] > 2; + } + + else if (std::fabs((*jetEta)[i]) > 3.0) { + return (*jetNEEF)[i] < 0.9 and (*jetNM)[i] > 10; + } + + return false; +} + + +bool NFRegion::isJetHtNFR() { + if (*pfmet > 100) + return false; + + for (long unsigned int i = 0; i < (*jetPt).size(); i++) { + if ((*jetPt)[i] < 200) + continue; + + if ((this->*passJetId)(i)) + favoredCandIdx_.push_back(i); + + if (favoredCandIdx_.size() == 2) + break; + } + + if (favoredCandIdx_.size() >= 2) { + short int const &O = favoredCandIdx_[0], &one = favoredCandIdx_[1]; + auto const deltaPhi = std::fabs( + TVector2::Phi_mpi_pi((*jetPhi)[O] - (*jetPhi)[one])); + if (deltaPhi >= 2.9) { + auto const ptRatio = std::fabs((*jetPt)[O] / (*jetPt)[one]); + if (ptRatio > 0.8 and ptRatio < 1.2) { + if (not fillMore_) + return true; + + TLorentzVector jet0P4(0, 0 ,0 ,0), jet1P4(0, 0, 0, 0); + jet0P4.SetPtEtaPhiE( + (*jetPt)[O], (*jetEta)[O], (*jetPhi)[O], (*jetEn)[O]); + jet1P4.SetPtEtaPhiE( + (*jetPt)[one], (*jetEta)[one], (*jetPhi)[one], (*jetEn)[one]); + + double const diJetMass = (jet0P4 + jet1P4).M(); + Fill(jetPt, pt); + Fill(jetEta, eta); + Fill(jetPhi, phi); + Fill(diJetMass, mass); + Fill(ptRatio, ptr); + return true; + } + } + } + + return false; +} + + +bool NFRegion::isDMuonNFR() { + if (*pfmet > 50) + return false; + + for (long unsigned int i = 0; i < (*isPFMuon).size(); i++) + if ((*isPFMuon)[i] and + (*isMediumMuon)[i] == 1 and + (*muonIso)[i] < 0.2 and + (*muonPt)[i] > 30) + favoredCandIdx_.push_back(i); + + if (favoredCandIdx_.size() == 2) { + short int const &O = favoredCandIdx_[0], &one = favoredCandIdx_[1]; + if ((*muonCharge)[O] * (*muonCharge)[one] != -1) + return false; + + TLorentzVector mu0P4(0, 0 ,0 ,0), mu1P4(0, 0, 0, 0); + + mu0P4.SetPtEtaPhiE((*muonPt)[O], (*muonEta)[O], + (*muonPhi)[O], (*muonEn)[O]); + mu1P4.SetPtEtaPhiE((*muonPt)[one], (*muonEta)[one], + (*muonPhi)[one], (*muonEn)[one]); + + double const invMass = (mu0P4 + mu1P4).M(); + if (invMass > 81 and invMass < 101) { + if (not fillMore_) + return true; + + Fill(muonPt, pt); + Fill(muonEta, eta); + Fill(muonPhi, phi); + Fill(invMass, mass); + return true; + } + } + + return false; +} + + +bool NFRegion::isEGammaNFR() { + if (*pfmet > 50) + return false; + + for (long unsigned int i = 0; i < (*elePt).size(); i++) + if ((*elePt)[i] > 30.0 and (*isMediumEle)[i] == 1) + favoredCandIdx_.push_back(i); + + if (favoredCandIdx_.size() == 2) { + short int const &O = favoredCandIdx_[0], &one = favoredCandIdx_[1]; + if ((*eleCharge)[O] * (*eleCharge)[one] != -1) + return false; + + TLorentzVector el0P4(0, 0 ,0 ,0), el1P4(0, 0, 0, 0); + + el0P4.SetPtEtaPhiE((*elePt)[O], (*eleEta)[O], + (*elePhi)[O], (*eleEn)[O]); + el1P4.SetPtEtaPhiE((*elePt)[one], (*eleEta)[one], + (*elePhi)[one], (*eleEn)[one]); + + double const invMass = (el0P4 + el1P4).M(); + if (invMass > 81 and invMass < 101) { + if (not fillMore_) + return true; + + Fill(elePt, pt); + Fill(eleEta, eta); + Fill(elePhi, phi); + Fill(invMass, mass); + return true; + } + } + + return false; +} + + +bool NFRegion::isSMuonNFR() { + if (*pfmet > 100.0) + return false; + + TLorentzVector pfmetP4(0, 0 ,0 ,0); + pfmetP4.SetPtEtaPhiE(*pfmet, 0, *pfmetPhi, *pfmet); + for (long unsigned int i = 0; i < (*isPFMuon).size(); i++) + if ((*isPFMuon)[i] and + (*isMediumMuon)[i] == 1 and + (*muonIso)[i] < 0.2 and + (*muonPt)[i] > 30.0) { + TLorentzVector muP4(0, 0 ,0 ,0); + + muP4.SetPtEtaPhiE( + (*muonPt)[i], (*muonEta)[i], (*muonPhi)[i], (*muonEn)[i]); + + auto const mT = (muP4 + pfmetP4).Mt(); + if (mT <= 120.0) { + favoredCandIdx_.push_back(i); + if (not fillMore_) + return true; + + Fill(muonPt, pt); + Fill(muonEta, eta); + Fill(muonPhi, phi); + Fill(*pfmetPhi, phi); + Fill(mT, mass); + return true; + } + } + + return false; +} + + +bool NFRegion::isSimNFR() { + if (*pfmet < 100) + return true; + + return false; +} + + +void NFRegion::Fill(doubleVectorReader &var, int const &varType) { + short int i = 0; + switch (varType) { + case pt: + for (auto const &idx : favoredCandIdx_) + ptDist_[i++].Fill((*var)[idx]); + break; + + case eta: + for (auto const &idx : favoredCandIdx_) + etaDist_[i++].Fill((*var)[idx]); + break; + + case phi: + for (auto const &idx : favoredCandIdx_) + phiDist_[i++].Fill((*var)[idx]); + break; + } +} + + +void NFRegion::Fill(double const &var, int const &varType) { + switch (varType) { + case mass: + massDist_.Fill(var); + break; + + case ptr: + ptRatioDist_.Fill(var); + break; + } +} + diff --git a/scan/bin/NFRegion.h b/scan/bin/NFRegion.h new file mode 100644 index 00000000000..72d532c7a49 --- /dev/null +++ b/scan/bin/NFRegion.h @@ -0,0 +1,62 @@ +#ifndef NFREGION_H +#define NFREGION_H + +#include + +#include "Tree.h" + + +class NFRegion final : private Tree { + public: + // Constructor + NFRegion(TTreeReader &reader, TString dataset, TString year, bool fillMore); + + bool operator()(); + + private: + TString dataset_; + + std::vector favoredCandIdx_; + + // Histograms for cross-check plots. + std::vector ptDist_, etaDist_, phiDist_; + TH1F massDist_, ptRatioDist_; + + // Checks whether a given jet passes JetID for 2018 datasets + bool passJetId_2018(int i); + // Checks whether a given jet passes JetID for 2017 datasets + bool passJetId_2017(int i); + // Checks whether a given jet passes JetID for 2016 datasets + bool passJetId_2016(int i); + + // A pointer to one of functions checking whether a given jet passes JetID + bool (NFRegion::*passJetId)(int i); + + // Check whether the event is in Noise Free Region for JetHT dataset + bool isJetHtNFR(); + + // Check whether the event is in Noise Free Region for Double Muon dataset + bool isDMuonNFR(); + + // Check whether the event is in Noise Free Region for + // EGamma or Single Electron dataset + bool isEGammaNFR(); + + // Check whether the event is in Noise Free Region for Single Muon dataset + bool isSMuonNFR(); + + // Check whether the event is in Noise Free Region for MC datasets + bool isSimNFR(); + + // A pointer to one of functions checking whether the event is in NFR or not + bool (NFRegion::*isNFR)(); + + void Fill(doubleVectorReader &var, int const &varType); + + void Fill(double const &var, int const &varType); + + // Indicates whether the cross-check plots should be filled or not. + bool fillMore_; +}; + +#endif diff --git a/scan/bin/Tree.cc b/scan/bin/Tree.cc new file mode 100644 index 00000000000..bf226fd3dbd --- /dev/null +++ b/scan/bin/Tree.cc @@ -0,0 +1,41 @@ +#include "Tree.h" + + +Tree::Tree(TTreeReader &reader) + : run(reader, "_runNb"), + lumi(reader, "_lumiBlock"), + event(reader, "_eventNb"), + npvx(reader, "_n_PV"), + numJetsPt25(reader, "_number_jets_pt25"), + pfmet(reader, "_met"), + pfmetPhi(reader, "_met_phi"), + puppimet(reader, "_puppimet"), + jetPt(reader, "_jetPt"), + jetEta(reader, "_jetEta"), + jetPhi(reader, "_jetPhi"), + jetEn(reader, "_jetEnergy"), + jetCHEF(reader, "_jet_CHEF"), + jetNEEF(reader, "_jet_NEEF"), + jetNHEF(reader, "_jet_NHEF"), + jetMuEF(reader, "_jet_MUEF"), + jetCEEF(reader, "_jet_CEEF"), + muonPt(reader, "_muonPt"), + muonEta(reader, "_muonEta"), + muonPhi(reader, "_muonPhi"), + muonEn(reader, "_muonEnergy"), + muonIso(reader, "_muonIsoSumDR04"), + elePt(reader, "_elePt"), + eleEta(reader, "_eleEta"), + elePhi(reader, "_elePhi"), + eleEn(reader, "_eleEnergy"), + pfCandPt(reader, "_PFcand_pt"), + pfCandPhi(reader, "_PFcand_phi"), + pfCandPdgId(reader, "_PFcand_pdgId"), + jetChM(reader, "_jet_CHM"), + jetNM(reader, "_jet_NM"), + isMediumMuon(reader, "_muonMedium"), + muonCharge(reader, "_muonCharge"), + isMediumEle(reader, "gsf_VID_cutBasedElectronID_Fall17_94X_V2_medium"), + eleCharge(reader, "_eleCharge"), + isPFMuon(reader, "_muonPF") {} + diff --git a/scan/bin/Tree.h b/scan/bin/Tree.h new file mode 100644 index 00000000000..20633ae25ab --- /dev/null +++ b/scan/bin/Tree.h @@ -0,0 +1,41 @@ +#ifndef TREE_H +#define TREE_H + +#include +#include + + +typedef TTreeReaderValue> doubleVectorReader; +typedef TTreeReaderValue> intVectorReader; + +class Tree { + public: + // Constructor + Tree(TTreeReader &reader); + + TTreeReaderValue run, lumi, event; + + TTreeReaderValue npvx, numJetsPt25; + + TTreeReaderValue pfmet, pfmetPhi, puppimet; + + doubleVectorReader jetPt, jetEta, jetPhi, jetEn; + + doubleVectorReader jetCHEF, jetNEEF, jetNHEF, jetMuEF, jetCEEF; + + doubleVectorReader muonPt, muonEta, muonPhi, muonEn, muonIso; + + doubleVectorReader elePt, eleEta, elePhi, eleEn; + + doubleVectorReader pfCandPt, pfCandPhi; + + intVectorReader pfCandPdgId, jetChM, jetNM; + + intVectorReader isMediumMuon, muonCharge; + + intVectorReader isMediumEle,eleCharge; + + TTreeReaderValue> isPFMuon; +}; + +#endif diff --git a/scan/bin/runAnalysis.cc b/scan/bin/runAnalysis.cc new file mode 100644 index 00000000000..ed8824197b6 --- /dev/null +++ b/scan/bin/runAnalysis.cc @@ -0,0 +1,249 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "BERegion.h" +#include "MetFilter.h" +#include "NFRegion.h" +#include "Tree.h" + + +namespace po = boost::program_options; + +int main(int argc, char *argv[]) { + unsigned int step; + int event_i = 0, maxEvents; + std::string output, dataset, year, oldAnlz, verbosity; + bool isVerbose, crossCheckPlots, passRecOption, isOldAnlz; + std::vector inputs; + YAML::Node filtersConfig = YAML::LoadFile("config/met_filters.yaml"); + int const metFiltersNum = filtersConfig.size(); + // Stores which recommended MET filters are passed. + int passRecStatus = 255; + + std::array statistics{}; + + enum EffCat{nfr_pfmet, nfr_pupmet, nfr_lJpt, nfr_npvx, + ber_pfmet, ber_pupmet, ber_lJpt, ber_npvx, + ar_pfmet, ar_pupmet, ar_lJpt, ar_npvx}; + enum OccMapCat{nfr, ber, ar}; + + std::map> effCat; + std::map occMap; + + // Managing program options. + po::options_description optionsDescription{"Options"}; + optionsDescription.add_options() + ("help,h", "Help screen") + ("year", po::value(&year)->required(), "Dataset year") + ("output,o", po::value(&output)->required(), + "Output root file") + ("dataset", po::value(&dataset)->required(), "Dataset name") + ("pass-rec", po::value(&passRecOption)->default_value(true), "Require" + "events to pass the recommended MET filters except the one under study") + ("max-events", po::value(&maxEvents)->default_value(-1), + "Maximum number of events to process.") + ("step", po::value(&step)->default_value(100000), + "Progress steps (if --verbose[-v] is passed to the program)") + ("cross-check", po::value(&crossCheckPlots)->default_value(false), + "Plot cross-check histograms") + ("old-analysis", "Enables the analysis without control regions Cuts.") + ("verbose,v", "Show progress"); + + po::options_description hiddenOptionsDescription; + hiddenOptionsDescription.add_options() + ("input-files", po::value>(), ""); + po::positional_options_description posOptionsDescription; + posOptionsDescription.add("input-files", -1); + + po::options_description allOptionsDescription; + allOptionsDescription.add(optionsDescription).add(hiddenOptionsDescription); + + po::variables_map options; + po::store( + po::command_line_parser(argc, argv).options(allOptionsDescription) + .positional(posOptionsDescription).run(), + options); + + if (options.count("help")) { + std::cerr << "Usage:" << std::endl + << " runAnalysis INPUT_FILE1 [INPUT_FILE2 [...]] [OPTIONS]" << std::endl; + std::cerr << optionsDescription << std::endl; + return EXIT_SUCCESS; + } + + isOldAnlz = options.count("old-analysis"); + isVerbose = options.count("verbose"); + po::notify(options); + + // If no input file is provided throw an exception. + if (options["input-files"].empty()) { + std::ostringstream message; + message << "No input file is provided. Please pass them as POSITIONAL " + << "arguments."; + throw std::runtime_error(message.str()); + } + + inputs = options["input-files"].as>(); + if( maxEvents == -1) + maxEvents = INT_MAX; + + TString datasetYear = dataset + "_" + year; + boost::algorithm::to_lower(dataset); + unsigned short int I = 0, J = 0; + for (auto const ®ion : MetFilter::regions) { + occMap[I++] = region.first; + for (auto const &var : MetFilter::vars) + effCat[J++] = {{region.first, var}}; + } + + TFile outputRootFile(output.c_str(), "RECREATE"); + TChain chain("ntuplemakerminiaod/tree"); + for (auto const &file : inputs) + chain.Add(file.c_str()); + + if (isVerbose) + std::cout << "Input files are added into the chain." << std::endl; + + TTreeReader reader(&chain); + Tree tree(reader); + NFRegion isNFR(reader, dataset, year, crossCheckPlots); + BERegion isBadChCandBER(reader, "BadChCand"), + isBadPFMuonBER(reader, "BadPFMuon"), + isGlbSTHaloBER(reader, "GlbSTightHalo"), + isEcalBadCalBER(reader, "EcalBadCal_U"), + isHBHENoiseBER(reader, "HBHENoise"), + isOthersBER(reader); + + std::map isBER; + isBER[MetFilter::GoodVertices] = &isOthersBER; + isBER[MetFilter::GlbSTightHalo] = &isGlbSTHaloBER; + isBER[MetFilter::HBHENoise] = &isHBHENoiseBER; + isBER[MetFilter::HBHEIsoNoise] = &isHBHENoiseBER; + isBER[MetFilter::EcalTP] = &isOthersBER; + isBER[MetFilter::EEBadSc] = &isOthersBER; + isBER[MetFilter::EcalBadCal_U] = &isEcalBadCalBER; + isBER[MetFilter::BadPFMuon] = &isBadPFMuonBER; + isBER[MetFilter::BadPFMuon_U] = &isBadPFMuonBER; + isBER[MetFilter::BadPFMuon_DzU] = &isBadPFMuonBER; + isBER[MetFilter::EcalDCBE] = &isOthersBER; + isBER[MetFilter::EcalDCBE_U] = &isOthersBER; + isBER[MetFilter::GlbTightHalo] = &isGlbSTHaloBER; + isBER[MetFilter::BadChCand] = &isBadChCandBER; + isBER[MetFilter::BadChCand_U] = &isBadChCandBER; + + // Uncomment below lines if you need to use run, lumi and event number. + //auto run = tree.run; + //auto lumi = tree.lumi; + //auto event = tree.event; + auto npvx = tree.npvx; + auto pfmet = tree.pfmet; + auto puppimet = tree.puppimet; + auto jetPt = tree.jetPt; + auto jetEta = tree.jetEta; + auto jetPhi = tree.jetPhi; + + std::vector metFilters; + for (auto const &filter : filtersConfig) { + metFilters.emplace_back( + datasetYear, reader, + filter["name"].as(), + filter["flag"].as(), + filter["isRecommended"].as(), + filter["N-1key"].as(), + isOldAnlz); + } + + for (auto &f : metFilters) + f.SetDirectory(outputRootFile); + + // Main loop. + while(reader.Next()) { + event_i++; + if (event_i > maxEvents) + break; + + if (isVerbose and (event_i % step == 0)) + std::cout << event_i << " events are processed" << std::endl; + + // Applying N-1 performance analysis if the option is enabled. + passRecStatus = -1; + if (passRecOption) { + passRecStatus = 255; + for (int i = 0; i < metFiltersNum; i++) + if (metFilters[i].IsRecommeded() and not metFilters[i].IsPassed()) + passRecStatus ^= 1 << i; + } + + if (isOldAnlz) { + for (int i = 0; i < metFiltersNum; i++) { + metFilters[i].Fill(*pfmet, effCat[ar_pfmet], passRecStatus); + metFilters[i].Fill(*puppimet, effCat[ar_pupmet], passRecStatus); + metFilters[i].Fill(*npvx, effCat[ar_npvx], passRecStatus); + if ((*jetPt).size() > 0) + metFilters[i].Fill((*jetPt)[0], effCat[ar_lJpt], passRecStatus); + metFilters[i].Fill(jetEta, jetPhi, occMap[ar], passRecStatus); + } + // As the old analysis option is enabled, don't go to the control regions. + continue; + } + + // Checking whether the event is in Noise Free Region w.r.t. the data-set. + if (isNFR()) { + statistics[0]++; + for (int i = 0; i < metFiltersNum; i++) { + metFilters[i].Fill(*pfmet, effCat[nfr_pfmet], passRecStatus); + metFilters[i].Fill(*puppimet, effCat[nfr_pupmet], passRecStatus); + metFilters[i].Fill(*npvx, effCat[nfr_npvx], passRecStatus); + if ((*jetPt).size() > 0) + metFilters[i].Fill((*jetPt)[0], effCat[nfr_lJpt], passRecStatus); + metFilters[i].Fill(jetEta, jetPhi, occMap[nfr], passRecStatus); + } + } + + // Check whether the event is in BKG Enriched Region w.r.t. the filters. + for (int i = 0; i < metFiltersNum; i++) { + if (not (*isBER[i])()) + continue; + statistics[i+1]++; + metFilters[i].Fill(*pfmet, effCat[ber_pfmet], passRecStatus); + metFilters[i].Fill(*puppimet, effCat[ber_pupmet], passRecStatus); + metFilters[i].Fill(*npvx, effCat[ber_npvx], passRecStatus); + if ((*jetPt).size() > 0) + metFilters[i].Fill((*jetPt)[0], effCat[ber_lJpt], passRecStatus); + metFilters[i].Fill(jetEta, jetPhi, occMap[ber], passRecStatus); + } + } // End of main loop. + + outputRootFile.cd(); + outputRootFile.Write(); + outputRootFile.Close(); + if (isVerbose) + std::cout << event_i << " events are processed." << std::endl; + + if (isOldAnlz or not isVerbose) + return 0; + + std::cout << std::endl << "------------------------------------" << std::endl; + std::cout << "Statistics Summary:" << std::endl; + std::string region = ""; + std::cout.fill(' '); + for (long unsigned int i = 0; i < statistics.size(); i++) { + if (i == 0) + region = "NFR"; + else + region = filtersConfig[i-1]["name"].as() + " BER"; + std::cout << statistics[i] << "\t Events in " << region << std::endl; + } + + return 0; +} + diff --git a/scan/config/BER.yaml b/scan/config/BER.yaml new file mode 100644 index 00000000000..563e3679cda --- /dev/null +++ b/scan/config/BER.yaml @@ -0,0 +1,48 @@ +BadChCand: + min_pfmet: 500.0 + min_pfcandid_pt: 500.0 + abs_pfcand_pdgid: 211 + min_dphi: 3.0 # Minimum dphi between pf-met and pf-candidate + +GlbSTightHalo: + min_pfmet: 200.0 + num_jets_ptgt25: 1 + num_jets_ptgt200: 1 + max_abs_pfmet_phi: 0.2 + min_abs_pfmet_phi: 2.9 + min_jet_pt: 200.0 + max_abs_jet_eta: 2.4 + max_jet_chef: 0.01 + +BadPFMuon: + min_pfmet: 200.0 + num_jets_ptgt25: 1 + num_jets_ptgt200: 1 + min_num_muon: 1 + min_muon_pt: 200.0 + min_dphi: 3.0 # Minimum dphi between pf-met and muon + max_additional_muon_pt: 10.0 + min_delta_r: 0.4 + +EcalBadCal_U: + min_pfmet: 200.0 + num_jets_ptgt25: 1 + num_jets_ptgt200: 1 + min_jet_pt: 200.0 + max_abs_jet_eta: 3.0 + min_abs_jet_eta: 2.5 + min_jet_neef: 0.9 + min_dphi: 3.0 # Minimum dphi between pf-met and jet + +HBHENoise: + min_pfmet: 200.0 + num_jets_ptgt25: 1 + num_jets_ptgt200: 1 + min_jet_pt: 200.0 + max_abs_jet_eta: 3.0 + min_jet_nhef: 0.9 + min_dphi: 3.0 # Minimum dphi between pf-met and jet + +Others: + min_pfmet: 200.0 + diff --git a/scan/config/BadChCand.yaml b/scan/config/BadChCand.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/BadChCand.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/BadPFMuon.yaml b/scan/config/BadPFMuon.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/BadPFMuon.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/EEBadSc.yaml b/scan/config/EEBadSc.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/EEBadSc.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/EcalBadCal.yaml b/scan/config/EcalBadCal.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/EcalBadCal.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/EcalDCBE.yaml b/scan/config/EcalDCBE.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/EcalDCBE.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/EcalTP.yaml b/scan/config/EcalTP.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/EcalTP.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/GlbSTightHalo.yaml b/scan/config/GlbSTightHalo.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/GlbSTightHalo.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/GlbTightHalo.yaml b/scan/config/GlbTightHalo.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/GlbTightHalo.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/GoodVertices.yaml b/scan/config/GoodVertices.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/GoodVertices.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/HBHEIsoNoise.yaml b/scan/config/HBHEIsoNoise.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/HBHEIsoNoise.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/HBHENoise.yaml b/scan/config/HBHENoise.yaml new file mode 100644 index 00000000000..df7b83aa037 --- /dev/null +++ b/scan/config/HBHENoise.yaml @@ -0,0 +1,164 @@ +# Background Enriched Regions +BER: + pfMet: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: + +# Noise Free Regions +NFR: + jetht: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singlemuon: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + egamma: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + singleelectron: + pfMet: + binning: + - [0, 95, 5] + overflow_center: 100 + puppiMet: + binning: + - [0, 300, 20] + - [300, 1000, 100] + overflow_center: 1100 + leadingJetPt: + binning: + - [200, 600, 25] + - [600, 800, 100] + overflow_center: 900 + nPVx: + binning: + - [0, 100, 2] + overflow_center: 105 + + doublemuon: + pfMet: + binning: + - [0, 101, 5] + overflow_center: 102 + puppiMet: + binning: + - [0, 200, 20] + - [0, 200, 20] + - [200, 600, 50] + - [600, 1500, 100] + overflow_center: 1550 + leadingJetPt: + binning: + - [200, 600, 50] + - [600, 1000, 100] + - [1000, 2000, 200] + - [2000, 3500, 500] + overflow_center: 3700 + nPVx: + binning: + - [0, 150, 2] + overflow_center: 152 + +# All Regions i.e. in the Old Analysis Mode. +AR: + pfMet: + binning: + - [0, 200, 20] + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + puppiMet: + binning: + - [0, 1000, 200] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + leadingJetPt: + binning: + - [200, 500, 100] + - [500, 1000, 250] + - [1000, 2000, 500] + - [2000, 3000, 1000] + overflow_center: 3100 + nPVx: + binning: + - [0, 60, 10] + - [60, 101, 40] + overflow_center: 120 + binning: diff --git a/scan/config/met_filters.yaml b/scan/config/met_filters.yaml new file mode 100644 index 00000000000..dff5c3a1283 --- /dev/null +++ b/scan/config/met_filters.yaml @@ -0,0 +1,85 @@ +# Some Explanation about N-1Key defined below: +# For example for second filter that is "GlbSTightHalo" the N-1key is 253 +# which in binary format is 11111101, this means all recommended filters are +# passed except for second filter i.e. itself, which is 0. +# So in order to fill the histograms for such filter, +# if you require the "event filters status" to be (11111101 OR 11111111), +# then indeed, we have simultaneously applied N-1 efficiency for recommeded +# MET filters and requiring non-recommended met filters to pass all +# recommended filters. + +- name: GoodVertices + flag: Flag_goodVertices + isRecommended: true + N-1key: 254 + +- name: GlbSTightHalo + flag: Flag_globalSuperTightHalo2016Filter + isRecommended: true + N-1key: 253 + +- name: HBHENoise + flag: Flag_HBHENoiseFilter + isRecommended: true + N-1key: 251 + +- name: HBHEIsoNoise + flag: Flag_HBHENoiseIsoFilter + isRecommended: true + N-1key: 247 + +- name: EcalTP + flag: Flag_EcalDeadCellTriggerPrimitiveFilter + isRecommended: true + N-1key: 239 + +- name: EEBadSc + flag: Flag_eeBadScFilter + isRecommended: true + N-1key: 223 + +- name: EcalBadCal_U + flag: PassecalBadCalibFilter_Update + isRecommended: true + N-1key: 191 + +- name: BadPFMuon + flag: Flag_BadPFMuonFilter + isRecommended: true + N-1key: 127 + +- name: BadPFMuon_U + flag: PassBadPFMuonFilter_Update + isRecommended: false + N-1key: 127 + +- name: BadPFMuon_Dz_U + flag: PassBadPFMuonFilterDz_Update + isRecommended: false + N-1key: 127 + +- name: EcalDCBE + flag: Flag_EcalDeadCellBoundaryEnergyFilter + isRecommended: false + N-1key: -1 + +- name: EcalDCBE_U + flag: PassEcalDeadCellBoundaryEnergyFilter_Update + isRecommended: false + N-1key: -1 + +- name: GlbTightHalo + flag: Flag_globalTightHalo2016Filter + isRecommended: false + N-1key: 253 + +- name: BadChCand + flag: Flag_BadChargedCandidateFilter + isRecommended: false + N-1key: -1 + +- name: BadChCand_U + flag: PassBadChargedCandidateFilter_Update + isRecommended: false + N-1key: -1 + diff --git a/scan/plot/env.sh b/scan/plot/env.sh new file mode 100644 index 00000000000..fe03b08b0dc --- /dev/null +++ b/scan/plot/env.sh @@ -0,0 +1,3 @@ +. /cvmfs/sft.cern.ch/lcg/views/setupViews.sh LCG_97python3 x86_64-slc6-gcc8-opt +PATH=$PATH:$(pwd)/bin + diff --git a/scan/plot/plot_efficiencies b/scan/plot/plot_efficiencies new file mode 100755 index 00000000000..533569fc905 --- /dev/null +++ b/scan/plot/plot_efficiencies @@ -0,0 +1,351 @@ +#!/usr/bin/env python3 + +print('Importing packages...') +import os +from array import array +import numpy as np +import argparse +import matplotlib.pyplot as plt +from matplotlib import rcParams, gridspec +import yaml + +import ROOT + +ROOT.PyConfig.IgnoreCommandLineOptions = True +plt.rcParams['axes.grid'] = True + + +def MakeBins(binning, overflow_center): + bin_centers = [(binning[0] + binning[1]) / 2] + \ + [(binning[i] + binning[i+1]) / 2 for i in range(1, len(binning) - 1)] + \ + [overflow_center] + + #widths = [bin_centers[0]] if binning[0] == 0 else + \ + widths = \ + [(binning[i+1] - binning[i]) / 2 for i in range(0, len(binning) - 1)] + \ + [bin_centers[-1] - binning[-1]] + + return {'bins': binning, + 'centers': np.array(bin_centers), + 'xerr': np.array(widths)} + + +def FindProperties(key): + info = {} + name = key[0:key.find('Title')].split(':')[1].strip() + + info['object'] = root_file.Get(name) + name = name.split('_') + info['type'] = name[0] + if info['type'] != 'eff': + return False + + for i in range(name.count('copy')): + name.remove('copy') + + info['name'] = '_'.join(name) + info['description'] = '_'.join(name[2:-2]) + + info['filter'], info['region'], info['variable'] = name[1:2] + name[-2:] + + return info + + +def MakeHist(config, teff): + ranges, overflow_center = config['binning'], config['overflow_center'] + binning = [] + for rng in ranges: + binning.append(np.arange(rng[0], rng[1], rng[2])) + + binning.append(rng[1:2]) + binning = np.concatenate(binning) + + bins, bin_centers, xerr = MakeBins(binning, overflow_center).values() + num = ROOT.TH1F('new_num' + info['name'], 'new_num' + info['name'], + len(bins)-1, array('d', bins)) + den = ROOT.TH1F('new_den' + info['name'], 'new_den' + info['name'], + len(bins)-1, array('d', bins)) + + old_num = teff.GetPassedHistogram() + old_den = teff.GetTotalHistogram() + for i in range(1, old_num.GetNbinsX()+1): + num.Fill(i, int(old_num.GetBinContent(i))) + den.Fill(i, int(old_den.GetBinContent(i))) + + num.Sumw2(False) + den.Sumw2(False) + + new_eff = ROOT.TEfficiency(num, den) + size = len(bins) + 1 + eff = np.zeros(size) + error_up, error_low = np.zeros(size), np.zeros(size) + + ## storing the efficiencies in numpy arrays + for i in range(size): + eff[i] = new_eff.GetEfficiency(i) + errUp = new_eff.GetEfficiencyErrorUp(i) + errLow = new_eff.GetEfficiencyErrorLow(i) + error_up[i] = errUp if errUp !=1 else 0 + error_low[i] = errLow if errLow !=1 else 0 + + return {'eff':eff, + 'error':[error_low[1:], error_up[1:]], + 'bins':bins, + 'bin_centers':bin_centers, + 'xerr':xerr} + + +#### Main Code ##### +arg_parser = argparse.ArgumentParser(description=__doc__) +arg_parser.add_argument('data', nargs='+', + help='List of root files obtained from runAnalysis.') +arg_parser.add_argument('--dataset', nargs='+', + help='List of datasets w.r.t. the given root files.') +arg_parser.add_argument('--year', help='Datasets year.') +arg_parser.add_argument('--all', action='count', default=0, + help='Will produce all individual and merged plots.') +arg_parser.add_argument('--old', action='count', default=0, + help='Use it if your analysis is in old strategy mode.') +args = arg_parser.parse_args() + +data_files, datasets, year = args.data, args.dataset, args.year +plot_all = args.all > 0 +isOld = args.old > 0 + +# Plotting variables +dpi = 200 +imageFormat = 'png' + +# Colors of: BadPFMuon_U, BadPFMuon_Dz_U, BadPFMuon, EcalBadCal_U, +#EcalTP, EEBadSc, GlbTightHalo, GoodVertices, HBHEIsoNoise, HBHENoise +rec_colors = ('blue', 'red', 'green', 'black', 'brown', 'cyan', + 'darkorange', 'y', 'magenta', 'gray') + +# Colors of: BadChCand, BadPFMuon_U, EcalDCBE, EcalBadCal_U, GlbTightHalo +non_rec_colors = ('blue', 'red', 'green', 'black', 'darkorange', 'dodgerblue') + +markers = ('o', 'x', '>', '^', 'v', 'o', 'x', '>', '^', 'v') +ms = 5 + +# Loading MET Filters Configuration file +with open('config/met_filters.yaml') as metFiltersCfg_file: + metFiltersConfig = yaml.safe_load(metFiltersCfg_file) +rec_filters, non_rec_filters = [], [] +for filter_ in metFiltersConfig: + filter_name = filter_['name'] + if filter_['isRecommended']: + rec_filters.append(filter_name.strip('_U')) + elif not filter_name.startswith('BadPFMuon'): + non_rec_filters.append(filter_name.strip('_U')) + +rec_filters.sort(key=lambda y: y.lower()) +non_rec_filters = list(set(non_rec_filters)) +non_rec_filters.sort(key=lambda y: y.lower()) +variables = 'pfMet', 'leadingJetPt', 'nPVx', 'puppiMet' + +full_info = {} +for data_file, dataset in zip(data_files, datasets): + start = '######## Loading information of {} {} dataset.'.format(dataset, year) + print(start) + root_file = ROOT.TFile(data_file) + dataset = dataset.lower() + full_info[dataset] = {} + filters = full_info[dataset] + plot_dir = '{}{}_plots'.format(dataset, year) + for key in root_file.GetListOfKeys(): + info = FindProperties(str(key)) + if not info: + continue + + fltr, region, var = info['filter'], info['region'], info['variable'] + desc, obj = info['description'], info['object'] + + with open('config/{}.yaml'.format(fltr)) as yaml_file: + config = yaml.safe_load(yaml_file) + config = config[region][var] if region != 'NFR' else \ + config[region][dataset][var] + + data = MakeHist(config, obj) + + if not fltr in filters.keys(): + filters[fltr] = {} + if not region in filters[fltr].keys(): + filters[fltr][region] = {} + if not var in filters[fltr][region].keys(): + filters[fltr][region][var] = {} + if not desc in filters[fltr][region][var].keys(): + filters[fltr][region][var][desc] = {} + + filters[fltr][region][var][desc]['data'] = data + + if not plot_all: + continue + # Plot efficiencies individually + print('Plotting MET filters efficiencies individually...') + for fltr, regions in filters.items(): + for region, vars_ in regions.items(): + for var, descs in vars_.items(): + descs = list(descs.items()) + descs.sort() + for l, (desc, val) in enumerate(descs): + efficiencies, errors, bins, bin_centers, xerr = val['data'].values() + plot = plt.errorbar(bin_centers, efficiencies[1:], xerr=xerr, + yerr=errors, ms=ms, fmt='', ls='none', + marker=markers[l], color=rec_colors[l], + label='{} {}'.format(fltr, desc)) + + plt.xlim(bins[0], bin_centers[-1] + xerr[-1] / 2 ) + plt.title('{} filter performance in {}, {} {}'.format( + fltr, region, dataset, year)) + plt.ylabel('Efficiency' if region == 'NFR' else \ + 'Noise rejection fraction') + plt.xlabel(var) + if len(descs) > 1: + plt.legend() + os.system('mkdir -p {}/effs/{}'.format(plot_dir, fltr)) + plt.savefig('{}/effs/{}/{}_{}_{}.{}'.format( + plot_dir, fltr, fltr, region, var, imageFormat), dpi=dpi) + plt.close() + + + allRegions = 'BER', 'NFR', 'AR' + # Merge Recommended MET Filters plots + print('Merging recommended MET filters plots...') + for var in variables: + for region in allRegions: + if isOld and region != 'AR': + continue + elif not isOld and region == 'AR': + continue + j = 0 + plt.figure(figsize=(12, 8)) + ax = plt.subplot(111) + box = ax.get_position() + ax.set_position([box.x0, box.y0, box.width * 0.9, box.height]) + + for fltr in rec_filters: + descs = list(filters[fltr][region][var].items()) + descs.sort() + for desc, val in descs: + efficiencies, errors, bins, bin_centers, xerr = val['data'].values() + plt.errorbar(bin_centers, efficiencies[1:], xerr=xerr, yerr=errors, + ms=ms, fmt='', ls='none', marker=markers[j], + color=rec_colors[j], label='{} {}'.format(fltr, desc)) + j += 1 + + plt.xlim(bins[0], bin_centers[-1] + xerr[-1] / 2) + plt.title('recommended filters performance in {}, {} {}'.format( + region, dataset, year)) + plt.ylabel('Efficiency' if region != 'BER' else \ + 'Noise rejection fraction') + plt.xlabel(var) + leg = plt.legend(loc='center left', bbox_to_anchor=(1.02, 0.5), + labelspacing=3) + leg.get_frame().set_edgecolor('white') + os.system('mkdir -p {}/effs/merged'.format(plot_dir)) + plt.savefig('{}/effs/merged/{}_{}.{}'.format( + plot_dir, region, var, imageFormat), dpi=dpi) + plt.close() + + + # Merge Non-Recommended MET Filters plots + print('Merging non-recommended MET filters plots...') + for var in variables: + for region in allRegions: + if isOld and region != 'AR': + continue + elif not isOld and region == 'AR': + continue + j = 0 + plt.figure(figsize=(12,8)) + ax = plt.subplot(111) + box = ax.get_position() + ax.set_position([box.x0, box.y0, box.width * 0.9, box.height]) + for fltr in non_rec_filters: + descs = list(filters[fltr][region][var].items()) + descs.sort() + for desc, val in descs: + #for desc, val in filters[fltr][region][var].items(): + efficiencies, errors, bins, bin_centers, xerr = val['data'].values() + plt.errorbar(bin_centers, efficiencies[1:], xerr=xerr, yerr=errors, + ms=ms, fmt='', ls='none', marker=markers[j], + color=non_rec_colors[j], label='{} {}'.format( + fltr, desc)) + j += 1 + + plt.xlim(bins[0], bin_centers[-1] + xerr[-1] / 2 ) + plt.title('Non recommended filters performance in {}, {} {}'.format( + region, dataset, year)) + plt.ylabel('Efficiency' if region != 'BER' else \ + 'Noise rejection fraction') + plt.xlabel(var) + leg = plt.legend(loc='center left', bbox_to_anchor=(1.02, 0.5), + labelspacing=3) + leg.get_frame().set_edgecolor('white') + os.system('mkdir -p {}/effs/merged/non_rec'.format(plot_dir)) + plt.savefig('{}/effs/merged/non_rec/{}_{}.{}'.format( + plot_dir, region, var, imageFormat), dpi=dpi) + plt.close() + + print('Everything is done with {} {} dataset.'.format(dataset, year)) + + +# Merging actual plots based on the proper datasets and filters +# BadPfMuon filter plots are from Single Muon dataset +# EcalBadCal filter plots are from Egamma dataset +# The rest plots are from JetHT dataset +if len(datasets) != 3 or len(data_files) != 3: + print('Warning: I\'m not going to do actual merged plots:') + print('For actual merged plots, jetht, singlemuon and egamma datasets', + 'are all needed.') + print('If you need the final actual merged plots Please provide all', + 'datasets properly, and try again.') + print('What is final actual merged plots? This is a plot which each filter', + 'efficiency is obtained from the most relevant dtaset') + exit(1) +plot_dir = 'actual_merged_plots' +os.system('mkdir -p {}'.format(plot_dir)) +print('Merging actual recommended MET filters plots...') +for var in variables: + for region in allRegions: + if isOld and region != 'AR': + continue + elif not isOld and region == 'AR': + continue + j = 0 + plt.figure(figsize=(14, 8)) + ax = plt.subplot(111) + box = ax.get_position() + ax.set_position([box.x0, box.y0, box.width * 0.85, box.height]) + + for fltr in rec_filters: + for dataset, filters in full_info.items(): + if (fltr == 'BadPFMuon' and dataset != 'singlemuon') or \ + (fltr == 'EcalBadCal' and dataset != 'egamma'): + continue + if (fltr != 'BadPFMuon' and fltr != 'EcalBadCal' and + dataset != 'jetht'): + continue + descs = list(filters[fltr][region][var].items()) + descs.sort() + for desc, val in descs: + efficiencies, errors, bins, bin_centers, xerr = val['data'].values() + plt.errorbar(bin_centers, efficiencies[1:], xerr=xerr, yerr=errors, + ms=ms, fmt='', ls='none', marker=markers[j], + color=rec_colors[j], label='{} {} ({})'.format( + fltr, desc, dataset)) + j += 1 + + plt.xlim(bins[0], bin_centers[-1] + xerr[-1] / 2) + if region == 'NFR': + plt.ylim(0.80, 1.005) + plt.title('recommended filters performance in {}, {}'.format(region, year)) + plt.ylabel('Efficiency' if region != 'BER' else 'Noise rejection fraction') + plt.xlabel(var) + leg = plt.legend(loc='center left', bbox_to_anchor=(1.02, 0.5), + labelspacing=3) + leg.get_frame().set_edgecolor('white') + plt.savefig('{}/{}_{}.{}'.format( + plot_dir, region, var, imageFormat), dpi=dpi) + plt.close() +print('Done...') diff --git a/scan/plot/plot_occupancy_maps b/scan/plot/plot_occupancy_maps new file mode 100755 index 00000000000..c921a2bd39d --- /dev/null +++ b/scan/plot/plot_occupancy_maps @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 + +print('Importing packages...') +import os +import argparse +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.colors import ListedColormap, LinearSegmentedColormap +from matplotlib import cm, rc, rcParams, gridspec + +import ROOT +ROOT.PyConfig.IgnoreCommandLineOptions = True +rc('text', usetex=True) +plt.rcParams['axes.grid'] = True + + +def findProperties(key): + info = {} + name = key[0:key.find('Title')].split(':')[1].strip() + + info['name'] = name + info['object'] = root_file.Get(name) + name = name.split('_') + info['type'] = name[0] + if info['type'] != 'occMap': + return False + + for i in range(name.count('copy')): + name.remove('copy') + info['is_updated'] = False + if 'U' in name: + info['is_updated'] = True + name.remove('U') + + more = '' + info['filter_status'], info['filter'], info['region'] = name[1:3] + name[-1:] + if len(name) > 4: + more = '(' + '_'.join(name[3:-1]) + ')' + + filter_detail = info['filter'] + ' {}{} '.format( + 'updated' if info['is_updated'] else '', more) + info['title'] = 'Jet ($p_t > 200~GeV$) occupancy map for events\n' + info['title'] += '{} {} in {}, {} {}' + info['title'] = info['title'].format( + info['filter_status'], filter_detail, info['region'], dataset, year) + + return info + + +def MakeHist(info): + obj = info['object'] + obj_type = info['type'] + region = info['region'] + err = False + obj.Rebin2D(eta_rebin, phi_rebin) + xnbins, ynbins = obj.GetNbinsX(), obj.GetNbinsY() + xaxis, yaxis = obj.GetXaxis(), obj.GetYaxis() + xmin, xmax = xaxis.GetXmin(), xaxis.GetXmax() + ymin, ymax = yaxis.GetBinCenter(1), yaxis.GetBinCenter(ynbins) + xaxis = np.array([i for i in np.linspace(xmin, xmax, xnbins)]) + yaxis = np.array([i for i in np.linspace(ymin, ymax, ynbins)]) + data = np.zeros(shape=(xnbins, ynbins)) + for x in range(xnbins): + for y in range(ynbins): + data[x,y] = obj.GetBinContent(x+1,y+1) + + return data, xaxis, yaxis + + +def PlotOccupancyMap(data, info): + z, x, y = np.flip(data[0],1).swapaxes(0,1), data[1], data[2] + P, xedges, yedges = np.histogram2d(z[0], z[1], bins=(x,y), density=True) + fig, ax = plt.subplots() + cax = ax.imshow(z, extent=(xedges[0], xedges[-1], yedges[0], yedges[-1]), + vmin=0, vmax=np.amax(z), interpolation='none', cmap=my_cmp) + cbar = fig.colorbar(cax, aspect=10) + + ax.set_aspect('auto') + ax.set_title(info['title']) + ax.set_xlabel(r'$\eta$') + ax.set_ylabel(r'$\phi$') + ax.xaxis.set_ticks(np.linspace(-5, 5, 11)) + plt.savefig('{}/occMap/{}.{}'.format( + plot_dir, info['name'], imageFormat), dpi=dpi) + plt.close() + + + +# Main Code +arg_parser = argparse.ArgumentParser(description=__doc__) +arg_parser.add_argument('data', nargs='+', + help='List of root files obtained from runAnalysis.') +arg_parser.add_argument('--dataset', nargs='+', + help='List of datasets w.r.t. the given root files.') +arg_parser.add_argument('--year', help='Datasets year.') +args = arg_parser.parse_args() +data_files, datasets, year = args.data, args.dataset, args.year + +# Create a new color map +# More color maps are available here if needed: +# https://matplotlib.org/3.2.1/tutorials/colors/colormaps.html +cmap = cm.get_cmap('jet') +newcolors = cmap(np.linspace(0, 1, 256)) +white, black = np.array([1, 1, 1, 1]), np.array([0, 0, 0, 1]) +newcolors[0, :] = white +my_cmp = ListedColormap(newcolors) + +# Set rebin value of the x and y-axis which are eta and phi respectively. +eta_rebin, phi_rebin = 9, 5 +# Set the quality (dpi) of plots +dpi = 200 +imageFormat = 'png' +ms = 3 + +for data_file, dataset in zip(data_files, datasets): + dataset = dataset.lower() + plot_dir = '{}{}_plots'.format(dataset, year) + os.system('mkdir -p {}/occMap'.format(plot_dir)) + root_file = ROOT.TFile(data_file) + keys_list = root_file.GetListOfKeys() + print('Plotting occupancy maps for {} {} dataset...'.format(dataset, year)) + for key in root_file.GetListOfKeys(): + info = findProperties(str(key)) + if not info: + continue + data = MakeHist(info) + PlotOccupancyMap(data, info) +print('Done.')