def getStatusPhotons(event, sample):
    GenMGPhotons = getCollection(event, 'GenMGPhoton',
                                 ["pt", "eta", "phi", "status"],
                                 'nGenMGPhoton')
    GenMGAllPhotons = getCollection(event, 'GenMGAllPhoton',
                                    ["pt", "eta", "phi", "status"],
                                    'nGenMGAllPhoton')
    GenAllJet = getCollection(event, 'GenAllJet', ["pt", "eta", "phi"],
                              'nGenAllJet')
    GenLepton = getCollection(event, 'GenLepton', ["pt", "eta", "phi"],
                              'nGenLepton')
    GenAllLepton = getCollection(event, 'GenLepton', ["pt", "eta", "phi"],
                                 'nGenAllLepton')

    GenMGAllPhotons = list(
        filter(
            lambda j: min([999] + [deltaR2(j, p) for p in GenAllJet]) > 0.04,
            GenMGAllPhotons))
    #    GenMGAllPhotons  = list( filter( lambda j: min( [999] + [ deltaR2( j, p ) for p in GenLepton ] ) > 0.04, GenMGAllPhotons ) )
    GenLepton = list(
        filter(
            lambda j: min([999] + [
                deltaR2(j, p) for p in GenMGAllPhotons if p["status"] > 1
            ]) > 0.04, GenLepton))

    #    GenMGPhotons = filter( lambda x: x["status"]>1, GenMGPhotons )
    event.nGenMGPhoton = len(GenMGPhotons) if event.nGenLepton == len(
        GenLepton) and len(GenAllLepton) == 1 else 0
Beispiel #2
0
def cleanJetsAndLeptons(jets,
                        leptons,
                        deltaR=0.4,
                        arbitration=(lambda jet, lepton: lepton)):
    # threshold
    dr2 = deltaR**2
    # Assume jets and leptons are all good
    goodjet = [True for jet in jets]
    goodlep = [True for lep in leptons]
    for i_lep, lep in enumerate(leptons):
        i_jet_best, d2min = -1, dr2
        for i_jet, jet in enumerate(jets):
            d2i = deltaR2(lep, jet)
            if d2i < dr2:
                choice = arbitration(jet, lep)
                if choice == jet:
                    # if the two match, and we prefer the jet, then drop the lepton and be done
                    goodlep[i_lep] = False
                    break
                elif choice == (jet, lep) or choice == (lep, jet):
                    # asked to keep both, so we don't consider this match
                    continue
            # find best match
            if d2i < d2min:
                i_jet_best, d2min = i_jet, d2i
        # this lepton has been killed by a jet, then we clean the jet that best matches it
        if not goodlep[i_lep]: continue
        if i_jet_best != -1: goodjet[i_jet_best] = False
    return ([
        jet for (i_jet, jet) in enumerate(jets) if goodjet[i_jet] == True
    ], [lep for (i_lep, lep) in enumerate(leptons) if goodlep[i_lep] == True])
def filler(event):

    event.run, event.luminosity, event.evt = reader.evt
    event.weight = lumiweight

    if reader.position % 100 == 0:
        logger.info("At event %i/%i", reader.position, reader.nEvents)

    # EFT weights
    if options.addReweights:
        event.nrw = weightInfo.nid
        lhe_weights = reader.products["lhe"].weights()
        weights = []
        param_points = []

        #        hyperPoly.initialized = False

        for weight in lhe_weights:
            # Store nominal weight (First position!)
            if weight.id == "rwgt_1": event.rw_nominal = weight.wgt

            if not weight.id in weightInfo.id: continue

            pos = weightInfo.data[weight.id]
            event.rw_w[pos] = weight.wgt
            weights += [weight.wgt]
            interpreted_weight = interpret_weight(weight.id)

            for var in weightInfo.variables:
                getattr(event, "rw_" + var)[pos] = interpreted_weight[var]

            # weight data for interpolation
            if not hyperPoly.initialized:
                param_points += [
                    tuple(interpreted_weight[var]
                          for var in weightInfo.variables)
                ]

        # get list of values of ref point in specific order
        ref_point_coordinates = [
            weightInfo.ref_point_coordinates[var]
            for var in weightInfo.variables
        ]

        # Initialize with Reference Point
        if not hyperPoly.initialized:
            hyperPoly.initialize(param_points, ref_point_coordinates)

        coeff = hyperPoly.get_parametrization(weights)
        event.np = hyperPoly.ndof
        event.chi2_ndof = hyperPoly.chi2_ndof(coeff, weights)

        if event.chi2_ndof > 10**-6:
            logger.warning("chi2_ndof is large: %f", event.chi2_ndof)

        for n in xrange(hyperPoly.ndof):
            event.p_C[n] = coeff[n]

        # lumi weight / w0
        event.ref_weight = event.weight / coeff[0]

    ##############################################
    ##############################################
    ##############################################

    # GEN Particles
    genPart = reader.products["gp"]

    # for searching
    search = GenSearch(genPart)

    # MET
    GenMET = {
        "pt": reader.products["genMET"][0].pt(),
        "phi": reader.products["genMET"][0].phi()
    }
    event.GenMET_pt = GenMET["pt"]
    event.GenMET_phi = GenMET["phi"]
    # reco naming
    event.MET_pt = GenMET["pt"]
    event.MET_phi = GenMET["phi"]

    # find heavy objects before they decay
    GenT = filter(lambda p: abs(p.pdgId()) == 6 and search.isLast(p), genPart)

    GenTopLep = []
    GenWLep = []
    GenTopHad = []
    GenWHad = []
    GenBLep = []
    GenBHad = []
    GenWs = []
    for top in GenT:
        GenW = [
            search.descend(w) for w in search.daughters(top)
            if abs(w.pdgId()) == 24
        ]
        GenB = [
            search.descend(w) for w in search.daughters(top)
            if abs(w.pdgId()) == 5
        ]
        if GenW:
            GenW = GenW[0]
            GenWs.append(GenW)
            wDecays = [abs(l.pdgId()) for l in search.daughters(GenW)]
            if 11 in wDecays or 13 in wDecays or 15 in wDecays:
                GenWLep.append(GenW)
                if GenB: GenBLep.append(GenB[0])
                GenTopLep.append(top)
            else:
                GenWHad.append(GenW)
                if GenB: GenBHad.append(GenB[0])
                GenTopHad.append(top)

    GenTops = map(lambda t: {var: getattr(t, var)()
                             for var in genTopVars}, GenT)
    GenTops.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenTop", genTopVars, GenTops)

    GenTopLep = map(lambda t: {var: getattr(t, var)()
                               for var in genTopVars}, GenTopLep)
    GenTopLep.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenTopLep", genTopVars, GenTopLep)

    GenTopHad = map(lambda t: {var: getattr(t, var)()
                               for var in genTopVars}, GenTopHad)
    GenTopHad.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenTopHad", genTopVars, GenTopHad)

    GenWs = map(lambda t: {var: getattr(t, var)() for var in genWVars}, GenWs)
    GenWs.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenW", genWVars, GenWs)

    GenWLep = map(lambda t: {var: getattr(t, var)()
                             for var in genWVars}, GenWLep)
    GenWLep.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenWLep", genWVars, GenWLep)

    GenWHad = map(lambda t: {var: getattr(t, var)()
                             for var in genWVars}, GenWHad)
    GenWHad.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenWHad", genWVars, GenWHad)

    GenBLep = map(lambda t: {var: getattr(t, var)()
                             for var in genWVars}, GenBLep)
    GenBLep.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenBLep", genWVars, GenBLep)

    GenBHad = map(lambda t: {var: getattr(t, var)()
                             for var in genWVars}, GenBHad)
    GenBHad.sort(key=lambda p: -p["pt"])
    fill_vector_collection(event, "GenBHad", genWVars, GenBHad)

    bPartonsFromTop = [
        b for b in filter(
            lambda p: abs(p.pdgId()) == 5 and p.numberOfMothers() == 1 and abs(
                p.mother(0).pdgId()) == 6, genPart)
    ]

    # genParticles for isolation
    GenParticlesIso = [
        l for l in filter(
            lambda p: abs(p.pdgId()) not in [12, 14, 16] and p.pt() > 5 and p.
            status() == 1, genPart)
    ]
    GenParticlesIso.sort(key=lambda p: -p.pt())
    GenParticlesIso = [{var: getattr(l, var)()
                        for var in genParticleVarsRead}
                       for l in GenParticlesIso]

    # genLeptons
    GenLeptonAll = [(search.ascend(l), l) for l in filter(
        lambda p: abs(p.pdgId()) in [11, 13] and search.isLast(p) and p.status(
        ) == 1, genPart)]
    GenLeptonAll.sort(key=lambda p: -p[1].pt())
    GenLepton = []

    for first, last in GenLeptonAll:

        mother = first.mother(0) if first.numberOfMothers() > 0 else None
        grandmother_pdgId = -999
        mother_pdgId = -999

        if mother:
            mother_pdgId = mother.pdgId()
            mother_ascend = search.ascend(mother)
            grandmother = mother_ascend.mother(
                0) if mother.numberOfMothers() > 0 else None
            if grandmother:
                grandmother_pdgId = grandmother.pdgId()

        genLep = {var: getattr(last, var)() for var in genLeptonVarsRead}
        genLep["motherPdgId"] = mother_pdgId
        genLep["grandmotherPdgId"] = grandmother_pdgId
        GenLepton.append(genLep)

    # Gen photons: particle-level isolated gen photons
    GenPhotonAll = [(search.ascend(l), l) for l in filter(
        lambda p: abs(p.pdgId()) == 22 and p.pt() > 1 and search.isLast(p),
        genPart)]
    #    GenPhotonAll = [ ( search.ascend(l), l ) for l in filter( lambda p: abs( p.pdgId() ) == 22 and search.isLast(p), genPart ) ]
    GenPhotonAll.sort(key=lambda p: -p[1].pt())
    GenPhoton = []

    for first, last in GenPhotonAll:

        mother = first.mother(0) if first.numberOfMothers() > 0 else None
        grandmother_pdgId = -999
        mother_pdgId = -999

        if mother:
            mother_pdgId = mother.pdgId()
            mother_ascend = search.ascend(mother)
            grandmother = mother_ascend.mother(
                0) if mother.numberOfMothers() > 0 else None
            if grandmother:
                grandmother_pdgId = grandmother.pdgId()

        GenP = {var: getattr(last, var)() for var in genPhotonVarsRead}
        GenP["motherPdgId"] = mother_pdgId
        GenP["grandmotherPdgId"] = grandmother_pdgId
        GenP["status"] = last.status()

        close_particles = filter(
            lambda p: p != last and deltaR2(
                {
                    "phi": last.phi(),
                    "eta": last.eta()
                }, {
                    "phi": p.phi(),
                    "eta": p.eta()
                }) < 0.16, search.final_state_particles_no_neutrinos)
        GenP["relIso04_all"] = sum([p.pt()
                                    for p in close_particles], 0) / last.pt()

        close_particles = filter(
            lambda p: p != last and deltaR2(
                {
                    "phi": last.phi(),
                    "eta": last.eta()
                }, {
                    "phi": p.phi(),
                    "eta": p.eta()
                }) < 0.09, search.final_state_particles_no_neutrinos)
        GenP["relIso03_all"] = sum([p.pt()
                                    for p in close_particles], 0) / last.pt()

        GenPhoton.append(GenP)

    # Jets
    GenJetAll = list(filter(genJetId, reader.products["genJets"]))
    GenJetAll.sort(key=lambda p: -p.pt())
    # Filter genJets
    GenJet = map(lambda t: {var: getattr(t, var)()
                            for var in genJetVarsRead}, GenJetAll)
    # BJets
    GenBJet = [b for b in filter(lambda p: abs(p.pdgId()) == 5, genPart)]

    for GenJ in GenJet:
        GenJ["isBJet"] = min(
            [999] +
            [deltaR2(GenJ, {
                "eta": b.eta(),
                "phi": b.phi()
            }) for b in GenBJet]) < 0.16
