def checkSignalContamination(config, outDir, lumi, box, model, mLSP, mGluino=-1, mStop=-1, mergeBins=False, treeName="RazorInclusive"):
    cfg = Config.Config(config)
    x = array('d', cfg.getBinning(box)[0]) # MR binning
    y = array('d', cfg.getBinning(box)[1]) # Rsq binning
    z = array('d', cfg.getBinning(box)[2]) # nBtag binning

    unrollBins = None
    if mergeBins:
        btagBins = cfg.getBinning(box)[2][:-1]
        unrollBins = [(xbinsSignal[box][str(int(btags))+'B'], colsSignal[box][str(int(btags))+'B']) for btags in btagBins]
    
    mergeBinsString = ''
    if mergeBins:
        mergeBinsString = '--merge-bins'

    brString = ""
    if 'T1x' in model:
        xBR = float(model[model.find('x')+1:model.find('y')].replace('p','.'))
        yBR = float(model[model.find('y')+1:].replace('p','.'))
        brString = '--xBR %.2f --yBR %.2f'%(xBR,yBR)
        modelName = 'SMS-%s_%i_%i'%(model,mGluino,mLSP)
        fileName = SIGNAL_DIR+'/SMS-T1ttbb_%i_%i.root'%(mGluino,mLSP)
    elif 'T2' in model:
        modelName = 'SMS-%s_%i_%i'%(model,mStop,mLSP)
        fileName = SIGNAL_DIR+'/%s.root'%(modelName)
    else:
        modelName = 'SMS-%s_%i_%i'%(model,mGluino,mLSP)
        fileName = SIGNAL_DIR+'/%s.root'%(modelName)
        
    os.system('python python/SMSTemplates.py %s -c %s -d %s/ --lumi %s --box %s --no-signal-sys %s %s'%(mergeBinsString,config,outDir,lumi,box,brString,fileName))
        
    signalFile = rt.TFile.Open('%s/%s_lumi-%.3f_%i-%ibtag_%s.root'%(outDir,modelName,lumi*1./1000.,z[0],z[-1]-1,box))
    sigTH1 = signalFile.Get('%s_%s'%(box,model))
    
    bkgdHistDict = importHists('%s/controlHistograms%s.root'%(BACKGROUND_DIR,box.replace('ControlRegion','').replace('WJet','WJetsSingleLepton')))
    tempTH2 = bkgdHistDict['Data'][('MR','Rsq')]
    
    #unroll into TH1F
    if unrollBins is None:
        nBins = (len(x)-1)*(len(y)-1)
        maxBins = nBins
        myTH1 = rt.TH1F(treeName,treeName,maxBins,0,maxBins)
        myTH1.SetDirectory(0) #prevent it from going out of scope
        myTH1.Sumw2()
        i = 0
        for ix in range(1,len(x)):
            for iy in range(1,len(y)):
                i += 1
                myTH1.SetBinContent(i,tempTH2.GetBinContent(ix,iy))
                myTH1.SetBinError(i,tempTH2.GetBinError(ix,iy))
    else:        
        print "Merging bins according to custom (MR-dependent) binning"
        layers = []
        #turn it into a TH2Poly with the reduced binning
        unrollRows = unrollBins[0][0]
        unrollCols = unrollBins[0][1]
        poly = makeTH2PolyFromColumns(tempTH2.GetName()+"poly", 'poly', unrollRows, unrollCols)
        fillTH2PolyFromTH2(tempTH2, poly)
        numbins = poly.GetNumberOfBins()
        unrolledSlice = rt.TH1D(tempTH2.GetName()+"Unroll", "slice", numbins, 0, numbins)
        for bn in range(1, numbins+1):
            unrolledSlice.SetBinContent(bn, poly.GetBinContent(bn))
            unrolledSlice.SetBinError(bn, poly.GetBinError(bn))
        layers.append(unrolledSlice)
        poly.Delete()
        myTH1 = stitch(layers)
        myTH1.SetName(treeName)
        myTH1.SetTitle(treeName)

    sigTH1.Sumw2()
    myTH1.Sumw2()
    sigTH1.Divide(myTH1)

    return sigTH1
