def parse_formula(fcn_string, pars_string): pars = [] formula = fcn_string for par_num, match in enumerate(re.finditer("(?P<name>\w+)(?P<boundaries>\[[^\]]+\]),? ?", pars_string)): par = struct() par.num = par_num par.name = match.group('name') par.bounds = eval( match.group('boundaries') ) formula = formula.replace(par.name, '[%i]' % par.num) pars.append(par) ret = ROOT.TF1('ret', formula, 0, 200) for par in pars: ret.SetParName(par.num, par.name) if len(par.bounds) == 1: ret.FixParameter(par.num, par.bounds[0]) else: ret.SetParameter(par.num, par.bounds[0]) ret.SetParLimits(par.num, par.bounds[1], par.bounds[2]) return ret
def process(self): logging.debug('Starting processing') systematics = self.systematics frw = [] lock = () ievt = 0 logging.debug('Starting evt loop') #pre-compute static things sys_shifts = systematics['trig'] # + \ # systematics['pu'] + \ # systematics['eid'] + \ # systematics['eiso'] #+ \ jes_dirs = [i.strip('_') for i in systematics['jes']] #anyway the first is always "" tes_dirs = [i.strip('_') for i in systematics['tes']][1:] ees_dirs = [i.strip('_') for i in systematics['ees']][1:] for row in self.tree: if (ievt % 100) == 0: logging.debug('New event') ievt += 1 #avoid double counting events! evt_id = (row.run, row.lumi, row.evt) if evt_id == lock: continue if lock != () and evt_id == lock: logging.info('Removing duplicate of event: %d %d %d' % evt_id) # #preselection, common to everything and everyone # #trigger if self.is_embedded: if not bool(row.doubleMuPass): continue else: if not bool(row.singleE27WP80Pass): continue if not bool(row.eMatchesSingleE27WP80): continue #objects if not selections.eSelection(row, 'e'): continue #if row.ePt < 30 : continue if not selections.tauSelection(row, 't'): continue if not row.tAntiElectronMVA5Tight: continue if not row.tAntiMuon2Loose: continue if not row.tLooseIso3Hits: continue logging.debug('object selection passed') #e ID/ISO if not selections.lepton_id_iso(row, 'e', 'eid13Tight_idiso02'): continue logging.debug('Passed preselection') # # Compute event weight # #event weight #sys_shifts is precomputed #set_trace() weight_map = self.event_weight(row, sys_shifts) #Fill embedded sample normalization BEFORE the vetoes # if not row.e_t_SS: # self.fill_histos('os/gg/ept30', row, weight_map['']) # it is better vetoing on b-jets after the histo for the DY embedded #bjet veto if row.bjetCSVVeto30 != 0: continue #tau ID, id Tau is tight then go in full selection, otherwise use for fakes isTauTight = bool(row.tTightIso3Hits) isETight = bool( selections.lepton_id_iso(row, 'e', 'eid13Tight_etauiso01')) # etau_category = [''] # if (not isETight) and (not isTauTight): # etau_category = ['etLoose', 'etLoose/Up', 'etLoose/Down'] # elif (not isTauTight): # etau_category = ['tLoose', 'tLoose/Up', 'tLoose/Down', 'tLooseUnweight'] # elif (not isETight): # etau_category = ['eLoose', 'eLoose/Up', 'eLoose/Down'] #jet category central = struct(njets=min(row.jetVeto30, 3), tPt=row.tPt, ePt=row.ePt) jets = [ min(row.jetVeto30, 3), min(row.jetVeto30jes_plus, 3), min(row.jetVeto30jes_minus, 3) ] tpts = [row.tPt_tes_plus, row.tPt_tes_minus] epts = [row.ePt_ees_plus, row.ePt_ees_minus] sys_effects = [(name, central.clone(njets=jnum)) for name, jnum in zip(jes_dirs, jets)] # sys_effects.extend( # [(name, central.clone(tPt = pt)) for name, pt in zip(tes_dirs, tpts)] # ) # sys_effects.extend( # [(name, central.clone(ePt = pt)) for name, pt in zip(ees_dirs, epts)] # ) # # Full tight selection # passes_full_selection = False selection_categories = [] # for name, shifted in sys_effects: #preselection. flat pt values if row.ePt < 30 and row.tPt < 30: # selection_categories.append((name, '%i' % shifted.njets, '')) # else: continue # if shifted.njets == 0 : # if shifted.tPt < 35: continue # if shifted.ePt < 40: continue # if deltaPhi(row.ePhi, row.tPhi) < 2.7 : continue # if row.tMtToPfMet > 50 : continue # selection_categories.append((name, '0', 'selected')) # passes_full_selection = True # elif shifted.njets == 1 : # if shifted.tPt < 40: continue # if shifted.ePt < 35: continue # if row.tMtToPfMet > 35 : continue # selection_categories.append((name, '1', 'selected')) # passes_full_selection = True # elif shifted.njets == 2 : # if shifted.tPt < 40: continue # if shifted.ePt < 30: continue # if row.tMtToPfMet > 35 : continue # if row.vbfMass < 550 : continue # if row.vbfDeta < 3.5 : continue # selection_categories.append((name, '2', 'selected')) # passes_full_selection = True #dir_name1 = os.path.join(sys, selection_sys, sign, processtype, # e_thr, jet_dir, selection_step) # tvetoes = [row.tauVetoPt20EleTight3MuLoose, row.tauVetoPt20EleTight3MuLoose_tes_plus, row.tauVetoPt20EleTight3MuLoose_tes_minus] # mvetoes = [row.muVetoPt5IsoIdVtx , row.muVetoPt5IsoIdVtx_mes_plus , row.muVetoPt5IsoIdVtx_mes_minus ] # evetoes = [row.eVetoCicLooseIso , row.eVetoCicLooseIso_ees_plus , row.eVetoCicLooseIso_ees_minus ] # tdirs = [ i for i, j in zip( systematics['tvetos'], tvetoes) if not j] # mdirs = [ i for i, j in zip( systematics['mvetos'], mvetoes) if not j] # edirs = [ i for i, j in zip( systematics['evetos'], evetoes) if not j] #if any of the lists is empty #set_trace() # if not tdirs or not mdirs or not edirs: # continue # logging.debug('Passed Vetoes') jet0panel = [('tPtcut', 1, 1, 30, 70), ('ePtcut', 1, 1, 30, 70), ('deltaPhicut', 1, 1, 20, 35), ('tMtToPFMETcut', 1, 1, 20, 80)] jet1panel = [('tPtcut', 1, 1, 30, 70), ('ePtcut', 1, 1, 30, 70), ('tMtToPFMETcut', 1, 1, 20, 80)] jet2panel = [('tPtcut', 1, 1, 30, 70), ('ePtcut', 1, 1, 30, 70), ('tMtToPFMETcut', 1, 1, 20, 80), ('vbfMasscut', 1, 4, 300, 700), ('vbfDetacut', 1, 1, 20, 60)] jet0refer = (30, 30, 2, 80) jet1refer = (30, 30, 80) jet2refer = (30, 30, 80, 300, 2) if (not isETight) or (not isTauTight): continue jn = row.jetVeto30 if jn > 3: jn = 3 jetlist = [(int(jn), str(int(jn)))] for jet in jetlist: foldertofill = 'os/gg/ept30/' + jet[1] + '/selected' if jets[0] == 0: for nbjet0, jetwhole0 in enumerate(jet0panel): if nbjet0 == 0 and jetwhole0[1] == 1: for j in range(jetwhole0[3], jetwhole0[4], jetwhole0[2]): if row.tPt < j: continue if row.ePt < jet0refer[1]: continue if deltaPhi(row.ePhi, row.tPhi) < jet0refer[2]: continue if row.tMtToPfMet > jet0refer[3]: continue passes_full_selection = True self.fill_histos3(jetwhole0[0], j, foldertofill, row, weight_map['']) if nbjet0 == 1 and jetwhole0[1] == 1: for j in range(jetwhole0[3], jetwhole0[4], jetwhole0[2]): if row.tPt < jet0refer[0]: continue if row.ePt < j: continue if deltaPhi(row.ePhi, row.tPhi) < jet0refer[2]: continue if row.tMtToPfMet > jet0refer[3]: continue passes_full_selection = True self.fill_histos3(jetwhole0[0], j, foldertofill, row, weight_map['']) if nbjet0 == 2 and jetwhole0[1] == 1: for j in range(jetwhole0[3], jetwhole0[4], jetwhole0[2]): if row.tPt < jet0refer[0]: continue if row.ePt < jet0refer[1]: continue if deltaPhi(row.ePhi, row.tPhi) < j / 10.0: continue if row.tMtToPfMet > jet0refer[3]: continue passes_full_selection = True self.fill_histos3(jetwhole0[0], j / 10.0, foldertofill, row, weight_map['']) if nbjet0 == 3 and jetwhole0[1] == 1: for j in range(jetwhole0[3], jetwhole0[4], jetwhole0[2]): if row.tPt < jet0refer[0]: continue if row.ePt < jet0refer[1]: continue if deltaPhi(row.ePhi, row.tPhi) < jet0refer[2]: continue if row.tMtToPfMet > j: continue passes_full_selection = True self.fill_histos3(jetwhole0[0], j, foldertofill, row, weight_map['']) elif jets[0] == 1: for nbjet1, jetwhole1 in enumerate(jet1panel): if nbjet1 == 0 and jetwhole1[1] == 1: for j in range(jetwhole1[3], jetwhole1[4], jetwhole1[2]): if row.tPt < j: continue if row.ePt < jet1refer[1]: continue if row.tMtToPfMet > jet1refer[2]: continue # selection_categories.append((name, '1', 'selected')) passes_full_selection = True self.fill_histos3(jetwhole1[0], j, foldertofill, row, weight_map['']) if nbjet1 == 1 and jetwhole1[1] == 1: for j in range(jetwhole1[3], jetwhole1[4], jetwhole1[2]): if row.tPt < jet1refer[0]: continue if row.ePt < j: continue if row.tMtToPfMet > jet1refer[2]: continue # selection_categories.append((name, '1', 'selected')) passes_full_selection = True self.fill_histos3(jetwhole1[0], j, foldertofill, row, weight_map['']) if nbjet1 == 2 and jetwhole1[1] == 1: for j in range(jetwhole1[3], jetwhole1[4], jetwhole1[2]): if row.tPt < jet1refer[0]: continue if row.ePt < jet1refer[1]: continue if row.tMtToPfMet > j: continue # selection_categories.append((name, '1', 'selected')) passes_full_selection = True self.fill_histos3(jetwhole1[0], j, foldertofill, row, weight_map['']) elif jets[0] == 2: for nbjet2, jetwhole2 in enumerate(jet2panel): if nbjet2 == 0 and jetwhole2[1] == 1: for j in range(jetwhole2[3], jetwhole2[4], jetwhole2[2]): if row.tPt < j: continue if row.ePt < jet2refer[1]: continue if row.tMtToPfMet > jet2refer[2]: continue if row.vbfMass < jet2refer[3]: continue if row.vbfDeta < jet2refer[4]: continue passes_full_selection = True self.fill_histos3(jetwhole2[0], j, foldertofill, row, weight_map['']) if nbjet2 == 1 and jetwhole2[1] == 1: for j in range(jetwhole2[3], jetwhole2[4], jetwhole2[2]): if row.tPt < jet2refer[0]: continue if row.ePt < j: continue if row.tMtToPfMet > jet2refer[2]: continue if row.vbfMass < jet2refer[3]: continue if row.vbfDeta < jet2refer[4]: continue passes_full_selection = True self.fill_histos3(jetwhole2[0], j, foldertofill, row, weight_map['']) if nbjet2 == 2 and jetwhole2[1] == 1: for j in range(jetwhole2[3], jetwhole2[4], jetwhole2[2]): if row.tPt < jet2refer[0]: continue if row.ePt < jet2refer[1]: continue if row.tMtToPfMet > j: continue if row.vbfMass < jet2refer[3]: continue if row.vbfDeta < jet2refer[4]: continue passes_full_selection = True self.fill_histos3(jetwhole2[0], j, foldertofill, row, weight_map['']) if nbjet2 == 3 and jetwhole2[1] == 1: for j in range(jetwhole2[3], jetwhole2[4], jetwhole2[2]): if row.tPt < jet2refer[0]: continue if row.ePt < jet2refer[1]: continue if row.tMtToPfMet > jet2refer[2]: continue if row.vbfMass < j: continue if row.vbfDeta < jet2refer[4]: continue passes_full_selection = True self.fill_histos3(jetwhole2[0], j, foldertofill, row, weight_map['']) if nbjet2 == 4 and jetwhole2[1] == 1: for j in range(jetwhole2[3], jetwhole2[4], jetwhole2[2]): if row.tPt < jet2refer[0]: continue if row.ePt < jet2refer[1]: continue if row.tMtToPfMet > jet2refer[2]: continue if row.vbfMass < jet2refer[3]: continue if row.vbfDeta < j / 10.0: continue passes_full_selection = True self.fill_histos3(jetwhole2[0], j / 10.0, foldertofill, row, weight_map['']) # selection_categories.append((name, '2', 'selected')) if passes_full_selection: logging.debug('Passed full selection')
def __init__(self, tree, outfile, **kwargs): logging.debug('LFVHETauAnalyzerMVA3 constructor') self.channel = 'ET' super(LFVHETauAnalyzerMVA3, self).__init__(tree, outfile, **kwargs) self.tree = ETauTree(tree) self.out = outfile self.histograms = {} #understand what we are running target = os.path.basename(os.environ['megatarget']) self.is_data = target.startswith('data_') self.is_embedded = ('Embedded' in target) self.is_mc = not (self.is_data or self.is_embedded) self.efake = e_fake_rate(0.2) self.efakeup = e_fake_rate_up(0.2) self.efakedw = e_fake_rate_dw(0.2) #systematics used self.systematics = { 'trig': (['', 'trp1s', 'trm1s'] if not self.is_data else []), 'pu': (['', 'p1s', 'm1s'] if self.is_mc else []), 'eid': (['', 'eidp1s', 'eidm1s'] if not self.is_data else []), 'eiso': (['', 'eisop1s', 'eisom1s'] if not self.is_data else []), 'jes': (['', '_jes_plus', '_jes_minus'] if self.is_mc else ['']), 'mvetos': (['', 'mVetoUp', 'mVetoDown'] if self.is_mc else ['']), 'tvetos': (['', 'tVetoUp', 'tVetoDown'] if self.is_mc else ['']), 'evetos': (['', 'eVetoUp', 'eVetoDown'] if self.is_mc else ['']), 'met': (["_mes_plus", "_ues_plus", "_mes_minus", "_ues_minus"] if self.is_mc else []), 'tes': (["", "_tes_plus", "_tes_minus"] if not self.is_data else ['']), 'ees': (["", "_ees_plus", '_ees_minus'] if not self.is_data else ['']) } #self filling histograms coll_mass = make_collmass_systematics('') #no sys shift self.histo_locations = { } #just a mapping of the histograms we have to avoid changing self.histograms indexing an screw other files self.hfunc = { #maps the name of non-trivial histograms to a function to get the proper value, the function MUST have two args (evt and weight). Used in fill_histos later 'nTruePU': lambda row, weight: (row.nTruePU, None), 'weight': lambda row, weight: (weight, None) if weight is not None else (1., None), 'Event_ID': lambda row, weight: (array.array("f", [ row.run, row.lumi, int(row.evt) / 10**5, int(row.evt) % 10**5 ]), None), 'h_collmass_pfmet': coll_mass, 'tPtcut': coll_mass, 'ePtcut': coll_mass, 'deltaPhicut': coll_mass, 'tMtToPFMETcut': coll_mass, 'vbfMasscut': coll_mass, 'vbfDetacut': coll_mass, 'h_collmass_vs_dPhi_pfmet': merge_functions(attr_getter('tToMETDPhi'), coll_mass), 'MetEt_vs_dPhi': merge_functions( lambda row, weight: (deltaPhi(row.tPhi, getattr(row, metphi())), weight), attr_getter('type1_pfMet_Et')), 'ePFMET_DeltaPhi': lambda row, weight: (deltaPhi(row.ePhi, getattr(row, metphi())), weight), 'tPFMET_DeltaPhi': lambda row, weight: (deltaPhi(row.tPhi, getattr(row, metphi())), weight), 'evtInfo': lambda row, weight: (struct( run=row.run, lumi=row.lumi, evt=row.evt, weight=weight), None) } for shift in self.systematics['met']: #patch name postfix = shift self.hfunc['h_collmass_pfmet%s' % postfix] = make_collmass_systematics(shift) for shift in self.systematics['tes']: #patch name postfix = shift self.hfunc['h_collmass_pfmet%s' % postfix] = make_collmass_systematics(shift) for shift in self.systematics['jes']: #patch name postfix = shift self.hfunc['h_collmass_pfmet%s' % postfix] = make_collmass_systematics(shift) for shift in self.systematics['ees']: #patch name postfix = shift self.hfunc['h_collmass_pfmet%s' % postfix] = make_collmass_systematics(shift) #PU correctors self.pucorrector = mcCorrections.make_shifted_weights( mcCorrections.make_puCorrector('singlee'), ['p1s', 'm1s'], [ mcCorrections.make_puCorrectorUp('singlee'), mcCorrections.make_puCorrectorDown('singlee') ]) self.trig_weight = mcCorrections.trig_efficiency if self.is_embedded else mcCorrections.trig_correction
def process(self): logging.debug('Starting processing') systematics = self.systematics frw = [] lock = () ievt = 0 logging.debug('Starting evt loop') #pre-compute static things sys_shifts = systematics['trig'] + \ systematics['pu'] + \ systematics['eid'] + \ systematics['eiso'] #+ \ jes_dirs = [i.strip('_') for i in systematics['jes']] #anyway the first is always "" tes_dirs = [i.strip('_') for i in systematics['tes']][1:] ees_dirs = [i.strip('_') for i in systematics['ees']][1:] for row in self.tree: if (ievt % 100) == 0: logging.debug('New event') ievt += 1 #avoid double counting events! evt_id = (row.run, row.lumi, row.evt) if evt_id == lock: continue if lock != () and evt_id == lock: logging.info('Removing duplicate of event: %d %d %d' % evt_id) # #preselection, common to everything and everyone # #trigger if self.is_embedded: if not bool(row.doubleMuPass): continue else: if not bool(row.singleE27WP80Pass): continue if not bool(row.eMatchesSingleE27WP80): continue #objects if not selections.eSelection(row, 'e'): continue #if row.ePt < 30 : continue if not selections.tauSelection(row, 't'): continue if not row.tAntiElectronMVA5Tight: continue if not row.tAntiMuon2Loose: continue if not row.tLooseIso3Hits: continue logging.debug('object selection passed') #e ID/ISO if not selections.lepton_id_iso(row, 'e', 'eid13Tight_idiso02'): continue logging.debug('Passed preselection') # # Compute event weight # #event weight #sys_shifts is precomputed #set_trace() weight_map = self.event_weight(row, sys_shifts) #Fill embedded sample normalization BEFORE the vetoes if not row.e_t_SS: self.fill_histos('os/gg/ept30', row, weight_map['']) # it is better vetoing on b-jets after the histo for the DY embedded #bjet veto if row.bjetCSVVeto30 == 0: continue #tau ID, id Tau is tight then go in full selection, otherwise use for fakes isTauTight = bool(row.tTightIso3Hits) isETight = bool( selections.lepton_id_iso(row, 'e', 'eid13Tight_etauiso01')) etau_category = [''] if (not isETight) and (not isTauTight): etau_category = ['etLoose', 'etLoose/Up', 'etLoose/Down'] elif (not isTauTight): etau_category = [ 'tLoose', 'tLoose/Up', 'tLoose/Down', 'tLooseUnweight' ] elif (not isETight): etau_category = ['eLoose', 'eLoose/Up', 'eLoose/Down'] #jet category central = struct( njets=2, #njets = min(row.jetVeto30, 3), tPt=row.tPt, ePt=row.ePt) #jets = [min(row.jetVeto30, 3), min(row.jetVeto30jes_plus, 3), min(row.jetVeto30jes_minus, 3)] jets = [2, 2, 2] tpts = [row.tPt_tes_plus, row.tPt_tes_minus] epts = [row.ePt_ees_plus, row.ePt_ees_minus] sys_effects = [(name, central.clone(njets=jnum)) for name, jnum in zip(jes_dirs, jets)] sys_effects.extend([(name, central.clone(tPt=pt)) for name, pt in zip(tes_dirs, tpts)]) sys_effects.extend([(name, central.clone(ePt=pt)) for name, pt in zip(ees_dirs, epts)]) # # Full tight selection # passes_full_selection = False selection_categories = [] for name, shifted in sys_effects: #preselection. flat pt values if shifted.ePt > 30 and shifted.tPt > 30: selection_categories.append( (name, '%i' % shifted.njets, '')) else: continue ##if shifted.njets == 0 : ## if shifted.tPt < 35: continue ## if shifted.ePt < 40: continue ## if deltaPhi(row.ePhi, row.tPhi) < 2.7 : continue ## if row.tMtToPfMet > 50 : continue ## selection_categories.append((name, '0', 'selected')) ## passes_full_selection = True ##elif shifted.njets == 1 : ## if shifted.tPt < 40: continue ## if shifted.ePt < 35: continue ## if row.tMtToPfMet > 35 : continue ## selection_categories.append((name, '1', 'selected')) ## passes_full_selection = True ##el if shifted.njets == 2: if shifted.tPt < 40: continue if shifted.ePt < 30: continue if row.tMtToPfMet > 35: continue if row.vbfMass < 550: continue if row.vbfDeta < 3.5: continue selection_categories.append((name, '2', 'selected')) passes_full_selection = True if passes_full_selection: logging.debug('Passed full selection') # #different selections # sign = 'ss' if row.e_t_SS else 'os' processtype = 'gg' ptthreshold = ['ept30'] # # Lepton vetoes # tvetoes = [ row.tauVetoPt20EleTight3MuLoose, row.tauVetoPt20EleTight3MuLoose_tes_plus, row.tauVetoPt20EleTight3MuLoose_tes_minus ] mvetoes = [ row.muVetoPt5IsoIdVtx, row.muVetoPt5IsoIdVtx_mes_plus, row.muVetoPt5IsoIdVtx_mes_minus ] evetoes = [ row.eVetoCicLooseIso, row.eVetoCicLooseIso_ees_plus, row.eVetoCicLooseIso_ees_minus ] tdirs = [ i for i, j in zip(systematics['tvetos'], tvetoes) if not j ] mdirs = [ i for i, j in zip(systematics['mvetos'], mvetoes) if not j ] edirs = [ i for i, j in zip(systematics['evetos'], evetoes) if not j ] #if any of the lists is empty #set_trace() if not tdirs or not mdirs or not edirs: continue logging.debug('Passed Vetoes') #make all possible veto combos... all_dirs = [ ''.join(i) for i in itertools.product(tdirs, mdirs, edirs) ] #...and choose only the meaningful ones veto_sys = set(systematics['tvetos'] + systematics['mvetos'] + systematics['evetos']) all_dirs = [i for i in all_dirs if i in veto_sys] sys_directories = all_dirs + sys_shifts #remove duplicates sys_directories = list(set(sys_directories)) #at least one loose object if (not isETight) or (not isTauTight): #if is a loose tau just compute the fakes! sys_directories = etau_category #gather the one and only weight we do care about mc_weight = weight_map[''] #weights are the fr ones... weight_map = self.fakerate_weights(row.tEta) for i in weight_map: #...times the mc weight (if any) weight_map[i] *= mc_weight #Fill histograms in appropriate direcotries #if passes_full_selection: #dirs = [os.path.join(sys, sign, processtype, e_thr, jet_dir) for sys, e_thr, jet_dir in itertools.product(sys_directories, ptthreshold, jet_directories)] #if len(dirs) <> len(set(dirs)): # set_trace() for sys, e_thr, selection in itertools.product( sys_directories, ptthreshold, selection_categories): selection_sys, jet_dir, selection_step = selection #if we have multiple systematic shifts applied #reject the combination if selection_sys and sys: continue #if we fill a histogram, lock the event lock = evt_id dir_name = os.path.join(sys, selection_sys, sign, processtype, e_thr, jet_dir, selection_step) if dir_name[-1] == '/': dir_name = dir_name[:-1] if passes_full_selection: logging.debug('Filling %s' % dir_name) #fill them! weight_to_use = weight_map[ sys] if sys in weight_map else weight_map[''] self.fill_histos(dir_name, row, weight_to_use)