#        GenJ["parton"] = [ p.pdgId() for p in filter( lambda x: abs( x.pdgId() ) not in [12,14,16] and x.status() == 1, genPart ) if deltaR2( GenJ, {"eta":p.eta(), "phi":p.phi() } ) < 0.16 ]
#        GenJ["parton"] = [ p.pdgId() for p in filter( lambda x: abs( x.pdgId() ) not in [12,14,16], genPart ) if deltaR2( GenJ, {"eta":p.eta(), "phi":p.phi() } ) < 0.16 ]
#        print GenJ["parton"]

# gen b jets
    GenBJet = list(filter(lambda j: j["isBJet"], GenJet))

    # store minimum DR to jets
    for GenP in GenPhoton:
        GenP["photonJetdR"] = min([999] + [deltaR(GenP, j) for j in GenJet])
        GenP["photonLepdR"] = min([999] + [deltaR(GenP, j) for j in GenLepton])
        GenP["photonAlldR"] = min([999] + [
            deltaR(GenP, j) for j in GenParticlesIso
            if abs(GenP["pt"] - j["pt"]) > 0.01 and j["pdgId"] != 22
        ])

    fill_vector_collection(event, "GenPhoton", genPhotonVars,
                           filter(lambda p: p["pt"] >= 5, GenPhoton))
    fill_vector_collection(event, "GenLepton", genLeptonVars, GenLepton)
    fill_vector_collection(event, "GenJet", genJetVars, GenJet)
    fill_vector_collection(event, "GenBJet", genJetVars, GenBJet)

    event.nGenElectron = len(filter(lambda l: abs(l["pdgId"]) == 11,
                                    GenLepton))
    event.nGenMuon = len(filter(lambda l: abs(l["pdgId"]) == 13, GenLepton))
    event.nGenLepton = len(GenLepton)
    event.nGenPhoton = len(filter(lambda p: p["pt"] >= 5, GenPhoton))
    event.nGenBJet = len(GenBJet)
    event.nGenJets = len(GenJet)
    event.nGenBJet = len(GenBJet)

    ##############################################
    ##############################################
    ##############################################

    # Analysis specific variables

    for il, genL in enumerate(GenLepton):
        if abs(genL["motherPdgId"]) not in [11, 13, 15, 23, 24, 25]: continue
        for genP in GenPhoton:
            if deltaR(genL, genP) < 0.1:
                dressedL = get4DVec(GenLepton[il]) + get4DVec(genP)
                GenLepton[il]["pt"] = dressedL.Pt()
                GenLepton[il]["eta"] = dressedL.Eta()
                GenLepton[il]["phi"] = dressedL.Phi()

    # no meson mother
    GenLeptonCMSUnfold = list(
        filter(
            lambda l: abs(l["motherPdgId"]) in [11, 13, 15, 23, 24, 25] and
            genLeptonSel_CMSUnfold(l), GenLepton))
    GenLeptonATLASUnfold = list(
        filter(
            lambda l: abs(l["motherPdgId"]) in [11, 13, 15, 23, 24, 25] and
            genLeptonSel_ATLASUnfold(l), GenLepton))

    GenPhotonCMSUnfold = list(
        filter(lambda p: genPhotonSel_CMSUnfold(p) and p["status"] == 1,
               GenPhoton))
    GenPhotonEECMSUnfold = list(
        filter(lambda p: genPhotonEESel_CMSUnfold(p) and p["status"] == 1,
               GenPhoton))
    GenPhotonATLASUnfold = list(
        filter(lambda p: genPhotonSel_ATLASUnfold(p) and p["status"] == 1,
               GenPhoton))

    GenJetCMSUnfold = list(filter(lambda j: genJetSel_CMSUnfold(j), GenJet))
    GenJetATLASUnfold = list(filter(lambda j: genJetSel_ATLASUnfold(j),
                                    GenJet))

    GenBJetCMSUnfold = list(filter(lambda j: genJetSel_CMSUnfold(j), GenBJet))
    GenBJetATLASUnfold = list(
        filter(lambda j: genJetSel_ATLASUnfold(j), GenBJet))

    for GenP in GenPhotonCMSUnfold:
        GenP["photonJetdR"] = min([999] +
                                  [deltaR(GenP, j) for j in GenJetCMSUnfold])
        GenP["photonLepdR"] = min(
            [999] + [deltaR(GenP, j) for j in GenLeptonCMSUnfold])
        GenP["photonAlldR"] = min([999] + [
            deltaR(GenP, j) for j in GenParticlesIso
            if abs(GenP["pt"] - j["pt"]) > 0.01 and j["pdgId"] != 22
        ])

    for GenP in GenPhotonEECMSUnfold:
        GenP["photonJetdR"] = min([999] +
                                  [deltaR(GenP, j) for j in GenJetCMSUnfold])
        GenP["photonLepdR"] = min(
            [999] + [deltaR(GenP, j) for j in GenLeptonCMSUnfold])
        GenP["photonAlldR"] = min([999] + [
            deltaR(GenP, j) for j in GenParticlesIso
            if abs(GenP["pt"] - j["pt"]) > 0.01 and j["pdgId"] != 22
        ])

    for GenP in GenPhotonATLASUnfold:
        GenP["photonJetdR"] = min([999] +
                                  [deltaR(GenP, j) for j in GenJetATLASUnfold])
        GenP["photonLepdR"] = min(
            [999] + [deltaR(GenP, j) for j in GenLeptonATLASUnfold])
        GenP["photonAlldR"] = min([999] + [
            deltaR(GenP, j) for j in GenParticlesIso
            if abs(GenP["pt"] - j["pt"]) > 0.01 and j["pdgId"] != 22
        ])

    # Isolated
    GenPhotonCMSUnfold = filter(lambda g: g["photonAlldR"] > 0.1,
                                GenPhotonCMSUnfold)
    GenPhotonCMSUnfold = filter(
        lambda g: abs(g["grandmotherPdgId"]) in range(37) + [2212] and abs(g[
            "motherPdgId"]) in range(37) + [2212], GenPhotonCMSUnfold)

    GenPhotonEECMSUnfold = filter(lambda g: g["photonAlldR"] > 0.1,
                                  GenPhotonEECMSUnfold)
    GenPhotonEECMSUnfold = filter(
        lambda g: abs(g["grandmotherPdgId"]) in range(37) + [2212] and abs(g[
            "motherPdgId"]) in range(37) + [2212], GenPhotonEECMSUnfold)

    GenPhotonATLASUnfold = filter(lambda g: g["relIso03_all"] < 0.1,
                                  GenPhotonATLASUnfold)
    GenPhotonATLASUnfold = filter(
        lambda g: abs(g["grandmotherPdgId"]) in range(37) + [2212] and abs(g[
            "motherPdgId"]) in range(37) + [2212], GenPhotonATLASUnfold)

    for GenJ in GenJetATLASUnfold:
        GenJ["jetPhotondR"] = min(
            [999] + [deltaR(GenJ, p) for p in GenPhotonATLASUnfold])
        GenJ["jetLepdR"] = min([999] +
                               [deltaR(GenJ, p) for p in GenLeptonATLASUnfold])

    for GenJ in GenBJetATLASUnfold:
        GenJ["jetPhotondR"] = min(
            [999] + [deltaR(GenJ, p) for p in GenPhotonATLASUnfold])
        GenJ["jetLepdR"] = min([999] +
                               [deltaR(GenJ, p) for p in GenLeptonATLASUnfold])

    for i_j, GenJ in enumerate(GenJetCMSUnfold):
        GenJ["jetPhotondR"] = min(
            [999] + [deltaR(GenJ, p) for p in GenPhotonCMSUnfold])
        GenJ["jetLepdR"] = min([999] +
                               [deltaR(GenJ, p) for p in GenLeptonCMSUnfold])