Пример #2
0
def uncorrelateSFs(hists, sysName, referenceHists, cfg, box, unrollBins=None):
    """Same as uncorrelate(), but treats bins as correlated if they lie inside the same bin in the reference histogram.
    Needs a config and a box name, to get the correct bin configuration for the razor histogram"""
    #get all histograms that match the input string
    toUncorrelate = [name for name in hists if sysName in name]
    print "Uncorrelate SFs:",sysName
    print("Treating the following distributions as uncorrelated: ")
    for name in toUncorrelate: print name

    x = array('d', cfg.getBinning(box)[0]) # MR binning
    y = array('d', cfg.getBinning(box)[1]) # Rsq binning
    z = array('d', cfg.getBinning(box)[2]) # nBtag binning
    #make histogram with razor binning
    myTH3 = rt.TH3D("razor3d"+name,"razor3d",len(x)-1,x,len(y)-1,y,len(z)-1,z)

    for name in toUncorrelate:
        print("Using reference histogram to determine bin correlations for "+name)
        #get histogram with central values
        centerName = name.split("_")[:-1]
        centerName = '_'.join(centerName)
        systName = name.split("_")[-1].replace("Up","").replace("Down","")
        print("Central values taken from "+centerName)
        #get reference histogram for scale factor binning
        referenceHist = referenceHists[centerName]
        #for each bin create a new histogram in which that bin is up/down and the rest are centered
        if referenceHist.InheritsFrom("TH2Poly"):
            for bn in range(1,referenceHist.GetNumberOfBins()+1):
                matchedAtLeastOneBin = False
                newHistName = makeNewHistogramForUncorrelateSFs(name, centerName, systName, bn, hists)
                #find all bins of signal histogram that are within this bin
                if unrollBins is None:
                    i = 0
                    for ix in range(1,len(x)):
                        for iy in range(1,len(y)):
                            for iz in range(1,len(z)):
                                #i = 1D histogram bin index
                                i += 1
                                #get MR and Rsq at center of bin in 3d histogram
                                mrCenter = myTH3.GetXaxis().GetBinCenter(ix)
                                rsqCenter = myTH3.GetYaxis().GetBinCenter(iy)
                                if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=bn,
                                        sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                        referenceHist=referenceHist):
                                    #print " bin",i,"(",ix,iy,iz,") matches!"
                                    matchedAtLeastOneBin = True
                else:
                    #make a TH2Poly from each xy slice of the histogram, unroll each one and attach together
                    i = 0
                    for iz in range(1, len(z)):
                        #one xy slice of the histogram 
                        unrollRows = unrollBins[iz-1][0]
                        unrollCols = unrollBins[iz-1][1]
                        poly = macro.makeTH2PolyFromColumns("poly"+str(iz)+name, 'poly', unrollRows, unrollCols)
                        polyBins = poly.GetBins()
                        for sigBN in range(1, poly.GetNumberOfBins()+1):
                            i += 1
                            thisSigBin = polyBins.At(sigBN-1)
                            #get MR and Rsq at center of bin in 3d histogram
                            mrCenter = (thisSigBin.GetXMax() + thisSigBin.GetXMin())/2.0
                            rsqCenter = (thisSigBin.GetYMax() + thisSigBin.GetYMin())/2.0
                            if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=bn,
                                    sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                    referenceHist=referenceHist):
                                #print " bin",i,"(",sigBN,iz,") matches!"
                                matchedAtLeastOneBin = True
                        poly.Delete()
                #don't save the histogram if there is no change from the nominal
                if not matchedAtLeastOneBin:
                    #print "No matching signal bins -- discarding histogram"
                    del hists[newHistName]
        else: #TH2F case
            for bx in range(1,referenceHist.GetNbinsX()+1):
                for by in range(1,referenceHist.GetNbinsY()+1):
                    b = referenceHist.GetBin(bx,by)
                    newHistName = makeNewHistogramForUncorrelateSFs(name, centerName, systName, b, hists)
                    matchedAtLeastOneBin = False
                    #find bins in hists[name] that lie inside bin b of referenceHist
                    if unrollBins is None:
                        i = 0
                        for ix in range(1,len(x)):
                            for iy in range(1,len(y)):
                                for iz in range(1,len(z)):
                                    #i = 1D histogram bin index
                                    i+= 1
                                    #get MR and Rsq at center of bin in 3d histogram
                                    mrCenter = myTH3.GetXaxis().GetBinCenter(ix)
                                    rsqCenter = myTH3.GetYaxis().GetBinCenter(iy)
                                    if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=b,
                                            sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                            referenceHist=referenceHist):
                                        #print " bin",i,"(",ix,iy,iz,") matches!"
                                        matchedAtLeastOneBin = True
                    else:
                        #make a TH2Poly from each xy slice of the histogram, unroll each one and attach together
                        i = 0
                        for iz in range(1, len(z)):
                            #one xy slice of the histogram 
                            unrollRows = unrollBins[iz-1][0]
                            unrollCols = unrollBins[iz-1][1]
                            poly = macro.makeTH2PolyFromColumns("poly"+str(iz)+name, 'poly', unrollRows, unrollCols)
                            polyBins = poly.GetBins()
                            for sigBN in range(1, poly.GetNumberOfBins()+1):
                                i += 1
                                thisSigBin = polyBins.At(sigBN-1)
                                #get MR and Rsq at center of bin in 3d histogram
                                mrCenter = (thisSigBin.GetXMax() + thisSigBin.GetXMin())/2.0
                                rsqCenter = (thisSigBin.GetYMax() + thisSigBin.GetYMin())/2.0
                                if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=b,
                                        sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                        referenceHist=referenceHist):
                                    #print " bin",i,"(",sigBN,iz,") matches!"
                                    matchedAtLeastOneBin = True
                            poly.Delete()
                    #don't save the histogram if there is no change from the nominal
                    if not matchedAtLeastOneBin:
                        #print "No matching signal bins -- discarding histogram"
                        del hists[newHistName]

        #remove the original histogram
        del hists[name]
