Example #1
0
def inputStaticCast(inputDict,cast='float'):
    return [op.static_cast(cast,v) for v in inputDict.values()]
Example #2
0
    def defineSkimSelection(self, t, noSel, sample=None, sampleCfg=None):
        noSel, PUWeight, corrMET, muons, electrons, AK4jets, AK8jets, bjets_resolved, bjets_boosted, categories, TwoLeptonsTwoJets_Resolved, TwoLeptonsTwoJets_Boosted, TwoLeptonsTwoBjets_Res, TwoLeptonsTwoBjets_Boo, TwoLeptonsTwoBjets_NoMETCut_Res, TwoLeptonsTwoBjets_NoMETCut_Boo, WorkingPoints = self.defineObjects(
            t, noSel, sample, sampleCfg)

        era = sampleCfg["era"]
        isMC = self.isMC(sample)

        if self.SetSel not in ["noSel", "catSel", "2Lep2Jets", "2Lep2bJets"]:
            print('[Skimedtree_NanoHtoZA]: %s Unkown selection ' % self.SetSel)
            sys.exit(0)

        if self.SetRegion not in ["boosted", "resolved"]:
            print(' Region of studies should be : boosted or resolved ! ')
            sys.exit(0)

        if self.SetRegion == "boosted":
            self.SetTagger = "DeepCSV"  # FIXME add later DeepDoubleB
        else:
            if self.SetTagger not in ["DeepFlavour", "DeepCSV"]:
                print(
                    '[Skimedtree_NanoHtoZA]: %s Unknown tagger for resolved region'
                    % self.SetTagger)
                sys.exit(0)

        if self.SetCat not in categories.keys():
            print('[Skimedtree_NanoHtoZA] channel %s not found in categories' %
                  self.SetCat)
            print('Available channel are :')
            print(categories.keys())
            sys.exit(0)

        if self.SetWP is None:
            print(
                '[Skimedtree_NanoHtoZA]: WP is MANDATORY, this is the working point as defined in the ZAtollbb_PreSelection.py'
            )
            sys.exit(0)

        if self.SetWP not in WorkingPoints:
            print(
                '[Skimedtree_NanoHtoZA] WP %s not found in working points definitions'
                % self.SetWP)
            print('  --> define in settings first')
            print('  In settings I found WPs: ')
            print(WorkingPoints)
            sys.exit(1)

        key = self.SetTagger + self.SetWP
        if self.SetRegion == "resolved":
            jets = AK4jets
            bjets = bjets_resolved
            suffix = "AK4Jets"
        elif self.SetRegion == "boosted":
            jets = AK8jets
            bjets = bjets_boosted
            suffix = "AK8Jets"
        else:
            raise RuntimeError('ERROR : %s Unkown args' % self.SetRegion)

        #variables to keep from the input tree
        varsToKeep = {"run": None, "luminosityBlock": None, "event": None}

        if isMC:
            varsToKeep["MC_weight"] = t.genWeight
            varsToKeep["PU_weight"] = PUWeight

        if self.SetSel == "noSel":
            FinalSel = noSel
            # Muons && Electrons selections
            for obj, flav in zip([muons, electrons], ["Muons", "Electrons"]):
                varsToKeep["n%s" % flav] = op.static_cast(
                    "UInt_t", op.rng_len(obj))
                varsToKeep["%s_pt" % flav] = op.map(obj, lambda lep: lep.pt)
                varsToKeep["%s_eta" % flav] = op.map(obj, lambda lep: lep.eta)
                varsToKeep["%s_phi" % flav] = op.map(obj, lambda lep: lep.phi)

            # resolved or boosted
            ### Jets selections
            varsToKeep["%s_pt" % suffix] = op.map(jets, lambda j: j.pt)
            varsToKeep["%s_eta" % suffix] = op.map(jets, lambda j: j.eta)
            varsToKeep["%s_phi" % suffix] = op.map(jets, lambda j: j.phi)
            varsToKeep["n%s" % suffix] = op.static_cast(
                "UInt_t", op.rng_len(jets))

            # MET selections
            varsToKeep["CorrMET_pt"] = corrMET.pt
            varsToKeep["CorrMET_phi"] = corrMET.phi

        for channel, (dilepton, catSel) in categories.items():

            ### Opposite sign leptons , Same Flavour  selection
            if self.SetSel == "catSel":
                FinalSel = catSel
                for i in range(2):
                    varsToKeep["lep{0}_pt_{1}".format(
                        i, self.SetCat)] = dilepton[i].p4.pt
                    varsToKeep["lep{0}_eta_{1}".format(
                        i, self.SetCat)] = dilepton[i].p4.eta
                    varsToKeep["lep{0}_phi_{1}".format(
                        i, self.SetCat)] = dilepton[i].p4.phi
                ll_M = op.invariant_mass(dilepton[0].p4, dilepton[1].p4)
                varsToKeep["ll_M_{0}".format(channel)] = ll_M

            # boosted or resolved
            ### Two OS SF Leptons _ Two Jets  selection
            elif self.SetSel == "2Lep2Jets":
                if self.SetRegion == "resolved":
                    FinalSel = TwoLeptonsTwoJets_Resolved.get(key)
                elif self.SetRegion == "boosted":
                    FinaSel = TwoLeptonsTwoJets_Boosted.get(key)

                lljj_M = (dilepton[0].p4 + dilepton[1].p4 + jets[0].p4 +
                          jets[1].p4).M()
                jj_M = op.invariant_mass(jets[0].p4, jets[1].p4)
                varsToKeep["lljj_M_{0}_{1}{2}_{3}".format(
                    self.SetRegion, self.SetTagger, self.SetWP,
                    self.SetCat)] = lljj_M
                varsToKeep["jj_M_{0}_{1}{2}_{3}".format(
                    self.SetRegion, self.SetTagger, self.SetWP,
                    self.SetCat)] = jj_M

                varsToKeep["nB_{0}_{1}{2}_{3}".format(
                    suffix, self.SetTagger, self.SetWP,
                    self.SetCat)] = op.static_cast("UInt_t", op.rng_len(bJets))

                ### Two OS SF Leptons _ Two bJets  selection +MET cut (xy corr applied too )
            elif self.SetSel == "2Lep2bJets":
                bJets = safeget(bjets, self.SetTagger, self.SetWP)
                if self.SetRegion == "resolved":
                    FinalSel = TwoLeptonsTwoBjets_Res.get(key)
                elif self.SetRegion == "boosted":
                    FinalSel = TwoLeptonsTwoBjets_Boo.get(key)

                llbb_M = (dilepton[0].p4 + dilepton[1].p4 + bJets[0].p4 +
                          bJets[1].p4).M()
                bb_M = op.invariant_mass(bJets[0].p4 + bJets[1].p4)
                varsToKeep["llbb_M_{0}_{1}{2}_{3}".format(
                    self.SetRegion, self.SetTagger, self.SetWP,
                    self.SetCat)] = llbb_M
                varsToKeep["bb_M_{0}_{1}{2}_{3}".format(
                    self.SetRegion, self.SetTagger, self.SetWP,
                    self.SetCat)] = bb_M

                varsToKeep["nB_{0}_{1}{2}_{3}".format(
                    suffix, self.SetTagger, self.SetWP,
                    self.SetCat)] = op.static_cast("UInt_t", op.rng_len(bJets))
            else:
                raise RuntimeError('ERROR : %s  in selection args' %
                                   self.SetSel)

            #sample_weight=
            #event_weight=
            #total_weight=
            #cross_section=

        return FinalSel, varsToKeep
    def defineSkimSelection(self, t, noSel, sample=None, sampleCfg=None):
        noSel = super(SkimmerNanoHHtobbWWSL,
                      self).prepareObjects(t,
                                           noSel,
                                           sample,
                                           sampleCfg,
                                           "SL",
                                           forSkimmer=True)
        # For the Skimmer, SF must not use defineOnFirstUse -> segmentation fault

        era = sampleCfg['era']

        # Initialize varsToKeep dict #
        varsToKeep = dict()

        #---------------------------------------------------------------------------------------#
        #                                     Selections                                        #
        #---------------------------------------------------------------------------------------#
        # keep the exact same order of nodes as mentioned in respective JPA model xml files
        ResolvedJPANodeList = [
            '2b2Wj', '2b1Wj', '1b2Wj', '2b0Wj', '1b1Wj', '1b0Wj', '0b'
        ]
        BoostedJPANodeList = ['Hbb2Wj', 'Hbb1Wj', 'Hbb0Wj']

        # JPA Models
        basepath = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                                'MachineLearning', 'ml-models',
                                'JPA_Loose_ttH')
        resolvedModelDict = getResolvedJpaModelDict(basepath,
                                                    ResolvedJPANodeList, era)
        boostedModelDict = getBoostedJpaModelDict(basepath, BoostedJPANodeList,
                                                  era)

        if not self.inclusive_sel:
            #----- Check arguments -----#
            jet_level = [
                "Ak4", "Ak8", "Res2b2Wj", "Res2b1Wj", "Res2b0Wj", "Res1b2Wj",
                "Res1b1Wj", "Res1b0Wj", "Res0b", "Hbb2Wj", "Hbb1Wj", "Hbb0Wj"
            ]

            if [
                    boolean for (level, boolean) in self.args.__dict__.items()
                    if level in jet_level
            ].count(True) != 1:
                raise RuntimeError(
                    "Only one of the jet arguments must be used, check --help")

            if self.args.Channel not in ["El", "Mu"]:
                raise RuntimeError("Channel must be either 'El' or 'Mu'")

            #----- Lepton selection -----#
            ElSelObj, MuSelObj = makeSingleLeptonSelection(
                self, noSel, use_dd=False, fake_selection=self.args.FakeCR)

            if self.args.Channel is None:
                raise RuntimeError("You need to specify --Channel")
            if self.args.Channel == "El":
                selObj = ElSelObj
                lep = self.electronsTightSel[0]
            if self.args.Channel == "Mu":
                selObj = MuSelObj
                lep = self.muonsTightSel[0]

            #----- Apply jet corrections -----#
            ElSelObject.sel = self.beforeJetselection(ElSelObj.sel, 'El')
            MuSelObject.sel = self.beforeJetselection(MuSelObj.sel, 'Mu')

            #----- Jet selection -----#
            if any([
                    self.args.__dict__[item] for item in [
                        "Ak4", "Res2b2Wj", "Res2b1Wj", "Res2b0Wj", "Res1b2Wj",
                        "Res1b1Wj", "Res1b0Wj", "Res0b"
                    ]
            ]):
                makeResolvedSelection(self, selObj)
                if self.args.Channel == "El":
                    print('... Resolved :: El Channel')
                    L1out, L2out, selObjAndJetsPerJpaCatDict = findJPACategoryResolved(
                        self,
                        selObj,
                        lep,
                        self.muonsPreSel,
                        self.electronsPreSel,
                        self.ak4Jets,
                        self.ak4BJetsLoose,
                        self.ak4BJets,
                        self.corrMET,
                        resolvedModelDict,
                        t.event,
                        self.HLL,
                        ResolvedJPANodeList,
                        plot_yield=False)

                if self.args.Channel == "Mu":
                    print('... Resolved :: Mu Channel')
                    L1out, L2out, selObjAndJetsPerJpaCatDict = findJPACategoryResolved(
                        self,
                        selObj,
                        lep,
                        self.muonsPreSel,
                        self.electronsPreSel,
                        self.ak4Jets,
                        self.ak4BJetsLoose,
                        self.ak4BJets,
                        self.corrMET,
                        resolvedModelDict,
                        t.event,
                        self.HLL,
                        ResolvedJPANodeList,
                        plot_yield=False)

            if any([
                    self.args.__dict__[item]
                    for item in ["Ak8", "Hbb2Wj", "Hbb1Wj", "Hbb0Wj"]
            ]):
                makeBoostedSelection(self, selObj)
                if self.args.Channel == "El":
                    print('... Boosted :: El Channel')
                    L1out, L2out, selObjAndJetsPerJpaCatDict = findJPACategoryBoosted(
                        self,
                        selObj,
                        lep,
                        self.muonsPreSel,
                        self.electronsPreSel,
                        self.ak8BJets,
                        self.ak4JetsCleanedFromAk8b,
                        self.ak4BJetsLoose,
                        self.ak4BJets,
                        self.corrMET,
                        boostedModelDict,
                        t.event,
                        self.HLL,
                        BoostedJPANodeList,
                        plot_yield=False)

                if self.args.Channel == "Mu":
                    print('... Boosted :: Mu Channel')
                    L1out, L2out, selObjAndJetsPerJpaCatDict = findJPACategoryBoosted(
                        self,
                        selObj,
                        lep,
                        self.muonsPreSel,
                        self.electronsPreSel,
                        self.ak8BJets,
                        self.ak4JetsCleanedFromAk8b,
                        self.ak4BJetsLoose,
                        self.ak4BJets,
                        self.corrMET,
                        boostedModelDict,
                        t.event,
                        self.HLL,
                        BoostedJPANodeList,
                        plot_yield=False)

            if self.args.Res2b2Wj:
                print("...... 2b2Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('2b2Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('2b2Wj')[1]
                jpaarg = "Res2b2Wj"

            if self.args.Res2b1Wj:
                print("...... 2b1Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('2b1Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('2b1Wj')[1]
                jpaarg = "Res2b1Wj"

            if self.args.Res1b2Wj:
                print("...... 1b2Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('1b2Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('1b2Wj')[1]
                jpaarg = "Res1b2Wj"

            if self.args.Res2b0Wj:
                print("...... 2b0Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('2b0Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('2b0Wj')[1]
                jpaarg = "Res2b0Wj"

            if self.args.Res1b1Wj:
                print("...... 1b1Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('1b1Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('1b1Wj')[1]
                jpaarg = "Res1b1Wj"

            if self.args.Res1b0Wj:
                print("...... 1b0Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('1b0Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('1b0Wj')[1]
                jpaarg = "Res1b0Wj"

            if self.args.Res0b:
                print("...... 0b")
                selObj = selObjAndJetsPerJpaCatDict.get('0b')[0]
                jpaJets = None
                jpaarg = "Res0b"

            #######################################
            # Hbb2Wj : jet1 jet2   jet3   jet4
            # Hbb1Wj : jet1 jet2   jet3   jet4=0
            # Hbb0Wj : jet1 jet2   jet3=0 jet4=0
            #######################################
            if self.args.Hbb2Wj:
                print("...... Hbb2Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('Hbb2Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('Hbb2Wj')[1]
                jpaarg = "Hbb2Wj"

            if self.args.Hbb1Wj:
                print("...... Hbb1Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('Hbb1Wj')[0]
                jpaJets = selObjAndJetsPerJpaCatDict.get('Hbb1Wj')[1]
                jpaarg = "Hbb1Wj"

            if self.args.Hbb0Wj:
                print("...... Hbb0Wj")
                selObj = selObjAndJetsPerJpaCatDict.get('Hbb0Wj')[0]
                jpaJets = None
                jpaarg = "Hbb0Wj"

        else:
            noSel = self.beforeJetselection(noSel)

        #---------------------------------------------------------------------------------------#
        #                                 Synchronization tree                                  #
        #---------------------------------------------------------------------------------------#
        if self.args.Synchronization:
            # Event variables #
            varsToKeep["event"] = None  # Already in tree
            varsToKeep["run"] = None  # Already in tree
            varsToKeep["ls"] = t.luminosityBlock
            varsToKeep["n_presel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsPreSel))
            varsToKeep["n_fakeablesel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsFakeSel))
            varsToKeep["n_mvasel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsTightSel))
            varsToKeep["n_presel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsPreSel))
            varsToKeep["n_fakeablesel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsFakeSel))
            varsToKeep["n_mvasel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsTightSel))
            varsToKeep["n_presel_ak4Jet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4Jets))
            varsToKeep["n_presel_ak8Jet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak8Jets))
            varsToKeep["n_presel_ak8BJet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak8BJets))
            varsToKeep["n_loose_ak4BJet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4BJetsLoose))
            varsToKeep["n_medium_ak4BJet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4BJets))
            varsToKeep["n_ak4JetsCleanAk8b"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4JetsCleanedFromAk8b))
            varsToKeep["n_presel_ak4JetVBF"] = op.static_cast(
                "UInt_t", op.rng_len(self.VBFJetsPreSel))

            varsToKeep["is_SR"] = op.static_cast(
                "UInt_t",
                op.OR(
                    op.rng_len(self.electronsTightSel) == 1,
                    op.rng_len(self.muonsTightSel) == 1))

            varsToKeep["is_e"] = op.c_float(
                True) if self.args.Channel == 'El' else op.c_float(False)
            varsToKeep["is_m"] = op.c_float(
                False) if self.args.Channel == 'El' else op.c_float(True)

            varsToKeep["is_resolved"] = op.switch(
                op.AND(
                    op.rng_len(self.ak4Jets) >= 3,
                    op.rng_len(self.ak4BJets) >= 1,
                    op.rng_len(self.ak8BJets) == 0), op.c_bool(True),
                op.c_bool(False))
            varsToKeep["is_boosted"] = op.switch(
                op.AND(
                    op.rng_len(self.ak8BJets) >= 1,
                    op.rng_len(self.ak4JetsCleanedFromAk8b) >= 1),
                op.c_bool(True), op.c_bool(False))

            varsToKeep["n_tau"] = op.static_cast("UInt_t",
                                                 op.rng_len(self.tauCleanSel))

            varsToKeep['resolved_tag'] = op.static_cast(
                "UInt_t",
                op.AND(
                    op.rng_len(self.ak4Jets) >= 3,
                    op.rng_len(self.ak4BJets) >= 1,
                    op.rng_len(self.ak8BJets) == 0))
            varsToKeep['boosted_tag'] = op.static_cast(
                "UInt_t",
                op.AND(
                    op.rng_len(self.ak8BJets) >= 1,
                    op.rng_len(self.ak4JetsCleanedFromAk8b) >= 1))

            # Triggers #
            '''
            varsToKeep["triggers"]                  = self.triggers
            varsToKeep["triggers_SingleElectron"]   = op.OR(*self.triggersPerPrimaryDataset['SingleElectron'])
            varsToKeep["triggers_SingleMuon"]       = op.OR(*self.triggersPerPrimaryDataset['SingleMuon'])
            varsToKeep["triggers_DoubleElectron"]   = op.OR(*self.triggersPerPrimaryDataset['DoubleEGamma'])
            varsToKeep["triggers_DoubleMuon"]       = op.OR(*self.triggersPerPrimaryDataset['DoubleMuon'])
            varsToKeep["triggers_MuonElectron"]     = op.OR(*self.triggersPerPrimaryDataset['MuonEG'])
            '''
            # Muons #

            for i in range(1, 3):  # 2 leading muons
                varsToKeep["mu{}_pt".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].pt, op.c_float(-9999., "float"))
                varsToKeep["mu{}_eta".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].eta, op.c_float(-9999.))
                varsToKeep["mu{}_phi".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].phi, op.c_float(-9999.))
                varsToKeep["mu{}_E".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].p4.E(),
                    op.c_float(-9999., "float"))
                varsToKeep["mu{}_charge".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].charge, op.c_int(-9999.))
                varsToKeep["mu{}_conept".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muon_conept[self.muonsPreSel[i - 1].idx],
                    op.c_float(-9999.))
                varsToKeep["mu{}_miniRelIso".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].miniPFRelIso_all,
                    op.c_float(-9999.))
                varsToKeep["mu{}_PFRelIso04".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].pfRelIso04_all, op.c_float(-9999.))
                varsToKeep["mu{}_jetNDauChargedMVASel".format(i)] = op.c_float(
                    -9999.)
                varsToKeep["mu{}_jetPtRel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.))
                varsToKeep["mu{}_jetRelIso".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jetRelIso, op.c_float(-9999.))
                varsToKeep["mu{}_jetDeepJet".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jet.btagDeepFlavB,
                    op.c_float(-9999.))
                varsToKeep["mu{}_sip3D".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].sip3d, op.c_float(-9999.))
                varsToKeep["mu{}_dxy".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].dxy, op.c_float(-9999.))
                varsToKeep["mu{}_dxyAbs".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.abs(self.muonsPreSel[i - 1].dxy), op.c_float(-9999.))
                varsToKeep["mu{}_dz".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].dz, op.c_float(-9999.))
                varsToKeep["mu{}_segmentCompatibility".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].segmentComp, op.c_float(-9999.))
                varsToKeep["mu{}_leptonMVA".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].mvaTTH, op.c_float(-9999.))
                varsToKeep["mu{}_mediumID".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].mediumId,
                    op.c_float(-9999., "Bool_t"))
                varsToKeep["mu{}_dpt_div_pt".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].tunepRelPt,
                    op.c_float(-9999.))  # Not sure
                varsToKeep["mu{}_isfakeablesel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(self.lambda_muonFakeSel(self.muonsPreSel[i - 1]),
                              op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["mu{}_ismvasel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(
                        op.AND(
                            self.lambda_muonTightSel(self.muonsPreSel[i - 1]),
                            self.lambda_muonFakeSel(self.muonsPreSel[i - 1])),
                        op.c_int(1), op.c_int(0)),
                    op.c_int(-9999))  # mvasel encompasses fakeablesel
                varsToKeep["mu{}_isGenMatched".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(self.lambda_is_matched(self.muonsPreSel[i - 1]),
                              op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["mu{}_genPartFlav".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].genPartFlav, op.c_int(-9999))
                varsToKeep["mu{}_FR".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.lambda_FR_mu(self.muonsPreSel[i - 1]),
                    op.c_int(-9999))
                varsToKeep["mu{}_FRcorr".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.lambda_FRcorr_mu(self.muonsPreSel[i - 1]),
                    op.c_int(-9999))
                varsToKeep["mu{}_FF".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.lambda_FF_mu(self.muonsPreSel[i - 1]),
                    op.c_int(-9999))
                varsToKeep["mu{}_looseSF".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    reduce(mul,
                           self.lambda_MuonLooseSF(self.muonsPreSel[i - 1])),
                    op.c_int(-9999))
                varsToKeep["mu{}_tightSF".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    reduce(mul,
                           self.lambda_MuonTightSF(self.muonsPreSel[i - 1])),
                    op.c_int(-9999))

            # Electrons #
            for i in range(1, 3):  # 2 leading electrons
                varsToKeep["ele{}_pt".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].pt, op.c_float(-9999.))
                varsToKeep["ele{}_eta".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].eta, op.c_float(-9999.))
                varsToKeep["ele{}_phi".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].phi, op.c_float(-9999.))
                varsToKeep["ele{}_E".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].p4.E(), op.c_float(-9999., ))
                varsToKeep["ele{}_charge".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].charge, op.c_int(-9999.))
                varsToKeep["ele{}_conept".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electron_conept[self.electronsPreSel[i - 1].idx],
                    op.c_float(-9999.))
                varsToKeep["ele{}_miniRelIso".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].miniPFRelIso_all,
                    op.c_float(-9999.))
                varsToKeep["ele{}_PFRelIso03".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].pfRelIso03_all,
                    op.c_float(-9999.))  # Iso03, Iso04 not in NanoAOD
                varsToKeep["ele{}_jetNDauChargedMVASel".format(
                    i)] = op.c_float(-9999.)
                varsToKeep["ele{}_jetPtRel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.))
                varsToKeep["ele{}_jetRelIso".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jetRelIso, op.c_float(-9999.))
                varsToKeep["ele{}_jetDeepJet".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jet.btagDeepFlavB,
                    op.c_float(-9999.))
                varsToKeep["ele{}_sip3D".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].sip3d, op.c_float(-9999.))

                varsToKeep["ele{}_dxy".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].dxy, op.c_float(-9999.))
                varsToKeep["ele{}_dxyAbs".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.abs(self.electronsPreSel[i - 1].dxy),
                    op.c_float(-9999.))
                varsToKeep["ele{}_dz".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].dz, op.c_float(-9999.))
                varsToKeep["ele{}_ntMVAeleID".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].mvaFall17V2noIso,
                    op.c_float(-9999.))
                varsToKeep["ele{}_leptonMVA".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].mvaTTH, op.c_float(-9999.))
                varsToKeep["ele{}_passesConversionVeto".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].convVeto,
                    op.c_float(-9999., "Bool_t"))
                varsToKeep["ele{}_nMissingHits".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].lostHits,
                    op.c_float(-9999., "UChar_t"))
                varsToKeep["ele{}_sigmaEtaEta".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].sieie, op.c_float(-9999.))
                varsToKeep["ele{}_HoE".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].hoe, op.c_float(-9999.))
                varsToKeep["ele{}_OoEminusOoP".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].eInvMinusPInv,
                    op.c_float(-9999.))
                varsToKeep["ele{}_isfakeablesel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        self.lambda_electronFakeSel(self.electronsPreSel[i -
                                                                         1]),
                        op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["ele{}_ismvasel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        op.AND(
                            self.lambda_electronTightSel(
                                self.electronsPreSel[i - 1]),
                            self.lambda_electronFakeSel(
                                self.electronsPreSel[i - 1])), op.c_int(1),
                        op.c_int(0)),
                    op.c_int(-9999))  # mvasel encompasses fakeablesel
                varsToKeep["ele{}_isGenMatched".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        self.lambda_is_matched(self.electronsPreSel[i - 1]),
                        op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["ele{}_genPartFlav".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].genPartFlav, op.c_int(-9999))
                varsToKeep["ele{}_deltaEtaSC".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].deltaEtaSC, op.c_int(-9999))
                varsToKeep["ele{}_FR".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.lambda_FR_el(self.electronsPreSel[i - 1]),
                    op.c_int(-9999))
                varsToKeep["ele{}_FRcorr".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.lambda_FRcorr_el(self.electronsPreSel[i - 1]),
                    op.c_int(-9999))
                varsToKeep["ele{}_FF".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.lambda_FF_el(self.electronsPreSel[i - 1]),
                    op.c_int(-9999))
                varsToKeep["ele{}_looseSF".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    reduce(
                        mul,
                        self.lambda_ElectronLooseSF(self.electronsPreSel[i -
                                                                         1])),
                    op.c_int(-9999))
                varsToKeep["ele{}_tightSF".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    reduce(
                        mul,
                        self.lambda_ElectronTightSF(self.electronsPreSel[i -
                                                                         1])),
                    op.c_int(-9999))

            # AK4 Jets #
            for i in range(1, 5):  # 4 leading jets
                varsToKeep["ak4Jet{}_pt".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].pt,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_eta".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].eta,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_phi".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].phi,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_E".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].p4.E(),
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.ak4Jets[i - 1].btagDeepFlavB, op.c_float(-9999.))
                varsToKeep["ak4Jet{}_hadronFlavour".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.ak4Jets[i - 1].hadronFlavour, op.c_float(-9999.))
                varsToKeep["ak4Jet{}_btagSF".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.DeepJetDiscReshapingSF(self.ak4Jets[i - 1]),
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_puid_eff".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.jetpuid_mc_eff(self.ak4Jets[i - 1]),
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_puid_sfeff".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.jetpuid_sf_eff(self.ak4Jets[i - 1]),
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_puid_mis".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.jetpuid_mc_mis(self.ak4Jets[i - 1]),
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_puid_sfmis".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.jetpuid_sf_mis(self.ak4Jets[i - 1]),
                    op.c_float(-9999.))

            # VBF Jets #
            for i in range(1, 6):  # 5 leading jets
                varsToKeep["ak4JetVBF{}_pt".format(i)] = op.switch(
                    op.rng_len(self.VBFJetsPreSel) >= i,
                    self.VBFJetsPreSel[i - 1].pt, op.c_float(-9999.))
                varsToKeep["ak4JetVBF{}_eta".format(i)] = op.switch(
                    op.rng_len(self.VBFJetsPreSel) >= i,
                    self.VBFJetsPreSel[i - 1].eta, op.c_float(-9999.))
                varsToKeep["ak4JetVBF{}_phi".format(i)] = op.switch(
                    op.rng_len(self.VBFJetsPreSel) >= i,
                    self.VBFJetsPreSel[i - 1].phi, op.c_float(-9999.))
                varsToKeep["ak4JetVBF{}_E".format(i)] = op.switch(
                    op.rng_len(self.VBFJetsPreSel) >= i,
                    self.VBFJetsPreSel[i - 1].p4.E(), op.c_float(-9999.))
                varsToKeep["ak4JetVBF{}_CSV".format(i)] = op.switch(
                    op.rng_len(self.VBFJetsPreSel) >= i,
                    self.VBFJetsPreSel[i - 1].btagDeepFlavB,
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBF{}_btagSF".format(i)] = op.switch(
                    op.rng_len(self.VBFJetsPreSel) >= i,
                    self.DeepJetDiscReshapingSF(self.VBFJetsPreSel[i - 1]),
                    op.c_float(-9999.))

            if not self.inclusive_sel:
                if not any([self.args.Res0b, self.args.Ak4, self.args.Ak8]):
                    varsToKeep["ak4JetVBFPair1_pt"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][0].pt, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair1_eta"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][0].eta, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair1_phi"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][0].phi, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair1_E"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][0].p4.E(), op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair1_CSV"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][0].btagDeepFlavB, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair1_btagSF"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        self.DeepJetDiscReshapingSF(VBFJetPairsJPA[0][0]),
                        op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair2_pt"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][1].pt, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair2_eta"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][1].eta, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair2_phi"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][1].phi, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair2_E"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][1].p4.E(), op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair2_CSV"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        VBFJetPairsJPA[0][1].btagDeepFlavB, op.c_float(-9999.))
                    varsToKeep["ak4JetVBFPair2_btagSF"] = op.switch(
                        op.rng_len(VBFJetPairsJPA) >= 1,
                        self.DeepJetDiscReshapingSF(VBFJetPairsJPA[0][1]),
                        op.c_float(-9999.))
                else:
                    varsToKeep["ak4JetVBFPair1_pt"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair1_eta"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair1_phi"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair1_E"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair1_CSV"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair1_btagSF"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair2_pt"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair2_eta"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair2_phi"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair2_E"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair2_CSV"] = op.c_float(-9999.)
                    varsToKeep["ak4JetVBFPair2_btagSF"] = op.c_float(-9999.)

            # AK8 Jets #
            for i in range(1, 3):  # 2 leading fatjets
                varsToKeep["ak8Jet{}_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].pt,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].eta,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].phi,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_E".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].p4.E(), op.c_float(-9999.))
                varsToKeep["ak8Jet{}_msoftdrop".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].msoftdrop, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_tau1".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau1,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_tau2".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau2,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.pt, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.eta, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.phi, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.btagDeepB, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.pt, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.eta, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.phi, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.btagDeepB, op.c_float(-9999.))

            varsToKeep["PFMET"] = self.corrMET.pt
            varsToKeep["PFMETphi"] = self.corrMET.phi
            varsToKeep["met1_E"] = self.corrMET.p4.E()
            varsToKeep["met1_pt"] = self.corrMET.pt
            varsToKeep["met1_eta"] = self.corrMET.eta
            varsToKeep["met1_phi"] = self.corrMET.phi

            # SF #
            electronMuon_cont = op.combine(
                (self.electronsFakeSel, self.muonsFakeSel))

            varsToKeep["trigger_SF"] = op.multiSwitch(
                (op.AND(
                    op.rng_len(self.electronsTightSel) == 1,
                    op.rng_len(self.muonsTightSel) == 0),
                 self.ttH_singleElectron_trigSF(self.electronsTightSel[0])),
                (op.AND(
                    op.rng_len(self.electronsTightSel) == 0,
                    op.rng_len(self.muonsTightSel)
                    == 1), self.ttH_singleMuon_trigSF(self.muonsTightSel[0])),
                (op.AND(
                    op.rng_len(self.electronsTightSel) >= 2,
                    op.rng_len(self.muonsTightSel) == 0),
                 self.lambda_ttH_doubleElectron_trigSF(
                     self.electronsTightSel)),
                (op.AND(
                    op.rng_len(self.electronsTightSel) == 0,
                    op.rng_len(self.muonsTightSel) >= 2),
                 self.lambda_ttH_doubleMuon_trigSF(self.muonsTightSel)),
                (op.AND(
                    op.rng_len(self.electronsTightSel) >= 1,
                    op.rng_len(self.muonsTightSel) >= 1),
                 self.lambda_ttH_electronMuon_trigSF(electronMuon_cont[0])),
                op.c_float(1.))

            if not self.inclusive_sel:
                varsToKeep["weight_trigger_el_sf"] = op.switch(
                    op.rng_len(self.electronsTightSel) > 0,
                    self.ttH_singleElectron_trigSF(lep), op.c_float(1.))
                varsToKeep["weight_trigger_mu_sf"] = op.switch(
                    op.rng_len(self.muonsTightSel) > 0,
                    self.ttH_singleMuon_trigSF(lep), op.c_float(1.))

                varsToKeep["lepton_IDSF"] = op.rng_product(self.electronsFakeSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el)+self.lambda_ElectronTightSF(el))) * \
                                            op.rng_product(self.muonsFakeSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu)+self.lambda_MuonTightSF(mu)))

                varsToKeep["lepton_IDSF_recoToLoose"]  = op.rng_product(self.electronsFakeSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el))) * \
                                                        op.rng_product(self.muonsFakeSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu)))
                varsToKeep["lepton_IDSF_looseToTight"] = op.rng_product(self.electronsFakeSel, lambda el : reduce(mul,self.lambda_ElectronTightSF(el))) * \
                                                         op.rng_product(self.muonsFakeSel, lambda mu : reduce(mul,self.lambda_MuonTightSF(mu)))
                if era == "2016" or era == "2017":
                    if self.args.Channel == "El":
                        varsToKeep["weight_electron_reco_low"] = op.switch(
                            op.AND(self.lambda_is_matched(lep), lep.pt <= 20.),
                            self.elLooseRecoPtLt20(lep), op.c_float(1.))
                        varsToKeep["weight_electron_reco_high"] = op.switch(
                            op.AND(self.lambda_is_matched(lep), lep.pt > 20.),
                            self.elLooseRecoPtGt20(lep), op.c_float(1.))
                        varsToKeep["weight_muon_idiso_loose"] = op.c_float(1.)
                        varsToKeep["weight_electron_id_loose_01"] = op.switch(
                            self.lambda_is_matched(lep), self.elLooseEff(lep),
                            op.c_float(1.))
                        varsToKeep["weight_electron_id_loose_02"] = op.switch(
                            self.lambda_is_matched(lep), self.elLooseId(lep),
                            op.c_float(1.))
                        varsToKeep[
                            "weight_electron_tth_loose"] = self.lambda_ElectronTightSF(
                                lep)[0]
                        varsToKeep["weight_muon_tth_loose"] = op.c_float(1.)

                    if self.args.Channel == "Mu":
                        varsToKeep["weight_muon_idiso_loose"] = op.switch(
                            self.lambda_is_matched(lep), self.muLooseId(lep),
                            op.c_float(1.))
                        varsToKeep["weight_electron_reco_low"] = op.c_float(1.)
                        varsToKeep["weight_electron_reco_high"] = op.c_float(
                            1.)
                        varsToKeep["weight_electron_id_loose_01"] = op.c_float(
                            1.)
                        varsToKeep["weight_electron_id_loose_02"] = op.c_float(
                            1.)
                        varsToKeep["weight_electron_tth_loose"] = op.c_float(
                            1.)
                        varsToKeep[
                            "weight_muon_tth_loose"] = self.lambda_MuonTightSF(
                                lep)[0]
                else:
                    raise NotImplementedError

            # L1 Prefire #
            if era in ["2016", "2017"]:
                varsToKeep["L1prefire"] = self.L1Prefiring
                varsToKeep["weight_l1_ecal_prefiring"] = self.L1Prefiring
            else:
                varsToKeep["L1prefire"] = op.c_float(-9999.)
                varsToKeep["weight_l1_ecal_prefiring"] = op.c_float(-9999.)

            # Fake rate #
            if self.args.Channel == "El":
                varsToKeep["fakeRate"] = op.switch(
                    self.lambda_electronTightSel(self.electronsFakeSel[0]),
                    self.ElFakeFactor(self.electronsFakeSel[0]),
                    op.c_float(1.))
                varsToKeep["weight_fake_electrons"] = op.switch(
                    self.lambda_electronTightSel(self.electronsFakeSel[0]),
                    op.abs(self.ElFakeFactor(self.electronsFakeSel[0])),
                    op.c_float(1.))
                varsToKeep["weight_fake_muons"] = op.c_float(1.)
                varsToKeep["weight_fake_two_non_tight"] = op.c_float(999.0)
            if self.args.Channel == "Mu":
                varsToKeep["fakeRate"] = op.switch(
                    self.lambda_muonTightSel(self.muonsFakeSel[0]),
                    self.MuFakeFactor(self.muonsFakeSel[0]), op.c_float(1.))
                varsToKeep["weight_fake_electrons"] = op.c_float(1.)
                varsToKeep["weight_fake_muons"] = op.switch(
                    self.lambda_muonTightSel(self.muonsFakeSel[0]),
                    op.abs(self.MuFakeFactor(self.muonsFakeSel[0])),
                    op.c_float(1.))
                varsToKeep["weight_fake_two_non_tight"] = op.c_float(999.0)

            if self.is_MC:
                varsToKeep["weight_fake_is_mc"] = op.c_float(-1.)
            else:
                varsToKeep["weight_fake_is_mc"] = op.c_float(1.)

            # PU ID SF #
            varsToKeep["PU_jetID_SF"] = self.puid_reweighting
            varsToKeep[
                "weight_jet_PUid_efficiency"] = self.puid_reweighting_efficiency
            varsToKeep["weight_jet_PUid_mistag"] = self.puid_reweighting_mistag

            # Btagging SF #
            varsToKeep["btag_SF"] = self.btagAk4SF
            varsToKeep["weight_btagWeight"] = self.btagAk4SF
            if "BtagRatioWeight" in self.__dict__.keys():
                varsToKeep["btag_ratio_SF"] = self.BtagRatioWeight
                varsToKeep["weight_btagNorm"] = self.BtagRatioWeight

            # PS weights #
            varsToKeep["weight_PSWeight_ISR"] = self.psISRSyst
            varsToKeep["weight_PSWeight_FSR"] = self.psFSRSyst

            # ttbar PT reweighting #
            if "group" in sampleCfg and sampleCfg["group"] == 'ttbar':
                varsToKeep["topPt_wgt"] = self.ttbar_weight(
                    self.genTop[0], self.genAntitop[0])

        # Event Weight #
            if self.is_MC:
                varsToKeep["MC_weight"] = t.genWeight
                puWeightsFile = os.path.join(os.path.dirname(__file__), "data",
                                             "pileup",
                                             sample + '_%s.json' % era)
                #puWeightsFile = os.path.join(os.path.dirname(__file__), "data" , "pileup", sampleCfg["pufile"])
                varsToKeep["PU_weight"] = makePileupWeight(
                    puWeightsFile,
                    t.Pileup_nTrueInt,
                    nameHint=f"puweightFromFile{sample}".replace('-', '_'))
                varsToKeep[
                    "eventWeight"] = noSel.weight if self.inclusive_sel else selObj.sel.weight

            if self.inclusive_sel:
                return noSel, varsToKeep
            else:
                return selObj.sel, varsToKeep

        #---------------------------------------------------------------------------------------#
        #                                    Selection tree                                     #
        #---------------------------------------------------------------------------------------#
        #----- EVT variables -----#
        varsToKeep["event"] = None  # Already in tree
        varsToKeep["run"] = None  # Already in tree
        varsToKeep["ls"] = t.luminosityBlock

        genVarsList = self.HLL.comp_cosThetaSbetBeamAndHiggs(t.GenPart)
        varsToKeep['mHH_gen'] = genVarsList[0]
        varsToKeep['consTheta1_gen'] = genVarsList[1]
        varsToKeep['consTheta2_gen'] = genVarsList[2]

        if any([
                self.args.__dict__[item] for item in [
                    "Ak4", "Res2b2Wj", "Res2b1Wj", "Res2b0Wj", "Res1b2Wj",
                    "Res1b1Wj", "Res1b0Wj", "Res0b"
                ]
        ]):
            commonInputs_Resolved = returnCommonInputs_Resolved(self=self)
            classicInputs_Resolved = returnClassicInputs_Resolved(
                self=self,
                lepton=lep,
                jpaSelectedJets=jpaJets,
                L1out=L1out,
                L2out=L2out,
                jpaArg=jpaarg)
            inputs_resolved = {
                **commonInputs_Resolved,
                **classicInputs_Resolved
            }

            for (varname, _, _), var in inputs_resolved.items():
                varsToKeep[varname] = var

        #----- Fatjet variables -----#
        if any([
                self.args.__dict__[item]
                for item in ["Ak8", "Hbb2Wj", "Hbb1Wj", "Hbb0Wj"]
        ]):
            commonInputs_Boosted = returnCommonInputs_Boosted(self=self)
            classicInputs_Boosted = returnClassicInputs_Boosted(
                self=self,
                lepton=lep,
                jpaSelectedJets=jpaJets,
                L1out=L1out,
                L2out=L2out,
                jpaArg=jpaarg)
            inputs_boosted = {**commonInputs_Boosted, **classicInputs_Boosted}

            for (varname, _, _), var in inputs_boosted.items():
                varsToKeep[varname] = var

        #----- Additional variables -----#
        varsToKeep["MC_weight"] = t.genWeight
        varsToKeep['total_weight'] = selObj.sel.weight

        #return leptonSel.sel, varsToKeep
        return selObj.sel, varsToKeep
    def defineSkimSelection(self, t, noSel, sample=None, sampleCfg=None):
        noSel = super(SkimmerNanoHHtobbWWSL,
                      self).prepareObjects(t,
                                           noSel,
                                           sample,
                                           sampleCfg,
                                           "SL",
                                           forSkimmer=True)
        era = sampleCfg['era']
        # Initialize varsToKeep dict #
        varsToKeep = dict()
        if not self.inclusive_sel:
            jet_level = ["Resolved2Btag", "Resolved1Btag", "Boosted"]
            # Only one lepton_level must be in args and Only one jet_level must be in args
            if [
                    boolean for (level, boolean) in self.args.__dict__.items()
                    if level in jet_level
            ].count(True) != 1:
                raise RuntimeError(
                    "Only one of the jet arguments must be used, check --help")

            if self.args.Channel not in ["El", "Mu"]:
                raise RuntimeError("Channel must be either 'El' or 'Mu'")

            #----- Machine Learning Model -----#
            model_nums = ["01", "02"]
            path_model_01 = os.path.join(
                os.path.abspath(os.path.dirname(__file__)), 'MachineLearning',
                'ml-models', 'models', 'multi-classification', 'dnn', 'SL',
                model_nums[0], 'model', 'model.pb')
            path_model_02 = os.path.join(
                os.path.abspath(os.path.dirname(__file__)), 'MachineLearning',
                'ml-models', 'models', 'multi-classification', 'dnn', 'SL',
                model_nums[1], 'model', 'model.pb')
            input_names_01 = [
                "lep", "jet", "fat", "met", "hl", "param", "eventnr"
            ]
            input_names_02 = [
                "lep", "jet", "fat", "met", "nu", "hl", "param", "eventnr"
            ]
            output_name = "Identity"

            if not self.args.OnlyYield:
                print("DNN model : %s" % path_model_02)
                if not os.path.exists(path_model_02):
                    raise RuntimeError('Could not find model file %s' %
                                       path_model_02)
                try:
                    DNN_02 = op.mvaEvaluator(path_model_02,
                                             mvaType='Tensorflow',
                                             otherArgs=(input_names_02,
                                                        output_name))
                except:
                    raise RuntimeError('Could not load model %s' %
                                       path_model_02)

            self.nodes = ['GGF', 'VBF', 'TT', 'ST', 'WJets', 'H', 'Other']

            #----- Lepton selection -----#
            # Args are passed within the self #
            #ElSelObj, MuSelObj = makeSingleLeptonSelection(self,noSel,use_dd=False)
            ElSelObj, MuSelObj = makeSingleLeptonSelection(
                self, noSel, use_dd=False, fake_selection=self.args.FakeCR)

            # --- apply jet correction --- #
            ElSelObj.sel = self.beforeJetselection(ElSelObj.sel, 'El')
            MuSelObj.sel = self.beforeJetselection(MuSelObj.sel, 'Mu')

            if self.args.Channel == "El":
                selObj = ElSelObj
                #lepton = self.electronsTightSel[0]
                lepton = self.electronsFakeSel[0]
                lepconep4 = self.getElectronConeP4(lepton)

            if self.args.Channel == "Mu":
                selObj = MuSelObj
                #lepton = self.muonsTightSel[0]
                lepton = self.muonsFakeSel[0]
                lepconep4 = self.getMuonConeP4(lepton)

            #----- Jet selection -----#
            # Since the selections in one line, we can use the non copy option of the selection to modify the selection object internally
            if any([
                    self.args.__dict__[item]
                    for item in ["Resolved2Btag", "Resolved1Btag"]
            ]):
                makeResolvedSelection(self, selObj)
                #VBFJetPairs = mvaEvaluatorSL_nonres_DNN01.VBFJetPairs_Resolved(self)
                VBFJetPairs = self.VBFJetPairsResolved
                if self.args.Resolved2Btag:
                    makeExclusiveResolvedSelection(self, selObj, nbJet=2)
                    print('Resolved2Btag')

                if self.args.Resolved1Btag:
                    makeExclusiveResolvedSelection(self, selObj, nbJet=1)
                    print('Resolved1Btag')

            if self.args.Boosted:
                makeBoostedSelection(self, selObj)
                #VBFJetPairs = mvaEvaluatorSL_nonres_DNN01.VBFJetPairs_Boosted(self)
                VBFJetPairs = self.VBFJetPairsBoosted
                print('BoostedHbb')

        else:
            noSel = self.beforeJetselection(noSel)

        #---------------------------------------------------------------------------------------#
        #                                Synchronization tree                                   #
        #---------------------------------------------------------------------------------------#
        if self.args.Synchronization:
            # Event variables #
            varsToKeep["event"] = None  # Already in tree
            varsToKeep["run"] = None  # Already in tree
            varsToKeep["ls"] = t.luminosityBlock

            varsToKeep["n_presel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsPreSel))
            varsToKeep["n_fakeablesel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsFakeSel))
            varsToKeep["n_tightsel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsTightSel))
            varsToKeep["n_presel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsPreSel))
            varsToKeep["n_fakeablesel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsFakeSel))
            varsToKeep["n_tightsel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsTightSel))

            varsToKeep["n_ak4Jet"] = op.static_cast("UInt_t",
                                                    op.rng_len(self.ak4Jets))

            varsToKeep["n_ak8Jet"] = op.static_cast("UInt_t",
                                                    op.rng_len(self.ak8Jets))
            varsToKeep["n_presel_ak8BJet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak8BJets))
            varsToKeep["n_loose_ak4BJet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4BJetsLoose))
            varsToKeep["n_medium_ak4BJet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4BJets))
            varsToKeep["n_ak4JetsCleanAk8b"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4JetsCleanedFromAk8b))
            varsToKeep["n_presel_ak4JetVBF"] = op.static_cast(
                "UInt_t", op.rng_len(self.VBFJetsPreSel))

            #varsToKeep["is_SR"]             = op.static_cast("UInt_t",op.OR(op.rng_len(self.electronsTightSel)==1,
            #                                                                op.rng_len(self.muonsTightSel)==1))

            varsToKeep["is_e_SR_prompt"] = op.switch(
                op.rng_len(self.electronsTightSel) == 1, op.c_bool(True),
                op.c_bool(False))
            varsToKeep["is_m_SR_prompt"] = op.switch(
                op.rng_len(self.muonsTightSel) == 1, op.c_bool(True),
                op.c_bool(False))
            varsToKeep["is_e_FR_prompt"] = op.switch(
                op.AND(
                    op.rng_len(self.electronsFakeSel) > 0,
                    op.AND(
                        self.lambda_is_matched(self.electronsFakeSel[0]),
                        op.NOT(
                            self.lambda_electronTightSel(
                                self.electronsFakeSel[0])))), op.c_bool(True),
                op.c_bool(False))
            varsToKeep["is_m_FR_prompt"] = op.switch(
                op.AND(
                    op.rng_len(self.muonsFakeSel) > 0,
                    op.AND(
                        self.lambda_is_matched(self.muonsFakeSel[0]),
                        op.NOT(self.lambda_muonTightSel(
                            self.muonsFakeSel[0])))), op.c_bool(True),
                op.c_bool(False))

            varsToKeep["is_resolved"] = op.switch(
                op.AND(
                    op.rng_len(self.ak4Jets) >= 3,
                    op.rng_len(self.ak4BJets) >= 1,
                    op.rng_len(self.ak8BJets) == 0), op.c_bool(True),
                op.c_bool(False))
            varsToKeep["is_boosted"] = op.switch(
                op.AND(
                    op.rng_len(self.ak8BJets) >= 1,
                    op.rng_len(self.ak4JetsCleanedFromAk8b) >= 1),
                op.c_bool(True), op.c_bool(False))

            varsToKeep["is_resolved_1b"] = op.switch(
                op.AND(
                    op.rng_len(self.ak4Jets) >= 3,
                    op.rng_len(self.ak4BJets) == 1,
                    op.rng_len(self.ak8BJets) == 0), op.c_bool(True),
                op.c_bool(False))
            varsToKeep["is_resolved_2b"] = op.switch(
                op.AND(
                    op.rng_len(self.ak4Jets) >= 3,
                    op.rng_len(self.ak4BJets) >= 2,
                    op.rng_len(self.ak8BJets) == 0), op.c_bool(True),
                op.c_bool(False))

            varsToKeep["n_tau"] = op.static_cast("UInt_t",
                                                 op.rng_len(self.tauCleanSel))

            #varsToKeep['resolved_tag']  = op.static_cast("UInt_t",op.AND(op.rng_len(self.ak4Jets) >= 3,
            #                                                             op.rng_len(self.ak4BJets) >= 1,
            #                                                             op.rng_len(self.ak8BJets) == 0))
            #varsToKeep['boosted_tag']   = op.static_cast("UInt_t",op.AND(op.rng_len(self.ak8BJets) >= 1,op.rng_len(self.ak4JetsCleanedFromAk8b) >= 1))

            # Triggers #
            '''
            varsToKeep["triggers"]                  = self.triggers
            varsToKeep["triggers_SingleElectron"]   = op.OR(*self.triggersPerPrimaryDataset['SingleElectron'])
            varsToKeep["triggers_SingleMuon"]       = op.OR(*self.triggersPerPrimaryDataset['SingleMuon'])
            varsToKeep["triggers_DoubleElectron"]   = op.OR(*self.triggersPerPrimaryDataset['DoubleEGamma'])
            varsToKeep["triggers_DoubleMuon"]       = op.OR(*self.triggersPerPrimaryDataset['DoubleMuon'])
            varsToKeep["triggers_MuonElectron"]     = op.OR(*self.triggersPerPrimaryDataset['MuonEG'])
            '''
            # Muons #

            for i in range(1, 3):  # 2 leading muons
                varsToKeep["mu{}_pt".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].pt, op.c_float(-9999., "float"))
                varsToKeep["mu{}_eta".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].eta, op.c_float(-9999.))
                varsToKeep["mu{}_phi".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].phi, op.c_float(-9999.))
                varsToKeep["mu{}_E".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].p4.E(),
                    op.c_float(-9999., "float"))
                varsToKeep["mu{}_charge".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].charge, op.c_int(-9999.))
                varsToKeep["mu{}_conept".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muon_conept[self.muonsPreSel[i - 1].idx],
                    op.c_float(-9999.))
                varsToKeep["mu{}_miniRelIso".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].miniPFRelIso_all,
                    op.c_float(-9999.))
                varsToKeep["mu{}_PFRelIso04".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].pfRelIso04_all, op.c_float(-9999.))
                varsToKeep["mu{}_jetNDauChargedMVASel".format(i)] = op.c_float(
                    -9999.)
                varsToKeep["mu{}_jetPtRel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.))
                varsToKeep["mu{}_jetRelIso".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jetRelIso, op.c_float(-9999.))
                varsToKeep["mu{}_jetDeepJet".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jet.btagDeepFlavB,
                    op.c_float(-9999.))
                varsToKeep["mu{}_sip3D".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].sip3d, op.c_float(-9999.))
                varsToKeep["mu{}_dxy".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].dxy, op.c_float(-9999.))
                varsToKeep["mu{}_dxyAbs".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.abs(self.muonsPreSel[i - 1].dxy), op.c_float(-9999.))
                varsToKeep["mu{}_dz".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].dz, op.c_float(-9999.))
                varsToKeep["mu{}_segmentCompatibility".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].segmentComp, op.c_float(-9999.))
                varsToKeep["mu{}_leptonMVA".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].mvaTTH, op.c_float(-9999.))
                varsToKeep["mu{}_mediumID".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].mediumId,
                    op.c_float(-9999., "Bool_t"))
                varsToKeep["mu{}_dpt_div_pt".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].tunepRelPt,
                    op.c_float(-9999.))  # Not sure
                varsToKeep["mu{}_isfakeablesel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(self.lambda_muonFakeSel(self.muonsPreSel[i - 1]),
                              op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["mu{}_ismvasel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(
                        op.AND(
                            self.lambda_muonTightSel(self.muonsPreSel[i - 1]),
                            self.lambda_muonFakeSel(self.muonsPreSel[i - 1])),
                        op.c_int(1), op.c_int(0)),
                    op.c_int(-9999))  # mvasel encompasses fakeablesel
                varsToKeep["mu{}_isGenMatched".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(self.lambda_is_matched(self.muonsPreSel[i - 1]),
                              op.c_int(1), op.c_int(0)), op.c_int(-9999))
                '''
                varsToKeep["mu{}_genPartFlav".format(i)]           = op.switch(op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i-1].genPartFlav, op.c_int(-9999))
                varsToKeep["mu{}_FR".format(i)]                    = op.switch(op.rng_len(self.muonsPreSel) >= i, self.lambda_FR_mu(self.muonsPreSel[i-1]), op.c_int(-9999))
                varsToKeep["mu{}_FRcorr".format(i)]                = op.switch(op.rng_len(self.muonsPreSel) >= i, self.lambda_FRcorr_mu(self.muonsPreSel[i-1]), op.c_int(-9999))
                varsToKeep["mu{}_FF".format(i)]                    = op.switch(op.rng_len(self.muonsPreSel) >= i, self.lambda_FF_mu(self.muonsPreSel[i-1]), op.c_int(-9999))
                varsToKeep["mu{}_looseSF".format(i)]               = op.switch(op.rng_len(self.muonsPreSel) >= i, reduce(mul,self.lambda_MuonLooseSF(self.muonsPreSel[i-1])), op.c_int(-9999))
                varsToKeep["mu{}_tightSF".format(i)]               = op.switch(op.rng_len(self.muonsPreSel) >= i, reduce(mul,self.lambda_MuonTightSF(self.muonsPreSel[i-1])), op.c_int(-9999))
                '''
            # Electrons #
            for i in range(1, 3):  # 2 leading electrons
                varsToKeep["ele{}_pt".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].pt, op.c_float(-9999.))
                varsToKeep["ele{}_eta".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].eta, op.c_float(-9999.))
                varsToKeep["ele{}_phi".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].phi, op.c_float(-9999.))
                varsToKeep["ele{}_E".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].p4.E(), op.c_float(-9999., ))
                varsToKeep["ele{}_charge".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].charge, op.c_int(-9999.))
                varsToKeep["ele{}_conept".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electron_conept[self.electronsPreSel[i - 1].idx],
                    op.c_float(-9999.))
                varsToKeep["ele{}_miniRelIso".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].miniPFRelIso_all,
                    op.c_float(-9999.))
                varsToKeep["ele{}_PFRelIso03".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].pfRelIso03_all,
                    op.c_float(-9999.))  # Iso03, Iso04 not in NanoAOD
                varsToKeep["ele{}_jetNDauChargedMVASel".format(
                    i)] = op.c_float(-9999.)
                varsToKeep["ele{}_jetPtRel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.))
                varsToKeep["ele{}_jetRelIso".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jetRelIso, op.c_float(-9999.))
                varsToKeep["ele{}_jetDeepJet".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jet.btagDeepFlavB,
                    op.c_float(-9999.))
                varsToKeep["ele{}_sip3D".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].sip3d, op.c_float(-9999.))

                varsToKeep["ele{}_dxy".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].dxy, op.c_float(-9999.))
                varsToKeep["ele{}_dxyAbs".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.abs(self.electronsPreSel[i - 1].dxy),
                    op.c_float(-9999.))
                varsToKeep["ele{}_dz".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].dz, op.c_float(-9999.))
                varsToKeep["ele{}_ntMVAeleID".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].mvaFall17V2noIso,
                    op.c_float(-9999.))
                varsToKeep["ele{}_leptonMVA".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].mvaTTH, op.c_float(-9999.))
                varsToKeep["ele{}_passesConversionVeto".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].convVeto,
                    op.c_float(-9999., "Bool_t"))
                varsToKeep["ele{}_nMissingHits".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].lostHits,
                    op.c_float(-9999., "UChar_t"))
                varsToKeep["ele{}_sigmaEtaEta".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].sieie, op.c_float(-9999.))
                varsToKeep["ele{}_HoE".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].hoe, op.c_float(-9999.))
                varsToKeep["ele{}_OoEminusOoP".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].eInvMinusPInv,
                    op.c_float(-9999.))
                varsToKeep["ele{}_isfakeablesel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        self.lambda_electronFakeSel(self.electronsPreSel[i -
                                                                         1]),
                        op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["ele{}_ismvasel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        op.AND(
                            self.lambda_electronTightSel(
                                self.electronsPreSel[i - 1]),
                            self.lambda_electronFakeSel(
                                self.electronsPreSel[i - 1])), op.c_int(1),
                        op.c_int(0)),
                    op.c_int(-9999))  # mvasel encompasses fakeablesel
                varsToKeep["ele{}_isGenMatched".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        self.lambda_is_matched(self.electronsPreSel[i - 1]),
                        op.c_int(1), op.c_int(0)), op.c_int(-9999))
                '''
                varsToKeep["ele{}_genPartFlav".format(i)]           = op.switch(op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i-1].genPartFlav, op.c_int(-9999))
                varsToKeep["ele{}_deltaEtaSC".format(i)]            = op.switch(op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i-1].deltaEtaSC, op.c_int(-9999))
                varsToKeep["ele{}_FR".format(i)]                    = op.switch(op.rng_len(self.electronsPreSel) >= i, self.lambda_FR_el(self.electronsPreSel[i-1]), op.c_int(-9999))
                varsToKeep["ele{}_FRcorr".format(i)]                = op.switch(op.rng_len(self.electronsPreSel) >= i, self.lambda_FRcorr_el(self.electronsPreSel[i-1]), op.c_int(-9999))
                varsToKeep["ele{}_FF".format(i)]                    = op.switch(op.rng_len(self.electronsPreSel) >= i, self.lambda_FF_el(self.electronsPreSel[i-1]), op.c_int(-9999))
                varsToKeep["ele{}_looseSF".format(i)]               = op.switch(op.rng_len(self.electronsPreSel) >= i, reduce(mul,self.lambda_ElectronLooseSF(self.electronsPreSel[i-1])), op.c_int(-9999))
                varsToKeep["ele{}_tightSF".format(i)]               = op.switch(op.rng_len(self.electronsPreSel) >= i, reduce(mul,self.lambda_ElectronTightSF(self.electronsPreSel[i-1])), op.c_int(-9999))
                '''
            # AK4 Jets #
            for i in range(1, 5):  # 4 leading jets
                varsToKeep["ak4Jet{}_pt".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].pt,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_eta".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].eta,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_phi".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].phi,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_E".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].p4.E(),
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.ak4Jets[i - 1].btagDeepFlavB, op.c_float(-9999.))
                #varsToKeep["ak4Jet{}_hadronFlavour".format(i)]      = op.switch(op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i-1].hadronFlavour, op.c_float(-9999.))
                #varsToKeep["ak4Jet{}_btagSF".format(i)]             = op.switch(op.rng_len(self.ak4Jets) >= i, self.DeepJetDiscReshapingSF(self.ak4Jets[i-1]), op.c_float(-9999.))
                #varsToKeep["ak4Jet{}_puid_eff".format(i)]           = op.switch(op.rng_len(self.ak4Jets) >= i, self.jetpuid_mc_eff(self.ak4Jets[i-1]), op.c_float(-9999.))
                #varsToKeep["ak4Jet{}_puid_sfeff".format(i)]         = op.switch(op.rng_len(self.ak4Jets) >= i, self.jetpuid_sf_eff(self.ak4Jets[i-1]), op.c_float(-9999.))
                #varsToKeep["ak4Jet{}_puid_mis".format(i)]           = op.switch(op.rng_len(self.ak4Jets) >= i, self.jetpuid_mc_mis(self.ak4Jets[i-1]), op.c_float(-9999.))
                #varsToKeep["ak4Jet{}_puid_sfmis".format(i)]         = op.switch(op.rng_len(self.ak4Jets) >= i, self.jetpuid_sf_mis(self.ak4Jets[i-1]), op.c_float(-9999.))

            # VBF Jets #
            if not self.inclusive_sel:
                varsToKeep["ak4JetVBFPair1_pt"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][0].pt,
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBFPair1_eta"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][0].eta,
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBFPair1_phi"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][0].phi,
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBFPair1_E"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][0].p4.E(),
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBFPair2_pt"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][1].pt,
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBFPair2_eta"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][1].eta,
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBFPair2_phi"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][1].phi,
                    op.c_float(-9999.))
                varsToKeep["ak4JetVBFPair2_E"] = op.switch(
                    op.rng_len(VBFJetPairs) >= 1, VBFJetPairs[0][1].p4.E(),
                    op.c_float(-9999.))
                '''
                # inputs : 
                inputsLeps = mvaEvaluatorSL_nonres_DNN01.returnLeptonsMVAInputs (self  = self, lep  = lepton)
                inputsJets = mvaEvaluatorSL_nonres_DNN01.returnJetsMVAInputs    (self  = self, bjets = self.bJetsByScore, jets = self.probableWJets)
                inputsMET = mvaEvaluatorSL_nonres_DNN01.returnMETMVAInputs      (self  = self, met  = self.corrMET)
                inputsFatjet = mvaEvaluatorSL_nonres_DNN01.returnFatjetMVAInputs(self  = self, fatjets = self.ak8Jets)
                inputsHL = mvaEvaluatorSL_nonres_DNN01.returnHighLevelMVAInputs (self  = self,
                                                                                 lep   = lepton,
                                                                                 bjets = self.bJetsByScore,
                                                                                 wjets = self.wJetsByPt,
                                                                                 VBFJetPairs = VBFJetPairs,
                                                                                 channel   = self.args.Channel)
                inputsParam   = mvaEvaluatorSL_nonres_DNN01.returnParamMVAInputs    (self)
                inputsEventNr = mvaEvaluatorSL_nonres_DNN01.returnEventNrMVAInputs  (self,t)

                inputDict = {**inputsLeps, **inputsJets, **inputsMET, **inputsFatjet, **inputsHL} 

                for (varname,_,_),var in inputDict.items():
                    varsToKeep[varname] = var

                from  mvaEvaluatorSL_nonres_DNN01 import inputStaticCast

                inputs = [op.array("double",*inputStaticCast(inputsLeps,"float")),
                          op.array("double",*inputStaticCast(inputsJets,"float")),
                          op.array("double",*inputStaticCast(inputsFatjet,"float")),
                          op.array("double",*inputStaticCast(inputsMET,"float")),
                          op.array("double",*inputStaticCast(inputsHL,"float")),
                          op.array("double",*inputStaticCast(inputsParam,"float")),
                          op.array("long",*inputStaticCast(inputsEventNr,"long"))]
                
                output_01 = DNN_01(*inputs)
                
                for node, output in zip(self.nodes,output_01):
                    varsToKeep['DNN_node_'+node] = output
                '''
            # AK8 Jets #
            for i in range(1, 3):  # 2 leading fatjets
                varsToKeep["ak8Jet{}_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].pt,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].eta,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].phi,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_E".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].p4.E(), op.c_float(-9999.))
                varsToKeep["ak8Jet{}_msoftdrop".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].msoftdrop, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_tau1".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau1,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_tau2".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau2,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.pt, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.eta, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.phi, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.btagDeepB, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.pt, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.eta, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.phi, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.btagDeepB, op.c_float(-9999.))

            varsToKeep["PFMET"] = self.corrMET.pt
            varsToKeep["PFMETphi"] = self.corrMET.phi
            varsToKeep["met1_E"] = self.corrMET.p4.E()
            varsToKeep["met1_pt"] = self.corrMET.pt
            varsToKeep["met1_eta"] = self.corrMET.eta
            varsToKeep["met1_phi"] = self.corrMET.phi

            # SF #
            electronMuon_cont = op.combine(
                (self.electronsFakeSel, self.muonsFakeSel))
            '''
            varsToKeep["trigger_SF"] = op.multiSwitch(
                (op.AND(op.rng_len(self.electronsTightSel)==1,op.rng_len(self.muonsTightSel)==0) , self.ttH_singleElectron_trigSF(self.electronsTightSel[0])),
                (op.AND(op.rng_len(self.electronsTightSel)==0,op.rng_len(self.muonsTightSel)==1) , self.ttH_singleMuon_trigSF(self.muonsTightSel[0])),
                (op.AND(op.rng_len(self.electronsTightSel)>=2,op.rng_len(self.muonsTightSel)==0) , self.lambda_ttH_doubleElectron_trigSF(self.electronsTightSel)),
                (op.AND(op.rng_len(self.electronsTightSel)==0,op.rng_len(self.muonsTightSel)>=2) , self.lambda_ttH_doubleMuon_trigSF(self.muonsTightSel)),
                (op.AND(op.rng_len(self.electronsTightSel)>=1,op.rng_len(self.muonsTightSel)>=1) , self.lambda_ttH_electronMuon_trigSF(electronMuon_cont[0])),
                op.c_float(1.))

            if not self.inclusive_sel:
                #varsToKeep["weight_trigger_el_sf"] = op.switch(op.rng_len(self.electronsTightSel)>0, self.ttH_singleElectron_trigSF(lepton),op.c_float(1.))
                #varsToKeep["weight_trigger_mu_sf"] = op.switch(op.rng_len(self.muonsTightSel)>0, self.ttH_singleMuon_trigSF(lepton),op.c_float(1.))

                varsToKeep["lepton_IDSF"] = op.rng_product(self.electronsFakeSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el)+self.lambda_ElectronTightSF(el))) * \
                                            op.rng_product(self.muonsFakeSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu)+self.lambda_MuonTightSF(mu))) 
                
                varsToKeep["lepton_IDSF_recoToLoose"]  = op.rng_product(self.electronsFakeSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el))) * \
                                                        op.rng_product(self.muonsFakeSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu)))
                varsToKeep["lepton_IDSF_looseToTight"] = op.rng_product(self.electronsFakeSel, lambda el : reduce(mul,self.lambda_ElectronTightSF(el))) * \
                                                         op.rng_product(self.muonsFakeSel, lambda mu : reduce(mul,self.lambda_MuonTightSF(mu)))

                if era == "2016" or era == "2017": 
                    if self.args.Channel == "El":
                        varsToKeep["weight_electron_reco_low"]    = op.switch(op.AND(self.lambda_is_matched(lepton),lepton.pt<=20.), self.elLooseRecoPtLt20(lepton), op.c_float(1.))
                        varsToKeep["weight_electron_reco_high"]   = op.switch(op.AND(self.lambda_is_matched(lepton),lepton.pt>20.), self.elLooseRecoPtGt20(lepton), op.c_float(1.))
                        varsToKeep["weight_muon_idiso_loose"]     = op.c_float(1.)
                        varsToKeep["weight_electron_id_loose_01"] = op.switch(self.lambda_is_matched(lepton), self.elLooseEff(lepton), op.c_float(1.))
                        varsToKeep["weight_electron_id_loose_02"] = op.switch(self.lambda_is_matched(lepton), self.elLooseId(lepton),  op.c_float(1.))
                        varsToKeep["weight_electron_tth_loose"]   = self.lambda_ElectronTightSF(lepton)[0]
                        varsToKeep["weight_muon_tth_loose"]       = op.c_float(1.)

                    if self.args.Channel == "Mu":
                        varsToKeep["weight_muon_idiso_loose"]     = op.switch(self.lambda_is_matched(lepton), self.muLooseId(lepton), op.c_float(1.))
                        varsToKeep["weight_electron_reco_low"]    = op.c_float(1.)
                        varsToKeep["weight_electron_reco_high"]   = op.c_float(1.)
                        varsToKeep["weight_electron_id_loose_01"] = op.c_float(1.)
                        varsToKeep["weight_electron_id_loose_02"] = op.c_float(1.)
                        varsToKeep["weight_electron_tth_loose"]   = op.c_float(1.)
                        varsToKeep["weight_muon_tth_loose"]       = self.lambda_MuonTightSF(lepton)[0]
                else:
                    raise NotImplementedError

            # L1 Prefire #
            if era in ["2016","2017"]:
                varsToKeep["L1prefire"] = self.L1Prefiring
                varsToKeep["weight_l1_ecal_prefiring"] = self.L1Prefiring
            else:
                varsToKeep["L1prefire"] = op.c_float(-9999.)
                varsToKeep["weight_l1_ecal_prefiring"] = op.c_float(-9999.)

            # Fake rate #
            if self.args.Channel == "El":
                varsToKeep["fakeRate"]                  = op.switch(self.lambda_electronTightSel(self.electronsFakeSel[0]), self.ElFakeFactor(self.electronsFakeSel[0]), op.c_float(1.))
                varsToKeep["weight_fake_electrons"]     = op.switch(self.lambda_electronTightSel(self.electronsFakeSel[0]), op.abs(self.ElFakeFactor(self.electronsFakeSel[0])), op.c_float(1.))
                varsToKeep["weight_fake_muons"]         = op.c_float(1.)
                varsToKeep["weight_fake_two_non_tight"] = op.c_float(999.0)
            if self.args.Channel == "Mu":
                varsToKeep["fakeRate"]                  = op.switch(self.lambda_muonTightSel(self.muonsFakeSel[0]), self.MuFakeFactor(self.muonsFakeSel[0]), op.c_float(1.))
                varsToKeep["weight_fake_electrons"]     = op.c_float(1.)
                varsToKeep["weight_fake_muons"]         = op.switch(self.lambda_muonTightSel(self.muonsFakeSel[0]), op.abs(self.MuFakeFactor(self.muonsFakeSel[0])), op.c_float(1.))
                varsToKeep["weight_fake_two_non_tight"] = op.c_float(999.0)

            if self.is_MC:
                varsToKeep["weight_fake_is_mc"] = op.c_float(-1.)
            else:
                varsToKeep["weight_fake_is_mc"] = op.c_float(1.)

            # PU ID SF #
            #varsToKeep["PU_jetID_SF"]                = self.puid_reweighting
            #varsToKeep["weight_jet_PUid_efficiency"] = self.puid_reweighting_efficiency
            #varsToKeep["weight_jet_PUid_mistag"]     = self.puid_reweighting_mistag

            # Btagging SF #
            varsToKeep["btag_SF"]           = self.btagAk4SF
            varsToKeep["weight_btagWeight"] = self.btagAk4SF
            if "BtagRatioWeight" in self.__dict__.keys():
                varsToKeep["btag_ratio_SF"]   = self.BtagRatioWeight
                varsToKeep["weight_btagNorm"] = self.BtagRatioWeight

            # PS weights #
            varsToKeep["weight_PSWeight_ISR"] = self.psISRSyst
            varsToKeep["weight_PSWeight_FSR"] = self.psFSRSyst
            '''
            # ttbar PT reweighting #
            if "group" in sampleCfg and sampleCfg["group"] == 'ttbar':
                varsToKeep["topPt_wgt"] = self.ttbar_weight(
                    self.genTop[0], self.genAntitop[0])

        # Event Weight #
            if self.is_MC:
                varsToKeep["MC_weight"] = t.genWeight
                puWeightsFile = os.path.join(os.path.dirname(__file__), "data",
                                             "pileup",
                                             sample + '_%s.json' % era)
                #puWeightsFile = os.path.join(os.path.dirname(__file__), "data" , "pileup", sampleCfg["pufile"])
                varsToKeep["PU_weight"] = makePileupWeight(
                    puWeightsFile,
                    t.Pileup_nTrueInt,
                    nameHint=f"puweightFromFile{sample}".replace('-', '_'))
                varsToKeep[
                    "eventWeight"] = noSel.weight if self.inclusive_sel else selObj.sel.weight

            if self.inclusive_sel:
                return noSel, varsToKeep
            else:
                return selObj.sel, varsToKeep

        #---------------------------------------------------------------------------------------#
        #                                    Selection tree                                     #
        #---------------------------------------------------------------------------------------#
        #----- EVT variables -----#
        varsToKeep["event"] = None  # Already in tree
        varsToKeep["run"] = None  # Already in tree
        varsToKeep["ls"] = t.luminosityBlock
        '''
        inputsLeps   = mva02.returnLeptonsMVAInputs   (self  = self, lep  = lepton)
        inputsJets   = mva02.returnJetsMVAInputs      (self  = self, bjets = self.bJetsByScore, jets = self.probableWJets)
        inputsMET    = mva02.returnMETMVAInputs       (self  = self, met  = self.corrMET)
        inputsFatjet = mva02.returnFatjetMVAInputs    (self  = self, fatbjets = self.ak8BJets)
        inputNeu     = mva02.returnNuMVAInputs        (self  = self)
        inputsHL     = mva02.returnHighLevelMVAInputs (self  = self,
                                                       lep   = lepton,
                                                       bjets = self.bJetsByScore,
                                                       wjets = self.wJetsByPt,
                                                       VBFJetPairs = VBFJetPairs,
                                                       channel   = self.args.Channel)
        inputsParam   = mva02.returnParamMVAInputs    (self)
        inputsEventNr = mva02.returnEventNrMVAInputs  (self,t)
        '''

        inputsLeps = mva02.returnLeptonsMVAInputs(self=self,
                                                  lep=lepton,
                                                  conep4=lepconep4)
        inputsJets = mva02.returnJetsMVAInputs(self=self,
                                               bjets=self.bJetsByScore,
                                               jets=self.probableWJets)
        inputsMET = mva02.returnMETMVAInputs(self=self, met=self.corrMET)
        inputsFatjet = mva02.returnFatjetMVAInputs(self=self,
                                                   fatbjets=self.ak8BJets)
        inputNeu = mva02.returnNuMVAInputs(self=self)
        inputsHL = mva02.returnHighLevelMVAInputs(self=self,
                                                  lep=lepton,
                                                  conep4=lepconep4,
                                                  bjets=self.bJetsByScore,
                                                  wjets=self.wJetsByPt,
                                                  VBFJetPairs=VBFJetPairs,
                                                  channel=self.args.Channel)
        inputsParam = mva02.returnParamMVAInputs(self)
        inputsEventNr = mva02.returnEventNrMVAInputs(self, t)

        inputDict = {
            **inputsLeps,
            **inputsJets,
            **inputsFatjet,
            **inputsMET,
            **inputNeu,
            **inputsHL,
            **inputsParam,
            **inputsEventNr
        }

        for (varname, _, _), var in inputDict.items():
            varsToKeep[varname] = var

        #from  mvaEvaluatorSL_nonres_DNN01 import inputStaticCast

        inputs = [
            op.array("double", *mva02.inputStaticCast(inputsLeps, "float")),
            op.array("double", *mva02.inputStaticCast(inputsJets, "float")),
            op.array("double", *mva02.inputStaticCast(inputsFatjet, "float")),
            op.array("double", *mva02.inputStaticCast(inputsMET, "float")),
            op.array("double", *mva02.inputStaticCast(inputNeu, "float")),
            op.array("double", *mva02.inputStaticCast(inputsHL, "float")),
            op.array("double", *mva02.inputStaticCast(inputsParam, "float")),
            op.array("long", *mva02.inputStaticCast(inputsEventNr, "long"))
        ]

        output_02 = DNN_02(*inputs)

        for node, output in zip(self.nodes, output_02):
            varsToKeep['DNN_node_' + node] = output

        #----- Additional variables -----#
        varsToKeep["MC_weight"] = t.genWeight
        varsToKeep['total_weight'] = selObj.sel.weight

        #return leptonSel.sel, varsToKeep
        return selObj.sel, varsToKeep