#        GenJ["jetJetdR"]    =  min( [999] + [ deltaR( GenJ, p ) for i_p, p in enumerate(GenJetCMSUnfold) if i_p != i_j ] )
#        print GenJ["jetJetdR"]

    for GenJ in GenBJetCMSUnfold:
        GenJ["jetPhotondR"] = min(
            [999] + [deltaR(GenJ, p) for p in GenPhotonCMSUnfold])
        GenJ["jetLepdR"] = min([999] +
                               [deltaR(GenJ, p) for p in GenLeptonCMSUnfold])

    GenJetEECMSUnfold = copy.deepcopy(GenJetCMSUnfold)
    for GenJ in GenJetEECMSUnfold:
        GenJ["jetPhotondR"] = min(
            [999] + [deltaR(GenJ, p) for p in GenPhotonEECMSUnfold])

    GenBJetEECMSUnfold = copy.deepcopy(GenBJetCMSUnfold)
    for GenJ in GenBJetEECMSUnfold:
        GenJ["jetPhotondR"] = min(
            [999] + [deltaR(GenJ, p) for p in GenPhotonEECMSUnfold])

    # CMS Unfolding cleaning
    GenPhotonCMSUnfold = filter(lambda g: g["photonLepdR"] > 0.4,
                                GenPhotonCMSUnfold)
    GenJetCMSUnfold = filter(lambda g: g["jetPhotondR"] > 0.1, GenJetCMSUnfold)
    GenBJetCMSUnfold = filter(lambda g: g["jetPhotondR"] > 0.1,
                              GenBJetCMSUnfold)
    GenJetCMSUnfold = filter(lambda g: g["jetLepdR"] > 0.4, GenJetCMSUnfold)
    GenBJetCMSUnfold = filter(lambda g: g["jetLepdR"] > 0.4, GenBJetCMSUnfold)

    GenPhotonEECMSUnfold = filter(lambda g: g["photonLepdR"] > 0.1,
                                  GenPhotonEECMSUnfold)
    GenJetEECMSUnfold = filter(lambda g: g["jetPhotondR"] > 0.1,
                               GenJetEECMSUnfold)
    GenBJetEECMSUnfold = filter(lambda g: g["jetPhotondR"] > 0.1,
                                GenBJetEECMSUnfold)
    GenJetEECMSUnfold = filter(lambda g: g["jetLepdR"] > 0.4,
                               GenJetEECMSUnfold)
    GenBJetEECMSUnfold = filter(lambda g: g["jetLepdR"] > 0.4,
                                GenBJetEECMSUnfold)

    # ATLAS Unfolding cleaning
    GenPhotonATLASUnfold = filter(lambda g: g["photonLepdR"] > 1.0,
                                  GenPhotonATLASUnfold)
    GenJetATLASUnfold = filter(lambda g: g["jetPhotondR"] > 0.4,
                               GenJetATLASUnfold)
    GenBJetATLASUnfold = filter(lambda g: g["jetPhotondR"] > 0.4,
                                GenBJetATLASUnfold)
    GenJetATLASUnfold = filter(lambda g: g["jetLepdR"] > 0.4,
                               GenJetATLASUnfold)
    GenBJetATLASUnfold = filter(lambda g: g["jetLepdR"] > 0.4,
                                GenBJetATLASUnfold)

    GenPhotonCMSUnfold.sort(key=lambda p: -p["pt"])
    genP0 = (GenPhotonCMSUnfold[:1] + [None])[0]
    if genP0: fill_vector(event, "GenPhotonCMSUnfold0", genPhotonVars, genP0)
    if genP0: fill_vector(event, "PhotonGood0", genPhotonVars, genP0)
    if genP0:
        fill_vector(event, "PhotonNoChgIsoNoSieie0", genPhotonVars, genP0)

    GenPhotonEECMSUnfold.sort(key=lambda p: -p["pt"])
    genP0 = (GenPhotonEECMSUnfold[:1] + [None])[0]
    if genP0: fill_vector(event, "PhotonEEGood0", genPhotonVars, genP0)

    GenPhotonATLASUnfold.sort(key=lambda p: -p["pt"])
    genP0 = (GenPhotonATLASUnfold[:1] + [None])[0]
    if genP0: fill_vector(event, "GenPhotonATLASUnfold0", genPhotonVars, genP0)

    GenLeptonCMSUnfold.sort(key=lambda p: -p["pt"])
    genL0 = (GenLeptonCMSUnfold[:1] + [None])[0]
    if genL0: fill_vector(event, "GenLeptonCMSUnfold0", genLeptonVars, genL0)
    if genL0: fill_vector(event, "LeptonTight0", genLeptonVars, genL0)

    GenJetCMSUnfold.sort(key=lambda p: -p["pt"])
    genJ0, genJ1, genJ2 = (GenJetCMSUnfold[:3] + [None, None, None])[:3]
    if genJ0: fill_vector(event, "GenJetsCMSUnfold0", genJetVars, genJ0)
    if genJ1: fill_vector(event, "GenJetsCMSUnfold1", genJetVars, genJ1)
    if genJ2: fill_vector(event, "GenJetsCMSUnfold2", genJetVars, genJ2)

    GenBJetCMSUnfold.sort(key=lambda p: -p["pt"])
    genB0, genB1 = (GenBJetCMSUnfold[:2] + [None, None])[:2]
    if genB0: fill_vector(event, "GenBJetCMSUnfold0", genJetVars, genB0)
    if genB1: fill_vector(event, "GenBJetCMSUnfold1", genJetVars, genB1)

    event.nGenElectronCMSUnfold = len(
        filter(lambda l: abs(l["pdgId"]) == 11, GenLeptonCMSUnfold))
    event.nGenMuonCMSUnfold = len(
        filter(lambda l: abs(l["pdgId"]) == 13, GenLeptonCMSUnfold))
    event.nGenLeptonCMSUnfold = len(GenLeptonCMSUnfold)
    event.nGenPhotonCMSUnfold = len(GenPhotonCMSUnfold)
    event.nGenBJetCMSUnfold = len(GenBJetCMSUnfold)
    event.nGenJetsCMSUnfold = len(GenJetCMSUnfold)

    event.nPhotonEEGood = len(GenPhotonEECMSUnfold)
    event.nGenBJetEECMSUnfold = len(GenBJetEECMSUnfold)
    event.nGenJetsEECMSUnfold = len(GenJetEECMSUnfold)

    # use reco naming for easier handling
    event.nLeptonTight = event.nGenLeptonCMSUnfold
    event.nElectronTight = event.nGenElectronCMSUnfold
    event.nMuonTight = event.nGenMuonCMSUnfold
    event.nLeptonVetoIsoCorr = event.nGenLeptonCMSUnfold
    event.nJetGood = event.nGenJetsCMSUnfold
    event.nBTagGood = event.nGenBJetCMSUnfold
    event.nPhotonGood = event.nGenPhotonCMSUnfold
    event.nPhotonNoChgIsoNoSieie = event.nGenPhotonCMSUnfold

    event.nGenElectronATLASUnfold = len(
        filter(lambda l: abs(l["pdgId"]) == 11, GenLeptonATLASUnfold))
    event.nGenMuonATLASUnfold = len(
        filter(lambda l: abs(l["pdgId"]) == 13, GenLeptonATLASUnfold))
    event.nGenLeptonATLASUnfold = len(GenLeptonATLASUnfold)
    event.nGenPhotonATLASUnfold = len(GenPhotonATLASUnfold)
    event.nGenBJetATLASUnfold = len(GenBJetATLASUnfold)
    event.nGenJetsATLASUnfold = len(GenJetATLASUnfold)

    ##############################################
    ##############################################
    ##############################################

    if GenPhotonCMSUnfold:
        if GenLeptonCMSUnfold:
            event.dPhiLepGamma = deltaPhi(GenPhotonCMSUnfold[0]["phi"],
                                          GenLeptonCMSUnfold[0]["phi"])
            event.dRLepGamma = deltaR(GenPhotonCMSUnfold[0],
                                      GenLeptonCMSUnfold[0])
        if GenTopHad:
            event.dPhiTopHadGamma = deltaPhi(GenPhotonCMSUnfold[0]["phi"],
                                             GenTopHad[0]["phi"])
            event.dRTopHadGamma = deltaR(GenPhotonCMSUnfold[0], GenTopHad[0])
        if GenWHad:
            event.dPhiWHadGamma = deltaPhi(GenPhotonCMSUnfold[0]["phi"],
                                           GenWHad[0]["phi"])
            event.dRWHadGamma = deltaR(GenPhotonCMSUnfold[0], GenWHad[0])
        if GenTopLep:
            event.dPhiTopLepGamma = deltaPhi(GenPhotonCMSUnfold[0]["phi"],
                                             GenTopLep[0]["phi"])
            event.dRTopLepGamma = deltaR(GenPhotonCMSUnfold[0], GenTopLep[0])
        if GenWLep:
            event.dPhiWLepGamma = deltaPhi(GenPhotonCMSUnfold[0]["phi"],
                                           GenWLep[0]["phi"])
            event.dRWLepGamma = deltaR(GenPhotonCMSUnfold[0], GenWLep[0])
        if GenBHad:
            event.dPhiBHadGamma = deltaPhi(GenPhotonCMSUnfold[0]["phi"],
                                           GenBHad[0]["phi"])
            event.dRBHadGamma = deltaR(GenPhotonCMSUnfold[0], GenBHad[0])
        if GenBLep:
            event.dPhiBLepGamma = deltaPhi(GenPhotonCMSUnfold[0]["phi"],
                                           GenBLep[0]["phi"])
            event.dRBLepGamma = deltaR(GenPhotonCMSUnfold[0], GenBLep[0])
    if GenBLep:
        if GenWLep:
            event.dPhiBLepWLep = deltaPhi(GenBLep[0]["phi"], GenWLep[0]["phi"])
            event.dRBLepWLep = deltaR(GenBLep[0], GenWLep[0])
        if GenBHad:
            event.dPhiBLepBHad = deltaPhi(GenBLep[0]["phi"], GenBHad[0]["phi"])
            event.dRBLepBHad = deltaR(GenBLep[0], GenBHad[0])
    if GenWHad:
        if GenBHad:
            event.dPhiBHadWHad = deltaPhi(GenBHad[0]["phi"], GenWHad[0]["phi"])
            event.dRBHadWHad = deltaR(GenBHad[0], GenWHad[0])
        if GenWLep:
            event.dPhiWLepWHad = deltaPhi(GenWLep[0]["phi"], GenWHad[0]["phi"])
            event.dRWLepWHad = deltaR(GenWLep[0], GenWHad[0])
    if GenTopLep and GenTopHad:
        event.dPhiTopLepTopHad = deltaPhi(GenTopLep[0]["phi"],
                                          GenTopHad[0]["phi"])
        event.dRTopLepTopHad = deltaR(GenTopLep[0], GenTopHad[0])
    if GenLeptonCMSUnfold:
        event.dPhiLepMET = deltaPhi(GenLeptonCMSUnfold[0]["phi"],
                                    GenMET["phi"])

    event.ht = -999
    event.m3 = -999
    event.mT = -999
    event.mLtight0Gamma = -999
    if GenJetCMSUnfold:
        event.ht = sum([j["pt"] for j in GenJetCMSUnfold])
        event.m3 = m3(GenJetCMSUnfold)[0]

    if GenLeptonCMSUnfold:
        event.mT = mT(GenLeptonCMSUnfold[0], GenMET)
        if GenPhotonCMSUnfold:
            event.mLtight0Gamma = (get4DVec(GenLeptonCMSUnfold[0]) +
                                   get4DVec(GenPhotonCMSUnfold[0])).M()
