def model_plots(model, all_nominal_templates = False, shape_templates = False): plotdir = os.path.join(config.workdir, 'plots') observables = sorted(list(model.observables.keys())) processes = sorted(list(model.processes)) #TODO: more / better colors background_colors = ['#edd400', '#f57900', '#c17d11', '#73d216', '#3465a4', '#75507b', '#d3d7cf', '#555753'] signal_colors = ['#ef2929', '#cc0000', '#a40000'] if not os.path.exists(plotdir): os.mkdir(plotdir) f = open(os.path.join(config.workdir, 'model_plots.thtml'), 'w') print >> f, "<h2>Stackplots</h2>" print >> f, "<p>Everything normalized to expectation, i.e., to the normalization in the template input file, possibly scaled via the python script file.</p>" print >> f, "<p>Color Code:</p><ul>" i_bkg_col = 0 i_signal_col = 0 for p in processes: if p in model.signal_processes: color = signal_colors[i_signal_col] i_signal_col = (i_signal_col + 1) % len(signal_colors) else: color = background_colors[i_bkg_col] i_bkg_col = (i_bkg_col + 1) % len(background_colors) print >> f, '<li><span style="background: %s;"> </span> %s</li>' % (color, p) print >>f, '</ul>' for o in observables: background_pds = [] signal_pds = [] i_bkg_col = 0 i_signal_col = 0 for p in processes: hf = model.get_histogram_function(o, p) if hf is None: continue pd = plotutil.plotdata() pd.histo_triple(hf.get_nominal_histo()) xmin, xmax, data = hf.get_nominal_histo() binwidth = (xmax - xmin) / len(data) if p in model.signal_processes: pd.color = signal_colors[i_signal_col] i_signal_col = (i_signal_col + 1) % len(signal_colors) signal_pds.append(pd) else: pd.fill_color = background_colors[i_bkg_col] pd.lw = 1 pd.color = '#000000' i_bkg_col = (i_bkg_col + 1) % len(background_colors) background_pds.append(pd) data_histo = model.get_data_histogram(o) data_pd = None if data_histo is not None: data_pd = plotutil.plotdata() data_pd.color = '#000000' data_pd.histo_triple(data_histo) data_pd.yerrors = map(math.sqrt, data_pd.y) data_pd.circle = 'o' plotutil.make_stack(background_pds) plots = background_pds + signal_pds if data_pd is not None: plots.append(data_pd) plotutil.plot(plots, o, '$N / %.4g$' % binwidth, os.path.join(plotdir, '%s_stack.png' % o), xmin=xmin, xmax=xmax) print >> f, "<p>Observable '%s':<br /><img src=\"plots/%s_stack.png\" /></p>" % (o, o) if all_nominal_templates: print >> f, "<h2>All 'nominal' Templates</h2>" print >> f, "<p>Everything normalized to expectation, i.e., to the normalization in the template input file, possibly scaled via the python script file.</p>" for o in observables: for p in processes: hf = model.get_histogram_function(o,p) if hf is None: continue xmin, xmax, data = hf.get_nominal_histo() binwidth = (xmax - xmin) / len(data) pd = plotutil.plotdata() pd.x = [xmin + i*binwidth for i in range(len(data))] pd.y = data[:] pd.color = signal_colors[0] xlabel = o plotutil.plot([pd], xlabel, '$N / %.4g$' % binwidth, os.path.join(plotdir, '%s_%s.png' % (o, p)), xmin=xmin, xmax=xmax) print >> f, '<p>Observable "%s", Process "%s":<br/><img src="plots/%s_%s.png"/></p>' % (o, p, o, p) # make also one plot with all signal processes, and normalization versus ordering: pd_norm = plotutil.plotdata() pd_norm.x = [] pd_norm.y = [] pd_norm.as_histo = False pd_norm.color = '#000000' plots = [] i_signal_col = 0 x_to_y = {} for p in processes: if p not in model.signal_processes: continue hf = model.get_histogram_function(o,p) if hf is None: continue xmin, xmax, data = hf.get_nominal_histo() x_to_y[utils.extract_number(p)] = sum(data) binwidth = (xmax - xmin) / len(data) pd = plotutil.plotdata() pd.x = [xmin + i*binwidth for i in range(len(data))] pd.y = data[:] pd.color = signal_colors[i_signal_col] plots.append(pd) i_signal_col = (i_signal_col + 1) % len(signal_colors) for x in sorted(x_to_y.keys()): pd_norm.x.append(x) pd_norm.y.append(x_to_y[x]) plotutil.plot(plots, o, '$N / %.4g$' % binwidth, os.path.join(plotdir, '%s_signals.png' % o), xmin=xmin, xmax=xmax) plotutil.plot([pd_norm], 'signal process', '$N$', os.path.join(plotdir, '%s_norm_vs_signals.png' % o)) print >> f, '<p>Observable "%s", all signals: <br/><img src="plots/%s_signals.png"/></p>' % (o, o) print >> f, '<p>Observable "%s", signal normalization: <br/><img src="plots/%s_norm_vs_signals.png"/></p>' % (o, o) # (end if all_nominal_templates) if not shape_templates: f.close() return # shape comparison for morphed templates: color_nominal, color_plus, color_minus = '#333333', '#aa3333', '#3333aa' print >> f, "<h2>Shape Uncertainty Plots</h2>" print >> f, "<p>Color Code:</p><ul>" print >> f, "<li><span style=\"background: %s;\"> </span> nominal</li><li><span style=\"background: %s;\"> </span> plus</li><li><span style=\"background: %s;\"> </span> minus</li>" % (color_nominal, color_plus, color_minus) print >> f, "</ul>" print >> f, "<p>Processes not appearing in the tables do not have any shape uncertainty for this observable.</p>" print >> f, "<p>Click on an image to enlarge. If you have javascript, the image will be displayed on this page and you can click through all shape uncertainties of that observable \ (instead of clicking, you can also use the left/right key on the keyboard).</p>" for o in observables: print >> f, '<h3>Observable \'%s\'</h3>' % o # save the triples (o,p,u) for which there is a plot: opus = [] for p in model.get_processes(o): hf = model.get_histogram_function(o,p) for u in hf.syst_histos: xmin, xmax, data_nominal = hf.nominal_histo xmin, xmax, data_plus = hf.syst_histos[u][0] xmin, xmax, data_minus = hf.syst_histos[u][1] binwidth = (xmax - xmin) / len(data_nominal) pd = plotutil.plotdata(color = color_nominal, legend = 'nominal') pd.x = [xmin + i*binwidth for i in range(len(data_nominal))] pd.y = data_nominal pd_plus = plotutil.plotdata(color = color_plus, legend = 'plus variation') pd_plus.x = pd.x pd_plus.y = data_plus pd_plus.color = color_plus pd_minus = plotutil.plotdata(color = color_minus, legend = 'minus variation') pd_minus.x = pd.x pd_minus.y = data_minus name = '%s__%s__%s' % (o,p,u) plotutil.plot((pd, pd_plus, pd_minus), o, '$N / %.4g$' % binwidth, os.path.join(plotdir, name + '.png'), xmin=xmin, xmax = xmax) opus.append((o,p,u)) #make a table for this observable: t = table() t.add_column('process', 'process / uncertainty') us = sorted(list(set([u for o,p,u in opus]))) ps = sorted(list(set([p for o,p,u in opus]))) for u in us: t.add_column(u) for p in ps: t.set_column('process', p) for u in us: if (o,p,u) in opus: t.set_column(u, '<a href="plots/%s__%s__%s.png" rel="lightbox[%s]"><img src="plots/%s__%s__%s.png" width="200"/></a>' % (o,p,u,o,o,p,u)) else: t.set_column(u, '---') t.add_row() print >>f, t.html() if len(opus)==0: print >> f, '<p>no shape uncertainties for this observable</p>' f.close()
def model_plots_at(model, par_values, signal_stacked = False): plotdir = os.path.join(config.workdir, 'plots') processes = sorted(list(model.processes)) #TODO: more / better colors h = str(hash(str(par_values))) background_colors = ['#edd400', '#f57900', '#c17d11', '#73d216', '#3465a4', '#75507b', '#d3d7cf', '#555753'] signal_colors = ['#ef2929', '#cc0000', '#a40000'] if not os.path.exists(plotdir): os.mkdir(plotdir) text = '<p>Templates evaluated at:<p><ul>' for p in par_values: text+='<li>%s = %.2g</li>\n' % (p, par_values[p]) text += '</ul>' text += "<p>Everything normalized to expectation, i.e., to the normalization in the template input file, possibly scaled via the python script file.</p>" text += "<p>Color Code:</p><ul>" i_bkg_col = 0 i_signal_col = 0 for p in processes: if p in model.signal_processes: color = signal_colors[i_signal_col] i_signal_col = (i_signal_col + 1) % len(signal_colors) else: color = background_colors[i_bkg_col] i_bkg_col = (i_bkg_col + 1) % len(background_colors) text += '<li><span style="background: %s;"> </span> %s</li>' % (color, p) text += '</ul>' templates = get_shifted_templates(model, par_values) for o in templates: background_pds = [] signal_pds = [] i_bkg_col = 0 i_signal_col = 0 for p in templates[o]: pd = plotutil.plotdata() pd.histo_triple(templates[o][p]) xmin, xmax, data = templates[o][p] binwidth = (xmax - xmin) / len(data) if p in model.signal_processes: pd.color = signal_colors[i_signal_col] i_signal_col = (i_signal_col + 1) % len(signal_colors) signal_pds.append(pd) else: pd.fill_color = background_colors[i_bkg_col] pd.lw = 1 pd.color = '#000000' i_bkg_col = (i_bkg_col + 1) % len(background_colors) background_pds.append(pd) data_histo = model.get_data_histogram(o) data_pd = None if data_histo is not None: xmin, xmax, data = data_histo data_pd = plotutil.plotdata() data_pd.color = '#000000' data_pd.histo_triple(data_histo) data_pd.yerrors = map(math.sqrt, data_pd.y) data_pd.circle = 'o' plots = background_pds if signal_stacked: plots.extend(signal_pds) plotutil.make_stack(background_pds) else: plotutil.make_stack(background_pds) plots.extend(signal_pds) if data_pd is not None: plots.append(data_pd) plotutil.plot(plots, o, '$N / %.4g$' % binwidth, os.path.join(plotdir, '%s_stack%s.png' % (o, h)), xmin=xmin, xmax=xmax) text += "<p>Observable '%s':<br /><img src=\"plots/%s_stack%s.png\" /></p>" % (o, o, h) config.report.new_section('Model Plots at parameter values', text)