Example #5
0
    def defineSkimSelection(self, t, noSel, sample=None, sampleCfg=None): 
        noSel = super(SkimmerMEMNanoHHtobbWWDL,self).prepareObjects(t, noSel, sample, sampleCfg, "DL", forSkimmer=True)
            # For the Skimmer, SF must not use defineOnFirstUse -> segmentation fault

        era = sampleCfg['era'] 

        # Initialize varsToKeep dict #
        varsToKeep = dict()  

        if self.inclusive_sel:
            raise RuntimeError("Inclusive analysis not possible")

        #---------------------------------------------------------------------------------------# 
        #                                     Selections                                        #
        #---------------------------------------------------------------------------------------#
        #----- Check arguments -----#
        jet_level = ["Resolved0Btag","Resolved1Btag","Resolved2Btag","Boosted0Btag","Boosted1Btag"] # Only one must be in args

        if [boolean for (level,boolean) in self.args.__dict__.items() if level in jet_level].count(True) != 1:
            raise RuntimeError("Only one of the jet arguments must be used, check --help")
        if self.args.Channel not in ["ElEl","MuMu","ElMu"]:
            raise RuntimeError("Channel must be either 'ElEl', 'MuMu' or 'ElMu'")

        #----- Lepton selection -----#
        # Args are passed within the self #
        ElElSelObj,MuMuSelObj,ElMuSelObj = makeDoubleLeptonSelection(self,noSel,use_dd=False,fake_selection=self.args.FakeCR)
        if self.args.Channel == "ElEl":
            selObj = ElElSelObj
            dilepton = self.ElElFakeSel[0]
        if self.args.Channel == "MuMu":
            selObj = MuMuSelObj
            dilepton = self.MuMuFakeSel[0]
        if self.args.Channel == "ElMu":
            selObj = ElMuSelObj
            dilepton = self.ElMuFakeSel[0]

        #----- Jet selection -----#
        # Since the selections in one line, we can use the non copy option of the selection to modify the selection object internally
        if any([self.args.__dict__[item] for item in ["Ak4","Resolved0Btag","Resolved1Btag","Resolved2Btag"]]):
            makeAtLeastTwoAk4JetSelection(self,selObj,use_dd=False) 
        if any([self.args.__dict__[item] for item in ["Ak8","Boosted0Btag","Boosted1Btag"]]):
           makeAtLeastOneAk8JetSelection(self,selObj,use_dd=False) 
        if self.args.Resolved0Btag:
            makeExclusiveResolvedNoBtagSelection(self,selObj,use_dd=False)
        if self.args.Resolved1Btag:
            makeExclusiveResolvedOneBtagSelection(self,selObj,use_dd=False)
        if self.args.Resolved2Btag:
            makeExclusiveResolvedTwoBtagsSelection(self,selObj,use_dd=False)
        if self.args.Boosted0Btag:
            makeInclusiveBoostedNoBtagSelection(self,selObj,use_dd=False)
        if self.args.Boosted1Btag:
            makeInclusiveBoostedOneBtagSelection(self,selObj,use_dd=False)


        #---------------------------------------------------------------------------------------# 
        #                                    Selection tree                                     #
        #---------------------------------------------------------------------------------------#

        #----- MET variables -----#
        MET = self.corrMET

        varsToKeep['met_pt']  = MET.pt
        varsToKeep['met_phi']  = MET.phi
        varsToKeep['met_E'] = MET.p4.E()
        varsToKeep['met_Px'] = MET.p4.Px()
        varsToKeep['met_Py'] = MET.p4.Py()
        varsToKeep['met_Pz'] = MET.p4.Pz()

        #----- Lepton variables -----#
        if self.args.Channel is None:
            raise RuntimeError("You need to specify --Channel")
        if self.args.Channel == "ElEl": dilepton = self.ElElTightSel[0]
        if self.args.Channel == "MuMu": dilepton = self.MuMuTightSel[0]
        if self.args.Channel == "ElMu": dilepton = self.ElMuTightSel[0]

        varsToKeep["is_SR"] = op.static_cast("UInt_t",op.OR(op.rng_len(self.ElElTightSel)>0,
                                                            op.rng_len(self.MuMuTightSel)>0,
                                                            op.rng_len(self.ElMuTightSel)>0))
        varsToKeep['is_ee'] = op.static_cast("UInt_t",op.rng_len(self.ElElTightSel)>0)
        varsToKeep['is_mm'] = op.static_cast("UInt_t",op.rng_len(self.MuMuTightSel)>0)
        varsToKeep['is_em'] = op.static_cast("UInt_t",op.rng_len(self.ElMuTightSel)>0)
        varsToKeep['resolved1b_tag'] = op.static_cast("UInt_t",op.AND(op.rng_len(self.ak4BJets)==1,op.rng_len(self.ak8BJets)==0))
        varsToKeep['resolved2b_tag'] = op.static_cast("UInt_t",op.AND(op.rng_len(self.ak4BJets)>=2,op.rng_len(self.ak8BJets)==0))
        varsToKeep['boosted1b_tag'] = op.static_cast("UInt_t",op.AND(op.rng_len(self.ak8BJets)>0))

        l1 = dilepton[0]
        l2 = dilepton[1]

        varsToKeep['l1_Px']     = l1.p4.Px()
        varsToKeep['l1_Py']     = l1.p4.Py()
        varsToKeep['l1_Pz']     = l1.p4.Pz()
        varsToKeep['l1_E']      = l1.p4.E()
        varsToKeep['l1_pt']     = l1.pt
        varsToKeep['l1_eta']    = l1.eta
        varsToKeep['l1_phi']    = l1.phi
        varsToKeep['l1_pdgId']  = l1.pdgId
        varsToKeep['l1_charge'] = l1.charge

        varsToKeep['l2_Px']     = l2.p4.Px()
        varsToKeep['l2_Py']     = l2.p4.Py()
        varsToKeep['l2_Pz']     = l2.p4.Pz()
        varsToKeep['l2_E']      = l2.p4.E()
        varsToKeep['l2_pt']     = l2.pt
        varsToKeep['l2_eta']    = l2.eta
        varsToKeep['l2_phi']    = l2.phi
        varsToKeep['l2_pdgId']  = l2.pdgId
        varsToKeep['l2_charge'] = l2.charge

        #----- Jet variables -----#
        jets = self.ak4JetsByBtagScore
        for idx in range(1,5):
            varsToKeep[f'j{idx}_Px']  = op.switch(op.rng_len(jets)>=idx, jets[idx-1].p4.Px(), op.c_float(-9999))
            varsToKeep[f'j{idx}_Py']  = op.switch(op.rng_len(jets)>=idx, jets[idx-1].p4.Py(), op.c_float(-9999))
            varsToKeep[f'j{idx}_Pz']  = op.switch(op.rng_len(jets)>=idx, jets[idx-1].p4.Pz(), op.c_float(-9999))
            varsToKeep[f'j{idx}_E']   = op.switch(op.rng_len(jets)>=idx, jets[idx-1].p4.E(), op.c_float(-9999))
            varsToKeep[f'j{idx}_pt']  = op.switch(op.rng_len(jets)>=idx, jets[idx-1].pt, op.c_float(-9999))
            varsToKeep[f'j{idx}_eta'] = op.switch(op.rng_len(jets)>=idx, jets[idx-1].eta, op.c_float(-9999))
            varsToKeep[f'j{idx}_phi'] = op.switch(op.rng_len(jets)>=idx, jets[idx-1].phi, op.c_float(-9999))
            varsToKeep[f'j{idx}_btag']= op.switch(op.rng_len(jets)>=idx, jets[idx-1].btagDeepFlavB, op.c_float(-9999))


        varsToKeep['n_ak4'] = op.static_cast("UInt_t",op.rng_len(self.ak4Jets))
        varsToKeep['n_ak4_btag'] = op.static_cast("UInt_t",op.rng_len(self.ak4BJets))


        #----- Fatjet variables -----#
        fatjets = self.ak8BJets
        subJet1 = fatjets[0].subJet1
        subJet2 = fatjets[0].subJet2

        varsToKeep['fatj_sub1_Px']   = op.switch(op.rng_len(fatjets)>0, subJet1.p4.Px(), op.c_float(-9999))
        varsToKeep['fatj_sub1_Py']   = op.switch(op.rng_len(fatjets)>0, subJet1.p4.Py(), op.c_float(-9999))
        varsToKeep['fatj_sub1_Pz']   = op.switch(op.rng_len(fatjets)>0, subJet1.p4.Pz(), op.c_float(-9999))
        varsToKeep['fatj_sub1_E']    = op.switch(op.rng_len(fatjets)>0, subJet1.p4.E(), op.c_float(-9999))
        varsToKeep['fatj_sub1_pt']   = op.switch(op.rng_len(fatjets)>0, subJet1.pt, op.c_float(-9999))
        varsToKeep['fatj_sub1_eta']  = op.switch(op.rng_len(fatjets)>0, subJet1.eta, op.c_float(-9999))
        varsToKeep['fatj_sub1_phi']  = op.switch(op.rng_len(fatjets)>0, subJet1.phi, op.c_float(-9999))
        varsToKeep['fatj_sub1_btag'] = op.switch(op.rng_len(fatjets)>0, subJet1.btagDeepB, op.c_float(-9999))

        varsToKeep['fatj_sub2_Px']   = op.switch(op.rng_len(fatjets)>0, subJet2.p4.Px(), op.c_float(-9999))
        varsToKeep['fatj_sub2_Py']   = op.switch(op.rng_len(fatjets)>0, subJet2.p4.Py(), op.c_float(-9999))
        varsToKeep['fatj_sub2_Pz']   = op.switch(op.rng_len(fatjets)>0, subJet2.p4.Pz(), op.c_float(-9999))
        varsToKeep['fatj_sub2_E']    = op.switch(op.rng_len(fatjets)>0, subJet2.p4.E(), op.c_float(-9999))
        varsToKeep['fatj_sub2_pt']   = op.switch(op.rng_len(fatjets)>0, subJet2.pt, op.c_float(-9999))
        varsToKeep['fatj_sub2_eta']  = op.switch(op.rng_len(fatjets)>0, subJet2.eta, op.c_float(-9999))
        varsToKeep['fatj_sub2_phi']  = op.switch(op.rng_len(fatjets)>0, subJet2.phi, op.c_float(-9999))
        varsToKeep['fatj_sub2_btag'] = op.switch(op.rng_len(fatjets)>0, subJet2.btagDeepB, op.c_float(-9999))

        varsToKeep['fatj_Px']             = op.switch(op.rng_len(fatjets)>0, fatjets[0].p4.Px(), op.c_float(-9999))
        varsToKeep['fatj_Py']             = op.switch(op.rng_len(fatjets)>0, fatjets[0].p4.Py(), op.c_float(-9999))
        varsToKeep['fatj_Pz']             = op.switch(op.rng_len(fatjets)>0, fatjets[0].p4.Pz(), op.c_float(-9999))
        varsToKeep['fatj_E']              = op.switch(op.rng_len(fatjets)>0, fatjets[0].p4.E(), op.c_float(-9999))
        varsToKeep['fatj_pt']             = op.switch(op.rng_len(fatjets)>0, fatjets[0].pt, op.c_float(-9999))
        varsToKeep['fatj_eta']            = op.switch(op.rng_len(fatjets)>0, fatjets[0].eta, op.c_float(-9999))
        varsToKeep['fatj_phi']            = op.switch(op.rng_len(fatjets)>0, fatjets[0].phi, op.c_float(-9999))
        varsToKeep['fatj_softdropMass']   = op.switch(op.rng_len(fatjets)>0, fatjets[0].msoftdrop, op.c_float(-9999))
        varsToKeep['fatj_btagDeepB']      = op.switch(op.rng_len(fatjets)>0, fatjets[0].btagDeepB, op.c_float(-9999))
        varsToKeep['fatj_btagHbb']        = op.switch(op.rng_len(fatjets)>0, fatjets[0].btagHbb, op.c_float(-9999))

        varsToKeep['n_ak8'] = op.static_cast("UInt_t",op.rng_len(self.ak8Jets))
        varsToKeep['n_ak8_btag'] = op.static_cast("UInt_t",op.rng_len(self.ak8BJets))

        #----- Additional variables -----#
        if self.is_MC:
            varsToKeep["MC_weight"]         = t.genWeight
        varsToKeep['total_weight']      = selObj.sel.weight
        varsToKeep["event"]             = None # Already in tree
        varsToKeep["run"]               = None # Already in tree 
        varsToKeep["ls"]                = t.luminosityBlock

        return selObj.sel, varsToKeep
    def defineSkimSelection(self, t, noSel, sample=None, sampleCfg=None):
        noSel = super(SkimmerNanoHHtobbWWDL,
                      self).prepareObjects(t,
                                           noSel,
                                           sample,
                                           sampleCfg,
                                           "DL",
                                           forSkimmer=True)
        # For the Skimmer, SF must not use defineOnFirstUse -> segmentation fault

        era = sampleCfg['era']

        #self.datadrivenContributions = {} # Avoid all data-driven estimates

        # Initialize varsToKeep dict #
        varsToKeep = dict()

        #---------------------------------------------------------------------------------------#
        #                                     Selections                                        #
        #---------------------------------------------------------------------------------------#
        if not self.inclusive_sel:
            #----- Check arguments -----#
            lepton_level = [
                "Preselected", "Fakeable", "Tight", "FakeExtrapolation"
            ]  # Only one must be in args
            jet_level = [
                "Ak4", "Ak8", "Resolved0Btag", "Resolved1Btag",
                "Resolved2Btag", "Boosted"
            ]  # Only one must be in args

            if [
                    boolean for (level, boolean) in self.args.__dict__.items()
                    if level in lepton_level
            ].count(True) != 1:
                raise RuntimeError(
                    "Only one of the lepton arguments must be used, check --help"
                )
            if [
                    boolean for (level, boolean) in self.args.__dict__.items()
                    if level in jet_level
            ].count(True) != 1:
                raise RuntimeError(
                    "Only one of the jet arguments must be used, check --help")
            if self.args.Channel not in ["ElEl", "MuMu", "ElMu"]:
                raise RuntimeError(
                    "Channel must be either 'ElEl', 'MuMu' or 'ElMu'")

            #----- Lepton selection -----#
            # Args are passed within the self #
            selLeptonDict = makeDoubleLeptonSelection(self,
                                                      noSel,
                                                      use_dd=False)
            # makeDoubleLeptonSelection returns dict -> value is list of three selections for 3 channels
            # [0] -> we take the first and only key and value because restricted to one lepton selection
            selLeptonList = list(selLeptonDict.values())[0]
            if self.args.Channel == "ElEl":
                selObj = selLeptonList[
                    0]  # First item of list is ElEl selection
            if self.args.Channel == "MuMu":
                selObj = selLeptonList[
                    1]  # Second item of list is MuMu selection
            if self.args.Channel == "ElMu":
                selObj = selLeptonList[
                    2]  # Third item of list is ElMu selection

            #----- Jet selection -----#
            # Since the selections in one line, we can use the non copy option of the selection to modify the selection object internally
            if any([
                    self.args.__dict__[item] for item in
                ["Ak4", "Resolved0Btag", "Resolved1Btag", "Resolved2Btag"]
            ]):
                makeAtLeastTwoAk4JetSelection(self, selObj, use_dd=False)
            if any([self.args.__dict__[item] for item in ["Ak8", "Boosted"]]):
                makeAtLeastOneAk8JetSelection(self, selObj, use_dd=False)
            if self.args.Resolved0Btag:
                makeExclusiveResolvedNoBtagSelection(self,
                                                     selObj,
                                                     use_dd=False)
            if self.args.Resolved1Btag:
                makeExclusiveResolvedOneBtagSelection(self,
                                                      selObj,
                                                      use_dd=False)
            if self.args.Resolved2Btag:
                makeExclusiveResolvedTwoBtagsSelection(self,
                                                       selObj,
                                                       use_dd=False)
            if self.args.Boosted:
                makeInclusiveBoostedSelection(self, selObj, use_dd=False)

        #---------------------------------------------------------------------------------------#
        #                                 Synchronization tree                                  #
        #---------------------------------------------------------------------------------------#
        if self.args.Synchronization:
            # Event variables #
            varsToKeep["event"] = None  # Already in tree
            varsToKeep["run"] = None  # Already in tree
            varsToKeep["ls"] = t.luminosityBlock
            varsToKeep["n_presel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsPreSel))
            varsToKeep["n_fakeablesel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsFakeSel))
            varsToKeep["n_mvasel_mu"] = op.static_cast(
                "UInt_t", op.rng_len(self.muonsTightSel))
            varsToKeep["n_presel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsPreSel))
            varsToKeep["n_fakeablesel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsFakeSel))
            varsToKeep["n_mvasel_ele"] = op.static_cast(
                "UInt_t", op.rng_len(self.electronsTightSel))
            varsToKeep["n_presel_ak4Jet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4Jets))
            varsToKeep["n_presel_ak8Jet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak8BJets))
            varsToKeep["n_medium_ak4BJet"] = op.static_cast(
                "UInt_t", op.rng_len(self.ak4BJets))
            varsToKeep["is_SR"] = op.static_cast(
                "UInt_t",
                op.OR(
                    op.rng_len(self.ElElDileptonTightSel) >= 1,
                    op.rng_len(self.MuMuDileptonTightSel) >= 1,
                    op.rng_len(self.ElMuDileptonTightSel) >= 1))
            varsToKeep["is_CR"] = op.static_cast(
                "UInt_t",
                op.OR(
                    op.rng_len(self.ElElDileptonFakeExtrapolationSel) >= 1,
                    op.rng_len(self.MuMuDileptonFakeExtrapolationSel) >= 1,
                    op.rng_len(self.ElMuDileptonFakeExtrapolationSel) >= 1))
            varsToKeep["is_ee"] = op.static_cast(
                "UInt_t",
                op.OR(
                    op.rng_len(self.ElElDileptonTightSel) >= 1,
                    op.rng_len(self.ElElDileptonFakeExtrapolationSel) >= 1))
            varsToKeep["is_mm"] = op.static_cast(
                "UInt_t",
                op.OR(
                    op.rng_len(self.MuMuDileptonTightSel) >= 1,
                    op.rng_len(self.MuMuDileptonFakeExtrapolationSel) >= 1))
            varsToKeep["is_em"] = op.static_cast(
                "UInt_t",
                op.OR(
                    op.rng_len(self.ElMuDileptonTightSel) >= 1,
                    op.rng_len(self.ElMuDileptonFakeExtrapolationSel) >= 1))
            varsToKeep["is_resolved"] = op.switch(
                op.AND(
                    op.rng_len(self.ak4Jets) >= 2,
                    op.rng_len(self.ak4BJets) >= 1,
                    op.rng_len(self.ak8BJets) == 0), op.c_bool(True),
                op.c_bool(False))
            varsToKeep["is_boosted"] = op.switch(
                op.rng_len(self.ak8BJets) >= 1, op.c_bool(True),
                op.c_bool(False))

            # Triggers #
            varsToKeep['n_leadfakeableSel_ele'] = op.static_cast(
                "UInt_t", op.rng_len(self.leadElectronsFakeSel))
            varsToKeep['n_leadfakeableSel_mu'] = op.static_cast(
                "UInt_t", op.rng_len(self.leadMuonsFakeSel))
            varsToKeep["triggers"] = self.triggers
            varsToKeep["triggers_SingleElectron"] = op.OR(
                *self.triggersPerPrimaryDataset['SingleElectron'])
            varsToKeep["triggers_SingleMuon"] = op.OR(
                *self.triggersPerPrimaryDataset['SingleMuon'])
            varsToKeep["triggers_DoubleElectron"] = op.OR(
                *self.triggersPerPrimaryDataset['DoubleEGamma'])
            varsToKeep["triggers_DoubleMuon"] = op.OR(
                *self.triggersPerPrimaryDataset['DoubleMuon'])
            varsToKeep["triggers_MuonElectron"] = op.OR(
                *self.triggersPerPrimaryDataset['MuonEG'])

            # Muons #
            for i in range(1, 3):  # 2 leading muons
                varsToKeep["mu{}_pt".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].pt, op.c_float(-9999., "float"))
                varsToKeep["mu{}_eta".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].eta, op.c_float(-9999.))
                varsToKeep["mu{}_phi".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].phi, op.c_float(-9999.))
                varsToKeep["mu{}_E".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].p4.E(),
                    op.c_float(-9999., "float"))
                varsToKeep["mu{}_charge".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].charge, op.c_int(-9999.))
                varsToKeep["mu{}_conept".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muon_conept[self.muonsPreSel[i - 1].idx],
                    op.c_float(-9999.))
                varsToKeep["mu{}_miniRelIso".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].miniPFRelIso_all,
                    op.c_float(-9999.))
                varsToKeep["mu{}_PFRelIso04".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].pfRelIso04_all, op.c_float(-9999.))
                varsToKeep["mu{}_jetNDauChargedMVASel".format(i)] = op.c_float(
                    -9999.)
                varsToKeep["mu{}_jetPtRel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.))
                varsToKeep["mu{}_jetRelIso".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jetRelIso, op.c_float(-9999.))
                varsToKeep["mu{}_jetDeepJet".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].jet.btagDeepFlavB,
                    op.c_float(-9999.))
                varsToKeep["mu{}_sip3D".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].sip3d, op.c_float(-9999.))
                varsToKeep["mu{}_dxy".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].dxy, op.c_float(-9999.))
                varsToKeep["mu{}_dxyAbs".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.abs(self.muonsPreSel[i - 1].dxy), op.c_float(-9999.))
                varsToKeep["mu{}_dz".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].dz, op.c_float(-9999.))
                varsToKeep["mu{}_segmentCompatibility".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].segmentComp, op.c_float(-9999.))
                varsToKeep["mu{}_leptonMVA".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].mvaTTH, op.c_float(-9999.))
                varsToKeep["mu{}_mediumID".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].mediumId,
                    op.c_float(-9999., "Bool_t"))
                varsToKeep["mu{}_dpt_div_pt".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].tunepRelPt,
                    op.c_float(-9999.))  # Not sure
                varsToKeep["mu{}_isfakeablesel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(self.lambda_muonFakeSel(self.muonsPreSel[i - 1]),
                              op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["mu{}_ismvasel".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(
                        op.AND(
                            self.lambda_muonTightSel(self.muonsPreSel[i - 1]),
                            self.lambda_muonFakeSel(self.muonsPreSel[i - 1])),
                        op.c_int(1), op.c_int(0)),
                    op.c_int(-9999))  # mvasel encompasses fakeablesel
                varsToKeep["mu{}_isGenMatched".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    op.switch(self.lambda_is_matched(self.muonsPreSel[i - 1]),
                              op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["mu{}_genPartFlav".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonsPreSel[i - 1].genPartFlav, op.c_int(-9999))
                varsToKeep["mu{}_FR".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.muonFR(self.muonsPreSel[i - 1]), op.c_int(-9999))
                varsToKeep["mu{}_FRCorr".format(i)] = op.switch(
                    op.rng_len(self.muonsPreSel) >= i,
                    self.lambda_FF_mu(self.muonsPreSel[i - 1]),
                    op.c_int(-9999))

            # Electrons #
            for i in range(1, 3):  # 2 leading electrons
                varsToKeep["ele{}_pt".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].pt, op.c_float(-9999.))
                varsToKeep["ele{}_eta".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].eta, op.c_float(-9999.))
                varsToKeep["ele{}_phi".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].phi, op.c_float(-9999.))
                varsToKeep["ele{}_E".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].p4.E(),
                    op.c_float(-9999., "float"))
                varsToKeep["ele{}_charge".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].charge, op.c_int(-9999.))
                varsToKeep["ele{}_conept".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electron_conept[self.electronsPreSel[i - 1].idx],
                    op.c_float(-9999.))
                varsToKeep["ele{}_miniRelIso".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].miniPFRelIso_all,
                    op.c_float(-9999.))
                varsToKeep["ele{}_PFRelIso03".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].pfRelIso03_all,
                    op.c_float(-9999.))  # Iso03, Iso04 not in NanoAOD
                varsToKeep["ele{}_jetNDauChargedMVASel".format(
                    i)] = op.c_float(-9999.)
                varsToKeep["ele{}_jetPtRel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.))
                varsToKeep["ele{}_jetRelIso".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jetRelIso, op.c_float(-9999.))
                varsToKeep["ele{}_jetDeepJet".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].jet.btagDeepFlavB,
                    op.c_float(-9999.))
                varsToKeep["ele{}_sip3D".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].sip3d, op.c_float(-9999.))

                varsToKeep["ele{}_dxy".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].dxy, op.c_float(-9999.))
                varsToKeep["ele{}_dxyAbs".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.abs(self.electronsPreSel[i - 1].dxy),
                    op.c_float(-9999.))
                varsToKeep["ele{}_dz".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].dz, op.c_float(-9999.))
                varsToKeep["ele{}_ntMVAeleID".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].mvaFall17V2noIso,
                    op.c_float(-9999.))
                varsToKeep["ele{}_leptonMVA".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].mvaTTH, op.c_float(-9999.))
                varsToKeep["ele{}_passesConversionVeto".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].convVeto,
                    op.c_float(-9999., "Bool_t"))
                varsToKeep["ele{}_nMissingHits".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].lostHits,
                    op.c_float(-9999., "UChar_t"))
                varsToKeep["ele{}_sigmaEtaEta".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].sieie, op.c_float(-9999.))
                varsToKeep["ele{}_HoE".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].hoe, op.c_float(-9999.))
                varsToKeep["ele{}_OoEminusOoP".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].eInvMinusPInv,
                    op.c_float(-9999.))
                varsToKeep["ele{}_isfakeablesel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        self.lambda_electronFakeSel(self.electronsPreSel[i -
                                                                         1]),
                        op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["ele{}_ismvasel".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        op.AND(
                            self.lambda_electronTightSel(
                                self.electronsPreSel[i - 1]),
                            self.lambda_electronFakeSel(
                                self.electronsPreSel[i - 1])), op.c_int(1),
                        op.c_int(0)),
                    op.c_int(-9999))  # mvasel encompasses fakeablesel
                varsToKeep["ele{}_isGenMatched".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    op.switch(
                        self.lambda_is_matched(self.electronsPreSel[i - 1]),
                        op.c_int(1), op.c_int(0)), op.c_int(-9999))
                varsToKeep["ele{}_genPartFlav".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].genPartFlav, op.c_int(-9999))
                varsToKeep["ele{}_deltaEtaSC".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronsPreSel[i - 1].deltaEtaSC, op.c_int(-9999))
                varsToKeep["ele{}_FR".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.electronFR(self.electronsPreSel[i - 1]),
                    op.c_int(-9999))
                varsToKeep["ele{}_FF".format(i)] = op.switch(
                    op.rng_len(self.electronsPreSel) >= i,
                    self.lambda_FF_el(self.electronsPreSel[i - 1]),
                    op.c_int(-9999))

            # AK4 Jets #
            for i in range(1, 5):  # 4 leading jets
                varsToKeep["ak4Jet{}_pt".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].pt,
                    op.c_float(-9999., "float"))
                varsToKeep["ak4Jet{}_eta".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].eta,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_phi".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].phi,
                    op.c_float(-9999.))
                varsToKeep["ak4Jet{}_E".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].p4.E(),
                    op.c_float(-9999., "float"))
                varsToKeep["ak4Jet{}_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.ak4Jets[i - 1].btagDeepFlavB, op.c_float(-9999.))
                varsToKeep["ak4Jet{}_hadronFlavour".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.ak4Jets[i - 1].hadronFlavour, op.c_float(-9999.))
                varsToKeep["ak4Jet{}_btagSF".format(i)] = op.switch(
                    op.rng_len(self.ak4Jets) >= i,
                    self.DeepJetDiscReshapingSF(self.ak4Jets[i - 1]),
                    op.c_float(-9999.))

            # AK8 Jets #
            for i in range(1, 3):  # 2 leading fatjets
                varsToKeep["ak8Jet{}_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].pt,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].eta,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].phi,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_E".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].p4.E(), op.c_float(-9999., "float"))
                varsToKeep["ak8Jet{}_msoftdrop".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].msoftdrop, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_tau1".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau1,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_tau2".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau2,
                    op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.pt, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.eta, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.phi, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet0_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet1.btagDeepB, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_pt".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.pt, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_eta".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.eta, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_phi".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.phi, op.c_float(-9999.))
                varsToKeep["ak8Jet{}_subjet1_CSV".format(i)] = op.switch(
                    op.rng_len(self.ak8BJets) >= i,
                    self.ak8BJets[i - 1].subJet2.btagDeepB, op.c_float(-9999.))

            # MET #

            varsToKeep["PFMET"] = self.corrMET.pt
            varsToKeep["PFMETphi"] = self.corrMET.phi

            # HME #

            # SF #
            from operator import mul
            from functools import reduce

            electronMuon_cont = op.combine(
                (self.electronsFakeSel, self.muonsFakeSel))
            varsToKeep["trigger_SF"] = op.multiSwitch(
                (op.AND(
                    op.rng_len(self.electronsTightSel) == 1,
                    op.rng_len(self.muonsTightSel) == 0),
                 self.ttH_singleElectron_trigSF(self.electronsTightSel[0])),
                (op.AND(
                    op.rng_len(self.electronsTightSel) == 0,
                    op.rng_len(self.muonsTightSel)
                    == 1), self.ttH_singleMuon_trigSF(self.muonsTightSel[0])),
                (op.AND(
                    op.rng_len(self.electronsTightSel) >= 2,
                    op.rng_len(self.muonsTightSel) == 0),
                 self.lambda_ttH_doubleElectron_trigSF(
                     self.electronsTightSel)),
                (op.AND(
                    op.rng_len(self.electronsTightSel) == 0,
                    op.rng_len(self.muonsTightSel) >= 2),
                 self.lambda_ttH_doubleMuon_trigSF(self.muonsTightSel)),
                (op.AND(
                    op.rng_len(self.electronsTightSel) >= 1,
                    op.rng_len(self.muonsTightSel) >= 1),
                 self.lambda_ttH_electronMuon_trigSF(electronMuon_cont[0])),
                op.c_float(1.))

            varsToKeep["lepton_IDSF"] = op.rng_product(self.electronsTightSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el)+self.lambda_ElectronTightSF(el))) * \
                                        op.rng_product(self.muonsTightSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu)+self.lambda_MuonTightSF(mu)))

            varsToKeep["lepton_IDSF_recoToLoose"] = op.rng_product(self.electronsTightSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el))) * \
                                                    op.rng_product(self.muonsTightSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu)))
            varsToKeep["lepton_IDSF_looseToTight"] = op.rng_product(self.electronsTightSel, lambda el : reduce(mul,self.lambda_ElectronTightSF(el))) * \
                                                     op.rng_product(self.muonsTightSel, lambda mu : reduce(mul,self.lambda_MuonTightSF(mu)))

            # L1 Prefire #
            if era in ["2016", "2017"]:
                varsToKeep["L1prefire"] = self.L1Prefiring
            else:
                varsToKeep["L1prefire"] = op.c_float(-9999.)

            # Fake rate #
            if self.args.FakeExtrapolation:
                varsToKeep["fakeRate"] = op.multiSwitch(
                    (op.rng_len(self.ElElDileptonFakeExtrapolationSel) >= 1,
                     self.ElElFakeFactor(
                         self.ElElDileptonFakeExtrapolationSel[0])),
                    (op.rng_len(self.MuMuDileptonFakeExtrapolationSel) >= 1,
                     self.MuMuFakeFactor(
                         self.MuMuDileptonFakeExtrapolationSel[0])),
                    (op.rng_len(self.ElMuDileptonFakeExtrapolationSel) >= 1,
                     self.ElMuFakeFactor(
                         self.ElMuDileptonFakeExtrapolationSel[0])),
                    op.c_float(0.))
            else:
                varsToKeep["fakeRate"] = op.c_float(-9999.)

            # Btagging SF #
            varsToKeep["btag_SF"] = self.btagSF
            if "BtagRatioWeight" in self.__dict__.keys():
                varsToKeep["btag_reweighting"] = self.BtagRatioWeight
                varsToKeep[
                    "btag_reweighting_SF"] = self.btagSF * self.BtagRatioWeight

            # ttbar PT reweighting #
            if "group" in sampleCfg and sampleCfg["group"] == 'ttbar':
                varsToKeep["topPt_wgt"] = self.ttbar_weight(
                    self.genTop[0], self.genAntitop[0])

        # Event Weight #
            if self.is_MC:
                #varsToKeep["MC_weight"] = op.sign(t.genWeight)
                varsToKeep["MC_weight"] = t.genWeight
                puWeightsFile = os.path.join(os.path.dirname(__file__), "data",
                                             "pileup", sampleCfg["pufile"])
                varsToKeep["PU_weight"] = makePileupWeight(
                    puWeightsFile,
                    t.Pileup_nTrueInt,
                    nameHint=f"puweightFromFile{sample}".replace('-', '_'))
                varsToKeep[
                    "eventWeight"] = noSel.weight if self.inclusive_sel else selObj.sel.weight

            if self.inclusive_sel:
                return noSel, varsToKeep
            else:
                return selObj.sel, varsToKeep

        #---------------------------------------------------------------------------------------#
        #                                    Selection tree                                     #
        #---------------------------------------------------------------------------------------#

        #----- MET variables -----#
        MET = self.corrMET

        varsToKeep['MET_pt'] = MET.pt
        varsToKeep['MET_phi'] = MET.phi

        #----- Lepton variables -----#
        if self.args.Channel is None:
            raise RuntimeError("You need to specify --Channel")
        dilepton = None
        if self.args.Preselected:
            if self.args.Channel == "ElEl":
                dilepton = self.ElElDileptonPreSel[0]
            if self.args.Channel == "MuMu":
                dilepton = self.MuMuDileptonPreSel[0]
            if self.args.Channel == "ElMu":
                dilepton = self.ElMuDileptonPreSel[0]
        if self.args.Fakeable:
            if self.args.Channel == "ElEl":
                dilepton = self.ElElDileptonFakeSel[0]
            if self.args.Channel == "MuMu":
                dilepton = self.MuMuDileptonFakeSel[0]
            if self.args.Channel == "ElMu":
                dilepton = self.ElMuDileptonFakeSel[0]
        if self.args.Tight:
            if self.args.Channel == "ElEl":
                dilepton = self.ElElDileptonTightSel[0]
            if self.args.Channel == "MuMu":
                dilepton = self.MuMuDileptonTightSel[0]
            if self.args.Channel == "ElMu":
                dilepton = self.ElMuDileptonTightSel[0]
        if self.args.FakeExtrapolation:
            if self.args.Channel == "ElEl":
                dilepton = self.ElElDileptonFakeExtrapolationSel[0]
            if self.args.Channel == "MuMu":
                dilepton = self.MuMuDileptonFakeExtrapolationSel[0]
            if self.args.Channel == "ElMu":
                dilepton = self.ElMuDileptonFakeExtrapolationSel[0]

        varsToKeep['l1_Px'] = dilepton[0].p4.Px()
        varsToKeep['l1_Py'] = dilepton[0].p4.Py()
        varsToKeep['l1_Pz'] = dilepton[0].p4.Pz()
        varsToKeep['l1_E'] = dilepton[0].p4.E()
        varsToKeep['l1_pt'] = dilepton[0].pt
        varsToKeep['l1_eta'] = dilepton[0].eta
        varsToKeep['l1_phi'] = dilepton[0].phi

        varsToKeep['l2_Px'] = dilepton[1].p4.Px()
        varsToKeep['l2_Py'] = dilepton[1].p4.Py()
        varsToKeep['l2_Pz'] = dilepton[1].p4.Pz()
        varsToKeep['l2_E'] = dilepton[1].p4.E()
        varsToKeep['l2_pt'] = dilepton[1].pt
        varsToKeep['l2_eta'] = dilepton[1].eta
        varsToKeep['l2_phi'] = dilepton[1].phi

        varsToKeep['ll_pt'] = (dilepton[0].p4 + dilepton[1].p4).Pt()
        varsToKeep['ll_DR'] = op.deltaR(dilepton[0].p4, dilepton[1].p4)
        varsToKeep['ll_DPhi'] = op.deltaPhi(dilepton[0].p4,
                                            dilepton[1].p4)  # Might need abs

        varsToKeep['llmet_DPhi'] = self.HLL.DilepMET_deltaPhi(
            dilepton[0], dilepton[1], MET)
        varsToKeep['llmet_pt'] = self.HLL.DilepMET_Pt(dilepton[0], dilepton[1],
                                                      MET)

        varsToKeep['ll_M'] = op.invariant_mass(dilepton[0].p4, dilepton[1].p4)
        varsToKeep['ll_MT'] = self.HLL.MT_ll(dilepton[0], dilepton[1], MET)

        #----- Jet variables -----#
        if any([
                self.args.__dict__[item] for item in
            ["Ak4", "Resolved0Btag", "Resolved1Btag", "Resolved2Btag"]
        ]):
            if self.args.Ak4:
                leadjet = self.ak4Jets[0]
                subleadjet = self.ak4Jets[1]
            if self.args.Resolved0Btag:
                leadjet = self.ak4LightJetsByBtagScore[0]
                subleadjet = self.ak4LightJetsByBtagScore[0]
            if self.args.Resolved1Btag:
                leadjet = self.ak4BJets[0]
                subleadjet = self.ak4LightJetsByBtagScore[0]
            if self.args.Resolved2Btag:
                leadjet = self.ak4BJets[0]
                subleadjet = self.ak4BJets[1]

            varsToKeep['j1_Px'] = leadjet.p4.Px()
            varsToKeep['j1_Py'] = leadjet.p4.Py()
            varsToKeep['j1_Pz'] = leadjet.p4.Pz()
            varsToKeep['j1_E'] = leadjet.p4.E()
            varsToKeep['j1_pt'] = leadjet.pt
            varsToKeep['j1_eta'] = leadjet.eta
            varsToKeep['j1_phi'] = leadjet.phi

            varsToKeep['j2_Px'] = subleadjet.p4.Px()
            varsToKeep['j2_Py'] = subleadjet.p4.Py()
            varsToKeep['j2_Pz'] = subleadjet.p4.Pz()
            varsToKeep['j2_E'] = subleadjet.p4.E()
            varsToKeep['j2_pt'] = subleadjet.pt
            varsToKeep['j2_eta'] = subleadjet.eta
            varsToKeep['j2_phi'] = subleadjet.phi

            varsToKeep['jj_pt'] = (leadjet.p4 + subleadjet.p4).Pt()
            varsToKeep['jj_DR'] = op.deltaR(leadjet.p4, subleadjet.p4)
            varsToKeep['jj_DPhi'] = op.deltaPhi(
                leadjet.p4, subleadjet.p4)  # Might need abs
            varsToKeep['jj_M'] = op.invariant_mass(leadjet.p4, subleadjet.p4)

            varsToKeep['lljj_M'] = self.HLL.M_lljj(dilepton[0], dilepton[1],
                                                   leadjet, subleadjet)
            varsToKeep['lljj_MT'] = self.HLL.MT_lljj(dilepton[0], dilepton[1],
                                                     leadjet, subleadjet, MET)
            varsToKeep['lj_MinDR'] = self.HLL.MinDR_lj(dilepton[0],
                                                       dilepton[1], leadjet,
                                                       subleadjet)
            varsToKeep['HT2'] = self.HLL.HT2(dilepton[0], dilepton[1], leadjet,
                                             subleadjet, MET)
            varsToKeep['HT2R'] = self.HLL.HT2R(dilepton[0], dilepton[1],
                                               leadjet, subleadjet, MET)

        #----- Fatjet variables -----#
        if any([self.args.__dict__[item] for item in ["Ak8", "Boosted"]]):
            if self.args.Ak8:
                fatjet = self.ak8Jets[0]
            if self.args.Boosted:
                fatjet = self.ak8BJets[0]

            varsToKeep['fatjet_Px'] = fatjet.p4.Px()
            varsToKeep['fatjet_Py'] = fatjet.p4.Py()
            varsToKeep['fatjet_Pz'] = fatjet.p4.Pz()
            varsToKeep['fatjet_E'] = fatjet.p4.E()
            varsToKeep['fatjet_pt'] = fatjet.pt
            varsToKeep['fatjet_eta'] = fatjet.eta
            varsToKeep['fatjet_phi'] = fatjet.phi
            varsToKeep['fatjet_softdropMass'] = fatjet.msoftdrop

            varsToKeep['lljj_M'] = self.HLL.M_lljj(dilepton[0], dilepton[1],
                                                   fatjet.subJet1,
                                                   fatjet.subJet2)
            varsToKeep['lljj_MT'] = self.HLL.MT_lljj(dilepton[0], dilepton[1],
                                                     fatjet.subJet1,
                                                     fatjet.subJet2, MET)
            varsToKeep['lj_MinDR'] = self.HLL.MinDR_lj(dilepton[0],
                                                       dilepton[1],
                                                       fatjet.subJet1,
                                                       fatjet.subJet2)
            varsToKeep['HT2'] = self.HLL.HT2(dilepton[0], dilepton[1],
                                             fatjet.subJet1, fatjet.subJet2,
                                             MET)
            varsToKeep['HT2R'] = self.HLL.HT2R(dilepton[0], dilepton[1],
                                               fatjet.subJet1, fatjet.subJet2,
                                               MET)

        #----- Additional variables -----#
        varsToKeep["MC_weight"] = t.genWeight
        varsToKeep['total_weight'] = selObj.sel.weight

        #return leptonSel.sel, varsToKeep
        return selObj.sel, varsToKeep