Ejemplo n.º 1
0
def load_tree(infiles):
    from rootpy.tree import TreeChain
    from rootpy.ROOT import gROOT
    gROOT.SetBatch(True)

    print('[INFO] Opening files: {0}'.format(infiles))
    tree = TreeChain('ntupler/tree', infiles)
    tree.define_collection(name='hits', prefix='vh_', size='vh_size')
    tree.define_collection(name='simhits', prefix='vc_', size='vc_size')
    tree.define_collection(name='tracks', prefix='vt_', size='vt_size')
    tree.define_collection(name='particles', prefix='vp_', size='vp_size')
    return tree
Ejemplo n.º 2
0
class MuonTypeLJEvents(object):
    def __init__(self, files=None, type='MC', maxevents=-1):
        if type.upper() not in ['MC', 'DATA']:
            raise ValueError("Argument `type` need to be MC/DATA")
        self.Type = type
        self.MaxEvents = maxevents

        if not files: raise ValueError("Argument `files` need to be non-empty")
        if isinstance(files, str): files = [
                files,
        ]
        self.Chain = TreeChain('ffNtuplizer/ffNtuple', files)

        ## register collections ###
        self.Chain.define_collection('pvs', prefix='pv_', size='pv_n')
        self.Chain.define_collection('muons', prefix='muon_', size='muon_n')
        self.Chain.define_collection('dsamuons',
                                     prefix='dsamuon_',
                                     size='dsamuon_n')
        self.Chain.define_collection('ak4jets',
                                     prefix='akjet_ak4PFJetsCHS_',
                                     size='akjet_ak4PFJetsCHS_n')
        self.Chain.define_collection('leptonjets',
                                     prefix='pfjet_',
                                     size='pfjet_n',
                                     mix=LeptonJetMix)

        self.Chain.define_collection('trigobjs',
                                     prefix='trigobj_',
                                     size='trigobj_n')

        self.Chain.define_object('hlt', prefix='HLT_')
        self.Chain.define_object('metfilters', prefix='metfilters_')
        self.Chain.define_object('cosmicveto', prefix='cosmicveto_')

        self.Histos = {}

        self.LookupWeight = root_open(
            os.path.join(
                os.getenv('CMSSW_BASE'),
                'src/FireROOT/Analysis/data/puWeights_10x_56ifb.root')).Get(
                    'puWeights')
        self.Scale = 1.

    def bookHisto(self, name, hist):
        self.Histos[name] = hist

    def setScale(self, scale):
        self.Scale = scale

    def process(self):

        for i, event in enumerate(self.Chain):

            if self.MaxEvents > 0 and i > self.MaxEvents: break

            ## event-level mask ##
            if not event.cosmicveto.result: continue
            if not event.metfilters.PrimaryVertexFilter: continue

            aux = {}
            ## event weight ##
            aux['wgt'] = self.Scale
            if self.Type == 'MC':
                aux['wgt'] *= event.weight  # gen weight
                aux['wgt'] *= self.LookupWeight.GetBinContent(
                    self.LookupWeight.GetXaxis().FindBin(
                        event.trueInteractionNum))  ## pileup correction

            leptonjets = [
                lj for lj in event.leptonjets if lj.passSelection(event)
            ]
            leptonjets.sort(key=lambda lj: lj.p4.pt(), reverse=True)
            leptonjets = leptonjets[:2]
            muontypeljs = [lj for lj in leptonjets if lj.isMuonType()]
            egmtypeljs = [lj for lj in leptonjets if lj.isEgmType()]
            # if not muontypeljs: continue

            aux['muontype'] = muontypeljs
            aux['egmtype'] = egmtypeljs
            aux['leptonjets'] = leptonjets

            looseMuonIdx, mediumMuonIdx = [], []
            for i, mu in enumerate(event.muons):
                if mu.p4.pt() < 5: continue
                if abs(mu.p4.eta()) > 2.4: continue
                if (mu.selectors & (1 << 0)) != (1 << 0): continue  # ID-loose
                if (mu.selectors & (1 << 7)) != (1 << 7): continue  # Iso-loose
                looseMuonIdx.append(i)
                if (mu.selectors & (1 << 1)) != (1 << 1): continue  # ID-medium
                mediumMuonIdx.append(i)

            if not mediumMuonIdx: continue
            muonpairs = []
            for m in mediumMuonIdx:
                for l in looseMuonIdx:
                    if m == l: continue
                    if (l, m) in muonpairs: continue
                    muonpairs.append((m, l))
            if not muonpairs: continue

            aux['muonpairs'] = muonpairs

            self.processEvent(event, aux)

    def processEvent(self, event, aux):
        """To be override by daughter class"""
        pass

    @property
    def histos(self):
        return self.Histos
