Example #1
0
def findJPACategoryBoosted (self, selObj, lepton, muons, electrons, fatJets, jets, bJetsL, bJetsM, met, modelPathDict, event, HLL, nodeList, plot_yield=False):
    JPAfuncDict = {'f1':evaluateJPA_Hbb2Wj, 
                   'f2':evaluateJPA_Hbb1Wj}

    JPAMaxScoreList = []
    bestCombo_per_cat = []
    
    combo2     = op.combine(jets, N=2, pred=lambda j1,j2 : j1.pt > j2.pt, samePred=lambda j1,j2 : j1.idx != j2.idx)
    fakeCombo2 = op.combine(jets, N=2, pred=lambda j1,j2 : j1.pt >= j2.pt, samePred=None)

    funckeys = [k for k in JPAfuncDict.keys()]
    for idx, func in enumerate(funckeys):
        node        = nodeList[idx]
        modelpaths  = modelPathDict.get(node)
        model = makeOddEvenEvaluator(event%2, modelpaths[1], modelpaths[0], mvaType="TMVA")
        lambdaFunc = lambda jetCombo : JPAfuncDict[func](lepton, muons, electrons, fatJets, jetCombo, bJetsL, bJetsM, met, model, HLL)

        if idx == 0:
            best = op.rng_max_element_by(combo2, lambdaFunc)
            maxScore = op.switch(best.idx != -1, best.idx.op.this.result.second, op.c_float(-1.))
        else:
            best = op.rng_max_element_by(fakeCombo2, lambdaFunc)
            #best = op.rng_max_element_by(combo2, lambdaFunc)
            maxScore = best.idx.op.this.result.second
            #maxScore = op.switch(best.idx != -1, best.idx.op.this.result.second, op.c_float(-1.))

        JPAMaxScoreList.append(op.pow((1.0 + op.sqrt((1 - maxScore)/(1 + maxScore))), -1))
        #JPAMaxScoreList.append(maxScore)
        bestCombo_per_cat.append(best)

    evtCat = makeOddEvenEvaluator(event%2, modelPathDict.get('evCat')[1], modelPathDict.get('evCat')[0], mvaType="TMVA")
    JPAL2outList = evtCat(*JPAMaxScoreList)
    maxIdx = op.rng_max_element_index(JPAL2outList)

    newSelObj  = copy(selObj)
    selObjJPAjetsIdxDict = {}
    for i, node in enumerate(nodeList):
        outSelObj = copy(newSelObj)
        outSelObj.selName += '%s'%node
        outSelObj.yieldTitle += " in %s node"%node 
        outSelObj.refine(cut = [maxIdx == op.c_int(i)])
        #if plot_yield:
        #    outSelObj.makeYield(self.yieldPlots)
        if i < 2:
            selObjJPAjetsIdxDict[node] = [outSelObj, bestCombo_per_cat[i]]
        else:
            selObjJPAjetsIdxDict[node] = [outSelObj, None]

    return JPAMaxScoreList, JPAL2outList, selObjJPAjetsIdxDict