Пример #3
0
def uncorrelateSFs1D(hists, sysName, referenceHists, unrollBins, 
        useRsq=True, bInclusive=False, xInclusive=False):
    """
    Same as uncorrelateSFs except that the reference histogram is assumed to
    be a 1D Rsq histogram instead of a 2D MR-Rsq histogram.
    (to decorrelate by MR value instead of Rsq, set useRsq to False)
    Set bInclusive to True to keep different b-tag bins correlated.
    Set xInclusive to True to have one shape uncertainty for each b-tag bin.
    """
    if bInclusive and xInclusive:
        print "bInclusive and xInclusive are both set to True.  Nothing to do..."
        return
    toUncorrelate = [name for name in hists if sysName in name]
    print "Uncorrelate SFs:",sysName
    print("Treating the following distributions as uncorrelated: ")
    for name in toUncorrelate: print name
    for name in toUncorrelate:
        print("Using reference histogram to determine bin correlations for "+name)
        centerName = name.split("_")[:-1]
        centerName = '_'.join(centerName)
        systName = name.split("_")[-1].replace("Up","").replace("Down","")
        print("Central values taken from "+centerName)
        referenceHist = referenceHists[centerName]
        ibin = 0
        for bx in range(1,referenceHist.GetNbinsX()+1):
            sigBNGlobal = 0
            if bInclusive:
                ibin += 1
                newHistName = makeNewHistogramForUncorrelateSFs(name, centerName, systName, ibin, hists)
                matchedAtLeastOneBin = False
            if xInclusive:
                ibin = 0
            for bz in range(len(unrollBins)):
                if not bInclusive:
                    ibin += 1
                    newHistName = makeNewHistogramForUncorrelateSFs(name, centerName, systName, ibin, hists)
                    matchedAtLeastOneBin = False
                unrollRows = unrollBins[bz][0]
                unrollCols = unrollBins[bz][1]
                poly = macro.makeTH2PolyFromColumns("poly"+str(bz)+name, 'poly', unrollRows, unrollCols)
                polyBins = poly.GetBins()
                for sigBN in range(1, poly.GetNumberOfBins()+1):
                    sigBNGlobal += 1
                    thisSigBin = polyBins.At(sigBN-1)
                    if useRsq:
                        binCenter = (thisSigBin.GetYMax() + thisSigBin.GetYMin())/2.0
                    else:
                        binCenter = (thisSigBin.GetXMax() + thisSigBin.GetXMin())/2.0
                    # Note that binCenter is an Rsq value but it is being passed
                    # into the mrCenter field of setBinContentsForUncorrelateSFs.  
                    # This is just for convenience -- that function assumes
                    # that MR values are on the x-axis and Rsq is on y (not true here)
                    if setBinContentsForUncorrelateSFs(binCenter, -1, refBN=bx,
                            sigBN=sigBNGlobal, sysHist=hists[name], newHist=hists[newHistName],
                            referenceHist=referenceHist, oneD=True):
                        matchedAtLeastOneBin = True
                poly.Delete()
                #don't save the histogram if there is no change from the nominal
                if not bInclusive and not xInclusive and not matchedAtLeastOneBin:
                    print "No matches for bin {} {}".format(bx, bz)
                    del hists[newHistName]
            if bInclusive and not matchedAtLeastOneBin:
                    print "No matches for bin {}".format(bx)
                    del hists[newHistName]
        del hists[name]
