def getName(self,t): """File name for the sample""" samplename = config.getSampleName(dsid=t.mcChannelNumber,root_tree=t) name = samplename['name'] isMC = samplename['isMC'] sample_key = samplename['key'] # check file in case we returned a different name tmp_r_filename = t.GetDirectory().GetName().split('/')[-1] #f.GetName().split('/')[-1] if 'noname' not in name and not tmp_r_filename.startswith(name) and not tmp_r_filename.startswith('user'): if tmp_r_filename.startswith(sample_key) and not name.startswith(sample_key): name = sample_key # ex. 'ttW_Np0' returned from config.dsid2name() but the file name # is 'ttbarV'; 'else' statement will return 'tt', not 'ttbarV' else: candidate_name = '' matched_name = '' for letter in name: matched_name+=letter if tmp_r_filename.startswith(matched_name): candidate_name = matched_name else: break candidate_name = candidate_name.replace('_','') if not candidate_name: name = tmp_r_filename.replace('.root','') # for files that start with 'user.xyz' (from the grid) if tmp_r_filename.startswith('user'): tmp_r_filename = tmp_r_filename.split(".") # to get the file ID numbers tmp_name = [piece for piece in tmp_r_filename if piece.strip('_').isdigit()] name = name+'_'+''.join(tmp_name) return name,isMC
def PMA_loop_2d_data(self,xvar,yvar): l_this_data = [] for var_data in self.data: if self.p_lepton!='muel': xvar_plot = [xx for xx in var_data[xvar][self.p_lepton]['value']] yvar_plot = [yy for yy in var_data[yvar][self.p_lepton]['value']] var_weight = var_data[xvar][self.p_lepton]['weight'] else: xvar_plot = [xx for xx in var_data[xvar]['el']['value']+var_data[xvar]['mu']['value']] yvar_plot = [yy for yy in var_data[yvar]['el']['value']+var_data[yvar]['mu']['value']] var_weight = var_data[xvar]['el']['weight']+var_data[xvar]['mu']['weight'] if self._leading['x']: xvar_lead_val = [] xvar_lead_weight = [] for vp,var_plt in enumerate(xvar_plot): try: xvar_lead_val.append( var_plt[self.xvar_entry] ) xvar_lead_weight.append( var_weight[vp][self.xvar_entry] ) except IndexError: continue xvar_plot = xvar_lead_val xvar_weight = xvar_lead_weight if self._leading['y']: yvar_lead_val = [] yvar_lead_weight = [] for vp,var_plt in enumerate(yvar_plot): try: yvar_lead_val.append( var_plt[self.yvar_entry] ) yvar_lead_weight.append( var_weight[vp][self.yvar_entry] ) except IndexError: continue yvar_plot = yvar_lead_val yvar_weight = yvar_lead_weight if not self._leading['x'] or not self._leading['y']: ## make sure the x-,y-, & weight-variables are the same length xvar_plot,yvar_plot,var_weight = self.PMA_match_variable_lengths(xvar_plot,yvar_plot,var_weight) if not self.p_scalefactor: var_weight = [1. for _ in var_weight] tmp_label = getSampleName(dsid=var_data['mcChannelNumber'])['name'] samp_label = self.plot_keys['samples'][tmp_label]['label'] l_this_data.append({'xvar':xvar_plot,'yvar':yvar_plot,\ 'weight':var_weight,\ 'label':samp_label}) return l_this_data
def main(self): """ Main function in the systematics class. Performs all of the writing to new histograms and json files """ logging.info(" Set the output paths:") logging.info(" > JSON: {0}".format(self.json_path)) logging.info(" > HIST: {0}".format(self.hist_path)) theta_nps = np.nplist() ## Mega-Loop over all of the input files ## Each systematic will have its own files for signal/ttbar/wjets/zjets/etc. ## The Scale Factor systematics are in the 'nominal' file files = open(self.p_rootfiles,'r').readlines() for file in files: file = file.rstrip('\n') logging.info(" Initializing root file: {0} ".format(file)) f = ROOT.TFile.Open(file) nuis = f.GetListOfKeys()[0].GetName() # only 1 tree and it's the systematic t = f.Get(nuis) # load the systematic tree name = config.getSampleName(root_tree=t)['name'] # the name is linked to the DSID # 'name' keeps everything up until 'pre','loose',etc. # Need to remove the systematic from the name...use another loop... for theta_np in theta_nps: if theta_np in name: name = name.split('_'+theta_np)[0] break if nuis == 'nominal': AllSystematics = np.npdict() SFsystematics = [i for key in AllSystematics.keys() if AllSystematics[key]['branch_name']] else: SFsystematics = [] if SFsystematics: ## More than 1 systematics in the nominal file, need another loop... for SFsystematic in SFsystematics: self.event_loop(kw_ttree=t,kw_name=name,kw_nuis=nuis,kw_sfsyst=SFsystematic) else: self.event_loop(kw_ttree=t,kw_name=name,kw_nuis=nuis,kw_sfsyst='')
def ROOT2json(cfg_parser): """ For converting data in the ROOT files to .json files for plotting. Increases ease-of-use for making Data/MC plots (don't have to re-process the ROOT file just to make a single plot). @param cfg_parser Object which parsed the configuration file """ logging.getLogger('share/datamc.log') loggingLEVEL = logging.getLogger().getEffectiveLevel() # DEBUG, INFO, ERROR, etc. logging.info("") logging.critical(" -- In root2json.py") logging.info(" ------------ ") logging.info(" Initializing the config file.") ## -- Configuration -- ## p_varList = cfg_parser.get('datamc','vars') # ex. 'share/varNames.txt' p_inputfiles = cfg_parser.get('datamc','rootfiles') # ex. 'share/datamc_ntuples.txt' p_lepton = cfg_parser.get('datamc','lepton') # ex. muel (both muon & electron) p_outfile = cfg_parser.get('datamc','jsonfilename') # ex. 'elLHMedium_pre_A1_1tagin' p_nEvents = int(cfg_parser.get('datamc','nEvents')) # ex. -1 ## ------------------- ## treename = info.treename() bckg_names = info.physicsSamples()['backgrounds'] savePath = "{0}/{1}".format(info.getJsonPath(),p_lepton) if not os.path.isdir(savePath): os.makedirs(savePath) logging.info(" Set the output path: {0}".format(savePath)) ## -- Load various files of data inputfiles = info.read_txt_file(p_inputfiles) if not inputfiles: print print " ERROR: File {0} is empty (no files!) ".format(p_inputfiles) print from sys import exit exit(1) i_varList = info.read_txt_file(p_varList) varList = [] for p_var in i_varList: p_var = p_var.split('[')[0] if p_var not in varList: varList.append(p_var) ## -- Loop over input files logging.info(" inputfiles = {0}".format(inputfiles)) logged_files = {} # keeping track if a sample has been used before # the list of input files may have multiple root files # for the same sample (ttbar, wjets, etc.) ## -- Make a simple text file that stores all of the json files we just made newfile = open("share/jsonfiles2plot.txt","w") for p in inputfiles: jsonData = config.AutoVivification() p_file = ROOT.TFile.Open(p) p_tree = p_file.Get(treename) p_tree.GetEntry(0) # just to get the mcChannelNumber name = config.getSampleName(root_tree=p_tree,dsid=p_tree.mcChannelNumber)['name'] # need different names from each file (otherwise different ttbar files # will overwrite each other!) ## -- load the new DataMC object if name not in logged_files.keys(): entry = DataMC_Type(name) logged_files[name] = entry for var in varList: entry.varVals[var] = [] entry.scaleFactors[var] = [] entry.lepCharges[var] = [] entry.lepNames[var] = [] else: entry = logged_files[name] print "\n ++ Producing json file from {0}\n".format(p) logging.info(" ++ Running {0}".format(name)) ## -- Attach the data (values,weights) to each DataMC object entry = addData.addData(entry, p_tree, varList, cfg_parser) # Get data from ROOT logging.info(" Exporting data to json format.") ## -- Log the DataMC object in the dictionary ## not sure that this is being used effectively... logged_files[name] = entry ## Save each json file now that we have looped over the file logging.info(" Saving json information.") outfile_name = '{0}/%s_{1}_{2}.json'.format(savePath,p_outfile,name) newfile.write("%s\n" % outfile_name) for var in varList: # put information in dictionaries to be saved to json jsonData[var][entry.name] = entry.varVals[var] jsonData[var][entry.name+'_weight'] = entry.scaleFactors[var] jsonData[var][entry.name+'_lepNames'] = entry.lepNames[var] jsonData[var]['LUMI'] = info.LUMI() print " Saving output to {0}".format(outfile_name%(var)) logging.info(" -- Saving output to {0}".format(outfile_name)) with open(outfile_name%(var),'w') as outputfile: json.dump(jsonData[var], outputfile) logging.info(" End root2json.py") return
def PMA_plot_1d(self,p1_m,p1_var): """ p1_m counter for number of vars being plotted p1_var variable being plotted """ ttree_name = self.PMA_varname2ttreename(p1_var) plot_args = {'bins':self.x_bins} ## -- Loop over the number of files that contain this variable ## (e.g., plotting ttbar vs TTS or something) for vv,var_data in enumerate(self.data): plot_args['color'] = self.colors[vv+p1_m] # increment colors based on number of vars and files if not self.leg_labels: plot_args['label'] = getSampleName(var_data['mcChannelNumber'])['name'] plot_args['label'] = plot_args['label'].replace('_',' ') else: plot_args['label'] = self.leg_labels[p1_var+'['+str(p1_m)+']'] # grab by object name # -- Efficiency plot (needs slightly different treatment - ROOT files) if self.p_plot1d_type=='efficiency': eff_c = re.search(r'\d+',self.eff_conditions[p1_m]).group() plt_data = self.PMA_efficiency(var_data,p1_var,eff_c) var_plot = plt_data['content'] self.y_err = plt_data['error'] self.x_bins = plt_data['midpts'] self.x_err = plt_data['width'] if '>' in self.eff_conditions[_m]: eff_c_text = r' $> $'+eff_c else: eff_c_text = r' = '+eff_c plot_args['label'] = self.plot_keys['variables'][ttree_name]['label']+eff_c_text plot_args['mec'] = plot_args['color'] plot_args['x'] = self.x_bins # self.x_bins represents the midpoints of each bin self.x_min = self.x_bins[0] - self.x_err[0] self.x_max = self.x_bins[-1] + self.x_err[0] eff_x_var = self.m_cfg_parser.get(self.p_cfg_name,'eff_x') # only 1 right now self.x_label = self.plot_keys['variables'][eff_x_var]['label'] self.ax.axhline(y=0.25,color='lightgray',ls='--',lw=1,zorder=0) # line at 0.75 self.ax.axhline(y=0.5 ,color='lightgray',ls='--',lw=1,zorder=0) # line at 0.75 self.ax.axhline(y=0.75,color='lightgray',ls='--',lw=1,zorder=0) # line at 0.75 self.ax.axhline(y=1.0 ,color='lightgray',ls='--',lw=1,zorder=0) # line at 1.0 self.PMA_errorbar(var_plot,plot_args) # -- Standard plot of error bars else: if self.p_lepton!='muel': var_plot = var_data[p1_var][self.p_lepton]['value'] var_weight = var_data[p1_var][self.p_lepton]['weight'] else: var_plot = var_data[p1_var]['el']['value'] + var_data[p1_var]['mu']['value'] var_weight = var_data[p1_var]['el']['weight'] + var_data[p1_var]['mu']['weight'] if self._leading: var_lead_val = [] var_lead_weight = [] for vp,var_plt in enumerate(var_plot): try: var_lead_val.append( var_plt[self.var_entry] ) var_lead_weight.append( var_weight[vp][self.var_entry] ) except IndexError: continue var_plot = var_lead_val var_weight = var_lead_weight if not self._leading: ## make sure the x- & weight-variables are the same length ## send dummy y-variables because function is 2D dummy_yvars = [] var_plot,dummy_yvars,var_weight = self.PMA_match_variable_lengths(var_plot,dummy_yvars,var_weight) if self.p_scalefactor: plot_args['weights'] = var_weight # only extend this if you're not doing a leading plot else: plot_args['weights'] = [1. for _ in var_weight] self.p_plot1d(var_plot,plot_args) self.PMA_atlas_label({'atlas':{'coords':[0.03,0.97],\ 'attr':{'fontsize':self.atlas_size,\ 'ha':'left','va':'top',\ 'transform':self.ax.transAxes}},\ 'energy_lumi':{'coords':[0.03,0.90],\ 'attr':{'fontsize':self.atlas_size,\ 'ha':'left','va':'top',\ 'transform':self.ax.transAxes}}}) return var_plot
def execute(self,parser,treename=''): """ Main function in the miniSL class -- does all the reading/writing of the flat ntuples. Just added the systematics functionality, so we've made this a hybrid class that can run over the nominal tree and trees for each systematics. @param treename The treename that we need to access for data This is now an option because of the systematics """ timeStamp = strftime("%d%b%Y",localtime()) if not treename: treename = info.treename() # 'nominal' systname = '' # for naming the output file cfg_name = 'miniSL' # which part of the config file to access else: systname = '_'+treename cfg_name = 'systematics' # which part of the config file to access ## -- Configuration -- ## p_sel_script = parser.get(cfg_name,'selection') # ex. pyMiniSL/SelectionBase.py p_nEvents = int(parser.get(cfg_name,'nEvents')) # ex. -1 p_firstEvent = int(parser.get(cfg_name,'firstevent')) # ex. 0 p_cutsfile = parser.get(cfg_name,'cutsfile') # ex. share/pre2loose_cuts.txt p_inputfile = parser.get(cfg_name,'inputfile') # ex. share/miniSL_ntuples.txt p_outputname = parser.get(cfg_name,'outputname') # ex. loose ## ------------------- ## files = open(p_inputfile,'r').readlines() sel_path,selection = p_sel_script.split('.py')[0].split('/') selClassName = selection[0].upper()+selection[1:] LUMI = info.LUMI() signalIDs = [i for key in info.dsids()['signal'].keys() for i in info.dsids()['signal'][key]] # TTS and XX signals ttbarIDs = [i for i in info.dsids()['background']['ttbar'].keys()] # Dynamic import the file without needing any hard-coding # This way, if someone makes a custom selection, this doesn't need to be changed. # Assumes that the class is the same as the filename just capitalized! pyEventFile = importlib.import_module(sel_path+"."+selection) pyEventSel = getattr(pyEventFile,selClassName) loggingLEVEL = logging.getLogger().getEffectiveLevel() logging.info(" -- In file {0}".format(os.path.basename(__file__))) logging.info(" -- Files: ") for i in files: logging.info(" "+i.rstrip('\n')) for ff,file in enumerate(files): ## Open the current file f = ROOT.TFile.Open("{0}".format(file.strip())) if not f or f.IsZombie(): print print " FILE {0} DOES NOT EXIST".format(f.GetName()) print " Continuing to next file in the loop. " print continue ## Load the TTree # For nominal, treename is an empty string # For systematics, pre2preSelection: it's the treename for a systematic # SelectionBase: it's a dummy string if treename == 'systs': treename = f.GetListOfKeys()[0].GetName() # only 1 tree and it's the systematic systname = '_'+treename elif treename != 'nominal': treename = f.GetListOfKeys()[0].GetName() # only 1 tree and it's the systematic systname = '_'+treename t = f.Get(treename) t.GetEntry(0) # to get the mcChannelNumber samplename = config.getSampleName(dsid=t.mcChannelNumber,root_tree=t) name = samplename['name'] isMC = samplename['isMC'] sample_key = samplename['key'] # check file in case we returned a different name tmp_r_filename = f.GetName().split('/')[-1] if 'noname' not in name and not tmp_r_filename.startswith(name) and not tmp_r_filename.startswith('user'): if tmp_r_filename.startswith(sample_key) and not name.startswith(sample_key): name = sample_key # ex. 'ttW_Np0' returned from config.dsid2name() but the file name # is 'ttbarV'; 'else' statement will return 'tt', not 'ttbarV' else: candidate_name = '' matched_name = '' for letter in name: matched_name+=letter if tmp_r_filename.startswith(matched_name): candidate_name = matched_name else: break if candidate_name.endswith('_'): name = candidate_name.rstrip('_') else: name = candidate_name # for files that start with 'user.xyz' (from the grid) if tmp_r_filename.startswith('user'): tmp_r_filename = tmp_r_filename.split(".") # to get the file ID numbers tmp_name = [piece for piece in tmp_r_filename if piece.strip('_').isdigit()] name = name+'_'+''.join(tmp_name) ## New File Stuff (the one to which we're writing) newfilename = "data/{0}{1}_{2}.root".format(name,systname,p_outputname) newfile = ROOT.TFile(newfilename,"RECREATE") self.newtree = ROOT.TTree(treename,"Event Information") ## Metadata pma_tag = getoutput("git describe --tags") # e.g., 'v2.0.0-20-g493beba' metadata = ROOT.TList() metadata.Add( ROOT.TObjString("Date Created: {0}".format(timeStamp)) ) metadata.Add( ROOT.TObjString("PyMiniAna: {0}".format(pma_tag)) ) metadata.Add( ROOT.TObjString("Selection: {0}".format(p_outputname)) ) metadata.Add( ROOT.TObjString("Original File:{0}".format(file.strip())) ) metadata.Add( ROOT.TObjString("Selection: {0}".format(p_outputname)) ) metadata.SetName("PyMetadata") self.newtree.GetUserInfo().Add(metadata) ## Log and print to the console before doing anything print " ++ Running over file: {0}".format(file.strip()) print " ++ Producing new file: {0}{1}_{2}.root".format(name,systname,p_outputname) logging.info(" ----") logging.info(" {0} Selection".format(p_outputname.title())) logging.info(" File: {0}".format(file.strip())) logging.info(" {0}".format(timeStamp)) logging.info(" ---- \n") # ----------------------------------------- # # Initialize the branches # # ----------------------------------------- # self.initBranches() # ----------------------------------------- # # Event Loop # # ----------------------------------------- # maxEntries = t.GetEntries() if p_nEvents < 0 or p_nEvents > maxEntries: nEvents = maxEntries logging.info(" Selected nEvents = {0}; running {1}".format(nEvents,maxEntries)) else: nEvents = p_nEvents ## -- Load the selection script evtSel = pyEventSel(t,f,parser) # imported using 'importlib' above evtSel.initialize() # setup some of the configurations ## -- While-loop (no list generation with for loop) entry = p_firstEvent # in case the user has split the file into pieces while entry < nEvents: #### -- APPLY THE SELECTION -- #### results = evtSel.event_loop(entry) vars = results['objects'] passedEvent = results['result'] #### ------------------------- #### if not passedEvent: logging.info(" ---- ") logging.info(" miniSL::Event {0} Failed Selection ".format(entry)) logging.info(" ---- ") entry+=1 # iterate entry to go to the next one continue fatJets = vars['fatjets'] rcJets = vars['rcjets'] resolvedJets = vars['resjets'] bJets = vars['bjets'] lepton = vars['lepton'] neutrino = vars['nu'] jets = vars['jets'] tjets = [] #vars['tjets'] MET = vars['met'] HT = vars['HT'] MC = vars['MC'] eventInfo = vars['eventinfo'] # ----------------------------------------- # # Fill the branches # # ----------------------------------------- # # Set the branches for each entry (element of a list) # hadtops,hadtops_subs,leptops,smallRjets,leptons,neutrinos,bTagCats self.m_isBoosted[0] = int(eventInfo['isBoosted']) self.m_isResolved[0] = int(eventInfo['isResolved']) ## boosted, hadronic W if len(fatJets) > 0: for hadW in fatJets: self.m_ljet_pt.push_back(hadW.Pt()) self.m_ljet_eta.push_back(hadW.Eta()) self.m_ljet_phi.push_back(hadW.Phi()) self.m_ljet_e.push_back(hadW.E()) self.m_ljet_m.push_back(hadW.M()) self.m_ljet_D2.push_back(hadW.D2) self.m_ljet_tau32_wta.push_back(hadW.tau32_wta) self.m_ljet_isSmoothTop50.push_back(hadW.isSmoothTop50) self.m_ljet_isSmoothTop80.push_back(hadW.isSmoothTop80) self.m_ljet_isWmed.push_back(hadW.isWmed) self.m_ljet_isWtight.push_back(hadW.isWtight) self.m_ljet_isGood.push_back(hadW.isGood) # suppress fatjet output variables. # These are extras we don't need in the analysis, # but we might need later for control plots if not self.min_fatjet_vars: self.m_ljet_track_m.push_back(hadW.track_m) self.m_ljet_track_pt.push_back(hadW.track_pt) self.m_ljet_trackjet_btag.push_back(hadW.trackjet_btag) self.m_ljet_LHtop.push_back(hadW.LHtop) self.m_ljet_LHw.push_back(hadW.LHw) self.m_ljet_C2.push_back(hadW.C2) self.m_ljet_d12.push_back(hadW.d12) self.m_ljet_d23.push_back(hadW.d23) self.m_ljet_tau1.push_back(hadW.tau1) self.m_ljet_tau2.push_back(hadW.tau2) self.m_ljet_tau3.push_back(hadW.tau3) self.m_ljet_tau21.push_back(hadW.tau21) self.m_ljet_tau32.push_back(hadW.tau32) self.m_ljet_tau1_wta.push_back(hadW.tau1_wta) self.m_ljet_tau2_wta.push_back(hadW.tau2_wta) self.m_ljet_tau3_wta.push_back(hadW.tau3_wta) self.m_ljet_tau21_wta.push_back(hadW.tau21_wta) self.m_ljet_isPtLowTop50.push_back(hadW.isPtLowTop50) self.m_ljet_isPtHighTop50.push_back(hadW.isPtHighTop50) self.m_ljet_isPtLowTop80.push_back(hadW.isPtLowTop80) self.m_ljet_isPtHighTop80.push_back(hadW.isPtHighTop80) self.m_ljet_isZmed.push_back(hadW.isZmed) self.m_ljet_isZtight.push_back(hadW.isZtight) if len(rcJets) > 0: rc_sub_pts = np.zeros(self.max_Nobjects,dtype=float) rc_sub_etas = np.zeros(self.max_Nobjects,dtype=float) rc_sub_phis = np.zeros(self.max_Nobjects,dtype=float) rc_sub_es = np.zeros(self.max_Nobjects,dtype=float) rc_sub_ms = np.zeros(self.max_Nobjects,dtype=float) rc_sub_mv2c20s = np.zeros(self.max_Nobjects,dtype=float) for hadW in rcJets: rctau = sum(s.Pt() for s in hadW.subjets) rctau = rctau / max(s.Pt() for s in hadW.subjets) self.m_rcjet_pt.push_back(hadW.Pt()) self.m_rcjet_eta.push_back(hadW.Eta()) self.m_rcjet_phi.push_back(hadW.Phi()) self.m_rcjet_e.push_back(hadW.E()) self.m_rcjet_m.push_back(hadW.M()) self.m_rcjet_D2.push_back(hadW.D2) self.m_rcjet_rctau.push_back(rctau) self.m_rcjet_nsub.push_back(len(hadW.subjets)) for s,sub in enumerate(hadW.subjets): rc_sub_pts.push_back(sub.Pt()) rc_sub_etas.push_back(sub.Eta()) rc_sub_phis.push_back(sub.Phi()) rc_sub_es.push_back(sub.E()) rc_sub_ms.push_back(sub.M()) rc_sub_mv2c20s.push_back(sub.mv2c20) self.m_rcjet_sub_pt.push_back(rc_sub_pts) self.m_rcjet_sub_eta.push_back(rc_sub_etas) self.m_rcjet_sub_phi.push_back(rc_sub_phis) self.m_rcjet_sub_e.push_back(rc_sub_es) self.m_rcjet_sub_m.push_back(rc_sub_ms) self.m_rcjet_sub_mv2c20.push_back(rc_sub_mv2c20s) # clear subjet vectors for next rcjet rc_sub_pts.resize(0) rc_sub_etas.resize(0) rc_sub_phis.resize(0) rc_sub_es.resize(0) rc_sub_ms.resize(0) rc_sub_mv2c20s.resize(0) ## resolved, hadronic W if len(resolvedJets) > 0: for hadW in resolvedJets: self.m_resolvedW_pt.push_back(hadW.Pt()) self.m_resolvedW_eta.push_back(hadW.Eta()) self.m_resolvedW_phi.push_back(hadW.Phi()) self.m_resolvedW_e.push_back(hadW.E()) self.m_resolvedW_m.push_back(hadW.M()) ## b-jets self.m_btags_n[0] = eventInfo['nbtags'] if bJets: # may not have bjets if it is pre-2-pre selection (not identified yet) for b in bJets: # Keeping only 2 jets as 'b-jets' (>=1 are actually b-tagged) self.m_bjet_pt.push_back(b.Pt()) self.m_bjet_eta.push_back(b.Eta()) self.m_bjet_phi.push_back(b.Phi()) self.m_bjet_e.push_back(b.E()) self.m_bjet_jvt.push_back(b.jvt) self.m_bjet_mv2c20.push_back(b.mv2c20) if isMC: self.m_bjet_true_flavor.push_back(b.true_flavor) else: self.m_bjet_true_flavor.push_back(-1) self.m_mass_lb[0] = (lepton+bJets[0]).M() ## Small-r jets TRF_jetFlavors = [] TRF_jetPts = [] # Needs to be in GeV! TRF_jetEtas = [] for j in jets: self.m_jet_pt.push_back(j.Pt()) self.m_jet_eta.push_back(j.Eta()) self.m_jet_phi.push_back(j.Phi()) self.m_jet_e.push_back(j.E()) self.m_jet_jvt.push_back(j.jvt) self.m_jet_mv2c20.push_back(j.mv2c20) # self.m_jet_track_m.push_back(j.track_m) # self.m_jet_track_pt.push_back(j.track_pt) self.m_jet_true_flavor.push_back(j.true_flavor) TRF_jetFlavors.append(j.true_flavor) TRF_jetPts.append(j.Pt()/1000.) # [GeV] TRF_jetEtas.append(j.Eta()) # TRF weight for the event if isMC: self.m_TRFWeight[0] = TRFWeight(TRF_jetFlavors,TRF_jetPts, TRF_jetEtas) else: self.m_TRFWeight[0] = -1. ## Track jets for j in tjets: self.m_tjet_pt.push_back(j.Pt()) self.m_tjet_eta.push_back(j.Eta()) self.m_tjet_phi.push_back(j.Phi()) self.m_tjet_e.push_back(j.E()) self.m_tjet_mv2c20.push_back(j.mv2c20) self.m_tjet_numConstituents.push_back(j.numConstituents) self.m_tjet_true_flavor.push_back(j.true_flavor) ## lepton (muon or electron) ## Just lepton branches: lep_e/m/pt self.m_ejets[0] = eventInfo['ejets'] self.m_mujets[0] = eventInfo['mujets'] self.m_lep_pt[0] = lepton.Pt() self.m_lep_eta[0] = lepton.Eta() self.m_lep_phi[0] = lepton.Phi() self.m_lep_e[0] = lepton.E() self.m_lep_charge[0] = lepton.charge ## neutrino (from W mass constraint) self.m_nu_pt[0] = neutrino.Pt() self.m_nu_eta[0] = neutrino.Eta() self.m_nu_phi[0] = neutrino.Phi() self.m_nu_e[0] = neutrino.E() ## leptonic W lepW = lepton+neutrino self.m_leptonicW_pt[0] = lepW.Pt() self.m_leptonicW_eta[0] = lepW.Eta() self.m_leptonicW_phi[0] = lepW.Phi() self.m_leptonicW_e[0] = lepW.E() self.m_leptonicW_m[0] = lepW.M() ## Build the TTbar and Hadronic W if selection!='grid2preSelection': # Only define the hadronic W candidate and TTbar # if we're beyond the pre-selection. # For users accessing the resulting root file, # TTbar and the Hadronic W will be saved if eventInfo['isBoosted']: hadW = fatJets[0] # Should only be 1 at this stage else: hadW = resolvedJets[0] TTbar = vlq.getTT(hadW,lepW,bJets) # returns dictionary of 'hadT' and 'lepT' hadT = TTbar['hadT'] # Note: These are defined for every sample, lepT = TTbar['lepT'] # not just the TT samples (there is a T and Tbar # candidate in each event that passes the cuts!) self.m_hadronicW_pt[0] = hadW.Pt() self.m_hadronicW_eta[0] = hadW.Eta() self.m_hadronicW_phi[0] = hadW.Phi() self.m_hadronicW_e[0] = hadW.E() self.m_hadronicW_m[0] = hadW.M() self.m_hadronicT_pt[0] = hadT.Pt() self.m_hadronicT_eta[0] = hadT.Eta() self.m_hadronicT_phi[0] = hadT.Phi() self.m_hadronicT_e[0] = hadT.E() self.m_hadronicT_m[0] = hadT.M() self.m_leptonicT_pt[0] = lepT.Pt() self.m_leptonicT_eta[0] = lepT.Eta() self.m_leptonicT_phi[0] = lepT.Phi() self.m_leptonicT_e[0] = lepT.E() self.m_leptonicT_m[0] = lepT.M() ## MET & HT self.m_met_met[0] = MET.met self.m_met_phi[0] = MET.phi self.m_mtw[0] = MET.mtw self.m_HT[0] = HT ## Kinematic Relationships self.m_DeltaR_lepnu[0] = lepton.DeltaR(neutrino) if selection!='grid2preSelection': self.m_minDeltaR_lepbjet[0] = min([b.DeltaR(lepton) for b in bJets]) self.m_DeltaR_bjet1bjet2[0] = bJets[0].DeltaR(bJets[1]) self.m_minDeltaR_hadWbjet[0] = min([b.DeltaR(hadW) for b in bJets]) self.m_DeltaM_hadtopleptop[0] = fabs(hadT.M() - lepT.M()) ## MC INFO -- only signal and ttbar if MC: t_t = MC['truth_t'] t_tbar = MC['truth_tbar'] t_Wp = MC['truth_wplus'] t_Wm = MC['truth_wminus'] t_b = MC['truth_b'] t_bbar = MC['truth_bbar'] t_lep = MC['truth_lep'] t_nu = MC['truth_nu'] t_q1 = MC['truth_q1'] t_q2 = MC['truth_q2'] self.m_truth_t_pt[0] = t_t.Pt() self.m_truth_t_eta[0] = t_t.Eta() self.m_truth_t_phi[0] = t_t.Phi() self.m_truth_t_e[0] = t_t.E() self.m_truth_tbar_pt[0] = t_tbar.Pt() self.m_truth_tbar_eta[0] = t_tbar.Eta() self.m_truth_tbar_phi[0] = t_tbar.Phi() self.m_truth_tbar_e[0] = t_tbar.E() self.m_truth_Wplus_pt[0] = t_Wp.Pt() self.m_truth_Wplus_eta[0] = t_Wp.Eta() self.m_truth_Wplus_phi[0] = t_Wp.Phi() self.m_truth_Wplus_e[0] = t_Wp.E() self.m_truth_Wminus_pt[0] = t_Wm.Pt() self.m_truth_Wminus_eta[0] = t_Wm.Eta() self.m_truth_Wminus_phi[0] = t_Wm.Phi() self.m_truth_Wminus_e[0] = t_Wm.E() self.m_truth_b_pt[0] = t_b.Pt() self.m_truth_b_eta[0] = t_b.Eta() self.m_truth_b_phi[0] = t_b.Phi() self.m_truth_b_e[0] = t_b.E() self.m_truth_bbar_pt[0] = t_bbar.Pt() self.m_truth_bbar_eta[0] = t_bbar.Eta() self.m_truth_bbar_phi[0] = t_bbar.Phi() self.m_truth_bbar_e[0] = t_bbar.E() self.m_truth_nu_pt[0] = t_nu.Pt() self.m_truth_nu_eta[0] = t_nu.Eta() self.m_truth_nu_phi[0] = t_nu.Phi() self.m_truth_nu_e[0] = t_nu.E() self.m_truth_nu_pdgId[0] = t_nu.pdgId self.m_truth_lep_pt[0] = t_lep.Pt() self.m_truth_lep_eta[0] = t_lep.Eta() self.m_truth_lep_phi[0] = t_lep.Phi() self.m_truth_lep_e[0] = t_lep.E() self.m_truth_lep_pdgId[0] = t_lep.pdgId self.m_truth_lep_charge[0] = t_lep.charge self.m_truth_q1_pt[0] = t_q1.Pt() self.m_truth_q1_eta[0] = t_q1.Eta() self.m_truth_q1_phi[0] = t_q1.Phi() self.m_truth_q1_e[0] = t_q1.E() self.m_truth_q1_pdgId[0] = t_q1.pdgId self.m_truth_q2_pt[0] = t_q2.Pt() self.m_truth_q2_eta[0] = t_q2.Eta() self.m_truth_q2_phi[0] = t_q2.Phi() self.m_truth_q2_e[0] = t_q2.E() self.m_truth_q2_pdgId[0] = t_q2.pdgId ## Event Info self.m_weight_mc[0] = eventInfo['mcWeight'] self.m_weight_pileup[0] = eventInfo['pileupWeight'] self.m_eventNumber[0] = eventInfo['eventNumber'] self.m_runNumber[0] = eventInfo['runNumber'] self.m_mcChannelNumber[0] = eventInfo['mcChannelNumber'] self.m_mu[0] = eventInfo['mu'] self.m_weight_btag_60[0] = eventInfo['weight_btag_60'] self.m_weight_btag_70[0] = eventInfo['weight_btag_70'] self.m_weight_btag_77[0] = eventInfo['weight_btag_77'] self.m_weight_btag_85[0] = eventInfo['weight_btag_85'] self.m_weight_lept_eff[0] = eventInfo['weight_lep_eff'] self.m_vlq_evtype[0] = eventInfo['vlq_tag'] self.m_AMI[0] = eventInfo['nAMI'] self.m_XSection[0] = eventInfo['XSection'] self.m_KFactor[0] = eventInfo['KFactor'] self.m_FilterEff[0] = eventInfo['FilterEff'] self.m_LUMI[0] = LUMI['lumi'] # Defined Above self.newtree.Fill() # ----------------------------------------- # # Clear the ROOT Vectors # # ----------------------------------------- # self.clearVectors() ## increment the while loop entry+=1 # ----------------------------------------- # # Write the new file # # ----------------------------------------- # newfile.Write() print print " New output file: {0}".format(newfilename) print " Ended at: {0}".format(strftime("%c",localtime())) print newfile.Close() return