def _plot(self): if not self.loader: raise RuntimeError("templates are not loaded") class Container: pass containers = [] for plot, channels in self.loader.plots.items(): for channel, systematics in channels.items(): obj = Container() obj.ratios = [] obj.stack = ROOT.THStack() obj.axis_hist = None obj.legend = ROOT.TLegend(.67, .60, .89, .88) obj.legend.SetMargin(0.12); obj.legend.SetTextSize(0.03); obj.legend.SetFillColor(10); obj.legend.SetBorderSize(0); obj.legend.SetHeader("{0}: {1}".format( self._systematic.capitalize(), self.channel_names.get(channel, "Unknown Channel"))) self.style(systematics) max_y = 0 for channel in (systematics.nominal, systematics.plus, systematics.minus): if not channel: continue if not obj.axis_hist: obj.axis_hist = channel.hist.Clone() channel_max_y = channel.hist.GetBinContent( channel.hist.GetMaximumBin()) if channel_max_y > max_y: max_y = channel_max_y obj.axis_hist.Reset() obj.axis_hist.SetMaximum(1.2 * max_y) if systematics.nominal: obj.stack.Add(systematics.nominal.hist) obj.legend.AddEntry(systematics.nominal.hist, "nominal", "lp") if systematics.plus: obj.stack.Add(systematics.plus.hist) obj.legend.AddEntry(systematics.plus.hist, "systematic plus", "lp") if systematics.nominal: obj.ratios.append(compare.ratio( systematics.plus.hist, systematics.nominal.hist, title="#frac{plus}{nominal}")) if systematics.minus: obj.stack.Add(systematics.minus.hist) obj.legend.AddEntry(systematics.minus.hist, "systematic minus", "lp") if systematics.nominal: obj.ratios.append(compare.ratio( systematics.minus.hist, systematics.nominal.hist, title="#frac{minus}{nominal}")) obj.canvas = ComparisonCanvas(len(obj.ratios) + 1) canvas = obj.canvas.canvas canvas.cd(1) obj.axis_hist.Draw("9") obj.stack.Draw("hist 9 nostack same") obj.labels = [root.label.CMSSimulationLabel()] for label in obj.labels: label.draw() obj.legend.Draw("9") for pad, ratio in enumerate(obj.ratios, 2): canvas.cd(pad) ratio.GetYaxis().SetRangeUser(0, 2) ratio.GetXaxis().SetTitle("") ratio.Draw("9 e") canvas.Update() containers.append(obj) if containers and not self._batch_mode: raw_input('enter')
def _plot(self): canvases = [] ''' loop over plots and draw them: 1. all background channels stacked (MC channels + QCD) 2. background error band (MC + QCD) 3. data with errors 4. ratio of data over background ''' # loop over plots for plot_name, channels in self.loader.plots.items(): # process Z' obj = None for channel_type, template in channels.items(): if not channel_type.startswith("zp"): continue hist = calculate_efficiency(template.hist) hist.SetFillStyle(0) hist.SetMaximum(1.2) hist.SetMinimum(0) hist.GetXaxis().SetRangeUser(0, 20) if not obj: obj = self._create_obj("canvas_signal_chi2") hist.Draw('hist 9') else: hist.Draw("hist 9 same") obj.legend.AddEntry(hist, channel_type, "l") obj.hist.append(hist) if obj: obj.legend.Draw('9') for label in obj.labels: label.draw() canvases.append(obj) # take care of background obj = None for channel_type, template in channels.items(): if (channel_type.startswith("zp") or channel_type not in set(channels.keys()) - set(["data", "mc"])): continue hist = calculate_efficiency(template.hist) hist.SetFillStyle(0) hist.SetMaximum(1.2) hist.SetMinimum(0) hist.GetXaxis().SetRangeUser(0, 20) if not obj: obj = self._create_obj("canvas_background_chi2") hist.Draw('hist 9') else: hist.Draw("hist 9 same") obj.legend.AddEntry(hist, channel_type, "l") obj.hist.append(hist) if obj: obj.legend.Draw('9') for label in obj.labels: label.draw() canvases.append(obj) return canvases
def _plot(self): # container where all canvas related objects will be saved class Canvas: pass canvases = [] ''' loop over plots and draw them: 1. all background channels stacked (MC channels + QCD) 2. background error band (MC + QCD) 3. data with errors 4. ratio of data over background ''' # loop over plots for plot_name, channels in self.loader.plots.items(): # create container for current objects obj = Canvas() # extact MC combined mc_combo = channels.get("mc") # extract Data data = channels.get("data") if "none" == self._ratio: obj.legend = ROOT.TLegend(.65, .50, .88, .88) else: obj.legend = ROOT.TLegend(.7, .50, .88, .88) obj.legend.SetMargin(0.12); obj.legend.SetTextSize(0.03); obj.legend.SetFillColor(10); obj.legend.SetBorderSize(0); # background combined obj.bg_combo = None for channel_type in ["mc", "qcd"]: if channel_type in channels: hist = channels[channel_type].hist if obj.bg_combo: obj.bg_combo.Add(hist) else: obj.bg_combo = hist.Clone() obj.bg_combo.SetDirectory(0) if obj.bg_combo: # apply uncertainty style MCChannelTemplate.channel_styles["mc"].apply(obj.bg_combo) # stack all backgrounds obj.bg_stack = None bg_order = ["qcd"] + (mc_combo.allowed_inputs if mc_combo else []) bg_channels = set(channels.keys()) & set(bg_order) # Add channels in order: QCD + channel_type["mc"] for channel_type in bg_order: if channel_type in bg_channels: hist = channels[channel_type].hist if not obj.bg_stack: obj.bg_stack = ROOT.THStack() clone = hist.Clone() clone.SetLineWidth(0) obj.bg_stack.Add(hist) # Add channels in order: QCD + channel_type["mc"] for channel_type in reversed(bg_order): if channel_type in bg_channels: hist = channels[channel_type].hist obj.legend.AddEntry(hist, self.channel_names.get(channel_type, "unknown"), "fe") # Adjust y-Maximum to be drawn max_y = 1.3 * max( (h.GetBinContent(h.GetMaximumBin()) + h.GetBinError(h.GetMaximumBin())) if h else 0 for h in [obj.bg_combo if obj.bg_combo else None, data.hist if data else None] + [ch.hist for name, ch in channels.items() if (name.startswith("zprime") or name.startswith("rsgluon"))] if h) # take care of ratio if self._ratio and self._ratio != "none": try: # make sure specified channels are available ratio = [] for term in self._ratio: if "bg" == term: if not obj.bg_combo: raise KeyError("background is not loaded") ratio.append({ "title": "BKGD", "hist": obj.bg_combo }) elif term in channels: ratio.append({ "title": self.channel_names.get(term, "unknown"), "hist": channels[term].hist }) else: raise KeyError("unsupported channel {0!r}".format( term)) obj.canvas_obj = ComparisonCanvas() obj.canvas = obj.canvas_obj.canvas obj.canvas.cd(2) obj.ratio = compare.ratio(ratio[0]["hist"], ratio[1]["hist"], title = "#frac{" + ratio[0]["title"] + "}{" + ratio[1]["title"] + "}") obj.ratio.GetXaxis().SetTitle("") obj.ratio.Draw("9 e") except KeyError as error: print("ratio error: {0}".format(error)) obj.canvas = ROOT.TCanvas() obj.canvas.SetWindowSize(640, 560) pad = obj.canvas.cd(1) pad.SetRightMargin(5) pad.SetBottomMargin(0.15) elif data and obj.bg_combo and self._ratio != "none": # Prepare comparison canvas: top pad plots, bottom - ratio obj.canvas_obj = ComparisonCanvas() obj.canvas = obj.canvas_obj.canvas obj.canvas.cd(2) obj.ratio = compare.data_mins_bg_over_bg(data.hist, obj.bg_combo) ''' obj.ratio = compare.ratio(channels["zprime_m1000_w10"].hist, obj.bg_combo, title = "#frac{Z' 1 TeV}{BKGD}") ''' obj.ratio.GetXaxis().SetTitle("") obj.ratio.Draw("9 e") else: obj.canvas = ROOT.TCanvas() obj.canvas.SetWindowSize(640, 560) pad = obj.canvas.cd(1) pad.SetRightMargin(5) pad.SetBottomMargin(0.15) obj.canvas.SetName("canvas_" + plot_name.replace("/", "_")) pad = obj.canvas.cd(1) if self._logy: pad.SetLogy() # use data or background to draw axes obj.axis_hist = None if data: obj.axis_hist = data.hist.Clone() elif obj.bg_combo: obj.axis_hist = obj.bg_combo.Clone() else: for name, channel in channels.items(): if name.startswith("zprime") or name.startswith("rsgluon"): obj.axis_hist = channel.hist.Clone() break obj.axis_hist.Reset() obj.axis_hist.SetLineWidth(1) for axis in ROOT.TH1.GetXaxis, ROOT.TH1.GetYaxis: axis(obj.axis_hist).SetLabelSize(0.04) axis(obj.axis_hist).SetAxisColor(ROOT.kBlack) if "chi2" in plot_name and False: obj.axis_hist.GetXaxis().SetRangeUser(0, 21) obj.axis_hist.Draw("9") # Draw plots if obj.bg_stack: obj.bg_stack.Draw("9 hist same") if obj.bg_combo: obj.legend.AddEntry(obj.bg_combo, "Uncertainty", "fe") obj.bg_combo.Draw("9 e2 same") if data: obj.legend.AddEntry(data.hist, "CMS Data 2011", "lpe") data.hist.Draw("9 same") obj.axis_hist.SetMaximum(max_y) obj.axis_hist.Draw("9 same") if "none" == self._ratio: obj.labels = [ root.label.CMSLabel(text_size=0.033), root.label.LuminosityLabel(InputTemplate.luminosity(), text_size=0.033) if data else root.label.CMSSimulationLabel(text_size=0.033)] else: obj.labels = [ root.label.CMSLabel(), root.label.LuminosityLabel(InputTemplate.luminosity()) if data else root.label.CMSSimulationLabel()] if self._label: obj.labels.append(root.label.ChannelLabel(self._label)) # draw signals for channel_type, channel in channels.items(): if (channel_type.startswith("zprime") or channel_type.startswith("rsgluon")): obj.legend.AddEntry(channel.hist, self.channel_names.get(channel_type, "unknown signal"), "l") channel.hist.Draw("9 hist same") print("{0} S: {s:.1f} B: {b:.1f} S/B: {r:.3f}".format( channel_type, s=channel.hist.Integral(), b=obj.bg_combo.Integral(), r=channel.hist.Integral() / obj.bg_combo.Integral())) # Draw Labels and Legend for label in obj.labels: label.draw() obj.legend.Draw("9") obj.canvas.Update() canvases.append(obj) return canvases