def uncorrelateSFs(hists, sysName, referenceHists, cfg, box, unrollBins=None):
    """Same as uncorrelate(), but treats bins as correlated if they lie inside the same bin in the reference histogram.
    Needs a config and a box name, to get the correct bin configuration for the razor histogram"""
    #get all histograms that match the input string
    toUncorrelate_tmp = [name for name in hists if sysName in name]
    # VERY AD HOC
    # to exclude uncertainties with overlapping names
    toUncorrelate = []
    badStrs = ['MR', 'NJets', 'NBTags']
    for name in toUncorrelate_tmp:
        ok = True
        for s in badStrs:
            if s in name:
                print "Excluding {} because its name contains {}".format(
                        name, s)
                ok = False
        if ok: 
            toUncorrelate.append(name)
    print "Uncorrelate SFs:",sysName
    print("Treating the following distributions as uncorrelated: ")
    for name in toUncorrelate: print name

    x = array('d', cfg.getBinning(box)[0]) # MR binning
    y = array('d', cfg.getBinning(box)[1]) # Rsq binning
    z = array('d', cfg.getBinning(box)[2]) # nBtag binning
    #make histogram with razor binning
    myTH3 = rt.TH3D("razor3d"+name,"razor3d",len(x)-1,x,len(y)-1,y,len(z)-1,z)

    for name in toUncorrelate:
        print("Using reference histogram to determine bin correlations for "+name)
        #get histogram with central values
        centerName = name.split("_")[:-1]
        centerName = '_'.join(centerName)
        systName = name.split("_")[-1].replace("Up","").replace("Down","")
        print("Central values taken from "+centerName)
        #get reference histogram for scale factor binning
        referenceHist = referenceHists[centerName]
        #for each bin create a new histogram in which that bin is up/down and the rest are centered
        if referenceHist.InheritsFrom("TH2Poly"):
            for bn in range(1,referenceHist.GetNumberOfBins()+1):
                matchedAtLeastOneBin = False
                newHistName = makeNewHistogramForUncorrelateSFs(name, centerName, systName, bn, hists)
                #find all bins of signal histogram that are within this bin
                if unrollBins is None:
                    i = 0
                    for ix in range(1,len(x)):
                        for iy in range(1,len(y)):
                            for iz in range(1,len(z)):
                                #i = 1D histogram bin index
                                i += 1
                                #get MR and Rsq at center of bin in 3d histogram
                                mrCenter = myTH3.GetXaxis().GetBinCenter(ix)
                                rsqCenter = myTH3.GetYaxis().GetBinCenter(iy)
                                if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=bn,
                                        sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                        referenceHist=referenceHist):
                                    #print " bin",i,"(",ix,iy,iz,") matches!"
                                    matchedAtLeastOneBin = True
                else:
                    #make a TH2Poly from each xy slice of the histogram, unroll each one and attach together
                    i = 0
                    for iz in range(1, len(z)):
                        #one xy slice of the histogram 
                        unrollRows = unrollBins[iz-1][0]
                        unrollCols = unrollBins[iz-1][1]
                        poly = macro.makeTH2PolyFromColumns("poly"+str(iz)+name, 'poly', unrollRows, unrollCols)
                        polyBins = poly.GetBins()
                        for sigBN in range(1, poly.GetNumberOfBins()+1):
                            i += 1
                            thisSigBin = polyBins.At(sigBN-1)
                            #get MR and Rsq at center of bin in 3d histogram
                            mrCenter = (thisSigBin.GetXMax() + thisSigBin.GetXMin())/2.0
                            rsqCenter = (thisSigBin.GetYMax() + thisSigBin.GetYMin())/2.0
                            if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=bn,
                                    sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                    referenceHist=referenceHist):
                                #print " bin",i,"(",sigBN,iz,") matches!"
                                matchedAtLeastOneBin = True
                        poly.Delete()
                #don't save the histogram if there is no change from the nominal
                if not matchedAtLeastOneBin:
                    #print "No matching signal bins -- discarding histogram"
                    del hists[newHistName]
        else: #TH2F case
            for bx in range(1,referenceHist.GetNbinsX()+1):
                for by in range(1,referenceHist.GetNbinsY()+1):
                    b = referenceHist.GetBin(bx,by)
                    newHistName = makeNewHistogramForUncorrelateSFs(name, centerName, systName, b, hists)
                    matchedAtLeastOneBin = False
                    #find bins in hists[name] that lie inside bin b of referenceHist
                    if unrollBins is None:
                        i = 0
                        for ix in range(1,len(x)):
                            for iy in range(1,len(y)):
                                for iz in range(1,len(z)):
                                    #i = 1D histogram bin index
                                    i+= 1
                                    #get MR and Rsq at center of bin in 3d histogram
                                    mrCenter = myTH3.GetXaxis().GetBinCenter(ix)
                                    rsqCenter = myTH3.GetYaxis().GetBinCenter(iy)
                                    if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=b,
                                            sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                            referenceHist=referenceHist):
                                        #print " bin",i,"(",ix,iy,iz,") matches!"
                                        matchedAtLeastOneBin = True
                    else:
                        #make a TH2Poly from each xy slice of the histogram, unroll each one and attach together
                        i = 0
                        for iz in range(1, len(z)):
                            #one xy slice of the histogram 
                            unrollRows = unrollBins[iz-1][0]
                            unrollCols = unrollBins[iz-1][1]
                            poly = macro.makeTH2PolyFromColumns("poly"+str(iz)+name, 'poly', unrollRows, unrollCols)
                            polyBins = poly.GetBins()
                            for sigBN in range(1, poly.GetNumberOfBins()+1):
                                i += 1
                                thisSigBin = polyBins.At(sigBN-1)
                                #get MR and Rsq at center of bin in 3d histogram
                                mrCenter = (thisSigBin.GetXMax() + thisSigBin.GetXMin())/2.0
                                rsqCenter = (thisSigBin.GetYMax() + thisSigBin.GetYMin())/2.0
                                if setBinContentsForUncorrelateSFs(mrCenter, rsqCenter, refBN=b,
                                        sigBN=i, sysHist=hists[name], newHist=hists[newHistName],
                                        referenceHist=referenceHist):
                                    #print " bin",i,"(",sigBN,iz,") matches!"
                                    matchedAtLeastOneBin = True
                            poly.Delete()
                    #don't save the histogram if there is no change from the nominal
                    if not matchedAtLeastOneBin:
                        #print "No matching signal bins -- discarding histogram"
                        del hists[newHistName]

        #remove the original histogram
        del hists[name]
