Ejemplo n.º 1
0
def studyVqqResolution(rootFile):

    #get all from file
    histos={}
    inF=TFile.Open(rootFile)
    keys=inF.GetListOfKeys()
    for k in keys:
        obj=inF.Get(k.GetName())
        obj.SetDirectory(0)
        histos[k.GetName()]=obj
    inF.Close()

    #plot
    gROOT.SetBatch()
    gROOT.SetStyle('Plain')
    gStyle.SetOptStat(0)
    gStyle.SetOptFit(1111)
    gStyle.SetOptTitle(0)
    gStyle.SetStatFont(42)

    kin=['','30to40','40to50','50to75','75to100','100toInf']
    for k in kin:        
        c=TCanvas('c','c',600,600)
        c.cd()
        c.SetCanvasSize(1000,500)
        c.SetWindowSize(1000,500)
        c.Divide(2,1)
        c.cd(1)
        histos['deta'+k+'barrel'].SetLineWidth(2)
        histos['deta'+k+'barrel'].SetTitle('barrel')
        histos['deta'+k+'barrel'].Draw('hist')
        histos['deta'+k+'endcap'].SetLineWidth(2)
        histos['deta'+k+'endcap'].SetLineStyle(7)
        histos['deta'+k+'endcap'].SetTitle('endcap')
        histos['deta'+k+'endcap'].Draw('histsame')
        leg=TLegend(0.6,0.92,0.9,0.98)
        leg.SetFillStyle(0)
        leg.SetBorderSize(0)
        leg.SetTextFont(42)
        leg.AddEntry(histos['deta'+k+'barrel'],'barrel','f')
        leg.AddEntry(histos['deta'+k+'endcap'],'endcap','f')
        leg.SetNColumns(2)
        leg.Draw()
        drawHeader()
        c.cd(2)
        histos['dphi'+k+'barrel'].SetLineWidth(2)
        histos['dphi'+k+'barrel'].SetTitle('barrel')
        histos['dphi'+k+'barrel'].Draw('hist')
        histos['dphi'+k+'endcap'].SetLineWidth(2)
        histos['dphi'+k+'endcap'].SetLineStyle(7)
        histos['dphi'+k+'endcap'].SetTitle('endcap')
        histos['dphi'+k+'endcap'].Draw('histsame')
        c.Modified()
        c.Update()
        c.SaveAs('dr_%s.png'%k)


    labels=[]
    responseVars=['dpt','den','dphi','deta','dr']
    for r in responseVars:
        barrelResponse=TGraphErrors()
        barrelResponse.SetName(r+'barrelresponse')
        barrelResponse.SetLineWidth(2)
        barrelResponse.SetFillStyle(0)
        barrelResponse.SetMarkerStyle(20)
        barrelCoreResponse=barrelResponse.Clone(r+'barrelcoreresponse')
        endcapResponse=TGraphErrors()
        endcapResponse.SetName(r+'endcapresponse')
        endcapResponse.SetLineWidth(2)
        endcapResponse.SetFillStyle(0)
        endcapResponse.SetMarkerStyle(24)
        endcapCoreResponse=endcapResponse.Clone(r+'endcapresponse')
        for k in kin: 
            c.cd()
            c.Clear()
            c.SetWindowSize(1000,500)
            c.Divide(2,1)
            for i in [1,2] :
                c.cd(i)
                reg='barrel'
                if i==2: reg='endcap' 

                h=histos[r+k+reg]
                x=RooRealVar("x", h.GetXaxis().GetTitle(), h.GetXaxis().GetXmin(), h.GetXaxis().GetXmax())
                data=RooDataHist("data", "dataset with x", RooArgList(x), h)
                frame=x.frame()
                RooAbsData.plotOn( data, frame, RooFit.DataError(RooAbsData.SumW2) )

                mean1=RooRealVar("mean1","mean1",0,-0.5,0.5);
                sigma1=RooRealVar("sigma1","sigma1",0.1,0.01,1.0);
                gauss1=RooGaussian("g1","g",x,mean1,sigma1)
                
                if r=='dpt' or r=='den' :
                    mean2=RooRealVar("mean2","mean2",0,-0.5,0.5);
                    sigma2=RooRealVar("sigma2","sigma2",0.1,0.01,1.0);
                    alphacb=RooRealVar("alphacb","alphacb",1,0.1,3);
                    ncb=RooRealVar("ncb","ncb",4,1,100)
                    gauss2 = RooCBShape("cb2","cb",x,mean2,sigma2,alphacb,ncb);
                else:
                    mean1.setRange(0,0.5)
                    mean2=RooRealVar("mean2","mean",0,0,1);
                    sigma2=RooRealVar("sigma2","sigma",0.1,0.01,1.0);
                    gauss2=RooGaussian("g2","g",x,mean2,sigma2) ;

                frac = RooRealVar("frac","fraction",0.9,0.0,1.0)
                if data.sumEntries()<100 :
                    frac.setVal(1.0)
                    frac.setConstant(True)
                model = RooAddPdf("sum","g1+g2",RooArgList(gauss1,gauss2), RooArgList(frac))

                status=model.fitTo(data,RooFit.Save()).status()
                if status!=0 : continue

                model_cdf=model.createCdf(RooArgSet(x)) ;
                cl=0.90
                ul=0.5*(1.0+cl)
                closestToCL=1.0
                closestToUL=-1
                closestToMedianCL=1.0
                closestToMedian=-1
                for ibin in xrange(1,h.GetXaxis().GetNbins()*10):
                    xval=h.GetXaxis().GetXmin()+(ibin-1)*h.GetXaxis().GetBinWidth(ibin)/10.
                    x.setVal(xval)
                    cdfValToCL=math.fabs(model_cdf.getVal()-ul)
                    if cdfValToCL<closestToCL:
                        closestToCL=cdfValToCL
                        closestToUL=xval
                    cdfValToCL=math.fabs(model_cdf.getVal()-0.5)
                    if cdfValToCL<closestToMedianCL:
                        closestToMedianCL=cdfValToCL
                        closestToMedian=xval

                RooAbsPdf.plotOn(model,frame)
                frame.Draw()

                if i==1: drawHeader()
                labels.append( TPaveText(0.6,0.92,0.9,0.98,'brNDC') )
                ilab=len(labels)-1
                labels[ilab].SetName(r+k+'txt')
                labels[ilab].SetBorderSize(0)
                labels[ilab].SetFillStyle(0)
                labels[ilab].SetTextFont(42)
                labels[ilab].SetTextAlign(12)
                kinReg=k.replace('to','-')
                kinReg=kinReg.replace('Inf','#infty')
                labels[ilab].AddText('['+reg+'] '+kinReg)
                labels[ilab].Draw()
                
                resolutionVal=math.fabs(closestToUL-closestToMedian)
                responseGr=barrelResponse
                responseCoreGr=barrelCoreResponse
                coreResolutionVal=sigma1.getVal()
                coreResolutionErr=sigma1.getError()
                if frac.getVal()<0.7 and (sigma2.getVal()<sigma1.getVal()) :
                    coreResolutionVal=sigma2.getVal()
                    coreResolutionErr=sigma2.getError()


                if i==2 : 
                    responseGr=endcapResponse
                    responseCoreGr=endcapCoreResponse
                if k!='' :
                    nrespPts=responseGr.GetN()
                    kinAvg=150
                    kinWidth=50
                    if k=='30to40' : 
                        kinAvg=35
                        kinWidth=5
                    if k=='40to50' : 
                        kinAvg=45
                        kinWidth=5
                    if k=='50to75' : 
                        kinAvg=62.5
                        kinWidth=12.5
                    elif k=='75to100' :
                        kinAvg=87.5
                        kinWidth=12.5
                    responseGr.SetPoint(nrespPts,kinAvg,resolutionVal)
                    responseCoreGr.SetPoint(nrespPts,kinAvg,coreResolutionVal)
                    responseCoreGr.SetPointError(nrespPts,kinWidth,coreResolutionErr)

                labels.append( TPaveText(0.15,0.7,0.4,0.9,'brNDC') )
                ilab=len(labels)-1
                labels[ilab].SetName(r+k+'fitrestxt')
                labels[ilab].SetBorderSize(0)
                labels[ilab].SetFillStyle(0)
                labels[ilab].SetTextFont(42)
                labels[ilab].SetTextAlign(12)
                labels[ilab].AddText('Gaussian #1 (f=%3.3f)'%frac.getVal())
                labels[ilab].AddText('#mu=%3.3f#pm%3.3f'%(mean1.getVal(),mean1.getError()))
                labels[ilab].AddText('#sigma=%3.3f#pm%3.3f'%(sigma1.getVal(),sigma1.getError()))
                labels[ilab].AddText('Gaussian #2 (f=%3.3f)'%(1-frac.getVal()))
                labels[ilab].AddText('#mu=%3.3f#pm%3.3f'%(mean2.getVal(),mean2.getError()))
                labels[ilab].AddText('#sigma=%3.3f#pm%3.3f'%(sigma2.getVal(),sigma2.getError()))
                
                labels[ilab].Draw()

            c.Modified()
            c.Update()
            c.SaveAs(r+'res_'+k+'.png')
        
        frame=TGraphErrors()
        frame.SetPoint(0,0,0)
        frame.SetPoint(1,200,0.3)
        frame.SetMarkerStyle(1)
        frame.SetFillStyle(0)
        frame.SetName('frame')
        cresp=TCanvas('cresp','cresp',500,500)
        cresp.cd()
        frame.Draw('ap')
        barrelResponse.Draw('pl')
        endcapResponse.Draw('pl')
        frame.GetXaxis().SetTitle("Quark transverse momentum [GeV]") 
        frame.GetYaxis().SetTitle("Resolution %3.2f C.L."%cl )
        frame.GetYaxis().SetTitleOffset(1.4)
        frame.GetYaxis().SetNdivisions(10)
        drawHeader()
        leg=TLegend(0.6,0.92,0.9,0.98)
        leg.SetFillStyle(0)
        leg.SetBorderSize(0)
        leg.SetTextFont(42)
        leg.AddEntry(barrelResponse,'barrel','fp')
        leg.AddEntry(endcapResponse,'endcap','fp')
        leg.SetNColumns(2)
        leg.Draw()
        cresp.Modified()
        cresp.Update()
        cresp.SaveAs(r+'res_evol.png')

        frameCore=frame.Clone('framecore')
        cresp.Clear()
        frameCore.Draw('ap')
        barrelCoreResponse.Draw('pl')
        endcapCoreResponse.Draw('pl')
        frameCore.GetXaxis().SetTitle("Quark transverse momentum [GeV]") 
        frameCore.GetYaxis().SetTitle("Core resolution")
        frameCore.GetYaxis().SetTitleOffset(1.4)
        frameCore.GetYaxis().SetNdivisions(10)
        frameCore.GetYaxis().SetRangeUser(0,0.2)
        drawHeader()
        leg=TLegend(0.6,0.92,0.9,0.98)
        leg.SetFillStyle(0)
        leg.SetBorderSize(0)
        leg.SetTextFont(42)
        leg.AddEntry(barrelCoreResponse,'barrel','fp')
        leg.AddEntry(endcapCoreResponse,'endcap','fp')
        leg.SetNColumns(2)
        leg.Draw()
        cresp.Modified()
        cresp.Update()
        cresp.SaveAs(r+'rescore_evol.png')

    bosons=['h','z','w']
    kin=['','50','100']
    region=['','bb','eb','ee']
    for k in kin:        
        for r in region:

            c=TCanvas('c','c',600,600)
            c.cd()
            histos['mjj'+k+r].Rebin()
            histos['mjj'+k+r].Draw()
            ic=1
            leg=TLegend(0.6,0.92,0.9,0.98)
            leg.SetFillStyle(0)
            leg.SetBorderSize(0)
            leg.SetTextFont(42)
            leg.AddEntry(histos['mjj'+k+r],'inclusive','f')
            for b in bosons:
                if histos[b+'mjj'+k+r].Integral()<=0 : continue 
                ic=ic+1
                histos[b+'mjj'+k+r].Rebin()
                histos[b+'mjj'+k+r].SetLineColor(ic)
                histos[b+'mjj'+k+r].SetLineWidth(2)
                histos[b+'mjj'+k+r].SetMarkerColor(ic)
                histos[b+'mjj'+k+r].SetMarkerStyle(1)
                histos[b+'mjj'+k+r].SetFillStyle(3000+ic)
                histos[b+'mjj'+k+r].SetFillColor(ic)
                histos[b+'mjj'+k+r].Draw('histsame')
                leg.AddEntry(histos[b+'mjj'+k+r],b,"f")
            leg.SetNColumns(ic)
            leg.Draw()
            drawHeader()
            labels.append( TPaveText(0.65,0.8,0.9,0.9,'brNDC') )
            ilab=len(labels)-1
            labels[ilab].SetName(k+r+'mjj')
            labels[ilab].SetBorderSize(0)
            labels[ilab].SetFillStyle(0)
            labels[ilab].SetTextFont(42)
            labels[ilab].SetTextAlign(12)
            regionTitle="inclusive"
            if r == 'bb' : regionTitle='barrel-barrel'
            if r == 'eb' : regionTitle='endcap-barrel'
            if r == 'ee' : regionTitle='endcap-endcap'
            labels[ilab].AddText(regionTitle)
            ptthreshold=30
            if k!='' : ptthreshold=float(k)
            labels[ilab].AddText('p_{T}>%3.0f GeV'%ptthreshold)
            labels[ilab].Draw()
            
            c.Modified()
            c.Update()
            c.SaveAs('mjj'+k+r+'.png')


    massResolutionGrs=[]
    for r in region:
        massResolution=TGraphErrors()
        massResolution.SetName(r+'dm')
        massResolution.SetLineWidth(2)
        massResolution.SetFillStyle(0)
        massResolution.SetMarkerStyle(20+len(massResolutionGrs))
        massResolution.SetMarkerColor(1+len(massResolutionGrs))
        massResolution.SetLineColor(1+len(massResolutionGrs))
        massResolution.SetFillColor(1+len(massResolutionGrs))
        massResolutionGrs.append(massResolution)
        
        for k in kin:        

            c=TCanvas('c','c',600,600)
            c.cd()
            h=histos['dmjj'+k+r]
            x=RooRealVar("x", h.GetXaxis().GetTitle(), h.GetXaxis().GetXmin(), h.GetXaxis().GetXmax())
            data=RooDataHist("data", "dataset with x", RooArgList(x), h)
            frame=x.frame()
            RooAbsData.plotOn( data, frame, RooFit.DataError(RooAbsData.SumW2) )
            
            mean1=RooRealVar("mean1","mean1",0,-0.5,0.5);
            sigma1=RooRealVar("sigma1","sigma1",0.1,0.01,1.0);
            gauss1=RooGaussian("g1","g",x,mean1,sigma1)
            mean2=RooRealVar("mean2","mean2",0,-0.5,0.5);
            sigma2=RooRealVar("sigma2","sigma2",0.1,0.01,1.0);
            alphacb=RooRealVar("alphacb","alphacb",1,0.1,3);
            ncb=RooRealVar("ncb","ncb",4,1,100)
            gauss2 = RooCBShape("cb2","cb",x,mean2,sigma2,alphacb,ncb);
            frac = RooRealVar("frac","fraction",0.9,0.0,1.0)
            model = RooAddPdf("sum","g1+g2",RooArgList(gauss1,gauss2), RooArgList(frac))
            status=model.fitTo(data,RooFit.Save()).status()
            if status!=0 : continue
            RooAbsPdf.plotOn(model,frame)
            frame.Draw()

            labels.append( TPaveText(0.6,0.65,0.85,0.9,'brNDC') )
            ilab=len(labels)-1
            labels[ilab].SetName(r+k+'dmfitrestxt')
            labels[ilab].SetBorderSize(0)
            labels[ilab].SetFillStyle(0)
            labels[ilab].SetTextFont(42)
            labels[ilab].SetTextAlign(12)
            labels[ilab].AddText('Gaussian #1 (f=%3.3f)'%frac.getVal())
            labels[ilab].AddText('#mu=%3.3f#pm%3.3f'%(mean1.getVal(),mean1.getError()))
            labels[ilab].AddText('#sigma=%3.3f#pm%3.3f'%(sigma1.getVal(),sigma1.getError()))
            labels[ilab].AddText('Gaussian #2 (f=%3.3f)'%(1-frac.getVal()))
            labels[ilab].AddText('#mu=%3.3f#pm%3.3f'%(mean2.getVal(),mean2.getError()))
            labels[ilab].AddText('#sigma=%3.3f#pm%3.3f'%(sigma2.getVal(),sigma2.getError()))
            labels[ilab].Draw()

            drawHeader()
            labels.append( TPaveText(0.15,0.8,0.4,0.9,'brNDC') )
            ilab=len(labels)-1
            labels[ilab].SetName(k+r+'dmjj')
            labels[ilab].SetBorderSize(0)
            labels[ilab].SetFillStyle(0)
            labels[ilab].SetTextFont(42)
            labels[ilab].SetTextAlign(12)
            regionTitle="inclusive"
            if r == 'bb' : regionTitle='barrel-barrel'
            if r == 'eb' : regionTitle='endcap-barrel'
            if r == 'ee' : regionTitle='endcap-endcap'
            labels[ilab].AddText(regionTitle)
            ptthreshold=30
            if k!='' : ptthreshold=float(k)
            labels[ilab].AddText('p_{T}>%3.0f GeV'%ptthreshold)
            labels[ilab].Draw()

            c.Modified()
            c.Update()
            c.SaveAs('dmjj'+k+r+'.png')

            massResolution.SetTitle(regionTitle)
            ip=massResolution.GetN()
            x=40
            xerr=10
            if k=='50' :
                x=75
                xerr=25
            elif k=='100':
                x=150
                xerr=50
            y=sigma1.getVal()
            yerr=sigma1.getError()
            if frac.getVal()<0.8:
                if sigma2.getVal()<sigma1.getVal():
                    y=sigma2.getVal()
                    ey=sigma2.getError()
            massResolution.SetPoint(ip,x,y)
            massResolution.SetPointError(ip,xerr,yerr)
            

    frame=TGraphErrors()
    frame.SetPoint(0,0,0)
    frame.SetPoint(1,200,0.2)
    frame.SetMarkerStyle(1)
    frame.SetFillStyle(0)
    frame.SetName('dmframe')
    cdmevol=TCanvas('cdmevol','cdmevol',500,500)
    cdmevol.cd()
    frame.Draw('ap')
    leg=TLegend(0.6,0.92,0.9,0.98)
    leg.SetFillStyle(0)
    leg.SetBorderSize(0)
    leg.SetTextFont(42)
    for dmGr in massResolutionGrs :
        dmGr.Draw('pl')
        leg.AddEntry(dmGr,dmGr.GetTitle(),'fp')
    frame.GetXaxis().SetTitle("Leading quark transverse momentum [GeV]") 
    frame.GetYaxis().SetTitle("Core resolution")
    frame.GetYaxis().SetTitleOffset(1.4)
    frame.GetYaxis().SetNdivisions(10)
    drawHeader()
    leg.SetNColumns(2)
    leg.Draw()
    cdmevol.Modified()
    cdmevol.Update()
    cdmevol.SaveAs('dm_evol.png')


    c=TCanvas('c','c',600,600)
    c.cd()
    histos['sel'].Draw('histtext')
    drawHeader()
    c.Modified()
    c.Update()
    c.SaveAs('selection.png')


    return
Ejemplo n.º 2
0
    genFitter.ws.defineSet("params", genstartpars)
    genFitter.ws.saveSnapshot("genInitPars", genstartpars)
    print "genPars:"
    genFitter.ws.set('params').Print('v')

    if opts.extendedGen:
        data = genPdf.generate(genFitter.ws.set('obsSet'), RooFit.Name('data_obs'),RooFit.Extended())
    else:
        data = genPdf.generate(genFitter.ws.set('obsSet'), RooFit.Name('data_obs'))
    
    if fitter.pars.binData:
        data = RooDataHist('data_obs', 'data_obs', genFitter.ws.set('obsSet'), data)
        data.Print('v')
    getattr(fitter.ws, 'import')(data)
    
    print 'Generated Data Events: %.0f' % (data.sumEntries())
    
elif opts.runMCGenToySim:
    print "performing Toy Generation from MC:"
    print "Generating ", opts.extdiboson, " diboson events"
    dibosonfiles = getattr(pars, 'dibosonFiles')
    dibosontoymodels = [-1]
    dibosonPdf = fitter.makeComponentPdf('dibosontoy',dibosonfiles,dibosontoymodels)
    dibosontoymc = dibosonPdf.generate(fitter.ws.set('obsSet'),opts.extdiboson,RooFit.Name('data_obs'))
    dibosontoymc.Print()
    gentoymc=dibosontoymc
    print "Generating ", opts.extWpJ, " WpJ events"
    WpJfiles = getattr(pars, 'WpJFiles')
    WpJtoymodels = [-1]
    WpJPdf = fitter.makeComponentPdf('WpJtoy',WpJfiles,WpJtoymodels)
    WpJtoymc = RooDataSet()
Ejemplo n.º 3
0
        mass) + '_datacard_const_' + name + '.txt'
    wsFN = outdir_datacards + 'Qstar' + str(
        mass) + '_workspace_const_' + name + '.root'
elif bkgNuisance:
    dcFN = outdir_datacards + 'Qstar' + str(mass) + '_datacard_nuisance.txt'
    wsFN = outdir_datacards + 'Qstar' + str(mass) + '_workspace_nuisance.root'
    #dcFN = outdir_datacards+'Qstar'+str(mass)+'_datacard_nuisance_testForSignificance.txt'
    #wsFN = outdir_datacards+'Qstar'+str(mass)+'_workspace_nuisance_testForSignificance.root'

else:
    dcFN = outdir_datacards + 'Qstar' + str(
        mass) + '_datacard_' + name + '.txt'
    wsFN = outdir_datacards + 'Qstar' + str(
        mass) + '_workspace_' + name + '.root'

nObs = dataHist_data.sumEntries()
#nObs = roohistBkg.sumEntries();
#nBkg = roohistBkg.sumEntries();

w = RooWorkspace('w', 'workspace')
getattr(w, 'import')(signal)
getattr(w, 'import')(background)
getattr(w, 'import')(background_norm)
getattr(w, 'import')(roohistBkg, RooFit.Rename("data_obs"))
#getattr(w,'import')(dataHist_data,RooFit.Rename("data_obs"))
#getattr(w,'import')(background_f6)
#getattr(w,'import')(background_f6_norm)
w.Print()
w.writeToFile(wsFN)

# -----------------------------------------
Ejemplo n.º 4
0
    parsBkg = background.getParameters(roohistBkg)
    parsBkg.setAttribAll('Constant', True)

if fitSig and fitDat:
    
    # -----------------------------------------
    # write everything to a workspace to make a datacard
    dcFN = 'RS'+str(mass)+'_datacard.txt'
    wsFN = 'RS'+str(mass)+'_workspace.root'
    
    if useSub:
      dcFN = 'RS'+str(mass)+'_sub_datacard.txt'
      wsFN = 'RS'+str(mass)+'_sub_workspace.root'

    nObs = roohistBkg.sumEntries();
    
    w = RooWorkspace('w','workspace')
    getattr(w,'import')(signal)
    getattr(w,'import')(background)
    getattr(w,'import')(roohistBkg,RooFit.Rename("data_obs"))  
    w.Print()
    w.writeToFile(wsFN)
    
    # -----------------------------------------
    # write a datacard
    LUMI = options.lumi
    signalCrossSection = options.sigXS
    signalEfficiency = options.sigEff
    ExpectedSignalRate = signalCrossSection*LUMI*signalEfficiency
