def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return
    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')
    Event = E.getPrimitives('EVENT')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    CutStrings = {
        '': '_Combined_NS_NH_FPTE_HLT_REP_PT_PC_LXYE_MASS',
        'G': '_Combined_NS_NH_FPTE_HLT_GLB_REP_PT_PC_LXYE_MASS',
        'GN': '_Combined_NS_NH_FPTE_HLT_GLB_NTL_REP_PT_PC_LXYE_MASS',
        'M': '_Combined_NS_NH_FPTE_HLT_MED_REP_PT_PC_LXYE_MASS',
        'MN': '_Combined_NS_NH_FPTE_HLT_MED_NTL_REP_PT_PC_LXYE_MASS',
    }
    CutStringKeys = ('', 'G', 'GN', 'M', 'MN')
    selectedDimuons, selectedDSAmuons, selectedPATmuons = {}, {}, {}

    for key in CutStringKeys:
        selectedDimuons[key], selectedDSAmuons[key], selectedPATmuons[
            key] = Selector.SelectObjects(E, CutStrings[key], Dimuons3,
                                          DSAmuons, PATmuons)

    selectedIDs = {key: set() for key in CutStringKeys}
    for key in CutStringKeys:
        if selectedDimuons[key] is None: continue
        for dim in selectedDimuons[key]:
            selectedIDs[key].add((dim.composition[:3], dim.idx1, dim.idx2))

    maxLen = max([len(selectedIDs[key]) for key in selectedIDs])

    if not selectedIDs[''] == selectedIDs['G'] == selectedIDs[
            'M'] == selectedIDs['GN'] == selectedIDs['MN']:
        print '::: {:13s} {:d} {:7d} {:10d} :::'.format(
            self.NAME, Event.run, Event.lumi, Event.event)
        for key in CutStringKeys:
            strings = []
            if selectedDimuons[key] is not None:
                for dim in selectedDimuons[key]:
                    strings.append(
                        '{:3s} {:2d} {:2d} ::: {:9.4f} {:8.4f} {:10.2f} {:6.2f}'
                        .format(dim.composition[:3], dim.idx1, dim.idx2,
                                dim.LxySig(), dim.Lxy(), dim.normChi2,
                                min(dim.mu1.d0Sig(), dim.mu2.d0Sig())))
            while len(strings) < maxLen:
                strings.append('-')

            for s in strings:
                print '  {:2s} ::: {:s}'.format(key if key != '' else 'X', s)
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # no LxySig, no Dphi, and no blinding
    # LxySig < 5 applied below; iDphi and Dphi applied separately and histogrammed separately
    CUTSTRING = '_Combined_NS_NH_FPTE_HLT_REP_PT_TRK_NDT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_OS'

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    def getOriginalMuons(dim, DSAmuons):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    def modifiedName(name):
        if 'DoubleMuon' in name:
            return 'Data' + name[17]
        if 'QCD' in name:
            return 'QCD'
        if 'HTo2X' in name:
            return '{:4d} {:3d} {:4d}'.format(*self.SP.SP)
        return name

    for DPHI in ('_IDPHI', '_DPHI'):
        selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
            E, CUTSTRING + DPHI, Dimuons3, DSAmuons, PATmuons)
        if selectedDimuons is None: continue

        DSADimuons = [
            dim for dim in selectedDimuons
            if dim.composition == 'DSA' and dim.LxySig() < 6.
        ]

        for dim in DSADimuons:
            self.HISTS['LxySig' + DPHI].Fill(dim.LxySig())
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    CUTSTRING = '_Combined_NS_NH_FPTE_HLT_REP_PT_TRK_NDT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_LXYSIG_OS_DPHI'

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    # gen stuff
    if self.SP is not None:
        if '4Mu' in self.NAME:
            mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives(
                'GEN')
            genMuons = (mu11, mu12, mu21, mu22)
            genMuonPairs = ((mu11, mu12), (mu21, mu22))
        elif '2Mu2J' in self.NAME:
            mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
            genMuons = (mu1, mu2)
            genMuonPairs = ((mu1, mu2), )

    # do the selection
    for key in ('before', 'after'):
        selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
            E, CUTSTRING, Dimuons3, DSAmuons, PATmuons, applyDeltaR=key)
        if selectedDimuons is None: continue
        DSADimuons = [
            dim for dim in selectedDimuons if dim.composition == 'DSA'
        ]

        if self.SP is not None:
            if len(genMuonPairs) == 1:
                genMuonPair = genMuonPairs[0]
                dimuonMatches, muonMatches, exitcode = matchedDimuons(
                    genMuonPair, DSADimuons)
                if len(dimuonMatches) > 0:
                    realMatches = {0: dimuonMatches[0]}
                else:
                    realMatches = {}
            else:
                realMatches, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(
                    genMuonPairs, DSADimuons)

            for pairIndex in realMatches:
                genMuon = genMuonPairs[pairIndex][0]
                self.HISTS['Lxy_{}'.format(key)].Fill(genMuon.Lxy())
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    CUTSTRING = '_Combined_NS_NH_FPTE_HLT_REP_PT_TRK_NDT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_LXYSIG_OS'

    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, CUTSTRING, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return

    for dim in selectedDimuons:
        if dim.composition != 'DSA': continue
        if not Selections.modelDependentMassCut(self.SP.mX, dim.mass): continue
        if dim.deltaPhi < R.TMath.Pi() / 2.:
            self.COUNTS['before'] += 1
        if dim.deltaPhi < R.TMath.Pi() / 4.:
            self.COUNTS['after'] += 1