def checkSignalContamination(config,
                             outDir,
                             lumi,
                             box,
                             model,
                             mLSP,
                             mGluino=-1,
                             mStop=-1,
                             mergeBins=False,
                             debugLevel=0,
                             treeName="RazorInclusive",
                             tag='Razor2016_MoriondRereco'):
    cfg = Config.Config(config)
    x = array('d', cfg.getBinning(box)[0])  # MR binning
    y = array('d', cfg.getBinning(box)[1])  # Rsq binning
    z = array('d', cfg.getBinning(box)[2])  # nBtag binning

    dirToUse = razorSignalDirs[tag]

    unrollBins = []
    analyses = []
    if mergeBins:
        btagBins = cfg.getBinning(box)[2][:-1]
        for btags in btagBins:
            analyses.append(Analysis(box, tag, nbMin=btags))
            unrollBins.append(analyses[-1].unrollBins)

    xBR = yBR = -1
    if 'T1x' in model:
        xBR, yBR = getBranchingFracsFromModelName(model)
        fileName = dirToUse + '/SMS-T1ttbb_%i_%i.root' % (mGluino, mLSP)
    elif 'T2' in model:
        modelName = getModelName(model, mStop, mLSP)
        fileName = dirToUse + '/%s.root' % (modelName)
    else:
        modelName = getModelName(model, mGluino, mLSP)
        fileName = dirToUse + '/%s.root' % (modelName)

    smsOpts = SMSOpts(xBR=xBR,
                      yBR=yBR,
                      doNPVExtrap=False,
                      doGenMetVsPFMet=False)
    sigTH1 = makeSMSTemplates(box,
                              fileName,
                              opts=smsOpts,
                              debugLevel=debugLevel,
                              tag=tag)['Signal']

    bkgdHistDict = importHists('%s/controlHistograms%s.root' %
                               (BACKGROUND_DIR, box))
    tempTH2 = bkgdHistDict['Data'][('MR', 'Rsq')]

    #unroll into TH1F
    if unrollBins is None:
        nBins = (len(x) - 1) * (len(y) - 1)
        maxBins = nBins
        myTH1 = rt.TH1F(treeName, treeName, maxBins, 0, maxBins)
        myTH1.SetDirectory(0)  #prevent it from going out of scope
        myTH1.Sumw2()
        i = 0
        for ix in range(1, len(x)):
            for iy in range(1, len(y)):
                i += 1
                myTH1.SetBinContent(i, tempTH2.GetBinContent(ix, iy))
                myTH1.SetBinError(i, tempTH2.GetBinError(ix, iy))
    else:
        print "Merging bins according to custom (MR-dependent) binning"
        layers = []
        #turn it into a TH2Poly with the reduced binning
        unrollRows = unrollBins[0][0]
        unrollCols = unrollBins[0][1]
        poly = makeTH2PolyFromColumns(tempTH2.GetName() + "poly", 'poly',
                                      unrollRows, unrollCols)
        fillTH2PolyFromTH2(tempTH2, poly)
        numbins = poly.GetNumberOfBins()
        unrolledSlice = rt.TH1D(tempTH2.GetName() + "Unroll", "slice", numbins,
                                0, numbins)
        for bn in range(1, numbins + 1):
            unrolledSlice.SetBinContent(bn, poly.GetBinContent(bn))
            unrolledSlice.SetBinError(bn, poly.GetBinError(bn))
        layers.append(unrolledSlice)
        poly.Delete()
        myTH1 = stitch(layers)
        myTH1.SetName(treeName)
        myTH1.SetTitle(treeName)

    sigTH1.Sumw2()
    myTH1.Sumw2()
    sigTH1.Divide(myTH1)

    return sigTH1