Ejemplo n.º 5
0
def main(options, args):

    from ROOT import gSystem, gROOT, gStyle
    gROOT.SetBatch()
    gSystem.Load("libRooFitCore")

    if options.doWebPage:
        from lip.Tools.rootutils import loadToolsLib, apply_modifs
        loadToolsLib()

    from ROOT import TFile, RooFit, RooArgSet, RooDataHist, RooKeysPdf, RooHistPdf, TCanvas, TLegend, TLatex, TArrow, TPaveText, RooAddPdf, RooArgList
    from ROOT import kWhite, kBlue, kOpenSquare
    if options.doWebPage:
        from ROOT import HtmlHelper, HtmlTag, HtmlTable, HtmlPlot

    rootglobestyle.setTDRStyle()
    gStyle.SetMarkerSize(1.5)
    gStyle.SetTitleYOffset(1.5)

    gStyle.SetPadLeftMargin(0.16)
    gStyle.SetPadRightMargin(0.05)
    gStyle.SetPadTopMargin(0.05)
    gStyle.SetPadBottomMargin(0.13)

    gStyle.SetLabelFont(42, "XYZ")
    gStyle.SetLabelOffset(0.007, "XYZ")
    gStyle.SetLabelSize(0.05, "XYZ")

    gStyle.SetTitleSize(0.06, "XYZ")
    gStyle.SetTitleXOffset(0.9)
    gStyle.SetTitleYOffset(1.24)
    gStyle.SetTitleFont(42, "XYZ")

    ##
    ## Read files
    ##
    options.outdir = "%s_m%1.0f" % (options.outdir, options.mH)
    if options.fp:
        options.outdir += "_fp"

    ncat = options.ncat
    cats = options.cats
    if cats is "":
        categories = ["_cat%d" % i for i in range(0, ncat)]
    else:
        categories = ["_cat%s" % i for i in cats.split(",")]

    if options.mva:
        clables = {
            "_cat0": ("MVA > 0.89", ""),
            "_cat1": ("0.74 #leq MVA", "MVA < 0.89"),
            "_cat2": ("0.545 #leq MVA", "MVA < 0.74"),
            "_cat3": ("0.05 #leq MVA", "MVA < 0.545"),
            "_cat4": ("Di-jet", "Tagged"),
            "_cat5": ("Di-jet", "Tagged"),
            "_combcat": ("All Classes", "Combined")
        }
    else:
        clables = {
            "_cat0": ("max(|#eta|<1.5", "min(R_{9})>0.94"),
            "_cat1": ("max(|#eta|<1.5", "min(R_{9})<0.94"),
            "_cat2": ("max(|#eta|>1.5", "min(R_{9})>0.94"),
            "_cat3": ("max(|#eta|>1.5", "min(R_{9})<0.94"),
            "_cat4": ("Di-jet", "Tagged"),
            "_cat5": ("Di-jet", "Tagged"),
            "_combcat": ("All Classes", "Combined")
        }
    helper = Helper()

    fin = TFile.Open(options.infile)
    helper.files.append(fin)
    ws = fin.Get("cms_hgg_workspace")
    mass = ws.var("CMS_hgg_mass")
    mass.SetTitle("m_{#gamma#gamma}")
    mass.setUnit("GeV")
    mass.setRange(100., 150.)
    mass.setBins(100, "plot")
    mass.setBins(5000)

    print ws

    aset = RooArgSet(mass)

    helper.objs.append(mass)
    helper.objs.append(aset)

    fitopt = (RooFit.Minimizer("Minuit2", ""), RooFit.Minos(False),
              RooFit.SumW2Error(False), RooFit.NumCPU(8))

    if not options.binned and not options.refit:
        finpdf = TFile.Open(options.infilepdf)
        helper.files.append(finpdf)
        wspdf = finpdf.Get("wsig")
    else:
        wspdf = ws

    for c in categories:
        processes = ["ggh", "vbf", "wzh"]
        if options.fp:
            processes = ["vbf", "wzh"]
        ### elif clables[c][0] == "Di-jet":
        ###     processes = [ "vbf", "ggh" ]

        dsname = "sig_mass_m%1.0f%s" % (options.mH, c)
        print dsname
        print ws
        ds = ws.data("sig_%s_mass_m%1.0f%s" %
                     (processes[0], options.mH, c)).Clone(dsname)
        for proc in processes[1:]:
            ds.append(ws.data("sig_%s_mass_m%1.0f%s" % (proc, options.mH, c)))
        helper.dsets.append(ds)

        if options.binned:
            binned_ds = RooDataHist("binned_%s" % dsname, "binned_%s" % dsname,
                                    aset, ds)
            pdf = RooKeysPdf("pdf_%s_%s" % (dsname, f), "pdf_%s" % dsname,
                             mass, ds)
            plot_pdf = RooHistPdf("pdf_%s" % dsname, "pdf_%s" % dsname, aset,
                                  plot_ds)
            helper.add(binned_ds, binned_ds.GetName())
        else:
            if options.refit:
                if options.refitall and clables[c][0] != "Di-jet":
                    rpdfs = []
                    for proc in processes:
                        for ngaus in range(1, 4):
                            pp = build_pdf(ws, "%s_%s" % (c, proc), ngaus,
                                           ngaus == 3)
                            pp.fitTo(
                                ws.data("sig_%s_mass_m%1.0f%s" %
                                        (proc, options.mH, c)),
                                RooFit.Strategy(0), *fitopt)
                        rpdfs.append(pp)
                    pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c,
                                    RooArgList(*tuple(rpdfs)))
                else:
                    if options.refitall and clables[c][0] == "Di-jet":
                        for ngaus in range(1, 5):
                            pdf = build_pdf(ws, c, ngaus, ngaus == 5)
                            pdf.fitTo(ds, RooFit.Strategy(0), *fitopt)
                    else:
                        for ngaus in range(1, 4):
                            pdf = build_pdf(ws, c, ngaus, ngaus == 3)
                            pdf.fitTo(ds, RooFit.Strategy(0), *fitopt)
            else:
                pdfs = (wspdf.pdf("hggpdfrel%s_%s" % (c, p))
                        for p in processes)
                pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c,
                                RooArgList(*pdfs))
            helper.add(pdf, pdf.GetName())
            plot_pdf = pdf.Clone("pdf_%s" % dsname)

        plot_ds = RooDataHist("plot_%s" % dsname, "plot_%s" % dsname, aset,
                              "plot")
        plot_ds.add(ds)

        cdf = pdf.createCdf(aset)
        hmin, hmax, hm = get_FWHM(mass, pdf, cdf, options.mH - 10.,
                                  options.mH + 10.)
        wmin, wmax = get_eff_sigma(mass, pdf, cdf, options.mH - 10.,
                                   options.mH + 10.)
        ### hmin, hmax, hm = get_FWHM( points )

        helper.add(plot_ds, plot_ds.GetName())
        helper.add(plot_pdf, plot_pdf.GetName())
        helper.add((wmin, wmax), "eff_sigma%s" % c)
        helper.add((hmin, hmax, hm), "FWHM%s" % c)
        helper.add(ds.sumEntries(),
                   "sumEntries%s" % c)  # signal model integral

        # data integral for PAS tables
        data = ws.data("data_mass%s" % c)
        helper.add(
            data.sumEntries("CMS_hgg_mass>=%1.4f && CMS_hgg_mass<=%1.4f" %
                            (options.mH - 10., options.mH + 10.)),
            "data_sumEntries%s" % c)

        del cdf
        del pdf

    dsname = "sig_mass_m%1.0f_combcat" % options.mH
    print dsname
    combined_ds = helper.dsets[0].Clone(dsname)
    for d in helper.dsets[1:]:
        combined_ds.append(d)

    if options.binned:
        binned_ds = RooDataHist("binned_%s" % dsname, "binned_%s" % dsname,
                                aset, combined_ds)
        pdf = RooKeysPdf("pdf_%s" % (dsname), "pdf_%s" % dsname, mass,
                         combined_ds)
        plot_pdf = RooHistPdf("pdf_%s" % dsname, "pdf_%s" % dsname, aset,
                              plot_ds)
        helper.add(binned_ds, binned_ds.GetName())
    else:
        #### pdf = build_pdf(ws,"_combcat")
        #### pdf.fitTo(combined_ds, RooFit.Strategy(0), *fitopt )
        #### plot_pdf = pdf.Clone( "pdf_%s" % dsname )
        pdf = RooAddPdf(
            "pdf_%s" % dsname, "pdf_%s" % dsname,
            RooArgList(*(helper.histos["hggpdfrel%s" % c]
                         for c in categories)))
        plot_pdf = pdf

    cdf = pdf.createCdf(aset)

    plot_ds = RooDataHist("plot_%s" % dsname, "plot_%s" % dsname, aset, "plot")
    plot_ds.add(combined_ds)

    wmin, wmax = get_eff_sigma(mass, pdf, cdf, options.mH - 10.,
                               options.mH + 10.)
    hmin, hmax, hm = get_FWHM(mass, pdf, cdf, options.mH - 10.,
                              options.mH + 10.)

    helper.add(plot_ds, plot_ds.GetName())
    helper.add(plot_pdf, plot_pdf.GetName())
    helper.add((wmin, wmax), "eff_sigma_combcat")
    helper.add((hmin, hmax, hm), "FWHM_combcat")
    helper.add(plot_ds.sumEntries(), "sumEntries_combcat")

    mass.setRange("higgsrange", options.mH - 25., options.mH + 15.)

    del cdf
    del pdf
    del helper.dsets

    ### label = TLatex(0.1812081,0.8618881,"#scale[0.8]{#splitline{CMS preliminary}{Simulation}}")
    label = TLatex(0.7, 0.86,
                   "#scale[0.65]{#splitline{CMS preliminary}{Simulation}}")
    label.SetNDC(1)

    ##
    ## Make web page with plots
    ##
    if options.doWebPage:
        hth = HtmlHelper(options.outdir)
        hth.navbar().cell(HtmlTag("a")).firstChild().txt("..").set(
            "href", "../?C=M;O=D")
        hth.navbar().cell(HtmlTag("a")).firstChild().txt("home").set(
            "href", "./")

        tab = hth.body().add(HtmlTable())

    ip = 0
    for c in ["_combcat"] + categories:
        ### for c in categories:
        if options.doWebPage and ip % 4 == 0:
            row = tab.row()
        ip = ip + 1

        dsname = "sig_mass_m%1.0f%s" % (options.mH, c)
        canv = TCanvas(dsname, dsname, 600, 600)
        helper.objs.append(canv)

        ### leg = TLegend(0.4345638,0.6835664,0.9362416,0.9178322)
        leg = TLegend(0.2, 0.96, 0.5, 0.55)
        #apply_modifs( leg, [("SetLineColor",kWhite),("SetFillColor",kWhite),("SetFillStyle",0),("SetLineStyle",0)] )

        hplotcompint = mass.frame(RooFit.Bins(250), RooFit.Range("higgsrange"))
        helper.objs.append(hplotcompint)
        helper.objs.append(leg)

        plot_ds = helper.histos["plot_%s" % dsname]
        plot_pdf = helper.histos["pdf_%s" % dsname]
        wmin, wmax = helper.histos["eff_sigma%s" % c]
        hmin, hmax, hm = helper.histos["FWHM%s" % c]
        print hmin, hmax, hm

        style = (RooFit.LineColor(kBlue), RooFit.LineWidth(2),
                 RooFit.FillStyle(0))
        style_seff = (
            RooFit.LineWidth(2),
            RooFit.FillStyle(1001),
            RooFit.VLines(),
            RooFit.LineColor(15),
        )
        style_ds = (RooFit.MarkerStyle(kOpenSquare), )

        plot_ds.plotOn(hplotcompint, RooFit.Invisible())

        plot_pdf.plotOn(hplotcompint, RooFit.NormRange("higgsrange"),
                        RooFit.Range(wmin, wmax), RooFit.FillColor(19),
                        RooFit.DrawOption("F"), *style_seff)
        seffleg = hplotcompint.getObject(int(hplotcompint.numItems() - 1))
        plot_pdf.plotOn(hplotcompint, RooFit.NormRange("higgsrange"),
                        RooFit.Range(wmin, wmax), RooFit.LineColor(15),
                        *style_seff)

        plot_pdf.plotOn(hplotcompint, RooFit.NormRange("higgsrange"),
                        RooFit.Range("higgsrange"), *style)
        pdfleg = hplotcompint.getObject(int(hplotcompint.numItems() - 1))

        plot_ds.plotOn(hplotcompint, *style_ds)
        pointsleg = hplotcompint.getObject(int(hplotcompint.numItems() - 1))

        iob = int(hplotcompint.numItems() - 1)
        leg.AddEntry(pointsleg, "Simulation", "pe")
        leg.AddEntry(pdfleg, "Parametric model", "l")
        leg.AddEntry(seffleg,
                     "#sigma_{eff} = %1.2f GeV " % (0.5 * (wmax - wmin)), "fl")

        clabel = TLatex(0.74, 0.65,
                        "#scale[0.65]{#splitline{%s}{%s}}" % clables[c])
        clabel.SetNDC(1)
        helper.objs.append(clabel)

        hm = hplotcompint.GetMaximum() * 0.5 * 0.9
        ### hm = pdfleg.GetMaximum()*0.5
        fwhmarrow = TArrow(hmin, hm, hmax, hm)
        fwhmarrow.SetArrowSize(0.03)
        helper.objs.append(fwhmarrow)
        fwhmlabel = TPaveText(0.20, 0.58, 0.56, 0.48, "brNDC")
        fwhmlabel.SetFillStyle(0)
        fwhmlabel.SetLineColor(kWhite)
        reducedFWHM = (hmax - hmin) / 2.3548200
        fwhmlabel.AddText("FWHM/2.35 = %1.2f GeV" % reducedFWHM)
        helper.objs.append(fwhmlabel)

        hplotcompint.SetTitle("")
        hplotcompint.GetXaxis().SetNoExponent(True)
        hplotcompint.GetXaxis().SetTitle("m_{#gamma#gamma} (GeV)")
        hplotcompint.GetXaxis().SetNdivisions(509)
        ## hplotcompint.GetYaxis().SetTitle("A.U.");
        ## hplotcompint.GetYaxis().SetRangeUser(0.,hplotcompint.GetMaximum()*1.4);
        hplotcompint.Draw()
        leg.Draw("same")
        label.Draw("same")
        clabel.Draw("same")
        fwhmarrow.Draw("<>")
        fwhmlabel.Draw("same")

        plot_ds.sumEntries()

        if options.doWebPage:
            hpl = HtmlPlot(canv, False, "", True, True, True)
            hpl.caption("<i>%s</i>" % canv.GetTitle())
            row.cell(hpl)
        else:
            if os.path.isdir(options.outdir) is False:
                os.mkdir(options.outdir)
            for ext in "C", "png", "pdf":
                canv.SaveAs(
                    os.path.join(options.outdir,
                                 "%s.%s" % (canv.GetName(), ext)))

        if "comb" in c:
            ip = 0

    if options.doWebPage:
        print "Creating pages..."
        hth.dump()

    for f in helper.files:
        f.Close()
    gROOT.Reset()

    from pprint import pprint
    pprint(helper)

    print 'Summary statistics per event class'
    print 'Cat\tSignal\t\tData/GeV (in %3.1f+/-10)\tsigEff\tFWHM/2.35' % options.mH
    sigTotal = 0.
    dataTotal = 0.
    for c in categories:
        sigVal = helper.histos["sumEntries%s" % c]
        datVal = helper.histos["data_sumEntries%s" % c]
        sigTotal += sigVal
        dataTotal += datVal
    for c in categories:
        sigVal = helper.histos["sumEntries%s" % c]
        datVal = helper.histos["data_sumEntries%s" % c]
        effSig = 0.5 * (helper.histos["eff_sigma%s" % c][1] -
                        helper.histos["eff_sigma%s" % c][0])
        fwhm = (helper.histos["FWHM%s" % c][1] -
                helper.histos["FWHM%s" % c][0]) / 2.3548200
        print c, '\t%3.1f (%3.1f%%)\t%3.1f (%3.1f%%)\t\t\t%2.2f\t%2.2f' % (
            sigVal, 100. * sigVal / sigTotal, datVal /
            (10. + 10.), 100. * datVal / dataTotal, effSig, fwhm)

    print "Done."
Ejemplo n.º 6
0
if bkgConst:
  dcFN = outdir_datacards+'Qstar'+str(mass)+'_datacard_const_'+name+'.txt'
  wsFN = outdir_datacards+'Qstar'+str(mass)+'_workspace_const_'+name+'.root'
elif bkgNuisance:
  dcFN = outdir_datacards+'Qstar'+str(mass)+'_datacard_nuisance.txt'
  wsFN = outdir_datacards+'Qstar'+str(mass)+'_workspace_nuisance.root'
  #dcFN = outdir_datacards+'Qstar'+str(mass)+'_datacard_nuisance_testForSignificance.txt'
  #wsFN = outdir_datacards+'Qstar'+str(mass)+'_workspace_nuisance_testForSignificance.root'

else:
  dcFN = outdir_datacards+'Qstar'+str(mass)+'_datacard_'+name+'.txt'
  wsFN = outdir_datacards+'Qstar'+str(mass)+'_workspace_'+name+'.root'



nObs = dataHist_data.sumEntries();
#nObs = roohistBkg.sumEntries();
#nBkg = roohistBkg.sumEntries();


w = RooWorkspace('w','workspace')
getattr(w,'import')(signal)
getattr(w,'import')(background)
#getattr(w,'import')(roohistBkg,RooFit.Rename("data_obs"))  
getattr(w,'import')(dataHist_data,RooFit.Rename("data_obs"))  
getattr(w,'import')(background_norm)
w.Print()
w.writeToFile(wsFN)

# -----------------------------------------
# write a datacard
    genFitter.ws.set('params').Print('v')

    if opts.extendedGen:
        data = genPdf.generate(genFitter.ws.set('obsSet'),
                               RooFit.Name('data_obs'), RooFit.Extended())
    else:
        data = genPdf.generate(genFitter.ws.set('obsSet'),
                               RooFit.Name('data_obs'))

    if fitter.pars.binData:
        data = RooDataHist('data_obs', 'data_obs', genFitter.ws.set('obsSet'),
                           data)
        data.Print('v')
    getattr(fitter.ws, 'import')(data)

    print 'Generated Data Events: %.0f' % (data.sumEntries())

elif opts.runMCGenToySim:
    print "performing ToyMC Generation:"
    print "Generating ", opts.extdiboson, " diboson events"
    dibosonfiles = getattr(pars, 'dibosonFiles')
    dibosontoymodels = [-1]
    dibosonPdf = fitter.makeComponentPdf('dibosontoy', dibosonfiles,
                                         dibosontoymodels)
    dibosontoymc = dibosonPdf.generate(fitter.ws.set('obsSet'),
                                       opts.extdiboson,
                                       RooFit.Name('data_obs'))
    dibosontoymc.Print()
    gentoymc = dibosontoymc
    print "Generating ", opts.extWpJ, " WpJ events"
    WpJfiles = getattr(pars, 'WpJFiles')
