Ejemplo n.º 1
0
 def __init__(self, label=""):
     JetReCleaner_TreeReaders.__init__(self, label)
     self._helper = CollectionSkimmer("JetGood" + self.label,
                                      "Jet",
                                      floats=self.vars,
                                      maxSize=20)
     self.branches = []  # output is done in C++
Ejemplo n.º 2
0
    def beginJob(self,histFile=None,histDirName=None):
        self.vars = ["eta","phi","mass"]
        self.vars_leptons = ["pdgId",'jetIdx','pt']
        self.vars_taus = ["pt"]
        self.vars_taus_int = ['jetIdx']
        self.vars_taus_uchar = ['idMVAoldDMdR032017v2','idDeepTau2017v2p1VSjet']
        self.vars_jets = [("pt","pt_nom") if self.isMC else 'pt',"btagDeepB","qgl",'btagDeepFlavB'] + [ 'pt_%s%s'%(x,y) for x in self.variations for y in ["Up","Down"]] #"btagCSVV2",,"btagDeepC"]#"btagCSV","btagDeepCSV",,"btagDeepCSVCvsL","btagDeepCSVCvsB","ptd","axis1"] # FIXME recover
        self.vars_jets_int = (["hadronFlavour"] if self.isMC else [])
        self.vars_jets_nooutput = []
        self.systsJEC = {0:""}
        if self.isMC:
            for sys in range(len(self.variations)):
                self.systsJEC[sys+1]    = '_' + self.variations[sys] + 'Up'
                self.systsJEC[-(sys+1)] = '_' + self.variations[sys] + 'Down'


        self.outmasses=['mZ1','minMllAFAS','minMllAFOS','minMllAFSS','minMllSFOS','mZ2','m4l']
        self._outjetvars = [x%self.jc for x in ['ht%s%%dj','mht%s%%d','nB%sLoose%%d','nB%sMedium%%d','n%s%%d']]
        self.outjetvars=[]
        for jetPt in self.jetPts: self.outjetvars.extend([(x%jetPt+y,'I' if ('nB%s'%self.jc in x or 'n%s'%self.jc in x) else 'F') for x in self._outjetvars for y in self.systsJEC.values()])
        self.outjetvars.extend([('nFwdJet'+self.systsJEC[y],'I') for y in self.systsJEC ])
        self.outjetvars.extend([(x+self.systsJEC[y],'F') for y in self.systsJEC for x in ['FwdJet1_pt','FwdJet1_eta'] ])
        
        self.branches = [var+self.label for var in self.outmasses]
        self.branches.extend([(var+self.label,_type) for var,_type in self.outjetvars])
        self.branches += [("LepGood_conePt","F",100,"nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO"+self.label, "LepGood", floats=[], maxSize=10, saveTagForAll=True, saveSelectedIndices=True,padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight"+self.label, "LepGood", floats=[], maxSize=10, saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel"+self.label, self.tauc, floats=self.vars+self.vars_taus, ints=self.vars_taus_int, uchars=self.vars_taus_uchar, maxSize=10)
        self._helper_jets = CollectionSkimmer("%sSel"%self.jc+self.label, self.jc, floats=self.vars+self.vars_jets, ints=self.vars_jets_int, maxSize=20, saveSelectedIndices=True,padSelectedIndicesWith=0)
        self._helpers = [self._helper_lepsF,self._helper_lepsT,self._helper_taus,self._helper_jets]
Ejemplo n.º 3
0
 def init(self, tree):
     for v in self.floats + self.ints:
         if not tree.GetBranch("Jet_" + v): print "Missing branch Jet_" + v
     self.floats = [v for v in self.floats if tree.GetBranch("Jet_" + v)]
     self.ints = [v for v in self.ints if tree.GetBranch("Jet_" + v)]
     self._helper = CollectionSkimmer("JetGood" + self.label,
                                      "Jet",
                                      floats=self.floats,
                                      ints=self.ints,
                                      saveSelectedIndices=True,
                                      maxSize=20)
     self._worker = ROOT.JetReCleanerExampleHelper(self._helper.cppImpl())
     self._helper.initInputTree(tree)
     self.initReaders(tree)
     self._helper.initOutputTree(self._out)
Ejemplo n.º 4
0
 def init(self, tree):
     for v in self.floats + self.ints:
         if not tree.GetBranch("LepOther_" + v):
             print "Missing branch LepOther_" + v
     self.floats = [
         v for v in self.floats if tree.GetBranch("LepOther_" + v)
     ]
     self.ints = [v for v in self.ints if tree.GetBranch("LepOther_" + v)]
     self._helper = CollectionSkimmer("LepOtherGood" + self.label,
                                      "LepOther",
                                      floats=self.floats,
                                      ints=self.ints,
                                      saveSelectedIndices=True,
                                      maxSize=20)
     self._helper.initInputTree(tree)
     self.initReaders(tree)
     self._helper.initOutputTree(self._out)
Ejemplo n.º 5
0
class JetReCleaner_CollectionSkimmer(JetReCleaner_TreeReaders):
    """Python version, using TreeReaderArray for input and CollectionSkimmer for output (runs at ~17 kHz)"""
    def __init__(self, label=""):
        JetReCleaner_TreeReaders.__init__(self, label)
        self._helper = CollectionSkimmer("JetGood" + self.label,
                                         "Jet",
                                         floats=self.vars,
                                         maxSize=20)
        self.branches = []  # output is done in C++

    def init(self, tree):
        self._helper.initInputTree(tree)
        self.initReaders(tree)

    def initReaders(self, tree):
        for B in "nLepGood", "nJet":
            setattr(self, B, tree.valueReader(B))
        for B in "eta", "phi":
            setattr(self, "LepGood_" + B, tree.arrayReader("LepGood_" + B))
        for B in "eta", "phi":
            setattr(self, "Jet_" + B, tree.arrayReader("Jet_" + B))

    def setOutputTree(self, pytree):
        self._helper.initOutputTree(pytree)

    def __call__(self, event):
        ## Init
        if self._helper.initEvent(event):
            self.initReaders(event._tree)
        ## Algo
        cleanJets = self.makeCleanJets(event)
        ## Output
        self._helper.push_back_all(cleanJets)
        return {}
    def __init__(self,label,inlabel,cleanTausWithLooseLeptons,cleanJetsWithFOTaus,doVetoZ,doVetoLMf,doVetoLMt,jetPts,btagL_thr,btagM_thr,jetCollection='Jet',isMC=True):

        self.label = "" if (label in ["",None]) else ("_"+label)
        self.inlabel = inlabel

        self.vars = ["pt","eta","phi","mass"]
        self.vars_leptons = ["pdgId"]
        self.vars_taus = ["mvaId2017"]
        self.vars_taus_int = ["idMVAdR03"]
        self.vars_jets = ["btagCSV","btagDeepCSV","qgl","btagDeepCSVCvsL","btagDeepCSVCvsB","ptd","axis1","corr","corr_JECUp","corr_JECDown"]
        self.vars_jets_int = ["mult"]+(["hadronFlavour"] if isMC else [])
        self.vars_jets_nooutput = []
        self.jc = jetCollection

        self.cleanTausWithLooseLeptons = cleanTausWithLooseLeptons
        self.cleanJetsWithFOTaus = cleanJetsWithFOTaus
        self.jetPts = jetPts

        self.systsJEC = {0:"", 1:"_jecUp", -1:"_jecDown"}

        self.outmasses=['mZ1','minMllAFAS','minMllAFOS','minMllAFSS','minMllSFOS','mZ2','m4l']
        self._outjetvars = [x%self.jc for x in ['ht%s%%dj','mht%s%%d','nB%sLoose%%d','nB%sMedium%%d','n%s%%d']]
        self.outjetvars=[]
        for jetPt in self.jetPts: self.outjetvars.extend([(x%jetPt+y,'I' if ('nB%s'%self.jc in x or 'n%s'%self.jc in x) else 'F') for x in self._outjetvars for y in self.systsJEC.values()])
        self.branches = [var+self.label for var in self.outmasses]
        self.branches.extend([(var+self.label,_type) for var,_type in self.outjetvars])
        self.branches += [("LepGood_conePt","F",20,"nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO"+self.label, "LepGood", floats=[], maxSize=20, saveSelectedIndices=True,padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight"+self.label, "LepGood", floats=[], maxSize=20, saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel"+self.label, "TauGood", floats=self.vars+self.vars_taus, ints=self.vars_taus_int, maxSize=20)
        self._helper_jets = CollectionSkimmer("%sSel"%self.jc+self.label, self.jc, floats=self.vars+self.vars_jets, ints=self.vars_jets_int, maxSize=20)
        self._helpers = [self._helper_lepsF,self._helper_lepsT,self._helper_taus,self._helper_jets]

        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries():
            print "Load C++ recleaner worker module"
            ROOT.gROOT.ProcessLine(".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O" % os.environ['CMSSW_BASE'])
        self._worker = ROOT.fastCombinedObjectRecleanerHelper(self._helper_taus.cppImpl(),self._helper_jets.cppImpl(),self.cleanJetsWithFOTaus,btagL_thr,btagM_thr)
        for x in self.jetPts: self._worker.addJetPt(x)

        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries():
            print "Load C++ recleaner mass and veto calculator module"
            ROOT.gROOT.ProcessLine(".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O" % os.environ['CMSSW_BASE'])
        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(self._helper_lepsF.cppImpl(),self._helper_lepsT.cppImpl(),doVetoZ,doVetoLMf,doVetoLMt)
Ejemplo n.º 7
0
    def init(self,tree):
        for v in self.floats+self.ints:
            if not tree.GetBranch("GenPart_"+v): print "Missing branch GenPart_"+v
        self.floats = [v for v in self.floats if tree.GetBranch("GenPart_"+v)]
        self.ints   = [v for v in self.ints   if tree.GetBranch("GenPart_"+v)]

        self.collections = ['Higgs','Top','ATop','bFromTop','WFromTop','bFromATop','WFromATop',
                            'dFromWFromTop','dFromWFromATop','dDirectFromHiggs','dAllFromHiggs',
                            'dFromOnShellVFromHiggs','dFromOffShellVFromHiggs','allFinalParton']

        for x in self.collections:
            cs = CollectionSkimmer(x+self.label, "GenPart", floats=self.floats, ints=self.ints, saveSelectedIndices=True, saveTagForAll=True, maxSize=50)
            setattr(self,'_h_%s'%x,cs)
            self._helpers.append(cs)
        for x in self._helpers:
            x.initInputTree(tree)
            x.initOutputTree(self._out)
        self.initReaders(tree)
Ejemplo n.º 8
0
class JetReCleaner:
    def __init__(self, label=""):
        self.label = "" if (label in ["", None]) else ("_" + label)
        self.floats = ("pt", "eta", "phi", "btagCSV")
        self.ints = ("hadronFlavour", )
        if "/jetReCleanerExampleHelper_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/jetReCleanerExampleHelper.cxx+"
                % os.environ['CMSSW_BASE'])

    def init(self, tree):
        for v in self.floats + self.ints:
            if not tree.GetBranch("Jet_" + v): print "Missing branch Jet_" + v
        self.floats = [v for v in self.floats if tree.GetBranch("Jet_" + v)]
        self.ints = [v for v in self.ints if tree.GetBranch("Jet_" + v)]
        self._helper = CollectionSkimmer("JetGood" + self.label,
                                         "Jet",
                                         floats=self.floats,
                                         ints=self.ints,
                                         saveSelectedIndices=True,
                                         maxSize=20)
        self._worker = ROOT.JetReCleanerExampleHelper(self._helper.cppImpl())
        self._helper.initInputTree(tree)
        self.initReaders(tree)
        self._helper.initOutputTree(self._out)

    def listBranches(self):
        return []

    def initReaders(self, tree):
        for B in "nLepGood", "nJet":
            setattr(self, B, tree.valueReader(B))
        for B in "eta", "phi":
            setattr(self, "LepGood_" + B, tree.arrayReader("LepGood_" + B))
        for B in "eta", "phi":
            setattr(self, "Jet_" + B, tree.arrayReader("Jet_" + B))
        self._worker.setLeptons(self.nLepGood, self.LepGood_eta,
                                self.LepGood_phi)
        self._worker.setJets(self.nJet, self.Jet_eta, self.Jet_phi)

    def setOutputTree(self, pytree):
        self._out = pytree

    def __call__(self, event):
        ## Init
        if self._helper.initEvent(event):
            self.initReaders(event._tree)
        ## Algo
        self._worker.run()
        return {}
class fastCombinedObjectRecleaner:
    def __init__(self,
                 label,
                 inlabel,
                 cleanTausWithLooseLeptons,
                 cleanJetsWithFOTaus,
                 doVetoZ,
                 doVetoLMf,
                 doVetoLMt,
                 jetPts,
                 btagL_thr,
                 btagM_thr,
                 jetCollection='Jet',
                 isMC=True):

        self.label = "" if (label in ["", None]) else ("_" + label)
        self.inlabel = inlabel

        self.vars = ["pt", "eta", "phi", "mass"]
        self.vars_leptons = ["pdgId"]
        self.vars_taus = ["idMVAdR03"]
        self.vars_jets = [
            "btagCSV", "btagDeepCSV", "qgl", "ctagCsvL", "ptd", "axis1",
            "corr", "corr_JECUp", "corr_JECDown"
        ]
        self.vars_jets_int = ["mult"] + (["hadronFlavour"] if isMC else [])
        self.vars_jets_nooutput = []
        self.jc = jetCollection

        self.cleanTausWithLooseLeptons = cleanTausWithLooseLeptons
        self.cleanJetsWithFOTaus = cleanJetsWithFOTaus
        self.jetPts = jetPts

        self.systsJEC = {0: "", 1: "_jecUp", -1: "_jecDown"}

        self.outmasses = [
            'mZ1', 'minMllAFAS', 'minMllAFOS', 'minMllAFSS', 'minMllSFOS'
        ]
        self._outjetvars = [
            x % self.jc for x in [
                'ht%s%%dj', 'mht%s%%d', 'nB%sLoose%%d', 'nB%sMedium%%d',
                'n%s%%d'
            ]
        ]
        self.outjetvars = []
        for jetPt in self.jetPts:
            self.outjetvars.extend([
                (x % jetPt + y, 'I' if
                 ('nB%s' % self.jc in x or 'n%s' % self.jc in x) else 'F')
                for x in self._outjetvars for y in self.systsJEC.values()
            ])
        self.branches = [var + self.label for var in self.outmasses]
        self.branches.extend([(var + self.label, _type)
                              for var, _type in self.outjetvars])
        self.branches += [("LepGood_conePt", "F", 20, "nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=20,
                                               saveSelectedIndices=True,
                                               padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=20,
                                               saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel" + self.label,
                                              "TauGood",
                                              floats=self.vars,
                                              ints=self.vars_taus,
                                              maxSize=20)
        self._helper_jets = CollectionSkimmer("%sSel" % self.jc + self.label,
                                              self.jc,
                                              floats=self.vars +
                                              self.vars_jets,
                                              ints=self.vars_jets_int,
                                              maxSize=20)
        self._helpers = [
            self._helper_lepsF, self._helper_lepsT, self._helper_taus,
            self._helper_jets
        ]

        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner worker module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._worker = ROOT.fastCombinedObjectRecleanerHelper(
            self._helper_taus.cppImpl(), self._helper_jets.cppImpl(),
            self.cleanJetsWithFOTaus, btagL_thr, btagM_thr)
        for x in self.jetPts:
            self._worker.addJetPt(x)

        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner mass and veto calculator module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(
            self._helper_lepsF.cppImpl(), self._helper_lepsT.cppImpl(),
            doVetoZ, doVetoLMf, doVetoLMt)

    def init(self, tree):
        self._ttreereaderversion = tree._ttreereaderversion
        for x in self._helpers:
            x.initInputTree(tree)
        self.initReaders(tree)
        self.initWorkers()

    def setOutputTree(self, pytree):
        for x in self._helpers:
            x.initOutputTree(pytree)

    def initReaders(self, tree):
        for coll in ["LepGood", "TauGood", self.jc]:
            setattr(self, 'n' + coll, tree.valueReader('n' + coll))
            _vars = self.vars[:]
            if coll == 'LepGood': _vars.extend(self.vars_leptons)
            if coll == 'TauGood': _vars.extend(self.vars_taus)
            if coll == self.jc:
                _vars.extend(self.vars_jets + self.vars_jets_int +
                             self.vars_jets_nooutput)
            for B in _vars:
                setattr(self, "%s_%s" % (coll, B),
                        tree.arrayReader("%s_%s" % (coll, B)))

    def initWorkers(self):
        self._worker.setLeptons(self.nLepGood, self.LepGood_pt,
                                self.LepGood_eta, self.LepGood_phi)
        self._worker.setTaus(self.nTauGood, self.TauGood_pt, self.TauGood_eta,
                             self.TauGood_phi)
        self._worker.setJets(getattr(self, 'n%s' % self.jc),
                             getattr(self, '%s_pt' % self.jc),
                             getattr(self, '%s_eta' % self.jc),
                             getattr(self, '%s_phi' % self.jc),
                             getattr(self, '%s_btagDeepCSV' % self.jc),
                             getattr(self, '%s_corr' % self.jc),
                             getattr(self, '%s_corr_JECUp' % self.jc),
                             getattr(self, '%s_corr_JECDown' % self.jc))
        self._workerMV.setLeptons(self.nLepGood, self.LepGood_pt,
                                  self.LepGood_eta, self.LepGood_phi,
                                  self.LepGood_mass, self.LepGood_pdgId)

    def listBranches(self):
        return self.branches

    def __call__(self, event):
        ## Init
        if any([x.initEvent(event) for x in self._helpers]):
            self.initReaders(event._tree)
            self.initWorkers()

        tags = getattr(event, '_CombinedTagsForCleaning%s' % self.inlabel)
        ret = {}
        ret['LepGood_conePt'] = [
            tags.leps_conept[i] for i in xrange(self.nLepGood.Get()[0])
        ]

        self._worker.clear()
        self._worker.loadTags(tags, self.cleanTausWithLooseLeptons)
        self._worker.run()

        for delta, varname in self.systsJEC.iteritems():
            for x in self._worker.GetJetSums(delta):
                for var in self._outjetvars:
                    ret[var % x.thr + varname + self.label] = getattr(
                        x,
                        var.replace('%d', '').replace(self.jc, 'Jet'))

        self._workerMV.clear()
        self._workerMV.loadTags(tags)
        self._workerMV.run()

        masses = self._workerMV.GetPairMasses()
        for var in self.outmasses:
            ret[var + self.label] = getattr(masses, var)
        return ret
Ejemplo n.º 10
0
class LepOtherCleaner:
    def __init__(self, label=""):
        self.label = "" if (label in ["", None]) else ("_" + label)
        self.floats = ("pt", "eta", "phi", "miniRelIso", "sip3d")
        self.ints = (
            "mcMatchAny",
            "mcMatchId",
            "mediumMuonId",
        )

    def init(self, tree):
        for v in self.floats + self.ints:
            if not tree.GetBranch("LepOther_" + v):
                print "Missing branch LepOther_" + v
        self.floats = [
            v for v in self.floats if tree.GetBranch("LepOther_" + v)
        ]
        self.ints = [v for v in self.ints if tree.GetBranch("LepOther_" + v)]
        self._helper = CollectionSkimmer("LepOtherGood" + self.label,
                                         "LepOther",
                                         floats=self.floats,
                                         ints=self.ints,
                                         saveSelectedIndices=True,
                                         maxSize=20)
        self._helper.initInputTree(tree)
        self.initReaders(tree)
        self._helper.initOutputTree(self._out)

    def listBranches(self):
        return []

    def initReaders(self, tree):
        for B in "nLepGood", "nLepOther", "nJet":
            setattr(self, B, tree.valueReader(B))
        for B in "eta", "phi":
            setattr(self, "LepGood_" + B, tree.arrayReader("LepGood_" + B))
        for B in "pt", "eta", "phi", "btagCSV":
            setattr(self, "Jet_" + B, tree.arrayReader("Jet_" + B))
        for B in "eta", "phi", "pdgId", "dz":
            setattr(self, "LepOther_" + B, tree.arrayReader("LepOther_" + B))

    def setOutputTree(self, pytree):
        self._out = pytree

    def __call__(self, event):
        ## Init
        if self._helper.initEvent(event):
            self.initReaders(event._tree)
        ## Algo
        vetos = [(self.LepGood_eta[i], self.LepGood_phi[i])
                 for i in xrange(self.nLepGood.Get()[0])]
        for i in xrange(self.nJet.Get()[0]):
            jeta, jphi = (self.Jet_eta[i], self.Jet_phi[i])
            if min(deltaR(jeta, jphi, leta, lphi)
                   for (leta, lphi) in vetos) > 0.4:
                vetos.append((jeta, jphi))
                break  ## clean respect to the leading jet only
        #vetos += [ (self.Jet_eta[i],self.Jet_phi[i]) for i in ijets if self.Jet_pt[i] > 40 or self.Jet_btagCSV[i] > 0.46 ]
        for i in xrange(self.nLepOther.Get()[0]):
            if abs(self.LepOther_pdgId[i]) != 13: continue
            if abs(self.LepOther_dz[i]) >= 0.2: continue
            eta, phi = self.LepOther_eta[i], self.LepOther_phi[i]
            bad = False
            for (le, lp) in vetos:
                if abs(le - eta) < 0.4 and deltaR(le, lp, eta, phi) < 0.4:
                    bad = True
                    break
            if not bad: self._helper.push_back(i)
        return {}
Ejemplo n.º 11
0
    def __init__(self, label, inlabel, cleanTausWithLooseLeptons,
                 cleanJetsWithFOTaus, doVetoZ, doVetoLMf, doVetoLMt, jetPts,
                 btagL_thr, btagM_thr):

        self.label = "" if (label in ["", None]) else ("_" + label)
        self.inlabel = inlabel

        self.vars = ["pt", "eta", "phi", "mass"]
        self.vars_leptons = ["pdgId"]
        self.vars_jets = ["btagCSV"]

        self.cleanTausWithLooseLeptons = cleanTausWithLooseLeptons
        self.cleanJetsWithFOTaus = cleanJetsWithFOTaus
        self.jetPts = jetPts

        self.outmasses = [
            'mZ1', 'minMllAFAS', 'minMllAFOS', 'minMllAFSS', 'minMllSFOS'
        ]
        self._outjetvars = [
            'htJet%dj', 'mhtJet%d', 'nBJetLoose%d', 'nBJetMedium%d'
        ]
        self.outjetvars = []
        for jetPt in self.jetPts:
            self.outjetvars.extend([(x % jetPt, 'I' if 'nBJet' in x else 'F')
                                    for x in self._outjetvars])
        self.branches = [var + self.label for var in self.outmasses]
        self.branches.extend([(var + self.label, _type)
                              for var, _type in self.outjetvars])
        self.branches += [("LepGood_conePt", "F", 20, "nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=20,
                                               saveSelectedIndices=True,
                                               padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=20,
                                               saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel" + self.label,
                                              "TauGood",
                                              floats=self.vars,
                                              maxSize=20)
        self._helper_jets = CollectionSkimmer("JetSel" + self.label,
                                              "Jet",
                                              floats=self.vars +
                                              self.vars_jets,
                                              maxSize=20)
        self._helpers = [
            self._helper_lepsF, self._helper_lepsT, self._helper_taus,
            self._helper_jets
        ]

        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner worker module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._worker = ROOT.fastCombinedObjectRecleanerHelper(
            self._helper_taus.cppImpl(), self._helper_jets.cppImpl(),
            self.cleanJetsWithFOTaus, btagL_thr, btagM_thr)
        for x in self.jetPts:
            self._worker.addJetPt(x)

        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner mass and veto calculator module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(
            self._helper_lepsF.cppImpl(), self._helper_lepsT.cppImpl(),
            doVetoZ, doVetoLMf, doVetoLMt)
Ejemplo n.º 12
0
class fastCombinedObjectRecleaner:
    def __init__(self, label, inlabel, cleanTausWithLooseLeptons,
                 cleanJetsWithFOTaus, doVetoZ, doVetoLMf, doVetoLMt, jetPts,
                 btagL_thr, btagM_thr):

        self.label = "" if (label in ["", None]) else ("_" + label)
        self.inlabel = inlabel

        self.vars = ["pt", "eta", "phi", "mass"]
        self.vars_leptons = ["pdgId"]
        self.vars_jets = ["btagCSV"]

        self.cleanTausWithLooseLeptons = cleanTausWithLooseLeptons
        self.cleanJetsWithFOTaus = cleanJetsWithFOTaus
        self.jetPts = jetPts

        self.outmasses = [
            'mZ1', 'minMllAFAS', 'minMllAFOS', 'minMllAFSS', 'minMllSFOS'
        ]
        self._outjetvars = [
            'htJet%dj', 'mhtJet%d', 'nBJetLoose%d', 'nBJetMedium%d'
        ]
        self.outjetvars = []
        for jetPt in self.jetPts:
            self.outjetvars.extend([(x % jetPt, 'I' if 'nBJet' in x else 'F')
                                    for x in self._outjetvars])
        self.branches = [var + self.label for var in self.outmasses]
        self.branches.extend([(var + self.label, _type)
                              for var, _type in self.outjetvars])
        self.branches += [("LepGood_conePt", "F", 20, "nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=20,
                                               saveSelectedIndices=True,
                                               padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=20,
                                               saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel" + self.label,
                                              "TauGood",
                                              floats=self.vars,
                                              maxSize=20)
        self._helper_jets = CollectionSkimmer("JetSel" + self.label,
                                              "Jet",
                                              floats=self.vars +
                                              self.vars_jets,
                                              maxSize=20)
        self._helpers = [
            self._helper_lepsF, self._helper_lepsT, self._helper_taus,
            self._helper_jets
        ]

        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner worker module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._worker = ROOT.fastCombinedObjectRecleanerHelper(
            self._helper_taus.cppImpl(), self._helper_jets.cppImpl(),
            self.cleanJetsWithFOTaus, btagL_thr, btagM_thr)
        for x in self.jetPts:
            self._worker.addJetPt(x)

        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner mass and veto calculator module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(
            self._helper_lepsF.cppImpl(), self._helper_lepsT.cppImpl(),
            doVetoZ, doVetoLMf, doVetoLMt)

    def init(self, tree):
        self._ttreereaderversion = tree._ttreereaderversion
        for x in self._helpers:
            x.initInputTree(tree)
        self.initReaders(tree)
        self.initWorkers()

    def setOutputTree(self, pytree):
        for x in self._helpers:
            x.initOutputTree(pytree)

    def initReaders(self, tree):
        for coll in ["LepGood", "TauGood", "Jet"]:
            setattr(self, 'n' + coll, tree.valueReader('n' + coll))
            _vars = self.vars[:]
            if coll == 'LepGood': _vars.extend(self.vars_leptons)
            if coll == 'Jet': _vars.extend(self.vars_jets)
            for B in _vars:
                setattr(self, "%s_%s" % (coll, B),
                        tree.arrayReader("%s_%s" % (coll, B)))

    def initWorkers(self):
        self._worker.setLeptons(self.nLepGood, self.LepGood_pt,
                                self.LepGood_eta, self.LepGood_phi)
        self._worker.setTaus(self.nTauGood, self.TauGood_pt, self.TauGood_eta,
                             self.TauGood_phi)
        self._worker.setJets(self.nJet, self.Jet_pt, self.Jet_eta,
                             self.Jet_phi, self.Jet_btagCSV)
        self._workerMV.setLeptons(self.nLepGood, self.LepGood_pt,
                                  self.LepGood_eta, self.LepGood_phi,
                                  self.LepGood_mass, self.LepGood_pdgId)

    def listBranches(self):
        return self.branches

    def __call__(self, event):
        ## Init
        if any([x.initEvent(event) for x in self._helpers]):
            self.initReaders(event._tree)
            self.initWorkers()

        tags = getattr(event, '_CombinedTagsForCleaning%s' % self.inlabel)
        ret = {}
        ret['LepGood_conePt'] = [
            tags.leps_conept[i] for i in xrange(self.nLepGood.Get()[0])
        ]

        self._worker.clear()
        self._worker.loadTags(tags, self.cleanTausWithLooseLeptons)
        self._worker.run()

        for x in self._worker.GetJetSums():
            for var in self._outjetvars:
                ret[var % x.thr + self.label] = getattr(
                    x, var.replace('%d', ''))

        self._workerMV.clear()
        self._workerMV.loadTags(tags)
        self._workerMV.run()

        masses = self._workerMV.GetPairMasses()
        for var in self.outmasses:
            ret[var + self.label] = getattr(masses, var)
        return ret
Ejemplo n.º 13
0
class fastCombinedObjectRecleaner(Module):
    def __init__(self,label,inlabel,cleanTausWithLooseLeptons,cleanJetsWithFOTaus,doVetoZ,doVetoLMf,doVetoLMt,jetPts,jetPtsFwd,btagL_thr,btagM_thr,jetCollection='Jet',jetBTag='btagDeepFlavB',tauCollection='Tau',isMC=None, 
                 variations=["jesTotalCorr","jesTotalUnCorr","jer"]):

        self.label = "" if (label in ["",None]) else ("_"+label)
        self.inlabel = inlabel
        self.tauc = tauCollection
        self.jc = jetCollection

        self.cleanTausWithLooseLeptons = cleanTausWithLooseLeptons
        self.cleanJetsWithFOTaus = cleanJetsWithFOTaus
        self.jetPts = jetPts
        self.jetPtsFwd = jetPtsFwd
        self.jetBTag = jetBTag
#        self.btagL_thr = btagL_thr
#        self.btagM_thr = btagM_thr
        self.btagL_thr = btagL_thr
        self.btagM_thr = btagM_thr
        self.doVetoZ = doVetoZ
        self.doVetoLMf = doVetoLMf
        self.doVetoLMt = doVetoLMt
        if isMC is not None: 
            self.isMC = isMC
        self.variations = variations

    def initComponent(self, component):
        self.isMC = component.isMC

    def beginJob(self,histFile=None,histDirName=None):
        self.vars = ["eta","phi","mass"]
        self.vars_leptons = ["pdgId",'jetIdx','pt']
        self.vars_taus = ["pt"]
        self.vars_taus_int = ['jetIdx']
        self.vars_taus_uchar = ['idMVAoldDMdR032017v2','idDeepTau2017v2p1VSjet']
        self.vars_jets = [("pt","pt_nom") if self.isMC else 'pt',"btagDeepB","qgl",'btagDeepFlavB'] + [ 'pt_%s%s'%(x,y) for x in self.variations for y in ["Up","Down"]] #"btagCSVV2",,"btagDeepC"]#"btagCSV","btagDeepCSV",,"btagDeepCSVCvsL","btagDeepCSVCvsB","ptd","axis1"] # FIXME recover
        self.vars_jets_int = (["hadronFlavour"] if self.isMC else [])
        self.vars_jets_nooutput = []
        self.systsJEC = {0:""}
        if self.isMC:
            for sys in range(len(self.variations)):
                self.systsJEC[sys+1]    = '_' + self.variations[sys] + 'Up'
                self.systsJEC[-(sys+1)] = '_' + self.variations[sys] + 'Down'


        self.outmasses=['mZ1','minMllAFAS','minMllAFOS','minMllAFSS','minMllSFOS','mZ2','m4l']
        self._outjetvars = [x%self.jc for x in ['ht%s%%dj','mht%s%%d','nB%sLoose%%d','nB%sMedium%%d','n%s%%d']]
        self.outjetvars=[]
        for jetPt in self.jetPts: self.outjetvars.extend([(x%jetPt+y,'I' if ('nB%s'%self.jc in x or 'n%s'%self.jc in x) else 'F') for x in self._outjetvars for y in self.systsJEC.values()])
        self.outjetvars.extend([('nFwdJet'+self.systsJEC[y],'I') for y in self.systsJEC ])
        self.outjetvars.extend([(x+self.systsJEC[y],'F') for y in self.systsJEC for x in ['FwdJet1_pt','FwdJet1_eta'] ])
        
        self.branches = [var+self.label for var in self.outmasses]
        self.branches.extend([(var+self.label,_type) for var,_type in self.outjetvars])
        self.branches += [("LepGood_conePt","F",100,"nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO"+self.label, "LepGood", floats=[], maxSize=10, saveTagForAll=True, saveSelectedIndices=True,padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight"+self.label, "LepGood", floats=[], maxSize=10, saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel"+self.label, self.tauc, floats=self.vars+self.vars_taus, ints=self.vars_taus_int, uchars=self.vars_taus_uchar, maxSize=10)
        self._helper_jets = CollectionSkimmer("%sSel"%self.jc+self.label, self.jc, floats=self.vars+self.vars_jets, ints=self.vars_jets_int, maxSize=20, saveSelectedIndices=True,padSelectedIndicesWith=0)
        self._helpers = [self._helper_lepsF,self._helper_lepsT,self._helper_taus,self._helper_jets]

##        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries():
##            print "Load C++ recleaner worker module"
##            ROOT.gROOT.ProcessLine(".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O" % os.environ['CMSSW_BASE'])
##        self._worker = ROOT.fastCombinedObjectRecleanerHelper(self._helper_taus.cppImpl(),self._helper_jets.cppImpl(),self.cleanJetsWithFOTaus,self.btagL_thr,self.btagM_thr, True)
##        for x in self.jetPts: self._worker.addJetPt(x)
##        self._worker.setFwdPt(self.jetPtsFwd[0], self.jetPtsFwd[1])
##
##        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries():
##            print "Load C++ recleaner mass and veto calculator module"
##            ROOT.gROOT.ProcessLine(".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O" % os.environ['CMSSW_BASE'])
##        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(self._helper_lepsF.cppImpl(),self._helper_lepsT.cppImpl(),self.doVetoZ,self.doVetoLMf,self.doVetoLMt)

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        for x in self._helpers:
            x.initInputTree(inputTree)
        self.initReaders(inputTree)
#        self.initWorkers(self.btagL_thr,self.btagM_thr)
        declareOutput(self, wrappedOutputTree, self.branches)
        for x in self._helpers: 
            x.initOutputTree(wrappedOutputTree.tree(), True);

    def initReaders(self,tree):
        self._ttreereaderversion = tree._ttreereaderversion
        for coll in ["LepGood",self.tauc,self.jc]:
            setattr(self,'n'+coll,tree.valueReader('n'+coll))
            _vars = self.vars[:]
            if coll=='LepGood': _vars.extend(self.vars_leptons)
            if coll==self.tauc: _vars.extend(self.vars_taus+self.vars_taus_int+self.vars_taus_uchar)
            if coll==self.jc: _vars.extend(self.vars_jets+self.vars_jets_int+self.vars_jets_nooutput)
            for B in _vars:
                if type(B) == tuple:
                    setattr(self,"%s_%s"%(coll,B[0]), tree.arrayReader("%s_%s"%(coll,B[1])))
                else:
                    setattr(self,"%s_%s"%(coll,B), tree.arrayReader("%s_%s"%(coll,B)))
        return True

    def initWorkers(self,wpL,wpM):
        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries():
            print "Load C++ recleaner worker module"
            ROOT.gROOT.ProcessLine(".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O" % os.environ['CMSSW_BASE'])
        self._worker = ROOT.fastCombinedObjectRecleanerHelper(self._helper_taus.cppImpl(),self._helper_jets.cppImpl(),self.cleanJetsWithFOTaus,wpL,wpM, True)
        for x in self.jetPts: self._worker.addJetPt(x)
        self._worker.setFwdPt(self.jetPtsFwd[0], self.jetPtsFwd[1])

        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries():
            print "Load C++ recleaner mass and veto calculator module"
            ROOT.gROOT.ProcessLine(".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O" % os.environ['CMSSW_BASE'])
        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(self._helper_lepsF.cppImpl(),self._helper_lepsT.cppImpl(),self.doVetoZ,self.doVetoLMf,self.doVetoLMt)

        self._worker.setLeptons(self.nLepGood, self.LepGood_pt, self.LepGood_eta, self.LepGood_phi, self.LepGood_jetIdx)
        self._worker.setTaus(getattr(self,'n%s'%self.tauc),getattr(self,'%s_pt'%self.tauc),getattr(self,'%s_eta'%self.tauc),getattr(self,'%s_phi'%self.tauc), getattr(self,'%s_jetIdx'%self.tauc))
        jecs= ROOT.vector("TTreeReaderArray<float>*")()
        if self.isMC:
            for var in self.variations:
                jecs.push_back( getattr(self, '%s_pt_%sUp'%(self.jc, var)))
                jecs.push_back( getattr(self, '%s_pt_%sDown'%(self.jc, var)))

        self._worker.setJets(getattr(self,'n%s'%self.jc),getattr(self,'%s_pt'%self.jc),getattr(self,'%s_eta'%self.jc),getattr(self,'%s_phi'%self.jc),
                             getattr(self,'%s_%s'%(self.jc,self.jetBTag)),
                             jecs
                         )
        
        self._workerMV.setLeptons(self.nLepGood, self.LepGood_pt, self.LepGood_eta, self.LepGood_phi, self.LepGood_mass, self.LepGood_pdgId)

    def analyze(self, event):
        # Init
        year = event.year
        # wpL = self.btagL_thr #_btagWPs["DeepFlav_%d_%s"%(event.year,"L")][1]
        # wpM = self.btagM_thr #_btagWPs["DeepFlav_%d_%s"%(event.year,"M")][1]
        wpL = self.btagL_thr(year) if type(self.btagL_thr) is types.LambdaType else self.btagL_thr #_btagWPs["DeepFlav_%d_%s"%(event.year,"L")][1]
        wpM = self.btagM_thr(year) if type(self.btagM_thr) is types.LambdaType else self.btagM_thr #_btagWPs["DeepFlav_%d_%s"%(event.year,"M")][1]      
        if self._ttreereaderversion != event._tree._ttreereaderversion:
            for x in self._helpers: x.initInputTree(event._tree)
            self.initReaders(event._tree)
            self.initWorkers(wpL,wpM)

        for x in self._helpers: x.clear()

        tags = getattr(event,'_CombinedTagsForCleaning%s'%self.inlabel)
        self.wrappedOutputTree.fillBranch('LepGood_conePt', [tags.leps_conept[i] for i in xrange(self.nLepGood.Get()[0])])


        self._worker.clear()
        self._worker.loadTags(tags,self.cleanTausWithLooseLeptons, wpL, wpM)
        self._worker.run()

        for delta,varname in self.systsJEC.iteritems():
            for x in self._worker.GetJetSums(delta):
                for var in self._outjetvars: 
                    self.wrappedOutputTree.fillBranch(var%x.thr+varname+self.label, getattr(x,var.replace('%d','').replace(self.jc,'Jet')))
                self.wrappedOutputTree.fillBranch('nFwdJet'+varname+self.label,getattr(x,'nFwdJet'))
                self.wrappedOutputTree.fillBranch('FwdJet1_pt'+varname+self.label,getattr(x,'fwd1_pt'))
                self.wrappedOutputTree.fillBranch('FwdJet1_eta'+varname+self.label,getattr(x,'fwd1_eta'))

        self._workerMV.clear()
        self._workerMV.loadTags(tags)
        self._workerMV.run()

        masses = self._workerMV.GetPairMasses()
        for var in self.outmasses: 
            self.wrappedOutputTree.fillBranch(var+self.label, getattr(masses,var))

        return True
    def beginJob(self, histFile=None, histDirName=None):
        self.vars = ["eta", "phi", "mass"]
        self.vars_leptons = ["pdgId", 'jetIdx', 'pt']
        self.vars_taus = ["pt"]
        self.vars_taus_int = ['jetIdx']
        self.vars_taus_uchar = [
            'idMVAoldDMdR032017v2', 'idDeepTau2017v2p1VSjet'
        ]
        self.vars_jets = [
            ("pt", "pt_nom") if self.isMC and len(self.variations) else 'pt',
            "btagDeepB", "qgl", 'btagDeepFlavB'
        ] + [
            'pt_%s%s' % (x, y) for x in self.variations
            for y in ["Up", "Down"]
        ]  #"btagCSVV2",,"btagDeepC"]#"btagCSV","btagDeepCSV",,"btagDeepCSVCvsL","btagDeepCSVCvsB","ptd","axis1"] # FIXME recover
        self.vars_jets_int = (["hadronFlavour"] if self.isMC else [])
        self.vars_jets_nooutput = []
        self.systsJEC = {0: ""}
        if self.isMC:
            for sys in range(len(self.variations)):
                self.systsJEC[sys + 1] = '_' + self.variations[sys] + 'Up'
                self.systsJEC[-(sys + 1)] = '_' + self.variations[sys] + 'Down'

        self.outmasses = [
            'mZ1', 'minMllAFAS', 'minMllAFOS', 'minMllAFSS', 'minMllSFOS',
            'mZ2', 'm4l'
        ]
        self._outjetvars = [
            x % self.jc for x in [
                'ht%s%%dj', 'mht%s%%d', 'nB%sLoose%%d', 'nB%sMedium%%d',
                'n%s%%d'
            ]
        ]
        self.outjetvars = []
        for jetPt in self.jetPts:
            self.outjetvars.extend([
                (x % jetPt + y, 'I' if
                 ('nB%s' % self.jc in x or 'n%s' % self.jc in x) else 'F')
                for x in self._outjetvars for y in self.systsJEC.values()
            ])
        self.outjetvars.extend([('nFwdJet' + self.systsJEC[y], 'I')
                                for y in self.systsJEC])
        self.outjetvars.extend([(x + self.systsJEC[y], 'F')
                                for y in self.systsJEC
                                for x in ['FwdJet1_pt', 'FwdJet1_eta']])

        self.branches = [var + self.label for var in self.outmasses]
        self.branches.extend([(var + self.label, _type)
                              for var, _type in self.outjetvars])
        self.branches += [("LepGood_conePt", "F", 100, "nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=10,
                                               saveSelectedIndices=True,
                                               padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=10,
                                               saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel" + self.label,
                                              self.tauc,
                                              floats=self.vars +
                                              self.vars_taus,
                                              ints=self.vars_taus_int,
                                              uchars=self.vars_taus_uchar,
                                              maxSize=10)
        self._helper_jets = CollectionSkimmer("%sSel" % self.jc + self.label,
                                              self.jc,
                                              floats=self.vars +
                                              self.vars_jets,
                                              ints=self.vars_jets_int,
                                              maxSize=20)
        self._helpers = [
            self._helper_lepsF, self._helper_lepsT, self._helper_taus,
            self._helper_jets
        ]

        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner worker module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._worker = ROOT.fastCombinedObjectRecleanerHelper(
            self._helper_taus.cppImpl(), self._helper_jets.cppImpl(),
            self.cleanJetsWithFOTaus, self.btagL_thr, self.btagM_thr, True)
        for x in self.jetPts:
            self._worker.addJetPt(x)
        self._worker.setFwdPt(self.jetPtsFwd[0], self.jetPtsFwd[1])

        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner mass and veto calculator module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(
            self._helper_lepsF.cppImpl(), self._helper_lepsT.cppImpl(),
            self.doVetoZ, self.doVetoLMf, self.doVetoLMt)
class fastCombinedObjectRecleaner(Module):
    def __init__(self,
                 label,
                 inlabel,
                 cleanTausWithLooseLeptons,
                 cleanJetsWithFOTaus,
                 doVetoZ,
                 doVetoLMf,
                 doVetoLMt,
                 jetPts,
                 btagL_thr,
                 btagM_thr,
                 jetCollection='Jet',
                 jetBTag='btagDeepB',
                 tauCollection='Tau',
                 isMC=None):

        self.label = "" if (label in ["", None]) else ("_" + label)
        self.inlabel = inlabel
        self.tauc = tauCollection
        self.jc = jetCollection

        self.cleanTausWithLooseLeptons = cleanTausWithLooseLeptons
        self.cleanJetsWithFOTaus = cleanJetsWithFOTaus
        self.jetPts = jetPts
        self.jetBTag = jetBTag
        self.btagL_thr = btagL_thr
        self.btagM_thr = btagM_thr
        self.doVetoZ = doVetoZ
        self.doVetoLMf = doVetoLMf
        self.doVetoLMt = doVetoLMt
        if isMC is not None:
            self.isMC = isMC

    def initComponent(self, component):
        self.isMC = component.isMC

    def beginJob(self, histFile=None, histDirName=None):
        self.vars = ["pt", "eta", "phi", "mass"]
        self.vars_leptons = ["pdgId"]
        self.vars_taus = []  #"mvaId2017"] # FIXME recover
        self.vars_taus_int = []  #"idMVAdR03"] # FIXME recover
        self.vars_jets = [
            "btagDeepB"
        ]  #"btagCSVV2",,"btagDeepC"]#"btagCSV","btagDeepCSV","qgl","btagDeepCSVCvsL","btagDeepCSVCvsB","ptd","axis1","corr","corr_JECUp","corr_JECDown"] # FIXME recover
        self.vars_jets_int = [
        ]  #(["hadronFlavour"] if self.isMC else [])#+["mult"] # FIXME
        self.vars_jets_nooutput = []

        self.systsJEC = {0: ""}  #, 1:"_jecUp", -1:"_jecDown"} # FIXME recover

        self.outmasses = [
            'mZ1', 'minMllAFAS', 'minMllAFOS', 'minMllAFSS', 'minMllSFOS'
        ]
        self._outjetvars = [
            x % self.jc for x in [
                'ht%s%%dj', 'mht%s%%d', 'nB%sLoose%%d', 'nB%sMedium%%d',
                'n%s%%d'
            ]
        ]
        self.outjetvars = []
        for jetPt in self.jetPts:
            self.outjetvars.extend([
                (x % jetPt + y, 'I' if
                 ('nB%s' % self.jc in x or 'n%s' % self.jc in x) else 'F')
                for x in self._outjetvars for y in self.systsJEC.values()
            ])

        self.branches = [var + self.label for var in self.outmasses]
        self.branches.extend([(var + self.label, _type)
                              for var, _type in self.outjetvars])
        self.branches += [("LepGood_conePt", "F", 100, "nLepGood")]

        self._helper_lepsF = CollectionSkimmer("LepFO" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=10,
                                               saveSelectedIndices=True,
                                               padSelectedIndicesWith=0)
        self._helper_lepsT = CollectionSkimmer("LepTight" + self.label,
                                               "LepGood",
                                               floats=[],
                                               maxSize=10,
                                               saveTagForAll=True)
        self._helper_taus = CollectionSkimmer("TauSel" + self.label,
                                              self.tauc,
                                              floats=self.vars +
                                              self.vars_taus,
                                              ints=self.vars_taus_int,
                                              maxSize=10)
        self._helper_jets = CollectionSkimmer("%sSel" % self.jc + self.label,
                                              self.jc,
                                              floats=self.vars +
                                              self.vars_jets,
                                              ints=self.vars_jets_int,
                                              maxSize=20)
        self._helpers = [
            self._helper_lepsF, self._helper_lepsT, self._helper_taus,
            self._helper_jets
        ]

        if "/fastCombinedObjectRecleanerHelper_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner worker module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerHelper.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._worker = ROOT.fastCombinedObjectRecleanerHelper(
            self._helper_taus.cppImpl(), self._helper_jets.cppImpl(),
            self.cleanJetsWithFOTaus, self.btagL_thr, self.btagM_thr)
        for x in self.jetPts:
            self._worker.addJetPt(x)

        if "/fastCombinedObjectRecleanerMassVetoCalculator_cxx.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ recleaner mass and veto calculator module"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/CMGTools/TTHAnalysis/python/tools/fastCombinedObjectRecleanerMassVetoCalculator.cxx+O"
                % os.environ['CMSSW_BASE'])
        self._workerMV = ROOT.fastCombinedObjectRecleanerMassVetoCalculator(
            self._helper_lepsF.cppImpl(), self._helper_lepsT.cppImpl(),
            self.doVetoZ, self.doVetoLMf, self.doVetoLMt)

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        for x in self._helpers:
            x.initInputTree(inputTree)
        self.initReaders(inputTree)
        self.initWorkers()
        declareOutput(self, wrappedOutputTree, self.branches)
        for x in self._helpers:
            x.initOutputTree(wrappedOutputTree.tree(), True)

    def initReaders(self, tree):
        self._ttreereaderversion = tree._ttreereaderversion
        for coll in ["LepGood", self.tauc, self.jc]:
            setattr(self, 'n' + coll, tree.valueReader('n' + coll))
            _vars = self.vars[:]
            if coll == 'LepGood': _vars.extend(self.vars_leptons)
            if coll == self.tauc:
                _vars.extend(self.vars_taus + self.vars_taus_int)
            if coll == self.jc:
                _vars.extend(self.vars_jets + self.vars_jets_int +
                             self.vars_jets_nooutput)
            for B in _vars:
                setattr(self, "%s_%s" % (coll, B),
                        tree.arrayReader("%s_%s" % (coll, B)))
        return True

    def initWorkers(self):
        self._worker.setLeptons(self.nLepGood, self.LepGood_pt,
                                self.LepGood_eta, self.LepGood_phi)
        self._worker.setTaus(getattr(self, 'n%s' % self.tauc),
                             getattr(self, '%s_pt' % self.tauc),
                             getattr(self, '%s_eta' % self.tauc),
                             getattr(self, '%s_phi' % self.tauc))
        self._worker.setJets(
            getattr(self, 'n%s' % self.jc), getattr(self, '%s_pt' % self.jc),
            getattr(self, '%s_eta' % self.jc), getattr(self,
                                                       '%s_phi' % self.jc),
            getattr(self, '%s_%s' % (self.jc, self.jetBTag))
        )  # ,getattr(self,'%s_corr'%self.jc),getattr(self,'%s_corr_JECUp'%self.jc),getattr(self,'%s_corr_JECDown'%self.jc)) # FIXME
        self._workerMV.setLeptons(self.nLepGood, self.LepGood_pt,
                                  self.LepGood_eta, self.LepGood_phi,
                                  self.LepGood_mass, self.LepGood_pdgId)

    def analyze(self, event):
        # Init
        if self._ttreereaderversion != event._tree._ttreereaderversion:
            for x in self._helpers:
                x.initInputTree(event._tree)
            self.initReaders(event._tree)
            self.initWorkers()

        for x in self._helpers:
            x.clear()

        tags = getattr(event, '_CombinedTagsForCleaning%s' % self.inlabel)
        self.wrappedOutputTree.fillBranch(
            'LepGood_conePt',
            [tags.leps_conept[i] for i in xrange(self.nLepGood.Get()[0])])

        self._worker.clear()
        self._worker.loadTags(tags, self.cleanTausWithLooseLeptons)
        self._worker.run()

        for delta, varname in self.systsJEC.iteritems():
            for x in self._worker.GetJetSums(delta):
                for var in self._outjetvars:
                    self.wrappedOutputTree.fillBranch(
                        var % x.thr + varname + self.label,
                        getattr(x,
                                var.replace('%d', '').replace(self.jc, 'Jet')))

        self._workerMV.clear()
        self._workerMV.loadTags(tags)
        self._workerMV.run()

        masses = self._workerMV.GetPairMasses()
        for var in self.outmasses:
            self.wrappedOutputTree.fillBranch(var + self.label,
                                              getattr(masses, var))

        return True