Beispiel #4
0
def filler(event):

    event.run, event.luminosity, event.evt = reader.evt
    event.weight = lumiweight

    if reader.position % 100 == 0:
        logger.info("At event %i/%i", reader.position, reader.nEvents)

    # EFT weights
    if options.addReweights:
        event.nrw = weightInfo.nid
        lhe_weights = reader.products['lhe'].weights()
        weights = []
        param_points = []

        for weight in lhe_weights:
            # Store nominal weight (First position!)
            if weight.id == 'rwgt_1': event.rw_nominal = weight.wgt

            if not weight.id in weightInfo.id: continue

            pos = weightInfo.data[weight.id]
            event.rw_w[pos] = weight.wgt
            weights += [weight.wgt]
            interpreted_weight = interpret_weight(weight.id)

            for var in weightInfo.variables:
                getattr(event, "rw_" + var)[pos] = interpreted_weight[var]

            # weight data for interpolation
            if not hyperPoly.initialized:
                param_points += [
                    tuple(interpreted_weight[var]
                          for var in weightInfo.variables)
                ]

        # get list of values of ref point in specific order
        ref_point_coordinates = [
            weightInfo.ref_point_coordinates[var]
            for var in weightInfo.variables
        ]

        # Initialize with Reference Point
        if not hyperPoly.initialized:
            hyperPoly.initialize(param_points, ref_point_coordinates)

        coeff = hyperPoly.get_parametrization(weights)
        event.np = hyperPoly.ndof
        event.chi2_ndof = hyperPoly.chi2_ndof(coeff, weights)

        if event.chi2_ndof > 10**-6:
            logger.warning("chi2_ndof is large: %f", event.chi2_ndof)

        for n in xrange(hyperPoly.ndof):
            event.p_C[n] = coeff[n]

        # lumi weight / w0
        event.ref_weight = event.weight / coeff[0]

    # GEN Particles
    genPart = reader.products['gp']

    # for searching
    search = GenSearch(genPart)

    # MET
    GenMET = {
        'pt': reader.products['genMET'][0].pt(),
        'phi': reader.products['genMET'][0].phi()
    }
    event.GenMET_pt = GenMET['pt']
    event.GenMET_phi = GenMET['phi']

    # find heavy objects before they decay
    GenTops = map(
        lambda t: {var: getattr(t, var)()
                   for var in genTopVars},
        filter(lambda p: abs(p.pdgId()) == 6 and search.isLast(p), genPart))
    GenTops.sort(key=lambda p: -p['pt'])
    fill_vector_collection(event, "GenTop", genTopVars, GenTops)

    # genLeptons: prompt gen-leptons
    #    GenLeptonsAll = [ (search.ascend(l), l) for l in filter( lambda p: abs( p.pdgId() ) in [11,13] and search.isLast(p) and p.status() == 1, genPart ) ]
    GenLeptonsAll = [(search.ascend(l), l) for l in filter(
        lambda p: abs(p.pdgId()) in [11, 13] and search.isLast(p), genPart)]
    GenPromptLeptons = []
    GenAllLeptons = []

    for first, last in GenLeptonsAll:

        mother = first.mother(0) if first.numberOfMothers() > 0 else None
        mother_pdgId = -999
        grandmother_pdgId = -999

        if mother:
            mother_pdgId = mother.pdgId()
            mother_ascend = search.ascend(mother)
            grandmother = mother_ascend.mother(
                0) if mother.numberOfMothers() > 0 else None
            grandmother_pdgId = grandmother.pdgId() if grandmother else -999

        genLep = {var: getattr(last, var)() for var in genLeptonVarsRead}
        genLep['motherPdgId'] = mother_pdgId
        genLep['grandmotherPdgId'] = grandmother_pdgId
        GenAllLeptons.append(genLep)

        if abs(mother_pdgId) in [11, 13, 15, 23, 24, 25
                                 ] and isGoodGenLepton(genLep):
            GenPromptLeptons.append(genLep)

    # Filter gen leptons
    GenAllLeptons.sort(key=lambda p: -p['pt'])
    fill_vector_collection(event, "GenAllLepton", genLeptonVars, GenAllLeptons)

    GenPromptLeptons.sort(key=lambda p: -p['pt'])

    if GenPromptLeptons:
        GenPromptLeptons[0]["clean"] = 1  #dont clean the high pT photons
        for i, GenPromptLepton in enumerate(GenPromptLeptons[::-1][:-1]):
            GenPromptLepton['clean'] = min([999] + [
                deltaR2(GenPromptLepton, p)
                for p in GenPromptLeptons[::-1][i + 1:]
            ]) > 0.16
        GenPromptLeptons = list(filter(lambda j: j["clean"], GenPromptLeptons))

    GenPromptElectrons = list(
        filter(lambda l: abs(l['pdgId']) == 11, GenPromptLeptons))
    GenPromptMuons = list(
        filter(lambda l: abs(l['pdgId']) == 13, GenPromptLeptons))
    event.nGenElectron = len(GenPromptElectrons)
    event.nGenMuon = len(GenPromptMuons)

    # Gen photons: particle-level isolated gen photons
    GenPhotonsAll = [(search.ascend(l), l) for l in filter(
        lambda p: abs(p.pdgId()) == 22 and p.pt() > 5 and search.isLast(p),
        genPart)]
    GenPhotonsAll.sort(key=lambda p: -p[1].pt())
    GenPhotons = []
    GenAllPhotons = []
    GenMGPhotons = []
    GenMGAllPhotons = []

    for first, last in GenPhotonsAll:
        mother_pdgId = first.mother(
            0).pdgId() if first.numberOfMothers() > 0 else -999
        GenPhoton = {var: getattr(last, var)() for var in genPhotonVarsRead}
        GenMGPhoton = {var: getattr(first, var)() for var in genPhotonVarsRead}

        GenPhoton['motherPdgId'] = mother_pdgId
        GenPhoton['status'] = last.status()
        GenMGPhoton['motherPdgId'] = mother_pdgId
        GenMGPhoton['status'] = first.status()

        mother_ascend = search.ascend(first.mother(0))
        grandmother = mother_ascend.mother(
            0) if first.mother(0).numberOfMothers() > 0 else None
        grandmother_pdgId = grandmother.pdgId() if grandmother else 0

        close_particles = filter(
            lambda p: p != last and deltaR2(
                {
                    'phi': last.phi(),
                    'eta': last.eta()
                }, {
                    'phi': p.phi(),
                    'eta': p.eta()
                }) < 0.16, search.final_state_particles_no_neutrinos)
        GenPhoton['relIso04_all'] = sum([p.pt() for p in close_particles],
                                        0) / last.pt()
        GenPhoton['photonJetdR'] = 999
        GenPhoton['photonLepdR'] = 999
        GenAllPhotons.append(GenPhoton)
        if isGoodGenPhoton(GenPhoton):
            GenPhotons.append(GenPhoton)

        close_particles = filter(
            lambda p: p != first and deltaR2(
                {
                    'phi': first.phi(),
                    'eta': first.eta()
                }, {
                    'phi': p.phi(),
                    'eta': p.eta()
                }) < 0.16, search.final_state_particles_no_neutrinos)
        GenMGPhoton['relIso04_all'] = sum([p.pt() for p in close_particles],
                                          0) / first.pt()
        GenMGPhoton['photonJetdR'] = 999
        GenMGPhoton['photonLepdR'] = 999
        GenMGAllPhotons.append(GenMGPhoton)
        if isGoodGenPhoton(GenMGPhoton):
            GenMGPhotons.append(GenMGPhoton)

    fill_vector_collection(event, "GenAllPhoton", genPhotonVars, GenAllPhotons)
    fill_vector_collection(event, "GenMGAllPhoton", genPhotonVars,
                           GenMGAllPhotons)

    if not options.noCleaning:
        # deltaR cleaning to photons as in run card
        GenPhotons = list(
            filter(
                lambda p: min(
                    [999] + [deltaR2(p, l) for l in GenPromptLeptons]) > 0.04,
                GenPhotons))
        GenMGPhotons = list(
            filter(
                lambda p: min(
                    [999] + [deltaR2(p, l) for l in GenPromptLeptons]) > 0.04,
                GenMGPhotons))

    # Jets
    GenJetsAll = list(filter(genJetId, reader.products['genJets']))
    GenJetsAll.sort(key=lambda p: -p.pt())
    # Filter genJets
    GenAllJets = map(
        lambda t: {var: getattr(t, var)()
                   for var in genJetVarsRead}, GenJetsAll)
    bPartons = [b for b in filter(lambda p: abs(p.pdgId()) == 5, genPart)]

    for GenJet in GenAllJets:
        GenJet['matchBParton'] = min([999] + [
            deltaR2(GenJet, {
                'eta': b.eta(),
                'phi': b.phi()
            }) for b in bPartons
        ]) < 0.04

    # store if gen-jet is DR matched to a B parton in cone of 0.2
    GenJets = list(filter(lambda j: isGoodGenJet(j), GenAllJets))

    trueAllNonBjets = list(filter(lambda j: not j['matchBParton'], GenAllJets))
    trueAllBjets = list(filter(lambda j: j['matchBParton'], GenAllJets))
    fill_vector_collection(event, "GenAllJet", genJetVars, GenAllJets)
    fill_vector_collection(event, "GenAllBJet", genJetVars, trueAllBjets)

    if not options.noCleaning:
        GenJets = list(
            filter(
                lambda j: min([999] + [deltaR2(j, p)
                                       for p in GenPhotons]) > 0.04, GenJets))

    # gen b jets
    trueBjets = list(filter(lambda j: j['matchBParton'], GenJets))
    trueNonBjets = list(filter(lambda j: not j['matchBParton'], GenJets))

    # Mimick b reconstruction ( if the trailing b fails acceptance, we supplement with the leading non-b jet )
    GenBj0, GenBj1 = (trueBjets + [None, None])[:2]
    if GenBj0: fill_vector(event, "GenBj0", genJetVars, GenBj0)
    if GenBj1: fill_vector(event, "GenBj1", genJetVars, GenBj1)

    # store minimum DR to jets
    for GenPhoton in GenPhotons + GenMGPhotons:
        GenPhoton['photonJetdR'] = min([999] +
                                       [deltaR(GenPhoton, j) for j in GenJets])
        GenPhoton['photonLepdR'] = min(
            [999] + [deltaR(GenPhoton, j) for j in GenPromptLeptons])

    fill_vector_collection(event, "GenPhoton", genPhotonVars, GenPhotons)
    fill_vector_collection(event, "GenMGPhoton", genPhotonVars, GenMGPhotons)
    fill_vector_collection(event, "GenLepton", genLeptonVars, GenPromptLeptons)
    fill_vector_collection(event, "GenJet", genJetVars, GenJets)
    event.nGenBJet = len(trueBjets)

    event.m3 = m3(GenJets)[0]
    if len(GenPhotons) > 0:
        event.m3gamma = m3(GenJets, photon=GenPhotons[0])[0]

    # Ovservables
    if len(GenPromptLeptons) > 1:
        event.mll = (get4DVec(GenPromptLeptons[0]) +
                     get4DVec(GenPromptLeptons[1])).M()
        if len(GenPhotons) > 0:
            event.mllgamma = (get4DVec(GenPromptLeptons[0]) +
                              get4DVec(GenPromptLeptons[1]) +
                              get4DVec(GenPhotons[0])).M()

    event.minDRjj = min([
        deltaR(j1, j2) for i, j1 in enumerate(trueNonBjets[:-1])
        for j2 in trueNonBjets[i + 1:]
    ] + [999])
    event.minDRbb = min([
        deltaR(b1, b2) for i, b1 in enumerate(trueBjets[:-1])
        for b2 in trueBjets[i + 1:]
    ] + [999])
    event.minDRll = min([
        deltaR(l1, l2) for i, l1 in enumerate(GenPromptLeptons[:-1])
        for l2 in GenPromptLeptons[i + 1:]
    ] + [999])
    event.minDRaa = min([
        deltaR(g1, g2) for i, g1 in enumerate(GenPhotons[:-1])
        for g2 in GenPhotons[i + 1:]
    ] + [999])
    event.minDRbj = min(
        [deltaR(b, j) for b in trueBjets for j in trueNonBjets] + [999])
    event.minDRaj = min(
        [deltaR(a, j) for a in GenPhotons for j in trueNonBjets] + [999])
    event.minDRjl = min(
        [deltaR(l, j) for l in GenPromptLeptons for j in trueNonBjets] + [999])
    event.minDRab = min([deltaR(a, b) for a in GenPhotons
                         for b in trueBjets] + [999])
    event.minDRbl = min(
        [deltaR(l, b) for l in GenPromptLeptons for b in trueBjets] + [999])
    event.minDRal = min(
        [deltaR(l, a) for l in GenPromptLeptons for a in GenPhotons] + [999])
