def addProcess(self, pname, histo1D): if options.mode == 'prefit': another_dummy_template_name = self._channame + '__fdummy' + '_dummy_template' another_dummy_template = Template(another_dummy_template_name, another_dummy_template_name, None) another_dummy_template.make_from_1D_histo(histo1D) histo1D = another_dummy_template.convertTo1D() self._processes.append(Process(pname, histo1D))
def buildResiduals(self): #first get the 1D input data graph from the initial template file and copy it into a 1D histogram like in the MC processes cnameapps = ['plus', 'minus'] if options.sumCharges else [''] newname = self._channame + '__data_obs' newdatatemp = Template(newname + '__POSTFIT', newname + '__POSTFIT', None) data1Dhisto = None if options.mode == 'postfit': combine_filep = TFile.Open(options.cfilename) data1Dhisto = self._processes[0].getHisto1D().Clone() data1Dhisto.SetDirectory(0) data1Dhisto.Reset() cnamesplit = self._channame.split('_') for cnameapp in cnameapps: realchanname = cnamesplit[0] + '_' + cnamesplit[ 1] + cnameapp + '_' + cnamesplit[2] if len(cnamesplit) == 4: realchanname += '_' + cnamesplit[3] data_graph = combine_filep.Get('shapes_fit_s/%s/data' % (realchanname)) # print ' ngraphpoints=%d data1Dhisto: nbins=%d, integral before filling=%.2f'%(data_graph.GetN(),data1Dhisto.GetSize()-2,data1Dhisto.Integral()) #DEBUG for i in range(data_graph.GetN()): px = array('d', [0.]) py = array('d', [0.]) data_graph.GetPoint(i, px, py) err = data_graph.GetErrorY(i) # if i==350 or i==475 : #DEBUG # print ' bin %d in data has px=%d, py=%.4f, err=%.4f'%(i,px[0],py[0],err) #DEBUG data1Dhisto.Fill(px[0], py[0]) #olderr = data1Dhisto.GetBinError(data1Dhisto.FindFixBin(px[0])) #data1Dhisto.SetBinError(data1Dhisto.FindFixBin(px[0]),sqrt(olderr**2+err**2)) data1Dhisto.SetBinError(data1Dhisto.FindFixBin(px[0]), err) combine_filep.Close() elif options.mode == 'prefit': initial_templates_file = TFile(options.tfilename) data1Dhisto = initial_templates_file.Get(newname).Clone() data1Dhisto.SetDirectory(0) initial_templates_file.Close() newdatatemp.make_from_1D_histo(data1Dhisto) #self._data_histo_x=newdatatemp.getHistoX() #self._data_histo_y=newdatatemp.getHistoY() #self._data_histo_z=newdatatemp.getHistoZ() self._data_histo_1D = newdatatemp.convertTo1D() # print ' plot group data histos: 1D=%s, x=%s, y=%s, z=%s (integrals: 1D=%.2f, x=%.2f, y=%.2f, z=%.2f)'%(data1Dhisto,self._data_histo_x,self._data_histo_y,self._data_histo_z,data1Dhisto.Integral(),self._data_histo_x.Integral(),self._data_histo_y.Integral(),self._data_histo_z.Integral()) #DEBUG #add them to the plot #self._x_plot.setDataHisto(self._data_histo_x) #self._y_plot.setDataHisto(self._data_histo_y) #self._z_plot.setDataHisto(self._data_histo_z) self._1D_plot.setDataHisto(self._data_histo_1D) #calculate residuals #self._x_plot.calculateResiduals() #self._y_plot.calculateResiduals() #self._z_plot.calculateResiduals() self._1D_plot.calculateResiduals()
def smooth_templates_1D_slices(nom, up, dn): #make template objects from the unrolled distributions uptemplate = Template(up.GetName(), up.GetTitle(), None) dntemplate = Template(dn.GetName(), dn.GetTitle(), None) uptemplate.make_from_1D_histo(up) dntemplate.make_from_1D_histo(dn) #loop over the 2D histos and smooth them olduphistos = uptemplate.getHistos() olddnhistos = dntemplate.getHistos() newuphistos = {} newdnhistos = {} for yt, h in olduphistos.items(): new_h = h.Clone() new_h.Reset() for i in range(1, h.GetNbinsY() + 1): h.GetYaxis().SetRange(i, i) projhisto = h.ProjectionX() projhisto.Smooth(1, smoothing_algo) for j in range(1, projhisto.GetNbinsX()): new_h.SetBinContent(j, i, projhisto.GetBinContent(j)) new_h.SetBinError(j, i, projhisto.GetBinError(j)) h.GetYaxis().SetRange() newuphistos[yt] = new_h for yt, h in olddnhistos.items(): new_h = h.Clone() new_h.Reset() for i in range(1, h.GetNbinsY() + 1): h.GetYaxis().SetRange(i, i) projhisto = h.ProjectionX() projhisto.Smooth(1, smoothing_algo) for j in range(1, projhisto.GetNbinsX()): new_h.SetBinContent(j, i, projhisto.GetBinContent(j)) new_h.SetBinError(j, i, projhisto.GetBinError(j)) h.GetYaxis().SetRange() newdnhistos[yt] = new_h #reset the template object histos, convert them 1D, correct, and return them uptemplate.setHistos(newuphistos) dntemplate.setHistos(newdnhistos) newup = uptemplate.convertTo1D() newdn = dntemplate.convertTo1D() return correct_template(nom, newup, newdn)
def smooth_templates_2D_slices(nom, up, dn): #make template objects from the unrolled distributions uptemplate = Template(up.GetName(), up.GetTitle(), None) dntemplate = Template(dn.GetName(), dn.GetTitle(), None) uptemplate.make_from_1D_histo(up) dntemplate.make_from_1D_histo(dn) #loop over the 2D histos and smooth them olduphistos = uptemplate.getHistos() olddnhistos = dntemplate.getHistos() newuphistos = {} newdnhistos = {} for yt, h in olduphistos.items(): h.Smooth(1, smoothing_algo) newuphistos[yt] = h for yt, h in olddnhistos.items(): h.Smooth(1, smoothing_algo) newdnhistos[yt] = h #reset the template object histos, convert them 1D, correct, and return them uptemplate.setHistos(newuphistos) dntemplate.setHistos(newdnhistos) newup = uptemplate.convertTo1D() newdn = dntemplate.convertTo1D() return correct_template(nom, newup, newdn)
def rebin2DSlicesFrom1D(hist, xrbin=5, yrbin=5): #make a template object for the old 1D histogram name_fine = hist.GetName() + '_fine' name_coarse = hist.GetName() + '_coarse' temp_fine = Template(name_fine, name_fine, None, binning='fine') temp_fine.make_from_1D_histo(hist) #get this template in three dimensions histo3D_fine = temp_fine.getHisto3D() #make a list of x-y projected 2D histograms, one for each Z bin proj_histos = {} nzbins = histo3D_fine.GetZaxis().GetNbins() for i in range(1, nzbins + 1): histo3D_fine.GetZaxis().SetRange(i, i) #projstring='yxe' if i==1 else 'yx' projstring = 'yx' newprojhisto = histo3D_fine.Project3D(projstring) proj_histos[i] = newprojhisto.Clone(newprojhisto.GetName() + '_' + str(i)) histo3D_fine.GetZaxis().SetRange(-1, nzbins + 5) #rebin each projection rebinned_proj_histos = {} for zbin, proj_histo in proj_histos.iteritems(): proj_histo.Rebin2D(xrbin, yrbin) rebinned_proj_histos[zbin] = proj_histo #build the new, coarsely-binned total template back up from its projections temp_coarse = Template(name_coarse, name_coarse, None, binning='coarse') histo3D_coarse = temp_coarse.getHisto3D() nxbins = histo3D_coarse.GetXaxis().GetNbins() nybins = histo3D_coarse.GetYaxis().GetNbins() for k in range(1, nzbins + 1): thisprojhisto = rebinned_proj_histos[k] for i in range(1, nxbins + 1): for j in range(1, nybins + 1): histo3D_coarse.SetBinContent( histo3D_coarse.GetBin(i, j, k), thisprojhisto.GetBinContent(thisprojhisto.GetBin(i, j, k))) temp_coarse.setHistos([ histo3D_coarse, histo3D_coarse.ProjectionX(), histo3D_coarse.ProjectionY(), histo3D_coarse.ProjectionZ() ]) returntemplate, garbage = temp_coarse.convertTo1D() return returntemplate
def __init__(self, channame, dim, lPos=3, iPos=11): self._dim = dim #dimension (x,y,z) plotvars = {'x': 'c*', 'y': '|x_{F}|', 'z': 'M', '1D': 'Template bin'} self._plotvar = plotvars[self._dim] #string of plot variable self._lPos = lPos self._iPos = iPos self._channame = channame #name of the channel this plot belongs to self._canvsize = (1100, 900) if self._channame.startswith('t3'): self._canvsize = (5500, 900) #pieces of the plot #MC stack self._MC_stack = THStack(channame + '_' + self._dim + '_stack', ';;Events/bin') #list of MC histograms for legend self._MC_histos = [] #make a new template to clone histogram shapes from dummy_template_name = channame + '__' + self._dim + '_dummy_template' dummy_template = Template(dummy_template_name, dummy_template_name, None) #clone histogram for MC error histograms, residual plots, and MC err residuals self._MC_err_histo = None self._resid = None self._MC_err_resid = None if self._dim == 'x': self._MC_err_histo = dummy_template.getHistoX().Clone() self._resid = dummy_template.getHistoX().Clone() self._MC_err_resid = dummy_template.getHistoX().Clone() elif self._dim == 'y': self._MC_err_histo = dummy_template.getHistoY().Clone() self._resid = dummy_template.getHistoY().Clone() self._MC_err_resid = dummy_template.getHistoY().Clone() elif self._dim == 'z': self._MC_err_histo = dummy_template.getHistoZ().Clone() self._resid = dummy_template.getHistoZ().Clone() self._MC_err_resid = dummy_template.getHistoZ().Clone() elif self._dim == '1D': self._MC_err_histo = dummy_template.convertTo1D().Clone() self._resid = dummy_template.convertTo1D().Clone() self._MC_err_resid = dummy_template.convertTo1D().Clone() if self._MC_err_histo == None: print 'ERROR: could not get histogram cloned for plot dimension %s in channel %s' % ( self._dim, self._channame) #Set attributes and directories #MC err histograms self._MC_err_histo.SetFillColor(kBlack) self._MC_err_histo.SetMarkerStyle(1) self._MC_err_histo.SetFillStyle(3013) self._MC_err_histo.SetStats(0) self._MC_err_histo.SetDirectory(0) #residual plots self._resid.SetTitle(';' + self._plotvar + ';Data/MC') self._resid.SetStats(0) self._resid.SetMarkerStyle(20) self._resid.SetDirectory(0) #MC err residuals self._MC_err_resid.SetTitle(';' + self._plotvar + ';Data/MC') self._MC_err_resid.SetFillColor(kBlack) self._MC_err_resid.SetStats(0) self._MC_err_resid.SetMarkerStyle(1) self._MC_err_resid.SetFillStyle(3013) self._MC_err_resid.SetDirectory(0) #"oneline" to go at y=1. on the residuals plot self._oneline = TLine( self._resid.GetXaxis().GetBinLowEdge(1), 1., self._resid.GetXaxis().GetBinUpEdge(self._resid.GetNbinsX()), 1.) self._oneline.SetLineWidth(3) self._oneline.SetLineStyle(2) #initialize the legend legwidth = 0.622 legheight = 0.272 if self._channame.startswith('t3'): legwidth = 0.561 legheight = 0.183 x2 = 0.922 y2 = 0.857 #if self._lPos==1 : # x2 = 0.44 #elif self._lPos==2 : # x2 = 0.7 self._leg = TLegend(x2 - legwidth, y2 - legheight, x2, y2) if self._channame.startswith('t3'): self._leg.SetNColumns(3) else: self._leg.SetNColumns(2) self._lumi_obj = None self._pnames_added_to_leg = [] #make the channel identifier text (and the key for the plot info) self._chanTxt = 'Type-' + self._channame.split('_')[0].split('t')[1] self._ckey = 't' + self._channame.split('_')[0].split('t')[1] + '_' if self._channame.split('_')[1].startswith('mu'): self._chanTxt += ' #mu+jets' self._ckey += 'mu' elif self._channame.split('_')[1].startswith('el'): self._chanTxt += ' e+jets' self._ckey += 'el' self._chanTxt += ' (' if self._channame.split('_')[1].endswith('plus'): self._chanTxt += 'Q>0 ' self._ckey += 'plus' elif self._channame.split('_')[1].endswith('minus'): self._chanTxt += 'Q<0 ' self._ckey += 'minus' if self._channame.find('SR') != -1: self._chanTxt += 'SR)' self._ckey += '_SR' elif self._channame.find('WJets_CR') != -1: self._chanTxt += 'W+jets CR)' self._ckey += '_CR'
all_fps[sn + '_dn'] = TFile( simple_add_files_dict[sn]['Down']['temp'], 'r') orig_dn_template = all_fps[sn + '_dn'].Get(old_template_name) #renormalize to the same event yield as the nominal template orig_up_template.Scale(nominal_template.Integral() / orig_up_template.Integral()) orig_dn_template.Scale(nominal_template.Integral() / orig_dn_template.Integral()) #create new Template objects for up/down scenarios and get their unfilled 1D templates new_up_template_obj = Template( new_template_name_up, old_template_name + ' ' + sn + ' up template', None) new_dn_template_obj = Template( new_template_name_dn, old_template_name + ' ' + sn + ' down template', None) new_up_template_histo = new_up_template_obj.convertTo1D() new_dn_template_histo = new_dn_template_obj.convertTo1D() #loop over the bins for i in range(1, nominal_template.GetNbinsX() + 1): nomcont = nominal_template.GetBinContent(i) upcont = orig_up_template.GetBinContent(i) dncont = orig_dn_template.GetBinContent(i) #set the up/down templates' bin contents equal to nominal +/- 1/2 up-down shift = 0.5 * (upcont - dncont) new_up_template_histo.SetBinContent(i, nomcont + shift) new_dn_template_histo.SetBinContent(i, nomcont - shift) ##set the up/down templates' bin contents equal to their original values #new_up_template_histo.SetBinContent(i,upcont) #new_dn_template_histo.SetBinContent(i,dncont) #correct the templates new_up_template_histo = correct_template(nominal_template,
def smooth_templates_polynomial_fit(nom, up, dn): #make template objects from the unrolled distributions nomtemplate = Template(nom.GetName(), nom.GetTitle(), None) uptemplate = Template(up.GetName(), up.GetTitle(), None) dntemplate = Template(dn.GetName(), dn.GetTitle(), None) nomtemplate.make_from_1D_histo(nom) uptemplate.make_from_1D_histo(up) dntemplate.make_from_1D_histo(dn) #loop over the 2D histos and smooth them oldnomhistos = nomtemplate.getHistos() olduphistos = uptemplate.getHistos() olddnhistos = dntemplate.getHistos() newuphistos = {} newdnhistos = {} func = TF1( 'f', 'pol3', -1., 1., ) for yt, h in olduphistos.items(): if h.GetNbinsX() > 2: new_h = h.Clone() new_h.Reset() for i in range(1, h.GetNbinsY() + 1): fcfp.cd() projhisto = h.ProjectionX('_px', i, i, 'e') nomprojhisto = oldnomhistos[yt].ProjectionX( '_nompx', i, i, 'e') for j in range(1, projhisto.GetNbinsX() + 1): projhisto.SetBinContent( j, projhisto.GetBinContent(j) / nomprojhisto.GetBinContent(j)) projhisto.Fit('f') print('{} + {} * x + {} * x**2 + {} * x**3'.format( func.GetParameter(0), func.GetParameter(1), func.GetParameter(2), func.GetParameter(3))) #print('i={}, nbinsX={}'.format(i,projhisto.GetNbinsX())) for j in range(1, projhisto.GetNbinsX() + 1): x1 = projhisto.GetBinLowEdge(j) x2 = x1 + projhisto.GetBinWidth(j) #new_h.SetBinContent(j,i,func.Integral(x1,x2)) #new_h.SetBinContent(j,i,0.5*(func.Eval(projhisto.GetBinCenter(j))+projhisto.GetBinContent(j))) new_h.SetBinContent( j, i, nomprojhisto.GetBinContent(j) * func.Eval(projhisto.GetBinCenter(j))) new_h.SetBinError(j, i, projhisto.GetBinError(j)) #print('i={}, j={}, x1 = {}, x2 = {}, oldcont = {}, cont = {}, err = {}'.format(i,j,x1,x2,projhisto.GetBinContent(j),func.Eval(projhisto.GetBinCenter(j)),projhisto.GetBinError(j))) fitcanv = TCanvas( up.GetName() + '_' + str(yt) + '_' + str(i) + '_fit', up.GetName() + '_' + str(yt) + '_' + str(i) + '_fit', 1100, 900) projhisto.Draw("HIST") func.Draw("SAME") fitcanv.Write() #new_h.Scale(h.Integral()/new_h.Integral()) #new_h.Scale(oldnomhistos[yt].Integral()/new_h.Integral()) newuphistos[yt] = new_h else: newuphistos[yt] = h for yt, h in olddnhistos.items(): if h.GetNbinsX() > 2: new_h = h.Clone() new_h.Reset() for i in range(1, h.GetNbinsY() + 1): fcfp.cd() projhisto = h.ProjectionX('_px', i, i, 'e') nomprojhisto = oldnomhistos[yt].ProjectionX( '_nompx', i, i, 'e') for j in range(1, projhisto.GetNbinsX() + 1): projhisto.SetBinContent( j, projhisto.GetBinContent(j) / nomprojhisto.GetBinContent(j)) projhisto.Fit('f') print('{} + {} * x + {} * x**2 + {} * x**3'.format( func.GetParameter(0), func.GetParameter(1), func.GetParameter(2), func.GetParameter(3))) #print('i={}, nbinsX={}'.format(i,projhisto.GetNbinsX())) for j in range(1, projhisto.GetNbinsX() + 1): x1 = projhisto.GetBinLowEdge(j) x2 = x1 + projhisto.GetBinWidth(j) #new_h.SetBinContent(j,i,func.Integral(x1,x2)) #new_h.SetBinContent(j,i,0.5*(func.Eval(projhisto.GetBinCenter(j))+projhisto.GetBinContent(j))) new_h.SetBinContent( j, i, nomprojhisto.GetBinContent(j) * func.Eval(projhisto.GetBinCenter(j))) new_h.SetBinError(j, i, projhisto.GetBinError(j)) #print('i={}, j={}, x1 = {}, x2 = {}, oldcont = {}, cont = {}, err = {}'.format(i,j,x1,x2,projhisto.GetBinContent(j),func.Eval(projhisto.GetBinCenter(j)),projhisto.GetBinError(j))) fitcanv = TCanvas( dn.GetName() + '_' + str(yt) + '_' + str(i) + '_fit', dn.GetName() + '_' + str(yt) + '_' + str(i) + '_fit', 1100, 900) projhisto.Draw("HIST") func.Draw("SAME") fitcanv.Write() #new_h.Scale(h.Integral()/new_h.Integral()) #new_h.Scale(oldnomhistos[yt].Integral()/new_h.Integral()) newdnhistos[yt] = new_h else: newdnhistos[yt] = h #reset the template object histos, convert them 1D, correct, and return them uptemplate.setHistos(newuphistos) dntemplate.setHistos(newdnhistos) newup = uptemplate.convertTo1D() newdn = dntemplate.convertTo1D() return correct_template(nom, newup, newdn)