def plot_exclusion(path, region, outdir): #set_default_style() set_atlas_style() ROOT.gStyle.SetLegendFont(42) # input files if sig_xs_syst: file_name = path + '/Output_fixSigXSecNominal_hypotest__1_harvest_list.root' file_name_high = path + '/Output_fixSigXSecUp_hypotest__1_harvest_list.root' file_name_low = path + '/Output_fixSigXSecDown_hypotest__1_harvest_list.root' else: file_name = path + '/Output_hypotest__1_harvest_list.root' # Get histograms ## obs CLs (Nominal, Low, High) sigp1clsf = return_contour95('sigp1clsf', file_name) if sig_xs_syst: sigp1clsfLow = return_contour95('sigp1clsf', file_name_low) sigp1clsfHigh = return_contour95('sigp1clsf', file_name_high) sigp1clsfLow.SetName('sigp1clsfLow') sigp1clsfLow.SetTitle('sigp1clsfLow') sigp1clsfHigh.SetName('sigp1clsfHigh') sigp1clsfHigh.SetTitle('sigp1clsfHigh') sigp1expclsf = return_contour95('sigp1expclsf', file_name) sigclsu1s = return_contour95('sigclsu1s', file_name) sigclsd1s = return_contour95('sigclsd1s', file_name) graph_sigp1clsf = convert_hist_to_graph(sigp1clsf) if sig_xs_syst: graph_sigp1clsfLow = convert_hist_to_graph(sigp1clsfLow) graph_sigp1clsfHigh = convert_hist_to_graph(sigp1clsfHigh) graph_sigp1expclsf = convert_hist_to_graph(sigp1expclsf) graph_sigclsu1s = convert_hist_to_graph(sigclsu1s) graph_sigclsd1s = convert_hist_to_graph(sigclsd1s) # Colours c_yellow = ROOT.TColor.GetColor('#ffe938') c_red = ROOT.TColor.GetColor('#aa0000') c_blue = ROOT.TColor.GetColor('#28373c') frame = draw_grid_frame(xmin=1146, xmax=2550, ymin=147, ymax=2550) # Create the text in the plot # DATA info leg1 = ROOT.TLatex() leg1.SetNDC() leg1.SetTextSize(0.035) leg1.SetTextColor(1) if args.datalabel is not None: leg1.DrawLatex(0.15, 0.7, args.datalabel) else: leg1.DrawLatex(0.15, 0.7, style.data_label) # if style.atlas_label: # leg1.SetTextSize(0.04) # leg1.DrawLatex(1810, 230, style.atlas_label) # Signal Regions label leg3 = ROOT.TLatex() leg3.SetNDC() leg3.SetTextSize(0.035) leg3.SetTextColor(1) leg3.SetTextFont(42) region_text = region if 'SRL,SRH' in region_text or 'SRiL,SRiH' in region_text: region_text = region_text = 'SR_{L} and SR_{H}' elif 'SRL' in region_text or 'SRiL' in region_text: region_text = 'SR_{L}' elif 'SRH' in region_text or 'SRiH' in region_text: region_text = 'SR_{H}' leg3.DrawLatex(0.15, 0.63, region_text) # Legend leg = ROOT.TLegend(0.15, 0.77, 0.49, 0.92) leg.SetFillColor(0) leg.SetBorderSize(0) # extra text leg4 = ROOT.TLatex() leg4.SetNDC() leg4.SetTextSize(0.03) leg4.SetTextColor(1) leg4.SetTextAngle(90) if (args.obscls or args.expcls or args.bestsr): leg4.SetTextColor(ROOT.kGray+2) textx = 0.98 texty = 0.12 if args.obscls: leg4.DrawLatex(textx, texty, 'Numbers give observed CL_{s} values') elif args.expcls: leg4.DrawLatex(textx, texty, 'Numbers give expected CL_{s} values') elif args.bestsr: leg4.DrawLatex(textx, texty, 'Labels indicate best-expected SR') # leg2 = ROOT.TLatex() # leg2.SetNDC() # leg2.SetTextSize(0.03) # leg2.SetTextColor(1) # leg2.DrawLatex(0.17, 0.75, "All limits at 95% CL") graph_sigp1clsf.SetFillColor(ROOT.kWhite) graph_sigp1clsf.SetFillStyle(3003) graph_sigp1clsf.SetLineColor(c_red) graph_sigp1clsf.SetLineStyle(1) graph_sigp1clsf.SetLineWidth(3) if sig_xs_syst: graph_sigp1clsfHigh.SetFillColor(ROOT.kWhite) graph_sigp1clsfHigh.SetFillStyle(3003) graph_sigp1clsfHigh.SetLineColor(c_red) graph_sigp1clsfHigh.SetLineStyle(3) graph_sigp1clsfHigh.SetLineWidth(2) graph_sigp1clsfLow.SetFillColor(ROOT.kWhite) graph_sigp1clsfLow.SetFillStyle(3003) graph_sigp1clsfLow.SetLineColor(c_red) graph_sigp1clsfLow.SetLineStyle(3) graph_sigp1clsfLow.SetLineWidth(2) sigp1expclsf.SetLineColor(c_blue) sigp1expclsf.SetLineStyle(1) sigp1expclsf.SetLineWidth(2) sigp1clsf.SetLineWidth(3) sigclsu1s.SetFillColor(ROOT.kWhite) sigclsd1s.SetFillColor(c_yellow) graph_sigp1expclsf.SetFillColor(c_yellow) graph_sigp1expclsf.SetFillStyle(1001) graph_sigp1expclsf.SetLineColor(c_blue) graph_sigp1expclsf.SetLineStyle(7) graph_sigp1expclsf.SetLineWidth(2) # Load run 1 limit # if ',' in region: # f = ROOT.TFile.Open(os.environ['SUSY_ANALYSIS'] + '/results/limit_run1_gln1.root') # limit_run1 = f.Get('clsf_obs') # leg.AddEntry(limit_run1, 'ATLAS 8 TeV, 20.3 fb^{-1}', 'F') if not args.onlyexp: obs_entry = leg.AddEntry(graph_sigp1clsf, "Observed limit (#pm1 #sigma^{SUSY}_{theory})", "LF") leg.AddEntry(graph_sigp1expclsf, "Expected limit (#pm1 #sigma_{exp})", "LF") leg.Draw() if not args.onlyexp and sig_xs_syst: ROOT.gPad.Update() n_rows = leg.GetNRows() x1 = 0.15 y1 = 0.77 x2 = 0.49 y2 = 0.92 margin = leg.GetMargin() * (x2-x1) boxw = margin*0.35 yspace = (y2-y1) / n_rows xsym = x1 + margin/2. ysym = y2 - 0.5*yspace - yspace * (n_rows-2) dy = 0.015 line = ROOT.TLine() ROOT.SetOwnership(line, False) line.SetLineColor(obs_entry.GetLineColor()) line.SetLineWidth(2) line.SetLineStyle(3) line.DrawLineNDC(xsym-boxw, ysym+dy, xsym+boxw, ysym+dy) line.DrawLineNDC(xsym-boxw, ysym-dy, xsym+boxw, ysym-dy) # Plot sigclsd1s.Draw("same cont0") sigclsu1s.Draw("same cont0") graph_sigp1expclsf.Draw("same l") if not args.onlyexp: graph_sigp1clsf.Draw('same l') if sig_xs_syst: graph_sigp1clsfHigh.Draw("same l") graph_sigp1clsfLow.Draw("same l") # plot Run 1 limit # if ',' in region: # limit_run1.SetLineWidth(2) # limit_run1.SetLineColor(get_color('#b9b7b7')) # limit_run1.SetFillColor(get_color('#c6c4c4')) # limit_run1.Draw('f same') # limit_run1.Draw('l same') # Redraw axis and update frame frame.RedrawAxis() ROOT.gPad.Update() output_tag = '' if args.obscls or args.expcls: # if sig_xs_syst: # file_name = '%s/Output_fixSigXSecNominal_hypotest__1_harvest_list.root' % path # else: # file_name = '%s/Output_hypotest__1_harvest_list.root' % path l_region = ROOT.TLatex() l_region.SetTextSize(0.014) l_region.SetTextColor(ROOT.kGray+2) if sig_xs_syst: tree_file = '%s/Output_fixSigXSecNominal_hypotest__1_harvest_list_hack.root' % path else: tree_file = '%s/Output_hypotest__1_harvest_list_hack.root' % path if args.obscls: cls_dict = get_cls_values(tree_file, False) output_tag = '_obscls' if args.expcls: cls_dict = get_cls_values(tree_file, True) output_tag = '_expcls' for (mgl, mn1), cls in cls_dict.iteritems(): l_region.DrawLatex(mgl, mn1, "%.3f" % cls) elif args.bestsr: output_tag = '_bestsr' region_events = dict() dict_events = dict() for sel in region.split(','): if sig_xs_syst: tree_file = '%s/Output_%s_fixSigXSecNominal_hypotest__1_harvest_list_hack.root' % (path, sel) else: tree_file = '%s/Output_%s_hypotest__1_harvest_list_hack.root' % (path, sel) dict_events = get_cls_values(tree_file, exp=True) region_events[sel] = dict_events l_tot = ROOT.TLatex() l_tot.SetTextSize(0.016) l_tot.SetTextColor(ROOT.kGray+3) for mgl, mn1 in dict_events.iterkeys(): binCLs = 100. best_region_string = '' for r in region_events.iterkeys(): if region_events[r][(mgl, mn1)] < binCLs: binCLs = region_events[r][(mgl, mn1)] best_region_string = r print mgl, mn1, r, binCLs l_tot.DrawLatex(mgl, mn1, "%s" % best_region_string[-1]) elif args.points: lp = ROOT.TLatex() lp.SetTextSize(0.016) lp.SetTextColor(ROOT.kGray+3) for (m3, mu), (mgl, mn1) in grid_m3_mu.iteritems(): if m3 > 2000: lp.SetTextColor(ROOT.kRed-4) lp.DrawLatex(mgl, mn1, "#times") else: lp.SetTextColor(ROOT.kGray+3) lp.DrawLatex(mgl, mn1, "#bullet") frame.SaveAs(path+'/limitPlot_%s%s.pdf' % (region.replace(',', '_'), output_tag)) # Save contours outname = path + '/limit_contour_%s' % region.replace(',', '_') + '.root' outfile = ROOT.TFile(outname, 'recreate') outfile.cd() ## observed graph_sigp1clsf.Write('clsf_obs') if sig_xs_syst: graph_sigp1clsfHigh.Write("clsf_obs_up") graph_sigp1clsfLow.Write("clsf_obs_dn") ## expected graph_sigp1expclsf.Write('clsf_exp') if sig_xs_syst: graph_sigclsd1s = convert_hist_to_graph(sigclsd1s) graph_sigclsu1s = convert_hist_to_graph(sigclsu1s) graph_sigclsd1s.Write('clsf_exp_dn') graph_sigclsu1s.Write('clsf_exp_up') outfile.Close()
else: names.append(name) x.append(counter) xe.append(0) y.append(val) y_dn.append(abs(val_dn)) y_up.append(val_up) counter += 1 # plot set_atlas_style() c = ROOT.TCanvas('pulls', '', 1200, 500) c.SetBottomMargin(0.32) c.SetTopMargin(0.03) c.SetRightMargin(0.06) c.SetLeftMargin(0.06) frame = ROOT.TH2D('frame_', '', len(y), -0.5, len(y)-0.5, 5, -1.5, 1.5) frame.SetYTitle('#alpha parameters after fit') frame.SetXTitle('') frame.Draw() frame.GetYaxis().SetTitleOffset(0.5) eg = ROOT.TGraphAsymmErrors(len(x), x, y, xe, xe, y_dn, y_up) eg.SetMarkerStyle(20)
def main(): parser = argparse.ArgumentParser(description='analysis.py') # Input/output # version, data parser.add_argument('-v', '--version', help='Mini-ntuples version') parser.add_argument('--data', help='2015+2016 or 2017') parser.add_argument('-o', dest='output_dir', help='Output directory') # Steps parser.add_argument('-c', '--chist', action='store_true', help='Do "ntuples -> cuts histograms" step') parser.add_argument('-d', '--dhist', action='store_true', help='Do "ntuples -> distributions histograms" step') parser.add_argument('-f', '--fit', action='store_true', help='Do "histograms -> fit" step') parser.add_argument('-t', '--tables', action='store_true', help='Do "fit -> tables" step') parser.add_argument('-p', '--plots', action='store_true', help='Do "histograms/fit -> plots" step') # Systematics parser.add_argument('--syst', action='store_true', help='Include all systematics (detector + DD + MC)') parser.add_argument('--detsyst', action='store_true', help='Include detector systematics') parser.add_argument('--ddsyst', action='store_true', help='Include DD systematics') parser.add_argument('--mcsyst', action='store_true', help='Include MC systematics') # Extra options parser.add_argument('--conf', help='HistFitter config file') parser.add_argument( '--unblind', action='store_true', help='Unblind Signal Regions! Use with caution, you can discover SUSY') parser.add_argument('--noval', action='store_true', help='Don\'t include Validation Regions') parser.add_argument('--mc', action='store_true', help='Use only MC') # Histogram options parser.add_argument('--force', action='store_true', help='Force histogram creation') parser.add_argument('-s', '--sample', help='Only update histograms for this sample') parser.add_argument( '--ignore-missing', dest='ignore_missing', action='store_true', help='Ignore missing samples. Do not use this option! ') args = parser.parse_args() step_chist = args.chist step_dhist = args.dhist step_fit = args.fit step_tables = args.tables step_plots = args.plots if not any([ step_chist, step_dhist, step_fit, step_tables, step_plots ]) or args.output_dir is None or args.version is None or args.data is None: parser.print_usage() sys.exit(1) # Configuration unblind = args.unblind data = args.data version = args.version do_validation = (not args.noval) use_mc = args.mc do_det_syst = False do_dd_syst = False do_mc_syst = False if args.syst: syst_str = ' --syst' do_det_syst = True do_dd_syst = True do_mc_syst = True else: syst_str = '' if args.detsyst: do_det_syst = True syst_str += ' --detsyst' if args.ddsyst: do_dd_syst = True syst_str += ' --ddsyst' if args.mcsyst: do_mc_syst = True syst_str += ' --mcsyst' # ------- # Regions # ------- srs = ['SRL200', 'SRL300', 'SRH'] crs = ['CRQ', 'CRW', 'CRT'] vrs = [ 'VRQ', 'VRM1L', 'VRM2L', 'VRM1H', 'VRM2H', 'VRL1', 'VRL2', 'VRL3', 'VRL4', 'VRE' ] sr_str = ','.join(srs) if do_validation: regions = crs + vrs + srs regions_str = '%s,%s,%s' % (','.join(srs), ','.join(crs), ','.join(vrs)) else: regions = crs + srs regions_str = '%s,%s' % (','.join(srs), ','.join(crs)) # ------- # Samples # ------- mc_samples = [ 'photonjet', 'wgamma', 'zllgamma', 'znunugamma', 'ttgamma', 'diphoton', ] mc_fake_samples = ['ttbar', 'multijet', 'wjets', 'zjets'] dd_samples = [ 'efake', 'jfake', ] if use_mc: backgrounds = mc_samples + mc_fake_samples else: backgrounds = dd_samples + mc_samples samples = [ 'data', ] + backgrounds #backgrounds_str = 'photonjet,wgamma,[zllgamma,znunugamma],ttgamma,efake,jfake,diphoton' #backgrounds_str = 'photonjet,wgamma,[zllgamma,znunugamma],ttgamma' backgrounds_str = ','.join(backgrounds) # ----- # Plots # ----- plot_variables = [ 'ph_pt[0]', 'jet_n', 'bjet_n', 'jet_pt[0]', 'met_et', 'ht', 'meff', 'dphi_jetmet', 'dphi_gammet', 'dphi_gamjet', 'rt4', ] #plot_bkgs = ['photonjet', 'wgamma','zgamma', 'fakes', 'ttgamma', 'diphoton'] plot_bkgs = [ 'photonjet', 'wgamma', 'zgamma', 'efake', 'jfake', 'ttgamma', 'diphoton' ] plot_regions = regions plot_bkg_merge_dict = { 'zgamma': [ 'zllgamma', 'znunugamma', ], #'fakes': ['efake', 'jfake'] } plot_bkg_norm_dict = { 'CRQ': 'photonjet', 'CRW': 'wgamma', 'CRT': 'ttgamma', } lumi = 0. for year in data.split('+'): lumi += miniutils.lumi_dict.get(year, 0.) lumi /= 1000. data_label = '#sqrt{s} = 13 TeV, %.1f fb^{-1}' % lumi # ------------------ # Results output dir # ------------------ susy_dir = os.environ['SUSY_ANALYSIS'] results_dir = args.output_dir log_dir = '%s/log' % results_dir histograms_dir = '%s/histograms' % results_dir fit_dir = '%s/fit' % results_dir tables_dir = '%s/tables' % results_dir plots_dir = '%s/plots' % results_dir mkdirp(results_dir) mkdirp(log_dir) mkdirp(histograms_dir) mkdirp(fit_dir) mkdirp(tables_dir) mkdirp(plots_dir) #------------------- # Create Histograms #------------------- histograms_txt_path = '%s/histograms_cuts.txt' % (histograms_dir) histograms_path = '%s/histograms_cuts.root' % (histograms_dir) if step_chist and (not os.path.isfile(histograms_path) or args.force): print('Creating cuts histograms ...') do_histograms(histograms_path, regions, samples, do_det_syst, do_dd_syst, do_mc_syst, data, version, unblind, ignore_missing=args.ignore_missing) # Observables distributions histograms_plots_path = '%s/histograms_plots.root' % (histograms_dir) histograms_plots_before_path = '%s/histograms_plots_before.root' % ( histograms_dir) histograms_plots_after_path = '%s/histograms_plots_after.root' % ( histograms_dir) if step_dhist and (not os.path.isfile(histograms_plots_path) or args.force or args.sample is not None): print('Creating histograms for plots ...') if args.force and os.path.isfile(histograms_plots_path): os.remove(histograms_plots_path) if args.sample is not None: do_plots_histograms(histograms_plots_path, plot_regions, args.sample.split(','), plot_variables, data, version) else: do_plots_histograms(histograms_plots_path, plot_regions, samples, plot_variables, data, version, ignore_missing=args.ignore_missing) #-------------- # Bkg-only Fit #-------------- if args.conf is not None: configfile = os.path.abspath(args.conf) else: configfile = susy_dir + '/lib/PhotonMet_HistFitter_config.py' ws = fit_dir + "/BkgOnlyFit_combined_BasicMeasurement_model_afterFit.root" if step_fit: print('Performing bkg-only fit ...') do_bkgonlyfit(configfile, histograms_path, fit_dir, sr_str, lumi, do_validation, syst_str, use_mc, '%s/bkgonlyfit.log' % log_dir, hf_options='-D correlationMatrix') # -m ALL #-------- # Tables #-------- if step_tables: print('Creating tables ...') do_tables(ws, tables_dir, backgrounds, regions, sr_str, do_validation, unblind, (do_det_syst or do_mc_syst or do_dd_syst), plot_bkg_norm_dict) #------- # Plots #------- if step_plots: print('Preparing histograms for plots...') prepare_histograms_for_plots(histograms_plots_path, histograms_plots_before_path, plot_regions, backgrounds, plot_variables, merge_dict=plot_bkg_merge_dict) prepare_histograms_for_plots(histograms_plots_path, histograms_plots_after_path, plot_regions, backgrounds, plot_variables, merge_dict=plot_bkg_merge_dict, ws=ws, norm_dict=plot_bkg_norm_dict) ## Pull plot print('Creating pull plot ...') do_regions_pull_plot(ws, plots_dir + '/regions_pull.pdf', backgrounds, plot_bkgs, regions, plot_bkg_merge_dict, unblind=unblind, data_label=data_label) #do_regions_pull_plot(ws, plots_dir+'/regions_pull_significance.pdf', backgrounds, plot_bkgs, regions, plot_bkg_merge_dict, unblind=unblind, data_label=data_label, plot_significance=True) set_atlas_style() # Before fit plots print('Creating before-fit plots ...') do_plots(histograms_plots_before_path, plots_dir, plot_regions, plot_bkgs, plot_variables, data_label, unblind=unblind, output_label='beforeFit') # After fit plots print('Creating after-fit plots ...') do_plots(histograms_plots_after_path, plots_dir, plot_regions, plot_bkgs, plot_variables, data_label, unblind=unblind, output_label='afterFit')
h_yields_norm.SetBinContent(counter, norm_yield) h_yields_norm.SetBinError(counter, error/lumi) print run, norm_yield # avgmu htemp = ROOT.TH1D('avgmu_%i' % run, 'avgmu', 50, 0., 50.) tree.Project('avgmu_%i' % run, 'avgmu', selection) h_avgmu.SetBinContent(counter, htemp.GetMean()) counter += 1 set_atlas_style() set_style(h_yields_norm, color=ROOT.kBlack, lwidth=1) set_style(h_avgmu, color='pink', lwidth=1, alpha=0.5) c = ROOT.TCanvas('', '', 2400, 600) c.SetFillColor(0) c.SetBorderMode(0) c.SetBorderSize(2) c.SetTicks(0,1) c.SetTickx(0) c.SetTopMargin (0.03) c.SetRightMargin(0.02) c.SetLeftMargin (0.05) c.SetBottomMargin (0.1)