Beispiel #5
0
def filler(event):

    event.run, event.lumi, event.evt = reader.evt
    event.lumiweight1fb = lumiweight1fb

    if reader.position % 100 == 0:
        logger.info("At event %i/%i", reader.position, reader.nEvents)

    if args.addReweights:
        event.nrw = weightInfo.nid
        lhe_weights = reader.products['lhe'].weights()
        weights = []
        param_points = []

        for weight in lhe_weights:
            # Store nominal weight (First position!)
            if weight.id == 'rwgt_1': event.rw_nominal = weight.wgt
            if not weight.id in weightInfo.id: continue
            pos = weightInfo.data[weight.id]
            event.rw_w[pos] = weight.wgt
            weights.append(weight.wgt)
            interpreted_weight = interpret_weight(weight.id)
            for var in weightInfo.variables:
                getattr(event, "rw_" + var)[pos] = interpreted_weight[var]
            # weight data for interpolation
            if not hyperPoly.initialized:
                param_points.append(
                    tuple(interpreted_weight[var]
                          for var in weightInfo.variables))

        # get list of values of ref point in specific order
        ref_point_coordinates = [
            weightInfo.ref_point_coordinates[var]
            for var in weightInfo.variables
        ]

        # Initialize with Reference Point
        if not hyperPoly.initialized:
            hyperPoly.initialize(param_points, ref_point_coordinates)
        coeff = hyperPoly.get_parametrization(weights)

        # = HyperPoly(weight_data, args.interpolationOrder)
        event.np = hyperPoly.ndof
        event.chi2_ndof = hyperPoly.chi2_ndof(coeff, weights)
        #logger.debug( "chi2_ndof %f coeff %r", event.chi2_ndof, coeff )
        if event.chi2_ndof > 10**-6:
            logger.warning("chi2_ndof is large: %f", event.chi2_ndof)
        for n in xrange(hyperPoly.ndof):
            event.p_C[n] = coeff[n]

        # lumi weight / w0
        event.ref_lumiweight1fb = event.lumiweight1fb / coeff[0]

    # All gen particles
    gp = reader.products['gp']

    # for searching
    search = GenSearch(gp)

    # find heavy objects before they decay
    genTops = map(
        lambda t: {var: getattr(t, var)()
                   for var in top_varnames},
        filter(lambda p: abs(p.pdgId()) == 6 and search.isLast(p), gp))

    genTops.sort(key=lambda p: -p['pt'])
    fill_vector_collection(event, "genTop", top_varnames, genTops)

    # generated Z's
    genZs = filter(
        lambda p: abs(p.pdgId()) == 23 and search.isLast(p) and abs(
            p.daughter(0).pdgId()) in [11, 13], gp)
    genZs.sort(key=lambda p: -p.pt())
    if len(genZs) > 0:
        genZ = genZs[0]
        for var in boson_read_varnames:
            setattr(event, "genZ_" + var, getattr(genZ, var)())
    else:
        genZ = None

    event.signalZ = 0  #ttZ with Z from gluon or top
    if genZ is not None:

        if abs(search.ascend(genZ).mother(0).pdgId()) in [6, 21]:
            event.signalZ = 1  #ttZ with Z from gluon or top

        d1, d2 = genZ.daughter(0), genZ.daughter(1)
        if d1.pdgId() > 0:
            lm, lp = d1, d2
        else:
            lm, lp = d2, d1
        event.genZ_daughterPdg = lm.pdgId()
        event.genZ_cosThetaStar = cosThetaStar(genZ.mass(), genZ.pt(),
                                               genZ.eta(), genZ.phi(), lm.pt(),
                                               lm.eta(), lm.phi())

    # generated W's
    genWs = filter(lambda p: abs(p.pdgId()) == 24 and search.isLast(p), gp)
    genWs.sort(key=lambda p: -p.pt())
    # W can't have a top-mother - We're looking for the extra boson (there is always an extra boson)
    genWs = filter(lambda p: abs(search.ascend(p).mother(0).pdgId()) != 6,
                   genWs)
    if len(genWs) > 0:
        genW = genWs[0]
        for var in boson_read_varnames:
            setattr(event, "genW_" + var, getattr(genW, var)())
    else:
        genW = None

    if genW is not None:
        d1, d2 = genW.daughter(0), genW.daughter(1)
        if abs(d1.pdgId()) in [11, 13, 15]:
            lep, neu = d1, d2
        else:
            lep, neu = d2, d1

        event.genW_daughterPdg = lep.pdgId()

    def printTopMothers():
        genTopCheck = [(search.ascend(l), l, search.ancestry(search.ascend(l)))
                       for l in filter(lambda p: abs(p.pdgId()) == 6, gp)]

        print genTopCheck
        genTopCheck.sort(key=lambda p: -p[1].pt())
        if len(genTopCheck) > 0:
            topPdg_ids = filter(
                lambda p: p != 2212,
                [abs(particle.pdgId()) for particle in genTopCheck[0][2]])
            print 'TOP 1'
            print topPdg_ids
            previous = genTopCheck[0][0].mother(1)
            print 'first', genTopCheck[0][0].pdgId()
            for i, pdg in enumerate(topPdg_ids):
                try:
                    print 'mother', i, previous.pdgId()
                    print 'mothers', i, [
                        p.pdgId() for p in search.ancestry(previous)
                    ]
                    previous = previous.mother(0)
                except Exception as val:
                    print val
                    break
        if len(genTopCheck) > 1:
            topPdg_ids = filter(
                lambda p: p != 2212,
                [abs(particle.pdgId()) for particle in genTopCheck[1][2]])
            print 'TOP 2'
            print topPdg_ids
            previous = genTopCheck[1][0].mother(1)
            print 'first', genTopCheck[1][0].pdgId()
            for i, pdg in enumerate(topPdg_ids):
                try:
                    print 'mother', i, previous.pdgId()
                    print 'mothers', i, [
                        p.pdgId() for p in search.ancestry(previous)
                    ]
                    previous = previous.mother(0)
                except Exception as val:
                    print val
                    break

    # MET
    genMet = {
        'pt': reader.products['genMET'][0].pt(),
        'phi': reader.products['genMET'][0].phi()
    }
    event.genMet_pt = genMet['pt']
    event.genMet_phi = genMet['phi']

    #    for ttgamma and tt events, categorize events:
    #        a1) ttgamma vertex, gamma from t/g, isolated, must be in ttgamma sample   = ttgamma signal (photonSignal == 1)
    #            -> gamma isolated
    #            -> gamma with only tops/gluons in ancestry
    #        a2) ttgamma, gamma from ISR, must be in ttgamma sample                    = tt ISR bg (photonISR == 1)
    #            -> gamma isolated
    #            -> gamma with no top in ancestry
    #            -> gamma with only gluons and light quarks in ancestry
    #            -> direct gamma mother != gluon!!! (this is a1)
    #        b) tt + isolated gamma from W, l, tau, must be in tt sample               = ttgamma (W,l,tau) bg (photonLep == 1)
    #            -> gamma isolated
    #            -> gamma with direct abs mother being 11, 13, 15 or 24
    #        c1) tt + non isolated gamma from anything including mesons                = tt bg (ttBg == 1)
    #            -> gamma non isolated or meson in ancestry
    #        c2) tt + isolated gamma from bottom quark (from t decay) or jets (from W) = tt bottom bg (ttBg == 1)
    #            -> gamma isolated from b or j (from t/W decay)
    #            ATTENTION: gammas from bottoms with off-shell tops where the
    #                       top decay is done by pythia are currently labeled as ISR!
    #                       However this case is currently not simulated in any sample
    #        d) tt + gamma fake                                                        = ttgamma fake (photonFake == 1)
    #            -> everything else does not contain a photon
    #            -> if it still passes selection: it is a photon fake

    genPhotonsSignalCheck = [
        (search.ascend(l), l, search.ancestry(search.ascend(l)))
        for l in filter(
            lambda p: abs(p.pdgId()) == 22 and p.pt() > 10 and abs(p.eta()) <
            2.5 and search.isLast(p) and p.status() == 1, gp)
    ]
    genPhotonsSignalCheck.sort(key=lambda p: -p[1].pt())

    photonSignal = 0  #a1
    photonISR = 0  #a2
    photonLep = 0  #b
    ttBg = 0  #c1
    photonJets = 0  #c2
    photonFake = 0  #d

    if len(genPhotonsSignalCheck) > 0:
        # check hardest photon with pT>13 and abs(eta)<2.5
        first, last, ancestry = genPhotonsSignalCheck[0]
        # get abs pdgIDs of ancestry
        pdg_ids = filter(lambda p: p != 2212,
                         [abs(particle.pdgId()) for particle in ancestry])
        # check if particles are close by
        close_particles = filter(
            lambda p: p != last and p.pt() > 5 and deltaR2(
                {
                    'phi': last.phi(),
                    'eta': last.eta()
                }, {
                    'phi': p.phi(),
                    'eta': p.eta()
                }) < 0.2**2, search.final_state_particles_no_neutrinos)

        #        print 'mothers pdg', pdg_ids
        #        print 'close', [p.pdgId() for p in close_particles]
        #        print 'first mother pdg', first.mother(0).pdgId()

        #        if len(pdg_ids) < 999:
        #            previous = first.mother(0)
        #            for i, pdg in enumerate(pdg_ids):
        #                try:
        #                    print 'mother', i, previous.pdgId()
        #                    previous = previous.mother(0)
        #                except Exception as val:
        #                    print val
        #                    break

        # deside the categories
        if max(pdg_ids) > 100 or len(close_particles) != 0:
            #photon with meson in ancestry or non isolated -> cat c1)
            ttBg = 1
        elif abs(first.mother(0).pdgId()) in [11, 13, 15, 24]:
            #isolated photon with W, l or tau direct mother -> cat b)
            photonLep = 1