Example #2
0
    def definePlots(self, t, noSel, sample=None, sampleCfg=None):
        # Some imports #
        from bamboo.analysisutils import forceDefine

        era = sampleCfg['era']
        # Get pile-up configs #
        puWeightsFile = None
        if era == "2016":
            sfTag = "94X"
            puWeightsFile = os.path.join(os.path.dirname(__file__), "data",
                                         "puweights2016.json")
        elif era == "2017":
            sfTag = "94X"
            puWeightsFile = os.path.join(os.path.dirname(__file__), "data",
                                         "puweights2017.json")
        elif era == "2018":
            sfTag = "102X"
            puWeightsFile = os.path.join(os.path.dirname(__file__), "data",
                                         "puweights2018.json")
        if self.isMC(sample) and puWeightsFile is not None:
            from bamboo.analysisutils import makePileupWeight
            noSel = noSel.refine("puWeight",
                                 weight=makePileupWeight(puWeightsFile,
                                                         t.Pileup_nTrueInt,
                                                         systName="pileup"))
        isMC = self.isMC(sample)
        plots = []

        forceDefine(t._Muon.calcProd, noSel)

        #############################################################################
        ################################  Muons #####################################
        #############################################################################
        # Wp // 2016- 2017 -2018 : Muon_mediumId   // https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideMuonIdRun2#Muon_Isolation
        muonsByPt = op.sort(t.Muon, lambda mu: -mu.p4.Pt())
        muons = op.select(
            muonsByPt, lambda mu: op.AND(mu.p4.Pt() > 10.,
                                         op.abs(mu.p4.Eta()) < 2.4, mu.tightId,
                                         mu.pfRelIso04_all < 0.15))

        # Scalefactors #
        #if era=="2016":
        #    doubleMuTrigSF = get_scalefactor("dilepton", ("doubleMuLeg_HHMoriond17_2016"), systName="mumutrig")
        #    muMediumIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "id_medium"), combine="weight", systName="muid")
        #    muMediumISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "iso_tight_id_medium"), combine="weight", systName="muiso")
        #    TrkIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "highpt"), combine="weight")
        #    TrkISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "isotrk_loose_idtrk_tightidandipcut"), combine="weight")
        #else:
        #    muMediumIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "id_medium"), systName="muid")
        #    muMediumISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "iso_tight_id_medium"), systName="muiso")

        #############################################################################
        #############################  Electrons  ###################################
        #############################################################################
        #Wp  // 2016: Electron_cutBased_Sum16==3  -> medium     // 2017 -2018  : Electron_cutBased ==3   --> medium ( Fall17_V2)
        # asking for electrons to be in the Barrel region with dz<1mm & dxy< 0.5mm   //   Endcap region dz<2mm & dxy< 0.5mm
        electronsByPt = op.sort(t.Electron, lambda ele: -ele.p4.Pt())
        electrons = op.select(
            electronsByPt,
            lambda ele: op.AND(ele.p4.Pt() > 15.,
                               op.abs(ele.p4.Eta()) < 2.5, ele.cutBased >= 3)
        )  # //cut-based ID Fall17 V2 the recomended one from POG for the FullRunII

        # Scalefactors #
        #elMediumIDSF = get_scalefactor("lepton", ("electron_{0}_{1}".format(era,sfTag), "id_medium"), systName="elid")
        #doubleEleTrigSF = get_scalefactor("dilepton", ("doubleEleLeg_HHMoriond17_2016"), systName="eleltrig")

        #elemuTrigSF = get_scalefactor("dilepton", ("elemuLeg_HHMoriond17_2016"), systName="elmutrig")
        #mueleTrigSF = get_scalefactor("dilepton", ("mueleLeg_HHMoriond17_2016"), systName="mueltrig")

        OsElEl = op.combine(
            electrons,
            N=2,
            pred=lambda el1, el2: op.AND(el1.charge != el2.charge,
                                         el1.p4.Pt() > 25,
                                         el2.p4.Pt() > 15))
        OsMuMu = op.combine(
            muons,
            N=2,
            pred=lambda mu1, mu2: op.AND(mu1.charge != mu2.charge,
                                         mu1.p4.Pt() > 25,
                                         mu2.p4.Pt() > 15))
        OsElMu = op.combine((electrons, muons),
                            pred=lambda el, mu: op.AND(el.charge != mu.charge,
                                                       el.p4.Pt() > 25,
                                                       mu.p4.Pt() > 15))
        OsMuEl = op.combine((electrons, muons),
                            pred=lambda el, mu: op.AND(el.charge != mu.charge,
                                                       el.p4.Pt() > 15,
                                                       mu.p4.Pt() > 25))

        hasOsElEl = noSel.refine("hasOsElEl", cut=[op.rng_len(OsElEl) >= 1])
        hasOsMuMu = noSel.refine("hasOsMuMu", cut=[op.rng_len(OsMuMu) >= 1])
        hasOsElMu = noSel.refine("hasOsElMu", cut=[op.rng_len(OsElMu) >= 1])
        hasOsMuEl = noSel.refine("hasOsMuEl", cut=[op.rng_len(OsMuEl) >= 1])

        plots.append(
            Plot.make1D("ElEl_channel",
                        op.rng_len(OsElEl),
                        noSel,
                        EquidistantBinning(10, 0, 10.),
                        title='Number of dilepton events in ElEl channel',
                        xTitle='N_{dilepton} (ElEl channel)'))
        plots.append(
            Plot.make1D("MuMu_channel",
                        op.rng_len(OsMuMu),
                        noSel,
                        EquidistantBinning(10, 0, 10.),
                        title='Number of dilepton events in MuMu channel',
                        xTitle='N_{dilepton} (MuMu channel)'))
        plots.append(
            Plot.make1D("ElMu_channel",
                        op.rng_len(OsElMu),
                        noSel,
                        EquidistantBinning(10, 0, 10.),
                        title='Number of dilepton events in ElMu channel',
                        xTitle='N_{dilepton} (ElMu channel)'))
        plots.append(
            Plot.make1D("MuEl_channel",
                        op.rng_len(OsMuEl),
                        noSel,
                        EquidistantBinning(10, 0, 10.),
                        title='Number of dilepton events in MuEl channel',
                        xTitle='N_{dilepton} (MuEl channel)'))

        plots += makeDileptonPlots(self,
                                   sel=hasOsElEl,
                                   dilepton=OsElEl[0],
                                   suffix='hasOsdilep',
                                   channel='ElEl')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuMu,
                                   dilepton=OsMuMu[0],
                                   suffix='hasOsdilep',
                                   channel='MuMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsElMu,
                                   dilepton=OsElMu[0],
                                   suffix='hasOsdilep',
                                   channel='ElMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuEl,
                                   dilepton=OsMuEl[0],
                                   suffix='hasOsdilep',
                                   channel='MuEl')

        # Dilepton Z peak exclusion (charge already done in previous selection) #
        lambda_mllLowerband = lambda dilep: op.in_range(
            12., op.invariant_mass(dilep[0].p4, dilep[1].p4), 80.)
        lambda_mllUpperband = lambda dilep: op.invariant_mass(
            dilep[0].p4, dilep[1].p4) > 100.
        lambda_mllCut = lambda dilep: op.OR(lambda_mllLowerband(dilep),
                                            lambda_mllUpperband(dilep))

        hasOsElElOutZ = hasOsElEl.refine("hasOsElElOutZ",
                                         cut=[lambda_mllCut(OsElEl[0])])
        hasOsMuMuOutZ = hasOsMuMu.refine("hasOsMuMuOutZ",
                                         cut=[lambda_mllCut(OsMuMu[0])])
        hasOsElMuOutZ = hasOsElMu.refine("hasOsElMuOutZ",
                                         cut=[lambda_mllCut(OsElMu[0])])
        hasOsMuElOutZ = hasOsMuEl.refine("hasOsMuElOutZ",
                                         cut=[lambda_mllCut(OsMuEl[0])])

        plots += makeDileptonPlots(self,
                                   sel=hasOsElElOutZ,
                                   dilepton=OsElEl[0],
                                   suffix='hasOsdilep_OutZ',
                                   channel='ElEl')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuMuOutZ,
                                   dilepton=OsMuMu[0],
                                   suffix='hasOsdilep_OutZ',
                                   channel='MuMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsElMuOutZ,
                                   dilepton=OsElMu[0],
                                   suffix='hasOsdilep_OutZ',
                                   channel='ElMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuElOutZ,
                                   dilepton=OsMuEl[0],
                                   suffix='hasOsdilep_OutZ',
                                   channel='MuEl')

        #############################################################################
        ################################  Jets  #####################################
        #############################################################################
        # select jets   // 2016 - 2017 - 2018   ( j.jetId &2) ->      tight jet ID
        jetsByPt = op.sort(t.Jet, lambda jet: -jet.p4.Pt())
        jetsSel = op.select(jetsByPt,
                            lambda j: op.AND(j.p4.Pt() > 20.,
                                             op.abs(j.p4.Eta()) < 2.4,
                                             (j.jetId & 2)))  # Jets = AK4 jets
        fatjetsByPt = op.sort(t.FatJet, lambda fatjet: -fatjet.p4.Pt())
        fatjetsSel = op.select(
            fatjetsByPt, lambda j: op.AND(j.p4.Pt() > 20.,
                                          op.abs(j.p4.Eta()) < 2.4,
                                          (j.jetId & 2)))  # FatJets = AK8 jets
        # exclude from the jetsSel any jet that happens to include within its reconstruction cone a muon or an electron.
        jets = op.select(
            jetsSel, lambda j: op.AND(
                op.NOT(
                    op.rng_any(electrons, lambda ele: op.deltaR(j.p4, ele.p4) <
                               0.3)),
                op.NOT(
                    op.rng_any(muons, lambda mu: op.deltaR(j.p4, mu.p4) < 0.3))
            ))
        fatjets = op.select(
            fatjetsSel, lambda j: op.AND(
                op.NOT(
                    op.rng_any(electrons, lambda ele: op.deltaR(j.p4, ele.p4) <
                               0.3)),
                op.NOT(
                    op.rng_any(muons, lambda mu: op.deltaR(j.p4, mu.p4) < 0.3))
            ))
        # Boosted and resolved jets categories #
        if era == "2016":  # Must check that subJet exists before looking at the btag
            lambda_boosted = lambda fatjet: op.OR(
                op.AND(fatjet.subJet1._idx.result != -1, fatjet.subJet1.
                       btagDeepB > 0.6321),
                op.AND(fatjet.subJet2._idx.result != -1, fatjet.subJet2.
                       btagDeepB > 0.6321))
            lambda_resolved = lambda jet: jet.btagDeepB > 0.6321
        elif era == "2017":
            lambda_boosted = lambda fatjet: op.OR(
                op.AND(fatjet.subJet1._idx.result != -1, fatjet.subJet1.
                       btagDeepB > 0.4941),
                op.AND(fatjet.subJet2._idx.result != -1, fatjet.subJet2.
                       btagDeepB > 0.4941))
            lambda_resolved = lambda jet: jet.btagDeepB > 0.4941
        elif era == "2018":
            lambda_boosted = lambda fatjet: op.OR(
                op.AND(fatjet.subJet1._idx.result != -1, fatjet.subJet1.
                       btagDeepB > 0.4184),
                op.AND(fatjet.subJet2._idx.result != -1, fatjet.subJet2.
                       btagDeepB > 0.4184))
            lambda_resolved = lambda jet: jet.btagDeepB > 0.4184

        # Select the bjets we want #
        bjetsResolved = op.select(jets, lambda_resolved)
        bjetsBoosted = op.select(fatjets, lambda_boosted)

        # Define the boosted and Resolved (+exclusive) selections #
        hasBoostedJets = noSel.refine("hasBoostedJets",
                                      cut=[op.rng_len(bjetsBoosted) >= 1])
        hasNotBoostedJets = noSel.refine("hasNotBoostedJets",
                                         cut=[op.rng_len(bjetsBoosted) == 0])
        hasResolvedJets = noSel.refine(
            "hasResolvedJets",
            cut=[op.rng_len(jets) >= 2,
                 op.rng_len(bjetsResolved) >= 1])
        hasNotResolvedJets = noSel.refine(
            "hasNotResolvedJets",
            cut=[op.OR(op.rng_len(jets) <= 1,
                       op.rng_len(bjetsResolved) == 0)])
        hasBoostedAndResolvedJets = noSel.refine(
            "hasBoostedAndResolvedJets",
            cut=[
                op.rng_len(bjetsBoosted) >= 1,
                op.rng_len(jets) >= 2,
                op.rng_len(bjetsResolved) >= 1
            ])
        hasNotBoostedAndResolvedJets = noSel.refine(
            "hasNotBoostedAndResolvedJets",
            cut=[
                op.OR(
                    op.rng_len(bjetsBoosted) == 0,
                    op.rng_len(jets) <= 1,
                    op.rng_len(bjetsResolved) == 0)
            ])
        hasExlusiveResolvedJets = noSel.refine(
            "hasExlusiveResolved",
            cut=[
                op.rng_len(jets) >= 2,
                op.rng_len(bjetsResolved) >= 1,
                op.rng_len(bjetsBoosted) == 0
            ])
        hasNotExlusiveResolvedJets = noSel.refine(
            "hasNotExlusiveResolved",
            cut=[
                op.OR(
                    op.OR(
                        op.rng_len(jets) <= 1,
                        op.rng_len(bjetsResolved) == 0),
                    op.AND(
                        op.rng_len(bjetsBoosted) >= 1,
                        op.rng_len(jets) >= 2,
                        op.rng_len(bjetsResolved) >= 1))
            ])
        hasExlusiveBoostedJets = noSel.refine(
            "hasExlusiveBoostedJets",
            cut=[
                op.rng_len(bjetsBoosted) >= 1,
                op.OR(op.rng_len(jets) <= 1,
                      op.rng_len(bjetsResolved) == 0)
            ])
        hasNotExlusiveBoostedJets = noSel.refine(
            "hasNotExlusiveBoostedJets",
            cut=[
                op.OR(
                    op.rng_len(bjetsBoosted) == 0,
                    op.AND(
                        op.rng_len(jets) >= 2,
                        op.rng_len(bjetsResolved) >= 1))
            ])

        # Counting events from different selections for debugging #
        # Passing Boosted selection #
        PassedBoosted = Plot.make1D("PassedBoosted",
                                    op.c_int(1),
                                    hasBoostedJets,
                                    EquidistantBinning(2, 0., 2.),
                                    title='Passed Boosted',
                                    xTitle='Passed Boosted')
        FailedBoosted = Plot.make1D("FailedBoosted",
                                    op.c_int(0),
                                    hasNotBoostedJets,
                                    EquidistantBinning(2, 0., 2.),
                                    title='Failed Boosted',
                                    xTitle='Failed Boosted')
        plots.append(
            SummedPlot("BoostedCase", [FailedBoosted, PassedBoosted],
                       xTitle="Boosted selection"))

        # Passing Resolved selection #
        PassedResolved = Plot.make1D("PassedResolved",
                                     op.c_int(1),
                                     hasResolvedJets,
                                     EquidistantBinning(2, 0., 2.),
                                     title='Passed Resolved',
                                     xTitle='Passed Resolved')
        FailedResolved = Plot.make1D("FailedResolved",
                                     op.c_int(0),
                                     hasNotResolvedJets,
                                     EquidistantBinning(2, 0., 2.),
                                     title='Failed Resolved',
                                     xTitle='Failed Resolved')
        plots.append(
            SummedPlot("ResolvedCase", [FailedResolved, PassedResolved],
                       xTitle="Resolved selection"))

        # Passing Exclusive Resolved (Resolved AND NOT Boosted) #
        PassedExclusiveResolved = Plot.make1D(
            "PassedExclusiveResolved",
            op.c_int(1),
            hasExlusiveResolvedJets,
            EquidistantBinning(2, 0., 2.),
            title='Passed Exclusive Resolved',
            xTitle='Passed Exclusive Resolved')
        FailedExclusiveResolved = Plot.make1D(
            "FailedExclusiveResolved",
            op.c_int(0),
            hasNotExlusiveResolvedJets,
            EquidistantBinning(2, 0., 2.),
            title='Failed Exclusive Resolved',
            xTitle='Failed Exclusive Resolved')
        plots.append(
            SummedPlot("ExclusiveResolvedCase",
                       [FailedExclusiveResolved, PassedExclusiveResolved],
                       xTitle="Exclusive Resolved selection"))

        # Passing Exclusive Boosted (Boosted AND NOT Resolved) #
        PassedExclusiveBoosted = Plot.make1D("PassedExclusiveBoosted",
                                             op.c_int(1),
                                             hasExlusiveBoostedJets,
                                             EquidistantBinning(2, 0., 2.),
                                             title='Passed Exclusive Boosted',
                                             xTitle='Passed Exclusive Boosted')
        FailedExclusiveBoosted = Plot.make1D("FailedExclusiveBoosted",
                                             op.c_int(0),
                                             hasNotExlusiveBoostedJets,
                                             EquidistantBinning(2, 0., 2.),
                                             title='Failed Exclusive Boosted',
                                             xTitle='Failed Exclusive Boosted')
        plots.append(
            SummedPlot("ExclusiveBoostedCase",
                       [FailedExclusiveBoosted, PassedExclusiveBoosted],
                       xTitle="Exclusive Boosted selection"))

        # Passing Boosted AND Resolved #
        PassedBoth = Plot.make1D("PassedBoth",
                                 op.c_int(1),
                                 hasBoostedAndResolvedJets,
                                 EquidistantBinning(2, 0., 2.),
                                 title='Passed Both Boosted and Resolved',
                                 xTitle='Passed Boosted and Resolved')
        FailedBoth = Plot.make1D(
            "FailedBoth",  # Means failed the (Boosted AND Resolved) = either one or the other 
            op.c_int(0),
            hasNotBoostedAndResolvedJets,
            EquidistantBinning(2, 0., 2.),
            title='Failed combination Boosted and Resolved',
            xTitle='Failed combination')
        plots.append(
            SummedPlot("BoostedAndResolvedCase", [FailedBoth, PassedBoth],
                       xTitle="Boosted and Resolved selection"))

        # Count number of boosted and resolved jets #
        plots.append(
            Plot.make1D("NBoostedJets",
                        op.rng_len(bjetsBoosted),
                        hasBoostedJets,
                        EquidistantBinning(5, 0., 5.),
                        title='Number of boosted jets in boosted case',
                        xTitle='N boosted bjets'))
        plots.append(
            Plot.make1D(
                "NResolvedJets",
                op.rng_len(bjetsResolved),
                hasExlusiveResolvedJets,
                EquidistantBinning(5, 0., 5.),
                title='Number of resolved jets in exclusive resolved case',
                xTitle='N resolved bjets'))

        # Plot number of subjets in the boosted fatjets #
        lambda_noSubjet = lambda fatjet: op.AND(
            fatjet.subJet1._idx.result == -1,
            op.AND(fatjet.subJet2._idx.result == -1))
        lambda_oneSubjet = lambda fatjet: op.AND(
            fatjet.subJet1._idx.result != -1,
            op.AND(fatjet.subJet2._idx.result == -1))
        lambda_twoSubjet = lambda fatjet: op.AND(
            fatjet.subJet1._idx.result != -1,
            op.AND(fatjet.subJet2._idx.result != -1))

        hasNoSubjet = hasBoostedJets.refine(
            "hasNoSubjet", cut=[lambda_noSubjet(bjetsBoosted[0])])
        hasOneSubjet = hasBoostedJets.refine(
            "hasOneSubjet", cut=[lambda_oneSubjet(bjetsBoosted[0])])
        hasTwoSubjet = hasBoostedJets.refine(
            "hasTwoSubjet", cut=[lambda_twoSubjet(bjetsBoosted[0])])

        plot_hasNoSubjet = Plot.make1D(
            "plot_hasNoSubjet",  # Fill bin 0
            op.c_int(0),
            hasNoSubjet,
            EquidistantBinning(3, 0., 3.),
            title='Boosted jet without subjet')
        plot_hasOneSubjet = Plot.make1D(
            "plot_hasOneSubjet",  # Fill bin 1
            op.c_int(1),
            hasOneSubjet,
            EquidistantBinning(3, 0., 3.),
            title='Boosted jet with one subjet')
        plot_hasTwoSubjet = Plot.make1D(
            "plot_hasTwoSubjet",  # Fill bin 2
            op.c_int(2),
            hasTwoSubjet,
            EquidistantBinning(3, 0., 3.),
            title='Boosted jet with two subjets')
        plots.append(
            SummedPlot(
                "NumberOfSubjets",
                [plot_hasNoSubjet, plot_hasOneSubjet, plot_hasTwoSubjet],
                xTitle="Number of subjets in boosted jet"))

        # Plot jets quantities without the dilepton selections #
        plots += makeFatJetPlots(self,
                                 sel=hasBoostedJets,
                                 fatjet=bjetsBoosted[0],
                                 suffix="BoostedJets",
                                 channel="NoChannel")
        plots += makeJetsPlots(self,
                               sel=hasResolvedJets,
                               jets=bjetsResolved,
                               suffix="ResolvedJets",
                               channel="NoChannel")

        #############################################################################
        ##################### Jets + Dilepton combination ###########################
        #############################################################################
        # Combine dilepton and Resolved (Exclusive = NOT Boosted) selections #
        hasOsElElOutZResolvedJets = hasOsElElOutZ.refine(
            "hasOsElElOutZResolvedJets",
            cut=[
                op.rng_len(jets) >= 2,
                op.rng_len(bjetsResolved) >= 1,
                op.rng_len(bjetsBoosted) == 0
            ])
        hasOsMuMuOutZResolvedJets = hasOsMuMuOutZ.refine(
            "hasOsMuMuOutZResolvedJets",
            cut=[
                op.rng_len(jets) >= 2,
                op.rng_len(bjetsResolved) >= 1,
                op.rng_len(bjetsBoosted) == 0
            ])
        hasOsElMuOutZResolvedJets = hasOsElMuOutZ.refine(
            "hasOsElMuOutZResolvedJets",
            cut=[
                op.rng_len(jets) >= 2,
                op.rng_len(bjetsResolved) >= 1,
                op.rng_len(bjetsBoosted) == 0
            ])
        hasOsMuElOutZResolvedJets = hasOsMuElOutZ.refine(
            "hasOsMuElOutZResolvedJets",
            cut=[
                op.rng_len(jets) >= 2,
                op.rng_len(bjetsResolved) >= 1,
                op.rng_len(bjetsBoosted) == 0
            ])

        # Combine dilepton and Boosted selections #
        hasOsElElOutZBoostedJets = hasOsElElOutZ.refine(
            "hasOsElElOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1])
        hasOsMuMuOutZBoostedJets = hasOsMuMuOutZ.refine(
            "hasOsMuMuOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1])
        hasOsElMuOutZBoostedJets = hasOsElMuOutZ.refine(
            "hasOsElMuOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1])
        hasOsMuElOutZBoostedJets = hasOsMuElOutZ.refine(
            "hasOsMuElOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1])

        # Plot dilepton with OS, Z peak and Resolved jets selections #
        plots += makeDileptonPlots(self,
                                   sel=hasOsElElOutZResolvedJets,
                                   dilepton=OsElEl[0],
                                   suffix='hasOsdilep_OutZ_ResolvedJets',
                                   channel='ElEl')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuMuOutZResolvedJets,
                                   dilepton=OsMuMu[0],
                                   suffix='hasOsdilep_OutZ_ResolvedJets',
                                   channel='MuMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsElMuOutZResolvedJets,
                                   dilepton=OsElMu[0],
                                   suffix='hasOsdilep_OutZ_ResolvedJets',
                                   channel='ElMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuElOutZResolvedJets,
                                   dilepton=OsMuEl[0],
                                   suffix='hasOsdilep_OutZ_ResolvedJets',
                                   channel='MuEl')

        # Plot dilepton with OS dilepton, Z peak and Boosted jets selections #
        plots += makeDileptonPlots(self,
                                   sel=hasOsElElOutZBoostedJets,
                                   dilepton=OsElEl[0],
                                   suffix='hasOsdilep_OutZ_BoostedJets',
                                   channel='ElEl')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuMuOutZBoostedJets,
                                   dilepton=OsMuMu[0],
                                   suffix='hasOsdilep_OutZ_BoostedJets',
                                   channel='MuMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsElMuOutZBoostedJets,
                                   dilepton=OsElMu[0],
                                   suffix='hasOsdilep_OutZ_BoostedJets',
                                   channel='ElMu')
        plots += makeDileptonPlots(self,
                                   sel=hasOsMuElOutZBoostedJets,
                                   dilepton=OsMuEl[0],
                                   suffix='hasOsdilep_OutZ_BoostedJets',
                                   channel='MuEl')

        # Plotting the fatjet for OS dilepton, Z peak and Boosted jets selections #
        plots += makeFatJetPlots(self,
                                 sel=hasOsElElOutZBoostedJets,
                                 fatjet=bjetsBoosted[0],
                                 suffix="hasOsdilep_OutZ_BoostedJets",
                                 channel="ElEl")
        plots += makeFatJetPlots(self,
                                 sel=hasOsMuMuOutZBoostedJets,
                                 fatjet=bjetsBoosted[0],
                                 suffix="hasOsdilep_OutZ_BoostedJets",
                                 channel="MuMu")
        plots += makeFatJetPlots(self,
                                 sel=hasOsElMuOutZBoostedJets,
                                 fatjet=bjetsBoosted[0],
                                 suffix="hasOsdilep_OutZ_BoostedJets",
                                 channel="ElMu")
        plots += makeFatJetPlots(self,
                                 sel=hasOsMuElOutZBoostedJets,
                                 fatjet=bjetsBoosted[0],
                                 suffix="hasOsdilep_OutZ_BoostedJets",
                                 channel="MuEl")

        # Plotting the jets for OS dilepton, Z peak and Resolved jets selections #
        plots += makeJetsPlots(self,
                               sel=hasOsElElOutZResolvedJets,
                               jets=bjetsResolved,
                               suffix="hasOsdilep_OutZ_ResolvedJets",
                               channel="ElEl")
        plots += makeJetsPlots(self,
                               sel=hasOsMuMuOutZResolvedJets,
                               jets=bjetsResolved,
                               suffix="hasOsdilep_OutZ_ResolvedJets",
                               channel="MuMu")
        plots += makeJetsPlots(self,
                               sel=hasOsElMuOutZResolvedJets,
                               jets=bjetsResolved,
                               suffix="hasOsdilep_OutZ_ResolvedJets",
                               channel="ElMu")
        plots += makeJetsPlots(self,
                               sel=hasOsMuElOutZResolvedJets,
                               jets=bjetsResolved,
                               suffix="hasOsdilep_OutZ_ResolvedJets",
                               channel="MuEl")

        ## helper selection (OR) to make sure jet calculations are only done once
        #hasOSLL = noSel.refine("hasOSLL", cut=op.OR(*( hasOSLL_cmbRng(rng) for rng in osLLRng.values())))
        #forceDefine(t._Jet.calcProd, hasOSLL)
        #for varNm in t._Jet.available:
        #    forceDefine(t._Jet[varNm], hasOSLL)
        return plots
Example #3
0
def returnHighLevelMVAInputs(self,l1,l2,met,jets,bjets,electrons,muons,channel):
    if channel == "ElEl":
        cone_l1 = self.getElectronConeP4(l1) 
        cone_l2 = self.getElectronConeP4(l2)
    elif channel == "MuMu":
        cone_l1 = self.getMuonConeP4(l1)
        cone_l2 = self.getMuonConeP4(l2)
    elif channel == "ElMu":
        cone_l1 = self.getElectronConeP4(l1)
        cone_l2 = self.getMuonConeP4(l2)
    else:
        raise RuntimeError("Wrong channel")

    dijets = op.combine(jets, N=2)

    import bamboo.treeoperations as _to
    def rng_min(rng, fun=(lambda x : x), typeName="float"):
        return op._to.Reduce.fromRngFun(rng, op.c_float(float("+inf"), typeName), ( lambda fn : (
                lambda res, elm : op.extMethod("std::min", returnType="Float_t")(res, fn(elm))
                        ) )(fun) )

    if self.args.Boosted0Btag or self.args.Boosted1Btag:
        VBFJetPairs = self.VBFJetPairsBoosted
    elif self.args.Resolved0Btag or self.args.Resolved1Btag or self.args.Resolved2Btag:
        VBFJetPairs = self.VBFJetPairsResolved
    else:
        raise RuntimeError("Wrong selection to be used by the DNN")

    return {
            ('m_bb_bregcorr',          'Di-bjet invariant mass (regcorr) [GeV]',  (100,0.,1000.))   : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)),
                                                                                                                     (op.rng_len(bjets) == 1, self.HLL.getCorrBp4(bjets[0]).M()),
                                                                                                                     op.invariant_mass(self.HLL.getCorrBp4(bjets[0]),self.HLL.getCorrBp4(bjets[1]))),
            ('ht',                     'HT(jets) [GeV]',                          (100,0.,1000.))   : op.rng_sum(jets, lambda j : j.pt),
            ('min_dr_jets_lep1',       'Min(#Delta R(lead lepton,jets))',         (25,0.,5.))       : op.switch(op.rng_len(jets) > 0,
                                                                                                                op.switch(cone_l1.Pt() >= cone_l2.Pt(),
                                                                                                                          self.HLL.MinDR_part1_partCont(cone_l1,jets),
                                                                                                                          self.HLL.MinDR_part1_partCont(cone_l2,jets)),
                                                                                                                op.c_float(0.)),
            ('min_dr_jets_lep2',       'Min(#Delta R(sublead lepton,jets))',      (25,0.,5.))       : op.switch(op.rng_len(jets) > 0,
                                                                                                                op.switch(cone_l1.Pt() >= cone_l2.Pt(),
                                                                                                                          self.HLL.MinDR_part1_partCont(cone_l2,jets),
                                                                                                                          self.HLL.MinDR_part1_partCont(cone_l1,jets)),
                                                                                                                op.c_float(0.)),
            ('m_ll',                   'Dilepton invariant mass [GeV]',           (100,0.,1000.))   : op.invariant_mass(cone_l1,cone_l2),
            ('dr_ll',                  'Dilepton #Delta R',                       (25,0.,5.))       : op.deltaR(cone_l1,cone_l2),
            ('min_dr_jet',             'Min(#Delta R(jets))',                     (25,0.,5.))       : op.switch(op.rng_len(dijets) > 0,
                                                                                                                op.rng_min(dijets,lambda dijet : op.deltaR(dijet[0].p4,dijet[1].p4)),
                                                                                                                op.c_float(0.)),
            ('min_dhi_jet',            'Min(#Delta #Phi(jets))',                  (16,0.,3.2))      : op.switch(op.rng_len(dijets) > 0,
                                                                                                                rng_min(dijets,lambda dijet : op.abs(op.deltaPhi(dijet[0].p4,dijet[1].p4)),typeName='double'),
                                                                                                                op.c_float(0.)),
            ('m_hh_simplemet_bregcorr','M_{HH} (simple MET) (regcorr) [GeV]',     (100,0.,1000.))   : op.invariant_mass(op.rng_sum(bjets,
                                                                                                                                   lambda bjet : self.HLL.getCorrBp4(bjet),
                                                                                                                                   start=self.HLL.empty_p4),
                                                                                                                        cone_l1,
                                                                                                                        cone_l2,
                                                                                                                        met.p4),
            ('met_ld',                 'MET_{LD}',                                (100,0.,1000.))   : self.HLL.MET_LD_DL(met,jets,electrons,muons),
            ('dr_bb',                  'Di-bjet #Delta R',                        (25,0.,5.))       : op.switch(op.rng_len(bjets)>=2,
                                                                                                                op.deltaR(bjets[0].p4,bjets[1].p4),
                                                                                                                op.c_float(0.)),
            ('min_dr_leps_b1',         'Min(#Delta R(lead bjet,dilepton))',       (25,0.,5.))       : op.switch(op.rng_len(bjets)>=1,
                                                                                                                self.HLL.MinDR_part1_dipart(bjets[0].p4,[cone_l1,cone_l2]),
                                                                                                                op.c_float(0.)),
            ('min_dr_leps_b2',         'Min(#Delta R(sublead bjet,dilepton))',    (25,0.,5.))       : op.switch(op.rng_len(bjets)>=2,
                                                                                                                self.HLL.MinDR_part1_dipart(bjets[1].p4,[cone_l1,cone_l2]),
                                                                                                                op.c_float(0.)),
            ('lep1_conept',            'Lead lepton cone-P_T [GeV]',              (40,0.,200.))     : op.switch(cone_l1.Pt() >= cone_l2.Pt() , cone_l1.Pt() , cone_l2.Pt()),
            ('lep2_conept',            'Sublead lepton cone-P_T [GeV]',           (40,0.,200.))     : op.switch(cone_l1.Pt() >= cone_l2.Pt() , cone_l2.Pt() , cone_l1.Pt()),
            ('mww_simplemet',          'M_{WW} (simple MET) [GeV]',               (100,0.,1000.))   : op.invariant_mass(cone_l1,cone_l2,met.p4),
            ('vbf_tag',                'VBF tag',                                 (2,0.,2.))        : op.c_int(op.rng_len(VBFJetPairs)>0),
            ('boosted_tag',            'Boosted tag',                             (2,0.,2.))        : op.c_int(op.OR(op.rng_len(self.ak8BJets) > 0,           # Boosted 1B
                                                                                                                     op.AND(op.rng_len(self.ak8BJets) == 0,   # Boosted 0B
                                                                                                                            op.rng_len(self.ak8Jets) > 0,
                                                                                                                            op.rng_len(self.ak4BJets) == 0))),
            ('dphi_met_dilep',         'Dilepton-MET #Delta #Phi',                (32,-3.2,3.2))    : op.abs(op.deltaPhi(met.p4,(cone_l1+cone_l2))),
            ('dphi_met_dibjet',        'Dibjet-MET #Delta #Phi',                  (32,-3.2,3.2))    : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)),
                                                                                                                     (op.rng_len(bjets) == 1, op.abs(op.deltaPhi(met.p4,bjets[0].p4))),
                                                                                                                     op.abs(op.deltaPhi(met.p4,(bjets[0].p4+bjets[1].p4)))),
            ('dr_dilep_dijet',         'Dilepton-dijet #Delta R',                 (25,0.,5.))       : op.multiSwitch((op.rng_len(jets) == 0, op.c_float(0.)),
                                                                                                                     (op.rng_len(jets) == 1, op.deltaR((cone_l1+cone_l2),jets[0].p4)),
                                                                                                                     op.deltaR((cone_l1+cone_l2),(jets[0].p4+jets[1].p4))),
            ('dr_dilep_dibjet',        'Dilepton-dibjet #Delta R',                (25,0.,5.))       : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)),
                                                                                                                     (op.rng_len(bjets) == 1, op.deltaR((cone_l1+cone_l2),bjets[0].p4)),
                                                                                                                     op.deltaR((cone_l1+cone_l2),(bjets[0].p4+bjets[1].p4))),
            ('vbf_pair_mass',          'VBF pair M_{jj}',                         (100,0.,1000.))   : op.switch(op.rng_len(VBFJetPairs)>0,
                                                                                                                op.invariant_mass(VBFJetPairs[0][0].p4,VBFJetPairs[0][1].p4),
                                                                                                                op.c_float(0.)),
            ('vbf_pairs_absdeltaeta',  'VBF pair #Delta#eta',                     (25,0.,5.))       : op.switch(op.rng_len(VBFJetPairs)>0,
                                                                                                                op.abs(VBFJetPairs[0][0].eta-VBFJetPairs[0][1].eta),
                                                                                                                op.c_float(0.)),
            ('sphericity',             'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('sphericity_T',           'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('aplanarity',             'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('eventshape_C',           'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('eventshape_D',           'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('eventshape_Y',           'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('foxwolfram1',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('foxwolfram2',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('foxwolfram3',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('foxwolfram4',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('foxwolfram5',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('centrality',             'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('centrality_jets',        'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('eigenvalue1',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('eigenvalue2',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            ('eigenvalue3',            'None',                                    (1,0.,1.))        : op.c_float(0.),
            }
Example #4
0
def returnParamMVAInputs(self):
    if self.args.era is None:
        return {('year',     'Year',         (3,2016.,2019.))    : op.c_int(int(self.era))}
    else:
        return {('year',     'Year',         (3,2016.,2019.))    : op.c_int(int(self.args.era))}
    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
Example #6
0
    def __init__(self, rawMET, pv, sample, era, isMC):
        if (era == '2016'):
            if isMC:
                xcorr = (0.195191, 0.170948)
                ycorr = (0.0311891, -0.787627)
            else:
                if '2016B' in sample:
                    xcorr = (0.0478335, 0.108032)
                    ycorr = (-0.125148, -0.355672)
                elif '2016C' in sample:
                    xcorr = (0.0916985, -0.393247)
                    ycorr = (-0.151445, -0.114491)
                elif '2016D' in sample:
                    xcorr = (0.0581169, -0.567316)
                    ycorr = (-0.147549, -0.403088)
                elif '2016E' in sample:
                    xcorr = (0.065622, -0.536856)
                    ycorr = (-0.188532, -0.495346)
                elif '2016F' in sample:
                    xcorr = (0.0313322, -0.39866)
                    ycorr = (-0.16081, -0.960177)
                elif '2016G' in sample:
                    xcorr = (-0.040803, 0.290384)
                    ycorr = (-0.0961935, -0.666096)
                else:
                    xcorr = (-0.0330868, 0.209534)
                    ycorr = (-0.141513, -0.816732)

        elif (era == '2017'):
            if isMC:
                xcorr = (0.217714, -0.493361)
                ycorr = (-0.177058, 0.336648)
            #these are the corrections for v2 MET recipe (currently recommended for 2017)
            else:
                if '2017B' in sample:
                    xcorr = (0.19563, -1.51859)
                    ycorr = (-0.306987, 1.84713)
                elif '2017C' in sample:
                    xcorr = (0.161661, -0.589933)
                    ycorr = (-0.233569, 0.995546)
                elif '2017D' in sample:
                    xcorr = (0.180911, -1.23553)
                    ycorr = (-0.240155, 1.27449)
                elif '2017E' in sample:
                    xcorr = (0.149494, -0.901305)
                    ycorr = (-0.178212, 0.535537)
                else:
                    xcorr = (0.165154, -1.02018)
                    ycorr = (-0.253794, -0.75776)
        elif (era == '2018'):
            if isMC:
                xcorr = (-0.296713, 0.141506)
                ycorr = (-0.115685, -0.0128193)
            else:
                if '2018A' in sample:
                    xcorr = (-0.362865, 1.94505)
                    ycorr = (-0.0709085, 0.307365)
                elif '2018B' in sample:
                    xcorr = (-0.492083, 2.93552)
                    ycorr = (-0.17874, 0.786844)
                elif '2018C' in sample:
                    xcorr = (-0.521349, 1.44544)
                    ycorr = (-0.118956, 1.96434)
                else:
                    xcorr = (-0.531151, 1.37568)
                    ycorr = (-0.0884639, 1.57089)

        METxcorr = xcorr[0] * op.min(pv.npvs, op.c_int(100)) + xcorr[1]
        METycorr = ycorr[0] * op.min(pv.npvs, op.c_int(100)) + ycorr[1]

        corrMETx = rawMET.pt * op.cos(rawMET.phi) + METxcorr
        corrMETy = rawMET.pt * op.sin(rawMET.phi) + METycorr

        atan = op.atan(corrMETy / corrMETx)

        self.pt = op.sqrt(corrMETx**2 + corrMETy**2)
        self.eta = op.c_float(0.)
        self.phi = op.multiSwitch((corrMETx > 0, atan),
                                  (corrMETy > 0, atan + math.pi),
                                  atan - math.pi)
        self.M = op.c_float(0.)

        #self.p4 = op.construct("ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> >",
        #                (corrMETx,corrMETy,op.c_float(0.),op.sqrt(corrMETx**2 +corrMETy**2)))
        self.p4 = op.construct(
            "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >",
            (self.pt, self.eta, self.phi, self.M))
def returnResonantMVAInputs(self, l1, l2, channel, jets, bjets, fatjets, met,
                            electrons, muons):
    if channel == "ElEl":
        l1conept = lambda l1: self.electron_conept[l1.idx]
        l2conept = lambda l2: self.electron_conept[l2.idx]
    elif channel == "MuMu":
        l1conept = lambda l1: self.muon_conept[l1.idx]
        l2conept = lambda l2: self.muon_conept[l2.idx]
    elif channel == "ElMu":
        l1conept = lambda l1: self.electron_conept[l1.idx]
        l2conept = lambda l2: self.muon_conept[l2.idx]
    else:
        raise RuntimeError("Wrong channel")

    dijets = op.combine(jets, N=2)

    import bamboo.treeoperations as _to

    def rng_min(rng, fun=(lambda x: x), typeName="float"):
        return op._to.Reduce.fromRngFun(
            rng, op.c_float(float("+inf"), typeName),
            (lambda fn:
             (lambda res, elm: op.extMethod("std::min", returnType="Float_t")
              (res, fn(elm))))(fun))

    if self.args.era is None:
        era = op.c_int(int(self.era))
    else:
        era = op.c_int(int(self.args.era))
        print(f'Using {self.args.era} as DNN input')

    return {
        ('eventnr', 'Event number', (100, 0., 1e6)):
        self.tree.event,
        ('era', 'Era', (3, 2016., 2019.)):
        era,
        ('l1_E', 'Lead lepton E [GeV]', (50, 0., 500.)):
        op.switch(l1conept(l1) >= l2conept(l2), l1.p4.E(), l2.p4.E()),
        ('l1_Px', 'Lead lepton P_x [GeV]', (40, -200., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Px(), l2.p4.Px()),
        ('l1_Py', 'Lead lepton P_y [GeV]', (40, -200., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Py(), l2.p4.Py()),
        ('l1_Pz', 'Lead lepton P_z [GeV]', (40, -200., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Pz(), l2.p4.Pz()),
        ('l1_charge', 'Lead lepton charge', (2, 0., 2.)):
        op.switch(l1conept(l1) >= l2conept(l2), l1.charge, l2.charge),
        ('l1_pdgId', 'Lead lepton pdg ID', (45, -22., 22.)):
        op.switch(l1conept(l1) >= l2conept(l2), l1.pdgId, l2.pdgId),
        ('l2_E', 'Sublead lepton E [GeV]', (50, 0., 500.)):
        op.switch(l1conept(l1) >= l2conept(l2), l2.p4.E(), l1.p4.E()),
        ('l2_Px', 'Sublead lepton P_x [GeV]', (40, -200., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Px(), l1.p4.Px()),
        ('l2_Py', 'Sublead lepton P_y [GeV]', (40, -200., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Py(), l1.p4.Py()),
        ('l2_Pz', 'Sublead lepton P_z [GeV]', (40, -200., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Pz(), l1.p4.Pz()),
        ('l2_charge', 'Sublead lepton charge', (2, 0., 2.)):
        op.switch(l1conept(l1) >= l2conept(l2), l2.charge, l1.charge),
        ('l2_pdgId', 'Sublead lepton pdg ID', (45, -22., 22.)):
        op.switch(l1conept(l1) >= l2conept(l2), l2.pdgId, l1.pdgId),
        ('j1_E', 'Lead jet E [GeV]', (50, 0., 500.)):
        op.switch(op.rng_len(jets) > 0, jets[0].p4.E(), op.c_float(0.)),
        ('j1_Px', 'Lead jet P_x [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 0, jets[0].p4.Px(), op.c_float(0.)),
        ('j1_Py', 'Lead jet P_y [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 0, jets[0].p4.Py(), op.c_float(0.)),
        ('j1_Pz', 'Lead jet P_z [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 0, jets[0].p4.Pz(), op.c_float(0.)),
        ('j2_E', 'Sublead jet E [GeV]', (50, 0., 500.)):
        op.switch(op.rng_len(jets) > 1, jets[1].p4.E(), op.c_float(0.)),
        ('j2_Px', 'Sublead jet P_x [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 1, jets[1].p4.Px(), op.c_float(0.)),
        ('j2_Py', 'Sublead jet P_y [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 1, jets[1].p4.Py(), op.c_float(0.)),
        ('j2_Pz', 'Sublead jet P_z [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 1, jets[1].p4.Pz(), op.c_float(0.)),
        ('j3_E', 'Subsublead jet E [GeV]', (50, 0., 500.)):
        op.switch(op.rng_len(jets) > 2, jets[2].p4.E(), op.c_float(0.)),
        ('j3_Px', 'Subsublead jet P_x [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 2, jets[2].p4.Px(), op.c_float(0.)),
        ('j3_Py', 'Subsublead jet P_y [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 2, jets[2].p4.Py(), op.c_float(0.)),
        ('j3_Pz', 'Subsublead jet P_z [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 2, jets[2].p4.Pz(), op.c_float(0.)),
        ('j4_E', 'Subsubsublead jet E [GeV]', (50, 0., 500.)):
        op.switch(op.rng_len(jets) > 3, jets[3].p4.E(), op.c_float(0.)),
        ('j4_Px', 'Subsubsublead jet P_x [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 3, jets[3].p4.Px(), op.c_float(0.)),
        ('j4_Py', 'Subsubsublead jet P_y [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 3, jets[3].p4.Py(), op.c_float(0.)),
        ('j4_Pz', 'Subsubsublead jet P_z [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(jets) > 3, jets[3].p4.Pz(), op.c_float(0.)),
        ('fatjet_E', 'Fatjet E [GeV]', (50, 0., 500.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.E(), op.c_float(0.)),
        ('fatjet_Px', 'Fatjet P_x [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.Px(), op.c_float(0.)),
        ('fatjet_Py', 'Fatjet P_y [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.Py(), op.c_float(0.)),
        ('fatjet_Pz', 'Fatjet P_z [GeV]', (40, -200., 200.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.Pz(), op.c_float(0.)),
        ('fatjet_tau1', 'Fatjet #tau_1', (50, 0., 1.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau1, op.c_float(0.)),
        ('fatjet_tau2', 'Fatjet #tau_2', (50, 0., 1.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau2, op.c_float(0.)),
        ('fatjet_tau3', 'Fatjet #tau_3', (50, 0., 1.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau3, op.c_float(0.)),
        ('fatjet_tau4', 'Fatjet #tau_4', (50, 0., 1.)):
        op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau4, op.c_float(0.)),
        ('fatjet_softdrop', 'Fatjet softdrop mass [GeV]', (50, 0., 1000.)):
        op.switch(
            op.rng_len(fatjets) > 0, fatjets[0].msoftdrop, op.c_float(0.)),
        ('met_E', 'MET Energy', (50, 0., 500.)):
        met.p4.E(),
        ('met_Px', 'MET P_x', (40, -200., 200.)):
        met.p4.Px(),
        ('met_Py', 'MET P_y', (40, -200., 200.)):
        met.p4.Py(),
        ('met_Pz', 'MET P_z', (40, -200., 200.)):
        met.p4.Pz(),
        ('m_bb_bregcorr', 'Di-bjet invariant mass (regcorr) [GeV]', (100, 0., 1000.)):
        op.multiSwitch(
            (op.rng_len(bjets) == 0, op.c_float(0.)),
            (op.rng_len(bjets) == 1, self.HLL.getCorrBp4(bjets[0]).M()),
            op.invariant_mass(self.HLL.getCorrBp4(bjets[0]),
                              self.HLL.getCorrBp4(bjets[1]))),
        ('ht', 'HT(jets) [GeV]', (100, 0., 1000.)):
        op.rng_sum(jets, lambda j: j.pt),
        ('min_dr_jets_lep1', 'Min(#Delta R(lead lepton,jets))', (25, 0., 5.)):
        op.switch(
            op.rng_len(jets) > 0,
            op.switch(
                l1conept(l1) >= l2conept(l2),
                self.HLL.MinDR_part1_partCont(l1.p4, jets),
                self.HLL.MinDR_part1_partCont(l2.p4, jets)), op.c_float(0.)),
        ('min_dr_jets_lep2', 'Min(#Delta R(sublead lepton,jets))', (25, 0., 5.)):
        op.switch(
            op.rng_len(jets) > 0,
            op.switch(
                l1conept(l1) >= l2conept(l2),
                self.HLL.MinDR_part1_partCont(l2.p4, jets),
                self.HLL.MinDR_part1_partCont(l1.p4, jets)), op.c_float(0.)),
        ('m_ll', 'Dilepton invariant mass [GeV]', (100, 0., 1000.)):
        op.invariant_mass(l1.p4, l2.p4),
        ('dr_ll', 'Dilepton #Delta R', (25, 0., 5.)):
        op.deltaR(l1.p4, l2.p4),
        ('min_dr_jet', 'Min(#Delta R(jets))', (25, 0., 5.)):
        op.switch(
            op.rng_len(dijets) > 0,
            op.rng_min(dijets,
                       lambda dijet: op.deltaR(dijet[0].p4, dijet[1].p4)),
            op.c_float(0.)),
        ('min_dphi_jet', 'Min(#Delta #Phi(jets))', (16, 0., 3.2)):
        op.switch(
            op.rng_len(dijets) > 0,
            rng_min(
                dijets,
                lambda dijet: op.abs(op.deltaPhi(dijet[0].p4, dijet[1].p4)),
                typeName='double'), op.c_float(0.)),
        ('m_hh_simplemet_bregcorr', 'M_{HH} (simple MET) (regcorr) [GeV]', (100, 0., 1000.)):
        op.invariant_mass(
            op.rng_sum(bjets,
                       lambda bjet: self.HLL.getCorrBp4(bjet),
                       start=self.HLL.empty_p4), l1.p4, l2.p4, met.p4),
        ('met_ld', 'MET_{LD}', (100, 0., 1000.)):
        self.HLL.MET_LD_DL(met, jets, electrons, muons),
        ('dr_bb', 'Di-bjet #Delta R', (25, 0., 5.)):
        op.switch(
            op.rng_len(bjets) >= 2, op.deltaR(bjets[0].p4, bjets[1].p4),
            op.c_float(0.)),
        ('min_dr_leps_b1', 'Min(#Delta R(lead bjet,dilepton))', (25, 0., 5.)):
        op.switch(
            op.rng_len(bjets) >= 1,
            self.HLL.MinDR_part1_dipart(bjets[0].p4, [l1.p4, l2.p4]),
            op.c_float(0.)),
        ('min_dr_leps_b2', 'Min(#Delta R(sublead bjet,dilepton))', (25, 0., 5.)):
        op.switch(
            op.rng_len(bjets) >= 2,
            self.HLL.MinDR_part1_dipart(bjets[1].p4, [l1.p4, l2.p4]),
            op.c_float(0.)),
        ('lep1_conept', 'Lead lepton cone-P_T [GeV]', (40, 0., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l1conept(l1), l2conept(l2)),
        ('lep2_conept', 'Sublead lepton cone-P_T [GeV]', (40, 0., 200.)):
        op.switch(l1conept(l1) >= l2conept(l2), l2conept(l2), l1conept(l1)),
        ('mww_simplemet', 'M_{WW} (simple MET) [GeV]', (100, 0., 1000.)):
        op.invariant_mass(l1.p4, l2.p4, met.p4),
        ('boosted_tag', 'Boosted tag', (2, 0., 2.)):
        op.c_int(
            op.OR(
                op.rng_len(self.ak8BJets) > 0,  # Boosted 1B
                op.AND(
                    op.rng_len(self.ak8BJets) == 0,  # Boosted 0B
                    op.rng_len(self.ak8Jets) > 0,
                    op.rng_len(self.ak4BJets) == 0))),
        ('dphi_met_dilep', 'Dilepton-MET #Delta #Phi', (32, -3.2, 3.2)):
        op.abs(op.deltaPhi(met.p4, (l1.p4 + l2.p4))),
        ('dphi_met_dibjet', 'Dibjet-MET #Delta #Phi', (32, -3.2, 3.2)):
        op.multiSwitch(
            (op.rng_len(bjets) == 0, op.c_float(0.)),
            (op.rng_len(bjets) == 1, op.abs(op.deltaPhi(met.p4, bjets[0].p4))),
            op.abs(op.deltaPhi(met.p4, (bjets[0].p4 + bjets[1].p4)))),
        ('dr_dilep_dijet', 'Dilepton-dijet #Delta R', (25, 0., 5.)):
        op.multiSwitch(
            (op.rng_len(jets) == 0, op.c_float(0.)),
            (op.rng_len(jets) == 1, op.deltaR((l1.p4 + l2.p4), jets[0].p4)),
            op.deltaR((l1.p4 + l2.p4), (jets[0].p4 + jets[1].p4))),
        ('dr_dilep_dibjet', 'Dilepton-dibjet #Delta R', (25, 0., 5.)):
        op.multiSwitch(
            (op.rng_len(bjets) == 0, op.c_float(0.)),
            (op.rng_len(bjets) == 1, op.deltaR((l1.p4 + l2.p4), bjets[0].p4)),
            op.deltaR((l1.p4 + l2.p4), (bjets[0].p4 + bjets[1].p4))),
        ('m_T', 'Transverse mass', (100, 0., 1000.)):
        op.sqrt(2 * (l1.p4 + l2.p4).Pt() * met.p4.E() *
                (1 - op.cos((l1.p4 + l2.p4).Phi() - met.p4.Phi()))),
        ('cosThetaS_Hbb', 'Helicity angle between Hbb and bjet', (20, 0., 1.)):
        op.switch(
            op.rng_len(bjets) == 2,
            op.extMethod("HHbbWWJPA::cosThetaS",
                         returnType="float")(bjets[0].p4, bjets[1].p4),
            op.c_float(0.)),
        ('LBN_inputs', 'LBN inputs', None): [
            op.switch(l1conept(l1) >= l2conept(l2), l1.p4.E(), l2.p4.E()),
            op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Px(), l2.p4.Px()),
            op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Py(), l2.p4.Py()),
            op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Pz(), l2.p4.Pz()),
            op.switch(l1conept(l1) >= l2conept(l2), l2.p4.E(), l1.p4.E()),
            op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Px(), l1.p4.Px()),
            op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Py(), l1.p4.Py()),
            op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Pz(), l1.p4.Pz()),
            op.switch(op.rng_len(jets) > 0, jets[0].p4.E(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 0, jets[0].p4.Px(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 0, jets[0].p4.Py(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 0, jets[0].p4.Pz(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 1, jets[1].p4.E(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 1, jets[1].p4.Px(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 1, jets[1].p4.Py(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 1, jets[1].p4.Pz(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 2, jets[2].p4.E(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 2, jets[2].p4.Px(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 2, jets[2].p4.Py(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 2, jets[2].p4.Pz(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 3, jets[3].p4.E(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 3, jets[3].p4.Px(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 3, jets[3].p4.Py(), op.c_float(0.)),
            op.switch(op.rng_len(jets) > 3, jets[3].p4.Pz(), op.c_float(0.)),
            op.switch(
                op.rng_len(fatjets) > 0, fatjets[0].p4.E(), op.c_float(0.)),
            op.switch(
                op.rng_len(fatjets) > 0, fatjets[0].p4.Px(), op.c_float(0.)),
            op.switch(
                op.rng_len(fatjets) > 0, fatjets[0].p4.Py(), op.c_float(0.)),
            op.switch(
                op.rng_len(fatjets) > 0, fatjets[0].p4.Pz(), op.c_float(0.))
        ]
    }
Example #8
0
    def defineSkimSelection(self, t, noSel, sample=None, sampleCfg=None):
        noSel = super(SkimmerHME, 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()

        #---------------------------------------------------------------------------------------#
        #                                     Selections                                        #
        #---------------------------------------------------------------------------------------#
        #----- Check arguments -----#
        jet_level = [
            "Ak4", "Ak8", "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]
        elif self.args.Channel == "MuMu":
            selObj = MuMuSelObj
            dilepton = self.MuMuFakeSel[0]
        elif self.args.Channel == "ElMu":
            selObj = ElMuSelObj
            dilepton = self.ElMuFakeSel[0]
        else:
            raise RuntimeError("You need to specify --Channel")

        #----- HME -----#
        if self.args.analysis != 'res':
            raise RuntimeError("This part of the Skimmer is only for resonant")

        #----- Apply jet corrections -----#
        ElElSelObj.sel = self.beforeJetselection(ElElSelObj.sel, 'ElEl')
        MuMuSelObj.sel = self.beforeJetselection(MuMuSelObj.sel, 'MuMu')
        ElMuSelObj.sel = self.beforeJetselection(ElMuSelObj.sel, 'ElMu')

        #----- 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,
                                                  dy_selection=self.args.DYCR)
        if self.args.Resolved2Btag:
            makeExclusiveResolvedTwoBtagsSelection(self,
                                                   selObj,
                                                   use_dd=False,
                                                   dy_selection=self.args.DYCR)
        if self.args.Boosted0Btag:
            makeInclusiveBoostedNoBtagSelection(self, selObj, use_dd=False)
        if self.args.Boosted1Btag:
            makeInclusiveBoostedOneBtagSelection(self,
                                                 selObj,
                                                 use_dd=False,
                                                 dy_selection=self.args.DYCR)

        #----- HME ----#
        if self.args.Resolved1Btag or self.args.Resolved2Btag:
            HME, HME_eff = self.computeResolvedHMEAfterLeptonSelections(
                sel=selObj.sel,
                l1=dilepton[0],
                l2=dilepton[1],
                bjets=self.ak4JetsByBtagScore,
                met=self.corrMET)
        elif self.args.Boosted1Btag:
            HME, HME_eff = self.computeBoostedHMEAfterLeptonSelections(
                sel=selObj.sel,
                l1=dilepton[0],
                l2=dilepton[1],
                fatjets=self.ak8BJets,
                met=self.corrMET)
        else:
            raise RuntimeError("Wrong category for resonant HME computations")

        varsToKeep["HME"] = HME
        varsToKeep["HME_eff"] = HME_eff

        #----- Additional variables -----#
        varsToKeep['era'] = op.c_int(int(self.era))
        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(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
    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
Example #11
0
def returnHighLevelMVAInputs(self, lep, conep4, bjets, wjets, VBFJetPairs, channel):
    if channel == 'El':
        lepconept  = self.electron_conept[lep.idx]
    elif channel == 'Mu':
        lepconept  = self.muon_conept[lep.idx]
    else:
        raise RuntimeError('Please mention the correct channel name!')

    import bamboo.treeoperations as _to
    def rng_min(rng, fun=(lambda x : x), typeName="float"):
        return op._to.Reduce.fromRngFun(rng, op.c_float(float("+inf"), typeName), ( lambda fn : (
            lambda res, elm : op.extMethod("std::min", returnType="Float_t")(res, fn(elm))
        ) )(fun) )

    
    return {
        #('m_hh_bregcorr',    'm_hh_bregcorr',     (50,0,400))  : self.HLL.comp_m_hh_bregcorr(bjets, wjets, lep, self.corrMET),
        ('m_hh_bregcorr',    'm_hh_bregcorr',     (50,0,400))  : self.HLL.comp_m_hh_bregcorr(bjets, wjets, conep4, self.corrMET),
        #('pt_hh',            'pt_hh',             (50,0,400))  : self.HLL.comp_pt_hh(bjets, wjets, lep, self.corrMET),
        ('pt_hh',            'pt_hh',             (50,0,400))  : self.HLL.comp_pt_hh(bjets, wjets, conep4, self.corrMET),
        ('m_hbb_bregcorr',   'm_hbb_bregcorr',    (25,0,200))  : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)),
                                                                                (op.rng_len(bjets) == 1, self.HLL.getCorrBp4(bjets[0]).M()),
                                                                                op.invariant_mass(self.HLL.getCorrBp4(bjets[0]),self.HLL.getCorrBp4(bjets[1]))),
        ('pt_hbb',           'pt_hbb',            (25,0,200))  : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)),
                                                                                (op.rng_len(bjets) == 1, bjets[0].pt),
                                                                                (bjets[0].p4 + bjets[1].p4).Pt()),
        #('m_hww',            'm_hww',             (25,0,200))  : op.multiSwitch((op.rng_len(wjets) >= 2, op.invariant_mass(wjets[0].p4 ,wjets[1].p4, self.corrMET.p4, lep.p4)),
        #                                                                        (op.rng_len(wjets) == 1, op.invariant_mass(wjets[0].p4 ,self.corrMET.p4, lep.p4)),
        #                                                                        op.invariant_mass(self.corrMET.p4, lep.p4)),
        ('m_hww',            'm_hww',             (25,0,200))  : op.multiSwitch((op.rng_len(wjets) >= 2, op.invariant_mass(wjets[0].p4 ,wjets[1].p4, self.corrMET.p4, conep4)),
                                                                                (op.rng_len(wjets) == 1, op.invariant_mass(wjets[0].p4 ,self.corrMET.p4, conep4)),
                                                                                op.invariant_mass(self.corrMET.p4, conep4)),
        #('pt_hww',           'pt_hww',            (25,0,200))  : op.multiSwitch((op.rng_len(wjets) >= 2, (wjets[0].p4 + wjets[1].p4 + self.corrMET.p4 + lep.p4).Pt()),
        #                                                                        (op.rng_len(wjets) == 1, (wjets[0].p4 + self.corrMET.p4 + lep.p4).Pt()),
        #                                                                        (self.corrMET.p4 + lep.p4).Pt()),
        ('pt_hww',           'pt_hww',            (25,0,200))  : op.multiSwitch((op.rng_len(wjets) >= 2, (wjets[0].p4 + wjets[1].p4 + self.corrMET.p4 + conep4).Pt()),
                                                                                (op.rng_len(wjets) == 1, (wjets[0].p4 + self.corrMET.p4 + conep4).Pt()),
                                                                                (self.corrMET.p4 + conep4).Pt()),
        ('m_wjj',            'm_wjj',             (25,0,200))  : op.multiSwitch((op.rng_len(wjets) >= 2, op.invariant_mass(wjets[0].p4 ,wjets[1].p4)),
                                                                                (op.rng_len(wjets) == 1, wjets[0].mass),
                                                                                op.c_float(0.)),
        ('pt_wjj',           'pt_wjj',            (25,0,200))  : op.multiSwitch((op.rng_len(wjets) >= 2, (wjets[0].p4 + wjets[1].p4).Pt()),
                                                                                (op.rng_len(wjets) == 1, wjets[0].pt),
                                                                                op.c_float(0.)),
        #('m_wlep',           'm_wlep',            (25,0,200))  : op.invariant_mass(self.corrMET.p4, lep.p4),    
        ('m_wlep',           'm_wlep',            (25,0,200))  : op.invariant_mass(self.corrMET.p4, conep4),    
        #('pt_wlep',          'pt_wlep',           (25,0,200))  : (self.corrMET.p4 + lep.p4).Pt(),
        ('pt_wlep',          'pt_wlep',           (25,0,200))  : (self.corrMET.p4 + conep4).Pt(),
        ('min_dr_lepbjets',  'min_dr_lepbjets',   (25,0,5))    : op.switch(op.rng_len(bjets) > 0, self.HLL.MinDR_part1_partCont(lep, bjets), op.c_float(0.)),
        #('dphi_hbb_hww',     'dphi_hbb_hww',      (22,0,3.2))  : op.abs(self.HLL.comp_dphi_hbb_hww(bjets, wjets, lep, self.corrMET)),
        ('dphi_hbb_hww',     'dphi_hbb_hww',      (22,0,3.2))  : op.abs(self.HLL.comp_dphi_hbb_hww(bjets, wjets, conep4, self.corrMET)),
        #('dphi_hbb_hwwvis',  'dphi_hbb_hwwvis',   (22,0,3.2))  : op.abs(self.HLL.comp_dphi_hbb_hwwvis(bjets, wjets, lep)),
        ('dphi_hbb_hwwvis',  'dphi_hbb_hwwvis',   (22,0,3.2))  : op.abs(self.HLL.comp_dphi_hbb_hwwvis(bjets, wjets, conep4)),
        #('dphi_met_lep',     'dphi_met_lep',      (22,0,3.2))  : op.abs(op.deltaPhi(self.corrMET.p4, lep.p4)),
        ('dphi_met_lep',     'dphi_met_lep',      (22,0,3.2))  : op.abs(op.deltaPhi(self.corrMET.p4, conep4)),
        ('dphi_met_hbb',     'dphi_met_hbb',      (22,0,3.2))  : op.multiSwitch((op.rng_len(bjets) >= 2, op.abs(op.deltaPhi(self.corrMET.p4,(bjets[0].p4 + bjets[1].p4)))),
                                                                                (op.rng_len(bjets) == 1, op.abs(op.deltaPhi(self.corrMET.p4, bjets[0].p4))),
                                                                                op.c_float(0.)),
        ('dphi_met_wjj',     'dphi_met_wjj',      (22,0,3.2))  : op.multiSwitch((op.rng_len(wjets) >= 2, op.abs(op.deltaPhi(self.corrMET.p4,(wjets[0].p4 + wjets[1].p4)))),
                                                                                (op.rng_len(wjets) == 1, op.abs(op.deltaPhi(self.corrMET.p4,wjets[0].p4))),
                                                                                op.c_float(0.)),
        ('dr_lep_hbb',       'dr_lep_hbb',        (25,0,5))    : op.multiSwitch((op.rng_len(bjets) >= 2, op.deltaR(conep4, (bjets[0].p4+bjets[1].p4))), 
                                                                                (op.rng_len(bjets) == 1, op.deltaR(conep4, bjets[0].p4)),
                                                                                op.c_float(0.)),
        ('dr_lep_wjj',       'dr_lep_wjj',        (25,0,5))    : op.multiSwitch((op.rng_len(wjets) >= 2, op.deltaR(conep4, (wjets[0].p4+wjets[1].p4))),
                                                                                (op.rng_len(wjets) == 1, op.deltaR(conep4, wjets[0].p4)),
                                                                                op.c_float(0.)),
        ('min_dr_wjets',     'min_dr_wjets',      (25,0,5))    : op.switch(op.rng_len(wjets) >= 2, op.deltaR(wjets[0].p4, wjets[1].p4), op.c_float(0.)),
        ('min_dhi_wjets',    'min_dphi_wjets',    (22,0,3.2))  : op.switch(op.rng_len(wjets) >= 2, op.abs(op.deltaPhi(wjets[0].p4,wjets[1].p4)),op.c_float(0.)),
        ('min_dr_bjets',     'min_dr_bjets',      (25,0,5))    : op.switch(op.rng_len(bjets) >= 2, op.deltaR(bjets[0].p4,bjets[1].p4), op.c_float(0.)),
        ('min_dphi_bjets',   'min_dphi_bjets',    (22,0,3.2))  : op.switch(op.rng_len(bjets) >= 2, op.abs(op.deltaPhi(bjets[0].p4,bjets[1].p4)),op.c_float(0.)),
        ('ht',               'ht',                (50,0,300))  : op.rng_sum(self.ak4Jets, lambda j : j.pt),
        #('smin',             'smin',              (50,0,300))  : self.HLL.comp_smin(lep,self.corrMET,self.ak4Jets,bjets,wjets), 
        ('smin',             'smin',              (50,0,300))  : self.HLL.comp_smin(conep4,self.corrMET,self.ak4Jets,bjets,wjets), 
        ('vbf_pair_mass',    'vbf_pair_mass',     (50,0,300))  : op.switch(op.rng_len(VBFJetPairs) > 0,op.invariant_mass(VBFJetPairs[0][0].p4,  VBFJetPairs[0][1].p4),
                                                                           op.c_float(0.)),
        ('vbf_pairs_absdeltaeta', 'vbf_pairs_absdeltaeta', (22,0,3.2)) : op.switch(op.rng_len(VBFJetPairs) > 0,op.abs(VBFJetPairs[0][0].eta - VBFJetPairs[0][1].eta),
                                                                                   op.c_float(0.)),
        ('lep_conept',       'lep_conept',        (25,0,200))  : lepconept,
        ('VBF_tag',          'vbf_tag',           (2,0,2))     : op.c_int(op.rng_len(VBFJetPairs) > 0),
        ('boosted_tag',      'boosted_tag',       (2,0,2))     : op.c_int(op.rng_len(self.ak8BJets) > 0),
        ('n_btag',           'n_btag',            (5,0,5))     : op.c_float(op.rng_len(self.ak4BJets)),
        ('sphericity',       'sphericity',        (1,0,1))     : op.c_float(0.), # not used
        ('sphericity_T',     'sphericity_T',      (1,0,1))     : op.c_float(0.), # not used
        ('aplanarity',       'aplanarity',        (1,0,1))     : op.c_float(0.), # not used
        ('eventshape_C',     'eventshape_C',      (1,0,1))     : op.c_float(0.), # not used
        ('eventshape_D',     'eventshape_D',      (1,0,1))     : op.c_float(0.), # not used
        ('eventshape_Y',     'eventshape_Y',      (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram1',      'foxwolfram1',       (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram2',      'foxwolfram2',       (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram3',      'foxwolfram3',       (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram4',      'foxwolfram4',       (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram5',      'foxwolfram5',       (1,0,1))     : op.c_float(0.), # not used
        ('centrality',       'centrality',        (1,0,1))     : op.c_float(0.), # not used
        ('centrality_jets',  'centrality_jets',   (1,0,1))     : op.c_float(0.), # not used
        ('eigenvalue1',      'eigenvalue1',       (1,0,1))     : op.c_float(0.), # not used
        ('eigenvalue2',      'eigenvalue2',       (1,0,1))     : op.c_float(0.), # not used
        ('eigenvalue3',      'eigenvalue3',       (1,0,1))     : op.c_float(0.), # not used
        ('sphericity_met',   'sphericity_met',    (1,0,1))     : op.c_float(0.), # not used
        ('sphericity_T_met', 'sphericity_T_met',  (1,0,1))     : op.c_float(0.), # not used
        ('aplanarity_met',   'aplanarity_met',    (1,0,1))     : op.c_float(0.), # not used
        ('eventshape_C_met', 'eventshape_C_met',  (1,0,1))     : op.c_float(0.), # not used
        ('eventshape_D_met', 'eventshape_D_met',  (1,0,1))     : op.c_float(0.), # not used
        ('eventshape_Y_met', 'eventshape_Y_met',  (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram1_met',  'foxwolfram1_met',   (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram2_met',  'foxwolfram2_met',   (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram3_met',  'foxwolfram3_met',   (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram4_met',  'foxwolfram4_met',   (1,0,1))     : op.c_float(0.), # not used
        ('foxwolfram5_met',  'foxwolfram5_met',   (1,0,1))     : op.c_float(0.), # not used
        ('centrality_met',   'centrality_met',    (1,0,1))     : op.c_float(0.), # not used
        ('centrality_jets_met','centrality_jets_met', (1,0,1)) : op.c_float(0.), # not used
        ('eigenvalue1_met',  'eigenvalue1_met',   (1,0,1))     : op.c_float(0.), # not used
        ('eigenvalue2_met',  'eigenvalue2_met',   (1,0,1))     : op.c_float(0.), # not used
        ('eigenvalue3_met',  'eigenvalue3_met',   (1,0,1))     : op.c_float(0.)  # not used
    }
Example #12
0
def returnParamMVAInputs(self):
    return {('year',     'Year',         (3,2016.,2019.))    : op.c_int(int(self.era))}