Ejemplo n.º 8
0
def main():
    # usage description
    usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2"

    # input parameters
    parser = ArgumentParser(
        description=
        'Script that creates combine datacards and corresponding RooFit workspaces',
        epilog=usage)

    parser.add_argument("--inputData",
                        dest="inputData",
                        required=True,
                        help="Input data spectrum",
                        metavar="INPUT_DATA")

    parser.add_argument("--dataHistname",
                        dest="dataHistname",
                        required=True,
                        help="Data histogram name",
                        metavar="DATA_HISTNAME")

    parser.add_argument("--inputSig",
                        dest="inputSig",
                        required=True,
                        help="Input signal shapes",
                        metavar="INPUT_SIGNAL")

    parser.add_argument("-f",
                        "--final_state",
                        dest="final_state",
                        required=True,
                        help="Final state (e.g. qq, qg, gg)",
                        metavar="FINAL_STATE")

    parser.add_argument("-f2",
                        "--type",
                        dest="atype",
                        required=True,
                        help="Type (e.g. hG, lG, hR, lR)")

    parser.add_argument(
        "-o",
        "--output_path",
        dest="output_path",
        required=True,
        help="Output path where datacards and workspaces will be stored",
        metavar="OUTPUT_PATH")

    parser.add_argument(
        "-l",
        "--lumi",
        dest="lumi",
        required=True,
        default=1000.,
        type=float,
        help="Integrated luminosity in pb-1 (default: %(default).1f)",
        metavar="LUMI")

    parser.add_argument(
        "--massMin",
        dest="massMin",
        default=500,
        type=int,
        help=
        "Lower bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MIN")

    parser.add_argument(
        "--massMax",
        dest="massMax",
        default=1200,
        type=int,
        help=
        "Upper bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MAX")

    parser.add_argument(
        "--p1",
        dest="p1",
        default=5.0000e-03,
        type=float,
        help="Fit function p1 parameter (default: %(default)e)",
        metavar="P1")

    parser.add_argument(
        "--p2",
        dest="p2",
        default=9.1000e+00,
        type=float,
        help="Fit function p2 parameter (default: %(default)e)",
        metavar="P2")

    parser.add_argument(
        "--p3",
        dest="p3",
        default=5.0000e-01,
        type=float,
        help="Fit function p3 parameter (default: %(default)e)",
        metavar="P3")

    parser.add_argument(
        "--lumiUnc",
        dest="lumiUnc",
        required=True,
        type=float,
        help="Relative uncertainty in the integrated luminosity",
        metavar="LUMI_UNC")

    parser.add_argument("--jesUnc",
                        dest="jesUnc",
                        type=float,
                        help="Relative uncertainty in the jet energy scale",
                        metavar="JES_UNC")

    parser.add_argument(
        "--jerUnc",
        dest="jerUnc",
        type=float,
        help="Relative uncertainty in the jet energy resolution",
        metavar="JER_UNC")

    parser.add_argument(
        "--sqrtS",
        dest="sqrtS",
        default=13000.,
        type=float,
        help="Collision center-of-mass energy (default: %(default).1f)",
        metavar="SQRTS")

    parser.add_argument("--fixP3",
                        dest="fixP3",
                        default=False,
                        action="store_true",
                        help="Fix the fit function p3 parameter")

    parser.add_argument("--runFit",
                        dest="runFit",
                        default=False,
                        action="store_true",
                        help="Run the fit")

    parser.add_argument("--fitBonly",
                        dest="fitBonly",
                        default=False,
                        action="store_true",
                        help="Run B-only fit")

    parser.add_argument("--fixBkg",
                        dest="fixBkg",
                        default=False,
                        action="store_true",
                        help="Fix all background parameters")

    parser.add_argument("--decoBkg",
                        dest="decoBkg",
                        default=False,
                        action="store_true",
                        help="Decorrelate background parameters")

    parser.add_argument("--fitStrategy",
                        dest="fitStrategy",
                        type=int,
                        default=1,
                        help="Fit strategy (default: %(default).1f)")

    parser.add_argument("--debug",
                        dest="debug",
                        default=False,
                        action="store_true",
                        help="Debug printout")

    parser.add_argument(
        "--postfix",
        dest="postfix",
        default='',
        help="Postfix for the output file names (default: %(default)s)")

    parser.add_argument("--pyes",
                        dest="pyes",
                        default=False,
                        action="store_true",
                        help="Make files for plots")

    parser.add_argument("--jyes",
                        dest="jyes",
                        default=False,
                        action="store_true",
                        help="Make files for JES/JER plots")

    parser.add_argument(
        "--pdir",
        dest="pdir",
        default='testarea',
        help="Name a directory for the plots (default: %(default)s)")

    parser.add_argument("--chi2",
                        dest="chi2",
                        default=False,
                        action="store_true",
                        help="Compute chi squared")

    parser.add_argument("--widefit",
                        dest="widefit",
                        default=False,
                        action="store_true",
                        help="Fit with wide bin hist")

    mass_group = parser.add_mutually_exclusive_group(required=True)
    mass_group.add_argument(
        "--mass",
        type=int,
        nargs='*',
        default=1000,
        help=
        "Mass can be specified as a single value or a whitespace separated list (default: %(default)i)"
    )
    mass_group.add_argument(
        "--massrange",
        type=int,
        nargs=3,
        help="Define a range of masses to be produced. Format: min max step",
        metavar=('MIN', 'MAX', 'STEP'))
    mass_group.add_argument("--masslist",
                            help="List containing mass information")

    args = parser.parse_args()

    if args.atype == 'hG':
        fstr = "bbhGGBB"
        in2 = 'bcorrbin/binmodh.root'
    elif args.atype == 'hR':
        fstr = "bbhRS"
        in2 = 'bcorrbin/binmodh.root'
    elif args.atype == 'lG':
        fstr = "bblGGBB"
        in2 = 'bcorrbin/binmodl.root'
    else:
        fstr = "bblRS"
        in2 = 'bcorrbin/binmodl.root'

    # check if the output directory exists
    if not os.path.isdir(os.path.join(os.getcwd(), args.output_path)):
        os.mkdir(os.path.join(os.getcwd(), args.output_path))

    # mass points for which resonance shapes will be produced
    masses = []

    if args.massrange != None:
        MIN, MAX, STEP = args.massrange
        masses = range(MIN, MAX + STEP, STEP)
    elif args.masslist != None:
        # A mass list was provided
        print "Will create mass list according to", args.masslist
        masslist = __import__(args.masslist.replace(".py", ""))
        masses = masslist.masses
    else:
        masses = args.mass

    # sort masses
    masses.sort()

    # import ROOT stuff
    from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine
    from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf, RooExtendPdf

    if not args.debug:
        RooMsgService.instance().setSilentMode(kTRUE)
        RooMsgService.instance().setStreamStatus(0, kFALSE)
        RooMsgService.instance().setStreamStatus(1, kFALSE)

    # input data file
    inputData = TFile(args.inputData)
    # input data histogram
    hData = inputData.Get(args.dataHistname)

    inData2 = TFile(in2)
    hData2 = inData2.Get('h_data')

    # input sig file
    inputSig = TFile(args.inputSig)

    sqrtS = args.sqrtS

    # mass variable
    mjj = RooRealVar('mjj', 'mjj', float(args.massMin), float(args.massMax))

    # integrated luminosity and signal cross section
    lumi = args.lumi
    signalCrossSection = 1.  # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section

    for mass in masses:

        print ">> Creating datacard and workspace for %s resonance with m = %i GeV..." % (
            args.final_state, int(mass))

        # get signal shape
        hSig = inputSig.Get("h_" + args.final_state + "_" + str(int(mass)))
        # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity)
        hSig.Scale(
            signalCrossSection * lumi / hSig.Integral()
        )  # divide by a number that provides roughly an r value of 1-10
        rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(mjj),
                                 hSig)
        print 'Signal acceptance:', (rooSigHist.sumEntries() / hSig.Integral())
        signal = RooHistPdf('signal', 'signal', RooArgSet(mjj), rooSigHist)
        signal_norm = RooRealVar('signal_norm', 'signal_norm', 0, -1e+05,
                                 1e+05)
        signal_norm2 = RooRealVar('signal_norm2', 'signal_norm2', 0, -1e+05,
                                  1e+05)
        signal_norm3 = RooRealVar('signal_norm3', 'signal_norm3', 0, -1e+05,
                                  1e+05)
        signal_norm4 = RooRealVar('signal_norm4', 'signal_norm4', 0, -1e+05,
                                  1e+05)
        signal_norm5 = RooRealVar('signal_norm5', 'signal_norm5', 0, -1e+05,
                                  1e+05)

        if args.fitBonly:
            signal_norm.setConstant()
            signal_norm2.setConstant()
            signal_norm3.setConstant()
            signal_norm4.setConstant()
            signal_norm5.setConstant()

        p1 = RooRealVar('p1', 'p1', args.p1, 0., 100.)
        p2 = RooRealVar('p2', 'p2', args.p2, 0., 60.)
        p3 = RooRealVar('p3', 'p3', args.p3, -10., 10.)
        p4 = RooRealVar('p4', 'p4', 5.6, -50., 50.)
        p5 = RooRealVar('p5', 'p5', 10., -50., 50.)
        p6 = RooRealVar('p6', 'p6', .016, -50., 50.)
        p7 = RooRealVar('p7', 'p7', 8., -50., 50.)
        p8 = RooRealVar('p8', 'p8', .22, -50., 50.)
        p9 = RooRealVar('p9', 'p9', 14.1, -50., 50.)
        p10 = RooRealVar('p10', 'p10', 8., -50., 50.)
        p11 = RooRealVar('p11', 'p11', 4.8, -50., 50.)
        p12 = RooRealVar('p12', 'p12', 7., -50., 50.)
        p13 = RooRealVar('p13', 'p13', 7., -50., 50.)
        p14 = RooRealVar('p14', 'p14', 7., -50., 50.)
        p15 = RooRealVar('p15', 'p15', 1., -50., 50.)
        p16 = RooRealVar('p16', 'p16', 9., -50., 50.)
        p17 = RooRealVar('p17', 'p17', 0.6, -50., 50.)

        if args.fixP3: p3.setConstant()

        background = RooGenericPdf(
            'background',
            '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
            (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p1, p2, p3))
        dataInt = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),
                                 hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm = RooRealVar('background_norm', 'background_norm',
                                     dataInt, 0., 1e+08)

        background2 = RooGenericPdf(
            'background2',
            '(pow(@0/%.1f,-@1)*pow(1-@0/%.1f,@2))' % (sqrtS, sqrtS),
            RooArgList(mjj, p4, p5))
        dataInt2 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background2_norm = RooRealVar('background2_norm', 'background2_norm',
                                      dataInt2, 0., 1e+08)

        background3 = RooGenericPdf('background3',
                                    '(1/pow(@1+@0/%.1f,@2))' % (sqrtS),
                                    RooArgList(mjj, p6, p7))
        dataInt3 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background3_norm = RooRealVar('background3_norm', 'background3_norm',
                                      dataInt3, 0., 1e+08)

        background4 = RooGenericPdf(
            'background4',
            '(1/pow(@1+@2*@0/%.1f+pow(@0/%.1f,2),@3))' % (sqrtS, sqrtS),
            RooArgList(mjj, p8, p9, p10))
        dataInt4 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background4_norm = RooRealVar('background4_norm', 'background4_norm',
                                      dataInt4, 0., 1e+08)

        background5 = RooGenericPdf(
            'background5',
            '(pow(@0/%.1f,-@1)*pow(1-pow(@0/%.1f,1/3),@2))' % (sqrtS, sqrtS),
            RooArgList(mjj, p11, p12))
        dataInt5 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background5_norm = RooRealVar('background5_norm', 'background5_norm',
                                      dataInt5, 0., 1e+08)

        background6 = RooGenericPdf(
            'background6', '(pow(@0/%.1f,2)+@1*@0/%.1f+@2)' % (sqrtS, sqrtS),
            RooArgList(mjj, p13, p14))
        dataInt6 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm6 = RooRealVar('background_norm6', 'background_norm6',
                                      dataInt6, 0., 1e+08)

        background7 = RooGenericPdf(
            'background7',
            '((-1+@1*@0/%.1f)*pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
            (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p15, p16, p17))
        dataInt7 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm7 = RooRealVar('background_norm7', 'background_norm7',
                                      dataInt7, 0., 1e+08)

        #Extend PDFs

        exts = RooExtendPdf('extsignal', 'Extended Signal Pdf', signal,
                            signal_norm)
        extb = RooExtendPdf('extbackground', 'Extended Background Pdf',
                            background, background_norm)
        exts2 = RooExtendPdf('extsignal2', 'Extended Signal Pdf2', signal,
                             signal_norm2)
        extb2 = RooExtendPdf('extbackground2', 'Extended Background Pdf2',
                             background2, background2_norm)
        exts3 = RooExtendPdf('extsignal3', 'Extended Signal Pdf3', signal,
                             signal_norm3)
        extb3 = RooExtendPdf('extbackground3', 'Extended Background Pdf3',
                             background3, background3_norm)
        exts4 = RooExtendPdf('extsignal4', 'Extended Signal Pdf4', signal,
                             signal_norm4)
        extb4 = RooExtendPdf('extbackground4', 'Extended Background Pdf4',
                             background4, background4_norm)
        exts5 = RooExtendPdf('extsignal5', 'Extended Signal Pdf5', signal,
                             signal_norm5)
        extb5 = RooExtendPdf('extbackground5', 'Extended Background Pdf5',
                             background5, background5_norm)

        # S+B model
        model = RooAddPdf("model", "s+b", RooArgList(extb, exts))
        model2 = RooAddPdf("model2", "s+b2", RooArgList(extb2, exts2))
        model3 = RooAddPdf("model3", "s+b3", RooArgList(extb3, exts3))
        model4 = RooAddPdf("model4", "s+b4", RooArgList(extb4, exts4))
        model5 = RooAddPdf("model5", "s+b5", RooArgList(extb5, exts5))

        #model6 = RooAddPdf("model6","s+b6",RooArgList(background6,signal),RooArgList(background_norm6,signal_norm))
        #model7 = RooAddPdf("model7","s+b7",RooArgList(background7,signal),RooArgList(background_norm7,signal_norm))

        rooDataHist = RooDataHist('rooDatahist', 'rooDathist', RooArgList(mjj),
                                  hData)

        if args.runFit:
            mframe = mjj.frame()
            rooDataHist.plotOn(mframe, ROOT.RooFit.Name("setonedata"))
            res = model.fitTo(rooDataHist, RooFit.Save(kTRUE),
                              RooFit.Extended(kTRUE),
                              RooFit.Strategy(args.fitStrategy))
            model.plotOn(mframe, ROOT.RooFit.Name("model1"),
                         ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1),
                         ROOT.RooFit.LineColor(ROOT.EColor.kRed))
            res2 = model2.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model2.plotOn(mframe, ROOT.RooFit.Name("model2"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kOrange))
            res3 = model3.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model3.plotOn(mframe, ROOT.RooFit.Name("model3"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
            res4 = model4.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model4.plotOn(mframe, ROOT.RooFit.Name("model4"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
            res5 = model5.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model5.plotOn(mframe, ROOT.RooFit.Name("model5"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kViolet))
            #	    res6 = model6.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            #           model6.plotOn(mframe, ROOT.RooFit.Name("model6"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kPink))
            #	    res7 = model7.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            #           model7.plotOn(mframe, ROOT.RooFit.Name("model7"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kAzure))

            rooDataHist2 = RooDataHist('rooDatahist2', 'rooDathist2',
                                       RooArgList(mjj), hData2)
            #	    rooDataHist2.plotOn(mframe, ROOT.RooFit.Name("data"))

            if args.pyes:
                c = TCanvas("c", "c", 800, 800)
                mframe.SetAxisRange(300., 1300.)
                c.SetLogy()
                #	    	mframe.SetMaximum(10)
                #	    	mframe.SetMinimum(1)
                mframe.Draw()
                fitname = args.pdir + '/5funcfit_m' + str(mass) + fstr + '.pdf'
                c.SaveAs(fitname)

#	        cpull = TCanvas("cpull","cpull",800,800)
#	    	pulls = mframe.pullHist("data","model1")
#	    	pulls.Draw("ABX")
#	   	pullname = args.pdir+'/pull_m'+str(mass)+fstr+'.pdf'
#	    	cpull.SaveAs(pullname)

#		cpull2 = TCanvas("cpull2","cpull2",800,800)
#               pulls2 = mframe.pullHist("setonedata","model1")
#              pulls2.Draw("ABX")
#             pull2name = args.pdir+'/pull2_m'+str(mass)+fstr+'.pdf'
#            cpull2.SaveAs(pull2name)

            if args.widefit:
                mframew = mjj.frame()
                rooDataHist2.plotOn(mframew, ROOT.RooFit.Name("data"))
                res6 = model.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                   RooFit.Strategy(args.fitStrategy))
                model.plotOn(mframew, ROOT.RooFit.Name("model1"),
                             ROOT.RooFit.LineStyle(1),
                             ROOT.RooFit.LineWidth(1),
                             ROOT.RooFit.LineColor(ROOT.EColor.kRed))
                res7 = model2.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                    RooFit.Strategy(args.fitStrategy))
                model2.plotOn(mframew, ROOT.RooFit.Name("model2"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kOrange))
                res8 = model3.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                    RooFit.Strategy(args.fitStrategy))
                model3.plotOn(mframew, ROOT.RooFit.Name("model3"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
                res9 = model4.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                    RooFit.Strategy(args.fitStrategy))
                model4.plotOn(mframew, ROOT.RooFit.Name("model4"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
                res10 = model5.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                     RooFit.Strategy(args.fitStrategy))
                model5.plotOn(mframew, ROOT.RooFit.Name("model5"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kViolet))

                if args.pyes:
                    c = TCanvas("c", "c", 800, 800)
                    mframew.SetAxisRange(300., 1300.)
                    c.SetLogy()
                    #                   mframew.SetMaximum(10)
                    #                   mframew.SetMinimum(1)
                    mframew.Draw()
                    fitname = args.pdir + '/5funcfittowide_m' + str(
                        mass) + fstr + '.pdf'
                    c.SaveAs(fitname)

                    cpull = TCanvas("cpull", "cpull", 800, 800)
                    pulls = mframew.pullHist("data", "model1")
                    pulls.Draw("ABX")
                    pullname = args.pdir + '/pullwidefit_m' + str(
                        mass) + fstr + '.pdf'
                    cpull.SaveAs(pullname)

            if args.chi2:
                fullInt = model.createIntegral(RooArgSet(mjj))
                norm = dataInt / fullInt.getVal()
                chi1 = 0.
                fullInt2 = model2.createIntegral(RooArgSet(mjj))
                norm2 = dataInt2 / fullInt2.getVal()
                chi2 = 0.
                fullInt3 = model3.createIntegral(RooArgSet(mjj))
                norm3 = dataInt3 / fullInt3.getVal()
                chi3 = 0.
                fullInt4 = model4.createIntegral(RooArgSet(mjj))
                norm4 = dataInt4 / fullInt4.getVal()
                chi4 = 0.
                fullInt5 = model5.createIntegral(RooArgSet(mjj))
                norm5 = dataInt5 / fullInt5.getVal()
                chi5 = 0.
                for i in range(args.massMin, args.massMax):
                    new = 0
                    new2 = 0
                    new3 = 0
                    new4 = 0
                    new5 = 0
                    height = hData.GetBinContent(i)
                    xLow = hData.GetXaxis().GetBinLowEdge(i)
                    xUp = hData.GetXaxis().GetBinLowEdge(i + 1)
                    obs = height * (xUp - xLow)
                    mjj.setRange("intrange", xLow, xUp)
                    integ = model.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp = integ.getVal() * norm
                    new = pow(exp - obs, 2) / exp
                    chi1 = chi1 + new
                    integ2 = model2.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp2 = integ2.getVal() * norm2
                    new2 = pow(exp2 - obs, 2) / exp2
                    chi2 = chi2 + new2
                    integ3 = model3.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp3 = integ3.getVal() * norm3
                    new3 = pow(exp3 - obs, 2) / exp3
                    chi3 = chi3 + new3
                    integ4 = model4.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp4 = integ4.getVal() * norm4
                    if exp4 != 0:
                        new4 = pow(exp4 - obs, 2) / exp4
                    else:
                        new4 = 0
                    chi4 = chi4 + new4
                    integ5 = model5.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp5 = integ5.getVal() * norm5
                    new5 = pow(exp5 - obs, 2) / exp5
                    chi5 = chi5 + new5
                print "chi1 %d " % (chi1)
                print "chi2 %d " % (chi2)
                print "chi3 %d " % (chi3)
                print "chi4 %d " % (chi4)
                print "chi5 %d " % (chi5)

            if not args.decoBkg:
                print " "
                res.Print()
                res2.Print()
                res3.Print()
                res4.Print()
                res5.Print()


#		res6.Print()
#		res7.Print()

# decorrelated background parameters for Bayesian limits
            if args.decoBkg:
                signal_norm.setConstant()
                res = model.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                  RooFit.Strategy(args.fitStrategy))
                res.Print()
                ## temp workspace for the PDF diagonalizer
                w_tmp = RooWorkspace("w_tmp")
                deco = PdfDiagonalizer("deco", w_tmp, res)
                # here diagonalizing only the shape parameters since the overall normalization is already decorrelated
                background_deco = deco.diagonalize(background)
                print "##################### workspace for decorrelation"
                w_tmp.Print("v")
                print "##################### original parameters"
                background.getParameters(rooDataHist).Print("v")
                print "##################### decorrelated parameters"
                # needed if want to evaluate limits without background systematics
                if args.fixBkg:
                    w_tmp.var("deco_eig1").setConstant()
                    w_tmp.var("deco_eig2").setConstant()
                    if not args.fixP3: w_tmp.var("deco_eig3").setConstant()
                background_deco.getParameters(rooDataHist).Print("v")
                print "##################### original pdf"
                background.Print()
                print "##################### decorrelated pdf"
                background_deco.Print()
                # release signal normalization
                signal_norm.setConstant(kFALSE)
                # set the background normalization range to +/- 5 sigma
                bkg_val = background_norm.getVal()
                bkg_error = background_norm.getError()
                background_norm.setMin(bkg_val - 5 * bkg_error)
                background_norm.setMax(bkg_val + 5 * bkg_error)
                background_norm.Print()
                # change background PDF names
                background.SetName("background_old")
                background_deco.SetName("background")

        # needed if want to evaluate limits without background systematics
        if args.fixBkg:
            background_norm.setConstant()
            p1.setConstant()
            p2.setConstant()
            p3.setConstant()

        # -----------------------------------------
        # dictionaries holding systematic variations of the signal shape
        hSig_Syst = {}
        hSig_Syst_DataHist = {}
        sigCDF = TGraph(hSig.GetNbinsX() + 1)

        # JES and JER uncertainties
        if args.jesUnc != None or args.jerUnc != None:

            sigCDF.SetPoint(0, 0., 0.)
            integral = 0.
            for i in range(1, hSig.GetNbinsX() + 1):
                x = hSig.GetXaxis().GetBinLowEdge(i + 1)
                integral = integral + hSig.GetBinContent(i)
                sigCDF.SetPoint(i, x, integral)

        if args.jesUnc != None:
            hSig_Syst['JESUp'] = copy.deepcopy(hSig)
            hSig_Syst['JESDown'] = copy.deepcopy(hSig)

        if args.jerUnc != None:
            hSig_Syst['JERUp'] = copy.deepcopy(hSig)
            hSig_Syst['JERDown'] = copy.deepcopy(hSig)

        # reset signal histograms
        for key in hSig_Syst.keys():
            hSig_Syst[key].Reset()
            hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key)

        # produce JES signal shapes
        if args.jesUnc != None:
            for i in range(1, hSig.GetNbinsX() + 1):
                xLow = hSig.GetXaxis().GetBinLowEdge(i)
                xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                jes = 1. - args.jesUnc
                xLowPrime = jes * xLow
                xUpPrime = jes * xUp
                hSig_Syst['JESUp'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                jes = 1. + args.jesUnc
                xLowPrime = jes * xLow
                xUpPrime = jes * xUp
                hSig_Syst['JESDown'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
            hSig_Syst_DataHist['JESUp'] = RooDataHist('hSig_JESUp',
                                                      'hSig_JESUp',
                                                      RooArgList(mjj),
                                                      hSig_Syst['JESUp'])
            hSig_Syst_DataHist['JESDown'] = RooDataHist(
                'hSig_JESDown', 'hSig_JESDown', RooArgList(mjj),
                hSig_Syst['JESDown'])

            if args.jyes:
                c2 = TCanvas("c2", "c2", 800, 800)
                mframe2 = mjj.frame(ROOT.RooFit.Title("JES One Sigma Shifts"))
                mframe2.SetAxisRange(args.massMin, args.massMax)
                hSig_Syst_DataHist['JESUp'].plotOn(
                    mframe2, ROOT.RooFit.Name("JESUP"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kRed),
                    ROOT.RooFit.LineColor(ROOT.EColor.kRed))
                hSig_Syst_DataHist['JESDown'].plotOn(
                    mframe2, ROOT.RooFit.Name("JESDOWN"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue),
                    ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
                rooSigHist.plotOn(mframe2, ROOT.RooFit.DataError(2),
                                  ROOT.RooFit.Name("SIG"),
                                  ROOT.RooFit.DrawOption("L"),
                                  ROOT.RooFit.LineStyle(1),
                                  ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen),
                                  ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
                mframe2.Draw()
                mframe2.GetXaxis().SetTitle("Dijet Mass (GeV)")
                leg = TLegend(0.7, 0.8, 0.9, 0.9)
                leg.SetFillColor(0)
                leg.AddEntry(mframe2.findObject("SIG"), "Signal Model", "l")
                leg.AddEntry(mframe2.findObject("JESUP"), "+1 Sigma", "l")
                leg.AddEntry(mframe2.findObject("JESDOWN"), "-1 Sigma", "l")
                leg.Draw()
                jesname = args.pdir + '/jes_m' + str(mass) + fstr + '.pdf'
                c2.SaveAs(jesname)

        # produce JER signal shapes
        if args.jesUnc != None:
            for i in range(1, hSig.GetNbinsX() + 1):
                xLow = hSig.GetXaxis().GetBinLowEdge(i)
                xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                jer = 1. - args.jerUnc
                xLowPrime = jer * (xLow - float(mass)) + float(mass)
                xUpPrime = jer * (xUp - float(mass)) + float(mass)
                hSig_Syst['JERUp'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                jer = 1. + args.jerUnc
                xLowPrime = jer * (xLow - float(mass)) + float(mass)
                xUpPrime = jer * (xUp - float(mass)) + float(mass)
                hSig_Syst['JERDown'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
            hSig_Syst_DataHist['JERUp'] = RooDataHist('hSig_JERUp',
                                                      'hSig_JERUp',
                                                      RooArgList(mjj),
                                                      hSig_Syst['JERUp'])
            hSig_Syst_DataHist['JERDown'] = RooDataHist(
                'hSig_JERDown', 'hSig_JERDown', RooArgList(mjj),
                hSig_Syst['JERDown'])

            if args.jyes:
                c3 = TCanvas("c3", "c3", 800, 800)
                mframe3 = mjj.frame(ROOT.RooFit.Title("JER One Sigma Shifts"))
                mframe3.SetAxisRange(args.massMin, args.massMax)
                hSig_Syst_DataHist['JERUp'].plotOn(
                    mframe3, ROOT.RooFit.Name("JERUP"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kRed),
                    ROOT.RooFit.LineColor(ROOT.EColor.kRed))
                hSig_Syst_DataHist['JERDown'].plotOn(
                    mframe3, ROOT.RooFit.Name("JERDOWN"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue),
                    ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
                rooSigHist.plotOn(mframe3, ROOT.RooFit.DrawOption("L"),
                                  ROOT.RooFit.Name("SIG"),
                                  ROOT.RooFit.DataError(2),
                                  ROOT.RooFit.LineStyle(1),
                                  ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen),
                                  ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
                mframe3.Draw()
                mframe3.GetXaxis().SetTitle("Dijet Mass (GeV)")
                leg = TLegend(0.7, 0.8, 0.9, 0.9)
                leg.SetFillColor(0)
                leg.AddEntry(mframe3.findObject("SIG"), "Signal Model", "l")
                leg.AddEntry(mframe3.findObject("JERUP"), "+1 Sigma", "l")
                leg.AddEntry(mframe3.findObject("JERDOWN"), "-1 Sigma", "l")
                leg.Draw()
                jername = args.pdir + '/jer_m' + str(mass) + fstr + '.pdf'
                c3.SaveAs(jername)

        # -----------------------------------------
        # create a datacard and corresponding workspace
        postfix = (('_' + args.postfix) if args.postfix != '' else '')
        dcName = 'datacard_' + args.final_state + '_m' + str(
            mass) + postfix + '.txt'
        wsName = 'workspace_' + args.final_state + '_m' + str(
            mass) + postfix + '.root'

        w = RooWorkspace('w', 'workspace')
        getattr(w, 'import')(rooSigHist, RooFit.Rename("signal"))
        if args.jesUnc != None:
            getattr(w, 'import')(hSig_Syst_DataHist['JESUp'],
                                 RooFit.Rename("signal__JESUp"))
            getattr(w, 'import')(hSig_Syst_DataHist['JESDown'],
                                 RooFit.Rename("signal__JESDown"))
        if args.jerUnc != None:
            getattr(w, 'import')(hSig_Syst_DataHist['JERUp'],
                                 RooFit.Rename("signal__JERUp"))
            getattr(w, 'import')(hSig_Syst_DataHist['JERDown'],
                                 RooFit.Rename("signal__JERDown"))
        if args.decoBkg:
            getattr(w, 'import')(background_deco, ROOT.RooCmdArg())
        else:
            getattr(w, 'import')(background, ROOT.RooCmdArg(),
                                 RooFit.Rename("background"))
            getattr(w, 'import')(background2, ROOT.RooCmdArg(),
                                 RooFit.Rename("background2"))
            getattr(w, 'import')(background3, ROOT.RooCmdArg(),
                                 RooFit.Rename("background3"))
            getattr(w, 'import')(background4, ROOT.RooCmdArg(),
                                 RooFit.Rename("background4"))
            getattr(w, 'import')(background5, ROOT.RooCmdArg(),
                                 RooFit.Rename("background5"))
            getattr(w, 'import')(background_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background_norm"))
            getattr(w, 'import')(background2_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background2_norm"))
            getattr(w, 'import')(background3_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background3_norm"))
            getattr(w, 'import')(background4_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background4_norm"))
            getattr(w, 'import')(background5_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background5_norm"))

        getattr(w, 'import')(res)
        getattr(w, 'import')(res2)
        getattr(w, 'import')(res3)
        getattr(w, 'import')(res4)
        getattr(w, 'import')(res5)
        getattr(w, 'import')(background_norm, ROOT.RooCmdArg())
        getattr(w, 'import')(signal_norm, ROOT.RooCmdArg())
        getattr(w, 'import')(rooDataHist, RooFit.Rename("data_obs"))
        w.Print()
        w.writeToFile(os.path.join(args.output_path, wsName))

        beffUnc = 0.3
        boffUnc = 0.06

        datacard = open(os.path.join(args.output_path, dcName), 'w')
        datacard.write('imax 1\n')
        datacard.write('jmax 1\n')
        datacard.write('kmax *\n')
        datacard.write('---------------\n')
        if args.jesUnc != None or args.jerUnc != None:
            datacard.write('shapes * * ' + wsName +
                           ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
        else:
            datacard.write('shapes * * ' + wsName + ' w:$PROCESS\n')
        datacard.write('---------------\n')
        datacard.write('bin 1\n')
        datacard.write('observation -1\n')
        datacard.write('------------------------------\n')
        datacard.write('bin          1          1\n')
        datacard.write('process      signal     background\n')
        datacard.write('process      0          1\n')
        datacard.write('rate         -1         1\n')
        datacard.write('------------------------------\n')
        datacard.write('lumi  lnN    %f         -\n' % (1. + args.lumiUnc))
        datacard.write('beff  lnN    %f         -\n' % (1. + beffUnc))
        datacard.write('boff  lnN    %f         -\n' % (1. + boffUnc))
        datacard.write('bkg   lnN     -         1.03\n')
        if args.jesUnc != None:
            datacard.write('JES  shape   1          -\n')
        if args.jerUnc != None:
            datacard.write('JER  shape   1          -\n')
        # flat parameters --- flat prior
        datacard.write('background_norm  flatParam\n')
        if args.decoBkg:
            datacard.write('deco_eig1  flatParam\n')
            datacard.write('deco_eig2  flatParam\n')
            if not args.fixP3: datacard.write('deco_eig3  flatParam\n')
        else:
            datacard.write('p1  flatParam\n')
            datacard.write('p2  flatParam\n')
            if not args.fixP3: datacard.write('p3  flatParam\n')
        datacard.close()

    print '>> Datacards and workspaces created and stored in %s/' % (
        os.path.join(os.getcwd(), args.output_path))
def main():
    # usage description
    usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2"

    # input parameters
    parser = ArgumentParser(description='Script that creates combine datacards and corresponding RooFit workspaces',epilog=usage)

    parser.add_argument("--inputData", dest="inputData", required=True,
                        help="Input data spectrum",
                        metavar="INPUT_DATA")

    parser.add_argument("--dataHistname", dest="dataHistname", required=True,
                        help="Data histogram name",
                        metavar="DATA_HISTNAME")

    parser.add_argument("--inputSig", dest="inputSig", required=True,
                        help="Input signal shapes",
                        metavar="INPUT_SIGNAL")

    parser.add_argument("-f", "--final_state", dest="final_state", required=True,
                        help="Final state (e.g. qq, qg, gg)",
                        metavar="FINAL_STATE")

    parser.add_argument("-f2", "--type", dest="atype", required=True, help="Type (e.g. hG, lG, hR, lR)")

    parser.add_argument("-o", "--output_path", dest="output_path", required=True,
                        help="Output path where datacards and workspaces will be stored",
                        metavar="OUTPUT_PATH")

    parser.add_argument("-l", "--lumi", dest="lumi", required=True,
                        default=1000., type=float,
                        help="Integrated luminosity in pb-1 (default: %(default).1f)",
                        metavar="LUMI")

    parser.add_argument("--massMin", dest="massMin",
                        default=500, type=int,
                        help="Lower bound of the mass range used for fitting (default: %(default)s)",
                        metavar="MASS_MIN")

    parser.add_argument("--massMax", dest="massMax",
                        default=1200, type=int,
                        help="Upper bound of the mass range used for fitting (default: %(default)s)",
                        metavar="MASS_MAX")

    parser.add_argument("--p1", dest="p1",
                        default=5.0000e-03, type=float,
                        help="Fit function p1 parameter (default: %(default)e)",
                        metavar="P1")

    parser.add_argument("--p2", dest="p2",
                        default=9.1000e+00, type=float,
                        help="Fit function p2 parameter (default: %(default)e)",
                        metavar="P2")

    parser.add_argument("--p3", dest="p3",
                        default=5.0000e-01, type=float,
                        help="Fit function p3 parameter (default: %(default)e)",
                        metavar="P3")

    parser.add_argument("--lumiUnc", dest="lumiUnc",
                        required=True, type=float,
                        help="Relative uncertainty in the integrated luminosity",
                        metavar="LUMI_UNC")

    parser.add_argument("--jesUnc", dest="jesUnc",
                        type=float,
                        help="Relative uncertainty in the jet energy scale",
                        metavar="JES_UNC")

    parser.add_argument("--jerUnc", dest="jerUnc",
                        type=float,
                        help="Relative uncertainty in the jet energy resolution",
                        metavar="JER_UNC")

    parser.add_argument("--sqrtS", dest="sqrtS",
                        default=13000., type=float,
                        help="Collision center-of-mass energy (default: %(default).1f)",
                        metavar="SQRTS")

    parser.add_argument("--fixP3", dest="fixP3", default=False, action="store_true", help="Fix the fit function p3 parameter")

    parser.add_argument("--runFit", dest="runFit", default=False, action="store_true", help="Run the fit")

    parser.add_argument("--fitBonly", dest="fitBonly", default=False, action="store_true", help="Run B-only fit")

    parser.add_argument("--fixBkg", dest="fixBkg", default=False, action="store_true", help="Fix all background parameters")

    parser.add_argument("--decoBkg", dest="decoBkg", default=False, action="store_true", help="Decorrelate background parameters")

    parser.add_argument("--fitStrategy", dest="fitStrategy", type=int, default=1, help="Fit strategy (default: %(default).1f)")

    parser.add_argument("--debug", dest="debug", default=False, action="store_true", help="Debug printout")

    parser.add_argument("--postfix", dest="postfix", default='', help="Postfix for the output file names (default: %(default)s)")

    parser.add_argument("--pyes", dest="pyes", default=False, action="store_true", help="Make files for plots")

    parser.add_argument("--jyes", dest="jyes", default=False, action="store_true", help="Make files for JES/JER plots")

    parser.add_argument("--pdir", dest="pdir", default='testarea', help="Name a directory for the plots (default: %(default)s)")

    parser.add_argument("--chi2", dest="chi2", default=False, action="store_true", help="Compute chi squared")

    parser.add_argument("--widefit", dest="widefit", default=False, action="store_true", help="Fit with wide bin hist")

    mass_group = parser.add_mutually_exclusive_group(required=True)
    mass_group.add_argument("--mass",
                            type=int,
                            nargs = '*',
                            default = 1000,
                            help="Mass can be specified as a single value or a whitespace separated list (default: %(default)i)"
                            )
    mass_group.add_argument("--massrange",
                            type=int,
                            nargs = 3,
                            help="Define a range of masses to be produced. Format: min max step",
                            metavar = ('MIN', 'MAX', 'STEP')
                            )
    mass_group.add_argument("--masslist",
                            help = "List containing mass information"
                            )

    args = parser.parse_args()

    if args.atype == 'hG':
	fstr = "bbhGGBB"
	in2 = 'bcorrbin/binmodh.root'
    elif args.atype == 'hR':
	fstr = "bbhRS"
	in2 = 'bcorrbin/binmodh.root'
    elif args.atype == 'lG':
	fstr = "bblGGBB"
	in2 = 'bcorrbin/binmodl.root'
    else:
	fstr = "bblRS"
	in2 = 'bcorrbin/binmodl.root'

    # check if the output directory exists
    if not os.path.isdir( os.path.join(os.getcwd(),args.output_path) ):
        os.mkdir( os.path.join(os.getcwd(),args.output_path) )

    # mass points for which resonance shapes will be produced
    masses = []

    if args.massrange != None:
        MIN, MAX, STEP = args.massrange
        masses = range(MIN, MAX+STEP, STEP)
    elif args.masslist != None:
        # A mass list was provided
        print  "Will create mass list according to", args.masslist
        masslist = __import__(args.masslist.replace(".py",""))
        masses = masslist.masses
    else:
        masses = args.mass

    # sort masses
    masses.sort()

    # import ROOT stuff
    from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine
    from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf

    if not args.debug:
        RooMsgService.instance().setSilentMode(kTRUE)
        RooMsgService.instance().setStreamStatus(0,kFALSE)
        RooMsgService.instance().setStreamStatus(1,kFALSE)

    # input data file
    inputData = TFile(args.inputData)
    # input data histogram
    hData = inputData.Get(args.dataHistname)

    inData2 = TFile(in2)
    hData2 = inData2.Get('h_data')

    # input sig file
    inputSig = TFile(args.inputSig)

    sqrtS = args.sqrtS

    # mass variable
    mjj = RooRealVar('mjj','mjj',float(args.massMin),float(args.massMax))

    # integrated luminosity and signal cross section
    lumi = args.lumi
    signalCrossSection = 1. # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section

    for mass in masses:

        print ">> Creating datacard and workspace for %s resonance with m = %i GeV..."%(args.final_state, int(mass))

        # get signal shape
        hSig = inputSig.Get( "h_" + args.final_state + "_" + str(int(mass)) )
        # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity)
        hSig.Scale(signalCrossSection*lumi/hSig.Integral()) # divide by a number that provides roughly an r value of 1-10
        rooSigHist = RooDataHist('rooSigHist','rooSigHist',RooArgList(mjj),hSig)
        print 'Signal acceptance:', (rooSigHist.sumEntries()/hSig.Integral())
        signal = RooHistPdf('signal','signal',RooArgSet(mjj),rooSigHist)
        signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+05,1e+05)
        if args.fitBonly: signal_norm.setConstant()

        p1 = RooRealVar('p1','p1',args.p1,0.,100.)
        p2 = RooRealVar('p2','p2',args.p2,0.,60.)
        p3 = RooRealVar('p3','p3',args.p3,-10.,10.)
	p4 = RooRealVar('p4','p4',5.6,-50.,50.)
	p5 = RooRealVar('p5','p5',10.,-50.,50.)
	p6 = RooRealVar('p6','p6',.016,-50.,50.)
	p7 = RooRealVar('p7','p7',8.,-50.,50.)
	p8 = RooRealVar('p8','p8',.22,-50.,50.)
	p9 = RooRealVar('p9','p9',14.1,-50.,50.)
	p10 = RooRealVar('p10','p10',8.,-50.,50.)
	p11 = RooRealVar('p11','p11',4.8,-50.,50.)
	p12 = RooRealVar('p12','p12',7.,-50.,50.)
	p13 = RooRealVar('p13','p13',7.,-50.,50.)
	p14 = RooRealVar('p14','p14',7.,-50.,50.)
	p15 = RooRealVar('p15','p15',1.,-50.,50.)
	p16 = RooRealVar('p16','p16',9.,-50.,50.)
	p17 = RooRealVar('p17','p17',0.6,-50.,50.)

        if args.fixP3: p3.setConstant()

        background = RooGenericPdf('background','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(sqrtS,sqrtS,sqrtS),RooArgList(mjj,p1,p2,p3))
        dataInt = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm = RooRealVar('background_norm','background_norm',dataInt,0.,1e+08)

	background2 = RooGenericPdf('background2','(pow(@0/%.1f,-@1)*pow(1-@0/%.1f,@2))'%(sqrtS,sqrtS),RooArgList(mjj,p4,p5))
        dataInt2 = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm2 = RooRealVar('background_norm2','background_norm2',dataInt2,0.,1e+08)

	background3 = RooGenericPdf('background3','(1/pow(@1+@0/%.1f,@2))'%(sqrtS),RooArgList(mjj,p6,p7))
        dataInt3 = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm3 = RooRealVar('background_norm3','background_norm3',dataInt3,0.,1e+08)

	background4 = RooGenericPdf('background4','(1/pow(@1+@2*@0/%.1f+pow(@0/%.1f,2),@3))'%(sqrtS,sqrtS),RooArgList(mjj,p8,p9,p10))
        dataInt4 = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm4 = RooRealVar('background_norm4','background_norm4',dataInt4,0.,1e+08)

	background5 = RooGenericPdf('background5','(pow(@0/%.1f,-@1)*pow(1-pow(@0/%.1f,1/3),@2))'%(sqrtS,sqrtS),RooArgList(mjj,p11,p12))
        dataInt5 = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm5 = RooRealVar('background_norm5','background_norm5',dataInt5,0.,1e+08)

	background6 = RooGenericPdf('background6','(pow(@0/%.1f,2)+@1*@0/%.1f+@2)'%(sqrtS,sqrtS),RooArgList(mjj,p13,p14))
        dataInt6 = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm6 = RooRealVar('background_norm6','background_norm6',dataInt6,0.,1e+08)

	background7 = RooGenericPdf('background7','((-1+@1*@0/%.1f)*pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(sqrtS,sqrtS,sqrtS),RooArgList(mjj,p15,p16,p17))
        dataInt7 = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm7 = RooRealVar('background_norm7','background_norm7',dataInt7,0.,1e+08)

        # S+B model
        model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm))
	model2 = RooAddPdf("model2","s+b2",RooArgList(background2,signal),RooArgList(background_norm2,signal_norm))
	model3 = RooAddPdf("model3","s+b3",RooArgList(background3,signal),RooArgList(background_norm3,signal_norm))
	model4 = RooAddPdf("model4","s+b4",RooArgList(background4,signal),RooArgList(background_norm4,signal_norm))
	model5 = RooAddPdf("model5","s+b5",RooArgList(background5,signal),RooArgList(background_norm5,signal_norm))
	model6 = RooAddPdf("model6","s+b6",RooArgList(background6,signal),RooArgList(background_norm6,signal_norm))
	model7 = RooAddPdf("model7","s+b7",RooArgList(background7,signal),RooArgList(background_norm7,signal_norm))

        rooDataHist = RooDataHist('rooDatahist','rooDathist',RooArgList(mjj),hData)


        if args.runFit:
	    mframe = mjj.frame()
	    rooDataHist.plotOn(mframe, ROOT.RooFit.Name("setonedata"), ROOT.RooFit.Invisible())
	    res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
	    model.plotOn(mframe, ROOT.RooFit.Name("model1"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kRed)) 
	    res2 = model2.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            model2.plotOn(mframe, ROOT.RooFit.Name("model2"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kOrange))
	    res3 = model3.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            model3.plotOn(mframe, ROOT.RooFit.Name("model3"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
	    res4 = model4.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            model4.plotOn(mframe, ROOT.RooFit.Name("model4"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
	    res5 = model5.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            model5.plotOn(mframe, ROOT.RooFit.Name("model5"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kViolet))
	    res6 = model6.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
#           model6.plotOn(mframe, ROOT.RooFit.Name("model6"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kPink))
	    res7 = model7.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
#           model7.plotOn(mframe, ROOT.RooFit.Name("model7"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kAzure))

	    rooDataHist2 = RooDataHist('rooDatahist2','rooDathist2',RooArgList(mjj),hData2)
	    rooDataHist2.plotOn(mframe, ROOT.RooFit.Name("data"))

	    canvas = TCanvas("cdouble", "cdouble", 800, 1000)

	    gStyle.SetOptStat(0);
            gStyle.SetOptTitle(0);
	    top = TPad("top", "top", 0., 0.5, 1., 1.)
	    top.SetBottomMargin(0.03)
	    top.Draw()
	    top.SetLogy()
            bottom = TPad("bottom", "bottom", 0., 0., 1., 0.5)
	    bottom.SetTopMargin(0.02)
	    bottom.SetBottomMargin(0.2)
	    bottom.Draw()

	    top.cd()
	    frame_top = TH1D("frame_top", "frame_top", 100, 526, 1500)
	    frame_top.GetXaxis().SetTitleSize(0)
	    frame_top.GetXaxis().SetLabelSize(0)
	    frame_top.GetYaxis().SetLabelSize(0.04)
            frame_top.GetYaxis().SetTitleSize(0.04)
            frame_top.GetYaxis().SetTitle("Events")
	    frame_top.SetMaximum(1000.)
	    frame_top.SetMinimum(0.1)
	    frame_top.Draw("axis")
            mframe.Draw("p e1 same")

            bottom.cd()
	    frame_bottom = TH1D("frame_bottom", "frame_bottom", 100, 526, 1500)
            frame_bottom.GetXaxis().SetTitle("m_{jj} [GeV]")
	    frame_bottom.GetYaxis().SetTitle("Pull")

  	    frame_bottom.GetXaxis().SetLabelSize(0.04)
	    frame_bottom.GetXaxis().SetTitleSize(0.06)
	    frame_bottom.GetXaxis().SetLabelOffset(0.01)
	    frame_bottom.GetXaxis().SetTitleOffset(1.1)

	    frame_bottom.GetYaxis().SetLabelSize(0.04)
	    frame_bottom.GetYaxis().SetTitleSize(0.04)
	    frame_bottom.GetYaxis().SetTitleOffset(0.85)

	    frame_bottom.SetMaximum(4.)
            frame_bottom.SetMinimum(-3.)

	    frame_bottom.Draw("axis")

	    zero = TLine(526., 0., 1500., 0.)
	    zero.SetLineColor(ROOT.EColor.kBlack)
	    zero.SetLineStyle(1)
	    zero.SetLineWidth(2)
	    zero.Draw("same")

	    # Ratio histogram with no errors (not so well defined, since this isn't a well-defined efficiency)
	    newHist = mframe.getHist("data")
	    curve = mframe.getObject(1)
	    hresid = newHist.makePullHist(curve,kTRUE)
	    resframe = mjj.frame()
	    mframe.SetAxisRange(526.,1500.)
	    resframe.addPlotable(hresid,"B X")
	    resframe.Draw("same")
	    canvas.cd()
	    canvas.SaveAs("testdouble.pdf")
		

	    if args.pyes:
	    	c = TCanvas("c","c",800,800)
		mframe.SetAxisRange(300.,1300.)
	    	c.SetLogy()
#	    	mframe.SetMaximum(10)
#	    	mframe.SetMinimum(1)
	    	mframe.Draw()
	    	fitname = args.pdir+'/5funcfit_m'+str(mass)+fstr+'.pdf'
	    	c.SaveAs(fitname)

	        cpull = TCanvas("cpull","cpull",800,800)
	    	pulls = mframe.pullHist("data","model3")
	    	pulls.Draw("ABX")
	   	pullname = args.pdir+'/pull_m'+str(mass)+fstr+'.pdf'
	    	cpull.SaveAs(pullname)

		cpull2 = TCanvas("cpull2","cpull2",800,800)
                pulls2 = mframe.pullHist("setonedata","model1")
                pulls2.Draw("ABX")
                pull2name = args.pdir+'/pull2_m'+str(mass)+fstr+'.pdf'
                cpull2.SaveAs(pull2name)

	    if args.widefit:	
		mframew = mjj.frame()
    	        rooDataHist2.plotOn(mframew, ROOT.RooFit.Name("data"))
                res6 = model.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            	model.plotOn(mframew, ROOT.RooFit.Name("model1"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kRed))
            	res7 = model2.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            	model2.plotOn(mframew, ROOT.RooFit.Name("model2"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kOrange))
            	res8 = model3.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            	model3.plotOn(mframew, ROOT.RooFit.Name("model3"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
            	res9 = model4.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            	model4.plotOn(mframew, ROOT.RooFit.Name("model4"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
            	res10 = model5.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            	model5.plotOn(mframew, ROOT.RooFit.Name("model5"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kViolet))

                if args.pyes:
                    c = TCanvas("c","c",800,800)
                    mframew.SetAxisRange(300.,1300.)
                    c.SetLogy()
#                   mframew.SetMaximum(10)
#                   mframew.SetMinimum(1)
                    mframew.Draw()
                    fitname = args.pdir+'/5funcfittowide_m'+str(mass)+fstr+'.pdf'
		    c.SaveAs(fitname)

                    cpull = TCanvas("cpull","cpull",800,800)
                    pulls = mframew.pullHist("data","model1")
                    pulls.Draw("ABX")
                    pullname = args.pdir+'/pullwidefit_m'+str(mass)+fstr+'.pdf'
                    cpull.SaveAs(pullname)


	    if args.chi2:
		    fullInt = model.createIntegral(RooArgSet(mjj))
		    norm = dataInt/fullInt.getVal()
		    chi1 = 0.
		    fullInt2 = model2.createIntegral(RooArgSet(mjj))
        	    norm2 = dataInt2/fullInt2.getVal()
	      	    chi2 = 0.
		    fullInt3 = model3.createIntegral(RooArgSet(mjj))
       		    norm3 = dataInt3/fullInt3.getVal()
	            chi3 = 0.
		    fullInt4 = model4.createIntegral(RooArgSet(mjj))
       		    norm4 = dataInt4/fullInt4.getVal()
         	    chi4 = 0.
		    fullInt5 = model5.createIntegral(RooArgSet(mjj))
	            norm5 = dataInt5/fullInt5.getVal()
     	            chi5 = 0.
		    for i in range(args.massMin, args.massMax):
        	        new = 0
			new2 = 0
			new3 = 0
			new4 = 0
			new5 = 0
			height = hData.GetBinContent(i)
	        	xLow = hData.GetXaxis().GetBinLowEdge(i)
			xUp = hData.GetXaxis().GetBinLowEdge(i+1)
			obs = height*(xUp-xLow)
			mjj.setRange("intrange",xLow,xUp)
			integ = model.createIntegral(RooArgSet(mjj),ROOT.RooFit.NormSet(RooArgSet(mjj)),ROOT.RooFit.Range("intrange"))
			exp = integ.getVal()*norm
			new = pow(exp-obs,2)/exp
                	chi1 = chi1 + new
			integ2 = model2.createIntegral(RooArgSet(mjj),ROOT.RooFit.NormSet(RooArgSet(mjj)),ROOT.RooFit.Range("intrange"))
                	exp2 = integ2.getVal()*norm2
                	new2 = pow(exp2-obs,2)/exp2
                	chi2 = chi2 + new2
			integ3 = model3.createIntegral(RooArgSet(mjj),ROOT.RooFit.NormSet(RooArgSet(mjj)),ROOT.RooFit.Range("intrange"))
                	exp3 = integ3.getVal()*norm3
                	new3 = pow(exp3-obs,2)/exp3
                	chi3 = chi3 + new3
			integ4 = model4.createIntegral(RooArgSet(mjj),ROOT.RooFit.NormSet(RooArgSet(mjj)),ROOT.RooFit.Range("intrange"))
                	exp4 = integ4.getVal()*norm4
			if exp4 != 0:
                	    new4 = pow(exp4-obs,2)/exp4
                	else:
			    new4 = 0
			chi4 = chi4 + new4
			integ5 = model5.createIntegral(RooArgSet(mjj),ROOT.RooFit.NormSet(RooArgSet(mjj)),ROOT.RooFit.Range("intrange"))
                	exp5 = integ5.getVal()*norm5
                	new5 = pow(exp5-obs,2)/exp5
                	chi5 = chi5 + new5
	    	    print "chi1 %d "%(chi1)
	    	    print "chi2 %d "%(chi2)
	    	    print "chi3 %d "%(chi3)
	    	    print "chi4 %d "%(chi4)
	    	    print "chi5 %d "%(chi5)

	    if not args.decoBkg: 
		print " "
		res.Print()
#	        res2.Print()
#		res3.Print()
#		res4.Print()
#		res5.Print()
#		res6.Print()
#		res7.Print()

            # decorrelated background parameters for Bayesian limits
            if args.decoBkg:
                signal_norm.setConstant()
                res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
                res.Print()
                ## temp workspace for the PDF diagonalizer
                w_tmp = RooWorkspace("w_tmp")
                deco = PdfDiagonalizer("deco",w_tmp,res)
                # here diagonalizing only the shape parameters since the overall normalization is already decorrelated
                background_deco = deco.diagonalize(background)
                print "##################### workspace for decorrelation"
                w_tmp.Print("v")
                print "##################### original parameters"
                background.getParameters(rooDataHist).Print("v")
                print "##################### decorrelated parameters"
                # needed if want to evaluate limits without background systematics
                if args.fixBkg:
                    w_tmp.var("deco_eig1").setConstant()
                    w_tmp.var("deco_eig2").setConstant()
                    if not args.fixP3: w_tmp.var("deco_eig3").setConstant()
                background_deco.getParameters(rooDataHist).Print("v")
                print "##################### original pdf"
                background.Print()
                print "##################### decorrelated pdf"
                background_deco.Print()
                # release signal normalization
                signal_norm.setConstant(kFALSE)
                # set the background normalization range to +/- 5 sigma
                bkg_val = background_norm.getVal()
                bkg_error = background_norm.getError()
                background_norm.setMin(bkg_val-5*bkg_error)
                background_norm.setMax(bkg_val+5*bkg_error)
                background_norm.Print()
                # change background PDF names
                background.SetName("background_old")
                background_deco.SetName("background")

        # needed if want to evaluate limits without background systematics
        if args.fixBkg:
            background_norm.setConstant()
            p1.setConstant()
            p2.setConstant()
            p3.setConstant()

        # -----------------------------------------
        # dictionaries holding systematic variations of the signal shape
        hSig_Syst = {}
        hSig_Syst_DataHist = {}
        sigCDF = TGraph(hSig.GetNbinsX()+1)

        # JES and JER uncertainties
        if args.jesUnc != None or args.jerUnc != None:

            sigCDF.SetPoint(0,0.,0.)
            integral = 0.
            for i in range(1, hSig.GetNbinsX()+1):
                x = hSig.GetXaxis().GetBinLowEdge(i+1)
                integral = integral + hSig.GetBinContent(i)
                sigCDF.SetPoint(i,x,integral)

        if args.jesUnc != None:
            hSig_Syst['JESUp'] = copy.deepcopy(hSig)
            hSig_Syst['JESDown'] = copy.deepcopy(hSig)

        if args.jerUnc != None:
            hSig_Syst['JERUp'] = copy.deepcopy(hSig)
            hSig_Syst['JERDown'] = copy.deepcopy(hSig)

        # reset signal histograms
        for key in hSig_Syst.keys():
            hSig_Syst[key].Reset()
            hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key)

        # produce JES signal shapes
        if args.jesUnc != None:
            for i in range(1, hSig.GetNbinsX()+1):
                xLow = hSig.GetXaxis().GetBinLowEdge(i)
                xUp = hSig.GetXaxis().GetBinLowEdge(i+1)
                jes = 1. - args.jesUnc
                xLowPrime = jes*xLow
                xUpPrime = jes*xUp
                hSig_Syst['JESUp'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                jes = 1. + args.jesUnc
                xLowPrime = jes*xLow
                xUpPrime = jes*xUp
                hSig_Syst['JESDown'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
            hSig_Syst_DataHist['JESUp'] = RooDataHist('hSig_JESUp','hSig_JESUp',RooArgList(mjj),hSig_Syst['JESUp'])
            hSig_Syst_DataHist['JESDown'] = RooDataHist('hSig_JESDown','hSig_JESDown',RooArgList(mjj),hSig_Syst['JESDown'])
	    
	    if args.jyes:
		c2 = TCanvas("c2","c2",800,800)
	    	mframe2 = mjj.frame(ROOT.RooFit.Title("JES One Sigma Shifts"))
	    	mframe2.SetAxisRange(525.,1200.)
		hSig_Syst_DataHist['JESUp'].plotOn(mframe2, ROOT.RooFit.Name("JESUP"),ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kRed), ROOT.RooFit.LineColor(ROOT.EColor.kRed))
	    	hSig_Syst_DataHist['JESDown'].plotOn(mframe2,ROOT.RooFit.Name("JESDOWN"),ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue), ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
	    	rooSigHist.plotOn(mframe2, ROOT.RooFit.DataError(2),ROOT.RooFit.Name("SIG"),ROOT.RooFit.DrawOption("L"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen), ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
	    	mframe2.Draw()
		mframe2.GetXaxis().SetTitle("Dijet Mass (GeV)")
		leg = TLegend(0.7,0.8,0.9,0.9)
		leg.AddEntry(mframe2.findObject("SIG"),"Signal Model","l")
		leg.AddEntry(mframe2.findObject("JESUP"),"+1 Sigma","l")
		leg.AddEntry(mframe2.findObject("JESDOWN"),"-1 Sigma","l")
		leg.Draw()
	    	jesname = args.pdir+'/jes_m'+str(mass)+fstr+'.pdf'
	    	c2.SaveAs(jesname)

        # produce JER signal shapes
        if args.jesUnc != None:
            for i in range(1, hSig.GetNbinsX()+1):
                xLow = hSig.GetXaxis().GetBinLowEdge(i)
                xUp = hSig.GetXaxis().GetBinLowEdge(i+1)
                jer = 1. - args.jerUnc
                xLowPrime = jer*(xLow-float(mass))+float(mass)
                xUpPrime = jer*(xUp-float(mass))+float(mass)
                hSig_Syst['JERUp'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                jer = 1. + args.jerUnc
                xLowPrime = jer*(xLow-float(mass))+float(mass)
                xUpPrime = jer*(xUp-float(mass))+float(mass)
                hSig_Syst['JERDown'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
            hSig_Syst_DataHist['JERUp'] = RooDataHist('hSig_JERUp','hSig_JERUp',RooArgList(mjj),hSig_Syst['JERUp'])
            hSig_Syst_DataHist['JERDown'] = RooDataHist('hSig_JERDown','hSig_JERDown',RooArgList(mjj),hSig_Syst['JERDown'])

	    if args.jyes:
	    	c3 = TCanvas("c3","c3",800,800)
            	mframe3 = mjj.frame(ROOT.RooFit.Title("JER One Sigma Shifts"))
	    	mframe3.SetAxisRange(525.,1200.)
		hSig_Syst_DataHist['JERUp'].plotOn(mframe3,ROOT.RooFit.Name("JERUP"),ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kRed), ROOT.RooFit.LineColor(ROOT.EColor.kRed))
            	hSig_Syst_DataHist['JERDown'].plotOn(mframe3,ROOT.RooFit.Name("JERDOWN"),ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue), ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
            	rooSigHist.plotOn(mframe3,ROOT.RooFit.DrawOption("L"),ROOT.RooFit.Name("SIG"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen), ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
            	mframe3.Draw()
	    	mframe3.GetXaxis().SetTitle("Dijet Mass (GeV)")
		leg = TLegend(0.7,0.8,0.9,0.9)
                leg.AddEntry(mframe3.findObject("SIG"),"Signal Model","l")
                leg.AddEntry(mframe3.findObject("JERUP"),"+1 Sigma","l")
                leg.AddEntry(mframe3.findObject("JERDOWN"),"-1 Sigma","l")
                leg.Draw()	
		jername = args.pdir+'/jer_m'+str(mass)+fstr+'.pdf'
           	c3.SaveAs(jername)


        # -----------------------------------------
        # create a datacard and corresponding workspace
        postfix = (('_' + args.postfix) if args.postfix != '' else '')
        dcName = 'datacard_' + args.final_state + '_m' + str(mass) + postfix + '.txt'
        wsName = 'workspace_' + args.final_state + '_m' + str(mass) + postfix + '.root'

        w = RooWorkspace('w','workspace')
        getattr(w,'import')(rooSigHist,RooFit.Rename("signal"))
        if args.jesUnc != None:
            getattr(w,'import')(hSig_Syst_DataHist['JESUp'],RooFit.Rename("signal__JESUp"))
            getattr(w,'import')(hSig_Syst_DataHist['JESDown'],RooFit.Rename("signal__JESDown"))
        if args.jerUnc != None:
            getattr(w,'import')(hSig_Syst_DataHist['JERUp'],RooFit.Rename("signal__JERUp"))
            getattr(w,'import')(hSig_Syst_DataHist['JERDown'],RooFit.Rename("signal__JERDown"))
        if args.decoBkg:
            getattr(w,'import')(background_deco,ROOT.RooCmdArg())
        else:
            getattr(w,'import')(background,ROOT.RooCmdArg(),RooFit.Rename("background"))

	#if use different fits for shape uncertainties
	#getattr(w,'import')(,ROOT.RooCmdArg(),RooFit.Rename("background__bkgUp"))
	#getattr(w,'import')(,ROOT.RooCmdArg(),RooFit.Rename("background__bkgDown"))
	
	getattr(w,'import')(background_norm,ROOT.RooCmdArg())
        getattr(w,'import')(rooDataHist,RooFit.Rename("data_obs"))
        w.Print()
        w.writeToFile(os.path.join(args.output_path,wsName))

	beffUnc = 0.3
	boffUnc = 0.06

        datacard = open(os.path.join(args.output_path,dcName),'w')
        datacard.write('imax 1\n')
        datacard.write('jmax 1\n')
        datacard.write('kmax *\n')
        datacard.write('---------------\n')
        if args.jesUnc != None or args.jerUnc != None:
            datacard.write('shapes * * '+wsName+' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
        else:
            datacard.write('shapes * * '+wsName+' w:$PROCESS\n')
        datacard.write('---------------\n')
        datacard.write('bin 1\n')
        datacard.write('observation -1\n')
        datacard.write('------------------------------\n')
        datacard.write('bin          1          1\n')
        datacard.write('process      signal     background\n')
        datacard.write('process      0          1\n')
        datacard.write('rate         -1         1\n')
        datacard.write('------------------------------\n')
        datacard.write('lumi  lnN    %f         -\n'%(1.+args.lumiUnc))
	datacard.write('beff  lnN    %f         -\n'%(1.+beffUnc))
	datacard.write('boff  lnN    %f         -\n'%(1.+boffUnc))
	datacard.write('bkg   lnN     -         1.03\n')
        if args.jesUnc != None:
            datacard.write('JES  shape   1          -\n')
        if args.jerUnc != None:
            datacard.write('JER  shape   1          -\n')
        # flat parameters --- flat prior
        datacard.write('background_norm  flatParam\n')
        if args.decoBkg:
            datacard.write('deco_eig1  flatParam\n')
            datacard.write('deco_eig2  flatParam\n')
            if not args.fixP3: datacard.write('deco_eig3  flatParam\n')
        else:
            datacard.write('p1  flatParam\n')
            datacard.write('p2  flatParam\n')
            if not args.fixP3: datacard.write('p3  flatParam\n')
        datacard.close()


    print '>> Datacards and workspaces created and stored in %s/'%( os.path.join(os.getcwd(),args.output_path) )
Ejemplo n.º 10
0
def main():
    # usage description
    usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2"

    # input parameters
    parser = ArgumentParser(description='Script that creates combine datacards and corresponding RooFit workspaces',epilog=usage)
    parser.add_argument("analysis", type=str, help="Analysis name")
    parser.add_argument("model", type=str, help="Model (Hbb, RSG)")

    #parser.add_argument("--inputData", dest="inputData", required=True,
    #                    help="Input data spectrum",
    #                    metavar="INPUT_DATA")

    parser.add_argument("--dataHistname", dest="dataHistname", type=str, default="h_data",
                        help="Data histogram name",
                        metavar="DATA_HISTNAME")

    #parser.add_argument("--inputSig", dest="inputSig", required=True,
    #                    help="Input signal shapes",
    #                    metavar="INPUT_SIGNAL")

    parser.add_argument("-f", "--final_state", dest="final_state", default="qq",
                        help="Final state (e.g. qq, qg, gg)",
                        metavar="FINAL_STATE")
    parser.add_argument("--fit_functions", dest="fit_functions", default="f1,f2,f3,f4,f5", help="List of fit functions")

    #parser.add_argument("-f2", "--type", dest="atype", required=True, help="Type (e.g. hG, lG, hR, lR)")

    parser.add_argument("-o", "--output_path", dest="output_path",
                        help="Output path where datacards and workspaces will be stored. If not specified, this is derived from limit_configuration.",
                        metavar="OUTPUT_PATH")

    parser.add_argument("--correctTrigger", dest="correctTrigger",
                        action='store_true',
                        help="Include trigger correction in PDF")

    parser.add_argument("-l", "--lumi", dest="lumi",
                        default=19700., type=float,
                        help="Integrated luminosity in pb-1 (default: %(default).1f)",
                        metavar="LUMI")

    parser.add_argument("--massMin", dest="massMin",
                        default=500, type=int,
                        help="Lower bound of the mass range used for fitting (default: %(default)s)",
                        metavar="MASS_MIN")

    parser.add_argument("--massMax", dest="massMax",
                        default=1200, type=int,
                        help="Upper bound of the mass range used for fitting (default: %(default)s)",
                        metavar="MASS_MAX")
    parser.add_argument("--fitSignal", action="store_true", help="Use signal fitted shapes (CB+Voigtian) instead of histogram templates")
    #parser.add_argument("--lumiUnc", dest="lumiUnc",
    #                    required=True, type=float,
    #                    help="Relative uncertainty in the integrated luminosity",
    #                    metavar="LUMI_UNC")

    #parser.add_argument("--jesUnc", dest="jesUnc",
    #                    type=float,
    #                    help="Relative uncertainty in the jet energy scale",
    #                    metavar="JES_UNC")

    #parser.add_argument("--jerUnc", dest="jerUnc",
    #                    type=float,
    #                    help="Relative uncertainty in the jet energy resolution",
    #                    metavar="JER_UNC")

    parser.add_argument("--sqrtS", dest="sqrtS",
                        default=8000., type=float,
                        help="Collision center-of-mass energy (default: %(default).1f)",
                        metavar="SQRTS")

    parser.add_argument("--fixP3", dest="fixP3", default=False, action="store_true", help="Fix the fit function p3 parameter")

    parser.add_argument("--runFit", dest="runFit", default=False, action="store_true", help="Run the fit")

    parser.add_argument("--fitBonly", dest="fitBonly", default=False, action="store_true", help="Run B-only fit")

    parser.add_argument("--fixBkg", dest="fixBkg", default=False, action="store_true", help="Fix all background parameters")

    parser.add_argument("--decoBkg", dest="decoBkg", default=False, action="store_true", help="Decorrelate background parameters")

    parser.add_argument("--fitStrategy", dest="fitStrategy", type=int, default=1, help="Fit strategy (default: %(default).1f)")

    parser.add_argument("--debug", dest="debug", default=False, action="store_true", help="Debug printout")

    parser.add_argument("--postfix", dest="postfix", default='', help="Postfix for the output file names (default: %(default)s)")

    parser.add_argument("--pyes", dest="pyes", default=False, action="store_true", help="Make files for plots")

    parser.add_argument("--jyes", dest="jyes", default=False, action="store_true", help="Make files for JES/JER plots")

    parser.add_argument("--pdir", dest="pdir", default='testarea', help="Name a directory for the plots (default: %(default)s)")

    parser.add_argument("--chi2", dest="chi2", default=False, action="store_true", help="Compute chi squared")

    parser.add_argument("--widefit", dest="widefit", default=False, action="store_true", help="Fit with wide bin hist")

    mass_group = parser.add_mutually_exclusive_group(required=True)
    mass_group.add_argument("--mass",
                            type=int,
                            nargs = '*',
                            default = 1000,
                            help="Mass can be specified as a single value or a whitespace separated list (default: %(default)i)"
                            )
    mass_group.add_argument("--massrange",
                            type=int,
                            nargs = 3,
                            help="Define a range of masses to be produced. Format: min max step",
                            metavar = ('MIN', 'MAX', 'STEP')
                            )
    mass_group.add_argument("--masslist",
                            help = "List containing mass information"
                            )

    args = parser.parse_args()

    fit_functions = args.fit_functions.split(",")

    # mass points for which resonance shapes will be produced
    masses = []

    if args.fitBonly:
        masses.append(750)
    else:
        if args.massrange != None:
            MIN, MAX, STEP = args.massrange
            masses = range(MIN, MAX+STEP, STEP)
        elif args.masslist != None:
            # A mass list was provided
            print  "Will create mass list according to", args.masslist
            masslist = __import__(args.masslist.replace(".py",""))
            masses = masslist.masses
        else:
            masses = args.mass

    # sort masses
    masses.sort()

    # import ROOT stuff
    from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine
    from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooProdPdf, RooEffProd, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf, RooExtendPdf

    if not args.debug:
        RooMsgService.instance().setSilentMode(kTRUE)
        RooMsgService.instance().setStreamStatus(0,kFALSE)
        RooMsgService.instance().setStreamStatus(1,kFALSE)

    # input data file
    #inputData = TFile(limit_config.get_data_input(args.analysis))
    # input data histogram
    #hData = inputData.Get(args.dataHistname)
    #hData.SetDirectory(0)
    data_file = TFile(analysis_config.get_b_histogram_filename(args.analysis, "BJetPlusX_2012"))
    hData = data_file.Get("BHistograms/h_pfjet_mjj")
    hData.SetDirectory(0)

    # input sig file
    if not args.fitSignal:
        print "[create_datacards] INFO : Opening resonance shapes file at " + limit_config.get_resonance_shapes(args.analysis, args.model)
        inputSig = TFile(limit_config.get_resonance_shapes(args.analysis, args.model), "READ")

    sqrtS = args.sqrtS

    # mass variable
    mjj = RooRealVar('mjj','mjj',float(args.massMin),float(args.massMax))

    # integrated luminosity and signal cross section
    lumi = args.lumi
    signalCrossSection = 1. # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section

    if args.correctTrigger:
        trigger_efficiency_pdf = trigger_efficiency.get_pdf(args.analysis, mjj)
        trigger_efficiency_formula = trigger_efficiency.get_formula(args.analysis, mjj)
    else:
        trigger_efficiency_pdf = trigger_efficiency.get_trivial_pdf(mjj)
        trigger_efficiency_formula = trigger_efficiency.get_trivial_formula(mjj)

    for mass in masses:

        print ">> Creating datacard and workspace for %s resonance with m = %i GeV..."%(args.final_state, int(mass))
        
        rooDataHist = RooDataHist('rooDatahist','rooDathist',RooArgList(mjj),hData)

        if not args.fitSignal:
            hSig = inputSig.Get( "h_" + args.final_state + "_" + str(int(mass)) )
            if not hSig:
                raise Exception("Couldn't find histogram " + "h_" + args.final_state + "_" + str(int(mass)) + " in file " + limit_config.get_resonance_shapes(args.analysis, args.model))
            # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity)
            hSig.Scale(signalCrossSection*lumi/hSig.Integral()) # divide by a number that provides roughly an r value of 1-10
            rooSigHist = RooDataHist('rooSigHist','rooSigHist',RooArgList(mjj),hSig)
            print 'Signal acceptance:', (rooSigHist.sumEntries()/hSig.Integral())

        # If using fitted signal shapes, load the signal PDF
        if args.fitSignal:
            print "[create_datacards] Loading fitted signal PDFs from " + analysis_config.get_signal_fit_file(args.analysis, args.model, mass, "bukin", interpolated=(not mass in analysis_config.simulation.simulated_masses))
            f_signal_pdfs = TFile(analysis_config.get_signal_fit_file(args.analysis, args.model, mass, "bukin", interpolated=(not mass in analysis_config.simulation.simulated_masses)), "READ")
            w_signal = f_signal_pdfs.Get("w_signal")
            input_parameters = signal_fits.get_parameters(w_signal.pdf("signal"))

            # Make a new PDF with nuisance parameters
            signal_pdf_notrig, signal_vars = signal_fits.make_signal_pdf_systematic("bukin", mjj, mass=mass)
            signal_pdf_name = signal_pdf_notrig.GetName()
            signal_pdf_notrig.SetName(signal_pdf_name + "_notrig")
            #signal_pdf = RooProdPdf(signal_pdf_name, signal_pdf_name, signal_pdf_notrig, trigger_efficiency_pdf) 
            signal_pdf = RooEffProd(signal_pdf_name, signal_pdf_name, signal_pdf_notrig, trigger_efficiency_formula)

            # Copy input parameter values
            signal_vars["xp_0"].setVal(input_parameters["xp"][0])
            signal_vars["xp_0"].setError(input_parameters["xp"][1])
            signal_vars["xp_0"].setConstant()
            signal_vars["sigp_0"].setVal(input_parameters["sigp"][0])
            signal_vars["sigp_0"].setError(input_parameters["sigp"][1])
            signal_vars["sigp_0"].setConstant()
            signal_vars["xi_0"].setVal(input_parameters["xi"][0])
            signal_vars["xi_0"].setError(input_parameters["xi"][1])
            signal_vars["xi_0"].setConstant()
            signal_vars["rho1_0"].setVal(input_parameters["rho1"][0])
            signal_vars["rho1_0"].setError(input_parameters["rho1"][1])
            signal_vars["rho1_0"].setConstant()
            signal_vars["rho2_0"].setVal(input_parameters["rho2"][0])
            signal_vars["rho2_0"].setError(input_parameters["rho2"][1])
            signal_vars["rho2_0"].setConstant()
            f_signal_pdfs.Close()

        signal_parameters = {}
        signal_pdfs_notrig = {}
        signal_pdfs = {}
        signal_norms = {}
        background_pdfs = {}
        background_pdfs_notrig = {}
        background_parameters = {}
        background_norms = {}
        signal_epdfs = {}
        background_epdfs = {}
        models = {}
        fit_results = {}

        for fit_function in fit_functions:
            print "[create_datacards] INFO : On fit function {}".format(fit_function)

            if args.fitSignal:
                # Make a copy of the signal PDF, so that each fitTo call uses its own copy.
                # The copy should have all variables set constant.  
                #signal_pdfs[fit_function], signal_parameters[fit_function] = signal_fits.copy_signal_pdf("bukin", signal_pdf, mjj, tag=fit_function, include_systematics=True)
                signal_pdfs_notrig[fit_function] = ROOT.RooBukinPdf(signal_pdf_notrig, signal_pdf_notrig.GetName() + "_" + fit_function)
                signal_pdfs[fit_function] = RooEffProd(signal_pdf.GetName() + "_" + fit_function, signal_pdf.GetName() + "_" + fit_function, signal_pdfs_notrig[fit_function], trigger_efficiency_formula) 
                #signal_pdfs[fit_function] = RooProdPdf(signal_pdf.GetName() + "_" + fit_function, signal_pdf.GetName() + "_" + fit_function, signal_pdfs_notrig[fit_function], trigger_efficiency_pdf) 
                iterator = signal_pdfs_notrig[fit_function].getVariables().createIterator()
                this_parameter = iterator.Next()
                while this_parameter:
                    this_parameter.setConstant()
                    this_parameter = iterator.Next()
            else:
                signal_pdfs[fit_function] = RooHistPdf('signal_' + fit_function,'signal_' + fit_function, RooArgSet(mjj), rooSigHist)
            signal_norms[fit_function] = RooRealVar('signal_norm_' + fit_function, 'signal_norm_' + fit_function, 0., 0., 1e+05)
            if args.fitBonly: 
                signal_norms[fit_function].setConstant()
            background_pdfs_notrig[fit_function], background_parameters[fit_function] = make_background_pdf(fit_function, mjj, collision_energy=8000.)
            background_pdf_name = background_pdfs_notrig[fit_function].GetName()
            background_pdfs_notrig[fit_function].SetName(background_pdf_name + "_notrig")
            background_pdfs[fit_function] = RooEffProd(background_pdf_name, background_pdf_name, background_pdfs_notrig[fit_function], trigger_efficiency_formula)
            #background_pdfs[fit_function] = RooProdPdf(background_pdf_name, background_pdf_name, background_pdfs_notrig[fit_function], trigger_efficiency_pdf)
            #background_pdfs[fit_function] = background_pdfs_notrig[fit_function]
            #background_pdfs[fit_function].SetName(background_pdf_name)
            
            # Initial values
            if "trigbbh" in args.analysis:
                if fit_function == "f3":
                    background_parameters[fit_function]["p1"].setVal(55.)
                    background_parameters[fit_function]["p1"].setMin(20.)
                    background_parameters[fit_function]["p2"].setVal(8.)
                elif fit_function == "f4":
                    background_parameters[fit_function]["p1"].setVal(28.)
                    background_parameters[fit_function]["p2"].setVal(-22.)
                    background_parameters[fit_function]["p3"].setVal(10.)
            elif "trigbbl" in args.analysis:
                if fit_function == "f3":
                    background_parameters[fit_function]["p1"].setVal(82.)
                    background_parameters[fit_function]["p1"].setMin(60.)
                    background_parameters[fit_function]["p2"].setVal(8.)
                elif fit_function == "f4":
                    background_parameters[fit_function]["p1"].setVal(41.)
                    background_parameters[fit_function]["p2"].setVal(-45.)
                    background_parameters[fit_function]["p3"].setVal(10.)

            data_integral = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),hData.GetXaxis().FindBin(float(args.massMax)))
            background_norms[fit_function] = RooRealVar('background_' + fit_function + '_norm', 'background_' + fit_function + '_norm', data_integral, 0., 1.e8)

            signal_epdfs[fit_function] = RooExtendPdf('esignal_' + fit_function, 'esignal_' + fit_function, signal_pdfs[fit_function], signal_norms[fit_function])
            background_epdfs[fit_function] = RooExtendPdf('ebackground_' + fit_function, 'ebackground_' + fit_function, background_pdfs[fit_function], background_norms[fit_function])

            models[fit_function] = RooAddPdf('model_' + fit_function, 's+b', RooArgList(background_epdfs[fit_function], signal_epdfs[fit_function]))

            if args.runFit:
                print "[create_datacards] INFO : Starting fit with function {}".format(fit_function)
                fit_results[fit_function] = models[fit_function].fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE), RooFit.Strategy(args.fitStrategy), RooFit.Verbose(0))
                print "[create_datacards] INFO : Done with fit {}. Printing results.".format(fit_function)
                fit_results[fit_function].Print()
                print "[create_datacards] DEBUG : End args.runFit if block."

            # needed if want to evaluate limits without background systematics
            if args.fixBkg:
                background_norms[fit_function].setConstant()
                for par_name, par in background_parameters[fit_function].iteritems():
                    par.setConstant()

        # -----------------------------------------
        #signal_pdfs_syst = {}
        # JES and JER uncertainties
        if args.fitSignal:
            print "[create_datacards] INFO : Getting signal PDFs from " + analysis_config.get_signal_fit_file(args.analysis, args.model, mass, "bukin", interpolated=(not mass in analysis_config.simulation.simulated_masses))
            f_signal_pdfs = TFile(analysis_config.get_signal_fit_file(args.analysis, args.model, mass, "bukin", interpolated=(not mass in analysis_config.simulation.simulated_masses)))
            w_signal = f_signal_pdfs.Get("w_signal")
            if "jes" in systematics:
                xp_central = signal_vars["xp_0"].getVal()
                #print w_signal.pdf("signal__JESUp")
                #print signal_fits.get_parameters(w_signal.pdf("signal__JESUp"))
                xp_up = signal_fits.get_parameters(w_signal.pdf("signal__JESUp"))["xpJESUp"][0]
                xp_down = signal_fits.get_parameters(w_signal.pdf("signal__JESDown"))["xpJESDown"][0]
                signal_vars["dxp"].setVal(max(abs(xp_up - xp_central), abs(xp_down - xp_central)))
                if signal_vars["dxp"].getVal() > 2 * mass * 0.1:
                    print "[create_datacards] WARNING : Large dxp value. dxp = {}, xp_down = {}, xp_central = {}, xp_up = {}".format(signal_vars["dxp"].getVal(), xp_down, xp_central, xp_up)
                signal_vars["alpha_jes"].setVal(0.)
                signal_vars["alpha_jes"].setConstant(False)
            else:
                signal_vars["dxp"].setVal(0.)
                signal_vars["alpha_jes"].setVal(0.)
                signal_vars["alpha_jes"].setConstant()
            signal_vars["dxp"].setError(0.)
            signal_vars["dxp"].setConstant()

            if "jer" in systematics:
                sigp_central = signal_vars["sigp_0"].getVal()
                sigp_up = signal_fits.get_parameters(w_signal.pdf("signal__JERUp"))["sigpJERUp"][0]
                sigp_down = signal_fits.get_parameters(w_signal.pdf("signal__JERDown"))["sigpJERDown"][0]
                signal_vars["dsigp"].setVal(max(abs(sigp_up - sigp_central), abs(sigp_down - sigp_central)))
                signal_vars["alpha_jer"].setVal(0.)
                signal_vars["alpha_jer"].setConstant(False)
            else:
                signal_vars["dsigp"].setVal(0.)
                signal_vars["alpha_jer"].setVal(0.)
                signal_vars["alpha_jer"].setConstant()
            signal_vars["dsigp"].setError(0.)
            signal_vars["dsigp"].setConstant()
                #for variation in ["JERUp", "JERDown"]:
                #    signal_pdfs_syst[variation] = w_signal.pdf("signal__" + variation)
            #for variation, pdf in signal_pdfs_syst.iteritems():
            #    signal_parameters = pdf.getVariables()
            #    iter = signal_parameters.createIterator()
            #    var = iter.Next()
            #    while var:
            #        var.setConstant()
            #        var = iter.Next()
            f_signal_pdfs.Close()
        else:
            # dictionaries holding systematic variations of the signal shape
            hSig_Syst = {}
            hSig_Syst_DataHist = {}
            sigCDF = TGraph(hSig.GetNbinsX()+1)

            if "jes" in systematics or "jer" in systematics:

                sigCDF.SetPoint(0,0.,0.)
                integral = 0.
                for i in range(1, hSig.GetNbinsX()+1):
                    x = hSig.GetXaxis().GetBinLowEdge(i+1)
                    integral = integral + hSig.GetBinContent(i)
                    sigCDF.SetPoint(i,x,integral)

            if "jes" in systematics:
                hSig_Syst['JESUp'] = copy.deepcopy(hSig)
                hSig_Syst['JESDown'] = copy.deepcopy(hSig)

            if "jer" in systematics:
                hSig_Syst['JERUp'] = copy.deepcopy(hSig)
                hSig_Syst['JERDown'] = copy.deepcopy(hSig)

            # reset signal histograms
            for key in hSig_Syst.keys():
                hSig_Syst[key].Reset()
                hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key)

            # produce JES signal shapes
            if "jes" in systematics:
                for i in range(1, hSig.GetNbinsX()+1):
                    xLow = hSig.GetXaxis().GetBinLowEdge(i)
                    xUp = hSig.GetXaxis().GetBinLowEdge(i+1)
                    jes = 1. - systematics["jes"]
                    xLowPrime = jes*xLow
                    xUpPrime = jes*xUp
                    hSig_Syst['JESUp'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                    jes = 1. + systematics["jes"]
                    xLowPrime = jes*xLow
                    xUpPrime = jes*xUp
                    hSig_Syst['JESDown'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                hSig_Syst_DataHist['JESUp'] = RooDataHist('hSig_JESUp','hSig_JESUp',RooArgList(mjj),hSig_Syst['JESUp'])
                hSig_Syst_DataHist['JESDown'] = RooDataHist('hSig_JESDown','hSig_JESDown',RooArgList(mjj),hSig_Syst['JESDown'])
            
            # produce JER signal shapes
            if "jer" in systematics:
                for i in range(1, hSig.GetNbinsX()+1):
                    xLow = hSig.GetXaxis().GetBinLowEdge(i)
                    xUp = hSig.GetXaxis().GetBinLowEdge(i+1)
                    jer = 1. - systematics["jer"]
                    xLowPrime = jer*(xLow-float(mass))+float(mass)
                    xUpPrime = jer*(xUp-float(mass))+float(mass)
                    hSig_Syst['JERUp'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                    jer = 1. + systematics["jer"]
                    xLowPrime = jer*(xLow-float(mass))+float(mass)
                    xUpPrime = jer*(xUp-float(mass))+float(mass)
                    hSig_Syst['JERDown'].SetBinContent(i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                hSig_Syst_DataHist['JERUp'] = RooDataHist('hSig_JERUp','hSig_JERUp',RooArgList(mjj),hSig_Syst['JERUp'])
                hSig_Syst_DataHist['JERDown'] = RooDataHist('hSig_JERDown','hSig_JERDown',RooArgList(mjj),hSig_Syst['JERDown'])


        # -----------------------------------------
        # create a datacard and corresponding workspace
        postfix = (('_' + args.postfix) if args.postfix != '' else '')
        wsName = 'workspace_' + args.final_state + '_m' + str(mass) + postfix + '.root'

        w = RooWorkspace('w','workspace')
        if args.fitSignal:
            signal_pdf.SetName("signal")
            getattr(w,'import')(signal_pdf,RooFit.Rename("signal"))
            # Create a norm variable "signal_norm" which normalizes the PDF to unity.
            norm = args.lumi
            #signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", 1. / norm, 0.1 / norm, 10. / norm)
            #if args.analysis == "trigbbh_CSVTM" and mass >= 1100:
            signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", norm/100., norm/100. / 10., norm * 10.)
            #else:
            #    signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", norm, norm / 10., norm * 10.)
            print "[create_datacards] INFO : Set signal norm to {}".format(signal_norm.getVal())
            signal_norm.setConstant()
            getattr(w,'import')(signal_norm,ROOT.RooCmdArg())
            #if "jes" in systematics:
            #    getattr(w,'import')(signal_pdfs_syst['JESUp'],RooFit.Rename("signal__JESUp"))
            #    getattr(w,'import')(signal_pdfs_syst['JESDown'],RooFit.Rename("signal__JESDown"))
            #if "jer" in systematics:
            #    getattr(w,'import')(signal_pdfs_syst['JERUp'],RooFit.Rename("signal__JERUp"))
            #    getattr(w,'import')(signal_pdfs_syst['JERDown'],RooFit.Rename("signal__JERDown"))
        else:
            getattr(w,'import')(rooSigHist,RooFit.Rename("signal"))
            if "jes" in systematics:
                getattr(w,'import')(hSig_Syst_DataHist['JESUp'],RooFit.Rename("signal__JESUp"))
                getattr(w,'import')(hSig_Syst_DataHist['JESDown'],RooFit.Rename("signal__JESDown"))
            if "jer" in systematics:
                getattr(w,'import')(hSig_Syst_DataHist['JERUp'],RooFit.Rename("signal__JERUp"))
                getattr(w,'import')(hSig_Syst_DataHist['JERDown'],RooFit.Rename("signal__JERDown"))
        if args.decoBkg:
            getattr(w,'import')(background_deco,ROOT.RooCmdArg())
        else:
            for fit_function in fit_functions:
                print "Importing background PDF"
                print background_pdfs[fit_function]
                background_pdfs[fit_function].Print()
                getattr(w,'import')(background_pdfs[fit_function],ROOT.RooCmdArg(),RooFit.Rename("background_" + fit_function), RooFit.RecycleConflictNodes())
                w.pdf("background_" + fit_function).Print()
                getattr(w,'import')(background_norms[fit_function],ROOT.RooCmdArg(),RooFit.Rename("background_" + fit_function + "_norm"))
                getattr(w,'import')(fit_results[fit_function])
                getattr(w,'import')(signal_norms[fit_function],ROOT.RooCmdArg())
                if args.fitBonly:
                    getattr(w,'import')(models[fit_function],ROOT.RooCmdArg(),RooFit.RecycleConflictNodes())
        getattr(w,'import')(rooDataHist,RooFit.Rename("data_obs"))

        w.Print()
        print "Starting save"
        if args.output_path:
            if not os.path.isdir( os.path.join(os.getcwd(),args.output_path) ):
                os.mkdir( os.path.join(os.getcwd(),args.output_path) )
            print "[create_datacards] INFO : Writing workspace to file {}".format(os.path.join(args.output_path,wsName))
            w.writeToFile(os.path.join(args.output_path,wsName))
        else:
            print "[create_datacards] INFO : Writing workspace to file {}".format(limit_config.get_workspace_filename(args.analysis, args.model, mass, fitBonly=args.fitBonly, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger))
            w.writeToFile(limit_config.get_workspace_filename(args.analysis, args.model, mass, fitBonly=args.fitBonly, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger))

        # Clean up
        for name, obj in signal_norms.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_pdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_pdfs_notrig.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_norms.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_pdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_pdfs_notrig.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_epdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_epdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in fit_results.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, dict_l2 in background_parameters.iteritems():
            for name2, obj in dict_l2.iteritems():
                if obj:
                    obj.IsA().Destructor(obj)
        for name, obj in models.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        rooDataHist.IsA().Destructor(rooDataHist)
        w.IsA().Destructor(w)

        # Make datacards only if S+B fitted
        if not args.fitBonly:
            beffUnc = 0.3
            boffUnc = 0.06
            for fit_function in fit_functions:
                if args.output_path:
                    dcName = 'datacard_' + args.final_state + '_m' + str(mass) + postfix + '_' + fit_function + '.txt'
                    print "[create_datacards] INFO : Writing datacard to file {}".format(os.path.join(args.output_path,dcName)) 
                    datacard = open(os.path.join(args.output_path,dcName),'w')
                else:
                    print "[create_datacards] INFO : Writing datacard to file {}".format(limit_config.get_datacard_filename(args.analysis, args.model, mass, fit_function, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger)) 
                    datacard = open(limit_config.get_datacard_filename(args.analysis, args.model, mass, fit_function, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger), 'w')
                datacard.write('imax 1\n')
                datacard.write('jmax 1\n')
                datacard.write('kmax *\n')
                datacard.write('---------------\n')
                if ("jes" in systematics or "jer" in systematics) and not args.fitSignal:
                    if args.output_path:
                        datacard.write('shapes * * '+wsName+' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
                    else:
                        datacard.write('shapes * * '+os.path.basename(limit_config.get_workspace_filename(args.analysis, args.model, mass, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger))+' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
                else:
                    if args.output_path:
                        datacard.write('shapes * * '+wsName+' w:$PROCESS\n')
                    else:
                        datacard.write('shapes * * '+os.path.basename(limit_config.get_workspace_filename(args.analysis, args.model, mass, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger))+' w:$PROCESS\n')
                datacard.write('---------------\n')
                datacard.write('bin 1\n')
                datacard.write('observation -1\n')
                datacard.write('------------------------------\n')
                datacard.write('bin          1          1\n')
                datacard.write('process      signal     background_' + fit_function + '\n')
                datacard.write('process      0          1\n')
                if args.fitSignal:
                    datacard.write('rate         1         1\n')
                else:
                    datacard.write('rate         -1         1\n')
                datacard.write('------------------------------\n')
                datacard.write('lumi  lnN    %f         -\n'%(1.+systematics["luminosity"]))
                datacard.write('beff  lnN    %f         -\n'%(1.+beffUnc))
                datacard.write('boff  lnN    %f         -\n'%(1.+boffUnc))
                #datacard.write('bkg   lnN     -         1.03\n')
                if args.fitSignal:
                    if "jes" in systematics:
                        datacard.write("alpha_jes  param  0.0  1.0\n")
                    if "jer" in systematics:
                        datacard.write("alpha_jer  param  0.0  1.0\n")
                else:
                    if "jes" in systematics:
                        datacard.write('JES  shape   1          -\n')
                    if "jer" in systematics:
                        datacard.write('JER  shape   1          -\n')
                # flat parameters --- flat prior
                datacard.write('background_' + fit_function + '_norm  flatParam\n')
                if args.decoBkg:
                    datacard.write('deco_eig1  flatParam\n')
                    datacard.write('deco_eig2  flatParam\n')
                else:
                    for par_name, par in background_parameters[fit_function].iteritems():
                        datacard.write(fit_function + "_" + par_name + '  flatParam\n')
                datacard.close()
                print "[create_datacards] INFO : Done with this datacard"

    #print '>> Datacards and workspaces created and stored in %s/'%( os.path.join(os.getcwd(),args.output_path) )
    print "All done."
def studyVqqResolution(rootFile):

    #get all from file
    histos = {}
    inF = TFile.Open(rootFile)
    keys = inF.GetListOfKeys()
    for k in keys:
        obj = inF.Get(k.GetName())
        obj.SetDirectory(0)
        histos[k.GetName()] = obj
    inF.Close()

    #plot
    gROOT.SetBatch()
    gROOT.SetStyle('Plain')
    gStyle.SetOptStat(0)
    gStyle.SetOptFit(1111)
    gStyle.SetOptTitle(0)
    gStyle.SetStatFont(42)

    kin = ['', '30to40', '40to50', '50to75', '75to100', '100toInf']
    for k in kin:
        c = TCanvas('c', 'c', 600, 600)
        c.cd()
        c.SetCanvasSize(1000, 500)
        c.SetWindowSize(1000, 500)
        c.Divide(2, 1)
        c.cd(1)
        histos['deta' + k + 'barrel'].SetLineWidth(2)
        histos['deta' + k + 'barrel'].SetTitle('barrel')
        histos['deta' + k + 'barrel'].Draw('hist')
        histos['deta' + k + 'endcap'].SetLineWidth(2)
        histos['deta' + k + 'endcap'].SetLineStyle(7)
        histos['deta' + k + 'endcap'].SetTitle('endcap')
        histos['deta' + k + 'endcap'].Draw('histsame')
        leg = TLegend(0.6, 0.92, 0.9, 0.98)
        leg.SetFillStyle(0)
        leg.SetBorderSize(0)
        leg.SetTextFont(42)
        leg.AddEntry(histos['deta' + k + 'barrel'], 'barrel', 'f')
        leg.AddEntry(histos['deta' + k + 'endcap'], 'endcap', 'f')
        leg.SetNColumns(2)
        leg.Draw()
        drawHeader()
        c.cd(2)
        histos['dphi' + k + 'barrel'].SetLineWidth(2)
        histos['dphi' + k + 'barrel'].SetTitle('barrel')
        histos['dphi' + k + 'barrel'].Draw('hist')
        histos['dphi' + k + 'endcap'].SetLineWidth(2)
        histos['dphi' + k + 'endcap'].SetLineStyle(7)
        histos['dphi' + k + 'endcap'].SetTitle('endcap')
        histos['dphi' + k + 'endcap'].Draw('histsame')
        c.Modified()
        c.Update()
        c.SaveAs('dr_%s.png' % k)

    labels = []
    responseVars = ['dpt', 'den', 'dphi', 'deta', 'dr']
    for r in responseVars:
        barrelResponse = TGraphErrors()
        barrelResponse.SetName(r + 'barrelresponse')
        barrelResponse.SetLineWidth(2)
        barrelResponse.SetFillStyle(0)
        barrelResponse.SetMarkerStyle(20)
        barrelCoreResponse = barrelResponse.Clone(r + 'barrelcoreresponse')
        endcapResponse = TGraphErrors()
        endcapResponse.SetName(r + 'endcapresponse')
        endcapResponse.SetLineWidth(2)
        endcapResponse.SetFillStyle(0)
        endcapResponse.SetMarkerStyle(24)
        endcapCoreResponse = endcapResponse.Clone(r + 'endcapresponse')
        for k in kin:
            c.cd()
            c.Clear()
            c.SetWindowSize(1000, 500)
            c.Divide(2, 1)
            for i in [1, 2]:
                c.cd(i)
                reg = 'barrel'
                if i == 2: reg = 'endcap'

                h = histos[r + k + reg]
                x = RooRealVar("x",
                               h.GetXaxis().GetTitle(),
                               h.GetXaxis().GetXmin(),
                               h.GetXaxis().GetXmax())
                data = RooDataHist("data", "dataset with x", RooArgList(x), h)
                frame = x.frame()
                RooAbsData.plotOn(data, frame,
                                  RooFit.DataError(RooAbsData.SumW2))

                mean1 = RooRealVar("mean1", "mean1", 0, -0.5, 0.5)
                sigma1 = RooRealVar("sigma1", "sigma1", 0.1, 0.01, 1.0)
                gauss1 = RooGaussian("g1", "g", x, mean1, sigma1)

                if r == 'dpt' or r == 'den':
                    mean2 = RooRealVar("mean2", "mean2", 0, -0.5, 0.5)
                    sigma2 = RooRealVar("sigma2", "sigma2", 0.1, 0.01, 1.0)
                    alphacb = RooRealVar("alphacb", "alphacb", 1, 0.1, 3)
                    ncb = RooRealVar("ncb", "ncb", 4, 1, 100)
                    gauss2 = RooCBShape("cb2", "cb", x, mean2, sigma2, alphacb,
                                        ncb)
                else:
                    mean1.setRange(0, 0.5)
                    mean2 = RooRealVar("mean2", "mean", 0, 0, 1)
                    sigma2 = RooRealVar("sigma2", "sigma", 0.1, 0.01, 1.0)
                    gauss2 = RooGaussian("g2", "g", x, mean2, sigma2)

                frac = RooRealVar("frac", "fraction", 0.9, 0.0, 1.0)
                if data.sumEntries() < 100:
                    frac.setVal(1.0)
                    frac.setConstant(True)
                model = RooAddPdf("sum", "g1+g2", RooArgList(gauss1, gauss2),
                                  RooArgList(frac))

                status = model.fitTo(data, RooFit.Save()).status()
                if status != 0: continue

                model_cdf = model.createCdf(RooArgSet(x))
                cl = 0.90
                ul = 0.5 * (1.0 + cl)
                closestToCL = 1.0
                closestToUL = -1
                closestToMedianCL = 1.0
                closestToMedian = -1
                for ibin in xrange(1, h.GetXaxis().GetNbins() * 10):
                    xval = h.GetXaxis().GetXmin() + (
                        ibin - 1) * h.GetXaxis().GetBinWidth(ibin) / 10.
                    x.setVal(xval)
                    cdfValToCL = math.fabs(model_cdf.getVal() - ul)
                    if cdfValToCL < closestToCL:
                        closestToCL = cdfValToCL
                        closestToUL = xval
                    cdfValToCL = math.fabs(model_cdf.getVal() - 0.5)
                    if cdfValToCL < closestToMedianCL:
                        closestToMedianCL = cdfValToCL
                        closestToMedian = xval

                RooAbsPdf.plotOn(model, frame)
                frame.Draw()

                if i == 1: drawHeader()
                labels.append(TPaveText(0.6, 0.92, 0.9, 0.98, 'brNDC'))
                ilab = len(labels) - 1
                labels[ilab].SetName(r + k + 'txt')
                labels[ilab].SetBorderSize(0)
                labels[ilab].SetFillStyle(0)
                labels[ilab].SetTextFont(42)
                labels[ilab].SetTextAlign(12)
                kinReg = k.replace('to', '-')
                kinReg = kinReg.replace('Inf', '#infty')
                labels[ilab].AddText('[' + reg + '] ' + kinReg)
                labels[ilab].Draw()

                resolutionVal = math.fabs(closestToUL - closestToMedian)
                responseGr = barrelResponse
                responseCoreGr = barrelCoreResponse
                coreResolutionVal = sigma1.getVal()
                coreResolutionErr = sigma1.getError()
                if frac.getVal() < 0.7 and (sigma2.getVal() < sigma1.getVal()):
                    coreResolutionVal = sigma2.getVal()
                    coreResolutionErr = sigma2.getError()

                if i == 2:
                    responseGr = endcapResponse
                    responseCoreGr = endcapCoreResponse
                if k != '':
                    nrespPts = responseGr.GetN()
                    kinAvg = 150
                    kinWidth = 50
                    if k == '30to40':
                        kinAvg = 35
                        kinWidth = 5
                    if k == '40to50':
                        kinAvg = 45
                        kinWidth = 5
                    if k == '50to75':
                        kinAvg = 62.5
                        kinWidth = 12.5
                    elif k == '75to100':
                        kinAvg = 87.5
                        kinWidth = 12.5
                    responseGr.SetPoint(nrespPts, kinAvg, resolutionVal)
                    responseCoreGr.SetPoint(nrespPts, kinAvg,
                                            coreResolutionVal)
                    responseCoreGr.SetPointError(nrespPts, kinWidth,
                                                 coreResolutionErr)

                labels.append(TPaveText(0.15, 0.7, 0.4, 0.9, 'brNDC'))
                ilab = len(labels) - 1
                labels[ilab].SetName(r + k + 'fitrestxt')
                labels[ilab].SetBorderSize(0)
                labels[ilab].SetFillStyle(0)
                labels[ilab].SetTextFont(42)
                labels[ilab].SetTextAlign(12)
                labels[ilab].AddText('Gaussian #1 (f=%3.3f)' % frac.getVal())
                labels[ilab].AddText('#mu=%3.3f#pm%3.3f' %
                                     (mean1.getVal(), mean1.getError()))
                labels[ilab].AddText('#sigma=%3.3f#pm%3.3f' %
                                     (sigma1.getVal(), sigma1.getError()))
                labels[ilab].AddText('Gaussian #2 (f=%3.3f)' %
                                     (1 - frac.getVal()))
                labels[ilab].AddText('#mu=%3.3f#pm%3.3f' %
                                     (mean2.getVal(), mean2.getError()))
                labels[ilab].AddText('#sigma=%3.3f#pm%3.3f' %
                                     (sigma2.getVal(), sigma2.getError()))

                labels[ilab].Draw()

            c.Modified()
            c.Update()
            c.SaveAs(r + 'res_' + k + '.png')

        frame = TGraphErrors()
        frame.SetPoint(0, 0, 0)
        frame.SetPoint(1, 200, 0.3)
        frame.SetMarkerStyle(1)
        frame.SetFillStyle(0)
        frame.SetName('frame')
        cresp = TCanvas('cresp', 'cresp', 500, 500)
        cresp.cd()
        frame.Draw('ap')
        barrelResponse.Draw('pl')
        endcapResponse.Draw('pl')
        frame.GetXaxis().SetTitle("Quark transverse momentum [GeV]")
        frame.GetYaxis().SetTitle("Resolution %3.2f C.L." % cl)
        frame.GetYaxis().SetTitleOffset(1.4)
        frame.GetYaxis().SetNdivisions(10)
        drawHeader()
        leg = TLegend(0.6, 0.92, 0.9, 0.98)
        leg.SetFillStyle(0)
        leg.SetBorderSize(0)
        leg.SetTextFont(42)
        leg.AddEntry(barrelResponse, 'barrel', 'fp')
        leg.AddEntry(endcapResponse, 'endcap', 'fp')
        leg.SetNColumns(2)
        leg.Draw()
        cresp.Modified()
        cresp.Update()
        cresp.SaveAs(r + 'res_evol.png')

        frameCore = frame.Clone('framecore')
        cresp.Clear()
        frameCore.Draw('ap')
        barrelCoreResponse.Draw('pl')
        endcapCoreResponse.Draw('pl')
        frameCore.GetXaxis().SetTitle("Quark transverse momentum [GeV]")
        frameCore.GetYaxis().SetTitle("Core resolution")
        frameCore.GetYaxis().SetTitleOffset(1.4)
        frameCore.GetYaxis().SetNdivisions(10)
        frameCore.GetYaxis().SetRangeUser(0, 0.2)
        drawHeader()
        leg = TLegend(0.6, 0.92, 0.9, 0.98)
        leg.SetFillStyle(0)
        leg.SetBorderSize(0)
        leg.SetTextFont(42)
        leg.AddEntry(barrelCoreResponse, 'barrel', 'fp')
        leg.AddEntry(endcapCoreResponse, 'endcap', 'fp')
        leg.SetNColumns(2)
        leg.Draw()
        cresp.Modified()
        cresp.Update()
        cresp.SaveAs(r + 'rescore_evol.png')

    bosons = ['h', 'z', 'w']
    kin = ['', '50', '100']
    region = ['', 'bb', 'eb', 'ee']
    for k in kin:
        for r in region:

            c = TCanvas('c', 'c', 600, 600)
            c.cd()
            histos['mjj' + k + r].Rebin()
            histos['mjj' + k + r].Draw()
            ic = 1
            leg = TLegend(0.6, 0.92, 0.9, 0.98)
            leg.SetFillStyle(0)
            leg.SetBorderSize(0)
            leg.SetTextFont(42)
            leg.AddEntry(histos['mjj' + k + r], 'inclusive', 'f')
            for b in bosons:
                if histos[b + 'mjj' + k + r].Integral() <= 0: continue
                ic = ic + 1
                histos[b + 'mjj' + k + r].Rebin()
                histos[b + 'mjj' + k + r].SetLineColor(ic)
                histos[b + 'mjj' + k + r].SetLineWidth(2)
                histos[b + 'mjj' + k + r].SetMarkerColor(ic)
                histos[b + 'mjj' + k + r].SetMarkerStyle(1)
                histos[b + 'mjj' + k + r].SetFillStyle(3000 + ic)
                histos[b + 'mjj' + k + r].SetFillColor(ic)
                histos[b + 'mjj' + k + r].Draw('histsame')
                leg.AddEntry(histos[b + 'mjj' + k + r], b, "f")
            leg.SetNColumns(ic)
            leg.Draw()
            drawHeader()
            labels.append(TPaveText(0.65, 0.8, 0.9, 0.9, 'brNDC'))
            ilab = len(labels) - 1
            labels[ilab].SetName(k + r + 'mjj')
            labels[ilab].SetBorderSize(0)
            labels[ilab].SetFillStyle(0)
            labels[ilab].SetTextFont(42)
            labels[ilab].SetTextAlign(12)
            regionTitle = "inclusive"
            if r == 'bb': regionTitle = 'barrel-barrel'
            if r == 'eb': regionTitle = 'endcap-barrel'
            if r == 'ee': regionTitle = 'endcap-endcap'
            labels[ilab].AddText(regionTitle)
            ptthreshold = 30
            if k != '': ptthreshold = float(k)
            labels[ilab].AddText('p_{T}>%3.0f GeV' % ptthreshold)
            labels[ilab].Draw()

            c.Modified()
            c.Update()
            c.SaveAs('mjj' + k + r + '.png')

    massResolutionGrs = []
    for r in region:
        massResolution = TGraphErrors()
        massResolution.SetName(r + 'dm')
        massResolution.SetLineWidth(2)
        massResolution.SetFillStyle(0)
        massResolution.SetMarkerStyle(20 + len(massResolutionGrs))
        massResolution.SetMarkerColor(1 + len(massResolutionGrs))
        massResolution.SetLineColor(1 + len(massResolutionGrs))
        massResolution.SetFillColor(1 + len(massResolutionGrs))
        massResolutionGrs.append(massResolution)

        for k in kin:

            c = TCanvas('c', 'c', 600, 600)
            c.cd()
            h = histos['dmjj' + k + r]
            x = RooRealVar("x",
                           h.GetXaxis().GetTitle(),
                           h.GetXaxis().GetXmin(),
                           h.GetXaxis().GetXmax())
            data = RooDataHist("data", "dataset with x", RooArgList(x), h)
            frame = x.frame()
            RooAbsData.plotOn(data, frame, RooFit.DataError(RooAbsData.SumW2))

            mean1 = RooRealVar("mean1", "mean1", 0, -0.5, 0.5)
            sigma1 = RooRealVar("sigma1", "sigma1", 0.1, 0.01, 1.0)
            gauss1 = RooGaussian("g1", "g", x, mean1, sigma1)
            mean2 = RooRealVar("mean2", "mean2", 0, -0.5, 0.5)
            sigma2 = RooRealVar("sigma2", "sigma2", 0.1, 0.01, 1.0)
            alphacb = RooRealVar("alphacb", "alphacb", 1, 0.1, 3)
            ncb = RooRealVar("ncb", "ncb", 4, 1, 100)
            gauss2 = RooCBShape("cb2", "cb", x, mean2, sigma2, alphacb, ncb)
            frac = RooRealVar("frac", "fraction", 0.9, 0.0, 1.0)
            model = RooAddPdf("sum", "g1+g2", RooArgList(gauss1, gauss2),
                              RooArgList(frac))
            status = model.fitTo(data, RooFit.Save()).status()
            if status != 0: continue
            RooAbsPdf.plotOn(model, frame)
            frame.Draw()

            labels.append(TPaveText(0.6, 0.65, 0.85, 0.9, 'brNDC'))
            ilab = len(labels) - 1
            labels[ilab].SetName(r + k + 'dmfitrestxt')
            labels[ilab].SetBorderSize(0)
            labels[ilab].SetFillStyle(0)
            labels[ilab].SetTextFont(42)
            labels[ilab].SetTextAlign(12)
            labels[ilab].AddText('Gaussian #1 (f=%3.3f)' % frac.getVal())
            labels[ilab].AddText('#mu=%3.3f#pm%3.3f' %
                                 (mean1.getVal(), mean1.getError()))
            labels[ilab].AddText('#sigma=%3.3f#pm%3.3f' %
                                 (sigma1.getVal(), sigma1.getError()))
            labels[ilab].AddText('Gaussian #2 (f=%3.3f)' % (1 - frac.getVal()))
            labels[ilab].AddText('#mu=%3.3f#pm%3.3f' %
                                 (mean2.getVal(), mean2.getError()))
            labels[ilab].AddText('#sigma=%3.3f#pm%3.3f' %
                                 (sigma2.getVal(), sigma2.getError()))
            labels[ilab].Draw()

            drawHeader()
            labels.append(TPaveText(0.15, 0.8, 0.4, 0.9, 'brNDC'))
            ilab = len(labels) - 1
            labels[ilab].SetName(k + r + 'dmjj')
            labels[ilab].SetBorderSize(0)
            labels[ilab].SetFillStyle(0)
            labels[ilab].SetTextFont(42)
            labels[ilab].SetTextAlign(12)
            regionTitle = "inclusive"
            if r == 'bb': regionTitle = 'barrel-barrel'
            if r == 'eb': regionTitle = 'endcap-barrel'
            if r == 'ee': regionTitle = 'endcap-endcap'
            labels[ilab].AddText(regionTitle)
            ptthreshold = 30
            if k != '': ptthreshold = float(k)
            labels[ilab].AddText('p_{T}>%3.0f GeV' % ptthreshold)
            labels[ilab].Draw()

            c.Modified()
            c.Update()
            c.SaveAs('dmjj' + k + r + '.png')

            massResolution.SetTitle(regionTitle)
            ip = massResolution.GetN()
            x = 40
            xerr = 10
            if k == '50':
                x = 75
                xerr = 25
            elif k == '100':
                x = 150
                xerr = 50
            y = sigma1.getVal()
            yerr = sigma1.getError()
            if frac.getVal() < 0.8:
                if sigma2.getVal() < sigma1.getVal():
                    y = sigma2.getVal()
                    ey = sigma2.getError()
            massResolution.SetPoint(ip, x, y)
            massResolution.SetPointError(ip, xerr, yerr)

    frame = TGraphErrors()
    frame.SetPoint(0, 0, 0)
    frame.SetPoint(1, 200, 0.2)
    frame.SetMarkerStyle(1)
    frame.SetFillStyle(0)
    frame.SetName('dmframe')
    cdmevol = TCanvas('cdmevol', 'cdmevol', 500, 500)
    cdmevol.cd()
    frame.Draw('ap')
    leg = TLegend(0.6, 0.92, 0.9, 0.98)
    leg.SetFillStyle(0)
    leg.SetBorderSize(0)
    leg.SetTextFont(42)
    for dmGr in massResolutionGrs:
        dmGr.Draw('pl')
        leg.AddEntry(dmGr, dmGr.GetTitle(), 'fp')
    frame.GetXaxis().SetTitle("Leading quark transverse momentum [GeV]")
    frame.GetYaxis().SetTitle("Core resolution")
    frame.GetYaxis().SetTitleOffset(1.4)
    frame.GetYaxis().SetNdivisions(10)
    drawHeader()
    leg.SetNColumns(2)
    leg.Draw()
    cdmevol.Modified()
    cdmevol.Update()
    cdmevol.SaveAs('dm_evol.png')

    c = TCanvas('c', 'c', 600, 600)
    c.cd()
    histos['sel'].Draw('histtext')
    drawHeader()
    c.Modified()
    c.Update()
    c.SaveAs('selection.png')

    return
Ejemplo n.º 12
0
def main():
    # usage description
    usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2"

    # input parameters
    parser = ArgumentParser(
        description=
        'Script that creates combine datacards and corresponding RooFit workspaces',
        epilog=usage)
    parser.add_argument("analysis", type=str, help="Analysis name")
    parser.add_argument("model", type=str, help="Model (Hbb, RSG)")

    #parser.add_argument("--inputData", dest="inputData", required=True,
    #                    help="Input data spectrum",
    #                    metavar="INPUT_DATA")

    parser.add_argument("--dataHistname",
                        dest="dataHistname",
                        type=str,
                        default="h_data",
                        help="Data histogram name",
                        metavar="DATA_HISTNAME")

    #parser.add_argument("--inputSig", dest="inputSig", required=True,
    #                    help="Input signal shapes",
    #                    metavar="INPUT_SIGNAL")

    parser.add_argument("-f",
                        "--final_state",
                        dest="final_state",
                        default="qq",
                        help="Final state (e.g. qq, qg, gg)",
                        metavar="FINAL_STATE")
    parser.add_argument("--fit_functions",
                        dest="fit_functions",
                        default="f1,f2,f3,f4,f5",
                        help="List of fit functions")

    #parser.add_argument("-f2", "--type", dest="atype", required=True, help="Type (e.g. hG, lG, hR, lR)")

    parser.add_argument(
        "-o",
        "--output_path",
        dest="output_path",
        help=
        "Output path where datacards and workspaces will be stored. If not specified, this is derived from limit_configuration.",
        metavar="OUTPUT_PATH")

    parser.add_argument("--correctTrigger",
                        dest="correctTrigger",
                        action='store_true',
                        help="Include trigger correction in PDF")

    parser.add_argument(
        "-l",
        "--lumi",
        dest="lumi",
        default=19700.,
        type=float,
        help="Integrated luminosity in pb-1 (default: %(default).1f)",
        metavar="LUMI")

    parser.add_argument(
        "--massMin",
        dest="massMin",
        default=500,
        type=int,
        help=
        "Lower bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MIN")

    parser.add_argument(
        "--massMax",
        dest="massMax",
        default=1200,
        type=int,
        help=
        "Upper bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MAX")
    parser.add_argument(
        "--fitSignal",
        action="store_true",
        help=
        "Use signal fitted shapes (CB+Voigtian) instead of histogram templates"
    )
    #parser.add_argument("--lumiUnc", dest="lumiUnc",
    #                    required=True, type=float,
    #                    help="Relative uncertainty in the integrated luminosity",
    #                    metavar="LUMI_UNC")

    #parser.add_argument("--jesUnc", dest="jesUnc",
    #                    type=float,
    #                    help="Relative uncertainty in the jet energy scale",
    #                    metavar="JES_UNC")

    #parser.add_argument("--jerUnc", dest="jerUnc",
    #                    type=float,
    #                    help="Relative uncertainty in the jet energy resolution",
    #                    metavar="JER_UNC")

    parser.add_argument(
        "--sqrtS",
        dest="sqrtS",
        default=8000.,
        type=float,
        help="Collision center-of-mass energy (default: %(default).1f)",
        metavar="SQRTS")

    parser.add_argument("--fixP3",
                        dest="fixP3",
                        default=False,
                        action="store_true",
                        help="Fix the fit function p3 parameter")

    parser.add_argument("--runFit",
                        dest="runFit",
                        default=False,
                        action="store_true",
                        help="Run the fit")

    parser.add_argument("--fitBonly",
                        dest="fitBonly",
                        default=False,
                        action="store_true",
                        help="Run B-only fit")

    parser.add_argument("--fixBkg",
                        dest="fixBkg",
                        default=False,
                        action="store_true",
                        help="Fix all background parameters")

    parser.add_argument("--decoBkg",
                        dest="decoBkg",
                        default=False,
                        action="store_true",
                        help="Decorrelate background parameters")

    parser.add_argument("--fitStrategy",
                        dest="fitStrategy",
                        type=int,
                        default=1,
                        help="Fit strategy (default: %(default).1f)")

    parser.add_argument("--debug",
                        dest="debug",
                        default=False,
                        action="store_true",
                        help="Debug printout")

    parser.add_argument(
        "--postfix",
        dest="postfix",
        default='',
        help="Postfix for the output file names (default: %(default)s)")

    parser.add_argument("--pyes",
                        dest="pyes",
                        default=False,
                        action="store_true",
                        help="Make files for plots")

    parser.add_argument("--jyes",
                        dest="jyes",
                        default=False,
                        action="store_true",
                        help="Make files for JES/JER plots")

    parser.add_argument(
        "--pdir",
        dest="pdir",
        default='testarea',
        help="Name a directory for the plots (default: %(default)s)")

    parser.add_argument("--chi2",
                        dest="chi2",
                        default=False,
                        action="store_true",
                        help="Compute chi squared")

    parser.add_argument("--widefit",
                        dest="widefit",
                        default=False,
                        action="store_true",
                        help="Fit with wide bin hist")

    mass_group = parser.add_mutually_exclusive_group(required=True)
    mass_group.add_argument(
        "--mass",
        type=int,
        nargs='*',
        default=1000,
        help=
        "Mass can be specified as a single value or a whitespace separated list (default: %(default)i)"
    )
    mass_group.add_argument(
        "--massrange",
        type=int,
        nargs=3,
        help="Define a range of masses to be produced. Format: min max step",
        metavar=('MIN', 'MAX', 'STEP'))
    mass_group.add_argument("--masslist",
                            help="List containing mass information")

    args = parser.parse_args()

    fit_functions = args.fit_functions.split(",")

    # mass points for which resonance shapes will be produced
    masses = []

    if args.fitBonly:
        masses.append(750)
    else:
        if args.massrange != None:
            MIN, MAX, STEP = args.massrange
            masses = range(MIN, MAX + STEP, STEP)
        elif args.masslist != None:
            # A mass list was provided
            print "Will create mass list according to", args.masslist
            masslist = __import__(args.masslist.replace(".py", ""))
            masses = masslist.masses
        else:
            masses = args.mass

    # sort masses
    masses.sort()

    # import ROOT stuff
    from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine
    from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooProdPdf, RooEffProd, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf, RooExtendPdf

    if not args.debug:
        RooMsgService.instance().setSilentMode(kTRUE)
        RooMsgService.instance().setStreamStatus(0, kFALSE)
        RooMsgService.instance().setStreamStatus(1, kFALSE)

    # input data file
    #inputData = TFile(limit_config.get_data_input(args.analysis))
    # input data histogram
    #hData = inputData.Get(args.dataHistname)
    #hData.SetDirectory(0)
    data_file = TFile(
        analysis_config.get_b_histogram_filename(args.analysis,
                                                 "BJetPlusX_2012"))
    hData = data_file.Get("BHistograms/h_pfjet_mjj")
    hData.SetDirectory(0)

    # input sig file
    if not args.fitSignal:
        print "[create_datacards] INFO : Opening resonance shapes file at " + limit_config.get_resonance_shapes(
            args.analysis, args.model)
        inputSig = TFile(
            limit_config.get_resonance_shapes(args.analysis, args.model),
            "READ")

    sqrtS = args.sqrtS

    # mass variable
    mjj = RooRealVar('mjj', 'mjj', float(args.massMin), float(args.massMax))

    # integrated luminosity and signal cross section
    lumi = args.lumi
    signalCrossSection = 1.  # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section

    if args.correctTrigger:
        trigger_efficiency_pdf = trigger_efficiency.get_pdf(args.analysis, mjj)
        trigger_efficiency_formula = trigger_efficiency.get_formula(
            args.analysis, mjj)
    else:
        trigger_efficiency_pdf = trigger_efficiency.get_trivial_pdf(mjj)
        trigger_efficiency_formula = trigger_efficiency.get_trivial_formula(
            mjj)

    for mass in masses:

        print ">> Creating datacard and workspace for %s resonance with m = %i GeV..." % (
            args.final_state, int(mass))

        rooDataHist = RooDataHist('rooDatahist', 'rooDathist', RooArgList(mjj),
                                  hData)

        if not args.fitSignal:
            hSig = inputSig.Get("h_" + args.final_state + "_" + str(int(mass)))
            if not hSig:
                raise Exception("Couldn't find histogram " + "h_" +
                                args.final_state + "_" + str(int(mass)) +
                                " in file " +
                                limit_config.get_resonance_shapes(
                                    args.analysis, args.model))
            # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity)
            hSig.Scale(
                signalCrossSection * lumi / hSig.Integral()
            )  # divide by a number that provides roughly an r value of 1-10
            rooSigHist = RooDataHist('rooSigHist', 'rooSigHist',
                                     RooArgList(mjj), hSig)
            print 'Signal acceptance:', (rooSigHist.sumEntries() /
                                         hSig.Integral())

        # If using fitted signal shapes, load the signal PDF
        if args.fitSignal:
            print "[create_datacards] Loading fitted signal PDFs from " + analysis_config.get_signal_fit_file(
                args.analysis,
                args.model,
                mass,
                "bukin",
                interpolated=(not mass
                              in analysis_config.simulation.simulated_masses))
            f_signal_pdfs = TFile(
                analysis_config.get_signal_fit_file(
                    args.analysis,
                    args.model,
                    mass,
                    "bukin",
                    interpolated=(
                        not mass
                        in analysis_config.simulation.simulated_masses)),
                "READ")
            w_signal = f_signal_pdfs.Get("w_signal")
            input_parameters = signal_fits.get_parameters(
                w_signal.pdf("signal"))

            # Make a new PDF with nuisance parameters
            signal_pdf_notrig, signal_vars = signal_fits.make_signal_pdf_systematic(
                "bukin", mjj, mass=mass)
            signal_pdf_name = signal_pdf_notrig.GetName()
            signal_pdf_notrig.SetName(signal_pdf_name + "_notrig")
            #signal_pdf = RooProdPdf(signal_pdf_name, signal_pdf_name, signal_pdf_notrig, trigger_efficiency_pdf)
            signal_pdf = RooEffProd(signal_pdf_name, signal_pdf_name,
                                    signal_pdf_notrig,
                                    trigger_efficiency_formula)

            # Copy input parameter values
            signal_vars["xp_0"].setVal(input_parameters["xp"][0])
            signal_vars["xp_0"].setError(input_parameters["xp"][1])
            signal_vars["xp_0"].setConstant()
            signal_vars["sigp_0"].setVal(input_parameters["sigp"][0])
            signal_vars["sigp_0"].setError(input_parameters["sigp"][1])
            signal_vars["sigp_0"].setConstant()
            signal_vars["xi_0"].setVal(input_parameters["xi"][0])
            signal_vars["xi_0"].setError(input_parameters["xi"][1])
            signal_vars["xi_0"].setConstant()
            signal_vars["rho1_0"].setVal(input_parameters["rho1"][0])
            signal_vars["rho1_0"].setError(input_parameters["rho1"][1])
            signal_vars["rho1_0"].setConstant()
            signal_vars["rho2_0"].setVal(input_parameters["rho2"][0])
            signal_vars["rho2_0"].setError(input_parameters["rho2"][1])
            signal_vars["rho2_0"].setConstant()
            f_signal_pdfs.Close()

        signal_parameters = {}
        signal_pdfs_notrig = {}
        signal_pdfs = {}
        signal_norms = {}
        background_pdfs = {}
        background_pdfs_notrig = {}
        background_parameters = {}
        background_norms = {}
        signal_epdfs = {}
        background_epdfs = {}
        models = {}
        fit_results = {}

        for fit_function in fit_functions:
            print "[create_datacards] INFO : On fit function {}".format(
                fit_function)

            if args.fitSignal:
                # Make a copy of the signal PDF, so that each fitTo call uses its own copy.
                # The copy should have all variables set constant.
                #signal_pdfs[fit_function], signal_parameters[fit_function] = signal_fits.copy_signal_pdf("bukin", signal_pdf, mjj, tag=fit_function, include_systematics=True)
                signal_pdfs_notrig[fit_function] = ROOT.RooBukinPdf(
                    signal_pdf_notrig,
                    signal_pdf_notrig.GetName() + "_" + fit_function)
                signal_pdfs[fit_function] = RooEffProd(
                    signal_pdf.GetName() + "_" + fit_function,
                    signal_pdf.GetName() + "_" + fit_function,
                    signal_pdfs_notrig[fit_function],
                    trigger_efficiency_formula)
                #signal_pdfs[fit_function] = RooProdPdf(signal_pdf.GetName() + "_" + fit_function, signal_pdf.GetName() + "_" + fit_function, signal_pdfs_notrig[fit_function], trigger_efficiency_pdf)
                iterator = signal_pdfs_notrig[fit_function].getVariables(
                ).createIterator()
                this_parameter = iterator.Next()
                while this_parameter:
                    this_parameter.setConstant()
                    this_parameter = iterator.Next()
            else:
                signal_pdfs[fit_function] = RooHistPdf(
                    'signal_' + fit_function, 'signal_' + fit_function,
                    RooArgSet(mjj), rooSigHist)
            signal_norms[fit_function] = RooRealVar(
                'signal_norm_' + fit_function, 'signal_norm_' + fit_function,
                0., 0., 1e+05)
            if args.fitBonly:
                signal_norms[fit_function].setConstant()
            background_pdfs_notrig[fit_function], background_parameters[
                fit_function] = make_background_pdf(fit_function,
                                                    mjj,
                                                    collision_energy=8000.)
            background_pdf_name = background_pdfs_notrig[fit_function].GetName(
            )
            background_pdfs_notrig[fit_function].SetName(background_pdf_name +
                                                         "_notrig")
            background_pdfs[fit_function] = RooEffProd(
                background_pdf_name, background_pdf_name,
                background_pdfs_notrig[fit_function],
                trigger_efficiency_formula)
            #background_pdfs[fit_function] = RooProdPdf(background_pdf_name, background_pdf_name, background_pdfs_notrig[fit_function], trigger_efficiency_pdf)
            #background_pdfs[fit_function] = background_pdfs_notrig[fit_function]
            #background_pdfs[fit_function].SetName(background_pdf_name)

            # Initial values
            if "trigbbh" in args.analysis:
                if fit_function == "f3":
                    background_parameters[fit_function]["p1"].setVal(55.)
                    background_parameters[fit_function]["p1"].setMin(20.)
                    background_parameters[fit_function]["p2"].setVal(8.)
                elif fit_function == "f4":
                    background_parameters[fit_function]["p1"].setVal(28.)
                    background_parameters[fit_function]["p2"].setVal(-22.)
                    background_parameters[fit_function]["p3"].setVal(10.)
            elif "trigbbl" in args.analysis:
                if fit_function == "f3":
                    background_parameters[fit_function]["p1"].setVal(82.)
                    background_parameters[fit_function]["p1"].setMin(60.)
                    background_parameters[fit_function]["p2"].setVal(8.)
                elif fit_function == "f4":
                    background_parameters[fit_function]["p1"].setVal(41.)
                    background_parameters[fit_function]["p2"].setVal(-45.)
                    background_parameters[fit_function]["p3"].setVal(10.)

            data_integral = hData.Integral(
                hData.GetXaxis().FindBin(float(args.massMin)),
                hData.GetXaxis().FindBin(float(args.massMax)))
            background_norms[fit_function] = RooRealVar(
                'background_' + fit_function + '_norm',
                'background_' + fit_function + '_norm', data_integral, 0.,
                1.e8)

            signal_epdfs[fit_function] = RooExtendPdf(
                'esignal_' + fit_function, 'esignal_' + fit_function,
                signal_pdfs[fit_function], signal_norms[fit_function])
            background_epdfs[fit_function] = RooExtendPdf(
                'ebackground_' + fit_function, 'ebackground_' + fit_function,
                background_pdfs[fit_function], background_norms[fit_function])

            models[fit_function] = RooAddPdf(
                'model_' + fit_function, 's+b',
                RooArgList(background_epdfs[fit_function],
                           signal_epdfs[fit_function]))

            if args.runFit:
                print "[create_datacards] INFO : Starting fit with function {}".format(
                    fit_function)
                fit_results[fit_function] = models[fit_function].fitTo(
                    rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE),
                    RooFit.Strategy(args.fitStrategy), RooFit.Verbose(0))
                print "[create_datacards] INFO : Done with fit {}. Printing results.".format(
                    fit_function)
                fit_results[fit_function].Print()
                print "[create_datacards] DEBUG : End args.runFit if block."

            # needed if want to evaluate limits without background systematics
            if args.fixBkg:
                background_norms[fit_function].setConstant()
                for par_name, par in background_parameters[
                        fit_function].iteritems():
                    par.setConstant()

        # -----------------------------------------
        #signal_pdfs_syst = {}
        # JES and JER uncertainties
        if args.fitSignal:
            print "[create_datacards] INFO : Getting signal PDFs from " + analysis_config.get_signal_fit_file(
                args.analysis,
                args.model,
                mass,
                "bukin",
                interpolated=(not mass
                              in analysis_config.simulation.simulated_masses))
            f_signal_pdfs = TFile(
                analysis_config.get_signal_fit_file(
                    args.analysis,
                    args.model,
                    mass,
                    "bukin",
                    interpolated=(
                        not mass
                        in analysis_config.simulation.simulated_masses)))
            w_signal = f_signal_pdfs.Get("w_signal")
            if "jes" in systematics:
                xp_central = signal_vars["xp_0"].getVal()
                #print w_signal.pdf("signal__JESUp")
                #print signal_fits.get_parameters(w_signal.pdf("signal__JESUp"))
                xp_up = signal_fits.get_parameters(
                    w_signal.pdf("signal__JESUp"))["xpJESUp"][0]
                xp_down = signal_fits.get_parameters(
                    w_signal.pdf("signal__JESDown"))["xpJESDown"][0]
                signal_vars["dxp"].setVal(
                    max(abs(xp_up - xp_central), abs(xp_down - xp_central)))
                if signal_vars["dxp"].getVal() > 2 * mass * 0.1:
                    print "[create_datacards] WARNING : Large dxp value. dxp = {}, xp_down = {}, xp_central = {}, xp_up = {}".format(
                        signal_vars["dxp"].getVal(), xp_down, xp_central,
                        xp_up)
                signal_vars["alpha_jes"].setVal(0.)
                signal_vars["alpha_jes"].setConstant(False)
            else:
                signal_vars["dxp"].setVal(0.)
                signal_vars["alpha_jes"].setVal(0.)
                signal_vars["alpha_jes"].setConstant()
            signal_vars["dxp"].setError(0.)
            signal_vars["dxp"].setConstant()

            if "jer" in systematics:
                sigp_central = signal_vars["sigp_0"].getVal()
                sigp_up = signal_fits.get_parameters(
                    w_signal.pdf("signal__JERUp"))["sigpJERUp"][0]
                sigp_down = signal_fits.get_parameters(
                    w_signal.pdf("signal__JERDown"))["sigpJERDown"][0]
                signal_vars["dsigp"].setVal(
                    max(abs(sigp_up - sigp_central),
                        abs(sigp_down - sigp_central)))
                signal_vars["alpha_jer"].setVal(0.)
                signal_vars["alpha_jer"].setConstant(False)
            else:
                signal_vars["dsigp"].setVal(0.)
                signal_vars["alpha_jer"].setVal(0.)
                signal_vars["alpha_jer"].setConstant()
            signal_vars["dsigp"].setError(0.)
            signal_vars["dsigp"].setConstant()
            #for variation in ["JERUp", "JERDown"]:
            #    signal_pdfs_syst[variation] = w_signal.pdf("signal__" + variation)
            #for variation, pdf in signal_pdfs_syst.iteritems():
            #    signal_parameters = pdf.getVariables()
            #    iter = signal_parameters.createIterator()
            #    var = iter.Next()
            #    while var:
            #        var.setConstant()
            #        var = iter.Next()
            f_signal_pdfs.Close()
        else:
            # dictionaries holding systematic variations of the signal shape
            hSig_Syst = {}
            hSig_Syst_DataHist = {}
            sigCDF = TGraph(hSig.GetNbinsX() + 1)

            if "jes" in systematics or "jer" in systematics:

                sigCDF.SetPoint(0, 0., 0.)
                integral = 0.
                for i in range(1, hSig.GetNbinsX() + 1):
                    x = hSig.GetXaxis().GetBinLowEdge(i + 1)
                    integral = integral + hSig.GetBinContent(i)
                    sigCDF.SetPoint(i, x, integral)

            if "jes" in systematics:
                hSig_Syst['JESUp'] = copy.deepcopy(hSig)
                hSig_Syst['JESDown'] = copy.deepcopy(hSig)

            if "jer" in systematics:
                hSig_Syst['JERUp'] = copy.deepcopy(hSig)
                hSig_Syst['JERDown'] = copy.deepcopy(hSig)

            # reset signal histograms
            for key in hSig_Syst.keys():
                hSig_Syst[key].Reset()
                hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key)

            # produce JES signal shapes
            if "jes" in systematics:
                for i in range(1, hSig.GetNbinsX() + 1):
                    xLow = hSig.GetXaxis().GetBinLowEdge(i)
                    xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                    jes = 1. - systematics["jes"]
                    xLowPrime = jes * xLow
                    xUpPrime = jes * xUp
                    hSig_Syst['JESUp'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                    jes = 1. + systematics["jes"]
                    xLowPrime = jes * xLow
                    xUpPrime = jes * xUp
                    hSig_Syst['JESDown'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                hSig_Syst_DataHist['JESUp'] = RooDataHist(
                    'hSig_JESUp', 'hSig_JESUp', RooArgList(mjj),
                    hSig_Syst['JESUp'])
                hSig_Syst_DataHist['JESDown'] = RooDataHist(
                    'hSig_JESDown', 'hSig_JESDown', RooArgList(mjj),
                    hSig_Syst['JESDown'])

            # produce JER signal shapes
            if "jer" in systematics:
                for i in range(1, hSig.GetNbinsX() + 1):
                    xLow = hSig.GetXaxis().GetBinLowEdge(i)
                    xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                    jer = 1. - systematics["jer"]
                    xLowPrime = jer * (xLow - float(mass)) + float(mass)
                    xUpPrime = jer * (xUp - float(mass)) + float(mass)
                    hSig_Syst['JERUp'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                    jer = 1. + systematics["jer"]
                    xLowPrime = jer * (xLow - float(mass)) + float(mass)
                    xUpPrime = jer * (xUp - float(mass)) + float(mass)
                    hSig_Syst['JERDown'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                hSig_Syst_DataHist['JERUp'] = RooDataHist(
                    'hSig_JERUp', 'hSig_JERUp', RooArgList(mjj),
                    hSig_Syst['JERUp'])
                hSig_Syst_DataHist['JERDown'] = RooDataHist(
                    'hSig_JERDown', 'hSig_JERDown', RooArgList(mjj),
                    hSig_Syst['JERDown'])

        # -----------------------------------------
        # create a datacard and corresponding workspace
        postfix = (('_' + args.postfix) if args.postfix != '' else '')
        wsName = 'workspace_' + args.final_state + '_m' + str(
            mass) + postfix + '.root'

        w = RooWorkspace('w', 'workspace')
        if args.fitSignal:
            signal_pdf.SetName("signal")
            getattr(w, 'import')(signal_pdf, RooFit.Rename("signal"))
            # Create a norm variable "signal_norm" which normalizes the PDF to unity.
            norm = args.lumi
            #signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", 1. / norm, 0.1 / norm, 10. / norm)
            #if args.analysis == "trigbbh_CSVTM" and mass >= 1100:
            signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm",
                                          norm / 100., norm / 100. / 10.,
                                          norm * 10.)
            #else:
            #    signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", norm, norm / 10., norm * 10.)
            print "[create_datacards] INFO : Set signal norm to {}".format(
                signal_norm.getVal())
            signal_norm.setConstant()
            getattr(w, 'import')(signal_norm, ROOT.RooCmdArg())
            #if "jes" in systematics:
            #    getattr(w,'import')(signal_pdfs_syst['JESUp'],RooFit.Rename("signal__JESUp"))
            #    getattr(w,'import')(signal_pdfs_syst['JESDown'],RooFit.Rename("signal__JESDown"))
            #if "jer" in systematics:
            #    getattr(w,'import')(signal_pdfs_syst['JERUp'],RooFit.Rename("signal__JERUp"))
            #    getattr(w,'import')(signal_pdfs_syst['JERDown'],RooFit.Rename("signal__JERDown"))
        else:
            getattr(w, 'import')(rooSigHist, RooFit.Rename("signal"))
            if "jes" in systematics:
                getattr(w, 'import')(hSig_Syst_DataHist['JESUp'],
                                     RooFit.Rename("signal__JESUp"))
                getattr(w, 'import')(hSig_Syst_DataHist['JESDown'],
                                     RooFit.Rename("signal__JESDown"))
            if "jer" in systematics:
                getattr(w, 'import')(hSig_Syst_DataHist['JERUp'],
                                     RooFit.Rename("signal__JERUp"))
                getattr(w, 'import')(hSig_Syst_DataHist['JERDown'],
                                     RooFit.Rename("signal__JERDown"))
        if args.decoBkg:
            getattr(w, 'import')(background_deco, ROOT.RooCmdArg())
        else:
            for fit_function in fit_functions:
                print "Importing background PDF"
                print background_pdfs[fit_function]
                background_pdfs[fit_function].Print()
                getattr(w,
                        'import')(background_pdfs[fit_function],
                                  ROOT.RooCmdArg(),
                                  RooFit.Rename("background_" + fit_function),
                                  RooFit.RecycleConflictNodes())
                w.pdf("background_" + fit_function).Print()
                getattr(w, 'import')(background_norms[fit_function],
                                     ROOT.RooCmdArg(),
                                     RooFit.Rename("background_" +
                                                   fit_function + "_norm"))
                getattr(w, 'import')(fit_results[fit_function])
                getattr(w, 'import')(signal_norms[fit_function],
                                     ROOT.RooCmdArg())
                if args.fitBonly:
                    getattr(w, 'import')(models[fit_function],
                                         ROOT.RooCmdArg(),
                                         RooFit.RecycleConflictNodes())
        getattr(w, 'import')(rooDataHist, RooFit.Rename("data_obs"))

        w.Print()
        print "Starting save"
        if args.output_path:
            if not os.path.isdir(os.path.join(os.getcwd(), args.output_path)):
                os.mkdir(os.path.join(os.getcwd(), args.output_path))
            print "[create_datacards] INFO : Writing workspace to file {}".format(
                os.path.join(args.output_path, wsName))
            w.writeToFile(os.path.join(args.output_path, wsName))
        else:
            print "[create_datacards] INFO : Writing workspace to file {}".format(
                limit_config.get_workspace_filename(
                    args.analysis,
                    args.model,
                    mass,
                    fitBonly=args.fitBonly,
                    fitSignal=args.fitSignal,
                    correctTrigger=args.correctTrigger))
            w.writeToFile(
                limit_config.get_workspace_filename(
                    args.analysis,
                    args.model,
                    mass,
                    fitBonly=args.fitBonly,
                    fitSignal=args.fitSignal,
                    correctTrigger=args.correctTrigger))

        # Clean up
        for name, obj in signal_norms.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_pdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_pdfs_notrig.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_norms.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_pdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_pdfs_notrig.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_epdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_epdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in fit_results.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, dict_l2 in background_parameters.iteritems():
            for name2, obj in dict_l2.iteritems():
                if obj:
                    obj.IsA().Destructor(obj)
        for name, obj in models.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        rooDataHist.IsA().Destructor(rooDataHist)
        w.IsA().Destructor(w)

        # Make datacards only if S+B fitted
        if not args.fitBonly:
            beffUnc = 0.3
            boffUnc = 0.06
            for fit_function in fit_functions:
                if args.output_path:
                    dcName = 'datacard_' + args.final_state + '_m' + str(
                        mass) + postfix + '_' + fit_function + '.txt'
                    print "[create_datacards] INFO : Writing datacard to file {}".format(
                        os.path.join(args.output_path, dcName))
                    datacard = open(os.path.join(args.output_path, dcName),
                                    'w')
                else:
                    print "[create_datacards] INFO : Writing datacard to file {}".format(
                        limit_config.get_datacard_filename(
                            args.analysis,
                            args.model,
                            mass,
                            fit_function,
                            fitSignal=args.fitSignal,
                            correctTrigger=args.correctTrigger))
                    datacard = open(
                        limit_config.get_datacard_filename(
                            args.analysis,
                            args.model,
                            mass,
                            fit_function,
                            fitSignal=args.fitSignal,
                            correctTrigger=args.correctTrigger), 'w')
                datacard.write('imax 1\n')
                datacard.write('jmax 1\n')
                datacard.write('kmax *\n')
                datacard.write('---------------\n')
                if ("jes" in systematics
                        or "jer" in systematics) and not args.fitSignal:
                    if args.output_path:
                        datacard.write('shapes * * ' + wsName +
                                       ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
                    else:
                        datacard.write('shapes * * ' + os.path.basename(
                            limit_config.get_workspace_filename(
                                args.analysis,
                                args.model,
                                mass,
                                fitSignal=args.fitSignal,
                                correctTrigger=args.correctTrigger)) +
                                       ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
                else:
                    if args.output_path:
                        datacard.write('shapes * * ' + wsName +
                                       ' w:$PROCESS\n')
                    else:
                        datacard.write('shapes * * ' + os.path.basename(
                            limit_config.get_workspace_filename(
                                args.analysis,
                                args.model,
                                mass,
                                fitSignal=args.fitSignal,
                                correctTrigger=args.correctTrigger)) +
                                       ' w:$PROCESS\n')
                datacard.write('---------------\n')
                datacard.write('bin 1\n')
                datacard.write('observation -1\n')
                datacard.write('------------------------------\n')
                datacard.write('bin          1          1\n')
                datacard.write('process      signal     background_' +
                               fit_function + '\n')
                datacard.write('process      0          1\n')
                if args.fitSignal:
                    datacard.write('rate         1         1\n')
                else:
                    datacard.write('rate         -1         1\n')
                datacard.write('------------------------------\n')
                datacard.write('lumi  lnN    %f         -\n' %
                               (1. + systematics["luminosity"]))
                datacard.write('beff  lnN    %f         -\n' % (1. + beffUnc))
                datacard.write('boff  lnN    %f         -\n' % (1. + boffUnc))
                #datacard.write('bkg   lnN     -         1.03\n')
                if args.fitSignal:
                    if "jes" in systematics:
                        datacard.write("alpha_jes  param  0.0  1.0\n")
                    if "jer" in systematics:
                        datacard.write("alpha_jer  param  0.0  1.0\n")
                else:
                    if "jes" in systematics:
                        datacard.write('JES  shape   1          -\n')
                    if "jer" in systematics:
                        datacard.write('JER  shape   1          -\n')
                # flat parameters --- flat prior
                datacard.write('background_' + fit_function +
                               '_norm  flatParam\n')
                if args.decoBkg:
                    datacard.write('deco_eig1  flatParam\n')
                    datacard.write('deco_eig2  flatParam\n')
                else:
                    for par_name, par in background_parameters[
                            fit_function].iteritems():
                        datacard.write(fit_function + "_" + par_name +
                                       '  flatParam\n')
                datacard.close()
                print "[create_datacards] INFO : Done with this datacard"

    #print '>> Datacards and workspaces created and stored in %s/'%( os.path.join(os.getcwd(),args.output_path) )
    print "All done."
Ejemplo n.º 13
0
def shapeCards(datahistosFile, histosFile, signalFile, signalSample, hist,
               signalMass, minMass, maxMass, outputName, outputFileTheta):
    """function to run Roofit and save workspace for RooStats"""
    warnings.filterwarnings(
        action='ignore',
        category=RuntimeWarning,
        message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >')

    ############################################################# DATA
    #hData = histosFile.Get('massAve_deltaEtaDijet_QCDPtAll')
    #hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
    dataFile = TFile(datahistosFile)
    hData = dataFile.Get(hist + '_DATA')
    hData.Rebin(args.reBin)
    #hData = hData.Rebin( len( boostedMassAveBins )-1, hData.GetName(), boostedMassAveBins )
    #hData = histosFile.Get(hist+'_QCDPtAll_A')
    #hData.Add(htmpSignal)
    #hData.Scale(1/hData.Integral())
    #maxMass = boostedMassAveBins[ hData.FindLastBinAbove( 0, 1) ]
    #minMass = signalMass-30
    #maxMass = signalMass+30
    massAve = RooRealVar('massAve', 'massAve', minMass, maxMass)
    #massAveData = RooRealVar( 'massAveData', 'massAveData', minMass, maxMass  )
    rooDataHist = RooDataHist('rooDatahist', 'rooDatahist',
                              RooArgList(massAve),
                              hData)  # if isData else hPseudo )
    rooDataHist.Print()
    ############################################################################################

    ####################### Signal
    if 'gaus' in args.job:
        hSignal = TH1F('massAve_RPVStop', 'massAve_RPVStop',
                       maxMass / args.reBin, minMass, maxMass)
        for q in range(hSignal.GetNbinsX() + 1):
            gausEval = signalFile.Eval(hSignal.GetXaxis().GetBinCenter(q))
            hSignal.SetBinContent(q, gausEval)

        #meanSig = RooRealVar( 'meanSig', 'mean of signal', sigGaus.GetParameter( 1 ) )
        #sigmaSig = RooRealVar( 'sigmaSig', 'sigma of signal', sigGaus.GetParameter( 2 ) )
        #signalPdf = RooGaussian( 'signal', 'signal', massAve, meanSig, sigmaSig )
        #signalPdf.Print()
    else:
        signalHistosFile = TFile(signalFile)
        hSignal = signalHistosFile.Get(hist + '_' + signalSample)
        hSignal.Rebin(args.reBin)
    hSignal.Scale(twoProngSF)

    signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-' + str(signalMass))
    rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(massAve),
                             hSignal)
    sigAcc = rooSigHist.sumEntries(
    )  #round(hSignal.Integral( hSignal.GetXaxis().FindBin( minMass ), hSignal.GetXaxis().FindBin( maxMass )), 2)
    rooSigHist.Print()

    #signal = RooHistPdf('signal','signal',RooArgSet(massAve),rooSigHist)
    #signal.Print()
    #signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+04,1e+04)
    #if args.fitBonly: signal_norm.setConstant()
    #signal_norm.Print()

    #####################################################################
    hSigSyst = signalUnc(hSignal, signalMass)
    hSigSystDataHist = {}
    if args.jesUnc:
        hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp', 'hSignalJESUp',
                                                RooArgList(massAve),
                                                hSigSyst['JESUp'])
        hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown',
                                                  'hSignalJESDown',
                                                  RooArgList(massAve),
                                                  hSigSyst['JESDown'])

    if args.jerUnc:
        hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp', 'hSignalJERUp',
                                                RooArgList(massAve),
                                                hSigSyst['JERUp'])
        hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown',
                                                  'hSignalJERDown',
                                                  RooArgList(massAve),
                                                  hSigSyst['JERDown'])

    #################################### Background
    if args.altBkg:
        newBkgHistoFile = datahistosFile.replace('DATA', 'DATA_ABCDBkg')
        newBkgFile = TFile(newBkgHistoFile)
        htmpBkg = newBkgFile.Get(
            'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
        if (htmpBkg.GetBinWidth(1) != args.reBin):
            print '|----- Bin size in DATA_C histogram is different than rest.'
            sys.exit(0)
    else:
        htmpBkg = dataFile.Get(
            'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
        htmpBkg.Rebin(args.reBin)
    #hBkg = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_QCDPtAll_ABCDProj')
    #hBkg = histosFile.Get(hist+'_QCDPtAll_BCD')
    #htmpBkg = htmpBkg.Rebin( len( boostedMassAveBins )-1, htmpBkg.GetName(), boostedMassAveBins )
    hBkg = htmpBkg.Clone()
    hBkg.Reset()
    for ibin in range(htmpBkg.GetNbinsX()):
        binCont = htmpBkg.GetBinContent(ibin)
        binErr = htmpBkg.GetBinError(ibin)
        if binCont == 0:
            hBkg.SetBinContent(ibin, 0)
            hBkg.SetBinError(ibin, 1.8)
        else:
            hBkg.SetBinContent(ibin, binCont)
            hBkg.SetBinError(ibin, binErr)
    #hBkg.Scale(1/hBkg.Integral())

    hPseudo = createPseudoExperiment(hBkg, bkgAcc)

    ###### Adding statistical uncertanty
    hBkgStatUncUp = hBkg.Clone()
    hBkgStatUncUp.Reset()
    hBkgStatUncDown = hBkg.Clone()
    hBkgStatUncDown.Reset()
    for i in range(hBkg.GetNbinsX() + 1):
        cont = hBkg.GetBinContent(i)
        contErr = hBkg.GetBinError(i)
        hBkgStatUncUp.SetBinContent(i, cont + (1 * contErr))
        hBkgStatUncDown.SetBinContent(i, cont - (1 * contErr))
    hBkgStatUncUpDataHist = RooDataHist('hBkgStatUncUp', 'hBkgStatUncUp',
                                        RooArgList(massAve), hBkgStatUncUp)
    hBkgStatUncDownDataHist = RooDataHist('hBkgStatUncDown', 'hBkgStatUncDown',
                                          RooArgList(massAve), hBkgStatUncDown)

    if 'template' in args.job:
        rooBkgHist = RooDataHist('rooBkgHist', 'rooBkgHist',
                                 RooArgList(massAve), hBkg)
        bkgAcc = rooBkgHist.sumEntries()
        rooBkgHist.Print()
        background = RooHistPdf('background', 'background', RooArgSet(massAve),
                                rooBkgHist)
        background.Print()

    else:
        massAveBkg = RooRealVar('massAveBkg', 'massAveBkg', minMass, maxMass)
        p1 = RooRealVar('p1', 'p1', 1, 0., 100.)
        p2 = RooRealVar('p2', 'p2', 1, 0., 60.)
        p3 = RooRealVar('p3', 'p3', 1, -10., 10.)

        bkgAcc = round(
            hBkg.Integral(hBkg.GetXaxis().FindBin(minMass),
                          hBkg.GetXaxis().FindBin(maxMass)), 2)
        background = RooGenericPdf(
            'background',
            '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
            (1300, 1300, 1300), RooArgList(massAveBkg, p1, p2, p3))
        background.Print()

    hBkgSyst = {}
    hBkgSystDataHist = {}

    if args.bkgUnc:
        print ' |---> Adding bkg unc'
        hBkgSyst['BkgUncUp'] = hBkg.Clone()
        hBkgSyst['BkgUncDown'] = hBkg.Clone()

        for key in hBkgSyst:
            hBkgSyst[key].Reset()
            hBkgSyst[key].SetName(hBkgSyst[key].GetName() + '_' + key)

        for q in range(0, hBkg.GetNbinsX()):
            binCont = hBkg.GetBinContent(q)
            bkgUncUp = 1. + (args.bkgUncValue / 100.)
            hBkgSyst['BkgUncUp'].SetBinContent(q, binCont * bkgUncUp)
            bkgUncDown = 1. - (args.bkgUncValue / 100.)
            hBkgSyst['BkgUncDown'].SetBinContent(q, binCont * bkgUncDown)
        hBkgSystDataHist['BkgUncUp'] = RooDataHist('hBkgBkgUncUp',
                                                   'hBkgBkgUncUp',
                                                   RooArgList(massAve),
                                                   hBkgSyst['BkgUncUp'])
        hBkgSystDataHist['BkgUncDown'] = RooDataHist('hBkgBkgUncDown',
                                                     'hBkgBkgUncDown',
                                                     RooArgList(massAve),
                                                     hBkgSyst['BkgUncDown'])

    ############################################################################################

    #model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm))
    #res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(0))
    #res.Print()

    ############################ Create Workspace
    myWS = RooWorkspace("myWS")
    getattr(myWS, 'import')(rooBkgHist, RooFit.Rename("background"))
    #getattr(myWS,'import')(background,RooFit.Rename("background"))
    #getattr(myWS,'import')(signal_norm)
    #getattr(myWS,'import')(background_norm)
    '''
	if 'gaus' in args.job: 
		getattr(myWS,'import')(signalPdf,RooFit.Rename("signal")) 
		if args.jesUnc:
			getattr(myWS,'import')(signalPdfJESUp,RooFit.Rename("signal__JESUp")) 
			getattr(myWS,'import')(signalPdfJESDown,RooFit.Rename("signal__JESDown")) 
	else: 
	'''
    getattr(myWS, 'import')(rooSigHist, RooFit.Rename("signal"))
    if args.jesUnc:
        getattr(myWS, 'import')(hSigSystDataHist['JESUp'],
                                RooFit.Rename("signal__JESUp"))
        getattr(myWS, 'import')(hSigSystDataHist['JESDown'],
                                RooFit.Rename("signal__JESDown"))
    if args.jerUnc:
        getattr(myWS, 'import')(hSigSystDataHist['JERUp'],
                                RooFit.Rename("signal__JERUp"))
        getattr(myWS, 'import')(hSigSystDataHist['JERDown'],
                                RooFit.Rename("signal__JERDown"))
    if args.bkgUnc:
        getattr(myWS, 'import')(hBkgSystDataHist['BkgUncUp'],
                                RooFit.Rename("background__BkgUncUp"))
        getattr(myWS, 'import')(hBkgSystDataHist['BkgUncDown'],
                                RooFit.Rename("background__BkgUncDown"))
    getattr(myWS, 'import')(hBkgStatUncUpDataHist,
                            RooFit.Rename("background__BkgStatUncUp"))
    getattr(myWS, 'import')(hBkgStatUncDownDataHist,
                            RooFit.Rename("background__BkgStatUncDown"))
    getattr(myWS, 'import')(rooDataHist, RooFit.Rename("data_obs"))
    myWS.Print()
    outputRootFile = currentDir + '/Rootfiles/workspace_' + outputName + '.root'
    myWS.writeToFile(outputRootFile, True)
    print ' |----> Workspace created in root file:\n', outputRootFile
    '''
	c1 = TCanvas('c1', 'c1',  10, 10, 750, 500 )
#	c1.SetLogy()
	xframe = myWS.var("massAve").frame()
	signalPdf.plotOn( xframe )
	xframe.Draw()
	c1.SaveAs('test.png')
	del c1
	'''
    ############################################################################################

    ######################### write a datacard

    dataCardName = currentDir + '/Datacards/datacard_' + outputName + '.txt'
    datacard = open(dataCardName, 'w')
    datacard.write('imax 1\n')
    datacard.write('jmax 1\n')
    datacard.write('kmax *\n')
    datacard.write('---------------\n')
    if args.jesUnc or args.jerUnc or args.lumiUnc or args.bkgUnc or args.unc:
        datacard.write('shapes * * ' + outputRootFile +
                       ' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n')
    else:
        datacard.write("shapes * * " + outputRootFile + " myWS:$PROCESS \n")
    datacard.write('---------------\n')
    datacard.write('bin ' + signalSample + '\n')
    datacard.write('observation -1\n')
    datacard.write('------------------------------\n')
    datacard.write('bin          ' + signalSample + '          ' +
                   signalSample + '\n')
    datacard.write('process      signal     background\n')
    datacard.write('process      0          1\n')
    #datacard.write('rate         -1         -1\n')
    datacard.write('rate         ' + str(sigAcc) + '         ' + str(bkgAcc) +
                   '\n')
    datacard.write('------------------------------\n')
    if args.lumiUnc:
        datacard.write('lumi  lnN    %f         -\n' % (lumiValue))
    if args.puUnc: datacard.write('pu  lnN    %f         -\n' % (puValue))
    if args.jesUnc: datacard.write('JES  shape   1          -\n')
    if args.jerUnc: datacard.write('JER  shape   1          -\n')
    #flat parameters --- flat prior
    #if args.bkgUnc: datacard.write('BkgUnc  shape   -	   '+str( round( 1/ (args.bkgUncValue/34.1), 2 ) )+'\n')
    if args.bkgUnc: datacard.write('BkgUnc  shape   -	   1 \n')
    #NcombineUnc = ( 1 / TMath.Sqrt( args.bkgUncValue / 100. ) ) - 1
    #datacard.write('background_norm  gmN '+str(int(round(NcombineUnc)))+'  -  '+str( round(bkgAcc/NcombineUnc,2) )+'\n')
    #datacard.write('p1  flatParam\n')
    datacard.write('BkgStatUnc  shape   -	   1 \n')
    datacard.close()
    print ' |----> Datacard created:\n', dataCardName
    ############################################################################################

    ########## Theta
    if args.theta:
        print ' |----> Creating Theta file\n', outputFileTheta
        outFile = TFile(outputFileTheta, 'update')
        tmpName = 'rpvstopjj' + str(signalMass)
        hSignal.SetName('massAve__' + tmpName)
        hSignal.Write()
        hSigSyst['JESDown'].SetName('massAve__' + tmpName + '__jes__down')
        hSigSyst['JESDown'].Write()
        hSigSyst['JESUp'].SetName('massAve__' + tmpName + '__jes__up')
        hSigSyst['JESUp'].Write()
        hSigSyst['JERDown'].SetName('massAve__' + tmpName + '__jer__down')
        hSigSyst['JERDown'].Write()
        hSigSyst['JERUp'].SetName('massAve__' + tmpName + '__jer__up')
        hSigSyst['JERUp'].Write()
        if (signalMass == 100):  #or (signalMass == 170):
            hBkg.SetName('massAve__background')
            hBkg.Write()
            hBkgSyst['BkgUncDown'].SetName('massAve__background__unc__down')
            hBkgSyst['BkgUncDown'].Write()
            hBkgSyst['BkgUncUp'].SetName('massAve__background__unc__up')
            hBkgSyst['BkgUncUp'].Write()
            hData.SetName('massAve__DATA')
            hData.Write()
        outFile.Close()
Ejemplo n.º 14
0
def main(options,args):

    from ROOT import gSystem, gROOT, gStyle
    gROOT.SetBatch()
    gSystem.Load("libRooFitCore")

    if options.doWebPage:
        from lip.Tools.rootutils import loadToolsLib, apply_modifs
        loadToolsLib()
    
    from ROOT import TFile, RooFit, RooArgSet, RooDataHist, RooKeysPdf, RooHistPdf, TCanvas, TLegend, TLatex, TArrow, TPaveText, RooAddPdf, RooArgList
    from ROOT import kWhite, kBlue, kOpenSquare
    if options.doWebPage:
        from ROOT import HtmlHelper, HtmlTag, HtmlTable, HtmlPlot

    rootglobestyle.setTDRStyle()
    gStyle.SetMarkerSize(1.5)
    gStyle.SetTitleYOffset(1.5)
    
    gStyle.SetPadLeftMargin(0.16)
    gStyle.SetPadRightMargin(0.05)
    gStyle.SetPadTopMargin(0.05)
    gStyle.SetPadBottomMargin(0.13)
    
    gStyle.SetLabelFont(42,"XYZ")
    gStyle.SetLabelOffset(0.007, "XYZ")
    gStyle.SetLabelSize(0.05,"XYZ")
    
    gStyle.SetTitleSize(0.06,"XYZ")
    gStyle.SetTitleXOffset(0.9)
    gStyle.SetTitleYOffset(1.24)
    gStyle.SetTitleFont(42,"XYZ")
    
    ##
    ## Read files
    ##
    options.outdir = "%s_m%1.0f" % ( options.outdir, options.mH  )
    if options.fp:
        options.outdir += "_fp"

    ncat=options.ncat
    cats=options.cats
    if cats is "":
        categories =[  "_cat%d" % i for i in range(0,ncat) ]
    else:
        categories =[  "_cat%s" % i for i in cats.split(",") ]
    
    if options.mva:
        clables = { "_cat0" : ("MVA > 0.89",""),
                    "_cat1" : ("0.74 #leq MVA","MVA < 0.89"),
                    "_cat2" : ("0.545 #leq MVA","MVA < 0.74"),
                    "_cat3" : ("0.05 #leq MVA","MVA < 0.545"),
                    "_cat4" : ("Di-jet","Tagged"),
                    "_cat5" : ("Di-jet","Tagged"),
                    "_combcat" : ("All Classes","Combined")
                    }
    else:
        clables = { "_cat0" : ("max(|#eta|<1.5","min(R_{9})>0.94"),
                    "_cat1" : ("max(|#eta|<1.5","min(R_{9})<0.94"),
                    "_cat2" : ("max(|#eta|>1.5","min(R_{9})>0.94"),
                    "_cat3" : ("max(|#eta|>1.5","min(R_{9})<0.94"),
                    "_cat4" : ("Di-jet","Tagged"),
                    "_cat5" : ("Di-jet","Tagged"),
                    "_combcat" : ("All Classes","Combined")
                    }
    helper = Helper()

    fin = TFile.Open(options.infile)
    helper.files.append(fin)
    ws = fin.Get("cms_hgg_workspace")
    mass = ws.var("CMS_hgg_mass")
    mass.SetTitle("m_{#gamma#gamma}");
    mass.setUnit("GeV");
    mass.setRange(100.,150.)
    mass.setBins(100,"plot")
    mass.setBins(5000)

    print ws
    
    aset = RooArgSet(mass)

    helper.objs.append( mass )
    helper.objs.append( aset )

    fitopt = ( RooFit.Minimizer("Minuit2", ""), RooFit.Minos(False), RooFit.SumW2Error(False), RooFit.NumCPU(8) )
        
    if not options.binned and not options.refit:
        finpdf =  TFile.Open(options.infilepdf)
        helper.files.append(finpdf)
        wspdf = finpdf.Get("wsig")
    else:
        wspdf = ws
    
    for c in categories:
        processes = [ "ggh", "vbf", "wzh" ]
        if options.fp:
            processes = [ "vbf", "wzh" ]
        ### elif clables[c][0] == "Di-jet":
        ###     processes = [ "vbf", "ggh" ]
        
        dsname = "sig_mass_m%1.0f%s" % (options.mH,c)
        print dsname
        print ws
        ds = ws.data( "sig_%s_mass_m%1.0f%s" % (processes[0],options.mH,c)  ).Clone(dsname)
        for proc in processes[1:]:
            ds.append( ws.data( "sig_%s_mass_m%1.0f%s" % (proc,options.mH,c)  ) )
        helper.dsets.append( ds )


        if options.binned:
            binned_ds = RooDataHist( "binned_%s" % dsname,"binned_%s" % dsname,aset, ds)
            pdf = RooKeysPdf( "pdf_%s_%s" % (dsname, f), "pdf_%s" % dsname, mass,  ds )
            plot_pdf = RooHistPdf( "pdf_%s" % dsname, "pdf_%s" % dsname, aset,  plot_ds )
            helper.add( binned_ds,    binned_ds.GetName()  )
        else:
            if options.refit:
                if options.refitall and clables[c][0] != "Di-jet":
                    rpdfs = []
                    for proc in processes:
                        for ngaus in range(1,4):
                            pp = build_pdf(ws,"%s_%s" % (c,proc),ngaus,ngaus==3 )
                            pp.fitTo( ws.data( "sig_%s_mass_m%1.0f%s" % (proc,options.mH,c)), RooFit.Strategy(0), *fitopt )
                        rpdfs.append(pp)
                    pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c, RooArgList(*tuple(rpdfs) ))
                else:
                    if options.refitall and clables[c][0] == "Di-jet":
                        for ngaus in range(1,5):
                            pdf = build_pdf(ws,c,ngaus,ngaus==5)
                            pdf.fitTo(ds, RooFit.Strategy(0), *fitopt )
                    else:
                        for ngaus in range(1,4):
                            pdf = build_pdf(ws,c,ngaus,ngaus==3)
                            pdf.fitTo(ds, RooFit.Strategy(0), *fitopt )
            else:
                pdfs = (wspdf.pdf( "hggpdfrel%s_%s" % (c, p)) for p in processes )
                pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c, RooArgList(*pdfs ))
            helper.add(pdf,pdf.GetName())
            plot_pdf = pdf.Clone("pdf_%s" % dsname)

        plot_ds = RooDataHist( "plot_%s" % dsname,"plot_%s" % dsname, aset, "plot")
        plot_ds.add( ds )

        cdf = pdf.createCdf(aset)
        hmin, hmax, hm = get_FWHM( mass, pdf, cdf, options.mH-10., options.mH+10. )
        wmin, wmax = get_eff_sigma( mass, pdf, cdf, options.mH-10., options.mH+10. )
        ### hmin, hmax, hm = get_FWHM( points )
        
        helper.add( plot_ds,      plot_ds.GetName()    )
        helper.add( plot_pdf,     plot_pdf.GetName()   )
        helper.add( (wmin,wmax),  "eff_sigma%s" % c    )
        helper.add( (hmin, hmax, hm),  "FWHM%s" % c    )
        helper.add( ds.sumEntries(), "sumEntries%s" %c ) # signal model integral

        # data integral for PAS tables
        data = ws.data( "data_mass%s"%c)
        helper.add( data.sumEntries("CMS_hgg_mass>=%1.4f && CMS_hgg_mass<=%1.4f"%(options.mH-10.,options.mH+10.)),"data_sumEntries%s"%c)

        
        del cdf
        del pdf
    

    dsname = "sig_mass_m%1.0f_combcat" % options.mH
    print dsname
    combined_ds = helper.dsets[0].Clone(dsname)
    for d in helper.dsets[1:]:
        combined_ds.append(d)
    
    if options.binned:
        binned_ds = RooDataHist( "binned_%s" % dsname,"binned_%s" % dsname,aset, combined_ds)
        pdf = RooKeysPdf( "pdf_%s" % (dsname), "pdf_%s" % dsname, mass,  combined_ds )
        plot_pdf = RooHistPdf( "pdf_%s" % dsname, "pdf_%s" % dsname, aset,  plot_ds )
        helper.add( binned_ds, binned_ds.GetName()  )
    else:
        #### pdf = build_pdf(ws,"_combcat")
        #### pdf.fitTo(combined_ds, RooFit.Strategy(0), *fitopt )
        #### plot_pdf = pdf.Clone( "pdf_%s" % dsname )
        pdf = RooAddPdf(  "pdf_%s" % dsname,  "pdf_%s" % dsname, RooArgList( *(helper.histos["hggpdfrel%s" % c] for c in categories) ) )
        plot_pdf = pdf
        
    cdf = pdf.createCdf(aset)
    
    plot_ds = RooDataHist( "plot_%s" % dsname,"plot_%s" % dsname, aset, "plot")
    plot_ds.add( combined_ds )
      
    wmin, wmax = get_eff_sigma( mass, pdf, cdf, options.mH-10., options.mH+10. )
    hmin, hmax, hm = get_FWHM( mass, pdf, cdf, options.mH-10., options.mH+10. )
    
    helper.add( plot_ds, plot_ds.GetName()  )
    helper.add( plot_pdf, plot_pdf.GetName()  )
    helper.add( (wmin,wmax), "eff_sigma_combcat"  )
    helper.add( (hmin, hmax, hm),  "FWHM_combcat"  )
    helper.add( plot_ds.sumEntries(), "sumEntries_combcat"  )
    
    mass.setRange("higgsrange",options.mH-25.,options.mH+15.);
    
    del cdf
    del pdf
    del helper.dsets
    
    ### label = TLatex(0.1812081,0.8618881,"#scale[0.8]{#splitline{CMS preliminary}{Simulation}}")
    label = TLatex(0.7,0.86,"#scale[0.65]{#splitline{CMS preliminary}{Simulation}}")
    label.SetNDC(1)
    
    ## 
    ## Make web page with plots
    ##
    if options.doWebPage:
        hth = HtmlHelper(options.outdir)
        hth.navbar().cell( HtmlTag("a") ).firstChild().txt("..").set("href","../?C=M;O=D")
        hth.navbar().cell( HtmlTag("a") ).firstChild().txt("home").set("href","./")
    
        tab = hth.body().add( HtmlTable() )
    
    ip = 0
    for c in ["_combcat"]+categories:
    ### for c in categories:
        if options.doWebPage and ip % 4 == 0:
            row = tab.row()
        ip = ip + 1

        dsname = "sig_mass_m%1.0f%s" % (options.mH,c)
        canv = TCanvas(dsname,dsname,600,600)
        helper.objs.append(canv)
        
        ### leg = TLegend(0.4345638,0.6835664,0.9362416,0.9178322)
        leg = TLegend(0.2,0.96,0.5,0.55)
        #apply_modifs( leg, [("SetLineColor",kWhite),("SetFillColor",kWhite),("SetFillStyle",0),("SetLineStyle",0)] )
        
        hplotcompint = mass.frame(RooFit.Bins(250),RooFit.Range("higgsrange"))
        helper.objs.append(hplotcompint)
        helper.objs.append(leg)
        
        plot_ds  =helper.histos["plot_%s" % dsname ]  
        plot_pdf =helper.histos["pdf_%s" % dsname ]  
        wmin,wmax = helper.histos["eff_sigma%s" % c ]
        hmin, hmax, hm = helper.histos["FWHM%s" % c ]
        print hmin, hmax, hm
        
        style = ( RooFit.LineColor(kBlue), RooFit.LineWidth(2), RooFit.FillStyle(0) )
        style_seff = (  RooFit.LineWidth(2), RooFit.FillStyle(1001), RooFit.VLines(), RooFit.LineColor(15), )
        style_ds = ( RooFit.MarkerStyle(kOpenSquare), )
                  
        plot_ds.plotOn(hplotcompint,RooFit.Invisible())
        
        plot_pdf.plotOn(hplotcompint,RooFit.NormRange("higgsrange"),RooFit.Range(wmin,wmax), RooFit.FillColor(19),
                        RooFit.DrawOption("F"), *style_seff)
        seffleg = hplotcompint.getObject(int(hplotcompint.numItems()-1))
        plot_pdf.plotOn(hplotcompint,RooFit.NormRange("higgsrange"),RooFit.Range(wmin,wmax), RooFit.LineColor(15), *style_seff)

        plot_pdf.plotOn(hplotcompint,RooFit.NormRange("higgsrange"),RooFit.Range("higgsrange"),*style)
        pdfleg = hplotcompint.getObject(int(hplotcompint.numItems()-1))

        plot_ds.plotOn(hplotcompint,*style_ds)
        pointsleg = hplotcompint.getObject(int(hplotcompint.numItems()-1))
        
        iob = int( hplotcompint.numItems() - 1 )
        leg.AddEntry( pointsleg,  "Simulation", "pe" )  
        leg.AddEntry( pdfleg,  "Parametric model", "l" )  
        leg.AddEntry( seffleg, "#sigma_{eff} = %1.2f GeV " % ( 0.5*(wmax-wmin) ), "fl" )  

        clabel = TLatex(0.74,0.65,"#scale[0.65]{#splitline{%s}{%s}}" % clables[c])
        clabel.SetNDC(1)
        helper.objs.append(clabel)

        hm = hplotcompint.GetMaximum()*0.5*0.9
        ### hm = pdfleg.GetMaximum()*0.5
        fwhmarrow = TArrow(hmin,hm,hmax,hm)
        fwhmarrow.SetArrowSize(0.03)
        helper.objs.append(fwhmarrow)
        fwhmlabel = TPaveText(0.20,0.58,0.56,0.48,"brNDC")
        fwhmlabel.SetFillStyle(0)
        fwhmlabel.SetLineColor(kWhite)
        reducedFWHM = (hmax-hmin)/2.3548200
        fwhmlabel.AddText("FWHM/2.35 = %1.2f GeV" % reducedFWHM)
        helper.objs.append(fwhmlabel)

        hplotcompint.SetTitle("");
        hplotcompint.GetXaxis().SetNoExponent(True);
        hplotcompint.GetXaxis().SetTitle("m_{#gamma#gamma} (GeV)");
        hplotcompint.GetXaxis().SetNdivisions(509);
        ## hplotcompint.GetYaxis().SetTitle("A.U.");
        ## hplotcompint.GetYaxis().SetRangeUser(0.,hplotcompint.GetMaximum()*1.4);
        hplotcompint.Draw();    
        leg.Draw("same")
        label.Draw("same")
        clabel.Draw("same")
        fwhmarrow.Draw("<>")
        fwhmlabel.Draw("same")
        
        plot_ds.sumEntries()

        
        if options.doWebPage:
            hpl = HtmlPlot(canv,False,"",True,True,True)
            hpl.caption("<i>%s</i>" % canv.GetTitle())
            row.cell( hpl )
        else:
            if os.path.isdir(options.outdir) is False:
                os.mkdir(options.outdir)
            for ext in "C","png","pdf":
                canv.SaveAs( os.path.join(options.outdir,"%s.%s" % (canv.GetName(), ext)) )
        
        if "comb" in c:
            ip = 0
            
    if options.doWebPage:
        print "Creating pages..."
        hth.dump()
        
    for f in helper.files:
        f.Close()
    gROOT.Reset()

    from pprint import pprint
    pprint(helper)
 
    print 'Summary statistics per event class'
    print 'Cat\tSignal\t\tData/GeV (in %3.1f+/-10)\tsigEff\tFWHM/2.35'%options.mH
    sigTotal=0.
    dataTotal=0.
    for c in categories:
      sigVal = helper.histos["sumEntries%s"%c]
      datVal = helper.histos["data_sumEntries%s"%c]
      sigTotal+=sigVal
      dataTotal+=datVal
    for c in categories:
      sigVal = helper.histos["sumEntries%s"%c]
      datVal = helper.histos["data_sumEntries%s"%c]
      effSig = 0.5*(helper.histos["eff_sigma%s"%c][1]-helper.histos["eff_sigma%s"%c][0])
      fwhm = (helper.histos["FWHM%s"%c][1]-helper.histos["FWHM%s"%c][0]) / 2.3548200
      print c, '\t%3.1f (%3.1f%%)\t%3.1f (%3.1f%%)\t\t\t%2.2f\t%2.2f'%(sigVal,100.*sigVal/sigTotal,datVal/(10.+10.),100.*datVal/dataTotal,effSig,fwhm)

    print "Done."