#        elif all( [ p in [ 6, 21 ] for p in pdg_ids ] ) or abs(first.mother(0).pdgId()) == 21: # not working for photons from top, as the gluons can come from light quarks
        elif abs(first.mother(0).pdgId()) in [6, 21]:
            #isolated photon with photon from top or gluon -> cat a1)
            photonSignal = 1


#            printTopMothers()
        elif all([p in [1, 2, 3, 4, 5, 21] for p in pdg_ids]):
            #isolated photon with photon ancestry only containing light quarks or gluons (ISR) -> cat a1)
            photonISR = 1
        else:
            #isolated gammas from bottoms originating from the top decay or jets from W -> cat c2)
            photonJets = 1

    else:
        # if events with photonFake == 1 pass selection: fake gamma -> cat d)
        photonFake = 1

    # if all flags are 0, it is an isolated gamma from a process I havn't thought of!
    # should not be there! - check!
    event.signalPhoton = photonSignal
    event.isrPhoton = photonISR
    event.lepPhoton = photonLep
    event.nonIsoPhoton = ttBg
    event.jetPhoton = photonJets
    event.fakePhoton = photonFake

    # gen photons: particle-level isolated gen photons
    genPhotons = [(search.ascend(l), l) for l in filter(
        lambda p: abs(p.pdgId()) == 22 and p.pt() > 15 and search.isLast(p) and
        p.status() == 1, gp)]
    genPhotons.sort(key=lambda p: -p[1].pt())
    genPhotons_ = []

    for first, last in genPhotons[:100]:
        mother_pdgId = first.mother(
            0).pdgId() if first.numberOfMothers() > 0 else 0
        genPhoton_ = {var: getattr(last, var)() for var in boson_read_varnames}
        # kinematic photon selection
        if not isGoodGenPhoton(genPhoton_): continue
        genPhoton_['motherPdgId'] = mother_pdgId
        genPhoton_['status'] = last.status()

        close_particles = filter(
            lambda p: p != last and deltaR2(
                {
                    'phi': last.phi(),
                    'eta': last.eta()
                }, {
                    'phi': p.phi(),
                    'eta': p.eta()
                }) < 0.4**2, search.final_state_particles_no_neutrinos)
        genPhoton_['relIso04'] = sum([p.pt() for p in close_particles],
                                     0) / last.pt()
        # require isolation
        if genPhoton_['relIso04'] < 0.4:
            genPhotons_.append(genPhoton_)

    # genLeptons: prompt gen-leptons
    genLeptons = [(search.ascend(l), l) for l in filter(
        lambda p: abs(p.pdgId()) in [11, 13] and search.isLast(p) and p.pt() >=
        0 and p.status() == 1, gp)]
    promptGenLeps = []
    allGenLeps = []
    for first, last in genLeptons:
        mother = first.mother(0) if first.numberOfMothers() > 0 else None
        if mother is not None:
            mother_pdgId = mother.pdgId()
            mother_ascend = search.ascend(mother)
            grandmother = mother_ascend.mother(
                0) if mother.numberOfMothers() > 0 else None
            grandmother_pdgId = grandmother.pdgId(
            ) if grandmother is not None else 0
        else:
            mother_pdgId = 0
            grandmother_pdgId = 0
        genLep = {var: getattr(last, var)() for var in lep_varnames}
        genLep['motherPdgId'] = mother_pdgId
        genLep['grandmotherPdgId'] = grandmother_pdgId
        allGenLeps.append(genLep)
        if abs(genLep['motherPdgId']) in [11, 13, 15, 23, 24, 25]:
            promptGenLeps.append(genLep)

    # filter gen leptons
    promptGenLeps = list(filter(lambda l: isGoodGenLepton(l), promptGenLeps))
    promptGenLeps.sort(key=lambda p: -p['pt'])
    addIndex(promptGenLeps)

    ## removing photons in dR cone leptons (radiation photons)
    for genPhoton in genPhotons_:
        genPhoton['minLeptonDR'] = min(
            [999] + [deltaR(genPhoton, l) for l in allGenLeps])
    genPhotons_ = list(filter(lambda g: g['minLeptonDR'] > 0.4, genPhotons_))
    addIndex(genPhotons_)

    # jets
    fwlite_genJets = filter(genJetId, reader.products['genJets'])
    genJets = map(
        lambda t: {var: getattr(t, var)()
                   for var in jet_read_varnames},
        filter(lambda j: j.pt() > 30, fwlite_genJets))
    # filter genJets
    genJets = list(filter(lambda j: isGoodGenJet(j), genJets))
    # cleaning of jets with isolated photons
    genJets = list(
        filter(
            lambda j: min([999] + [deltaR2(j, p)
                                   for p in genPhotons_]) > 0.4**2, genJets))

    # store minimum DR to jets
    for genPhoton in genPhotons_:
        genPhoton['minJetDR'] = min([999] +
                                    [deltaR(genPhoton, j) for j in genJets])

    # find b's from tops:
    b_partons = [
        b for b in filter(
            lambda p: abs(p.pdgId()) == 5 and p.numberOfMothers() == 1 and abs(
                p.mother(0).pdgId()) == 6, gp)
    ]

    # store if gen-jet is DR matched to a B parton
    for genJet in genJets:
        genJet['matchBParton'] = (min([999] + [
            deltaR2(genJet, {
                'eta': b.eta(),
                'phi': b.phi()
            }) for b in b_partons
        ]) < 0.2**2)

    genJets = filter(
        lambda j:
        (min([999] + [deltaR2(j, l) for l in promptGenLeps
                      if l['pt'] > 10]) > 0.3**2), genJets)
    genJets.sort(key=lambda p: -p['pt'])
    addIndex(genJets)

    # gen b jets
    trueBjets = list(filter(lambda j: j['matchBParton'], genJets))
    trueNonBjets = list(filter(lambda j: not j['matchBParton'], genJets))

    # Mimick b reconstruction ( if the trailing b fails acceptance, we supplement with the leading non-b jet )
    genBj0, genBj1 = (trueBjets + trueNonBjets + [None, None])[:2]
    if genBj0: fill_vector(event, "genBj0", jet_write_varnames, genBj0)
    if genBj1: fill_vector(event, "genBj1", jet_write_varnames, genBj1)

    # reco-bjet/leading lepton association
    if len(promptGenLeps) > 0 and genBj0 and genBj1:
        if vecSumPt(genBj0, promptGenLeps[0], genMet) > vecSumPt(
                genBj1, promptGenLeps[0], genMet):
            event.genBjLeadlep_index, event.genBjLeadhad_index = genBj0[
                'index'], genBj1['index']
        else:
            event.genBjLeadlep_index, event.genBjLeadhad_index = genBj1[
                'index'], genBj0['index']

    # find Z in genLep
    (event.genLepZ_mass, genLepZ_l1_index,
     genLepZ_l2_index) = closestOSDLMassToMZ(promptGenLeps)
    genLepNonZ_indices = [
        i for i in range(len(promptGenLeps))
        if i not in [genLepZ_l1_index, genLepZ_l2_index]
    ]
    event.genLepZ_l1_index = promptGenLeps[genLepZ_l1_index][
        'index'] if genLepZ_l1_index >= 0 else -1
    event.genLepZ_l2_index = promptGenLeps[genLepZ_l2_index][
        'index'] if genLepZ_l2_index >= 0 else -1
    event.genLepNonZ_l1_index = promptGenLeps[
        genLepNonZ_indices[0]]['index'] if len(genLepNonZ_indices) > 0 else -1
    event.genLepNonZ_l2_index = promptGenLeps[
        genLepNonZ_indices[1]]['index'] if len(genLepNonZ_indices) > 1 else -1
    # store genLepZ stuff
    if event.genLepZ_mass > 0:
        genLepZ_l1 = ROOT.TLorentzVector()
        genLepZ_l1.SetPtEtaPhiM(promptGenLeps[event.genLepZ_l1_index]['pt'],
                                promptGenLeps[event.genLepZ_l1_index]['eta'],
                                promptGenLeps[event.genLepZ_l1_index]['phi'],
                                0)
        genLepZ_l2 = ROOT.TLorentzVector()
        genLepZ_l2.SetPtEtaPhiM(promptGenLeps[event.genLepZ_l2_index]['pt'],
                                promptGenLeps[event.genLepZ_l2_index]['eta'],
                                promptGenLeps[event.genLepZ_l2_index]['phi'],
                                0)
        genLepZ = genLepZ_l1 + genLepZ_l2
        event.genLepZ_pt = genLepZ.Pt()
        event.genLepZ_eta = genLepZ.Eta()
        event.genLepZ_phi = genLepZ.Phi()
        event.genLepZ_lldPhi = deltaPhi(
            promptGenLeps[event.genLepZ_l1_index]['phi'],
            promptGenLeps[event.genLepZ_l2_index]['phi'])
        event.genLepZ_lldR = deltaR(promptGenLeps[event.genLepZ_l1_index],
                                    promptGenLeps[event.genLepZ_l2_index])
        genLepMinus_index = event.genLepZ_l1_index if promptGenLeps[
            event.genLepZ_l1_index]['pdgId'] > 0 else event.genLepZ_l2_index
        event.genLepZ_cosThetaStar = cosThetaStar(
            event.genLepZ_mass, event.genLepZ_pt, event.genLepZ_eta,
            event.genLepZ_phi, promptGenLeps[genLepMinus_index]['pt'],
            promptGenLeps[genLepMinus_index]['eta'],
            promptGenLeps[genLepMinus_index]['phi'])

    # reco-bjet/nonZ lepton association
    if event.genLepNonZ_l1_index >= 0 and genBj0 and genBj1:
        if vecSumPt(genBj0, promptGenLeps[event.genLepNonZ_l1_index],
                    genMet) > vecSumPt(
                        genBj1, promptGenLeps[event.genLepNonZ_l1_index],
                        genMet):
            event.genBjNonZlep_index, event.genBjNonZhad_index = genBj0[
                'index'], genBj1['index']
        else:
            event.genBjNonZlep_index, event.genBjNonZhad_index = genBj1[
                'index'], genBj0['index']

    #for jet in genJets:
    #    print jet['isMuon'], jet['isElectron'], jet['isPhoton'], min([999]+[deltaR2(jet, l) for l in promptGenLeps if l['pt']>10]), jet

    # jet/lepton disambiguation -> remove jets, because gen-jets cluster all leptons
    #if args.logLevel == 'DEBUG':
    #    for jet in filter( lambda j: not (min([999]+[deltaR2(j, l) for l in promptGenLeps if l['pt']>10]) > 0.3**2 ), genJets ):
    #        logger.debug( "Filtered gen %f jet %r lep %r", sqrt((min([999]+[deltaR2(jet, l) for l in promptGenLeps if l['pt']>10]))), jet, [ (l['eta'], jet['pt']/l['pt']) for l in promptGenLeps] )
    #        assert False, ""

    fill_vector_collection(event, "genPhoton", gen_photon_varnames,
                           genPhotons_)
    fill_vector_collection(event, "genLep", lep_all_varnames, promptGenLeps)
    fill_vector_collection(event, "genJet", jet_write_varnames, genJets)