Ejemplo n.º 3
0
class Events(object):
    def __init__(self,
                 files=None,
                 outname=None,
                 type='MC',
                 dtag='',
                 maxevents=-1,
                 channel=['4mu', '2mu2e'],
                 ctau=None,
                 chargedlj=False):

        if type.upper() not in ['MC', 'DATA']:
            raise ValueError("Argument `type` need to be MC/DATA")
        self.OutName = outname
        self.Type = type.upper()
        self.ChargedLJ = chargedlj
        self.MaxEvents = maxevents
        self.Channel = channel
        self.Dtag = dtag
        self.Ctau = ctau
        __signal_sample_param = dict(
            [substr.split('-') for substr in self.Dtag.split('_')])
        self.SignalParam = {
            k.upper(): float(v.replace('p', '.'))
            for k, v in __signal_sample_param.items()
        }

        if not files: raise ValueError("Argument `files` need to be non-empty")
        if isinstance(files, str): files = [
                files,
        ]
        self.Chain = TreeChain('ffNtuplizer/ffNtuple', files)

        ### register collections ###
        # self.Chain.define_collection('pvs', prefix='pv_', size='pv_n')
        self.Chain.define_collection('electrons',
                                     prefix='electron_',
                                     size='electron_n')
        self.Chain.define_collection('muons', prefix='muon_', size='muon_n')
        self.Chain.define_collection('dsamuons',
                                     prefix='dsamuon_',
                                     size='dsamuon_n')
        self.Chain.define_collection('photons',
                                     prefix='photon_',
                                     size='photon_n')
        self.Chain.define_collection('ak4jets',
                                     prefix='akjet_ak4PFJetsCHS_',
                                     size='akjet_ak4PFJetsCHS_n')
        self.Chain.define_collection('hftagscores',
                                     prefix='hftagscore_',
                                     size='hftagscore_n')
        self.Chain.define_collection('leptonjets',
                                     prefix='pfjet_',
                                     size='pfjet_n',
                                     mix=LeptonJetMix)
        self.Chain.define_collection('ljsources',
                                     prefix='ljsource_',
                                     size='ljsource_n')
        self.Chain.define_collection('cosmicmuons',
                                     prefix='cosmicmuon_',
                                     size='cosmicmuon_n')

        self.Chain.define_collection('trigobjs',
                                     prefix='trigobj_',
                                     size='trigobj_n')
        #        self.Chain.define_collection('',)

        self.Chain.define_object('hlt', prefix='HLT_')
        self.Chain.define_object('metfilters', prefix='metfilters_')
        self.Chain.define_object('cosmicveto', prefix='cosmicveto_')

        self.Triggers = [
            "DoubleL2Mu23NoVtx_2Cha",
            "DoubleL2Mu23NoVtx_2Cha_NoL2Matched",
            "DoubleL2Mu23NoVtx_2Cha_CosmicSeed",
            "DoubleL2Mu23NoVtx_2Cha_CosmicSeed_NoL2Matched",
            "DoubleL2Mu25NoVtx_2Cha_Eta2p4",
            "DoubleL2Mu25NoVtx_2Cha_CosmicSeed_Eta2p4",
        ]

        #self.addTRG = [
        # "DoubleL2Mu23NoVtx_2Cha",]

        self.Histos = {}
        for chan in channel:
            self.Histos['{}/cutflow'.format(chan)] = ROOT.Hist(
                20, 0, 20, title='cutflow', drawstyle='hist')
        self.KeepCutFlow = False
        self.RawCutFlow = False

        self.LookupWeight = root_open(
            os.path.join(
                os.getenv('CMSSW_BASE'),
                'src/FireROOT/Analysis/data/PUWeights_2018.root')).Get(
                    'puWeights')
        self.LookupMuonSFLowpT = root_open(
            os.path.join(os.getenv('CMSSW_BASE'),
                         'src/FireROOT/Analysis/data/mu_Loose_pt7.root')).Get(
                             'ratio_syst')
        self.LookupMuonSF = root_open(
            os.path.join(os.getenv('CMSSW_BASE'),
                         'src/FireROOT/Analysis/data/RunABCD_SF_ID.root')).Get(
                             'NUM_LooseID_DEN_TrackerMuons_pt_abseta_syst')
        self.LookupElectronSF = root_open(
            os.path.join(
                os.getenv('CMSSW_BASE'),
                'src/FireROOT/Analysis/data/2018_ElectronLoose.root')).Get(
                    'EGamma_SF2D')
        self.LookupPhotonSF = root_open(
            os.path.join(
                os.getenv('CMSSW_BASE'),
                'src/FireROOT/Analysis/data/2018_PhotonsLoose.root')).Get(
                    'EGamma_SF2D')
        self.Scale = 1.

    def setTriggers(self, triggers):
        self.Triggers = triggers

    def addTrigger(self, trigger):
        self.Triggers.append(trigger)

    def bookHisto(self, name, hist):
        self.Histos[name] = hist

    def setScale(self, scale):
        self.Scale = scale

    def process(self):

        for i, event in enumerate(self.Chain):
            if self.MaxEvents > 0 and i > self.MaxEvents: break

            ## event weight ##
            aux = {}
            aux['wgt'] = self.Scale
            if self.Type == 'MC':
                aux['wgt'] *= event.weight  # gen weight
                aux['wgt'] *= self.LookupWeight.GetBinContent(
                    self.LookupWeight.GetXaxis().FindBin(
                        event.trueInteractionNum))  ## pileup correction

            for ch in self.Channel:
                if self.RawCutFlow:
                    self.Histos['{}/cutflow'.format(ch)].Fill(0)
                else:
                    self.Histos['{}/cutflow'.format(ch)].Fill(0, aux['wgt'])

            ## trigger ##
            #if not any([getattr(event.hlt, t) for t in self.Triggers]): continue

            #if not any([getattr(event.hlt, t) for t in self.addTRG]): continue

            for ch in self.Channel:
                if self.RawCutFlow:
                    self.Histos['{}/cutflow'.format(ch)].Fill(1)
                else:
                    self.Histos['{}/cutflow'.format(ch)].Fill(1, aux['wgt'])

            ## 2 leptonjets in channel definition ##
            leptonjets = [lj for lj in event.leptonjets]
            if len(leptonjets) < 2: continue

            #print len(leptonjets)#js
            #LJ2 = none
            leptonjets.sort(key=lambda lj: lj.p4.pt(), reverse=True)
            LJ0 = leptonjets[0]
            LJ1 = leptonjets[1]
            #LJ2 = leptonjets[2]
            #if len(event.leptonjets)>2:#
            #LJ2 = leptonjets[2]#
            #aux['lj2'] = LJ2

            if self.ChargedLJ:
                if not LJ0.passChargedSelection(event): continue
                if not LJ1.passChargedSelection(event): continue
                #if not LJ2.passChargedSelection(event): continue
            else:
                if not LJ0.passSelection(event): continue
                if not LJ1.passSelection(event): continue
                #if not LJ2.passSelection(event): continue

            if LJ0.isMuonType() and LJ1.isMuonType(): aux['channel'] = '4mu'
            elif LJ0.isMuonType() and LJ1.isEgmType(): aux['channel'] = '2mu2e'
            elif LJ0.isEgmType() and LJ1.isMuonType(): aux['channel'] = '2mu2e'
            else: continue

            aux['lj0'] = LJ0
            aux['lj1'] = LJ1
            #aux['lj2'] = LJ2

            if self.Type == 'MC':
                aux['sf_electron'] = 1.
                aux['sf_electron_up'] = 1.
                aux['sf_electron_low'] = 1.

                aux['sf_photon'] = 1.
                aux['sf_photon_up'] = 1.
                aux['sf_photon_low'] = 1.

                aux['sf_pfmuon'] = 1.
                aux['sf_pfmuon_up'] = 1.
                aux['sf_pfmuon_low'] = 1.

                for lj in [LJ0, LJ1]:
                    ## muon scale factor
                    for i in lj.pfcand_pfmuonIdx:
                        _pfmu_p4 = event.muons[i].p4
                        pt, eta = _pfmu_p4.pt(), _pfmu_p4.eta()
                        if pt >= 20:
                            xbin = self.LookupMuonSF.xaxis.FindBin(pt)
                            xbin = min(max(xbin, 1),
                                       self.LookupMuonSF.nbins(0))
                            ybin = self.LookupMuonSF.yaxis.FindBin(abs(eta))
                            sf = self.LookupMuonSF.GetBinContent(xbin, ybin)
                            err_up = self.LookupMuonSF.GetBinErrorUp(
                                xbin, ybin)
                            err_lo = self.LookupMuonSF.GetBinErrorLow(
                                xbin, ybin)
                        else:
                            for i in range(self.LookupMuonSFLowpT.num_points):
                                x = self.LookupMuonSFLowpT.x(i)
                                xh = x + self.LookupMuonSFLowpT.xerrh(i)
                                xl = x - self.LookupMuonSFLowpT.xerrl(i)
                                if xl <= eta and eta <= xh:
                                    sf = self.LookupMuonSFLowpT.y(i)
                                    err_up = self.LookupMuonSFLowpT.yerrh(i)
                                    err_lo = self.LookupMuonSFLowpT.yerrl(i)
                                    break
                        aux['wgt'] *= sf

                        aux['sf_pfmuon'] *= sf
                        aux['sf_pfmuon_up'] *= sf + err_up
                        aux['sf_pfmuon_low'] *= sf - err_lo

                    ## NOTE DSA scale factor, nothing for now
                    for i in lj.pfcand_dsamuonIdx:
                        #print dsamu.pt.P4()
                        sf = 1.
                        aux['wgt'] *= sf

                    ## electron scale factor
                    for i in lj.pfcand_electronIdx:
                        _electron = event.electrons[i]
                        xbin = self.LookupElectronSF.xaxis.FindBin(
                            _electron.scEta)
                        ybin = self.LookupElectronSF.xaxis.FindBin(
                            _electron.p4.pt())
                        ybin = min(max(ybin, 1),
                                   self.LookupElectronSF.nbins(1))
                        sf = self.LookupElectronSF.GetBinContent(xbin, ybin)
                        aux['wgt'] *= sf

                        aux['sf_electron'] *= sf
                        aux['sf_electron_up'] *= sf + self.LookupElectronSF.GetBinErrorUp(
                            xbin, ybin)
                        aux['sf_electron_low'] *= sf - self.LookupElectronSF.GetBinErrorLow(
                            xbin, ybin)

                    ## photon scale factor
                    for i in lj.pfcand_photonIdx:
                        _photon = event.photons[i]
                        xbin = self.LookupPhotonSF.xaxis.FindBin(_photon.scEta)
                        ybin = self.LookupPhotonSF.xaxis.FindBin(
                            _photon.p4.pt())
                        ybin = min(max(ybin, 1), self.LookupPhotonSF.nbins(1))
                        sf = self.LookupPhotonSF.GetBinContent(xbin, ybin)
                        aux['wgt'] *= sf

                        aux['sf_photon'] *= sf
                        aux['sf_photon_up'] *= sf + self.LookupPhotonSF.GetBinErrorUp(
                            xbin, ybin)
                        aux['sf_photon_low'] *= sf - self.LookupPhotonSF.GetBinErrorLow(
                            xbin, ybin)

                aux['wgt_electron_up'] = aux['wgt'] / aux['sf_electron'] * aux[
                    'sf_electron_up']
                aux['wgt_electron_low'] = aux['wgt'] / aux[
                    'sf_electron'] * aux['sf_electron_low']
                aux['wgt_photon_up'] = aux['wgt'] / aux['sf_photon'] * aux[
                    'sf_photon_up']
                aux['wgt_photon_low'] = aux['wgt'] / aux['sf_photon'] * aux[
                    'sf_photon_low']
                aux['wgt_pfmuon_up'] = aux['wgt'] / aux['sf_pfmuon'] * aux[
                    'sf_pfmuon_up']
                aux['wgt_pfmuon_low'] = aux['wgt'] / aux['sf_pfmuon'] * aux[
                    'sf_pfmuon_low']

                # for t, pt, eta in zip(list(lj.pfcand_type), list(lj.pfcand_pt), list(lj.pfcand_eta)):
                #     ## muon scale factor, DSA same as muon for now
                #     if t==3 or t==8:
                #         xbin = self.LookupMuonSF.xaxis.FindBin(pt)
                #         xbin = min(max(xbin, 1), self.LookupMuonSF.nbins(0))
                #         ybin = self.LookupMuonSF.yaxis.FindBin(abs(eta))
                #         sf = self.LookupMuonSF.GetBinContent(xbin, ybin)
                #         aux['wgt'] *= sf
                #     ## electron scale factor, using eta instead of SC eta for now
                #     if t==2:
                #         xbin = self.LookupElectronSF.xaxis.FindBin(eta)
                #         ybin = self.LookupElectronSF.xaxis.FindBin(pt)
                #         ybin = min(max(ybin, 1), self.LookupElectronSF.nbins(1))
                #         sf = self.LookupElectronSF.GetBinContent(xbin, ybin)
                #         aux['wgt'] *= sf
                #     ## photon scale factor, using eta instead of SC eta for now
                #     if t==4:
                #         xbin = self.LookupPhotonSF.xaxis.FindBin(eta)
                #         ybin = self.LookupPhotonSF.xaxis.FindBin(pt)
                #         ybin = min(max(ybin, 1), self.LookupPhotonSF.nbins(1))
                #         sf = self.LookupPhotonSF.GetBinContent(xbin, ybin)
                #         aux['wgt'] *= sf

            for ch in self.Channel:
                if self.RawCutFlow:
                    self.Histos['{}/cutflow'.format(ch)].Fill(2)
                else:
                    self.Histos['{}/cutflow'.format(ch)].Fill(2, aux['wgt'])

            ## event-level mask ##
            if not event.metfilters.PrimaryVertexFilter: continue
            for ch in self.Channel:
                if self.RawCutFlow:
                    self.Histos['{}/cutflow'.format(ch)].Fill(3)
                else:
                    self.Histos['{}/cutflow'.format(ch)].Fill(3, aux['wgt'])

            nppCOSMIC, cosmicShowerTagged = globalCosmicShower(
                event.cosmicmuons, aux['channel'])
            if cosmicShowerTagged: continue

            for ch in self.Channel:
                if self.RawCutFlow:
                    self.Histos['{}/cutflow'.format(ch)].Fill(4)
                else:
                    self.Histos['{}/cutflow'.format(ch)].Fill(4, aux['wgt'])

            self.processEvent(event, aux)

    def processEvent(self, event, aux):
        """To be override by daughter class"""
        pass

    def postProcess(self):
        if self.KeepCutFlow:
            labels = [
                'total', 'trigger_pass', 'leptonjet_ge2', 'pv_good',
                'cosmicveto_pass'
            ]
            for ch in self.Channel:
                xaxis = self.Histos['{}/cutflow'.format(ch)].axis(0)
                for i, s in enumerate(labels, start=1):
                    xaxis.SetBinLabel(i, s)
                    # binNum., labAngel, labSize, labAlign, labColor, labFont, labText
                    xaxis.ChangeLabel(i, 315, -1, 11, -1, -1, s)
        else:
            for ch in self.Channel:
                self.Histos.pop('{}/cutflow'.format(ch))

    @property
    def histos(self):
        return self.Histos

    @property
    def channel(self):
        return self.Channel