def analyze(self, E, PARAMS=None):
    Event = E.getPrimitives('EVENT')

    for key in self.COUNTS:
        weight = PileupWeight(Event.nTruePV, variation=key)
        self.COUNTS[key]['sumWeights'] += weight

    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    cutstring = CUTSTRING
    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(E, cutstring, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is not None:
        for dim in selectedDimuons:
            if dim.composition != 'DSA': continue
            if dim.LxySig() < 7.: continue

            for key in self.COUNTS:
                weight = PileupWeight(Event.nTruePV, variation=key)
                self.COUNTS[key]['counts'] += weight
Пример #6
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # take 10% of data: event numbers ending in 7
    # unmask data if we're sure we're in the |deltaPhi| > pi/2 range
    #if 'DoubleMuon' in self.NAME and '_IDPHI' not in self.CUTS:
    #    if Event.event % 10 != 7: return

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, self.CUTS, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return

    def getOriginalMuons(dim, DSAmuons):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    def modifiedName(name):
        if 'DoubleMuon' in name:
            return 'Data' + name[17]
        if 'QCD' in name:
            return 'QCD'
        if 'HTo2X' in name:
            return '{:4d} {:3d} {:4d}'.format(*self.SP.SP)
        return name

    cleanMuons = [
        d for d in DSAmuons if d.nCSCHits + d.nDTHits > 12 and d.pt > 5.
    ]

    for dim in selectedDimuons:
        if dim.composition != 'DSA': continue
        #if not (dim.composition == 'DSA' or dim.composition == 'HYBRID'): continue

        mu1, mu2 = getOriginalMuons(dim, DSAmuons)
        nMinusPP, nPlusPP = numberOfParallelPairs(DSAmuons)

        print '{:9s} {:d} {:7d} {:10d} {:2d} ::: {:3s} {:2d} {:2d} ::: {:9.4f} {:8.4f} {:5.2f} {:6.3f} {:6.3f} {:.3e} ::: {:6.2f} {:6.2f} {:7.2f} {:7.2f} ::: {:2d} {:2d} {:2d} {:2d} {:2d} ::: {:6.3f} {:6.3f} ::: {:2d} {:2d} {:2d} {:2d} ::: {:6.4f} ::: {:2d} {:2d} {:2d} {:2d} ::: {:.5e} {:.5e} {:.5e} ::: {:.3e} ::: {:6.4f} {:6.4f} {:7.4f} {:7.4f}'.format(
            modifiedName(self.NAME), Event.run, Event.lumi, Event.event,
            int(eventWeight), dim.composition[:3], dim.idx1, dim.idx2,
            dim.LxySig(), dim.Lxy(), dim.normChi2, dim.cosAlpha,
            dim.cosAlphaOriginal, dim.DCA, mu1.d0(), mu2.d0(), mu1.d0Sig(),
            mu2.d0Sig(), len(DSAmuons), len(cleanMuons), nMinusPP, nPlusPP,
            nMinusPP + nPlusPP, mu1.normChi2, mu2.normChi2, mu1.nCSCHits,
            mu2.nCSCHits, mu1.nDTHits, mu2.nDTHits, dim.deltaPhi, mu1.charge,
            mu2.charge, dim.mu1.charge, dim.mu2.charge, dim.mu1.pt, dim.mu2.pt,
            dim.pt, dim.mass, mu1.deltaR_SA, mu2.deltaR_SA, mu1.timeAtIP_InOut,
            mu2.timeAtIP_InOut)
Пример #7
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return
    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')
    Event = E.getPrimitives('EVENT')

    Dimuons = [dim for dim in Dimuons3 if dim.composition == 'DSA']

    if self.SP is not None:
        if '4Mu' in self.NAME:
            mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives(
                'GEN')
            genMuons = (mu11, mu12, mu21, mu22)
            genMuonPairs = ((mu11, mu12), (mu21, mu22))
        elif '2Mu2J' in self.NAME:
            mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
            genMuons = (mu1, mu2)
            genMuonPairs = ((mu1, mu2), )

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    selectedDimuons, selectedDSAmuons = Selector.SelectObjects(
        E, self.CUTS, Dimuons, DSAmuons)
    if selectedDimuons is None: return

    selectedIDs = [dim.ID for dim in selectedDimuons]
    replacedDimuons, wasReplaced = replaceDSADimuons(Dimuons3,
                                                     DSAmuons,
                                                     mode='PAT')
    replacedIDs = {
        dim.ID: rdim
        for dim, rdim, isReplaced in zip(Dimuons, replacedDimuons, wasReplaced)
        if isReplaced
    }

    # this script is for dumping Drell Yan events with Lxy Sig > 100
    # the output of this is used in badChi2.py

    for dim in selectedDimuons:
        if dim.ID in replacedIDs:
            rdim = replacedIDs[dim.ID]
            if rdim.LxySig() > 100.:
                print '{:d} {:7d} {:10d} ::: {} ==> {} ::: {:9.4f} ==> {:9.4f} ::: {:8.4f} ==> {:8.4f} ::: {:10.2f} ==> {:10.2f}'.format(
                    Event.run,
                    Event.lumi,
                    Event.event,
                    dim.ID,
                    rdim.ID,
                    dim.LxySig(),
                    rdim.LxySig(),
                    dim.Lxy(),
                    rdim.Lxy(),
                    dim.normChi2,
                    rdim.normChi2,
                )
Пример #8
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # take 10% of data: event numbers ending in 7
    if 'DoubleMuon' in self.NAME:
        if Event.event % 10 != 7: return

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(E, self.CUTS, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return
    selectedDimuons = [dim for dim in selectedDimuons if dim.composition == 'DSA']

    def getOriginalMuons(dim):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    for dim in selectedDimuons:
        for val in self.COUNTS:
            if dim.normChi2 < val:
                self.COUNTS[val] += 1

    if len(selectedDimuons) == 0: return

    if '4Mu' in self.NAME:
        mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives('GEN')
        genMuons = (mu11, mu12, mu21, mu22)
        genMuonPairs = ((mu11, mu12), (mu21, mu22))
    elif '2Mu2J' in self.NAME:
        mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
        genMuons = (mu1, mu2)
        genMuonPairs = ((mu1, mu2),)

    # do the signal matching
    if len(genMuonPairs) == 1:
        genMuonPair = genMuonPairs[0]
        dimuonMatches, muonMatches, exitcode = matchedDimuons(genMuonPair, selectedDimuons)
        if len(dimuonMatches) > 0:
            realMatches = {0:dimuonMatches[0]}
        else:
            realMatches = {}
    else:
        realMatches, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(genMuonPairs, selectedDimuons)

    for pairIndex in realMatches:
        genMuon = genMuonPairs[pairIndex][0]
        dim = realMatches[pairIndex]['dim']

        for val in self.COUNTS:
            if dim.normChi2 < val:
                self.MATCH[val] += 1
Пример #9
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return
    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')
    Event = E.getPrimitives('EVENT')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    selectedDimuonsOld, selectedDSAmuonsOld = Selector.SelectObjects(
        E, self.CUTS, [dim for dim in Dimuons3 if dim.composition == 'DSA'],
        DSAmuons)
    if selectedDimuonsOld is None: return

    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjectsReordered(
        E, self.CUTS, Dimuons3, DSAmuons, PATmuons)

    selectedDimuonsHyb, selectedDSAmuonsHyb, selectedPATmuonsHyb = Selector.SelectObjectsReordered(
        E,
        self.CUTS,
        Dimuons3,
        DSAmuons,
        PATmuons,
        keepHybrids=True,
        option=ARGS.PCOPTION)

    if self.SP is not None:
        if '4Mu' in self.NAME:
            mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives(
                'GEN')
            genMuons = (mu11, mu12, mu21, mu22)
            genMuonPairs = ((mu11, mu12), (mu21, mu22))
        elif '2Mu2J' in self.NAME:
            mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
            genMuons = (mu1, mu2)
            genMuonPairs = ((mu1, mu2), )

        realMatches = {}
        if selectedDimuons is not None:
            # do the signal matching
            if len(genMuonPairs) == 1:
                genMuonPair = genMuonPairs[0]
                dimuonMatches, muonMatches, exitcode = matchedDimuons(
                    genMuonPair, selectedDimuons)
                if len(dimuonMatches) > 0:
                    realMatches = {0: dimuonMatches[0]}
                else:
                    realMatches = {}
            else:
                realMatches, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(
                    genMuonPairs, selectedDimuons)

        if len(realMatches) == 0:
            if len(genMuonPairs) == 1:
                genMuonPair = genMuonPairs[0]
                dimuonMatches, muonMatches, exitcode = matchedDimuons(
                    genMuonPair, selectedDimuonsOld)
                if len(dimuonMatches) > 0:
                    realMatchesOld = {0: dimuonMatches[0]}
                else:
                    realMatchesOld = {}
            else:
                realMatchesOld, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(
                    genMuonPairs, selectedDimuonsOld)

            if len(realMatchesOld) > 0:
                # huzzah!
                self.COUNTS['huzzah'] += 1
                HybridDimuons = [
                    dim for dim in Dimuons3 if dim.composition == 'HYBRID'
                ]
                HybridIDs = [dim.ID for dim in HybridDimuons]

                # defines a SegMatch, returns a pair of indices (called candidate)
                def lookForSegMatch(DSAmuon):
                    candidate = None
                    if DSAmuon.idx_SegMatch is None:
                        pass
                    elif len(DSAmuon.idx_SegMatch) > 1:
                        if DSAmuon.idx_ProxMatch in DSAmuon.idx_SegMatch:
                            candidate = DSAmuon.idx_ProxMatch
                        else:
                            # take first entry
                            # which is the smallest index = largest pT
                            candidate = DSAmuon.idx_SegMatch[0]
                    else:
                        candidate = DSAmuon.idx_SegMatch[0]
                    return candidate

                # check whether the DSA dimuons have hybrid replacements
                for dim in selectedDimuonsOld:
                    candidates = map(lookForSegMatch,
                                     (DSAmuons[dim.idx1], DSAmuons[dim.idx2]))

                    if candidates.count(None) == 1:
                        PATIndex = candidates[0] if candidates[
                            0] is not None else candidates[1]
                        DSAIndex = dim.idx2 if candidates[
                            1] is None else dim.idx1
                        testID = (DSAIndex, PATIndex)
                        if testID in HybridIDs:
                            self.COUNTS['hybfound'] += 1
                        else:
                            self.COUNTS['hybnot'] += 1
                    elif candidates.count(None) == 2:
                        self.COUNTS['nomatch'] += 1
                    elif candidates.count(None) == 0:
                        self.COUNTS['bothmatch'] += 1
                        PATDim = None
                        for pd in Dimuons3:
                            if pd.composition == 'PAT' and set(
                                    candidates).issubset(pd.ID):
                                PATDim = pd
                                break
                        if PATDim is None:
                            self.COUNTS['failedDim'] += 1
                            continue
                        elif PATmuons[PATDim.idx1].pt < 10. or PATmuons[
                                PATDim.idx2].pt < 10.:
                            self.COUNTS['failedPT'] += 1
                            continue
                        elif PATDim.LxyErr() > 99.:
                            self.COUNTS['failedLxyE'] += 1
                            continue
                        elif PATDim.mass < 5.:
                            self.COUNTS['failedM'] += 1
                            continue
                        else:
                            self.COUNTS['failedMatch'] += 1
                    else:
                        print 'What?'

                # see if gen muons matched with hybrid selection
                if selectedDimuonsHyb is not None:
                    if len(genMuonPairs) == 1:
                        genMuonPair = genMuonPairs[0]
                        dimuonMatches, muonMatches, exitcode = matchedDimuons(
                            genMuonPair, selectedDimuonsHyb)
                        if len(dimuonMatches) > 0:
                            realMatchesHyb = {0: dimuonMatches[0]}
                        else:
                            realMatchesHyb = {}
                    else:
                        realMatchesHyb, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(
                            genMuonPairs, selectedDimuonsHyb)

                    if len(realMatchesHyb) > 0:
                        self.COUNTS['recovered'] += 1
Пример #10
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    for attr in ('DSAmuons', 'PATmuons', 'Dimuons3'):
        setattr(self, attr, locals()[attr])

    def modifiedName(name):
        if 'DoubleMuon' in name:
            return 'Data' + name[17]
        if 'QCD' in name:
            return 'QCD'
        return name

    # no replacement, LxySig, no Dphi, and no blinding
    # LxySig < 1.5 or 60 < < 115. applied to the REPLACED PAT muons below; iDphi and Dphi kept track of in dump
    CUTSTRING = '_Combined_NS_NH_FPTE_HLT_PT_TRK_NDT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_TIME'

    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, CUTSTRING, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return

    def keepEvent(patDimuon, mu1, mu2):
        if ARGS.STYLE == 'QCD':
            return (patDimuon.LxySig() < 115. and patDimuon.LxySig() > 60.
                    and mu1.trackIso / mu1.pt > 0.5
                    and mu2.trackIso / mu2.pt > 0.5)
        if ARGS.STYLE == 'DY':
            return (patDimuon.LxySig() < 1.5 and mu1.trackIso / mu1.pt < 0.05
                    and mu2.trackIso / mu2.pt < 0.05)

    for dim in selectedDimuons:

        # opposite sign and same sign are combined
        # depending on QCD mode or DY mode, select DSA-DSA dimuons based on PAT quantities
        # print useful information

        patDimuon = self.getPATDimuon(dim)
        if patDimuon is None:
            continue

        mu1, mu2 = PATmuons[patDimuon.mu1.idx], PATmuons[patDimuon.mu2.idx]

        if keepEvent(patDimuon, mu1, mu2):
            print '{:9s} {:d} {:7d} {:10d} {:2d} ::: PAT {:2d} {:2d} <-- DSA {:2d} {:2d} ::: {:9.4f} {:9.4f} ::: {:6.4f} {:6.4f} ::: {:.5e} {:.5e} ::: {:.5e} {:.5e} {:.5e} ::: {:.4e} {:6.4f} ::: {:2s}'.format(
                modifiedName(self.NAME), Event.run, Event.lumi, Event.event,
                int(eventWeight), patDimuon.ID[0],
                patDimuon.ID[1], dim.ID[0], dim.ID[1], patDimuon.LxySig(),
                dim.LxySig(), patDimuon.deltaPhi, dim.deltaPhi, dim.Lxy(),
                dim.LxyErr(), dim.mu1.pt, dim.mu2.pt, dim.pt, dim.mass,
                dim.deltaR,
                'OS' if dim.mu1.charge + dim.mu2.charge == 0 else 'SS')
Пример #11
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # no Lxy sig
    CUTSTRING = '_Combined_NS_NH_FPTE_HLT_REP_PT_TRK_NDT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_OS'
    if 'DoubleMuon' in self.NAME:
        CUTSTRING += '_IDPHI'
    else:
        CUTSTRING += '_DPHI'

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    # gen stuff
    if self.SP is not None:
        if '4Mu' in self.NAME:
            mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives(
                'GEN')
            genMuons = (mu11, mu12, mu21, mu22)
            genMuonPairs = ((mu11, mu12), (mu21, mu22))
        elif '2Mu2J' in self.NAME:
            mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
            genMuons = (mu1, mu2)
            genMuonPairs = ((mu1, mu2), )

    # do the selection
    selectedDimuons, selectedDSAmuons, selectedPATmuons, DSADimuons = {}, {}, {}, {}
    for deltaR in DELTARS:
        # deltaR was a keyword here controlling the deltaR parameter, now 0.1 with PP
        selectedDimuons[deltaR], selectedDSAmuons[deltaR], selectedPATmuons[
            deltaR] = Selector.SelectObjects(E,
                                             CUTSTRING,
                                             Dimuons3,
                                             DSAmuons,
                                             PATmuons,
                                             deltaR=deltaR)
        if selectedDimuons[deltaR] is None:
            DSADimuons[deltaR] = []
            continue
        DSADimuons[deltaR] = [
            dim for dim in selectedDimuons[deltaR] if dim.composition == 'DSA'
        ]

    def getOriginalMuons(dim, DSAmuons):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    def modifiedName(name):
        if 'DoubleMuon' in name:
            return 'Data' + name[17]
        if 'QCD' in name:
            return 'QCD'
        if 'HTo2X' in name:
            return '{:4d} {:3d} {:4d}'.format(*self.SP.SP)
        return name

    # meh
    for deltaR in DELTARS:

        # do the signal matching
        if self.SP is not None:
            if len(genMuonPairs) == 1:
                genMuonPair = genMuonPairs[0]
                dimuonMatches, muonMatches, exitcode = matchedDimuons(
                    genMuonPair, DSADimuons[deltaR])
                if len(dimuonMatches) > 0:
                    realMatches = {0: dimuonMatches[0]}
                else:
                    realMatches = {}
            else:
                realMatches, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(
                    genMuonPairs, DSADimuons[deltaR])

            for pairIndex in realMatches:
                genMuon = genMuonPairs[pairIndex][0]
                self.HISTS['Lxy_{}'.format(DELTARS[deltaR]['tag'])].Fill(
                    genMuon.Lxy())

        else:
            self.COUNTS[deltaR] += len(DSADimuons[deltaR])
Пример #12
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # no Lxy sig
    CUTSTRING = '_Combined_NS_NH_FPTE_HLT_REP_PT_TRK_NDT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_OS'
    if 'DoubleMuon' in self.NAME:
        CUTSTRING += '_IDPHI'
    else:
        CUTSTRING += '_DPHI'

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    # do the selection
    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, CUTSTRING, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None:
        DSADimuons = []
        return
    DSADimuons = [dim for dim in selectedDimuons if dim.composition == 'DSA']

    def getOriginalMuons(dim, DSAmuons):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    def modifiedName(name):
        if 'DoubleMuon' in name:
            return 'Data' + name[17]
        if 'QCD' in name:
            return 'QCD'
        if 'HTo2X' in name:
            return '{:4d} {:3d} {:4d}'.format(*self.SP.SP)
        return name

    # gen stuff
    if self.SP is not None:
        if '4Mu' in self.NAME:
            mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives(
                'GEN')
            genMuons = (mu11, mu12, mu21, mu22)
            genMuonPairs = ((mu11, mu12), (mu21, mu22))
        elif '2Mu2J' in self.NAME:
            mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
            genMuons = (mu1, mu2)
            genMuonPairs = ((mu1, mu2), )

        if len(genMuonPairs) == 1:
            genMuonPair = genMuonPairs[0]
            dimuonMatches, muonMatches, exitcode = matchedDimuons(
                genMuonPair, selectedDimuons)  #DSADimuons)
            if len(dimuonMatches) > 0:
                realMatches = {0: dimuonMatches[0]}
            else:
                realMatches = {}
        else:
            realMatches, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(
                genMuonPairs, selectedDimuons)  # DSADimuons)

    # the other plots
    for dim in DSADimuons:

        matched = None
        if self.SP is not None and dim.ID in [
                realMatches[pIdx]['dim'].ID for pIdx in realMatches
        ]:
            matched = True

        mu1, mu2 = getOriginalMuons(dim, DSAmuons)

        for mu in (mu1, mu2):
            for matchType in ('Prox', 'Seg'):
                for vectorType in ('PD', 'PP'):
                    match = getattr(mu,
                                    '{}Match{}'.format(matchType, vectorType))
                    if match.idx is not None:
                        if matchType == 'Prox':
                            iterables = [(match.idx, match.deltaR, match.nSeg,
                                          mu.nSegments)]
                        else:
                            iterables = [
                                (a, b, c, mu.nSegments) for a, b, c in zip(
                                    match.idx, match.deltaR, match.nSeg)
                            ]

                        for idx, deltaR, nSeg, nDSASeg in iterables:
                            self.HISTS['{}_{}_deltaR'.format(
                                matchType, vectorType)].Fill(deltaR)
                            self.HISTS['{}_{}_fSeg'.format(
                                matchType, vectorType)].Fill(
                                    float(nSeg) /
                                    nDSASeg if nDSASeg != 0 else 0.)

                            if matched is not None:
                                self.HISTS['{}_{}_deltaR_Matched'.format(
                                    matchType, vectorType)].Fill(deltaR)
                                self.HISTS['{}_{}_fSeg_Matched'.format(
                                    matchType, vectorType)].Fill(
                                        float(nSeg) /
                                        nDSASeg if nDSASeg != 0 else 0.)
def analyze(self, E, PARAMS=None):
    # so, a bit of a weird ordering here compared to my usual preferences
    # Event weight goes first because it doesn't depend on anything else
    # Gens come next because signal weights need gens to compute
    # Then the weight sum is computed, because it should not depend on trigger
    # THEN the trigger is applied, the other primitives are extracted, etc.

    Event = E.getPrimitives('EVENT')

    # take 10% of data: event numbers ending in 7
    if 'DoubleMuon' in self.NAME and not self.ARGS.IDPHI:
        if Event.event % 10 != 7: return

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    if self.SP is not None:
        if '2Mu2J' in self.NAME:
            mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
            genMuons = (mu1, mu2)
            genMuonPairs = ((mu1, mu2),)

            for factor in self.FACTORS:
                signalWeight = AT.SignalWeight(self.SP.cTau, self.SP.cTau/float(factor), mu1, X)
                self.WEIGHTS[factor] += signalWeight*eventWeight

    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    cutString = ALL[:]
    if ('DoubleMuon' in self.NAME or ('DoubleMuon' not in self.NAME and self.SP is None)) and self.ARGS.IDPHI:
        cutString = cutString.replace('DPHI', 'IDPHI')
    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(E, cutString, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return

    def getOriginalMuons(dim):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    for factor in self.FACTORS:
        signalWeight = 1.
        if self.SP is not None:
            signalWeight = AT.SignalWeight(self.SP.cTau, self.SP.cTau/float(factor), mu1, X)
        for key in CONFIG:
            f = CONFIG[key]['LAMBDA']
            for dim in selectedDimuons:
                if dim.composition != 'DSA': continue

                mus = getOriginalMuons(dim)

                if CONFIG[key]['TYPE'] == 'DSA':
                    fills = [f(*mus)]
                else:
                    fills = [f(dim)]

                for fill in fills:
                    self.HISTS['{}_{}'.format(key, factor)].Fill(fill, eventWeight*signalWeight)
Пример #14
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    for attr in ('DSAmuons', 'PATmuons', 'Dimuons3'):
        setattr(self, attr, locals()[attr])

    def modifiedName(name):
        if 'DoubleMuon' in name:
            return 'Data' + name[17]
        if 'QCD' in name:
            return 'QCD'
        return name

    # no LxySig, no Dphi, and no blinding
    # LxySig < 1 applied below; iDphi and Dphi kept track of in dump
    CUTSTRING = '_Combined_NS_NH_FPTE_HLT_REP_PT_TRK_NDT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_OS'

    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, CUTSTRING, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return

    for dim in selectedDimuons:
        if dim.composition == 'PAT' and dim.LxySig() < 1.:
            daddyMuons = self.getOriginalDSAMuons(dim)

            if sum([len(daddyMuons[idx]) for idx in daddyMuons]) < 2:
                print 'After original: Something is wrong: why did you not find 2 DSA muons leading to 2 PAT muons?'

            selectedDSAIndices = []
            for patIdx in daddyMuons:
                # dirty disambiguation
                if len(daddyMuons[patIdx]) == 0:
                    print 'In Loop: Something is wrong: why did you not find 2 DSA muons leading to 2 PAT muons?'
                elif len(daddyMuons[patIdx]) > 1:
                    thisDSAmuon = list(
                        sorted(daddyMuons[patIdx],
                               key=lambda mu: mu.pt,
                               reverse=True))[0]
                    selectedDSAIndices.append(thisDSAmuon.idx)
                else:
                    thisDSAmuon = daddyMuons[patIdx][0]
                    selectedDSAIndices.append(thisDSAmuon.idx)

            parentDSADim = None
            if len(selectedDSAIndices) == 2:
                for DSADim in Dimuons3:
                    if DSADim.composition != 'DSA': continue
                    if selectedDSAIndices[
                            0] in DSADim.ID and selectedDSAIndices[
                                1] in DSADim.ID:
                        parentDSADim = DSADim
                        break

            if parentDSADim is None: continue

            print '{:9s} {:d} {:7d} {:10d} ::: PAT {:2d} {:2d} <-- DSA {:2d} {:2d} ::: {:9.4f} {:9.4f} ::: {:6.4f} {:6.4f}'.format(
                modifiedName(self.NAME),
                Event.run,
                Event.lumi,
                Event.event,
                dim.ID[0],
                dim.ID[1],
                parentDSADim.ID[0],
                parentDSADim.ID[1],
                dim.LxySig(),
                parentDSADim.LxySig(),
                dim.deltaPhi,
                parentDSADim.deltaPhi,
            )
Пример #15
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # take 10% of data: event numbers ending in 7
    if 'DoubleMuon' in self.NAME and not self.ARGS.IDPHI:
        if Event.event % 10 != 7: return

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    def getOriginalMuons(dim):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    for key in CONFIG:
        cutString = ALL.replace(CONFIG[key]['OMIT'], '')
        if key == 'deltaPhi':
            if ('DoubleMuon' in self.NAME or ('DoubleMuon' not in self.NAME and self.SP is None)) and self.ARGS.IDPHI:
                cutString += '_IDPHI'
        else:
            if ('DoubleMuon' in self.NAME or ('DoubleMuon' not in self.NAME and self.SP is None)) and self.ARGS.IDPHI:
                cutString = cutString.replace('DPHI', 'IDPHI')
        selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(E, cutString, Dimuons3, DSAmuons, PATmuons)
        if selectedDimuons is None: continue

        f = CONFIG[key]['LAMBDA']
        if key == 'Npp':
            if [dim.composition for dim in selectedDimuons].count('DSA') > 0:
                val = sum(f(DSAmuons))
                self.HISTS[key].Fill(val, eventWeight)
        else:
            for dim in selectedDimuons:
                if dim.composition != 'DSA': continue
                if CONFIG[key]['CASTTYPE'] is not None:
                    mus = getOriginalMuons(dim)
                    if key != 'nDTHits':
                        val = OP[CONFIG[key]['CASTTYPE']]([f(mu) for mu in mus])
                    else:
                        vals = [f(mu) for mu in mus if mu.nCSCHits == 0]
                        if len(vals) != 0:
                            val = min(vals)
                        else:
                            val = None
                else:
                    if key == 'time':
                        val = f(dim, DSAmuons)
                    else:
                        val = f(dim)

                if val is not None:
                    self.HISTS[key].Fill(val, eventWeight)
Пример #16
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # take 10% of data: event numbers ending in 7
    if 'DoubleMuon' in self.NAME and not self.ARGS.IDPHI:
        if Event.event % 10 != 7: return

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    def getOriginalMuons(dim):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    cutString = ALL[:]
    if ('DoubleMuon' in self.NAME or
        ('DoubleMuon' not in self.NAME
         and self.SP is None)) and self.ARGS.IDPHI:
        cutString = cutString.replace('DPHI', 'IDPHI')
    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, cutString, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return

    for key in CONFIG:
        f = CONFIG[key]['LAMBDA']
        for dim in selectedDimuons:
            if dim.composition != 'DSA': continue
            mus = getOriginalMuons(dim)

            if CONFIG[key]['TYPE'] == 'DSA':
                fills = [f(*mus)]
            else:
                fills = [f(dim)]

            # as above; this is fully general for N dimensions
            # funcs are the others' lambdas; ops are the others' ops; args are dim if it's a dim cut else mus; passedKeys are if they passed the cut
            # if they all passed, construct the hkey as above and fill
            keys = others(key)
            for vals in itertools.product(*[CONFIG[k]['VALS'] for k in keys]):
                keyvals = {k: float(val) for k, val in zip(keys, vals)}
                funcs = {k: CONFIG[k]['LAMBDA'] for k in keys}
                ops = {k: CONFIG[k]['OP'] for k in keys}
                args = {
                    k: [dim] if CONFIG[k]['TYPE'] == 'DIM' else mus
                    for k in keys
                }
                passedKeys = {
                    k: ops[k](funcs[k](*args[k]), keyvals[k])
                    for k in keys
                }

                if all(passedKeys.values()):

                    fstring = '{}_'
                    fstring += '_'.join(['{}-{}'] * len(keys))
                    hkey = fstring.format(
                        key, *[
                            item for keyvalpair in zip(keys, vals)
                            for item in keyvalpair
                        ])

                    for fill in fills:
                        self.HISTS[hkey].Fill(fill, eventWeight)
def analyze(self, E, PARAMS=None):

    Event = E.getPrimitives('EVENT')

    # take 10% of data: event numbers ending in 7
    if 'DoubleMuon' in self.NAME:
        if Event.event % 10 != 7: return

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    if '4Mu' in self.NAME:
        mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives('GEN')
        genMuons = (mu11, mu12, mu21, mu22)
        genMuonPairs = ((mu11, mu12), (mu21, mu22))
    elif '2Mu2J' in self.NAME:
        mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
        genMuons = (mu1, mu2)
        genMuonPairs = ((mu1, mu2), )

    genMuonPair = genMuonPairs[0]
    genLxy = genMuonPair[0].Lxy()

    TRIG = Selections.passedTrigger(E)

    ACC = Selections.AcceptanceSelection(genMuonPair)

    RECO = False
    dimuonMatches, muonMatches, exitcode = matchedDimuons(genMuonPair,
                                                          Dimuons3,
                                                          DSAmuons,
                                                          vertex='BS',
                                                          doDimuons=False)
    genMuonMatches = exitcode.getBestGenMuonMatches(muonMatches)
    if genMuonMatches[0] is not None and genMuonMatches[1] is not None:
        RECO = True

    SEL = False
    CUTS = '_Combined_NS_NH_FPTE_HLT_REP_PT_DCA_PC_LXYE_MASS_CHI2_VTX_COSA_NPP_LXYSIG_TRK_NDT_DPHI'
    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, CUTS, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is not None:

        selectedDimuons = [
            dim for dim in selectedDimuons if dim.composition == 'DSA'
        ]

        dimuonMatches, muonMatches, exitcode = matchedDimuons(
            genMuonPair, selectedDimuons)
        if len(dimuonMatches) > 0:
            realMatches = {0: dimuonMatches[0]}
        else:
            realMatches = {}

        if len(realMatches) > 0:
            SEL = True

    KEY = 'Trig{}-Acc{}-Reco{}-Sel{}'.format(
        *[int(bool(x)) for x in (TRIG, ACC, RECO, SEL)])

    genLxy = genMuonPair[0].Lxy()
    self.HISTS['Lxy-' + KEY].Fill(genLxy)
Пример #18
0
def analyze(self, E, PARAMS=None):
    if self.TRIGGER and self.SP is not None:
        if not Selections.passedTrigger(E): return

    Event = E.getPrimitives('EVENT')

    # take 10% of data: event numbers ending in 7
    if 'DoubleMuon' in self.NAME and '_IDPHI' not in self.CUTS:
        self.DATACOUNTER['all'] += 1
        if Event.event % 10 != 7: return
        self.DATACOUNTER['selected'] += 1

    DSAmuons = E.getPrimitives('DSAMUON')
    PATmuons = E.getPrimitives('PATMUON')
    Dimuons3 = E.getPrimitives('DIMUON')

    eventWeight = 1.
    try:
        eventWeight = 1. if Event.weight > 0. else -1.
    except:
        pass

    selectedDimuons, selectedDSAmuons, selectedPATmuons = Selector.SelectObjects(
        E, self.CUTS, Dimuons3, DSAmuons, PATmuons)
    if selectedDimuons is None: return

    for dim in selectedDimuons:
        if dim.composition == 'DSA':
            self.HISTS['nDimuon'].Fill(len(selectedDimuons), eventWeight)
            self.HISTS['nDSA'].Fill(len(DSAmuons), eventWeight)
            self.HISTS['nDSA12'].Fill(
                len([d for d in DSAmuons if d.nCSCHits + d.nDTHits > 12]),
                eventWeight)
            self.HISTS['nDSA12-pT'].Fill(
                len([
                    d for d in DSAmuons
                    if d.nCSCHits + d.nDTHits > 12 and d.pt > 5.
                ]), eventWeight)
            self.HISTS['nDSA-DT'].Fill(
                len([d for d in DSAmuons if d.nCSCHits == 0]), eventWeight)
            break

    def getOriginalMuons(dim):
        if dim.composition == 'PAT':
            return PATmuons[dim.idx1], PATmuons[dim.idx2]
        elif dim.composition == 'DSA':
            return DSAmuons[dim.idx1], DSAmuons[dim.idx2]
        else:
            return DSAmuons[dim.idx1], PATmuons[dim.idx2]

    for dim in selectedDimuons:
        RTYPE = dim.composition[:3]
        for QKEY in DIMQUANTITIES:
            KEY = RTYPE + '-' + QKEY
            if QKEY not in ('mind0Sig', 'minNHits', 'qsum'):
                self.HISTS[KEY].Fill(DIMQUANTITIES[QKEY]['LAMBDA'](dim),
                                     eventWeight)
            elif QKEY in ('mind0Sig', 'minNHits'):
                self.HISTS[KEY].Fill(
                    DIMQUANTITIES[QKEY]['LAMBDA'](*getOriginalMuons(dim)),
                    eventWeight,
                )  # ew
            else:
                self.HISTS[KEY].Fill(
                    DIMQUANTITIES[QKEY]['LAMBDA'](dim.mu1, dim.mu2),
                    eventWeight)

        if RTYPE == 'DSA':
            for QKEY in DSAQUANTITIES:
                KEY = RTYPE + '-' + QKEY
                for mu in getOriginalMuons(dim):
                    self.HISTS[KEY].Fill(DSAQUANTITIES[QKEY]['LAMBDA'](mu),
                                         eventWeight)

        if RTYPE == 'PAT':
            for QKEY in PATQUANTITIES:
                KEY = RTYPE + '-' + QKEY
                for mu in getOriginalMuons(dim):
                    self.HISTS[KEY].Fill(PATQUANTITIES[QKEY]['LAMBDA'](mu),
                                         eventWeight)

        if RTYPE == 'HYB':
            DSAmu, PATmu = getOriginalMuons(dim)

            for QKEY in DSAQUANTITIES:
                KEY = 'HYB-DSA' + '-' + QKEY
                self.HISTS[KEY].Fill(DSAQUANTITIES[QKEY]['LAMBDA'](DSAmu),
                                     eventWeight)

            for QKEY in PATQUANTITIES:
                KEY = 'HYB-PAT' + '-' + QKEY
                self.HISTS[KEY].Fill(PATQUANTITIES[QKEY]['LAMBDA'](PATmu),
                                     eventWeight)

        self.HISTS[RTYPE + '-LxySigVSdeltaPhi'].Fill(
            DIMQUANTITIES['deltaPhi']['LAMBDA'](dim),
            DIMQUANTITIES['LxySig']['LAMBDA'](dim), eventWeight)

        # temporary 2D histograms
        if dim.composition != 'DSA':
            mu1, mu2 = getOriginalMuons(dim)
            FC2, FMED = PAT2DQUANTITIES['normChi2']['LAMBDA'], PAT2DQUANTITIES[
                'isMedium']['LAMBDA']

            for mu in (mu1, mu2) if RTYPE == 'PAT' else (mu2, ):
                self.HISTS['PAT-normChi2VSisMedium'].Fill(
                    FMED(mu), FC2(mu), eventWeight)

        if dim.composition == 'DSA':
            mu1, mu2 = getOriginalMuons(dim)
            for QKEY in DSA2DQUANTITIES:
                KEY = 'DSA-12-' + QKEY
                F = DSA2DQUANTITIES[QKEY]['LAMBDA']
                self.HISTS[KEY].Fill(F(mu1), F(mu2), eventWeight)

            F = DSAQUANTITIES['FPTE']['LAMBDA']
            self.HISTS['REF-DSA-FPTE'].Fill(F(dim.mu1), eventWeight)
            self.HISTS['REF-DSA-FPTE'].Fill(F(dim.mu2), eventWeight)

        if self.SP is None and dim.LxySig() > 20.:
            mu1, mu2 = getOriginalMuons(dim)
            if dim.composition == 'PAT':
                for QKEY in PAT2DQUANTITIES:
                    KEY = 'PAT-12-' + QKEY
                    F = PAT2DQUANTITIES[QKEY]['LAMBDA']
                    if QKEY in ('hitsBeforeVtx', 'missingHitsAfterVtx'):
                        self.HISTS[KEY].Fill(F(dim.mu1), F(dim.mu2),
                                             eventWeight)
                    else:
                        self.HISTS[KEY].Fill(F(mu1), F(mu2), eventWeight)

                print '{:13s} {:d} {:7d} {:10d} {:2d} ::: {:3s} {:2d} {:2d} ::: {:6.2f} {:2d} {:1d} {:1d} {:1d} {:1d} {:6.2f} {:2d} {:1d} {:1d} {:1d} {:1d} ::: {:9.4f} {:8.4f} {:5.2f} {:6.2f} {:6.2f}'.format(
                    self.NAME, Event.run, Event.lumi, Event.event,
                    int(eventWeight), dim.composition[:3], dim.idx1, dim.idx2,
                    mu1.normChi2, mu1.nTrackerLayers, mu1.nPixelHits,
                    int(mu1.highPurity), int(mu1.isGlobal), int(mu1.isMedium),
                    mu2.normChi2, mu2.nTrackerLayers, mu2.nPixelHits,
                    int(mu2.highPurity), int(mu2.isGlobal), int(mu2.isMedium),
                    dim.LxySig(), dim.Lxy(), dim.normChi2, mu1.d0Sig(),
                    mu2.d0Sig())
            elif dim.composition == 'DSA':
                print '{:13s} {:d} {:7d} {:10d} {:2d} ::: {:3s} {:2d} {:2d} ::: {:6.2f} {:2s} {:1s} {:1s} {:1s} {:1s} {:6.2f} {:2s} {:1s} {:1s} {:1s} {:1s} ::: {:9.4f} {:8.4f} {:5.2f} {:6.2f} {:6.2f}'.format(
                    self.NAME, Event.run, Event.lumi, Event.event,
                    int(eventWeight), dim.composition[:3], dim.idx1, dim.idx2,
                    mu1.normChi2, '-', '-', '-', '-', '-', mu2.normChi2, '-',
                    '-', '-', '-', '-', dim.LxySig(), dim.Lxy(), dim.normChi2,
                    mu1.d0Sig(), mu2.d0Sig())
            else:
                print '{:13s} {:d} {:7d} {:10d} {:2d} ::: {:3s} {:2d} {:2d} ::: {:6.2f} {:2s} {:1s} {:1s} {:1s} {:1s} {:6.2f} {:2d} {:1d} {:1d} {:1d} {:1d} ::: {:9.4f} {:8.4f} {:5.2f} {:6.2f} {:6.2f}'.format(
                    self.NAME, Event.run, Event.lumi, Event.event,
                    int(eventWeight), dim.composition[:3], dim.idx1, dim.idx2,
                    mu1.normChi2, '-', '-', '-', '-', '-', mu2.normChi2,
                    mu2.nTrackerLayers, mu2.nPixelHits, int(mu2.highPurity),
                    int(mu2.isGlobal), int(mu2.isMedium), dim.LxySig(),
                    dim.Lxy(), dim.normChi2, mu1.d0Sig(), mu2.d0Sig())

    if self.SP is not None:
        if '4Mu' in self.NAME:
            mu11, mu12, mu21, mu22, X1, X2, H, P, extramu = E.getPrimitives(
                'GEN')
            genMuons = (mu11, mu12, mu21, mu22)
            genMuonPairs = ((mu11, mu12), (mu21, mu22))
        elif '2Mu2J' in self.NAME:
            mu1, mu2, j1, j2, X, XP, H, P, extramu = E.getPrimitives('GEN')
            genMuons = (mu1, mu2)
            genMuonPairs = ((mu1, mu2), )

        # do the signal matching
        if len(genMuonPairs) == 1:
            genMuonPair = genMuonPairs[0]
            dimuonMatches, muonMatches, exitcode = matchedDimuons(
                genMuonPair, selectedDimuons)
            if len(dimuonMatches) > 0:
                realMatches = {0: dimuonMatches[0]}
            else:
                realMatches = {}
        else:
            realMatches, dimuonMatches, muon0Matches, muon1Matches = matchedDimuonPairs(
                genMuonPairs, selectedDimuons)

        for pairIndex in realMatches:
            genMuon = genMuonPairs[pairIndex][0]
            dim = realMatches[pairIndex]['dim']
            self.HISTS['GEN-Lxy'].Fill(genMuon.Lxy(), eventWeight)

            RTYPE = dim.composition[:3]
            KEY = 'GEN-Lxy-' + RTYPE
            self.HISTS[KEY].Fill(genMuon.Lxy(), eventWeight)

            KEY = RTYPE + '-' + 'LxyRes'
            self.HISTS[KEY].Fill(dim.Lxy() - genMuon.Lxy(), eventWeight)

            KEY = RTYPE + '-' + 'LxyRes' + 'VSGEN-Lxy'
            self.HISTS[KEY].Fill(genMuon.Lxy(),
                                 dim.Lxy() - genMuon.Lxy(), eventWeight)

            KEY = RTYPE + '-' + 'LxyPull'
            self.HISTS[KEY].Fill((dim.Lxy() - genMuon.Lxy()) / dim.LxyErr(),
                                 eventWeight)

            KEY = RTYPE + '-' + 'LxyRes' + 'VS' + RTYPE + '-' + 'LxyErr'
            self.HISTS[KEY].Fill(dim.LxyErr(),
                                 dim.Lxy() - genMuon.Lxy(), eventWeight)

            # temporary 2D histograms
            if RTYPE == 'DSA': continue

            mu1, mu2 = getOriginalMuons(dim)
            FC2, FMED = PAT2DQUANTITIES['normChi2']['LAMBDA'], PAT2DQUANTITIES[
                'isMedium']['LAMBDA']

            for mu in (mu1, mu2) if RTYPE == 'PAT' else (mu2, ):
                self.HISTS['PAT-normChi2VSGEN-Lxy'].Fill(
                    genMuon.Lxy(), FC2(mu), eventWeight)
                self.HISTS['PAT-isMediumVSGEN-Lxy'].Fill(
                    genMuon.Lxy(), FMED(mu), eventWeight)

            # permanent
            if RTYPE != 'PAT': continue
            mu1, mu2 = PATmuons[dim.idx1], PATmuons[dim.idx2]
            for QKEY in PAT2DQUANTITIES:
                KEY = RTYPE + '-' + '12' + '-' + QKEY
                F = PAT2DQUANTITIES[QKEY]['LAMBDA']
                if QKEY in ('hitsBeforeVtx', 'missingHitsAfterVtx'):
                    self.HISTS[KEY].Fill(F(dim.mu1), F(dim.mu2), eventWeight)
                else:
                    self.HISTS[KEY].Fill(F(mu1), F(mu2), eventWeight)