def draw_hists(hists, field, category, textsize=22, logy=False, unit_area=False): xtitle = get_xtitle(field) c = Canvas() c.SetGridx() c.SetGridy() c.SetLogy(logy) if not isinstance(hists, (list, tuple)): hists = [hists] if unit_area: for h in hists: if h.integral() != 0: h /= h.integral() hists[0].xaxis.title = xtitle hists[0].yaxis.title = 'Arbitrary Unit' y_max = get_ymax(hists) hists[0].yaxis.SetRangeUser(0., 1.05 * y_max) hists[0].Draw('HIST') colors = [ 'black', 'red', 'orange', 'blue', 'green', 'purple', 'yellow', 'pink', ] if len(hists) > len(colors): colors = len(hists) * colors for hist, col in zip(hists, colors): hist.color = col hist.color = col hist.fillstyle = 'hollow' hist.markersize = 0 hist.linewidth = 2 hist.linestyle = 'solid' hist.drawstyle = 'hist E0' hist.legendstyle = 'l' hist.Draw('SAMEHIST') label = ROOT.TLatex(c.GetLeftMargin() + 0.04, 0.9, category.label) label.SetNDC() label.SetTextFont(43) label.SetTextSize(textsize) label.Draw() leg = Legend(hists, pad=c, textsize=20) # textsize=20, leftmargin=0.6, topmargin=0.6) leg.Draw('same') return c
def plot(params, rates): canvas = Canvas(width=500, height=500) draw_axes(params) draw_rates(params, rates) HGCAL_label(text='HGCAL Simulation', pad=canvas) canvas.SetLogy() canvas.RedrawAxis() canvas.Print('%s.png' % params.name) canvas.Print('%s.pdf' % params.name) canvas.Print('%s.C' % params.name)
markercolor='blue') uct_iso_efficiency = Efficiency(uct_iso_pass_vs_pu, total_vs_pu).decorate(linecolor='green', linewidth=2, markerstyle=20, markercolor='green') frame = Hist(*binning) frame.SetMaximum(1) frame.SetMinimum(0) frame.axis().SetTitle("Number of vertices") frame.axis(2).SetTitle("Efficiency (w.r.t. reco. p_{T}>40 GeV)") canvas.SetLogy(False) canvas.SetLeftMargin(0.2) frame.Draw() l1_efficiency.Draw('pe same') uct_efficiency.Draw('pe same') uct_iso_efficiency.Draw('pe same') legend = Legend(3, topmargin=0.25, leftmargin=0.25) legend.AddEntry(l1_efficiency, 'lp', 'Current Tau44') legend.AddEntry(uct_efficiency, 'lp', 'Upgrade RlxTau25 Rel. Rate %0.2f' % (9488. / 9355)) legend.AddEntry(uct_iso_efficiency, 'lp', 'Upgrade IsoTau25 Rel. Rate %0.2f' % (6224. / 9355)) legend.SetBorderSize(0) legend.SetTextSize(0.03)
dn.Draw('same hist') leg = Legend(3, pad=canvas, leftmargin=.5) leg.AddEntry(nominal, style='LEP') leg.AddEntry(up, style='L') leg.AddEntry(dn, style='L') leg.Draw() canvas.SaveAs('canvas_original.png') # Take the ratio of systematic / nominal ratio_up = up / nominal ratio_dn = dn / nominal ratio_canvas = Canvas() ratio_canvas.SetLogy() ratio_up.SetMinimum(0.001) ratio_up.Draw('hist') ratio_dn.Draw('same hist') ratio_up.xaxis.SetTitle('BDT Score') ratio_up.yaxis.SetTitle('Systematic / Nominal') ratio_canvas.SaveAs('canvas_ratio.png') # Now smooth each ratio ratio_up_smooth = ratio_up.Clone() ratio_up_smooth.Smooth(args.smooth_iterations) ratio_dn_smooth = ratio_dn.Clone() ratio_dn_smooth.Smooth(args.smooth_iterations) ratio_smooth_canvas = Canvas()
def mpe_fitting(filename, run, num_photons, use_ideal=True): run_number = int(run) if filename[-5:] == '.root': filename = filename[:-5] s_data_path = './data/%s.p' % filename if filename[:5] == 'nerix': file_identifier = filename else: file_identifier = filename[-9:] a_integral = pickle.load((open(s_data_path, 'r'))) # max_num_events used to limit amplitudes max_num_events = len(a_integral) s_path_to_save = './results/%s/' % (file_identifier) l_colors = [4, 2, 8, 7, 5, 9] + [4, 2, 8, 7, 5, 9] d_mpe_fit = {} if file_identifier == '0062_0061': d_mpe_fit['settings'] = [250, -1e6, 2e7] d_mpe_fit['bkg_mean_low'] = -1e6 d_mpe_fit['bkg_mean_high'] = 2e6 d_mpe_fit['bkg_width_low'] = 1e4 d_mpe_fit['bkg_width_high'] = 1e6 d_mpe_fit['spe_mean_low'] = 3.5e6 d_mpe_fit['spe_mean_high'] = 1e7 d_mpe_fit['spe_width_low'] = 8e5 d_mpe_fit['spe_width_high'] = 3e6 d_mpe_fit['ua_mean_low'] = 1e5 d_mpe_fit['ua_mean_high'] = 5e6 d_mpe_fit['ua_width_low'] = 1e4 d_mpe_fit['ua_width_high'] = 1e6 d_mpe_fit['spe_mean_guess'] = 6e6 d_mpe_fit['spe_width_guess'] = 1.9e6 elif file_identifier == '0066_0065': d_mpe_fit['settings'] = [250, -1e6, 1.2e7] d_mpe_fit['bkg_mean_low'] = -1e6 d_mpe_fit['bkg_mean_high'] = 2e6 d_mpe_fit['bkg_width_low'] = 1e4 d_mpe_fit['bkg_width_high'] = 1e6 d_mpe_fit['spe_mean_low'] = 2e6 d_mpe_fit['spe_mean_high'] = 6e6 d_mpe_fit['spe_width_low'] = 8e5 d_mpe_fit['spe_width_high'] = 3e6 d_mpe_fit['ua_mean_low'] = 1e5 d_mpe_fit['ua_mean_high'] = 5e6 d_mpe_fit['ua_width_low'] = 1e4 d_mpe_fit['ua_width_high'] = 1e6 d_mpe_fit['spe_mean_guess'] = 3.6e6 d_mpe_fit['spe_width_guess'] = 1.1e6 elif file_identifier == '0067_0068': d_mpe_fit['settings'] = [250, -1e6, 7.5e6] d_mpe_fit['bkg_mean_low'] = -5e5 d_mpe_fit['bkg_mean_high'] = 5e5 d_mpe_fit['bkg_width_low'] = 1e4 d_mpe_fit['bkg_width_high'] = 1e6 d_mpe_fit['spe_mean_low'] = 1.2e6 d_mpe_fit['spe_mean_high'] = 3.5e6 d_mpe_fit['spe_width_low'] = 3e5 d_mpe_fit['spe_width_high'] = 1e6 d_mpe_fit['ua_mean_low'] = 1e5 d_mpe_fit['ua_mean_high'] = 1.5e6 d_mpe_fit['ua_width_low'] = 1e4 d_mpe_fit['ua_width_high'] = 1e6 d_mpe_fit['spe_mean_guess'] = 2.1e6 d_mpe_fit['spe_width_guess'] = 6.6e5 elif file_identifier == '0071_0072': d_mpe_fit['settings'] = [250, -1e6, 3.4e7] d_mpe_fit['bkg_mean_low'] = -1e6 d_mpe_fit['bkg_mean_high'] = 2e6 d_mpe_fit['bkg_width_low'] = 1e4 d_mpe_fit['bkg_width_high'] = 1e6 d_mpe_fit['spe_mean_low'] = 7.5e6 d_mpe_fit['spe_mean_high'] = 1.4e7 d_mpe_fit['spe_width_low'] = 1e6 d_mpe_fit['spe_width_high'] = 3.5e6 d_mpe_fit['ua_mean_low'] = 1e5 d_mpe_fit['ua_mean_high'] = 5e6 d_mpe_fit['ua_width_low'] = 1e4 d_mpe_fit['ua_width_high'] = 1e6 d_mpe_fit['spe_mean_guess'] = 9.5e6 d_mpe_fit['spe_width_guess'] = 2.9e6 elif file_identifier == '0073_0074': d_mpe_fit['settings'] = [50, -1e6, 4.2e7] d_mpe_fit['bkg_mean_low'] = -1e6 d_mpe_fit['bkg_mean_high'] = 2e6 d_mpe_fit['bkg_width_low'] = 1e5 d_mpe_fit['bkg_width_high'] = 2e6 d_mpe_fit['spe_mean_low'] = 8.5e6 d_mpe_fit['spe_mean_high'] = 1.4e7 d_mpe_fit['spe_width_low'] = 1.5e6 d_mpe_fit['spe_width_high'] = 4.5e6 d_mpe_fit['ua_mean_low'] = 5e5 d_mpe_fit['ua_mean_high'] = 4e6 d_mpe_fit['ua_width_low'] = 0.5e6 d_mpe_fit['ua_width_high'] = 1e6 d_mpe_fit['spe_mean_guess'] = 9.5e6 d_mpe_fit['spe_width_guess'] = 2.9e6 elif file_identifier == 'nerix_160418_1523': d_mpe_fit['settings'] = [50, -5e5, 3.e6] d_mpe_fit['bkg_mean_low'] = -5e5 d_mpe_fit['bkg_mean_high'] = 5e5 d_mpe_fit['bkg_width_low'] = 1e4 d_mpe_fit['bkg_width_high'] = 5e5 d_mpe_fit['spe_mean_low'] = 6e5 d_mpe_fit['spe_mean_high'] = 11e5 d_mpe_fit['spe_width_low'] = 3e5 d_mpe_fit['spe_width_high'] = 9e5 d_mpe_fit['ua_mean_low'] = 1e3 d_mpe_fit['ua_mean_high'] = 5e5 d_mpe_fit['ua_width_low'] = 1e4 d_mpe_fit['ua_width_high'] = 5e5 elif file_identifier == 'nerix_160418_1531': d_mpe_fit['settings'] = [50, -5e5, 4.e6] d_mpe_fit['bkg_mean_low'] = -5e5 d_mpe_fit['bkg_mean_high'] = 5e5 d_mpe_fit['bkg_width_low'] = 1e4 d_mpe_fit['bkg_width_high'] = 5e5 d_mpe_fit['spe_mean_low'] = 6e5 d_mpe_fit['spe_mean_high'] = 11e5 d_mpe_fit['spe_width_low'] = 3e5 d_mpe_fit['spe_width_high'] = 9e5 d_mpe_fit['ua_mean_low'] = 1e3 d_mpe_fit['ua_mean_high'] = 5e5 d_mpe_fit['ua_width_low'] = 1e4 d_mpe_fit['ua_width_high'] = 5e5 else: print '\n\nSettings do not exist for given setup: %s\n\n' % (file_identifier) sys.exit() l_plots = ['plots', file_identifier] par_names = ['p0_ampl', 'mean_bkg', 'width_bkg', 'mean_spe', 'width_spe'] + ['p%d_ampl' % (i + 1) for i in xrange(num_photons)] a_integral = pickle.load((open(s_data_path, 'r'))) if use_ideal: l_mpe_fit_func = ['[5]/(2*3.14*%d*[4]**2.)**0.5*TMath::Poisson(%d, [0])*exp(-0.5/%.1f*((x - %.1f*[3])/[4])**2)' % (iElectron, iElectron, iElectron, iElectron) for iElectron in xrange(1, num_photons + 1)] else: l_mpe_fit_func = ['[5]/(2*3.14*([2]**2. + %d*[4]**2.))**0.5*TMath::Poisson(%d, [0])*exp(-0.5*((x - %.1f*[3] - [1])/(%.1f*[4]**2 + [2]**2)**0.5)**2)' % (iElectron, iElectron, iElectron, iElectron) for iElectron in xrange(1, num_photons + 1)] h_mpe_spec = Hist(*d_mpe_fit['settings'], name='h_mpe_spec', title='MPE Spectrum with Gaussian Fit - %s' % filename) h_mpe_spec.SetMarkerSize(0) h_mpe_spec.fill_array(a_integral) c1 = Canvas() h_mpe_spec.Draw() s_bkg = '[5]/(2*3.14*[2]**2.)**0.5*TMath::Poisson(0, [0])*exp(-0.5*((x - [1])/[2])**2)' s_under_amplified = '[6]/(2*3.14*[8]**2.)**0.5*exp(-0.5*((x - [7])/[8])**2)' s_fit_mpe = '(%s) + (%s) + (%s)' % (s_bkg, s_under_amplified, ' + '.join(l_mpe_fit_func)) s_fit_mpe = '(%s)*([1] < [3] ? 1. : 0.)*([1] < [7] ? 1. : 0.)*([7] < [3] ? 1. : 0.)' % (s_fit_mpe) fit_mpe = root.TF1('fit_mpe', s_fit_mpe, *d_mpe_fit['settings'][1:]) fit_mpe.SetLineColor(46) fit_mpe.SetLineStyle(2) fit_mpe.SetLineWidth(3) h_mpe_spec.GetXaxis().SetTitle('Integrated Charge [e-]') h_mpe_spec.GetYaxis().SetTitle('Counts') h_mpe_spec.GetYaxis().SetTitleOffset(1.4) h_mpe_spec.SetStats(0) c1.SetLogy() fit_mpe.SetParLimits(0, 0.9, 2.5) fit_mpe.SetParameter(0, 1.3) fit_mpe.SetParLimits(1, d_mpe_fit['bkg_mean_low'], d_mpe_fit['bkg_mean_high']) fit_mpe.SetParameter(1, (d_mpe_fit['bkg_mean_low']+d_mpe_fit['bkg_mean_high'])/2.) fit_mpe.SetParLimits(2, d_mpe_fit['bkg_width_low'], d_mpe_fit['bkg_width_high']) fit_mpe.SetParameter(2, (d_mpe_fit['bkg_width_low']+d_mpe_fit['bkg_width_high'])/2.) fit_mpe.SetParLimits(3, d_mpe_fit['spe_mean_low'], d_mpe_fit['spe_mean_high']) fit_mpe.SetParameter(3, d_mpe_fit['spe_mean_guess']) fit_mpe.SetParLimits(4, d_mpe_fit['spe_width_low'], d_mpe_fit['spe_width_high']) fit_mpe.SetParameter(4, d_mpe_fit['spe_width_guess']) fit_mpe.SetParLimits(5, 10, max_num_events*1e6) fit_mpe.SetParameter(5, (10+max_num_events*1e6)/2.) fit_mpe.SetParLimits(6, 10, max_num_events*1e6) fit_mpe.SetParameter(6, (10+max_num_events*1e6)/2.) fit_mpe.SetParLimits(7, d_mpe_fit['ua_mean_low'], d_mpe_fit['ua_mean_high']) fit_mpe.SetParameter(7, (d_mpe_fit['ua_mean_low']+d_mpe_fit['ua_mean_high'])/2.) fit_mpe.SetParLimits(8, d_mpe_fit['ua_width_low'], d_mpe_fit['ua_width_high']) fit_mpe.SetParameter(8, (d_mpe_fit['ua_width_low']+d_mpe_fit['ua_width_high'])/2.) """ for i, guess in enumerate(mpe_par_guesses): fit_mpe.SetParameter(i, guess) for i in xrange(len(par_names)): fit_mpe.SetParName(i, par_names[i]) for photon in xrange(num_photons): fit_mpe.SetParLimits(5 + photon, 0, max_num_events) """ fitResult = h_mpe_spec.Fit('fit_mpe', 'MILES') # draw individual peaks s_gaussian = '[0]*exp(-0.5/%.1f*((x - %.1f*[1])/[2])**2)' l_functions = [] l_individual_integrals = [0. for i in xrange(num_photons+2)] for i in xrange(num_photons + 2): l_functions.append(root.TF1('peak_%d' % i, '[0]*exp(-0.5*((x - [1])/[2])**2)', *d_mpe_fit['settings'][1:])) # set parameters if i == 0: ampl = fit_mpe.GetParameter(5)*root.TMath.Poisson(0, fit_mpe.GetParameter(0)) mean = fit_mpe.GetParameter(1) width = fit_mpe.GetParameter(2) if width > 0: ampl /= (2*3.14*width**2.)**0.5 l_functions[i].SetParameters(ampl, mean, width) # under amplified peak elif i == (num_photons + 1): ampl = fit_mpe.GetParameter(6) mean = fit_mpe.GetParameter(7) width = fit_mpe.GetParameter(8) if width > 0: ampl /= (2*3.14*width**2.)**0.5 l_functions[i].SetParameters(ampl, mean, width) else: ampl = fit_mpe.GetParameter(5)*root.TMath.Poisson(i, fit_mpe.GetParameter(0)) if use_ideal: mean = fit_mpe.GetParameter(3) * i width = fit_mpe.GetParameter(4)*i**0.5 else: mean = fit_mpe.GetParameter(3)*i + fit_mpe.GetParameter(1) width = (fit_mpe.GetParameter(4)**2*i + fit_mpe.GetParameter(2)**2)**0.5 if width > 0: ampl /= (2*3.14*width**2.)**0.5 l_functions[i].SetParameters(ampl, mean, width) l_individual_integrals[i] = ampl*width*(2*3.1415)**0.5 l_functions[i].SetLineColor(l_colors[i]) l_functions[i].Draw('same') c1.Update() fitStatus = fitResult.CovMatrixStatus() if fitStatus != 3: neriX_analysis.failure_message('Fit failed, please adjust guesses and try again.') fit_successful = False else: neriX_analysis.success_message('Fit successful, please copy output to appropriate files.') fit_successful = True #if not os.path.exists(sPathToSaveOutput): # os.makedirs(sPathToSaveOutput) fitter = root.TVirtualFitter.Fitter(fit_mpe) #fitter = root.TVirtualFitter.GetFitter() amin = np.asarray([0], dtype=np.float64) dum1 = np.asarray([0], dtype=np.float64) dum2 = np.asarray([0], dtype=np.float64) dum3 = np.asarray([0], dtype=np.int32) dum4 = np.asarray([0], dtype=np.int32) fitter.GetStats(amin, dum1, dum2, dum3, dum4) print '\n\namin for %d photons: %f' % (num_photons, amin) print 'fAmin for %d photons: %f\n\n' % (num_photons, root.gMinuit.fAmin) print fit_mpe.GetChisquare() # draw tpavetext tpt_mpe = root.TPaveText(.55,.75,.85,.85,'blNDC') tpt_mpe.AddText('#mu_{SPE} = %.2e #pm %.2e' % (fit_mpe.GetParameter(3), fit_mpe.GetParError(3))) tpt_mpe.AddText('#sigma_{SPE} = %.2e #pm %.2e' % (fit_mpe.GetParameter(4), fit_mpe.GetParError(4))) tpt_mpe.Draw('same') tpt_mpe.SetTextColor(root.kBlack) tpt_mpe.SetFillStyle(0) tpt_mpe.SetBorderSize(0) c1.Update() neriX_analysis.save_plot(l_plots, c1, 'mpe_poisson_gaussian_fit_%s' % (file_identifier)) return (0,0,0)
# ymax = getMax( [h_data, h_t1After, h_t2After, h_t3After] ) # h_data.GetYaxis().SetRangeUser(0,ymax) # h_t1After.GetYaxis().SetRangeUser(0,ymax) # h_t2After.GetYaxis().SetRangeUser(0,ymax) # h_t3After.GetYaxis().SetRangeUser(0,ymax) leg.AddEntry(h_tSumAfter, style='L', label='Sum') leg.Draw() c.Update() if drawScancan: scancan = Canvas() scancan.Divide(nTemplates) scancan.SetLogy() nCan = 1 if useT1: scancan.cd(nCan) # scan1.SetMaximum(scan1.GetMaximum()/100) scan1.SetMarkerStyle(20) # scan1.SetMarkerSize(1) scan1.Draw('AP') nCan = nCan + 1 pass if useT2: scancan.cd(nCan) scan2.SetMaximum(1000) scan2.SetMarkerStyle(20) # scan2.SetMarkerSize(20) scan2.Draw('AP')
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
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