elif mystate == 1:
    tree_name_i = '/home/jlow/L1MuonTrigger/CRAB3/P2_9_2_3_patch1/crab_projects/crab_ntuple_SingleNeutrino_PU200/results/ntuple_SingleNeutrino_PU200_%i.root'
    tree = TreeChain('ntupler/tree',
                     [(tree_name_i % (i + 1)) for i in range(50)])
else:
    raise Exception("Unexpected state: %i" % mystate)

maxEvents = -1
#maxEvents = 2000

# ROOT globals
gROOT.SetBatch(batch_mode)

# Define collection
tree.define_collection(name='hits', prefix='vh_', size='vh_size')
tree.define_collection(name='tracks', prefix='vt_', size='vt_size')
tree.define_collection(name='genparticles', prefix='vp_', size='vp_size')

# Enums
kDT, kCSC, kRPC, kGEM, kTT = 0, 1, 2, 3, 20

# Lambdas
deg_to_rad = lambda x: x * np.pi / 180.

rad_to_deg = lambda x: x * 180. / np.pi


# Functions
def delta_phi(lhs, rhs):  # in degrees
    deg = lhs - rhs
Ejemplo n.º 5
0
    def work(self):

        # trigger config tool to read trigger info in the ntuples
        trigger_config = get_trigger_config()

        OutputModel = (RecoTauBlock + EventVariables + SkimExtraModel +
            TrueTauBlock)

        onfilechange = []
        # update the trigger config maps on every file change
        onfilechange.append((update_trigger_config, (trigger_config,)))

        cutflow = Hist(2, 0, 2, name='cutflow', type='D')

        # initialize the TreeChain of all input files (each containing one tree named self.metadata.treename)
        chain = TreeChain(self.metadata.treename,
                         files=self.files,
                         events=self.events,
                         cache=True,
                         cache_size=10000000,
                         learn_entries=30,
                         onfilechange=onfilechange)

        # create output tree
        self.output.cd()
        tree = Tree(name='higgstautauhh', model=OutputModel)

        copied_variables = ['actualIntPerXing',
                            'averageIntPerXing',
                            'RunNumber',
                            'EventNumber',
                            'lbn']

        tree.set_buffer(
                chain.buffer,
                branches=copied_variables,
                create_branches=True,
                visible=False)
        chain.always_read(copied_variables)

        # set the event filters
        event_filters = EventFilterList([
            #Triggers(
            #    datatype=self.metadata.datatype,
            #    year=YEAR,
            #    skim=False),
            PriVertex(),
            LArError(),
            LArHole(datatype=self.metadata.datatype),
            JetCleaning(
                datatype=self.metadata.datatype,
                year=YEAR),
            TauAuthor(1),
            TauHasTrack(1),
            TauPT(1, thresh=25 * GeV),
            TauEta(1),
            TauCrack(1),
            TauLArHole(1),
            #TauTriggerMatch(
            #    config=trigger_config,
            #    year=YEAR,
            #    datatype=self.metadata.datatype,
            #    skim=False,
            #    tree=tree,
            #    min_taus=1),
        ])

        self.filters['event'] = event_filters
        chain.filters += event_filters

        # define tree collections
        chain.define_collection(name="taus", prefix="tau_", size="tau_n", mix=TauFourMomentum)
        chain.define_collection(name="taus_EF", prefix="trig_EF_tau_",
                                size="trig_EF_tau_n", mix=TauFourMomentum)

        # jet_* etc. is AntiKt4LCTopo_* in tau-perf D3PDs
        chain.define_collection(name="jets", prefix="jet_", size="jet_n", mix=FourMomentum)
        chain.define_collection(name="truetaus", prefix="trueTau_", size="trueTau_n", mix=MCTauFourMomentum)
        chain.define_collection(name="mc", prefix="mc_", size="mc_n", mix=MCParticle)
        chain.define_collection(name="muons", prefix="mu_staco_", size="mu_staco_n")
        chain.define_collection(name="electrons", prefix="el_", size="el_n")
        chain.define_collection(name="vertices", prefix="vxp_", size="vxp_n")

        from externaltools import PileupReweighting
        from ROOT import Root
        # Initialize the pileup reweighting tool
        pileup_tool = Root.TPileupReweighting()
        if YEAR == 2011:
            pileup_tool.AddConfigFile(PileupReweighting.get_resource('mc11b_defaults.prw.root'))
            pileup_tool.AddLumiCalcFile('lumi/2011/hadhad/ilumicalc_histograms_None_178044-191933.root')
        elif YEAR == 2012:
            pileup_tool.AddConfigFile(PileupReweighting.get_resource('mc12a_defaults.prw.root'))
            pileup_tool.SetDataScaleFactors(1./1.11)
            pileup_tool.AddLumiCalcFile('lumi/2012/hadhad/ilumicalc_histograms_None_200841-205113.root')
        else:
            raise ValueError('No pileup reweighting defined for year %d' %
                    YEAR)
        # discard unrepresented data (with mu not simulated in MC)
        pileup_tool.SetUnrepresentedDataAction(2)
        pileup_tool.Initialize()

        # entering the main event loop...
        for event in chain:
            tree.reset()

            event.vertices.select(vertex_selection)
            tree.number_of_good_vertices = len(event.vertices)

            # match only with visible true taus
            event.truetaus.select(lambda tau: tau.vis_Et > 10 * GeV and abs(tau.vis_eta) < 2.5)

            if len(event.truetaus) == 1:
                true_tau = event.truetaus[0]
                TrueTauBlock.set(tree, 1, true_tau)
            else:
                continue

            # Truth-matching
            matched_reco = None
            reco_index = true_tau.tauAssoc_index
            tau = event.taus.getitem(reco_index)
            if tau in event.taus:
                matched_reco = tau
            else:
                continue

            tree.MET = event.MET_RefFinal_BDTMedium_et

            # fill tau block
            RecoTauBlock.set(event, tree, matched_reco, None)

            # set the event weight
            tree.pileup_weight = pileup_tool.GetCombinedWeight(event.RunNumber,
                                                               event.mc_channel_number,
                                                               event.averageIntPerXing)
            tree.mc_weight = event.mc_event_weight
            tree.Fill(reset=True)

        self.output.cd()
        tree.FlushBaskets()
        tree.Write()
        total_events = event_filters[0].total
        cutflow[0] = total_events
        cutflow[1] = total_events
        cutflow.Write()
