def applyCuts(self,objects): """Apply cuts to our event-level quantities.""" self.objects = objects # unique to each event # ----------------------- # # CONFIGURE EVENT OBJECTS # # ----------------------- # event_level_keys = self.cuts[self.lvl].keys() remake_met = [self.skip_met,self.redefine_met][('met' in self.objects.keys())] if any('ht' in ee for ee in event_level_keys): self.objects['ht'] = vlq.calcHT(self.objects) ## modify the objects dictionary to make keys for met,mtw,met+mtw,HT self.init_met() elif 'met' in self.objects.keys(): self.init_met() elif 'mass_lb' in event_level_keys: self.objects['mass_lb'] = (self.objects['lepton']+self.objects['bjets'][0]).M() elif 'A_mass' in event_level_keys: self.objects['A_mass'] = self.objects['TTbar']['A_mass'] elif 'A_dr' in event_level_keys: self.objects['A_dr'] = self.objects['TTbar']['A_dr'] elif 'A_distance' in event_level_keys: self.objects['A_distance'] = self.objects['TTbar']['asymmR'] # -------------------------- # # LOOP OVER EVENT-LEVEL CUTS # # -------------------------- # # # There are three cases for types of event-level cuts: # 1. DeltaX cut -- requires 2 4-vectors inside parentheses # 2. min/max -- no DeltaX cut, can contain anything inside # 3. Unique -- [HT,nbtags,met+mtw]; no processing (grab from self.objects) for _k in event_level_keys: failed_cut = False evt_results = [] self.cut_value = self.cuts[self.lvl][_k]['value'] # cut value self.cut_cond = self.cuts[self.lvl][_k]['cond'] # cut condition (>,<,etc.) ## ## CASE 1 or 2 ## if any(_k.startswith(i) for i in self.op_keys): ## -- CASE 1: DeltaX if any(i+'(' in _k for i in self.name2attr.keys()): c_result = self.deltaX_cut(_k) # {'result':False,'value':None} # {'result':True,'value':evt_objects} # evt_objects = {'names':[name0,name1],\ # name0: {'isVector':False,'index':None},\ # name1: {'isVector':False,'index':None},\ # 'minmax':min_max} if not c_result['result']: remake_met() return {'result':False,'objects':self.objects} # cut passed, now we need to either: # - save only the objects that passed the cut # - return all objects (min/max) [do nothing] else: c_result = c_result['value'] if not c_result['min_max']: ## set new objects that survived! good_objects = [None,None] obj0_name,obj1_name = c_result['names'] # -- Save object '0' if not c_result[obj0_name]['isVector']: good_objects[0] = self.objects[obj0_name] else: good_objects[0] = [] selected_objects = [] # only save an object once for ii in c_result[obj0_name]['index']: if ii not in selected_objects: selected_objects.append(ii) good_objects[0].append( self.objects[obj0_name][ii] ) self.objects[obj0_name] = good_objects[0] # -- Save object '1' if not c_result[obj1_name]['isVector']: good_objects[1] = self.objects[obj1_name] else: good_objects[1] = [] selected_objects = [] # only save an object once for ii in c_result[obj1_name]['index']: if ii not in selected_objects: selected_objects.append(ii) good_objects[1].append( self.objects[obj1_name][ii] ) self.objects[obj1_name] = good_objects[1] ## -- end saving -- ## ## -- CASE 2: min/max else: c_result = self.minmax_cut(_k) if not c_result['result']: remake_met() return {'result':False,'objects':self.objects} ## ## CASE 3 ## else: c_result = self.ops[self.cut_cond]( self.objects[_k],self.cut_value ) if not c_result: remake_met() return {'result':False,'objects':self.objects} ## -- Event Succeeded! -- ## remake_met() return {'result':True,'objects':self.objects}
def event_loop(self,Entry): """Running the event selection for a single event.""" self.entry = Entry logging.getLogger('share/{0}.log'.format(self.cfg_name)) loggingLEVEL = logging.getLogger().getEffectiveLevel() # DEBUG, INFO, ERROR, etc. logging.info("") logging.critical(" -- In file 'SelectionBase.py'\n") logging.info(" ------------ ") self.t.GetEntry(self.entry) sampleID = self.t.mcChannelNumber if sampleID > 0: self.isMC = True evt_weights = self.Weights[self.energy][str(sampleID)] KFactor = evt_weights['KFactor'] XSection = evt_weights['XSection'] FilterEff = evt_weights['FilterEff'] else: self.isMC = False KFactor = 1.0 XSection = 1.0 FilterEff = 1.0 if not self.entry%1000: print " -> Entry {0}".format(self.entry) # So we can see it's actually running # Initialize these variables in case stuff fails # Then, empty things are just passed around passedSelection = False savedEventVariables = {'fatjets': [],\ 'rcjets': [],\ 'resjets': [],\ 'bjets': [],\ 'lepton': None,\ 'nu': None,\ 'jets': [],\ 'tjets': [],\ 'met': -999.,\ 'HT': -999.,\ 'MC': {},\ 'eventinfo': {}} # ---------------- # # Physics Objects # # ---------------- # self.initializeObjects() # Protect against events with 3 jets but no boosted candidate if len(self.objects['jets']) <= 3 and not self.objects['fatjets']: logging.error(" Processing Pre-selection failed ") logging.error(" -- Entry {0} ".format(self.entry)) logging.error(" -- Too few jets (3 small-r jets and not Boosted) ") logging.info(" jet assignments failed.") return {'objects':savedEventVariables,'result':passedSelection} # ---------------- # # Cuts # # ---------------- # ## -- cuts on objects c_objlevel = self.objectLevelCuts() # function below if not c_objlevel['result']: return {'objects':savedEventVariables,'result':passedSelection} self.objects = c_objlevel['objects'] # update our dictionary of objects ## -- cuts on event-level quantities (HT, DeltaR(x,y), etc.) c_evtlevel = self.eventLevelCuts() # function below if not c_evtlevel['result']: return {'objects':savedEventVariables,'result':passedSelection} self.objects = c_evtlevel['objects'] ## -- record HT if it hasn't been saved or used if not self.objects.get('ht'): self.objects['ht'] = vlq.calcHT(self.objects) # ---------------- # # Hadronic W # # ---------------- # logging.debug(' Hadronic W') self.resjets = [] ## Check for boosted W first if not self.objects['fatjets']: logging.debug(' Resolved Event') self.objects['resjets'] = [self.objects['jets'][0]+self.objects['jets'][1]] # ----------------- # # Truth Information # # ----------------- # all_sample_dsids = info.dsids() signal_dsids = all_sample_dsids['signal']['TTS'].keys() # Just TTS ttbar_dsids = all_sample_dsids['background']['ttbar'].keys() if self.isMC: if self.t.mcChannelNumber in signal_dsids: self.SetupTruth('vlq') elif self.t.mcChannelNumber in ttbar_dsids: if not self.init_prev_entry: prev_truth_entry = 0 else: prev_truth_entry = int(open(self.ttbar_truth_file,'r').readlines()[0]) self.SetupTruth('ttbar',prev_truth_entry) else: self.MC = {} else: self.MC = {} # ---------------- # # Event Info # # ---------------- # boostedEvent = (len(self.objects['fatjets'])>0) # converted to int in miniSL resolvedEvent = (not boostedEvent) if self.isMC: trackjet_btag_weight_70 = self.t.weight_trackjet_bTagSF_70 btag_weight_60 = self.t.weight_bTagSF_60 btag_weight_70 = self.t.weight_bTagSF_70 btag_weight_77 = self.t.weight_bTagSF_77 btag_weight_85 = self.t.weight_bTagSF_85 lept_eff = self.t.weight_leptonSF self.weight_mc = self.t.weight_mc self.weight_pileup = self.t.weight_pileup else: trackjet_btag_weight_70 = 1.0 btag_weight_60 = 1.0 btag_weight_70 = 1.0 btag_weight_77 = 1.0 btag_weight_85 = 1.0 lept_eff = 1.0 self.weight_mc = 1.0 self.weight_pileup = 1.0 eventInfo = {'mcWeight': self.weight_mc,\ 'pileupWeight': self.weight_pileup,\ 'eventNumber': self.t.eventNumber,\ 'runNumber': self.t.runNumber,\ 'mcChannelNumber': self.t.mcChannelNumber,\ 'mu': self.t.mu,\ 'nAMI': self.eventWeight[self.t.mcChannelNumber],\ 'KFactor': KFactor,\ 'XSection': XSection,\ 'FilterEff': FilterEff,\ 'weight_btag_track_70': trackjet_btag_weight_70,\ 'weight_btag_60': btag_weight_60,\ 'weight_btag_70': btag_weight_70,\ 'weight_btag_77': btag_weight_77,\ 'weight_btag_85': btag_weight_85,\ 'weight_lep_eff': lept_eff,\ 'isBoosted': boostedEvent,\ 'isResolved': resolvedEvent,\ 'mujets': self.t.mujets,\ 'ejets': self.t.ejets,\ 'nbtags': self.objects['nbtags'],\ 'vlq_tag': self.objects['vlq_evtype']} # ------------------------------------------------------------- # # Log the results for inspection later # # ------------------------------------------------------------- # if loggingLEVEL >= 20: self.logResults() # ------------------------------------------------------------- # # Return the results to miniSL.py # # ------------------------------------------------------------- # passedSelection = True savedEventVariables = {'fatjets': self.objects['fatjets'],\ 'rcjets': self.objects['rcjets'],\ 'resjets': self.objects['resjets'],\ 'lepton': self.objects['lepton'],\ 'nu': self.objects['nu'],\ 'jets': self.objects['jets'],\ 'tjets': self.objects['tjets'],\ 'met': self.objects['met'],\ 'HT': self.objects['ht'],\ 'MC': self.MC,\ 'eventinfo': eventInfo} ## Hard-coded analysis-specific objects... if self.objects.get('bjets'): savedEventVariables['bjets'] = self.objects['bjets'] else: savedEventVariables['bjets'] = [] return {'objects':savedEventVariables,'result':passedSelection}
def event_loop(self,Entry): """Running the event selection for a single event.""" self.entry = Entry self.t.GetEntry(self.entry) if not self.entry%1000: print " -> Entry {0}".format(self.entry) ## Initialize these in case stuff fails we can return empty values passedSelection = False savedEventVariables = {'fatjets': [],\ 'rcjets': [],\ 'resjets': [],\ 'bjets': [],\ 'jets': [],\ 'lepton': False,\ 'nu': False,\ 'MET': 0,\ 'HT': 0,\ 'MC': {},\ 'eventinfo': {}} # ---------------- # # Physics Objects # # ---------------- # self.initializeObjects() # ---------------- # # Cuts # # ---------------- # ## Cutting on truth objects? DeltaR matching? if any('truth' in i for i in self.cuts): truth_objs = truthBase(self.t) for truth_obj in truth_objs.keys(): self.objects[truth_obj] = truth_objs[truth_obj] ## -- cuts on objects c_objlevel = self.objectLevelCuts() # function below if not c_objlevel['result']: return {'objects':savedEventVariables,'result':passedSelection} self.objects = c_objlevel['objects'] # update our dictionary of objects ## -- cuts on event-level quantities (HT, DeltaR(x,y), etc.) c_evtlevel = self.eventLevelCuts() # function below if not c_evtlevel['result']: return {'objects':savedEventVariables,'result':passedSelection} self.objects = c_evtlevel['objects'] ## -- record HT if it hasn't been saved or used if not self.objects.get('ht'): self.objects['ht'] = vlq.calcHT(self.objects) # ---------------- # # Event Info # # ---------------- # signal_dsids = info.dsids()['signal']['TTS'].keys() ttbar_dsids = info.dsids()['background']['ttbar'].keys() if self.t.mcChannelNumber in signal_dsids+ttbar_dsids: # setup the truth (after cuts and only for signal & ttbar) self.MC = truthBase(self.t) else: self.MC = {} boostedEvent = (len(self.objects['fatjets'])>0) resolvedEvent = (not boostedEvent) eventInfo = {'mcWeight': self.t.weight_mc,\ 'pileupWeight': self.t.weight_pileup,\ 'eventNumber': self.t.eventNumber,\ 'runNumber': self.t.runNumber,\ 'mcChannelNumber': self.t.mcChannelNumber,\ 'mu': self.t.mu,\ 'weight_btag_track_70': self.t.weight_btag_track_70,\ 'weight_btag_60': self.t.weight_btag_60,\ 'weight_btag_70': self.t.weight_btag_70,\ 'weight_btag_77': self.t.weight_btag_77,\ 'weight_btag_85': self.t.weight_btag_85,\ 'weight_lep_eff': self.t.weight_lept_eff,\ 'nAMI': self.t.AMI,\ 'isBoosted': boostedEvent,\ 'isResolved': resolvedEvent,\ 'mujets': self.t.mujets,\ 'ejets': self.t.ejets,\ 'nbtags': self.t.btags_n,\ 'KFactor': self.t.KFactor,\ 'XSection': self.t.XSection,\ 'vlq_tag': self.t.vlq_evtype,\ 'FilterEff': self.t.FilterEff} # ------------------------------------------------------------- # # Log the results for inspection later # # ------------------------------------------------------------- # if self.loggingLEVEL >= 20: self.logResults() # ------------------------------------------------------------- # # Return the results to miniSL.py # # ------------------------------------------------------------- # passedSelection = True savedEventVariables = {'fatjets': self.objects['fatjets'],\ 'rcjets': self.objects['rcjets'],\ 'resjets': self.objects['resjets'],\ 'lepton': self.objects['lepton'],\ 'nu': self.objects['nu'],\ 'jets': self.objects['jets'],\ 'tjets': self.objects['tjets'],\ 'met': self.objects['met'],\ 'HT': self.objects['ht'],\ 'MC': self.MC,\ 'eventinfo': eventInfo} ## Analysis-specific custom object :: need to remove this hard-coding... if self.objects.get('TTbar'): savedEventVariables['TTbar'] = self.objects['TTbar'] else: savedEventVariables['TTbar'] = [] return {'objects':savedEventVariables,'result':passedSelection}
def BuildObjects(self): """ Build 4-vectors of objects in event: lepton,met,nu,jets,tjets,bjets,fatjets,rcjets,resjets """ objects = self.p_objects.split(',') # make 'resjets' be the last thing built (need the jets first) if objects[-1]!='resjets' and 'resjets' in objects: objects.remove('resjets') objects.append('resjets') ## possible objects linked to their functions import_keys = {'lepton': lepBase,\ 'met': metBase,\ 'nu': nuBase,\ 'jets': jetBase,\ 'bjets': bjetBase,\ 'tjets': tjetBase,\ 'fatjets': fjBase,\ 'rcjets': rcBase,\ 'resjets': resBase} self.event_objects = {'vlq_evtype':self.ttree.vlq_evtype} ## special treatment for truth information because of how it is saved in truthSelection if any(ob.startswith('truth') for ob in objects) or self.p_plot1d=='efficiency': objs = truthBase(self.ttree) for key in objs.keys(): self.event_objects[key] = objs[key] objects.remove('truth') # just set it up, done with truth information for event_object in objects: if event_object == 'bjets+jets' or event_object == 'jets+bjets': jets = jetBase(self.ttree) bjets = bjetBase(self.ttree) jets = jets+bjets # merge the objects into one list jets.sort( key=lambda x: x.Pt(), reverse=True) # [0] has the highest pT self.event_objects['jets'] = jets elif event_object == 'resjets': obj = import_keys[event_object](self.event_objects['jets']) self.event_objects[event_object] = obj obj.sort( key=lambda x: x.Pt(), reverse=True) # [0] has the highest pT else: obj = import_keys[event_object](self.ttree) self.event_objects[event_object] = obj try: obj.sort( key=lambda x: x.Pt(), reverse=True) # [0] has the highest pT except AttributeError: continue if 'jets' in objects or 'bjets' in objects or 'bjets+jets' in objects: self.event_objects['nbtags'] = len( [q for q in self.event_objects['jets'] if q.mv2c20>self.p_btag_wkpt] ) if 'bjets' not in objects: self.event_objects['bjets'] = [] self.event_objects['resjets'] = [] if 'ht' in self.p_variables: self.event_objects['ht'] = vlq.calcHT(self.event_objects) return