def draw(self, region, objects, **kwargs): pad = self.pad(region) x, y = self.axes(region) if region == 'ratio' and self.ratio_range is not None: y = None draw(objects, pad=pad, xaxis=x, yaxis=y, same=True, **kwargs) if region == 'ratio': # update ratio line lengths for line in self.lines: line.SetX1(x.GetXmin()) line.SetX2(x.GetXmax())
def draw(self, region, objects, **kwargs): pad = self.pad(region) x, y = self.axes(region) if self.logy: kwargs['logy'] = True _, bounds = draw(objects, pad=pad, xaxis=x, yaxis=y, same=True, **kwargs) return bounds
def draw(self, region, objects, **kwargs): pad = self.pad(region) x, y = self.axes(region) if region == 'ratio' and self.ratio_limits is not None: y = None if region == 'main' and self.logy: kwargs['logy'] = True _, bounds = draw(objects, pad=pad, xaxis=x, yaxis=y, same=True, **kwargs) if region == 'ratio': self.update_lines() return bounds
def main(args): fileName = '/data/nawoods/lepsForSIP/lepsForSIP_M2500.root' checker = MuonCandMatchChecker('Check PF cand matching', [fileName]) checker.processSample() h = checker.hists['pfCandPt'] h.Sumw2() h.drawstyle = 'HIST' h.legendstyle = 'L' h.linewidth = 2 h.color = 'red' c = Canvas(1000, 1000) (xax, yax), lims = draw( h, c, ytitle='PF Cands', xtitle='PF Cand p_T', ) xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) c.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/matchedCandPt.png') h2 = checker.hists['pfCandPtVsGenPt'] c2 = Canvas(1000, 1000) h2.xaxis.SetTitleOffset(1.8) h2.yaxis.SetTitleOffset(1.7) h2.xaxis.SetTitleSize(0.5 * h2.xaxis.GetTitleSize()) h2.yaxis.SetTitleSize(0.5 * h2.yaxis.GetTitleSize()) h2.xaxis.SetLabelSize(0.6 * h2.xaxis.GetLabelSize()) h2.yaxis.SetLabelSize(0.6 * h2.yaxis.GetLabelSize()) h2.xaxis.SetTitle("Gen #mu p_{T}") h2.yaxis.SetTitle("PF cand p_{T}") h2.Draw("COLZ") c2.Print( '/afs/cern.ch/user/n/nawoods/www/ptStudy/matchedCandPtVsGenPt.png') print "Out of {} good muons, {} failed PF ID ({}%).".format( checker.nTot, checker.nFailPF, 100. * float(checker.nFailPF) / checker.nTot) print( "Out of those failing PF, {} shared a track with a PF charged hadron " "({}%, {}% of the total)").format( checker.nPFMatched, 100. * checker.nPFMatched / checker.nFailPF, 100. * checker.nPFMatched / checker.nTot)
def main(args): fileName = '/data/nawoods/lepsForSIP/lepsForSIP_M2500.root' checker = MuonCandMatchChecker('Check PF cand matching', [fileName]) checker.processSample() h = checker.hists['pfCandPt'] h.Sumw2() h.drawstyle = 'HIST' h.legendstyle = 'L' h.linewidth = 2 h.color = 'red' c = Canvas(1000,1000) (xax,yax), lims = draw(h, c, ytitle='PF Cands', xtitle='PF Cand p_T',) xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) c.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/matchedCandPt.png') h2 = checker.hists['pfCandPtVsGenPt'] c2 = Canvas(1000,1000) h2.xaxis.SetTitleOffset(1.8) h2.yaxis.SetTitleOffset(1.7) h2.xaxis.SetTitleSize(0.5 * h2.xaxis.GetTitleSize()) h2.yaxis.SetTitleSize(0.5 * h2.yaxis.GetTitleSize()) h2.xaxis.SetLabelSize(0.6 * h2.xaxis.GetLabelSize()) h2.yaxis.SetLabelSize(0.6 * h2.yaxis.GetLabelSize()) h2.xaxis.SetTitle("Gen #mu p_{T}") h2.yaxis.SetTitle("PF cand p_{T}") h2.Draw("COLZ") c2.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/matchedCandPtVsGenPt.png') print "Out of {} good muons, {} failed PF ID ({}%).".format(checker.nTot, checker.nFailPF, 100. * float(checker.nFailPF) / checker.nTot) print ("Out of those failing PF, {} shared a track with a PF charged hadron " "({}%, {}% of the total)").format(checker.nPFMatched, 100. * checker.nPFMatched / checker.nFailPF, 100. * checker.nPFMatched / checker.nTot)
def calc_fake_factors(name, numers_data, numers_bkg, denoms_data, denoms_bkg, labels, xtitle, ytitle, save=None, ylimits=None): assert numers_data, numers_bkg if not isinstance(numers_data, list): numers_data = [numers_data] if not isinstance(numers_bkg, list): numers_bkg = [numers_bkg] if not isinstance(denoms_data, list): denoms_data = [denoms_data] if not isinstance(denoms_bkg, list): denoms_bkg = [denoms_bkg] if save is None: save = ['pdf', 'png'] stuff = dict() objects = list() colors = [ ipyhep.style.red, ipyhep.style.blue, ipyhep.style.orange, ipyhep.style.violet, ] i_ff = 0 for numer_data, numer_bkg, denom_data, denom_bkg in zip( numers_data, numers_bkg, denoms_data, denoms_bkg): for h in (numer_data, numer_bkg, denom_data, denom_bkg): if h and not h.GetSumw2N(): h.Sumw2() h_numer = numer_data.Clone() h_numer.SetDirectory(0) if numer_bkg: set_negative_bins_zero(numer_bkg) h_numer.Add(numer_bkg, -1.0) h_denom = denom_data.Clone() h_denom.SetDirectory(0) if denom_bkg: set_negative_bins_zero(denom_bkg) h_denom.Add(denom_bkg, -1.0) h_ff = h_numer.Clone() h_ff.SetDirectory(0) divide_option = '' h_ff.Divide(h_numer, h_denom, 1.0, 1.0, divide_option) h_ff.linecolor = colors[i_ff] h_ff.markercolor = colors[i_ff] h_ff.markerstyle = 20 h_ff.markersize = 1.2 h_ff.fillstyle = ipyhep.style.fill_hollow h_ff.drawstyle = 'PE' h_ff.legendstyle = 'LP' if labels: h_ff.title = '%s' % labels[i_ff] else: h_ff.title = '%i' % i_ff h_ff.name = 'h_ff_%s' % h_ff.title stuff['h_ff_%s' % h_ff.title] = h_ff objects.append(h_ff) i_ff += 1 ## make canvas canvas = Canvas(800, 600) stuff['canvas'] = canvas xmin, xmax, ymin, ymax = get_limits(objects) xlimits = (xmin, xmax) # ylimits = (ymin, ymax) ylimits = ylimits or (0.0, 1.0) draw(objects, pad=canvas, xtitle=xtitle, ytitle=ytitle, xlimits=xlimits, ylimits=ylimits) ## legend header = '' legend = Legend(objects, pad=canvas, header=header, textsize=16, topmargin=0.02, leftmargin=0.60, rightmargin=0.02, entrysep=0.01, entryheight=0.04) legend.Draw() stuff['legend'] = legend ## save figures if save: ipyhep.file.save_figures(canvas, 'h_ff', save) ## save fake factors timestamp = time.strftime('%Y_%m_%d_%Hh%M') outfile = 'fakefactors-%s.root' % timestamp f_out = None for h_ff in objects: f_out = ipyhep.file.write(h_ff, outfile) # f_out.Close() # ipyhep.file.close_all_files() return stuff
def plot(self): evaluator = Evaluator(self.model, self.transformation, self.features) makedirs(self.plt_dir, exist_ok=True) makedirs('/'.join([self.plt_dir, 'lin']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'log']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lin', 'png']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lin', 'root']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'log', 'png']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'log', 'root']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lnt_region', 'lin']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lnt_region', 'log']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lnt_region', 'lin', 'png']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lnt_region', 'lin', 'root']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lnt_region', 'log', 'png']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'lnt_region', 'log', 'root']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'shapes', 'lin']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'shapes', 'log']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'shapes', 'lin', 'png']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'shapes', 'lin', 'root']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'shapes', 'log', 'png']), exist_ok=True) makedirs('/'.join([self.plt_dir, 'shapes', 'log', 'root']), exist_ok=True) # NN evaluator print('============> starting reading the trees') print('Plots will be stored in: ', self.plt_dir) now = time() signal = [] if self.process_signals: signal = self.get_signal_samples(self.channel, self.base_dir, self.post_fix, self.selection_data, mini=self.mini_signals) else: signal = [] data = self.get_data_samples(self.channel, self.base_dir, self.post_fix, self.selection_data) mc = self.get_mc_samples(self.channel, self.base_dir, self.post_fix, self.selection_mc) print('============> it took %.2f seconds' % (time() - now)) # evaluate FR for isample in (mc + data): #+signal): isample.df['fr'] = evaluator.evaluate(isample.df) # already corrected, ready to be applied in lnt-not-tight isample.df['fr_corr'] = isample.df['fr'] / (1. - isample.df['fr']) # apply an extra selection to the pandas dataframes if len(self.pandas_selection): for isample in (mc + data + signal): isample.df = isample.df.query(self.pandas_selection) # split the dataframe in tight and lnt-not-tight (called simply lnt for short) print('============> splitting dataframe in tight and loose not tight') for isample in (mc + data + signal): isample.df_tight = isample.df.query(self.selection_tight) if isample not in signal: isample.df_lnt = isample.df.query(self.selection_lnt) # free some mem del isample.df gc.collect() print('============> ... done') # sort depending on their position in the stack mc.sort(key=lambda x: x.position_in_stack) # now we plot self.create_canvas(self.do_ratio) for ivar in variables: variable, bins, label, xlabel, ylabel, extra_sel = ivar.var, ivar.bins, ivar.label, ivar.xlabel, ivar.ylabel, ivar.extra_selection print('plotting', label) ###################################################################################### # plot MC stacks, in tight and lnt ###################################################################################### stack_prompt = [] stack_nonprompt = [] stack_nonprompt_control = [] for imc in mc: if extra_sel: mc_df_tight = imc.df_tight.query(extra_sel) mc_df_lnt = imc.df_lnt.query(extra_sel) else: mc_df_tight = imc.df_tight mc_df_lnt = imc.df_lnt histo_tight = Hist(bins, title=imc.label, markersize=0, legendstyle='F', name=imc.datacard_name + '#' + label + '#t') weights = self.total_weight_calculator( mc_df_tight, ['weight'] + imc.extra_signal_weights, [self.lumi, imc.lumi_scaling]) histo_tight.fill_array(mc_df_tight[variable], weights=weights * self.relaxed_mc_scaling) histo_tight.fillstyle = 'solid' histo_tight.fillcolor = 'steelblue' if self.data_driven else imc.colour histo_tight.linewidth = 0 stack_prompt.append(histo_tight) # optionally remove the MC subtraction in loose-not-tight # may help if MC stats is terrible (and it often is) if self.data_driven: if self.mc_subtraction: histo_lnt = Hist(bins, title=imc.label, markersize=0, legendstyle='F', name=imc.datacard_name + '#' + label + '#lnt') weights = self.total_weight_calculator( mc_df_lnt, ['weight', 'fr_corr'] + imc.extra_signal_weights, [-1., self.lumi, imc.lumi_scaling]) histo_lnt.fill_array(mc_df_lnt[variable], weights=weights * self.relaxed_mc_scaling) histo_lnt.fillstyle = 'solid' histo_lnt.fillcolor = 'skyblue' if self.data_driven else imc.colour histo_lnt.linewidth = 0 stack_nonprompt.append(histo_lnt) histo_lnt_control = Hist(bins, title=imc.label, markersize=0, legendstyle='F', name=imc.datacard_name + '#' + label + '#lntcontrol') weights_control = self.total_weight_calculator( mc_df_lnt, ['weight'] + imc.extra_signal_weights, [self.lumi, imc.lumi_scaling]) histo_lnt_control.fill_array(mc_df_lnt[variable], weights=weights_control * self.relaxed_mc_scaling) histo_lnt_control.fillstyle = 'solid' histo_lnt_control.fillcolor = imc.colour histo_lnt_control.linewidth = 0 # print(histo_lnt_control) # print(histo_lnt_control.fillcolor) # print(imc.name, imc.colour) # print(histo_lnt_control.integral()) stack_nonprompt_control.append(histo_lnt_control) # merge different samples together (add the histograms) # prepare two temporary containers for the post-grouping histograms stack_prompt_tmp = [] stack_nonprompt_tmp = [] stack_nonprompt_control_tmp = [] for ini, fin in [(stack_prompt, stack_prompt_tmp), (stack_nonprompt, stack_nonprompt_tmp), (stack_nonprompt_control, stack_nonprompt_control_tmp)]: for k, v in groups.items(): grouped = [] for ihist in ini: if ihist.name.split('#')[0] in v: grouped.append(ihist) elif ihist.name.split('#')[0] not in togroup: fin.append(ihist) if len(grouped): group = sum(grouped) group.title = k group.name = '#'.join([k] + ihist.name.split('#')[1:]) group.fillstyle = grouped[0].fillstyle group.fillcolor = grouped[0].fillcolor group.linewidth = grouped[0].linewidth fin.append(group) stack_prompt = stack_prompt_tmp stack_nonprompt = stack_nonprompt_tmp stack_nonprompt_control = stack_nonprompt_control_tmp ###################################################################################### # plot the signals ###################################################################################### all_signals = [] signals_to_plot = [] for isig in signal: if variable not in self.datacards: if not isig.toplot: continue if variable == 'fr' or variable == 'fr_corr': continue if extra_sel: isig_df_tight = isig.df_tight.query(extra_sel) else: isig_df_tight = isig.df_tight histo_tight = Hist( bins, title=isig.label, markersize=0, legendstyle='L', name=isig.datacard_name + '#' + label ) # the "#" thing is a trick to give hists unique name, else ROOT complains weights = self.total_weight_calculator( isig_df_tight, ['weight'] + isig.extra_signal_weights, [self.lumi, isig.lumi_scaling]) histo_tight.fill_array(isig_df_tight[variable], weights=weights) histo_tight.color = isig.colour histo_tight.fillstyle = 'hollow' histo_tight.linewidth = 2 histo_tight.linestyle = 'dashed' histo_tight.drawstyle = 'HIST' all_signals.append(histo_tight) if isig.toplot: signals_to_plot.append(histo_tight) ###################################################################################### # plot the data ###################################################################################### data_prompt = [] data_nonprompt = [] data_nonprompt_control = [] for idata in data: if extra_sel: idata_df_tight = idata.df_tight.query(extra_sel) idata_df_lnt = idata.df_lnt.query(extra_sel) else: idata_df_tight = idata.df_tight idata_df_lnt = idata.df_lnt histo_tight = Hist(bins, title=idata.label, markersize=1, legendstyle='LEP') histo_tight.fill_array(idata_df_tight[variable]) data_prompt.append(histo_tight) if self.data_driven: histo_lnt = Hist(bins, title=idata.label, markersize=0, legendstyle='F') histo_lnt.fill_array(idata_df_lnt[variable], weights=idata_df_lnt.fr_corr) histo_lnt.fillstyle = 'solid' histo_lnt.fillcolor = 'skyblue' histo_lnt.linewidth = 0 histo_lnt_control = Hist(bins, title=idata.label, markersize=1, legendstyle='LEP') histo_lnt_control.fill_array(idata_df_lnt[variable]) data_nonprompt.append(histo_lnt) data_nonprompt_control.append(histo_lnt_control) if self.data_driven: # put the prompt backgrounds together all_exp_prompt = sum(stack_prompt) all_exp_prompt.title = 'prompt' # put the nonprompt backgrounds together all_exp_nonprompt = sum(stack_nonprompt + data_nonprompt) all_exp_nonprompt.fillstyle = 'solid' all_exp_nonprompt.fillcolor = 'skyblue' all_exp_nonprompt.linewidth = 0 all_exp_nonprompt.title = 'nonprompt' # create the stacks stack = HistStack([all_exp_prompt, all_exp_nonprompt], drawstyle='HIST', title='') stack_control = HistStack(stack_nonprompt_control, drawstyle='HIST', title='') else: stack = HistStack(stack_prompt, drawstyle='HIST', title='') # stat uncertainty hist_error = stack.sum #sum([all_exp_prompt, all_exp_nonprompt]) hist_error.drawstyle = 'E2' hist_error.fillstyle = '/' hist_error.color = 'gray' hist_error.title = 'stat. unc.' hist_error.legendstyle = 'F' if self.data_driven: hist_error_control = stack_control.sum hist_error_control.drawstyle = 'E2' hist_error_control.fillstyle = '/' hist_error_control.color = 'gray' hist_error_control.title = 'stat. unc.' hist_error_control.legendstyle = 'F' # put the data together all_obs_prompt = sum(data_prompt) all_obs_prompt.title = 'observed' if self.data_driven: all_obs_nonprompt_control = sum(data_nonprompt_control) all_obs_nonprompt_control.title = 'observed' all_obs_nonprompt_control.drawstyle = 'EP' # prepare the legend print(signals_to_plot) for jj in signals_to_plot: print(jj.name, jj.integral()) if len(signals_to_plot): legend = Legend([all_obs_prompt, stack, hist_error], pad=self.main_pad, leftmargin=0., rightmargin=0., topmargin=0., textfont=42, textsize=0.025, entrysep=0.01, entryheight=0.04) legend_signals = Legend(signals_to_plot, pad=self.main_pad, leftmargin=0., rightmargin=0., topmargin=0., textfont=42, textsize=0.025, entrysep=0.01, entryheight=0.04) legend_signals.SetBorderSize(0) legend_signals.x1 = 0.42 legend_signals.y1 = 0.74 legend_signals.x2 = 0.88 legend_signals.y2 = 0.90 legend_signals.SetFillColor(0) legend.SetBorderSize(0) legend.x1 = 0.2 legend.y1 = 0.74 legend.x2 = 0.45 legend.y2 = 0.90 legend.SetFillColor(0) else: legend = Legend([all_obs_prompt, stack, hist_error], pad=self.main_pad, leftmargin=0., rightmargin=0., topmargin=0., textfont=42, textsize=0.03, entrysep=0.01, entryheight=0.04) legend.SetBorderSize(0) legend.x1 = 0.55 legend.y1 = 0.74 legend.x2 = 0.88 legend.y2 = 0.90 legend.SetFillColor(0) # plot with ROOT, linear and log scale for islogy in [False, True]: things_to_plot = [stack, hist_error] if not self.blinded: things_to_plot.append(all_obs_prompt) # plot signals, as an option if self.plot_signals: things_to_plot += signals_to_plot # set the y axis range # FIXME! setting it by hand to each object as it doesn't work if passed to draw if islogy: yaxis_max = 40. * max( [ithing.max() for ithing in things_to_plot]) else: yaxis_max = 1.65 * max( [ithing.max() for ithing in things_to_plot]) if islogy: yaxis_min = 0.01 else: yaxis_min = 0. for ithing in things_to_plot: ithing.SetMaximum(yaxis_max) draw(things_to_plot, xtitle=xlabel, ytitle=ylabel, pad=self.main_pad, logy=islogy) # expectation uncertainty in the ratio pad ratio_exp_error = Hist(bins) ratio_data = Hist(bins) for ibin in hist_error.bins_range(): ratio_exp_error.set_bin_content(ibin, 1.) ratio_exp_error.set_bin_error( ibin, hist_error.get_bin_error(ibin) / hist_error.get_bin_content(ibin) if hist_error.get_bin_content(ibin) != 0. else 0.) ratio_data.set_bin_content( ibin, all_obs_prompt.get_bin_content(ibin) / hist_error.get_bin_content(ibin) if hist_error.get_bin_content(ibin) != 0. else 0.) ratio_data.set_bin_error( ibin, all_obs_prompt.get_bin_error(ibin) / hist_error.get_bin_content(ibin) if hist_error.get_bin_content(ibin) != 0. else 0.) ratio_data.drawstyle = 'EP' ratio_data.title = '' ratio_exp_error.drawstyle = 'E2' ratio_exp_error.markersize = 0 ratio_exp_error.title = '' ratio_exp_error.fillstyle = '/' ratio_exp_error.color = 'gray' for ithing in [ratio_data, ratio_exp_error]: ithing.xaxis.set_label_size( ithing.xaxis.get_label_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.yaxis.set_label_size( ithing.yaxis.get_label_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.xaxis.set_title_size( ithing.xaxis.get_title_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.yaxis.set_title_size( ithing.yaxis.get_title_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.yaxis.set_ndivisions(405) ithing.yaxis.set_title_offset(0.4) things_to_plot = [ratio_exp_error] if not self.blinded: things_to_plot.append(ratio_data) draw(things_to_plot, xtitle=xlabel, ytitle='obs/exp', pad=self.ratio_pad, logy=False, ylimits=(0.5, 1.5)) line = ROOT.TLine(min(bins), 1., max(bins), 1.) line.SetLineColor(ROOT.kBlack) line.SetLineWidth(1) self.ratio_pad.cd() line.Draw('same') # chi2_score_text = '\chi^{2}/NDF = %.1f' %(all_obs_prompt.Chi2Test(hist_error, 'UW CHI2/NDF')) chi2_score_text = 'p-value = %.2f' % (all_obs_prompt.Chi2Test( hist_error, 'UW')) chi2_score = ROOT.TLatex(0.7, 0.81, chi2_score_text) chi2_score.SetTextFont(43) chi2_score.SetTextSize(15) chi2_score.SetNDC() chi2_score.Draw('same') self.canvas.cd() # FIXME! add SS and OS channels if self.full_channel == 'mmm': channel = '\mu\mu\mu' elif self.full_channel == 'eee': channel = 'eee' elif self.full_channel == 'mem_os': channel = '\mu^{\pm}\mu^{\mp}e' elif self.full_channel == 'mem_ss': channel = '\mu^{\pm}\mu^{\pm}e' elif self.full_channel == 'eem_os': channel = 'e^{\pm}e^{\mp}\mu' elif self.full_channel == 'eem_ss': channel = 'e^{\pm}e^{\pm}\mu' else: assert False, 'ERROR: Channel not valid.' finalstate = ROOT.TLatex(0.68, 0.68, channel) finalstate.SetTextFont(43) finalstate.SetTextSize(25) finalstate.SetNDC() finalstate.Draw('same') self.canvas.cd() # remove old legend for iprim in self.canvas.primitives: if isinstance(iprim, Legend): self.canvas.primitives.remove(iprim) legend.Draw('same') if self.plot_signals: legend_signals.Draw('same') CMS_lumi(self.main_pad, 4, 0, lumi_13TeV="%d, L = %.1f fb^{-1}" % (self.year, self.lumi / 1000.)) self.canvas.Modified() self.canvas.Update() for iformat in ['pdf', 'png', 'root']: self.canvas.SaveAs('/'.join([ self.plt_dir, 'log' if islogy else 'lin', iformat if iformat != 'pdf' else '', '%s%s.%s' % (label, '_log' if islogy else '_lin', iformat) ])) # plot distributions in loose not tight # check MC contamination there if self.data_driven and variable not in ['fr', 'fr_corr']: things_to_plot = [ stack_control, hist_error_control, all_obs_nonprompt_control ] # set the y axis range # FIXME! setting it by hand to each object as it doesn't work if passed to draw if islogy: yaxis_max = 40. * max( [ithing.max() for ithing in things_to_plot]) else: yaxis_max = 1.65 * max( [ithing.max() for ithing in things_to_plot]) if islogy: yaxis_min = 0.01 else: yaxis_min = 0. for ithing in things_to_plot: ithing.SetMaximum(yaxis_max) ithing.SetMinimum(yaxis_min) draw(things_to_plot, xtitle=xlabel, ytitle=ylabel, pad=self.main_pad, logy=islogy, ylimits=(yaxis_min, yaxis_max)) new_legend = Legend( stack_control.hists + [hist_error_control, all_obs_nonprompt_control], pad=self.main_pad, leftmargin=0., rightmargin=0., topmargin=0., textfont=42, textsize=0.03, entrysep=0.01, entryheight=0.04) new_legend.SetBorderSize(0) new_legend.x1 = 0.55 new_legend.y1 = 0.71 new_legend.x2 = 0.88 new_legend.y2 = 0.90 new_legend.SetFillColor(0) # divide MC to subtract by data stack_nonprompt_control_scaled_list = [] for ihist in stack_control.hists: new_hist = copy(ihist) for ibin in new_hist.bins_range(): new_hist.SetBinContent( ibin, np.nan_to_num( np.divide( new_hist.GetBinContent(ibin), all_obs_nonprompt_control. GetBinContent(ibin)))) new_hist.SetBinError( ibin, np.nan_to_num( np.divide( new_hist.GetBinError(ibin), all_obs_nonprompt_control. GetBinContent(ibin)))) stack_nonprompt_control_scaled_list.append(new_hist) stack_control_scaled = HistStack( stack_nonprompt_control_scaled_list, drawstyle='HIST', title='') stack_control_scaled_err = stack_control_scaled.sum stack_control_scaled_err.drawstyle = 'E2' stack_control_scaled_err.fillstyle = '/' stack_control_scaled_err.color = 'gray' stack_control_scaled_err.title = 'stat. unc.' stack_control_scaled_err.legendstyle = 'F' draw([stack_control_scaled, stack_control_scaled_err], xtitle=xlabel, ytitle='MC/data', pad=self.ratio_pad, logy=False) stack_control_scaled.xaxis.set_label_size( stack_control_scaled.xaxis.get_label_size() * 3. ) # the scale should match that of the main/ratio pad size ratio stack_control_scaled.yaxis.set_label_size( stack_control_scaled.yaxis.get_label_size() * 3. ) # the scale should match that of the main/ratio pad size ratio stack_control_scaled.xaxis.set_title_size( stack_control_scaled.xaxis.get_title_size() * 3. ) # the scale should match that of the main/ratio pad size ratio stack_control_scaled.yaxis.set_title_size( stack_control_scaled.yaxis.get_title_size() * 3. ) # the scale should match that of the main/ratio pad size ratio stack_control_scaled.yaxis.set_ndivisions(405) stack_control_scaled.yaxis.set_title_offset(0.4) stack_control_scaled.SetMinimum(0.) stack_control_scaled.SetMaximum(1.5) CMS_lumi(self.main_pad, 4, 0, lumi_13TeV="%d, L = %.1f fb^{-1}" % (self.year, self.lumi / 1000.)) self.canvas.cd() # remove old legend for iprim in self.canvas.primitives: if isinstance(iprim, Legend): self.canvas.primitives.remove(iprim) # draw new legend new_legend.Draw('same') self.canvas.Modified() self.canvas.Update() for iformat in ['pdf', 'png', 'root']: self.canvas.SaveAs('/'.join([ self.plt_dir, 'lnt_region', 'log' if islogy else 'lin', iformat if iformat != 'pdf' else '', '%s%s.%s' % (label, '_log' if islogy else '_lin', iformat) ])) # compare shapes in tight and loose not tight # data in tight all_obs_prompt_norm = copy(all_obs_prompt) if all_obs_prompt_norm.integral() != 0: all_obs_prompt_norm.Scale( np.nan_to_num( np.divide(1., all_obs_prompt_norm.integral()))) #import pdb; pdb.set_trace() all_obs_prompt_norm.drawstyle = 'hist e' all_obs_prompt_norm.linecolor = 'black' all_obs_prompt_norm.markersize = 0 all_obs_prompt_norm.legendstyle = 'LE' all_obs_prompt_norm.title = '' all_obs_prompt_norm.label = 'data - tight' # data MC subtracted in loose all_obs_prompt_mc_sub_norm = copy(all_obs_prompt) all_obs_prompt_mc_sub_norm.add(all_exp_prompt, -1) all_obs_prompt_mc_sub_norm.Scale( np.nan_to_num( np.divide(1., all_obs_prompt_mc_sub_norm.integral()))) all_obs_prompt_mc_sub_norm.drawstyle = 'hist e' all_obs_prompt_mc_sub_norm.linecolor = 'green' all_obs_prompt_mc_sub_norm.markersize = 0 all_obs_prompt_mc_sub_norm.legendstyle = 'LE' all_obs_prompt_mc_sub_norm.title = '' all_obs_prompt_mc_sub_norm.label = '(data-MC) - tight' # data in loose all_obs_nonprompt_control_norm = copy( all_obs_nonprompt_control) all_obs_nonprompt_control_norm.Scale( np.nan_to_num( np.divide( 1., all_obs_nonprompt_control_norm.integral()))) all_obs_nonprompt_control_norm.drawstyle = 'hist e' all_obs_nonprompt_control_norm.linecolor = 'red' all_obs_nonprompt_control_norm.markersize = 0 all_obs_nonprompt_control_norm.legendstyle = 'LE' all_obs_nonprompt_control_norm.title = '' all_obs_nonprompt_control_norm.label = 'data - l-n-t' # data MC subtracted in loose all_obs_nonprompt_control_mc_sub_norm = copy( all_obs_nonprompt_control) all_obs_nonprompt_control_mc_sub_norm.add( stack_control.sum, -1) all_obs_nonprompt_control_mc_sub_norm.Scale( np.nan_to_num( np.divide( 1., all_obs_nonprompt_control_mc_sub_norm.integral( )))) all_obs_nonprompt_control_mc_sub_norm.drawstyle = 'hist e' all_obs_nonprompt_control_mc_sub_norm.linecolor = 'blue' all_obs_nonprompt_control_mc_sub_norm.markersize = 0 all_obs_nonprompt_control_mc_sub_norm.legendstyle = 'LE' all_obs_nonprompt_control_mc_sub_norm.title = '' all_obs_nonprompt_control_mc_sub_norm.label = '(data-MC) - l-n-t' things_to_plot = [ all_obs_prompt_norm, all_obs_prompt_mc_sub_norm, all_obs_nonprompt_control_norm, all_obs_nonprompt_control_mc_sub_norm, ] yaxis_max = max([ii.GetMaximum() for ii in things_to_plot]) draw(things_to_plot, xtitle=xlabel, ytitle=ylabel, pad=self.main_pad, logy=islogy, ylimits=(yaxis_min, 1.55 * yaxis_max)) self.canvas.cd() # remove old legend for iprim in self.canvas.primitives: if isinstance(iprim, Legend): self.canvas.primitives.remove(iprim) shape_legend = Legend([], pad=self.main_pad, leftmargin=0., rightmargin=0., topmargin=0., textfont=42, textsize=0.03, entrysep=0.01, entryheight=0.04) shape_legend.AddEntry(all_obs_prompt_norm, all_obs_prompt_norm.label, all_obs_prompt_norm.legendstyle) shape_legend.AddEntry( all_obs_prompt_mc_sub_norm, all_obs_prompt_mc_sub_norm.label, all_obs_prompt_mc_sub_norm.legendstyle) shape_legend.AddEntry( all_obs_nonprompt_control_norm, all_obs_nonprompt_control_norm.label, all_obs_nonprompt_control_norm.legendstyle) shape_legend.AddEntry( all_obs_nonprompt_control_mc_sub_norm, all_obs_nonprompt_control_mc_sub_norm.label, all_obs_nonprompt_control_mc_sub_norm.legendstyle) shape_legend.SetBorderSize(0) shape_legend.x1 = 0.50 shape_legend.y1 = 0.71 shape_legend.x2 = 0.88 shape_legend.y2 = 0.90 shape_legend.SetFillColor(0) shape_legend.Draw('same') # plot ratios all_obs_prompt_norm_ratio = copy(all_obs_prompt_norm) all_obs_prompt_mc_sub_norm_ratio = copy( all_obs_prompt_mc_sub_norm) all_obs_nonprompt_control_norm_ratio = copy( all_obs_nonprompt_control_norm) all_obs_nonprompt_control_mc_sub_norm_ratio = copy( all_obs_nonprompt_control_mc_sub_norm) all_obs_prompt_norm_ratio.Divide( all_obs_prompt_mc_sub_norm_ratio) all_obs_nonprompt_control_norm_ratio.Divide( all_obs_prompt_mc_sub_norm_ratio) all_obs_nonprompt_control_mc_sub_norm_ratio.Divide( all_obs_prompt_mc_sub_norm_ratio) things_to_plot_ratio = [ all_obs_prompt_norm_ratio, all_obs_nonprompt_control_norm_ratio, all_obs_nonprompt_control_mc_sub_norm_ratio, ] for ithing in things_to_plot_ratio: ithing.xaxis.set_label_size( ithing.xaxis.get_label_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.yaxis.set_label_size( ithing.yaxis.get_label_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.xaxis.set_title_size( ithing.xaxis.get_title_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.yaxis.set_title_size( ithing.yaxis.get_title_size() * 3. ) # the scale should match that of the main/ratio pad size ratio ithing.yaxis.set_ndivisions(405) ithing.yaxis.set_title_offset(0.4) ithing.SetMinimum(0.) ithing.SetMaximum(2.) draw(things_to_plot_ratio, xtitle=xlabel, ytitle='1/(data-MC)_{tight}', pad=self.ratio_pad, logy=False, ylimits=(0., 2.)) self.ratio_pad.cd() line.Draw('same') CMS_lumi(self.main_pad, 4, 0, lumi_13TeV="%d, L = %.1f fb^{-1}" % (self.year, self.lumi / 1000.)) self.canvas.Modified() self.canvas.Update() for iformat in ['pdf', 'png', 'root']: self.canvas.SaveAs('/'.join([ self.plt_dir, 'shapes', 'log' if islogy else 'lin', iformat if iformat != 'pdf' else '', '%s%s.%s' % (label, '_log' if islogy else '_lin', iformat) ])) # save only the datacards you want, don't flood everything if len(self.datacards) and label not in self.datacards: continue # FIXME! allow it to save datacards even for non data driven bkgs if self.data_driven: self.create_datacards(data=all_obs_prompt, bkgs={ 'prompt': all_exp_prompt, 'nonprompt': all_exp_nonprompt }, signals=all_signals, label=label)
# set visual attributes h1.fillstyle = 'solid' h1.fillcolor = 'green' h1.linecolor = 'green' h1.linewidth = 0 h2.fillstyle = 'solid' h2.fillcolor = 'red' h2.linecolor = 'red' h2.linewidth = 0 stack = HistStack([h1, h2], drawstyle='HIST E1 X0') # plot with ROOT canvas = Canvas(width=700, height=500) draw([stack, h3], xtitle='Mass', ytitle='Events', pad=canvas) # set the number of expected legend entries legend = Legend([h1, h2, h3], leftmargin=0.45, margin=0.3) legend.Draw() label = ROOT.TText(0.3, 0.8, 'ROOT') label.SetTextFont(43) label.SetTextSize(25) label.SetNDC() label.Draw() canvas.Modified() canvas.Update() # plot with matplotlib set_style('ATLAS', mpl=True) fig = plt.figure(figsize=(7, 5), dpi=100) axes = plt.axes()
def main(args): fileList = glob('/data/nawoods/lepsForSIP/*.root') files = {int(f.split('_M')[1].split('.')[0]) : f for f in fileList} checkers = {m : MuonSIPChecker('m={}'.format(m), [f]) for m,f in files.iteritems()} sipRMS = Graph(len(fileList), type='errors') sipHists = [] dxyRMS = Graph(len(fileList), type='errors') dxyHists = [] dzRMS = Graph(len(fileList), type='errors') dzHists = [] ipHists = [] ipErrHists = [] fracFailing = Graph(len(fileList), type='errors') for i, m in enumerate(sorted(files.keys())): checkers[m].processSample() checkers[m].hists['sip'].Sumw2() sipRMS.SetPoint(i, float(m), checkers[m].hists['sip'].GetRMS()) sipRMS.SetPointError(i, 0., checkers[m].hists['sip'].GetRMSError()) sipHists.append(checkers[m].hists['sip']) sipHists[-1].color = getColor(m) sipHists[-1].title = "m_{{H}} = {}".format(m) sipHists[-1].drawstyle = 'hist' sipHists[-1].legendstyle = 'L' sipHists[-1].linewidth = 2 sipHists[-1].scale(1./sipHists[-1].integral()) ipHists.append(checkers[m].hists['ip']) ipHists[-1].color = getColor(m) ipHists[-1].title = "m_{{H}} = {}".format(m) ipHists[-1].drawstyle = 'hist' ipHists[-1].legendstyle = 'L' ipHists[-1].linewidth = 2 ipHists[-1].scale(1./ipHists[-1].integral()) ipErrHists.append(checkers[m].hists['ipErr']) ipErrHists[-1].color = getColor(m) ipErrHists[-1].title = "m_{{H}} = {}".format(m) ipErrHists[-1].drawstyle = 'hist' ipErrHists[-1].legendstyle = 'L' ipErrHists[-1].linewidth = 2 ipErrHists[-1].scale(1./ipErrHists[-1].integral()) checkers[m].hists['dxy'].Sumw2() dxyRMS.SetPoint(i, float(m), checkers[m].hists['dxy'].GetRMS()) dxyRMS.SetPointError(i, 0., checkers[m].hists['dxy'].GetRMSError()) dxyHists.append(checkers[m].hists['dxy']) dxyHists[-1].color = getColor(m) dxyHists[-1].title = "m_{{H}} = {}".format(m) dxyHists[-1].drawstyle = 'hist' dxyHists[-1].legendstyle = 'L' dxyHists[-1].linewidth = 2 dxyHists[-1].scale(1./dxyHists[-1].integral()) checkers[m].hists['dz'].Sumw2() dzRMS.SetPoint(i, float(m), checkers[m].hists['dz'].GetRMS()) dzRMS.SetPointError(i, 0., checkers[m].hists['dz'].GetRMSError()) dzHists.append(checkers[m].hists['dz']) dzHists[-1].color = getColor(m) dzHists[-1].title = "m_{{H}} = {}".format(m) dzHists[-1].drawstyle = 'hist' dzHists[-1].legendstyle = 'L' dzHists[-1].linewidth = 2 dzHists[-1].scale(1./dzHists[-1].integral()) fracFailing.SetPoint(i, float(m), 1. - float(checkers[m].nPassSIP) / checkers[m].nTot) cSIP = Canvas(1000,1000) draw(sipHists, cSIP, xtitle='#frac{IP_{3D}}{#sigma_{IP_{3D}}}', ytitle='arb.') legSIP = Legend(sipHists, cSIP, textsize=.03, entrysep=0.015, leftmargin=0.6, entryheight=0.04) legSIP.Draw("same") cSIP.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/sips.png') cSIPLog = Canvas(1000,1000) draw(sipHists, cSIPLog, xtitle='#frac{IP_{3D}}{#sigma_{IP_{3D}}}', ytitle='arb.', logy=True) legSIPLog = Legend(sipHists, cSIPLog, textsize=.027, entrysep=0.012, leftmargin=0.6, entryheight=0.03) legSIPLog.Draw("same") cSIPLog.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/sipsLog.png') cSIPRMS = Canvas(1000, 1000) sipRMS.color = 'b' sipRMS.drawstyle = 'PE' sipRMS.legendstyle = 'PE' draw(sipRMS, cSIPRMS, xtitle="m_{H}", ytitle="RMS(SIP_{3D})", xlimits=(0.,2600.)) cSIPRMS.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/sipRMS.png') cIP = Canvas(1000,1000) draw(ipHists, cIP, xtitle='IP_{3D}', ytitle='arb.') legIP = Legend(ipHists, cIP, textsize=.03, entrysep=0.015, leftmargin=0.6, entryheight=0.04) legIP.Draw("same") cIP.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/ips.png') cIPLog = Canvas(1000,1000) draw(ipHists, cIPLog, xtitle='#frac{IP_{3D}}{#sigma_{IP_{3D}}}', ytitle='arb.', logy=True) legIPLog = Legend(ipHists, cIPLog, textsize=.027, entrysep=0.012, leftmargin=0.6, entryheight=0.03) legIPLog.Draw("same") cIPLog.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/ipsLog.png') cIPErr = Canvas(1000,1000) draw(ipErrHists, cIPErr, xtitle='#sigma_{IP_{3D}}', ytitle='arb.') legIPErr = Legend(ipErrHists, cIPErr, textsize=.03, entrysep=0.015, leftmargin=0.6, entryheight=0.04) legIPErr.Draw("same") cIPErr.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/ipErrs.png') cIPErrLog = Canvas(1000,1000) draw(ipErrHists, cIPErrLog, xtitle='#sigma_{IP_{3D}}', ytitle='arb.', logy=True) legIPErrLog = Legend(ipErrHists, cIPErrLog, textsize=.027, entrysep=0.012, leftmargin=0.6, entryheight=0.03) legIPErrLog.Draw("same") cIPErrLog.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/ipErrsLog.png') cFail = Canvas(1000, 1000) fracFailing.color = 'b' fracFailing.drawstyle = 'PE' fracFailing.legendstyle = 'PE' draw(fracFailing, cSIPRMS, xtitle="m_{H}", ytitle="Fraction failing SIP", xlimits=(0.,2600.)) cSIPRMS.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/fracFailing.png') cDXY = Canvas(1000,1000) draw(dxyHists, cDXY, xtitle='#Delta_{xy}', ytitle='arb.') legDXY = Legend(dxyHists, cDXY, textsize=.03, entrysep=0.015, leftmargin=0.6, entryheight=0.04) legDXY.Draw("same") cDXY.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/dxys.png') cDXYRMS = Canvas(1000, 1000) dxyRMS.color = 'b' dxyRMS.drawstyle = 'PE' dxyRMS.legendstyle = 'PE' draw(dxyRMS, cDXYRMS, xtitle="m_{H}", ytitle="RMS(#Delta_{xy})", xlimits=(0.,2600.)) cDXYRMS.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/dxyRMS.png') cDZ = Canvas(1000,1000) draw(dzHists, cDZ, xtitle='#Delta_{z}', ytitle='arb.') legDZ = Legend(dzHists, cDZ, textsize=.03, entrysep=0.015, leftmargin=0.6, entryheight=0.04) legDZ.Draw("same") cDZ.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/dzs.png') cDZRMS = Canvas(1000, 1000) dzRMS.color = 'b' dzRMS.drawstyle = 'PE' dzRMS.legendstyle = 'PE' draw(dzRMS, cDZRMS, xtitle="m_{H}", ytitle="RMS(#Delta_{z})", xlimits=(0.,2600.)) cDZRMS.Print('/afs/cern.ch/user/n/nawoods/www/sipStudy/dzRMS.png')
def pvalue_plot(poi, pvalues, pad=None, xtitle='X', ytitle='P_{0}', linestyle=None, linecolor=None, yrange=None, verbose=False): """ Draw a pvalue plot Parameters ---------- poi : list List of POI values tested pvalues : list List of p-values or list of lists of p-values to overlay multiple p-value curves pad : Canvas or Pad, optional (default=None) Pad to draw onto. Create new pad if None. xtitle : str, optional (default='X') The x-axis label (POI name) ytitle : str, optional (default='P_{0}') The y-axis label linestyle : str or list, optional (default=None) Line style for the p-value graph or a list of linestyles for multiple p-value graphs. linecolor : str or list, optional (default=None) Line color for the p-value graph or a list of linestyles for multiple p-value graphs. Returns ------- pad : Canvas The pad. graphs : list of Graph The p-value graphs """ if not pvalues: raise ValueError("pvalues is empty") if not poi: raise ValueError("poi is empty") # determine if pvalues is list or list of lists if not isinstance(pvalues[0], (list, tuple)): pvalues = [pvalues] if linecolor is not None: if not isinstance(linecolor, list): linecolor = [linecolor] linecolor = cycle(linecolor) if linestyle is not None: if not isinstance(linestyle, list): linestyle = [linestyle] linestyle = cycle(linestyle) with preserve_current_canvas(): if pad is None: pad = Canvas() pad.cd() pad.SetLogy() # create the axis min_poi, max_poi = min(poi), max(poi) haxis = Hist(1000, min_poi, max_poi) xaxis = haxis.xaxis yaxis = haxis.yaxis xaxis.SetRangeUser(min_poi, max_poi) haxis.Draw('AXIS') min_pvalue = float('inf') graphs = [] for ipv, pv in enumerate(pvalues): graph = Graph(len(poi), linestyle='dashed', drawstyle='L', linewidth=2) for idx, (point, pvalue) in enumerate(zip(poi, pv)): graph.SetPoint(idx, point, pvalue) if linestyle is not None: graph.linestyle = linestyle.next() if linecolor is not None: graph.linecolor = linecolor.next() graphs.append(graph) curr_min_pvalue = min(pv) if curr_min_pvalue < min_pvalue: min_pvalue = curr_min_pvalue if verbose: for graph in graphs: log.info(['{0:1.1f}'.format(xval) for xval in list(graph.x())]) log.info(['{0:0.3f}'.format(yval) for yval in list(graph.y())]) # automatically handles axis limits axes, bounds = draw(graphs, pad=pad, same=True, logy=True, xtitle=xtitle, ytitle=ytitle, xaxis=xaxis, yaxis=yaxis, ypadding=(0.2, 0.1), logy_crop_value=1E-300) if yrange is not None: xaxis, yaxis = axes yaxis.SetLimits(*yrange) yaxis.SetRangeUser(*yrange) min_pvalue = yrange[0] # draw sigma levels up to minimum of pvalues line = Line() line.SetLineStyle(2) line.SetLineColor(2) latex = ROOT.TLatex() latex.SetNDC(False) latex.SetTextSize(20) latex.SetTextColor(2) sigma = 0 while True: pvalue = gaussian_cdf_c(sigma) if pvalue < min_pvalue: break keepalive( pad, latex.DrawLatex(max_poi, pvalue, " {0}#sigma".format(sigma))) keepalive(pad, line.DrawLine(min_poi, pvalue, max_poi, pvalue)) sigma += 1 pad.RedrawAxis() pad.Update() return pad, graphs
stackError = _sumStack.poisson_errors() stackError.fillstyle = '/' stackError.fillcolor = 'black' stackError.drawstyle = '2' # stack.Draw('HIST') # stackError.Draw('2 [] same') objects.append(stackError) import ROOT from FireROOT.Analysis.Utils import * ROOT.gPad.SetLogy(True) draw(objects, xtitle='Some Variable [Units]', ytitle='Events', ypadding=0.05, logy=True, ylimits=(1e-3, 1e3)) print(ROOT.gStyle.GetPadTopMargin()) label = ROOT.TLatex(ROOT.gStyle.GetPadLeftMargin(), 0.9 + ROOT.gStyle.GetPadTopMargin(), 'This is a title') label.SetTextFont(43) label.SetTextAlign(11) label.SetTextSize(25) label.SetNDC() label.Draw() # canvas.Modified() # canvas.Update() canvas.Print('test2.pdf')
def addRatio(canvas, num, denom, height=0.23, ratioMin=1., ratioMax=1.4, bottomMargin=0.34, topMargin=0.06, yTitle="Ratio", mainXAxis=None, mainYAxis=None, yRange=(.95,1.3), xRange=None): newCanvas = Canvas(canvas.GetWw(), canvas.GetWh()) newCanvas.Divide(1,2) pad2 = asrootpy(newCanvas.GetPad(2)) pad2.SetPad(0.,0.,1.,height) pad2.SetBottomMargin(bottomMargin) pad2.SetTopMargin(0.) canvas.SetTopMargin(topMargin) canvas.SetBottomMargin(0.01) pad1 = asrootpy(newCanvas.GetPad(1)) pad1.SetPad(0.,height,1.,1.) pad1.SetTopMargin(topMargin) pad1.SetBottomMargin(0.01) hNum = num.clone() hNum.sumw2() numerator = Graph(hNum) hDenom = denom.clone() hDenom.sumw2() denominator = Graph(hDenom) nRemoved = 0 for i in range(numerator.GetN()): if hDenom[i+1].value <= 0. or hNum[i+1].value <= 0.: numerator.RemovePoint(i - nRemoved) denominator.RemovePoint(i - nRemoved) nRemoved += 1 ratio = numerator / denominator ratio.drawstyle = 'PE' ratio.color = 'black' unity = TLine(hNum.lowerbound(), 1, hNum.upperbound(), 1) unity.SetLineStyle(7) if yRange: ylimits = yRange else: ylimits = (1.-((ratio.GetMaximum()-1.)*.15), 1.+((ratio.GetMaximum()-1.)*1.2)) if ylimits[0] >= ylimits[1]: ylimits = (.95, 1.3) (xaxis,yaxis),axisRange = draw(ratio, pad2, ytitle=yTitle, ylimits=ylimits, xlimits=xRange) pad2.cd() unity.Draw("SAME") # correct placement of axes and label/titles if mainXAxis is not None and mainYAxis is not None: mainX = mainXAxis mainY = mainYAxis ratioX = xaxis ratioY = yaxis ratioX.title = mainX.title ratioX.SetTitleSize(mainX.GetTitleSize() * pad1.height / pad2.height) ratioX.SetLabelSize(mainX.GetLabelSize() * pad1.height / pad2.height) ratioY.SetTitleSize(mainY.GetTitleSize() * pad1.height / (2*pad2.height)) ratioY.SetTitleOffset(0.6) ratioY.SetLabelSize(mainY.GetLabelSize() * pad1.height / (2*pad2.height)) mainX.SetLabelOffset(999) mainX.SetTitleOffset(999) pad1.cd() canvas.DrawClonePad() return newCanvas
Hist(100, -5, 5, color='salmon', drawstyle='hist').FillRandom(F1('TMath::Gaus(x, 2, 1)'), 500)) stack.Add( Hist(100, -5, 5, color='powderblue', drawstyle='hist').FillRandom(F1('TMath::Gaus(x, 2, 0.6)'), 300)) objects.append(stack) # create some random histograms for i, (mu, sigma, n, c, s) in enumerate(zip(mus, sigmas, events, colors, styles)): hist = Hist(100, -5, 5, color=c, fillstyle=s, drawstyle='hist' if i % 2 == 0 else '') hist.FillRandom(F1('TMath::Gaus(x,{0},{1})'.format(mu, sigma)), n) objects.append(hist) # create a graph graph = Graph(10, drawstyle='P') for i in range(10): x = -2 + i * 4 / 10. graph.SetPoint(i, x, 40 + 10 * sin(x)) objects.append(graph) draw(objects, xtitle='Some Variable [Units]', ytitle='Events', ypadding=0.05) # see rootpy.plotting.utils.get_limits for details on what arguments are # supported for setting the axes ranges. wait()
def main(args): fileName = '/data/nawoods/lepsForSIP/lepsForSIP_M2500.root' checker = MuonPtMatchChecker('Check Pt', [fileName]) checker.processSample() hs = checker.hists.copy() for var, h in hs.iteritems(): h.Sumw2() h.drawstyle = 'HIST' h.legendstyle = 'L' h.linewidth = 2 h.color = 'red' cRes = Canvas(1000,1000) hs['pfPtRes'].color = 'black' hs['pfPtRes'].title = 'PF' hs['tunePPtResUncor'].title = 'Tune P' (xax,yax), lims = draw([hs['pfPtRes'], hs['tunePPtResUncor']], cRes, xtitle='#frac{reco p_T - gen p_T}{gen p_T}', ytitle='Muons') xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) legRes = Legend([hs['pfPtRes'], hs['tunePPtResUncor']], cRes) legRes.Draw("same") cRes.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/ptRes.png') cResComp = Canvas(1000,1000) (xax,yax), lims = draw(hs['resCompare'], cResComp, ytitle='Muons', xtitle='#frac{|PF p_T - gen p_T|}{gen p_T} - #frac{|tuneP p_T - gen p_T|}{gen p_T}') xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) cResComp.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/ptResComp.png') cResCor = Canvas(1000,1000) hs['pfPtRes'].color = 'black' hs['pfPtRes'].title = 'PF' hs['tunePPtRes'].title = 'Tune P' (xax,yax), lims = draw([hs['pfPtRes'], hs['tunePPtRes']], cResCor, xtitle='#frac{reco p_T - gen p_T}{gen p_T}', ytitle='Muons') xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) legResCor = Legend([hs['pfPtRes'], hs['tunePPtRes']], cResCor) legResCor.Draw("same") cResCor.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/ptResCor.png') cResCompCor = Canvas(1000,1000) (xax,yax), lims = draw(hs['resCompareBothCor'], cResCompCor, ytitle='Muons', xtitle='#frac{|PF p_T - gen p_T|}{gen p_T} - #frac{|tuneP p_T - gen p_T|}{gen p_T}') xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) cResCompCor.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/ptResCompCor.png') cResUncor = Canvas(1000,1000) hs['pfPtResUncor'].color = 'black' hs['pfPtResUncor'].title = 'PF' hs['tunePPtResUncor'].title = 'Tune P' (xax,yax), lims = draw([hs['pfPtResUncor'], hs['tunePPtResUncor']], cResUncor, xtitle='#frac{reco p_T - gen p_T}{gen p_T}', ytitle='Muons') xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) legResUncor = Legend([hs['pfPtResUncor'], hs['tunePPtResUncor']], cResUncor) legResUncor.Draw("same") cResUncor.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/ptResUncor.png') cResCompUncor = Canvas(1000,1000) (xax,yax), lims = draw(hs['resCompareUncor'], cResCompUncor, ytitle='Muons', xtitle='#frac{|PF p_T - gen p_T|}{gen p_T} - #frac{|tuneP p_T - gen p_T|}{gen p_T}') xax.SetTitleSize(0.4 * xax.GetTitleSize()) xax.SetTitleOffset(1.6) xax.SetLabelSize(0.7 * xax.GetLabelSize()) cResCompUncor.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/ptResCompUncor.png') hs2 = checker.hists2D.copy() hs2['pfPtResVsPt'].yaxis.title = '#frac{PF p_T - gen p_T}{gen p_T}' hs2['tunePPtResVsPt'].yaxis.title = '#frac{tuneP p_T - gen p_T}{gen p_T}' hs2['pfPtResVsPt'].yaxis.title = '#frac{|PF p_T - gen p_T|}{gen p_T} - #frac{|tuneP p_T - gen p_T|}{gen p_T}' for var, h in hs2.iteritems(): c = Canvas(1000,1000) h.xaxis.title = 'gen p_T' h.drawstyle = 'COLZ' h.xaxis.SetTitleSize(0.5 * h.xaxis.GetTitleSize()) h.xaxis.SetLabelSize(0.7 * h.xaxis.GetLabelSize()) h.xaxis.SetTitleOffset(1.4) h.yaxis.SetTitleSize(0.5 * h.yaxis.GetTitleSize()) h.yaxis.SetLabelSize(0.7 * h.yaxis.GetLabelSize()) h.yaxis.SetTitleOffset(1.4) h.draw() c.Print('/afs/cern.ch/user/n/nawoods/www/ptStudy/{}.png'.format(var))
drawstyle='hist', linewidth=2), clf, Category_VBF, 'OS_ISOL', systematics=True, mva=True) hsys = sample.GetHistoSys('QCDscale_ggH3in') nom = sample.hist.Clone(shallow=True, drawstyle='hist', color='red', fillstyle='hollow', linewidth=2) up = hsys.high.Clone(shallow=True, drawstyle='hist', color='red', linestyle='dashed', fillstyle='hollow', linewidth=2) dn = hsys.low.Clone(shallow=True, drawstyle='hist', color='red', linestyle='dotted', fillstyle='hollow', linewidth=2) canvas = Canvas() draw([nom, up, dn]) canvas.SaveAs('test_ggH3in.png')
styles = ('\\', '/', '-') canvas = Canvas() objects = [] # create a stack stack = HistStack() stack.Add(Hist(100, -5, 5, color='salmon', drawstyle='hist').FillRandom( F1('TMath::Gaus(x, 2, 1)'), 500)) stack.Add(Hist(100, -5, 5, color='powderblue', drawstyle='hist').FillRandom( F1('TMath::Gaus(x, 2, 0.6)'), 300)) objects.append(stack) # create some random histograms for i, (mu, sigma, n, c, s) in enumerate(zip(mus, sigmas, events, colors, styles)): hist = Hist(100, -5, 5, color=c, fillstyle=s, drawstyle='hist' if i % 2 == 0 else '') hist.FillRandom(F1('TMath::Gaus(x,{0},{1})'.format(mu, sigma)), n) objects.append(hist) # create a graph graph = Graph(10, drawstyle='P') for i in range(10): x = -2 + i * 4 / 10. graph.SetPoint(i, x, 40 + 10 * sin(x)) objects.append(graph) draw(objects, xtitle='Some Variable [Units]', ytitle='Events', ypadding=0.05) # see rootpy.plotting.utils.get_limits for details on what arguments are # supported for setting the axes ranges. wait()
from mva.samples import Higgs from mva.analysis import Analysis from mva.categories import Category_VBF from rootpy.plotting import Hist, Canvas from rootpy.plotting.utils import draw ana = Analysis(2012) clf = ana.get_clf(Category_VBF, load=True) h = Higgs(2012, mode='gg', systematics=True) sample = h.get_histfactory_sample( Hist(clf.binning(2012), color='red', fillstyle='hollow', drawstyle='hist', linewidth=2), clf, Category_VBF, 'OS_ISOL', systematics=True, mva=True) hsys = sample.GetHistoSys('QCDscale_ggH3in') nom = sample.hist.Clone(shallow=True, drawstyle='hist', color='red', fillstyle='hollow', linewidth=2) up = hsys.high.Clone(shallow=True, drawstyle='hist', color='red', linestyle='dashed', fillstyle='hollow', linewidth=2) dn = hsys.low.Clone(shallow=True, drawstyle='hist', color='red', linestyle='dotted', fillstyle='hollow', linewidth=2) canvas = Canvas() draw([nom, up, dn]) canvas.SaveAs('test_ggH3in.png')
# nWithFSR += 1 #print "%s: %d / %d"%(ch, nWithFSR, int(plotter.ntuples['data']['data'][ch].GetEntries())) #for gr in g.values(): # gr.yaxis.SetTitleOffset(gr.yaxis.GetTitleOffset()*0.8) # gr.yaxis.SetTitleSize(gr.yaxis.GetTitleSize()*0.9) #c.Update() if ana == 'z4l': xlimits=(40.,90.) ylimits=(0.,60.) else: xlimits=(40.,120.) ylimits=(0.,120.) c = Canvas(1000,1000) (xaxis,yaxis), things = draw(g.values(), c, xtitle='m_{\\text{Z}_1} \\, [\\text{GeV}]', ytitle='m_{\\text{Z}_2} \\, [\\text{GeV}]', xlimits=xlimits, ylimits=ylimits) yaxis.SetTitleSize(yaxis.GetTitleSize()*0.9) c.Update() leg = Legend(g.values(), c, leftmargin=0.6, textsize=0.04, header='\\text{ Data}', entrysep=0.01, entryheight=0.04) leg.Draw("same") plotter.style.setCMSStyle(c, "", True, "", 13, plotter.intLumi) c.Print('~/www/ZZPlots/mZ2VsmZ1_{}.png'.format(ana))
def stack(x, *args, **kwargs): ## parse arguments _data = kwargs.pop('data', None) _bkgs = kwargs.pop('bkgs', None) _sigs = kwargs.pop('sigs', None) _treename = kwargs.pop('treename', None) _datasearchpath = kwargs.pop('datasearchpath', None) _datadrivensearchpath = kwargs.pop('datadrivensearchpath', None) _bkgsearchpath = kwargs.pop('bkgsearchpath', None) _sigsearchpath = kwargs.pop('sigsearchpath', None) _lumi = kwargs.pop('lumi', None) global data global bkgs global sigs global treename global datasearchpath global datadrivensearchpath global bkgsearchpath global sigsearchpath global lumi data = _data or data bkgs = _bkgs or bkgs sigs = _sigs or sigs treename = _treename or treename datasearchpath = _datasearchpath or datasearchpath datadrivensearchpath = _datadrivensearchpath or datadrivensearchpath bkgsearchpath = _bkgsearchpath or bkgsearchpath sigsearchpath = _sigsearchpath or sigsearchpath if _lumi: lumi = float(_lumi) xtitle = kwargs.pop('xtitle', '') ytitle = kwargs.pop('ytitle', '') logx = bool(kwargs.pop('logx', False)) logy = bool(kwargs.pop('logy', False)) blind = kwargs.pop('blind', None) has_blinded_data = False ## save stuff to bookkeep and return stuff = dict() stuff['x'] = x ## get data histogram h_data = None if data: sp = datasearchpath # HACK: just data to True! newx = '%s::%s::%s' % (sp, treename, x) h_data = ipyhep.tree.project(newx, *args, **kwargs) if h_data: stuff['h_data'] = h_data ## blind the data? if h_data and not blind is None: if isinstance(blind, tuple): blind1, blind2 = blind nbins = h_data.GetNbinsX() for i_bin in xrange(1, nbins + 2): # skip underflow (but not overflow) xval1 = h_data.GetXaxis().GetBinLowEdge(i_bin) xval2 = h_data.GetXaxis().GetBinUpEdge(i_bin) if xval1 >= blind1 and xval2 <= blind2: h_data.SetBinContent(i_bin, 0.0) h_data.SetBinError(i_bin, 0.0) has_blinded_data = True else: nbins = h_data.GetNbinsX() for i_bin in xrange(1, nbins + 2): # skip underflow (but not overflow) xval = h_data.GetXaxis().GetBinLowEdge(i_bin) if xval >= blind: h_data.SetBinContent(i_bin, 0.0) h_data.SetBinError(i_bin, 0.0) has_blinded_data = True ## get background histograms h_bkgs = list() n_bkgs = list() if bkgs: for bkg in bkgs: if isinstance(bkg, list): h_subtotal = None for dsid in bkg: assert isinstance(dsid, str) h_bkg = None if dsid.isdigit(): ## mc backgrounds sp = bkgsearchpath % int(dsid) newx = '%s::%s::%s' % (sp, treename, x) h_bkg = ipyhep.tree.project(newx, *args, **kwargs) else: ## data-driven backgrounds assert dsid == 'fakes' or dsid == 'efakes' sp = datadrivensearchpath % dsid newx = '%s::%s::%s' % (sp, treename, x) h_bkg = ipyhep.tree.project(newx, *args, **kwargs) if h_bkg: if h_subtotal: h_subtotal.Add(h_bkg) else: h_subtotal = h_bkg.Clone() if h_subtotal: h_bkgs.append(h_subtotal) dsid = bkg[0] n_bkgs.append(dsid) else: dsid = bkg assert isinstance(dsid, str) h_bkg = None if dsid.isdigit(): ## mc backgrounds sp = bkgsearchpath % int(dsid) newx = '%s::%s::%s' % (sp, treename, x) h_bkg = ipyhep.tree.project(newx, *args, **kwargs) else: ## data-driven backgrounds assert dsid == 'fakes' or dsid == 'efakes' sp = datadrivensearchpath % dsid newx = '%s::%s::%s' % (sp, treename, x) h_bkg = ipyhep.tree.project(newx, *args, **kwargs) if h_bkg: h_bkgs.append(h_bkg) n_bkgs.append(dsid) if h_bkgs: stuff['h_bkgs'] = h_bkgs ## get signal histograms h_sigs = list() n_sigs = list() if sigs: for dsid in sigs: sp = sigsearchpath % int(dsid) newx = '%s::%s::%s' % (sp, treename, x) h_sig = ipyhep.tree.project(newx, *args, **kwargs) if h_sig: h_sigs.append(h_sig) n_sigs.append(dsid) if h_sigs: stuff['h_sigs'] = h_sigs assert h_sigs ## style data if h_data: h_data.title = 'Data' h_data.linecolor = ipyhep.style.black h_data.linewidth = 2 h_data.markercolor = ipyhep.style.black h_data.markerstyle = 20 h_data.markersize = 1.2 h_data.fillstyle = ipyhep.style.fill_hollow h_data.drawstyle = 'PE' h_data.legendstyle = 'LP' ## scale and style background histograms if h_bkgs: assert len(h_bkgs) == len(n_bkgs), '%s\n%s' % (h_bkgs, n_bkgs) for h, dsid in zip(h_bkgs, n_bkgs): sf = ipyhep.sampleops.get_sf(dsid) if dsid.isdigit(): sf *= lumi / __ntuple_lumi h.Scale(sf) h.title = ipyhep.sampleops.get_label(dsid) h.linecolor = ipyhep.style.black h.linewidth = 1 h.markercolor = ipyhep.sampleops.get_color(dsid) h.fillcolor = ipyhep.sampleops.get_color(dsid) h.fillstyle = ipyhep.style.fill_solid h.legendstyle = 'F' ## calculate stat error on total background h_bkg_total = None if h_bkgs: for h_bkg in h_bkgs: if h_bkg_total: h_bkg_total.Add(h_bkg) else: h_bkg_total = h_bkg.Clone() stuff['h_bkg_total'] = h_bkg_total ## style h_bkg_total if h_bkg_total: h_bkg_total.title = 'stat. uncert.' h_bkg_total.linecolor = ipyhep.style.black h_bkg_total.linewidth = 1 h_bkg_total.markerstyle = 0 h_bkg_total.fillcolor = ipyhep.style.dark_gray h_bkg_total.fillstyle = ipyhep.style.fill_lines h_bkg_total.drawstyle = 'E2' h_bkg_total.legendstyle = 'LF' ## scale and style signal histograms if h_sigs: assert len(h_sigs) == len(n_sigs) for h, dsid in zip(h_sigs, n_sigs): sf = ipyhep.sampleops.get_sf(dsid) sf *= lumi / __ntuple_lumi h.Scale(sf) h.title = ipyhep.sampleops.get_label(dsid) h.linecolor = ipyhep.sampleops.get_color(dsid) h.linewidth = 3 h.fillstyle = ipyhep.style.fill_hollow h.markerstyle = 0 h.drawstyle = 'HIST' h.legendstyle = 'L' ## build list of all_hists all_hists = list() main_hists = list() if h_data: all_hists.append(h_data) main_hists.append(h_data) if h_bkgs: all_hists.extend(h_bkgs) main_hists.extend(h_bkgs) if h_bkg_total: all_hists.append(h_bkg_total) main_hists.append(h_bkg_total) if h_sigs: all_hists.extend(h_sigs) ## get statistics if all_hists: stats_list = list() for h in all_hists: stats_list.extend(get_stats(h)) html = convert_table_to_html(convert_stats_to_table(stats_list)) stuff['html'] = html ## renormalize for bin widths bins = kwargs.pop('bins', None) if bins and isinstance(bins, list): for h in all_hists: renormalize_for_bin_widths(h, bins) ## stack background histograms if h_bkgs: assert len(h_bkgs) == len(n_bkgs), '%s\n%s' % (h_bkgs, n_bkgs) h_bkgs.reverse() n_bkgs.reverse() hstack = HistStack() for h in h_bkgs: hstack.Add(h) hstack.title = 'stack sum' hstack.drawstyle = 'HIST' stuff['stack'] = hstack h_bkgs.reverse() n_bkgs.reverse() # ## convert data to TGraphAsymmErrors # g_data = None # if h_data: # if __use_poissonize: # g_data = poissonize.GetPoissonizedGraph(h_data) # else: # g_data = ROOT.TGraphAsymmErrors() # i_g = 0 # nbins = h_data.GetNbinsX() # for i_bin in xrange(1, nbins+1): # skip underflow/overflow # c = h_data.GetBinContent(i_bin) # e = h_data.GetBinError(i_bin) # if c != 0.0: # g_data.SetPoint(i_g, h_data.GetBinCenter(i_bin), c) # g_ratio.SetPointError(i_g, # h_data.GetBinWidth(i_bin)/2., # h_data.GetBinWidth(i_bin)/2., # e, # e) # i_g += 1 ## build list of objects to draw objects = list() if h_bkgs: objects.append(stuff['stack']) objects.append(stuff['h_bkg_total']) if h_sigs: objects.extend(h_sigs) if h_data: objects.append(h_data) ## set xlimits and ylimits ypadding = 0.21 logy_crop_value = 7e-3 xmin, xmax, ymin, ymax = 0.0, 1.0, 0.0, 1.0 if objects: xmin, xmax, ymin, ymax = get_limits(objects, logx=logx, logy=logy, ypadding=ypadding, logy_crop_value=logy_crop_value) if logy: ymin = 7e-3 else: ymin = 0.0 xlimits = (xmin, xmax) ylimits = (ymin, ymax) stuff['xlimits'] = xlimits stuff['ylimits'] = ylimits ## remove xtitle for do_ratio _xtitle = xtitle if h_data and h_bkg_total and kwargs.get('do_ratio'): _xtitle = '' ## make canvas canvas = Canvas(800, 600) stuff['canvas'] = canvas ## draw the objects if objects: canvas.cd() draw(objects, pad=canvas, xtitle=_xtitle, ytitle=ytitle, xlimits=xlimits, ylimits=ylimits) ## set log x/y, for some reason doesn't work before draw if logx or logy: if logx: canvas.SetLogx() if logy: canvas.SetLogy() canvas.Update() ## draw blind_line if has_blinded_data: if isinstance(blind, tuple): blind_list = list(blind) else: blind_list = [blind] blind_lines = list() for bl in blind_list: line_y1 = ymin line_y2 = ymax blind_line = ROOT.TLine(bl, line_y1, bl, line_y2) blind_line.SetLineColor(ROOT.kGray + 2) blind_line.SetLineStyle(7) blind_line.SetLineWidth(2) blind_line.Draw() blind_lines.append(blind_line) stuff['blind_lines'] = blind_lines canvas.Update() ## legend lefty = True if h_bkg_total: lefty = is_left_sided(h_bkg_total) elif h_data: lefty = is_left_sided(h_data) elif h_sigs: lefty = is_left_sided(h_sigs[0]) if main_hists: header = '%.1f fb^{-1}, 13 TeV' % (lumi / 1000.0) if lefty: legend = Legend(main_hists, pad=canvas, header=header, textsize=16, topmargin=0.03, leftmargin=0.60, rightmargin=0.02, entrysep=0.01, entryheight=0.04) else: legend = Legend(main_hists, pad=canvas, header=header, textsize=16, topmargin=0.03, leftmargin=0.03, rightmargin=0.59, entrysep=0.01, entryheight=0.04) legend.Draw() stuff['legend'] = legend if h_sigs: # header = 'ATLAS Internal' header = '' if lefty: legend2 = Legend(h_sigs, pad=canvas, header=header, textsize=16, topmargin=0.03, leftmargin=0.37, rightmargin=0.23, entrysep=0.01, entryheight=0.04) else: legend2 = Legend(h_sigs, pad=canvas, header=header, textsize=16, topmargin=0.03, leftmargin=0.20, rightmargin=0.40, entrysep=0.01, entryheight=0.04) legend2.Draw() stuff['legend2'] = legend2 ## do_ratio if h_data and h_bkg_total and kwargs.get('do_ratio'): ## top canvas top_canvas = stuff.pop('canvas') stuff['top_canvas'] = top_canvas ## make SM/SM with error band: h_ratio_band i_sfratio = int(kwargs.get('sfratio', -1)) if i_sfratio < 0: # ratio plot of Data/Model h_ratio_band = h_bkg_total.Clone() nbins = h_ratio_band.GetNbinsX() for i_bin in xrange(nbins + 2): h_ratio_band.SetBinContent(i_bin, 1.0) c = h_bkg_total.GetBinContent(i_bin) e = h_bkg_total.GetBinError(i_bin) / c if c > 0.0 else 0.0 h_ratio_band.SetBinError(i_bin, e) stuff['h_ratio_band'] = h_ratio_band else: # ratio plot of Scale Factor for ith background hi = h_bkgs[i_sfratio] h_ratio_band = hi.Clone() nbins = h_ratio_band.GetNbinsX() for i_bin in xrange(nbins + 2): h_ratio_band.SetBinContent(i_bin, 1.0) c = hi.GetBinContent(i_bin) e = hi.GetBinError(i_bin) / c if c > 0.0 else 0.0 h_ratio_band.SetBinError(i_bin, e) stuff['h_ratio_band'] = h_ratio_band ## make data/(SM) h_ratio if i_sfratio < 0: h_ratio = h_data.Clone() h_ratio.Divide(h_data, h_bkg_total, 1.0, 1.0) stuff['h_ratio'] = h_ratio else: ## SF1 = 1.0 + (data - MCtot) / MC1 sfname = kwargs.get('sfname') sffile = kwargs.get('sffile') if not sfname: sfname = 'h_sf' hi = h_bkgs[i_sfratio] h_numer = h_data.Clone() h_numer.Add(h_bkg_total, -1.0) ## do the division h_ratio = h_data.Clone(sfname) h_ratio.Divide(h_numer, hi, 1.0, 1.0) ## add the 1.0 nbins = h_ratio.GetNbinsX() for i_bin in xrange(nbins + 2): c = h_ratio.GetBinContent(i_bin) h_ratio.SetBinContent(i_bin, c + 1.0) h_ratio_band.SetBinContent(i_bin, c + 1.0) ## ignore bins with no data for SF for i_bin in xrange(nbins + 2): c = h_data.GetBinContent(i_bin) if c <= 0: h_ratio.SetBinContent(i_bin, 0.0) h_ratio.SetBinError(i_bin, 0.0) h_ratio_band.SetBinError(i_bin, 0.0) stuff['h_ratio'] = h_ratio if sffile: f_out = ipyhep.file.write(h_ratio, sffile) # f_out.Close() ## convert ratio to a TGraphErrors so that Draw('E0') ## shows error bars for points off the pad g_ratio = ROOT.TGraphErrors() i_g = 0 for i_bin in xrange(1, nbins + 1): # skip underflow/overflow ratio_content = h_ratio.GetBinContent(i_bin) if ratio_content != 0.0: g_ratio.SetPoint(i_g, h_ratio.GetBinCenter(i_bin), ratio_content) g_ratio.SetPointError(i_g, h_ratio.GetBinWidth(i_bin) / 2., h_ratio.GetBinError(i_bin)) i_g += 1 else: h_ratio.SetBinError(i_bin, 0.0) stuff['g_ratio'] = g_ratio ## style ratio h_ratio_band.title = 'bkg uncert.' if i_sfratio < 0: h_ratio_band.linecolor = ipyhep.style.yellow else: h_ratio_band.linecolor = ipyhep.style.light_gray h_ratio_band.linewidth = 0 h_ratio_band.markerstyle = 0 if i_sfratio < 0: h_ratio_band.fillcolor = ipyhep.style.yellow else: h_ratio_band.linecolor = ipyhep.style.light_gray h_ratio_band.fillstyle = ipyhep.style.fill_solid h_ratio_band.drawstyle = 'E2' h_ratio_band.legendstyle = 'F' h_ratio.title = 'ratio' h_ratio.linecolor = ipyhep.style.black h_ratio.linewidth = 2 h_ratio.markercolor = ipyhep.style.black h_ratio.markerstyle = 20 h_ratio.markersize = 1.2 h_ratio.fillstyle = ipyhep.style.fill_hollow h_ratio.drawstyle = 'PE' h_ratio.legendstyle = 'LP' ## bottom canvas bottom_canvas = Canvas(800, 600) bottom_canvas.cd() stuff['bottom_canvas'] = bottom_canvas ## set ratio ylimits ratio_min = kwargs.get('ratio_min', -0.2) ratio_max = kwargs.get('ratio_max', 2.2) ratio_ylimits = (ratio_min, ratio_max) ## draw ratio band if i_sfratio < 0: _ytitle = 'Data / Model' else: hi = h_bkgs[i_sfratio] _ytitle = 'SF(%s)' % hi.title draw([h_ratio_band], pad=bottom_canvas, xtitle=xtitle, ytitle=_ytitle, xlimits=xlimits, ylimits=ratio_ylimits) ## set log x/y, for some reason doesn't work before draw? if logx: bottom_canvas.SetLogx() bottom_canvas.Update() ### make horiz lines in ratio plot every 0.5: line_ys = [ y / 10.0 for y in range(10 * int(round(ratio_min)), 10 * int(round(ratio_max)) + 5, 5) ] line_x1 = canvas.GetUxmin() line_x2 = canvas.GetUxmax() line_xwidth = abs(line_x2 - line_x1) lines = [] for line_y in line_ys: line = ROOT.TLine(line_x1 + 0.02 * line_xwidth, line_y, line_x2 - 0.02 * line_xwidth, line_y) line.SetLineWidth(1) line.SetLineStyle(7) if line_y == 1.0: line.SetLineColor(ROOT.kGray + 2) else: line.SetLineColor(ROOT.kGray + 0) line.Draw() lines.append(line) stuff['lines'] = lines ## draw blind_line if has_blinded_data: if isinstance(blind, tuple): blind_list = list(blind) else: blind_list = [blind] blind_lines = list() for bl in blind_list: line_y1 = ymin line_y2 = ymax blind_line = ROOT.TLine(bl, line_y1, bl, line_y2) blind_line.SetLineColor(ROOT.kGray + 2) blind_line.SetLineStyle(7) blind_line.SetLineWidth(2) blind_line.Draw() blind_lines.append(blind_line) stuff['blind_lines2'] = blind_lines canvas.Update() ## draw ratio g_ratio.Draw('PE0') # h_ratio.GetYaxis().SetRangeUser(ratio_min, ratio_max) # h_ratio.Draw('PE,SAME') ## shared canvas shared_canvas = Canvas(800, 800) shared_plot = plot_shared_axis(top_canvas, bottom_canvas, canvas=shared_canvas, split=0.35, axissep=0.01) stuff['canvas'] = shared_canvas canvas = shared_canvas ## save figures save = kwargs.get('save') if save is None: # NOTE: save can be False to skip saving save = ['pdf', 'png'] if save: ipyhep.file.save_figures(canvas, x, save) global results results = stuff return stuff
def pvalue_plot(poi, pvalues, pad=None, xtitle='X', ytitle='P_{0}', linestyle=None, linecolor=None, yrange=None, verbose=False): """ Draw a pvalue plot Parameters ---------- poi : list List of POI values tested pvalues : list List of p-values or list of lists of p-values to overlay multiple p-value curves pad : Canvas or Pad, optional (default=None) Pad to draw onto. Create new pad if None. xtitle : str, optional (default='X') The x-axis label (POI name) ytitle : str, optional (default='P_{0}') The y-axis label linestyle : str or list, optional (default=None) Line style for the p-value graph or a list of linestyles for multiple p-value graphs. linecolor : str or list, optional (default=None) Line color for the p-value graph or a list of linestyles for multiple p-value graphs. Returns ------- pad : Canvas The pad. graphs : list of Graph The p-value graphs """ if not pvalues: raise ValueError("pvalues is empty") if not poi: raise ValueError("poi is empty") # determine if pvalues is list or list of lists if not isinstance(pvalues[0], (list, tuple)): pvalues = [pvalues] if linecolor is not None: if not isinstance(linecolor, list): linecolor = [linecolor] linecolor = cycle(linecolor) if linestyle is not None: if not isinstance(linestyle, list): linestyle = [linestyle] linestyle = cycle(linestyle) with preserve_current_canvas(): if pad is None: pad = Canvas() pad.cd() pad.SetLogy() # create the axis min_poi, max_poi = min(poi), max(poi) haxis = Hist(1000, min_poi, max_poi) xaxis = haxis.xaxis yaxis = haxis.yaxis xaxis.SetRangeUser(min_poi, max_poi) haxis.Draw('AXIS') min_pvalue = float('inf') graphs = [] for ipv, pv in enumerate(pvalues): graph = Graph(len(poi), linestyle='dashed', drawstyle='L', linewidth=2) for idx, (point, pvalue) in enumerate(zip(poi, pv)): graph.SetPoint(idx, point, pvalue) if linestyle is not None: graph.linestyle = linestyle.next() if linecolor is not None: graph.linecolor = linecolor.next() graphs.append(graph) curr_min_pvalue = min(pv) if curr_min_pvalue < min_pvalue: min_pvalue = curr_min_pvalue if verbose: for graph in graphs: log.info(['{0:1.1f}'.format(xval) for xval in list(graph.x())]) log.info(['{0:0.3f}'.format(yval) for yval in list(graph.y())]) # automatically handles axis limits axes, bounds = draw(graphs, pad=pad, same=True, logy=True, xtitle=xtitle, ytitle=ytitle, xaxis=xaxis, yaxis=yaxis, ypadding=(0.2, 0.1), logy_crop_value=1E-300) if yrange is not None: xaxis, yaxis = axes yaxis.SetLimits(*yrange) yaxis.SetRangeUser(*yrange) min_pvalue = yrange[0] # draw sigma levels up to minimum of pvalues line = Line() line.SetLineStyle(2) line.SetLineColor(2) latex = ROOT.TLatex() latex.SetNDC(False) latex.SetTextSize(20) latex.SetTextColor(2) sigma = 0 while True: pvalue = gaussian_cdf_c(sigma) if pvalue < min_pvalue: break keepalive(pad, latex.DrawLatex(max_poi, pvalue, " {0}#sigma".format(sigma))) keepalive(pad, line.DrawLine(min_poi, pvalue, max_poi, pvalue)) sigma += 1 pad.RedrawAxis() pad.Update() return pad, graphs
hOr.scale(1./hOr.Integral()) if hNew.Integral(): hNew.scale(1./hNew.Integral()) hOr.color = 'b' hOr.drawstyle = 'LPE' hOr.legendstyle = "LPE" hLeg.color = 'r' hLeg.drawstyle = 'LPE' hLeg.legendstyle = "LPE" hNew.color = 'b' hNew.drawstyle = 'hist' cCompare = Canvas(1000,1200) (xaxis, yaxis), axisRanges = draw([hOr, hLeg], cCompare, ytitle='arb.', xtitle=xTitles[v]) legCompare = Legend([hOr, hLeg], **legPlacement[v]) legCompare.Draw("SAME") cCompare = addRatio(cCompare, hOr, hLeg, mainXAxis=xaxis, mainYAxis=yaxis, xRange=axisRanges[:2]) style.setCMSStyle(cCompare, "", True, "Preliminary Simulation", 13, -1) cCompare.Print(path.join(outdir, 'compare', '{}_m{}_{}.png'.format(v,m,c))) cNew = Canvas(1000,1000) draw(hNew, cNew, ytitle='arb', xtitle=xTitles[v]) style.setCMSStyle(cNew, "", True, "Preliminary Simulation", 13, -1) cNew.Print(path.join(outdir, 'rescued', '{}_m{}_{}.png'.format(v,m,c))) hOrQQ = Hist(*binning['sm'][v], title='\\text{qq} \\!\\! \\rightarrow \\!\\! \\text{ZZ New ID}')