Пример #6
0
def checkSignalContamination(config,
                             outDir,
                             lumi,
                             box,
                             model,
                             mLSP,
                             mGluino=-1,
                             mStop=-1,
                             mergeBins=False,
                             treeName="RazorInclusive"):
    cfg = Config.Config(config)
    x = array('d', cfg.getBinning(box)[0])  # MR binning
    y = array('d', cfg.getBinning(box)[1])  # Rsq binning
    z = array('d', cfg.getBinning(box)[2])  # nBtag binning

    unrollBins = None
    if mergeBins:
        btagBins = cfg.getBinning(box)[2][:-1]
        unrollBins = [(xbinsSignal[box][str(int(btags)) + 'B'],
                       colsSignal[box][str(int(btags)) + 'B'])
                      for btags in btagBins]

    mergeBinsString = ''
    if mergeBins:
        mergeBinsString = '--merge-bins'

    brString = ""
    if 'T1x' in model:
        xBR = float(model[model.find('x') + 1:model.find('y')].replace(
            'p', '.'))
        yBR = float(model[model.find('y') + 1:].replace('p', '.'))
        brString = '--xBR %.2f --yBR %.2f' % (xBR, yBR)
        modelName = 'SMS-%s_%i_%i' % (model, mGluino, mLSP)
        fileName = SIGNAL_DIR + '/SMS-T1ttbb_%i_%i.root' % (mGluino, mLSP)
    elif 'T2' in model:
        modelName = 'SMS-%s_%i_%i' % (model, mStop, mLSP)
        fileName = SIGNAL_DIR + '/%s.root' % (modelName)
    else:
        modelName = 'SMS-%s_%i_%i' % (model, mGluino, mLSP)
        fileName = SIGNAL_DIR + '/%s.root' % (modelName)

    os.system(
        'python python/SMSTemplates.py %s -c %s -d %s/ --lumi %s --box %s --no-signal-sys %s %s'
        % (mergeBinsString, config, outDir, lumi, box, brString, fileName))

    signalFile = rt.TFile.Open(
        '%s/%s_lumi-%.3f_%i-%ibtag_%s.root' %
        (outDir, modelName, lumi * 1. / 1000., z[0], z[-1] - 1, box))
    sigTH1 = signalFile.Get('%s_%s' % (box, model))

    bkgdHistDict = importHists(
        '%s/controlHistograms%s.root' %
        (BACKGROUND_DIR, box.replace('ControlRegion', '').replace(
            'WJet', 'WJetsSingleLepton')))
    tempTH2 = bkgdHistDict['Data'][('MR', 'Rsq')]

    #unroll into TH1F
    if unrollBins is None:
        nBins = (len(x) - 1) * (len(y) - 1)
        maxBins = nBins
        myTH1 = rt.TH1F(treeName, treeName, maxBins, 0, maxBins)
        myTH1.SetDirectory(0)  #prevent it from going out of scope
        myTH1.Sumw2()
        i = 0
        for ix in range(1, len(x)):
            for iy in range(1, len(y)):
                i += 1
                myTH1.SetBinContent(i, tempTH2.GetBinContent(ix, iy))
                myTH1.SetBinError(i, tempTH2.GetBinError(ix, iy))
    else:
        print "Merging bins according to custom (MR-dependent) binning"
        layers = []
        #turn it into a TH2Poly with the reduced binning
        unrollRows = unrollBins[0][0]
        unrollCols = unrollBins[0][1]
        poly = makeTH2PolyFromColumns(tempTH2.GetName() + "poly", 'poly',
                                      unrollRows, unrollCols)
        fillTH2PolyFromTH2(tempTH2, poly)
        numbins = poly.GetNumberOfBins()
        unrolledSlice = rt.TH1D(tempTH2.GetName() + "Unroll", "slice", numbins,
                                0, numbins)
        for bn in range(1, numbins + 1):
            unrolledSlice.SetBinContent(bn, poly.GetBinContent(bn))
            unrolledSlice.SetBinError(bn, poly.GetBinError(bn))
        layers.append(unrolledSlice)
        poly.Delete()
        myTH1 = stitch(layers)
        myTH1.SetName(treeName)
        myTH1.SetTitle(treeName)

    sigTH1.Sumw2()
    myTH1.Sumw2()
    sigTH1.Divide(myTH1)

    return sigTH1