Ejemplo n.º 6
0
    def work(self):

        D4PD_model = RecoTauBlock + RecoJetBlock + EventVariables + TrueTauBlock + PartonBlock

        # initialize the TreeChain of all input files (each containing one tree named self.metadata.treename)
        tree = TreeChain(self.metadata.treename,
                         files=self.files,
                         events=self.events,
                         cache=True,
                         cache_size=10000000,
                         learn_entries=30)

        # create output tree
        self.output.cd()
        D4PD = Tree(name=self.metadata.name, model=D4PD_model)

        copied_variables = ['actualIntPerXing',
                            'averageIntPerXing']
        copied_variables += mc_triggers

        D4PD.set_buffer(tree.buffer, variables=copied_variables, create_branches=True, visible=False)
        tree.always_read(copied_variables)

        # set the event filters
        # passthrough for MC for trigger acceptance studies
        self.event_filters = EventFilterList([
            GRLFilter(self.grl, passthrough = self.metadata.datatype != datasets.DATA),
            PriVertex(),
            LArError(),
            JetCleaningLoose(passthrough = self.metadata.datatype != datasets.DATA),
            #JetCleaningMedium(passthrough = self.metadata.datatype != datasets.DATA),
            LArHole(),
            #JetCrackVeto(),
            ElectronVeto(),
            MuonVeto(),
            TauElectronVeto(),
            TauMuonVeto(),
            TauAuthorTrack(),
        ])

        self.event_filters.insert(1, MCTriggers())
        tree.filters += self.event_filters

        cutflow = Cutflow()

        # define tree collections
        tree.define_collection(name="taus", prefix="tau_", size="tau_n", mix=TauFourMomentum)
        # jet_eta etc is AntiKt4LCTopo in tau-perf D3PDs
        tree.define_collection(name="jets", prefix="jet_", size="jet_n", mix=FourMomentum)
        tree.define_collection(name="truetaus", prefix="trueTau_", size="trueTau_n", mix=MCTauFourMomentum)
        tree.define_collection(name="mc", prefix="mc_", size="mc_n", mix=MCParticle)
        tree.define_collection(name="muons", prefix="mu_staco_", size="mu_staco_n")
        tree.define_collection(name="electrons", prefix="el_", size="el_n")
        tree.define_collection(name="vertices", prefix="vxp_", size="vxp_n")

        # define tree objects
        D4PD.define_object(name='tau1', prefix='tau1_')
        D4PD.define_object(name='tau2', prefix='tau2_')
        D4PD.define_object(name='jet1', prefix='jet1_')
        D4PD.define_object(name='jet2', prefix='jet2_')

        """
        tree.define_association(origin='taus', target='truetaus', prefix='trueTauAssoc_', link='index')
        tree.define_association(origin='truetaus', target='taus', prefix='tauAssoc_', link='index')
        """

        # entering the main event loop...
        for event in tree:

            D4PD.reset()
            cutflow.reset()

            # tau selection
            event.taus.select(lambda tau: tau.pt > 15*GeV)
            # Jet selection
            event.jets.select(lambda jet: jet.fourvect.P() > 25*GeV and abs(jet.emscale_eta) < 4.5)

            """
            Get VBF jets
            """
            # get partons (already sorted by eta in hepmc)
            parton1, parton2 = hepmc.get_VBF_partons(event)
            PartonBlock.set(D4PD, parton1, parton2)
            D4PD.dR_quarks = parton1.fourvect.DeltaR(parton2.fourvect)

            """
            Get true taus
            """
            event.truetaus.select(lambda tau: tau.vis_Et > 10 * GeV and abs(tau.vis_eta) < 2.5)
            if len(event.truetaus) > 2:
                print "ERROR: too many true taus: %i" % len(event.truetaus)
                D4PD.error = 1
                D4PD.Fill()
                continue
            elif len(event.truetaus) < 2:
                print "ERROR: too few true taus: %i" % len(event.truetaus)
                D4PD.error = 2
                D4PD.Fill()
                continue

            """
            fourvects = []
            colors = []
            radii = []
            for thing in event.jets:
                fourvects.append(thing.fourvect)
                colors.append('blue')
                radii.append(.4)
            for parton in (parton1, parton2):
                fourvects.append(parton.fourvect)
                colors.append('green')
                radii.append(.1)
            for thing in event.taus:
                fourvects.append(thing.fourvect)
                colors.append('red')
                radii.append(.2)
            for tau in event.truetaus:
                fourvects.append(tau.fourvect)
                colors.append('purple')
                radii.append(.1)

            eventview.draw(event, fourvects, colors=colors, radii=radii)
            """

            TrueTauBlock.set(D4PD, 1, event.truetaus[0])
            TrueTauBlock.set(D4PD, 2, event.truetaus[1])

            D4PD.dR_truetaus = event.truetaus[0].fourvect.DeltaR(event.truetaus[1].fourvect)

            D4PD.dR_quark_tau = min([
                                    parton1.fourvect.DeltaR(event.truetaus[0].fourvect),
                                    parton2.fourvect.DeltaR(event.truetaus[0].fourvect),
                                    parton1.fourvect.DeltaR(event.truetaus[1].fourvect),
                                    parton2.fourvect.DeltaR(event.truetaus[1].fourvect),
                                    ])

            taus = []
            if event.taus:
                for truetau in event.truetaus:
                    closest_tau = min(event.taus, key=lambda tau: utils.dR(tau.seedCalo_eta, tau.seedCalo_phi, truetau.vis_eta, truetau.vis_phi))
                    if utils.dR(closest_tau.seedCalo_eta, closest_tau.seedCalo_phi, truetau.vis_eta, truetau.vis_phi) < 0.2:
                        if closest_tau in taus:
                            # collision
                            D4PD.error = 3
                            break
                        taus.append(closest_tau)
            if len(taus) < 2:
                # collision
                D4PD.Fill()
                continue

            """
            # Overlap removal between taus and jets
            event.jets.select(lambda jet: not any([tau for tau in taus if
                              utils.dR(jet.emscale_eta, jet.emscale_phi, tau.seedCalo_eta, tau.seedCalo_phi) < .2]))
            """

            jets = []
            if event.jets:
                for quark in (parton1, parton2):
                    closest_jet = min(event.jets, key=lambda jet: utils.dR(jet.eta, jet.phi, quark.eta, quark.phi))
                    if utils.dR(closest_jet.eta, closest_jet.phi, quark.eta, quark.phi) < 0.4:
                        if closest_jet in jets:
                            # collision
                            D4PD.error = 4
                            break
                        jets.append(closest_jet)
            if len(jets) < 2:
                # collision
                D4PD.Fill()
                continue

            """
            Jet variables
            """
            RecoJetBlock.set(D4PD, jets[0], jets[1])

            """
            Reco tau variables
            This must come after the RecoJetBlock is filled since
            that sets the jet_beta for boosting the taus
            """
            RecoTauBlock.set(event, D4PD, taus[0], taus[1])
            D4PD.true_Mvis_tau1_tau2 = (D4PD.trueTau1_fourvect_vis + D4PD.trueTau2_fourvect_vis).M()

            """
            MET
            """
            METx = event.MET_RefFinal_etx
            METy = event.MET_RefFinal_ety
            MET_vect = Vector2(METx, METy)
            MET_3vect = Vector3(METx, METy, 0.)

            D4PD.MET = event.MET_RefFinal_et
            D4PD.MET_phi = event.MET_RefFinal_phi

            # HT TODO: Fix
            sumET = event.MET_RefFinal_sumet
            D4PD.HT = sumET

            D4PD.numVertices = len([vtx for vtx in event.vertices if (vtx.type == 1 and vtx.nTracks >= 4) or
                                    (vtx.type == 3 and vtx.nTracks >= 2)])
            # fill output ntuple
            # use reset=True to reset all variables to their defaults after the fill
            # to avoid any values from this event carrying over into the next
            D4PD.cutflow = cutflow.int()
            D4PD.Fill()

        self.output.cd()
        D4PD.FlushBaskets()
        D4PD.Write()