def __init__(self, source=None, process_fn=None, name='Variation', fallback=None, **kwargs): self._calculables = {} self._source = source self._fallback = fallback self._process_fn = process_fn self._name = name self._warn_once = False self.set_valid(False) self._cutflow = Cutflow() # set up a list of calculable items by sniffing out methods # named _get_xxxx(). Save a reference to the instance method # for later. # self._calculables = dict([ (n[5:], m) for (n,m) in inspect.getmembers(self) # if n.startswith('_get_') and inspect.ismethod(m) ]) self._calculables = dict([(n[5:], m) for (n, m) in inspect.getmembers(self) if n.startswith('_get_') and inspect.ismethod(m)])
def run_with_chain(tree, n_max_entries=-1): nttool = r.SusyNtTools() m_entry = r.Long(-1) ntevent = r.Susy.SusyNtObject(m_entry) ntevent.ReadFrom(tree) isSimplifiedModel = False period, useRewUtils = "Moriond", False trig_logic = r.DilTrigLogic(period, useRewUtils) n_entries_to_print = 4 sys = utils.SusyNtSys.NOM tauId = utils.TauID tauJetId, tauEleId, tauMuoId = tauId.TauID_loose, tauId.TauID_medium, tauId.TauID_medium cutflow = Cutflow() for iEntry, entry in enumerate(tree): m_entry = iEntry if n_max_entries > 0 and m_entry >= n_max_entries: break if iEntry < n_entries_to_print: print "run ", ntevent.evt().run, " event ", ntevent.evt().event pre_elecs = nttool.getPreElectrons(ntevent, sys) pre_muons = nttool.getPreMuons(ntevent, sys) pre_taus = nttool.getPreTaus(ntevent, sys) pre_jets = nttool.getPreJets(ntevent, sys) nttool.performOverlap(pre_elecs, pre_muons, pre_taus, pre_jets) nttool.removeSFOSPair(pre_elecs, 12.0) nttool.removeSFOSPair(pre_muons, 12.0) rmLepsFromIso = False n_vertices = ntevent.evt().nVtx is_mc = ntevent.evt().isMC sig_elecs = nttool.getSignalElectrons(pre_elecs, pre_muons, n_vertices, is_mc, rmLepsFromIso) sig_muons = nttool.getSignalMuons(pre_muons, pre_elecs, n_vertices, is_mc, rmLepsFromIso) sig_taus = nttool.getSignalTaus(pre_taus, tauJetId, tauEleId, tauMuoId) sig_jets = nttool.getSignalJets(pre_jets, sys) sig_jets2l = nttool.getSignalJets2Lep(pre_jets, sys) met = nttool.getMet(ntevent, sys) pre_lep, sig_lep = r.LeptonVector(), r.LeptonVector() nttool.buildLeptons(pre_lep, pre_elecs, pre_muons) nttool.buildLeptons(sig_lep, sig_elecs, sig_muons) if iEntry < n_entries_to_print: print "pre_lep:\n", "\n".join( [ "[%d] %s (eta,phi,pt) = (%.3f, %.3f, %.3f)" % (iL, "mu" if l.isMu() else "el", l.Eta(), l.Phi(), l.Pt()) for iL, l in enumerate(pre_lep) ] ) event_flag = ntevent.evt().cutFlags[0] def mll(leps): return (leps[0] + leps[1]).M() try: cutflow.cut_if(False, "input") cutflow.cut_if(not nttool.passLAr(event_flag), "lar") cutflow.cut_if(not nttool.passBadJet(event_flag), "bad_jet") cutflow.cut_if(not nttool.passBadMuon(event_flag), "bad_mu") cutflow.cut_if(not nttool.passCosmic(event_flag), "cosmic") cutflow.cut_if(not pre_lep.size() == 2, "2lep") cutflow.cut_if(not trig_logic.passDilTrig(pre_lep, met.Et, ntevent.evt()), "trigger") cutflow.cut_if(not mll(pre_lep) > 20.0, "mll20") except SkipEvent: continue print "\n" + 8 * "-" + " cutflow " + 8 * "-" print cutflow
def run_with_chain(tree, n_max_entries=-1): nttool = r.SusyNtTools() m_entry = r.Long(-1) ntevent = r.Susy.SusyNtObject(m_entry) ntevent.ReadFrom(tree) isSimplifiedModel = False nttool.buildSumwMap(tree, isSimplifiedModel) period, useRewUtils = 'Moriond', False trig_logic = r.DilTrigLogic(period, useRewUtils) n_entries_to_print = 4 sys = utils.SusyNtSys.NtSys_NOM tauId = utils.TauID tauJetId, tauEleId, tauMuoId = tauId.TauID_loose, tauId.TauID_medium, tauId.TauID_medium cutflow = Cutflow() for iEntry, entry in enumerate(tree): m_entry = iEntry if n_max_entries>0 and m_entry >= n_max_entries : break if iEntry < n_entries_to_print : print 'run ', ntevent.evt().run,' event ',ntevent.evt().event pre_elecs = nttool.getPreElectrons(ntevent, sys) pre_muons = nttool.getPreMuons(ntevent, sys) pre_taus = nttool.getPreTaus(ntevent, sys) pre_jets = nttool.getPreJets(ntevent, sys) nttool.performOverlap(pre_elecs, pre_muons, pre_taus, pre_jets) nttool.removeSFOSPair(pre_elecs, 12.0) nttool.removeSFOSPair(pre_muons, 12.0) rmLepsFromIso = False n_vertices = ntevent.evt().nVtx is_mc = ntevent.evt().isMC sig_elecs = nttool.getSignalElectrons(pre_elecs, pre_muons, n_vertices, is_mc, rmLepsFromIso) sig_muons = nttool.getSignalMuons(pre_muons, pre_elecs, n_vertices, is_mc, rmLepsFromIso) sig_taus = nttool.getSignalTaus(pre_taus, tauJetId, tauEleId, tauMuoId) sig_jets = nttool.getSignalJets(pre_jets, sys) sig_jets2l = nttool.getSignalJets2Lep(pre_jets, sys) met = nttool.getMet(ntevent, sys) pre_lep, sig_lep = r.LeptonVector(), r.LeptonVector() nttool.buildLeptons(pre_lep, pre_elecs, pre_muons) nttool.buildLeptons(sig_lep, sig_elecs, sig_muons) if iEntry<n_entries_to_print: print 'pre_lep:\n','\n'.join(["[%d] %s (eta,phi,pt) = (%.3f, %.3f, %.3f)" % (iL, "mu" if l.isMu() else "el", l.Eta(), l.Phi(), l.Pt()) for iL, l in enumerate(pre_lep)]) event_flag = ntevent.evt().cutFlags[0] def mll(leps): return (leps[0] + leps[1]).M() try: cutflow.cut_if(False, 'input') cutflow.cut_if(not nttool.passLAr(event_flag), 'lar') cutflow.cut_if(not nttool.passBadJet(event_flag), 'bad_jet') cutflow.cut_if(not nttool.passBadMuon(event_flag), 'bad_mu') cutflow.cut_if(not nttool.passCosmic(event_flag), 'cosmic') cutflow.cut_if(not pre_lep.size()==2, '2lep') cutflow.cut_if(not trig_logic.passDilTrig(pre_lep, met.Et, ntevent.evt()), 'trigger') cutflow.cut_if(not mll(pre_lep)>20.0, 'mll20') except SkipEvent: continue print '\n'+8*'-'+' cutflow '+8*'-' print cutflow
class AnalysisVariation: def __init__(self, source=None, process_fn=None, name='Variation', fallback=None, **kwargs): self._calculables = {} self._source = source self._fallback = fallback self._process_fn = process_fn self._name = name self._warn_once = False self.set_valid(False) self._cutflow = Cutflow() # set up a list of calculable items by sniffing out methods # named _get_xxxx(). Save a reference to the instance method # for later. # self._calculables = dict([ (n[5:], m) for (n,m) in inspect.getmembers(self) # if n.startswith('_get_') and inspect.ismethod(m) ]) self._calculables = dict([(n[5:], m) for (n, m) in inspect.getmembers(self) if n.startswith('_get_') and inspect.ismethod(m)]) def set_source(self, source): self._source = source def set_fallback(self, fallback): if fallback == self: return self._fallback = fallback ''' A convenience method; simply tries to invoke the user-supplied process function. ''' def process_entry(self): # NB this is slow... maybe we should optimize. # but we'll put it here as a convenience method. try: self._process_fn(self) except TypeError as e: if e.message == "'NoneType' object is not callable": if not self._warn_once: print "Warning! No process function supplied for variation `%s`!" % self._name self._warn_once = True else: raise e ''' These methods may be called once (by a driver) before and after the main event loop. ''' def pre_run(self): pass def post_run(self): pass ''' This method is called if the input entry has been accepted *and* this instance passed (i.e. is in the valid state). It may be used, e.g., to write out ntuple branches. ''' def accept_entry(self): if not self._warn_once: print "WARNING! Base class accept_entry() invoked for variation `%s`!" % self._name self._warn_once = True ''' This method is called if the input entry was accepted for *some* variation, but this instance did not pass (i.e. this entry is not valid). It may be used, e.g., to fill an empty ntuple entry. ''' def reject_entry(self): pass ''' Reset the state of all managed calculables. Also set the current entry status to invalid for this object. ''' def reset(self): # delete any cached calcuable results for c in self._calculables: try: delattr(self, c) except AttributeError: # fine, nothing to delete. it was never set. pass # and set state to invalid self.set_valid(False) def cut_if(self, expr, cutname): self._cutflow.cut_if(expr, cutname) def defer(self): if self._fallback: raise CalculationFallback def defer_if(self, expr): if self._fallback and expr: raise CalculationFallback def defer_unless(self, expr): if self._fallback and not expr: raise CalculationFallback def can_defer(self): return self._fallback is not None def set_valid(self, valid): self._valid = valid def __getattr__(self, attr): # here's the magic. if the requested attribute is calculable, # go calculate it and then cache the result. try: # user tried to access a calculable item, but it's not cached. # calculate and save the result, then return it. v = self._calculables[attr]() setattr(self, attr, v) return v except KeyError: # we're not managing this attribute, so escalate to the # "source" object (which by default is the underlying # TTree): return getattr(self._source, attr) except CalculationFallback: # defer the calculation to the fallback object return getattr(self._fallback, attr) def __str__(self): return "<Varation object `%s`>" % self._name
def fill_histos(input_files, histos, tree_name='susyNt', max_num_entries=None, verbose=False): "fill histograms (for now unweighted, just to do a per-lepton comparison)" chain = r.TChain(tree_name) for f in input_files : chain.Add(f) num_entries = chain.GetEntries() if verbose : print "About to loop on %d entries from %d files"%(num_entries, len(input_files)) nttool = r.SusyNtTools() m_entry = r.Long(-1) ntevent = r.Susy.SusyNtObject(m_entry) ntevent.ReadFrom(chain) isSimplifiedModel = False period, useRewUtils = 'Moriond', False trig_logic = r.DilTrigLogic(period, useRewUtils) n_entries_to_print = 4 sys = utils.SusyNtSys.NOM tauId = utils.TauID tauJetId, tauEleId, tauMuoId = tauId.TauID_loose, tauId.TauID_medium, tauId.TauID_medium cutflow = Cutflow() for iEntry, entry in enumerate(chain): m_entry = iEntry if max_num_entries and iEntry > max_num_entries : break pre_elecs = nttool.getPreElectrons(ntevent, sys) pre_muons = nttool.getPreMuons(ntevent, sys) pre_taus = nttool.getPreTaus(ntevent, sys) pre_jets = nttool.getPreJets(ntevent, sys) nttool.performOverlap(pre_elecs, pre_muons, pre_taus, pre_jets) nttool.removeSFOSPair(pre_elecs, 12.0) nttool.removeSFOSPair(pre_muons, 12.0) rmLepsFromIso = False n_vertices = ntevent.evt().nVtx is_mc = ntevent.evt().isMC sig_elecs = nttool.getSignalElectrons(pre_elecs, pre_muons, n_vertices, is_mc, rmLepsFromIso) sig_muons = nttool.getSignalMuons(pre_muons, pre_elecs, n_vertices, is_mc, rmLepsFromIso) sig_taus = nttool.getSignalTaus(pre_taus, tauJetId, tauEleId, tauMuoId) sig_jets = nttool.getSignalJets(pre_jets, sys) sig_jets2l = nttool.getSignalJets2Lep(pre_jets, sys) met = nttool.getMet(ntevent, sys) pre_lep, sig_lep = r.LeptonVector(), r.LeptonVector() nttool.buildLeptons(pre_lep, pre_elecs, pre_muons) nttool.buildLeptons(sig_lep, sig_elecs, sig_muons) if verbose and iEntry<n_entries_to_print: print "run {0} event {1}".format(ntevent.evt().run, ntevent.evt().event) print "pre_elecs[{0}], pre_muons[{1}] pre_taus[{2}] pre_jets[{3}]".format(len(pre_elecs), len(pre_muons), len(pre_taus), len(pre_jets)) print 'pre_lep:\n','\n'.join(["[%d] %s (eta,phi,pt) = (%.3f, %.3f, %.3f)" % (iL, "mu" if l.isMu() else "el", l.Eta(), l.Phi(), l.Pt()) for iL, l in enumerate(pre_lep)]) print 'pre_jets:\n','\n'.join(["[%d] (eta,phi,pt) = (%.3f, %.3f, %.3f)" % (iL, j.Eta(), j.Phi(), j.Pt()) for iL, j in enumerate(pre_jets)]) event_flag = ntevent.evt().cutFlags[0] def mll(leps): return (leps[0] + leps[1]).M() try: cutflow.cut_if(False, 'input') cutflow.cut_if(not nttool.passLAr(event_flag), 'lar') cutflow.cut_if(False, 'bad_jet') #not nttool.passBadJet(event_flag), 'bad_jet') cutflow.cut_if(False, 'bad_mu') #not nttool.passBadMuon(event_flag), 'bad_mu') cutflow.cut_if(False, 'cosmic') #not nttool.passCosmic(event_flag), 'cosmic') cutflow.cut_if(not pre_lep.size()==2, '2lep') cutflow.cut_if(not trig_logic.passDilTrig(pre_lep, met.Et, ntevent.evt()), 'trigger') cutflow.cut_if(not mll(pre_lep)>20.0, 'mll20') histos['el_n_base'].Fill(len(pre_elecs)) # todo: fix, use base rather than pre histos['el_n_sign'].Fill(len(sig_elecs)) histos['mu_n_base'].Fill(len(pre_muons)) # todo: fix, use base rather than pre histos['mu_n_sign'].Fill(len(sig_muons)) for el in sig_elecs: histos['el_pt'].Fill(el.Pt()) histos['el_eta'].Fill(el.Eta()) histos['el_phi'].Fill(el.Phi()) for mu in sig_muons: histos['mu_pt'].Fill(mu.Pt()) histos['mu_eta'].Fill(mu.Eta()) histos['mu_phi'].Fill(mu.Phi()) except SkipEvent: continue print '\n'+8*'-'+' cutflow '+8*'-' print cutflow
def fill_histos(input_files, histos, tree_name='susyNt', max_num_entries=None, verbose=False): "fill histograms (for now unweighted, just to do a per-lepton comparison)" chain = r.TChain(tree_name) for f in input_files: chain.Add(f) num_entries = chain.GetEntries() if verbose: print "About to loop on %d entries" % num_entries nttool = r.SusyNtTools() m_entry = r.Long(-1) ntevent = r.Susy.SusyNtObject(m_entry) ntevent.ReadFrom(chain) isSimplifiedModel = False period, useRewUtils = 'Moriond', False trig_logic = r.DilTrigLogic(period, useRewUtils) n_entries_to_print = 4 sys = utils.SusyNtSys.NtSys_NOM tauId = utils.TauID tauJetId, tauEleId, tauMuoId = tauId.TauID_loose, tauId.TauID_medium, tauId.TauID_medium cutflow = Cutflow() for iEntry, entry in enumerate(chain): m_entry = iEntry if max_num_entries and iEntry > max_num_entries: break pre_elecs = nttool.getPreElectrons(ntevent, sys) pre_muons = nttool.getPreMuons(ntevent, sys) pre_taus = nttool.getPreTaus(ntevent, sys) pre_jets = nttool.getPreJets(ntevent, sys) nttool.performOverlap(pre_elecs, pre_muons, pre_taus, pre_jets) nttool.removeSFOSPair(pre_elecs, 12.0) nttool.removeSFOSPair(pre_muons, 12.0) rmLepsFromIso = False n_vertices = ntevent.evt().nVtx is_mc = ntevent.evt().isMC sig_elecs = nttool.getSignalElectrons(pre_elecs, pre_muons, n_vertices, is_mc, rmLepsFromIso) sig_muons = nttool.getSignalMuons(pre_muons, pre_elecs, n_vertices, is_mc, rmLepsFromIso) sig_taus = nttool.getSignalTaus(pre_taus, tauJetId, tauEleId, tauMuoId) sig_jets = nttool.getSignalJets(pre_jets, sys) sig_jets2l = nttool.getSignalJets2Lep(pre_jets, sys) met = nttool.getMet(ntevent, sys) pre_lep, sig_lep = r.LeptonVector(), r.LeptonVector() nttool.buildLeptons(pre_lep, pre_elecs, pre_muons) nttool.buildLeptons(sig_lep, sig_elecs, sig_muons) if verbose and iEntry < n_entries_to_print: print 'pre_lep:\n', '\n'.join([ "[%d] %s (eta,phi,pt) = (%.3f, %.3f, %.3f)" % (iL, "mu" if l.isMu() else "el", l.Eta(), l.Phi(), l.Pt()) for iL, l in enumerate(pre_lep) ]) event_flag = ntevent.evt().cutFlags[0] def mll(leps): return (leps[0] + leps[1]).M() try: cutflow.cut_if(False, 'input') cutflow.cut_if(not nttool.passLAr(event_flag), 'lar') cutflow.cut_if(not nttool.passBadJet(event_flag), 'bad_jet') cutflow.cut_if(not nttool.passBadMuon(event_flag), 'bad_mu') cutflow.cut_if(not nttool.passCosmic(event_flag), 'cosmic') cutflow.cut_if(not pre_lep.size() == 2, '2lep') cutflow.cut_if( not trig_logic.passDilTrig(pre_lep, met.Et, ntevent.evt()), 'trigger') cutflow.cut_if(not mll(pre_lep) > 20.0, 'mll20') for el in sig_elecs: histos['el_pt'].Fill(el.Pt()) histos['el_eta'].Fill(el.Eta()) histos['el_phi'].Fill(el.Phi()) for mu in sig_muons: histos['mu_pt'].Fill(mu.Pt()) histos['mu_eta'].Fill(mu.Eta()) histos['mu_phi'].Fill(mu.Phi()) except SkipEvent: continue print '\n' + 8 * '-' + ' cutflow ' + 8 * '-' print cutflow
class AnalysisVariation: def __init__(self, source=None, process_fn=None, name='Variation', fallback=None, **kwargs): self.__calculables = {} self.__source = source self.__fallback = fallback self.process_fn = process_fn self.name = name self.warn_once = False self.set_valid(False) self.cutflow = Cutflow() # set up a list of calculable items by sniffing out methods # named _get_xxxx(). Save a reference to the instance method # for later. #self.__calculables = dict([ (n[5:], m) for (n,m) in inspect.getmembers(self) # if n.startswith('_get_') and inspect.ismethod(m) ]) self.__calculables = dict([ (n[5:], m) for (n,m) in inspect.getmembers(self) if n.startswith('_get_') and inspect.ismethod(m) ]) def set_source(self, source): self.__source = source def set_fallback(self, fallback): if fallback == self: return self.__fallback = fallback def process(self): # this is slow... maybe we should optimize. # but we'll put it here as a convenience method. try: self.process_fn(self) except TypeError as e: if e.message == "'NoneType' object is not callable": if not self.warn_once: print "Warning! No process() function supplied for variation `%s`!"%self.name self.warn_once = True else: raise e def cut_if(self, expr, cutname): self.cutflow.cut_if(expr, cutname) def defer(self): if self.__fallback: raise CalculationFallback def defer_if(self, expr): if self.__fallback and expr: raise CalculationFallback def defer_unless(self, expr): if self.__fallback and not expr: raise CalculationFallback def reset(self): # delete any cached calcuable results for c in self.__calculables: try: delattr(self, c) except AttributeError: # fine, nothing to delete. it was never set. pass # and set state to invalid self.set_valid(False) def set_valid(self, valid): self.__valid = valid def write_ntuple(self): if not self.warn_once: print "WARNING! Base class write_ntuple() invoked for variation `%s`!"%self.name self.warn_once = True def __getattr__(self, attr): # here's the magic. if the requested attribute is calculable, # go calculate it and then cache the result. try: # user tried to access a calculable item, but it's not cached. # calculate and save the result, then return it. v = self.__calculables[attr]() setattr(self, attr, v) return v except KeyError: # we're not managing this attribute, so escalate to the # "source" object (which by default is the underlying # TTree): return getattr(self.__source, attr) except CalculationFallback: # defer the calculation to the fallback object return getattr(self.__fallback, attr) def __str__(self): return "<Varation object `%s`>"%self.name