def make_h_fcn(nm, fcn): h = ROOT.TH1D(nm, '%s - %s' % (fn1, fn2), nnames, 0, nnames) h_fcns.append((h, fcn)) return h
def make_signals_2015p6(f, name_list): # Pull 2015+6 values from previous-format limitsinput file(s). # (Not all 2017+8 signal points exist in the final one for the # 2016 paper, but we make new ones now using the scanpack2017p8_2016 branch.) # Rescale+add how SignalEfficiencyCombiner did previously. Go # ahead and store the rate already scaled by the integrated # luminosity. This makes the 2016 weighted sum situation easier # downstream. fnpairs = [ # (hip, nonhip)--the first pair are to be the final 2016 paper one, the rest define newly generated signal points ('/uscms/home/tucker/public/mfv/limitsinput_data_v15v5_scanpack_merge_hip_1_2_2p6_3_3p6_removeddbar.root', '/uscms/home/tucker/public/mfv/limitsinput_data_v15v5_scanpack_merge_1_1p5_2_2p5_2p7_3_3p5_removeddbar.root',), ('/uscms/home/tucker/public/mfv/limitsinput_scanpack1D2016missing_hip.root', '/uscms/home/tucker/public/mfv/limitsinput_scanpack1D2016missing.root',), ('/uscms/home/tucker/public/mfv/limitsinput_scanpack4p6_hip.root', '/uscms/home/tucker/public/mfv/limitsinput_scanpack4p6.root',), ] def trigmult2016(x): return 1 # this was 0.99 in signal_efficiency, but now it's already in int_lumi at top def sf20156(x, pars=(0.9784, -1128., 1444.)): return trigmult2016(x) * (2. - pars[0] * ROOT.TMath.Erf((x-pars[1])/pars[2])) sfs = [sf20156, trigmult2016, trigmult2016] int_lumis = [2592.4, 19492., 16059.] for ipair, (fn_2016_hip, fn_2016_nonhip) in enumerate(fnpairs): name_list['title'] = name_list.get('title', '') + '+%s+%s' % (fn_2016_hip, fn_2016_nonhip) f_2015 = f_2016 = f_2016_nonhip = ROOT.TFile.Open(fn_2016_nonhip) f_2016_hip = ROOT.TFile.Open(fn_2016_hip) h_name_list_2016 = f_2016_nonhip.Get('name_list') # already checked that the two files are in sync def _hs(n): return [f_2015.Get(n), f_2016_hip.Get(n), f_2016_nonhip.Get(n)] nsigs = h_name_list_2016.GetNbinsX() for ibin in xrange(1, nsigs+1): if (ibin-1)%(nsigs/20) == 0: sys.stdout.write('\rmake_signals_2015p6: pair %i/%i, %i/%i' % (ipair+1, len(fnpairs), ibin, nsigs)); sys.stdout.flush() old_isample = -ibin new_isample = old_isample if ipair == 0 else signalset.next_isample() old_bn = 'h_signal_%i_' % old_isample new_bn = 'h_signal_%i_' % new_isample # convert sample name to new format--really only more digits in tau field old_name = f_2016.Get(old_bn + 'norm').GetTitle() mass = name2mass(old_name) # needed in scalefactor too new_name = details2name(name2kind(old_name), name2tau(old_name), mass) if name_list.has_key(new_name): print colors.warning('\nwarning: %s found in ipair %i with isample %i was found in previous ipair %s with isample %i, skipping' % (new_name, ipair, old_isample, name_list[new_name].ipair, name_list[new_name].isample)) continue name_list[new_name] = ss = signalset(new_name, '2016', new_isample) ss.ipair = ipair norms = _hs(old_bn + 'norm') ngens = [1e-3/h.GetBinContent(2) for h in norms] ngentot = sum(ngens[1:]) # hip/nonhip are the only independent samples, 2015 is just 2016 that we rescale for n in 'dbv', 'dphi', 'dvv', 'dvv_rebin': hs = _hs(old_bn + n) for h,ng,sf,il in zip(hs, ngens, sfs, int_lumis): if n == 'dbv' or n == 'dvv': h.Rebin(10) # did too many bins last time h.Scale(sf(mass) * 1e-3 * il / ng) h = hs.pop(0) for h2 in hs: h.Add(h2) h.SetName(new_bn + n + '_2016') h.SetTitle(new_name + '_2016') f.cd(); h.Write() f.cd() h = ROOT.TH1D(new_bn + 'uncert_2016', new_name + '_2016', gp.nbins, gp.bins) uncerts = [0.24, sig_uncert_pdf(new_name + '_2016')] # ignore old hist, just use the previous total 24% for ib in xrange(1,gp.nbins+1): h.SetBinContent(ib, 1+sum(x**2 for x in uncerts)**0.5) h.Write() h = ROOT.TH1D(new_bn + 'ngen_2016', new_name + '_2016', 1,0,1) h.SetBinContent(1, ngentot) h.Write() print '\rmake_signals_2015p6: done with pair %i ' % (ipair+1)
def make_signals_2017p8(f, name_list): # 2017,8 are from minitrees (the 100kevt official samples) and scanpack. scanpack_list = '/uscms/home/tucker/public/mfv/scanpacks/2017p8/scanpack1D_4_4p7_4p8.merged.list.gz' trees = '/uscms_data/d2/tucker/crab_dirs/MiniTreeV27m/mfv*.root' title = [] sigs = {} if scanpack_list: title.append(scanpack_list) sigs.update(eval(GzipFile(scanpack_list).read())) if trees: title.append(trees) sigs.update({os.path.basename(fn).replace('.root', '') : [fn] for fn in sorted(glob(trees))}) # overrides scanpack entries name_list['title'] = name_list.get('title', '') + '+' + '+'.join(title) nsigs = len(sigs) for isig, (name_year, fns) in enumerate(sigs.iteritems()): if isig%(nsigs/20) == 0: sys.stdout.write('\rmake_signals_2017p8: %i/%i' % (isig, nsigs)); sys.stdout.flush() name, year = name_year.rsplit('_',1) if name_list.has_key(name): s = name_list[name] s.years.add(year) else: s = name_list[name] = signalset(name, year) n = lambda x: 'h_signal_%i_%s_%s' % (s.isample, x, year) ngen = 0. t = ROOT.TChain('mfvMiniTree/t') for fn in fns: sig_f = ROOT.TFile.Open(fn) ngen += sig_f.Get('mfvWeight/h_sums').GetBinContent(1) sig_f.Close() t.Add(fn) if year == '2017' and gp.l1eeprefiring_2017: t.SetAlias('jet_l1ee', 'abs(jet_eta) > 2.25 && jet_pt > 100') t.SetAlias('njets_l1ee', 'Sum$(!jet_l1ee)') t.SetAlias('jetht_l1ee', 'Sum$(jet_pt * (jet_pt > 40 && !jet_l1ee))') t.SetAlias('limitsinput_pass', '(njets_l1ee >= 4 && jetht_l1ee >= 1200)') elif year == '2018' and gp.hem1516_2018: t.SetAlias('jet_hem1516', 'jet_eta < -1.3 && jet_phi < -0.87 && jet_phi > -1.57') t.SetAlias('njets_hem1516', 'Sum$(!jet_hem1516)') t.SetAlias('jetht_hem1516', 'Sum$(jet_pt * (jet_pt > 40 && !jet_hem1516))') t.SetAlias('limitsinput_pass', '(njets_hem1516 >= 4 && jetht_hem1516 >= 1200) || (rndm < 0.36)') # silly way to represent effect only on 64% of the data else: t.SetAlias('limitsinput_pass', '1==1') iyear = gp.years.index(year) scale = 1e-3 * gp.int_lumis[iyear] / ngen data_mc_scale = sig_datamcSF_2017p8(name_year) ROOT.TH1.AddDirectory(1) # the Draw>> output goes off into the ether without this stupid crap h_dbv = ROOT.TH1D(n('dbv'), '', 1250, 0, 2.5) h_dvv = ROOT.TH1D(n('dvv'), '', 400, 0, 4) h_dphi = ROOT.TH1D(n('dphi'), '', 10, -3.15, 3.15) t.Draw('dist0>>%s' % n('dbv'), 'weight*(limitsinput_pass && nvtx==1)') t.Draw('svdist>>%s' % n('dvv'), 'weight*(limitsinput_pass && nvtx>=2)') t.Draw('svdphi>>%s' % n('dphi'), 'weight*(limitsinput_pass && nvtx>=2)') ROOT.TH1.AddDirectory(0) for h in h_dbv, h_dvv, h_dphi: h.SetDirectory(0) h.Scale(scale) if 'dbv' in h.GetTitle(): h.Scale(data_mc_scale) else: h.Scale(data_mc_scale**2) h_dvv_rebin = h_dvv.Rebin(gp.nbins, n('dvv_rebin'), gp.bins) move_overflow_into_last_bin(h_dvv_rebin) h_ngen = ROOT.TH1D(n('ngen'), '', 1,0,1) h_ngen.SetBinContent(1, ngen) h_uncert = ROOT.TH1D(n('uncert'), '', gp.nbins, gp.bins) for i,v in enumerate(sig_uncert_2017p8(name_year)): h_uncert.SetBinContent(i+1, v) f.cd() for h in h_dbv, h_dphi, h_dvv, h_dvv_rebin, h_uncert, h_ngen: h.SetTitle(name_year) h.Write() print '\rmake_signals_2017p8: done '
def make_bkg(f): # the first 3 sets of values override what's in 2v_from_jets observed = (1,0,0), (0,0,0), (0,0,0) bkg_n1v = 1183, 1303, 908 bkg_n2v = 1, 0.241, 0.111 # this is not supposed to be the sum of observed, but could/should be set to the pre-fit expectation (predict2v.py) # but bkg_c1v is checked against what's in 2v_from_jets bkg_c1v = (0.509, 0.374, 0.117), (0.709, 0.257, 0.034), (0.650, 0.313, 0.037) bkg_uncert = [(1.25, 1.25, 1.69), (1.16, 1.30, 1.51), (1.19, 1.30, 1.91)] # combine lnN convention import statmodel bkg_uncert_stat = [statmodel.ebins['data100pc_%s_5track' % year] for year in gp.years] for y in xrange(gp.nyears): bkg_uncert[y] = [(a**2 + b**2)**0.5 for a,b in zip(bkg_uncert[y], bkg_uncert_stat[y])] # JMTBAD use proper gmN? bkg_stat_uncert = [(1.071, 1.128, 1.465), (1.173, 1.216, 1.454), (1.217, 1.238, 1.586)] # stat errors uncorrelated bkg_syst_uncert = [(0.758, 1.218, 1.542), (0.743, 1.338, 1.389), (0.766, 1.315, 1.760)] # syst error anti-correlated def bkg_fn(year, which='default'): path = '/uscms/home/tucker/public/mfv/' if year == '2016': return path + '2v_from_jets_data_2015p6_5track_default_v15_v5.root' else: if which == 'c': which = 'btag_corrected_nom' else: assert which == 'default' return path + '2v_from_jets_data_%s_5track_%s_V27m.root' % (year, which) def bkg_f(year, which='default', _c={}): k = year, which if not _c.has_key(k): _c[k] = ROOT.TFile.Open(bkg_fn(*k)) return _c[k] def cbkg_f(year): return bkg_f(year, which='c') ## print 'make_bkg:', for y, year in enumerate(gp.years): h_int_lumi = ROOT.TH1D('h_int_lumi_%s' % year, '', 1, 0, 1) h_int_lumi.SetBinContent(1, gp.int_lumis[y]) h_observed = ROOT.TH1D('h_observed_%s' % year, '', gp.nbins, gp.bins) for i,v in enumerate(observed[y]): h_observed.SetBinContent(i+1, v) h_bkg_dbv = to_TH1D( bkg_f(year).Get('h_1v_dbv'), 'h_bkg_dbv_%s' % year) h_bkg_dvv = to_TH1D(cbkg_f(year).Get('h_c1v_dvv'), 'h_bkg_dvv_%s' % year) h_bkg_dbv.Scale(bkg_n1v[y]/get_integral(h_bkg_dbv)[0]) h_bkg_dvv.Scale(bkg_n2v[y]/get_integral(h_bkg_dvv)[0]) h = h_bkg_dvv_rebin = h_bkg_dvv.Rebin(gp.nbins, 'h_bkg_dvv_rebin_%s' % year, gp.bins) move_overflow_into_last_bin(h_bkg_dvv_rebin) for i in xrange(gp.nbins): if abs(bkg_c1v[y][i] - h.GetBinContent(i+1)/bkg_n2v[y]) > 0.001: print y,i, bkg_c1v[y][i], h.GetBinContent(i+1)/bkg_n1v[y] assert 0 h_bkg_uncert = ROOT.TH1D('h_bkg_uncert_%s' % year, '', gp.nbins, gp.bins) h_bkg_stat_uncert = ROOT.TH1D('h_bkg_uncert_stat_%s' % year, '', gp.nbins, gp.bins) h_bkg_syst_uncert = ROOT.TH1D('h_bkg_uncert_syst_%s' % year, '', gp.nbins, gp.bins) for i,v in enumerate(bkg_uncert[y]): h_bkg_uncert.SetBinContent(i+1, v) for i,v in enumerate(bkg_stat_uncert[y]): h_bkg_stat_uncert.SetBinContent(i+1, v) for i,v in enumerate(bkg_syst_uncert[y]): h_bkg_syst_uncert.SetBinContent(i+1, v) f.cd() for h in h_int_lumi, h_observed, h_bkg_dbv, h_bkg_dvv, h_bkg_dvv_rebin, h_bkg_uncert, h_bkg_stat_uncert, h_bkg_syst_uncert: h.SetTitle('') h.Write() print 'done'