import os
from analysis_tools.utils import import_root
ROOT = import_root()
import correctionlib
correctionlib.register_pyroot_binding()
json_path = "/cvmfs/cms.cern.ch/rsync/cms-nanoAOD/jsonpog-integration/POG/EGM/{}/electron.json.gz"
class eleSFRDFProducer():
def __init__(self, *args, **kwargs):
self.year = kwargs.pop("year")
self.isUL = kwargs.pop("isUL")
self.isMC = kwargs.pop("isMC")
self.wps = kwargs.pop("wps", ["wp80iso"])
if self.isMC:
if not self.isUL:
raise ValueError("Only implemented for UL datasets")
if self.year == 2018:
self.tag = "2018"
filename = json_path.format("%s_UL" % self.tag)
else:
raise ValueError("2016 and 2017 not yet implemented")
if "/libCorrectionsWrapper.so" not in ROOT.gSystem.GetLibraries():
ROOT.gInterpreter.Load("libCorrectionsWrapper.so")
ROOT.gInterpreter.Declare(os.path.expandvars(
'#include "$CMSSW_BASE/src/Corrections/Wrapper/interface/custom_sf.h"'))
ROOT.gInterpreter.ProcessLine(
'auto corr = MyCorrections("%s", "UL-Electron-ID-SF");' % filename)
ROOT.gInterpreter.Declare("""
using Vfloat = const ROOT::RVec<float>&;
using Vint = const ROOT::RVec<int>&;
ROOT::RVec<double> get_ele_sf(
std::string syst, std::string wp, Vfloat eta, Vfloat pt) {
ROOT::RVec<double> sf;
for (size_t i = 0; i < pt.size(); i++) {
if (pt[i] < 10.) sf.push_back(1.);
else sf.push_back(corr.eval({"%s", syst, wp, eta[i], pt[i]}));
}
return sf;
}
""" % self.tag)
def run(self, df):
if not self.isMC:
return df, []
branches = []
for syst_name, syst in [("", "sf"), ("_up", "sfup"), ("_down", "sfdown")]:
for wp in self.wps:
df = df.Define("elesf_%s%s" % (wp, syst_name),
'get_ele_sf("%s", "%s", Electron_eta, Electron_pt)' % (syst, wp))
branches.append("elesf_%s%s" % (wp, syst_name))
return df, branches
[docs]def eleSFRDF(**kwargs):
"""
Module to obtain electron SFs with their uncertainties.
:param wps: name of the wps to consider among ``Loose``, ``Medium``,
``RecoAbove20``, ``RecoBelow20``, ``Tight``, ``Veto``, ``wp80iso`` (default),
``wp80noiso``, ``wp90iso,`` ``wp90noiso``.
:type wps: list of str
YAML sintaxis:
.. code-block:: yaml
codename:
name: eleSFRDF
path: Corrections.EGM.eleCorrections
parameters:
isMC: self.dataset.process.isMC
year: self.config.year
isUL: self.dataset.has_tag('ul')
wps: [wp80iso, ...]
"""
return lambda: eleSFRDFProducer(**kwargs)