Exemple #1
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()
Exemple #2
0
    def work(self):
        """
        This is the one function that all "ATLASStudent"s must implement.
        """
        datatype = self.metadata.datatype
        year = self.metadata.year
        verbose = self.args.verbose

        OutputModel = C3POEvent

        if datatype == datasets.MC:
            # only create truth branches for MC
            OutputModel += (
                    FourVectModel.prefix('resonance_') +
                    TrueTau.prefix('truetau1_') +
                    TrueTau.prefix('truetau2_'))

        onfilechange = []
        count_funcs = {}

        if datatype in (datasets.MC, datasets.EMBED):

            def mc_weight_count(event):
                return event.mc_event_weight

            count_funcs = {
                'mc_weight': mc_weight_count,
            }

        trigger_config = None

        if datatype != datasets.EMBED:
            # trigger config tool to read trigger info in the ntuples
            trigger_config = get_trigger_config()

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

        if datatype == datasets.DATA:
            merged_grl = GRL()

            def update_grl(student, grl, name, file, tree):

                grl |= str(file.Get('Lumi/%s' % student.metadata.treename).GetString())

            onfilechange.append((update_grl, (self, merged_grl,)))

        if datatype == datasets.DATA:
            merged_cutflow = Hist(1, 0, 1, name='cutflow', type='D')
        else:
            merged_cutflow = Hist(2, 0, 2, name='cutflow', type='D')

        def update_cutflow(student, cutflow, name, file, tree):

            year = student.metadata.year
            datatype = student.metadata.datatype
            if datatype == datasets.MC:
                cutflow[0] += file.cutflow_event[0]
                cutflow[1] += file.cutflow_event_mc_weight[0]
            else:
                cutflow[0] += file.cutflow_event[0]

        onfilechange.append((update_cutflow, (self, merged_cutflow,)))

        # 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,
                read_branches_on_demand=True,
                cache=True,
                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([
            CoreFlags(
                count_funcs=count_funcs),
            TauSelected(2,
                count_funcs=count_funcs),
            TruthMatching(
                passthrough=datatype != datasets.MC,
                count_funcs=count_funcs),
            MCWeight(
                datatype=datatype,
                tree=tree,
                passthrough=datatype != datasets.MC,
                count_funcs=count_funcs)
        ])

        self.filters['event'] = event_filters

        chain._filters += event_filters

        define_objects(chain, year, skim=False)

        # define tree objects
        taus = [
            tree.define_object(name='tau1', prefix='tau1_'),
            tree.define_object(name='tau2', prefix='tau2_')]

        if datatype == datasets.MC:
            truetaus = [
                tree.define_object(name='truetau1', prefix='truetau1_'),
                tree.define_object(name='truetau2', prefix='truetau2_')]

            tree.define_object(name='resonance', prefix='resonance_')

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

            # sort taus and jets in decreasing order by pT
            event.taus.sort(key=lambda tau: tau.pt, reverse=True)

            tau1, tau2 = event.taus

            # MET
            METx = event.MET.etx
            METy = event.MET.ety
            MET_vect = Vector2(METx, METy)
            MET = event.MET.et
            MET_phi = event.MET.phi

            tree.MET = MET
            tree.MET_x = METx
            tree.MET_y = METy
            tree.MET_phi = MET_phi

            sumET = event.MET.sumet
            tree.sumET = sumET
            if sumET != 0:
                tree.MET_sig = ((2. * MET / GeV) /
                        (utils.sign(sumET) * sqrt(abs(sumET / GeV))))
            else:
                tree.MET_sig = -1.

            # use MMC values from skim
            mmc_mass = event.tau_MMC_mass
            mmc_resonance = event.tau_MMC_resonance
            mmc_met = Vector2(event.tau_MMC_MET_x, event.tau_MMC_MET_y)

            tree.mass_mmc_tau1_tau2 = mmc_mass
            tree.mmc_resonance.copy_from(mmc_resonance)
            if mmc_mass > 0:
                tree.mmc_resonance_pt = mmc_resonance.Pt()
            tree.MET_mmc = mmc_met.Mod()
            tree.MET_mmc_x = mmc_met.X()
            tree.MET_mmc_y = mmc_met.Y()
            tree.MET_mmc_phi = math.pi - mmc_met.Phi()

            # truth matching
            if datatype == datasets.MC:

                resonance, tau_decays = get_taus(event)

                if resonance is not None:

                    FourVectModel.set(tree.resonance, resonance)

                    matched_taus = []
                    decays = tau_decays[:]
                    for itau, tau in enumerate(event.taus):
                        for idecay, tau_decay in enumerate(decays):
                            if tau.matches_vect(tau_decay.fourvect_visible):
                                tau_decay.matched = True
                                tau_decay.matched_object = tau
                                tau.matched = True
                                tau.matched_object = tau_decay
                                TrueTau.set(truetaus[itau], tau_decay,
                                        verbose=verbose)
                                decays.pop(idecay)
                                matched_taus.append(itau)
                                break

                    if len(decays) > 0:
                        for idecay, decay in enumerate(decays):
                            reco_idx = -1
                            remaining_idx = range(2)
                            for imatched in remaining_idx:
                                if imatched not in matched_taus:
                                    reco_idx = imatched
                                    remaining_idx.remove(imatched)
                                    break
                            TrueTau.set(truetaus[reco_idx], tau_decay,
                                    verbose=verbose)

                    if len(tau_decays) == 2:
                        # write truth met
                        fourvect_missing = (tau_decays[0].fourvect_missing +
                                            tau_decays[1].fourvect_missing)

                        tree.MET_true = fourvect_missing.Pt()
                        tree.MET_phi_true = fourvect_missing.Phi()
                        tree.MET_x_true = tree.MET_true * math.cos(tree.MET_phi_true)
                        tree.MET_y_true = tree.MET_true * math.sin(tree.MET_phi_true)
                        tree.MET_phi_diff = Vector2.Phi_mpi_pi(tree.MET_phi_true - MET_phi)

            # tau - vertex association
            tree.tau_same_vertex = (
                    tau1.privtx_x == tau2.privtx_x and
                    tau1.privtx_y == tau2.privtx_y and
                    tau1.privtx_z == tau2.privtx_z)

            # fill tau block
            for outtau, intau in zip(taus, event.taus):
                RecoTau.set(outtau, intau, verbose=verbose)

            # fill output ntuple
            tree.Fill(reset=True)

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

        if datatype == datasets.DATA:
            xml_string = ROOT.TObjString(merged_grl.str())
            xml_string.Write('lumi')
        merged_cutflow.Write()
Exemple #3
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()