var_name = pars_mWW.var[0]
other_var = pars_mWW.var[1]
compPdfs = []
for comp in components:
    compPdf = fitter_mWW.ws.pdf(comp)
    getattr(combinedWS, 'import')(compPdf)
    newPdf = combinedWS.pdf(comp)
    newPdf.SetName('%s_%s' % (comp, var_name))
    norm = combinedWS.function('f_%s_norm' % comp)
    combinedWS.factory('PROD::%s(%s_%s, %s)' % (comp, comp, other_var,
                                                newPdf.GetName()))
    compPdfs.append(combinedWS.factory('RooExtendPdf::%s_extended(%s, %s)' %\
                                           (comp, comp, norm.GetName())))

combinedWS.defineSet('obsSet', '%s,%s' % (other_var, var_name))

if opts.sigInject:
    combinedWS.var('r_signal').setVal(opts.sigInject)
combinedWS.var('r_signal').setError(0.1)
combinedWS.var('r_signal').setRange(-3., 9.)
combinedWS.var('r_signal').setConstant(False)

compNames = [ c.GetName() for c in compPdfs ]
compList = RooArgList(combinedWS.argSet(','.join(compNames)))
getattr(combinedWS, 'import')(RooAddPdf('total', 'total', compList))
combinedPdf = combinedWS.pdf('total')
genPars = combinedPdf.getParameters(combinedWS.set('obsSet'))
combinedWS.defineSet('params', genPars)

if opts.toy:
Esempio n. 2
0
nullPars = pars.snapshot()
nullPars.assignValueOnly(parsNull)

mc = RooStats.ModelConfig('mc')
mc.SetWorkspace(ws)
mc.SetPdf(simPdf)
mc.SetObservables(obs)
mc.SetParametersOfInterest(poi)
mc.SetNuisanceParameters(nuis)

plc = RooStats.ProfileLikelihoodCalculator(data, mc)
plc.SetConfidenceLevel(0.68)

NullSnapshotName = 'null_snapshot'
ws.defineSet('params', pars, False)
ws.saveSnapshot(NullSnapshotName, nullPars, True)
#ws.Print()

ws.loadSnapshot(NullSnapshotName)

nullSet = ws.set('params')
#nullSet.Print('v')
plc.SetNullParameters(nullSet)

htr = plc.GetHypoTest()
signif = htr.Significance()

pars.Print("v")
print "suppression significance:",signif
                   n_epsbins, yedges)
plrPvalHist = TH2D("plrPval", "plrPval", n_massbins, xedges, n_epsbins, yedges)
plrSigHist = TH2D("plrSig", "plrSig", n_massbins, xedges, n_epsbins, yedges)
logplrHist = TH2D("logplr", "logplr", n_massbins, xedges, n_epsbins, yedges)
candRescaledHist = TH1D("candidates_rescaled", "candidates_rescaled", 100, 0,
                        1.0)
candRescaled2DHist = TH2D("candidates_rescaled_2d", "candidates_rescaled_2d",
                          n_massbins, xedges, 100, 0, 1.0)

w = RooWorkspace("w")
w.factory("{0}[0,0.18]".format(massVar))
w.factory("{0}[-100,100]".format(vtxVar))
w.factory("uncP[0,10]")
w.factory("cut[0,1]")

w.defineSet("myVars", "{0},{1}".format(massVar, vtxVar))

dataset = RooDataSet("data", "data", events, w.set("myVars"), "")

w.factory("Gaussian::vtx_model({0},mean[-50,50],sigma[0,50])".format(vtxVar))
gauss_pdf = w.pdf("vtx_model")
w.factory(
    "EXPR::gaussExp('exp( ((@0-@1)<@3)*(-0.5*(@0-@1)^2/@2^2) + ((@0-@1)>=@3)*(-0.5*@3^2/@2^2-(@0-@1-@3)/@4))',{0},gauss_mean[0,-20,20],gauss_sigma[5,1,50],exp_breakpoint[10,0,50],exp_length[3,0.5,20])"
    .format(vtxVar))
gaussexp_pdf = w.pdf("gaussExp")
w.defineSet("obs_1d", vtxVar)
obs = w.set("obs_1d")
vtxZRefitUnc = w.var(vtxVar)
vtxZRefitUnc.setBins(200)
gauss_params = gauss_pdf.getParameters(obs)
gaussexp_params = gaussexp_pdf.getParameters(obs)
#!/usr/bin/env python

from ROOT import TFile, TCanvas
from ROOT import RooDataSet, RooWorkspace, RooArgSet

tf = TFile.Open('AnalysisOut.root')
tree = tf.Get('AnalysisTree')

ws = RooWorkspace("w", "w")
observables = RooArgSet()
ws.defineSet("observables", observables)

ws.factory("mass[5050,6000]")
getattr(ws, 'set')("observables").add(ws.var("mass"))
ws.factory("gamgams_pt[0,40e3]")
getattr(ws, 'set')("observables").add(ws.var("gamgams_pt"))

mc = RooDataSet('mc', '', getattr(ws, 'set')('observables'))
data = RooDataSet('data', '', getattr(ws, 'set')('observables'))

for ev in range(tree.GetEntries()):
    tree.GetEntry(ev)
    if tree.itype != -88 and tree.itype != 72 and tree.itype != 82: continue
    if tree.bdtoutput < 0.2: continue
    if tree.B0_MM < ws.var("mass").getMin() or tree.B0_MM > ws.var(
            "mass").getMax():
        continue

    ws.var("mass").setVal(tree.B0_MM)
    ws.var("gamgams_pt").setVal(tree.gamgams_PT)
Esempio n. 5
0
fitfunc = TF1("fitfunc","[0]*exp( ((x-[1])<[3])*(-0.5*(x-[1])^2/[2]^2) + ((x-[1])>=[3])*(-0.5*[3]^2/[2]^2-(x-[1]-[3])/[4]))",-50,50)
fitfunc.SetParName(0,"Amplitude")
fitfunc.SetParName(1,"Mean")
fitfunc.SetParName(2,"Sigma")
fitfunc.SetParName(3,"Tail Z")
fitfunc.SetParName(4,"Tail length")


w = RooWorkspace("w")
w.factory("{0}[0,0.1]".format("uncM"))
w.factory("uncVZ[-100,100]")
w.factory("uncP[0,10]")
w.factory("cut[0,1]")

w.defineSet("myVars","{0},uncVZ".format("uncM"))

events = infile.Get("cut")
#eventsrad = radfile.Get("ntuple")
eventsprompt = promptfile.Get("cut")
dataset = RooDataSet("data","data",events,w.set("myVars"),"")

w.factory("Gaussian::vtx_model(uncVZ,mean[-50,50],sigma[0,50])")
gauss_pdf = w.pdf("vtx_model")
w.factory("EXPR::gaussExp('exp( ((@0-@1)<@3)*(-0.5*(@0-@1)^2/@2^2) + ((@0-@1)>=@3)*(-0.5*@3^2/@2^2-(@0-@1-@3)/@4))',uncVZ,gauss_mean[-5,-20,20],gauss_sigma[5,1,50],exp_breakpoint[10,0,50],exp_length[3,0.5,20])")
gaussexp_pdf = w.pdf("gaussExp")
w.defineSet("obs_1d","uncVZ")
obs=w.set("obs_1d")
uncVZ = w.var("uncVZ")
uncVZ.setBins(200)
gauss_params = gauss_pdf.getParameters(obs)
Esempio n. 6
0
    # dataHist = utils.File2Hist(params.MCDirectory + \
    #                                'RD_mu_HWWMH250_CMSSW525_private.root',
    #                            'dataHist')
    # dataHist.Print()
    # dataHist.Draw('colz')
    # gPad.Update()
    # gPad.WaitPrimitive()

    theWS = RooWorkspace()
    theWS.factory('%s[%f,%f]' % (params.var[0], 
                                 params.varRanges[params.var[0]][1], 
                                 params.varRanges[params.var[0]][2]))
    theWS.factory('%s[%f,%f]' % (params.var[1], 
                                 params.varRanges[params.var[1]][1], 
                                 params.varRanges[params.var[1]][2]))
    theWS.defineSet('obsSet', ','.join(params.var))

    #theWS.Print()
    # utils.Hist2Pdf(dataHist, "H250SignalHist", theWS)
    #theWS.Print()

    # dataset = utils.File2Dataset(params.MCDirectory + \
    #                                  'RD_mu_HWWMH250_CMSSW525_private.root', 
    #                              "H250SignalData", theWS)
    # dataset.Print()

    print 

    for model in range(10):
        utils.analyticPdf(theWS, params.var[0], model, 'pdf_%i' % model,
                          '%i_%s' % (model,params.var[0]))
Esempio n. 7
0
w.factory("uncM[0,0.1]")
w.factory("uncVZ[-100,100]")
w.factory("uncP[0,10]")
w.factory("bscChisq[-100,100]")
w.factory("minIso[-100,100]")
w.factory("eleFirstHitX[-100,100]")
w.factory("posFirstHitX[-100,100]")
w.factory("eleP[-100,100]")
w.factory("posP[-100,100]")
w.factory("bscPY[-100,100]")
w.factory("bscPX[-100,100]")
w.factory("cut[0,1]")

#uncM = RooRealVar("uncM","uncM",0,0.1)
#uncVZ = RooRealVar("uncVZ","uncVZ",-100,100)
w.defineSet("allVars","uncM,uncVZ,uncP,bscChisq,minIso,eleFirstHitX,posFirstHitX,eleP,posP,bscPY,bscPX")
w.defineSet("myVars","uncM,uncVZ,cut")
myVars = w.set("myVars")
#myVars = RooArgSet(uncM,uncVZ)
#cutVar = w.factory("expr::cutFunc('bscChisq<5&&minIso>0.5&&eleFirstHitX-posFirstHitX<2&&abs(eleP-posP)/(eleP+posP)<0.4&&abs(bscPY)<0.01&&abs(bscPX)<0.01',bscChisq,minIso,eleFirstHitX,posFirstHitX,eleP,posP,bscPY,bscPX)")
#cutVar = w.factory("expr::cutFunc('bscChisq<5&&minIso>0.5',bscChisq,minIso,eleFirstHitX,posFirstHitX,eleP,posP,bscPY,bscPX)")
#cutVar = w.function("cutFunc")
w.Print()
#cutVar = RooFormulaVar("cut","","bscChisq<5&&minIso>0.5&&eleFirstHitX-posFirstHitX<2&&abs(eleP-posP)/(eleP+posP)<0.4&&abs(bscPY)<0.01&&abs(bscPX)<0.01",RooArgList(
#dataset = RooDataSet("data","data",events,myVars,cutVar)
#dataset = RooDataSet("data","data",events,w.set("allVars"),cuts)

#RooDataSet.setDefaultStorageType(RooAbsData.Tree)

dataset = RooDataSet("data","data",events,w.set("myVars"),"cut==1")
Esempio n. 8
0
def setup_workspace(config):

  import ROOT
  from ROOT import RooWorkspace, gROOT, gStyle, RooAbsReal, RooMsgService, RooFit
  #from ROOT import RooFit, gROOT, gDirectory, gStyle, gPad, TTree, RooCmdArg,RooBinning
  #from ROOT import RooRealVar, RooMappedCategory, RooCategory, RooFormulaVar, RooAbsData
  #from ROOT import RooBMixDecay, RooMCStudy, RooAddModel, RooEffProd, RooMsgService
  #from ROOT import RooWorkspace, TCanvas, TFile, kFALSE, kTRUE, RooDataSet, TStopwatch
  #from ROOT import RooArgSet, RooArgList, RooRandom, RooMinuit, RooAbsReal, RooDataHist
  #from ROOT import TBrowser, TH2F, TF1, TH1F, RooGenericPdf, RooLinkedList
  from math import sqrt

  gROOT.SetStyle("Plain")
  gStyle.SetPalette(1)
  gStyle.SetOptStat(0)
  gStyle.SetOptFit(0)
  gStyle.SetOptStat(1111)
  gStyle.SetOptFit(10111)
  gStyle.SetOptTitle(1)

  #gROOT.ProcessLine(".L RooGaussianTrunk.cxx+")
  #gROOT.ProcessLine(".L RooCBShapeTrunk.cxx+")
  #gROOT.ProcessLine(".L RooChebychevTrunk.cxx+")
  #from ROOT import RooGaussianTrunk, RooChebychevTrunk, RooCBShapeTrunk

  #RooAbsReal.defaultIntegratorConfig().Print()
  RooAbsReal.defaultIntegratorConfig().setEpsAbs(1e-8)
  RooAbsReal.defaultIntegratorConfig().setEpsRel(1e-8)
  #RooAbsReal.defaultIntegratorConfig().setEpsAbs(1e-6)
  #RooAbsReal.defaultIntegratorConfig().setEpsRel(1e-6)
  RooAbsReal.defaultIntegratorConfig().Print()

  print "Numeric integration set up" #TODO: is the integration acceptable?

  ##This controls the logging output from RooFit
  #RooMsgService.instance().addStream(RooFit.DEBUG,RooFit.Topic(RooFit.Fitting))
  RooMsgService.instance().deleteStream(1)
  #RooMsgService.instance().addStream(RooFit.INFO,RooFit.Topic(RooFit.Generation + RooFit.Minization + RooFit.Plotting + RooFit.Fitting + RooFit.Integration + RooFit.LinkStateMgmt + RooFit.Eval + RooFit.Caching + RooFit.Optimization + RooFit.ObjectHandling + RooFit.InputArguments + RooFit.Tracing + RooFit.Contents + RooFit.DataHandling + RooFit.NumericIntegration))
  RooMsgService.instance().addStream(RooFit.INFO,RooFit.Topic(RooFit.LinkStateMgmt + RooFit.Caching + RooFit.ObjectHandling + RooFit.InputArguments + RooFit.Tracing))
  RooMsgService.instance().Print()


  print "Message service set up"

  w = RooWorkspace("w",False)

  w.factory("RAND[0,1]")
  
  if "norm" not in config["mode"]:
    D0_Mass = w.factory("D0_Mass[1815,1915]") 
  else:
    D0_Mass = w.factory("D0_Mass[1800,1930]")
  D0_Mass.setUnit("MeV")
  D0_Mass.setBins(60)
  
  Del_Mass = w.factory("Del_Mass[139,155]")
  Del_Mass.setUnit("MeV")
  Del_Mass.setBins(60)

  if "norm" not in config["mode"]:
    Dataset = w.factory("DataSet[BDT1,BDT2,BDT3]")
  else:
    Dataset = w.factory("DataSet[Norm]")

  w.factory("classID[Sig=0,Bkg=1]")
  w.factory("BDT_ada[-1,1]")
  w.factory("x1_PIDe[-2,20]")
  w.factory("x2_ProbNNmu[0,1]")

  #D0_Mass.setRange("blinded",1700.,1900.)
  
  if "norm" not in config["mode"]:
    dataCats = ["", "BDT1", "BDT2", "BDT3"]
  else:
    dataCats = ["", "Norm"]

  for data in dataCats:
    for dst_side in ["", "delsig", "delhigh", "dellow"]:
      for d_side in ["", "dsig", "dhigh", "dlow", "dhigh1", "dlow1", "dhigh2", "dlow2"]:
        name = data+dst_side+d_side

        if data == "BDT1":
          Dataset.setRange(name,"BDT1")
        elif data == "BDT2":
          Dataset.setRange(name,"BDT2")
        elif data == "BDT3":
          Dataset.setRange(name,"BDT3")
        elif data == "Norm":
          Dataset.setRange(name,"Norm")

        if dst_side == "delhigh":
          Del_Mass.setRange(name,148.,155.)
        elif dst_side == "delsig":
          Del_Mass.setRange(name,143.,148.)
        elif dst_side == "dellow":
          Del_Mass.setRange(name,139.,143.)

        if d_side == "dhigh2":
          D0_Mass.setRange(name,1910.,1930.)
        elif d_side == "dhigh1":
          D0_Mass.setRange(name,1890.,1910.)
        elif d_side == "dhigh":
          D0_Mass.setRange(name,1890.,1930.)
        elif d_side == "dsig":
          D0_Mass.setRange(name,1840.,1890.)
        elif d_side == "dlow":
          D0_Mass.setRange(name,1800.,1840.)
        elif d_side == "dlow1":
          D0_Mass.setRange(name,1820.,1840.)
        elif d_side == "dlow2":
          D0_Mass.setRange(name,1800.,1820.)

  w.defineSet("args","D0_Mass,Del_Mass,DataSet")
  w.defineSet("argsBasic","D0_Mass,Del_Mass")
  #w.defineSet("argsPreCut","D0_Mass,Del_Mass,RAND,classID,BDT_ada")
  w.defineSet("argsPreCut","D0_Mass,Del_Mass,RAND,classID,BDT_ada,x1_PIDe,x2_ProbNNmu")
  w.defineSet("argsPreCutPiPi","D0_Mass,Del_Mass,RAND")
  w.defineSet("argsPreCutKPi","D0_Mass,Del_Mass,RAND")

  # --- Norm ---
  if config['norm'] is "kpi":
    w.factory("{D0_Mass,Norm_D0M_Min[1815],Norm_D0M_Max[1915]}")
  else:
    w.factory("{D0_Mass,Norm_D0M_Min[1826],Norm_D0M_Max[1920]}")

  w.factory("RooGenericPdf::Norm_D0M_Range('(D0_Mass>Norm_D0M_Min&&D0_Mass<Norm_D0M_Max)',{D0_Mass,Norm_D0M_Min,Norm_D0M_Max})")


  w.factory("RooFormulaVar::Norm_D0M_Sig_Gaus2_Sigma('Norm_D0M_Sig_Gaus1_Sigma+Norm_D0M_Sig_Gaus2_Sigma_Diff',{Norm_D0M_Sig_Gaus1_Sigma[5,0,10],Norm_D0M_Sig_Gaus2_Sigma_Diff[5,0.,10.]})")
  w.factory("RooFormulaVar::Norm_D0M_Sig_Gaus3_Sigma('Norm_D0M_Sig_Gaus1_Sigma+Norm_D0M_Sig_Gaus2_Sigma_Diff+Norm_D0M_Sig_Gaus3_Sigma_Diff',{Norm_D0M_Sig_Gaus1_Sigma,Norm_D0M_Sig_Gaus2_Sigma_Diff,Norm_D0M_Sig_Gaus3_Sigma_Diff[2,0.,20.]})")

  w.factory("RooFormulaVar::Norm_D0M_Sig_Gaus1_Sigma_Scaled('Norm_D0M_Sig_Gaus1_Sigma*Norm_D0M_Sig_Gaus_Sigma_Scale',{Norm_D0M_Sig_Gaus1_Sigma,Norm_D0M_Sig_Gaus_Sigma_Scale[1]})")
  w.factory("RooFormulaVar::Norm_D0M_Sig_Gaus2_Sigma_Scaled('(Norm_D0M_Sig_Gaus1_Sigma+Norm_D0M_Sig_Gaus2_Sigma_Diff)*Norm_D0M_Sig_Gaus_Sigma_Scale',{Norm_D0M_Sig_Gaus1_Sigma,Norm_D0M_Sig_Gaus2_Sigma_Diff,Norm_D0M_Sig_Gaus_Sigma_Scale})")
  w.factory("RooFormulaVar::Norm_D0M_Sig_Gaus3_Sigma_Scaled('(Norm_D0M_Sig_Gaus1_Sigma+Norm_D0M_Sig_Gaus2_Sigma_Diff+Norm_D0M_Sig_Gaus3_Sigma_Diff)*Norm_D0M_Sig_Gaus_Sigma_Scale',{Norm_D0M_Sig_Gaus1_Sigma,Norm_D0M_Sig_Gaus2_Sigma_Diff,Norm_D0M_Sig_Gaus3_Sigma_Diff,Norm_D0M_Sig_Gaus_Sigma_Scale})")

  #  D0_Mass Signal
  w.factory("RooCBShape::Norm_D0M_Sig_Gaus1(D0_Mass,Norm_D0M_Sig_Gaus_Mean[1867,1850,1880],Norm_D0M_Sig_Gaus1_Sigma_Scaled,Norm_D0M_Sig_Gaus1_alpha[1.5,0,6],Norm_D0M_Sig_Gaus1_n[2,0,20])")
  #w.factory("RooGaussian::Norm_D0M_Sig_Gaus1(D0_Mass,Norm_D0M_Sig_Gaus_Mean[1867,1850,1880],Norm_D0M_Sig_Gaus1_Sigma_Scaled)")
  w.factory("RooCBShape::Norm_D0M_Sig_Gaus2(D0_Mass,Norm_D0M_Sig_Gaus_Mean,Norm_D0M_Sig_Gaus2_Sigma_Scaled,Norm_D0M_Sig_Gaus2_alpha[1.5,0,6],Norm_D0M_Sig_Gaus2_n[2,0,20])")
  #w.factory("RooGaussian::Norm_D0M_Sig_Gaus2(D0_Mass,Norm_D0M_Sig_Gaus_Mean,Norm_D0M_Sig_Gaus2_Sigma_Scaled)")
  #w.factory("RooGaussian::Norm_D0M_Sig_Gaus3(D0_Mass,Norm_D0M_Sig_Gaus3_Mean[1867,1850,1880],Norm_D0M_Sig_Gaus3_Sigma_Scaled)")
  w.factory("RooGaussian::Norm_D0M_Sig_Gaus3(D0_Mass,Norm_D0M_Sig_Gaus_Mean,Norm_D0M_Sig_Gaus3_Sigma_Scaled)")
  #w.factory("RooCBShape::Norm_D0M_Sig_Gaus3(D0_Mass,Norm_D0M_Sig_Gaus_Mean,Norm_D0M_Sig_Gaus3_Sigma_Scaled,Norm_D0M_Sig_Gaus3_alpha[1.5,0,6],Norm_D0M_Sig_Gaus3_n[0.5,0,20])")
  #w.factory("SUM::Norm_D0M_Sig(Norm_D0M_Sig_Gaus1_Frac[0.4,0,1]*Norm_D0M_Sig_Gaus1,Norm_D0M_Sig_Gaus3_Frac[0.1,0,1]*Norm_D0M_Sig_Gaus3,Norm_D0M_Sig_Gaus2)")
  w.factory("SUM::Norm_D0M_Sig(Norm_D0M_Sig_Gaus1_Frac[0.4,0,1]*Norm_D0M_Sig_Gaus1,Norm_D0M_Sig_Gaus2)")
  #w.factory("PROD::Norm_D0M_Sig(Norm_D0M_Sig_Sum,Norm_D0M_Range)")

  #  D0_Mass MisId
  #w.factory("RooGaussian::Norm_D0M_MisId_Gaus1(D0_Mass,Norm_D0M_MisId_Gaus_Mean[1790,1720,1820],Norm_D0M_Sig_Gaus1_Sigma)")
  #w.factory("RooGaussian::Norm_D0M_MisId_Gaus2(D0_Mass,Norm_D0M_MisId_Gaus_Mean,Norm_D0M_Sig_Gaus2_Sigma)")
  #w.factory("SUM::Norm_D0M_MisId(Norm_D0M_Sig_Gaus1_Frac*Norm_D0M_MisId_Gaus1,Norm_D0M_MisId_Gaus2)")
  ##w.factory("PROD::Norm_D0M_MisId(Norm_D0M_MisId_Sum,Norm_D0M_Range)")
  ##w.factory("RooExponential::Norm_D0M_MisId_Exp(D0_Mass,Norm_D0M_MisId_Exp_Const[-0.15,-.3,-.1])")
  ##w.factory("PROD::Norm_D0M_MisId(Norm_D0M_MisId_Exp,Norm_D0M_Range)")

  #  D0_Mass Combinatorical
  w.factory('{Norm_D0M_Bkg_Cheby_1[-0.5,-1,1]}')
  #w.factory("RooChebychev::Norm_D0M_Bkg_Poly(D0_Mass,{Norm_D0M_Bkg_Cheby_1[-0.25,-1.5,1]})")
  #w.factory("PROD::Norm_D0M_Bkg(Norm_D0M_Bkg_Poly,Norm_D0M_Range)")
  w.factory("RooExponential::Norm_D0M_Bkg(D0_Mass,Norm_D0M_Bkg_Exp_c[-0.0088,-0.05,-0.001])")
  #w.factory("RooChebychev::Norm_D0M_Bkg(D0_Mass,{Norm_D0M_Bkg_Cheby_1})")
  #w.factory("RooChebychev::Norm_D0M_Bkg(D0_Mass,{Norm_D0M_Bkg_Cheby_1,Norm_D0M_Bkg_Cheby_2[-0.1,-0.7,1]})")

  
  w.factory("RooFormulaVar::Norm_DelM_Sig_Gaus_Mean_Shifted('Norm_DelM_Sig_Gaus_Mean+Norm_DelM_Sig_Gaus_Mean_Shift',{Norm_DelM_Sig_Gaus_Mean[145.5,145,146],Norm_DelM_Sig_Gaus_Mean_Shift[0]})")
  w.factory("RooFormulaVar::Norm_DelM_Sig_Gaus3_Mean_Shifted('Norm_DelM_Sig_Gaus3_Mean+Norm_DelM_Sig_Gaus_Mean_Shift',{Norm_DelM_Sig_Gaus3_Mean[145.7,144,155],Norm_DelM_Sig_Gaus_Mean_Shift})")

  w.factory("RooFormulaVar::Norm_DelM_Sig_Gaus2_Sigma('Norm_DelM_Sig_Gaus1_Sigma+Norm_DelM_Sig_Gaus2_Sigma_Diff',{Norm_DelM_Sig_Gaus1_Sigma[.4,0,1],Norm_DelM_Sig_Gaus2_Sigma_Diff[0.4,0.,1.]})")
  w.factory("RooFormulaVar::Norm_DelM_Sig_Gaus3_Sigma('Norm_DelM_Sig_Gaus1_Sigma+Norm_DelM_Sig_Gaus2_Sigma_Diff+Norm_DelM_Sig_Gaus3_Sigma_Diff',{Norm_DelM_Sig_Gaus1_Sigma,Norm_DelM_Sig_Gaus2_Sigma_Diff,Norm_DelM_Sig_Gaus3_Sigma_Diff[0.4,0.,3.]})")

  #  Del_Mass signal
  w.factory("{Norm_DelM_Sig_Gaus3_Frac[0.01,0,.7]}")
  #w.factory("RooCBShape::Norm_DelM_Sig_Gaus1(Del_Mass,Norm_DelM_Sig_Gaus_Mean_Shifted,Norm_DelM_Sig_Gaus1_Sigma[.4,0,1],Norm_DelM_Sig_CB1_alpha[1.5,0,6], BDT%(n)i_D0M_Sig_CB1_n[2,0,10] )")
  w.factory("RooGaussian::Norm_DelM_Sig_Gaus1(Del_Mass,Norm_DelM_Sig_Gaus_Mean_Shifted,Norm_DelM_Sig_Gaus1_Sigma)")
  w.factory("RooGaussian::Norm_DelM_Sig_Gaus2(Del_Mass,Norm_DelM_Sig_Gaus_Mean_Shifted,Norm_DelM_Sig_Gaus2_Sigma)")
  w.factory("RooGaussian::Norm_DelM_Sig_Gaus3(Del_Mass,Norm_DelM_Sig_Gaus3_Mean_Shifted,Norm_DelM_Sig_Gaus3_Sigma)")
  w.factory("SUM::Norm_DelM_Sig(Norm_DelM_Sig_Gaus1_Frac[0.1,0,.7]*Norm_DelM_Sig_Gaus1,Norm_DelM_Sig_Gaus3_Frac*Norm_DelM_Sig_Gaus3,Norm_DelM_Sig_Gaus2)")
  #w.factory("SUM::Norm_DelM_Sig(Norm_DelM_Sig_Gaus1_Frac[0.1,0,.7]*Norm_DelM_Sig_Gaus1,Norm_DelM_Sig_Gaus2)")
  
  # mis recod
  w.factory("RooGaussian::Norm_DelM_MisRecod_Gaus1(Del_Mass,Norm_DelM_MisRecod_Gaus_Mean[145.5,145,146],Norm_DelM_MisRecod_Gaus_Sigma1[1.2,0,5] )")


  w.factory("RooChebychev::Norm_D0M_MisRecod(D0_Mass,{Norm_D0M_MisRecod_Cheby_1[0,-1,1]})")

  #  Del_Mass Combinatorical
  #w.factory("RooDstD0BG::Norm_DelM_Bkg(Del_Mass,Norm_DelM_Bkg_m0[139.5,137.5,140.5],Norm_DelM_Bkg_c[40,7,350],Norm_DelM_Bkg_a[-20,-100,-1],Norm_DelM_Bkg_b[0.4,-1,2])")
  w.factory("RooDstD0BG::Norm_DelM_Bkg(Del_Mass,Norm_DelM_Bkg_m0[139.5,137.5,140.5],Norm_DelM_Bkg_m0,Norm_DelM_Bkg_a[-20,-100,-1],Norm_DelM_Bkg_b[0.4,-1,2])")
  w.factory("{Norm_DelM_Bkg_c[40,7,350]}")

  #  Del_Mass signal
  w.factory("RooGaussian::Norm_DelM_MisId(Del_Mass,Norm_DelM_Sig_Gaus_Mean,Norm_DelM_MisId_Gaus_Sigma1[1,0,3])")

  w.factory("PROD::Norm_Sig(Norm_DelM_Sig,Norm_D0M_Sig)")
  w.factory("PROD::Norm_Comb(Norm_DelM_Bkg,Norm_D0M_Bkg)")
  w.factory("PROD::Norm_MisRecod(Norm_DelM_MisRecod_Gaus1,Norm_D0M_MisRecod)")
  #w.factory("PROD::Norm_MisId(Norm_DelM_MisId,Norm_D0M_MisId)")
  #w.factory("PROD::Norm_MisId(Norm_DelM_Sig,Norm_D0M_MisId)")
  #w.factory("PROD::Norm_MisId_Prompt(Norm_DelM_Bkg,Norm_D0M_MisId)")
  w.factory("PROD::Norm_Prompt(Norm_DelM_Bkg,Norm_D0M_Sig)")

  w.factory("{Norm_N_Sig[65000,20000,500000],Norm_N_MisId[1300,100,3000],Norm_N_MisRecod[5000,100,30000],Norm_N_MisId_Prompt[500,10,1000]}")


  # --- eMu ---

  #w.factory("EMu_N_Sig[1000,0,100000]")
  for n in (1,2,3):
    w.factory("BDT%(n)i_Sig_Eff[0.3,0,1]"%({"n":n}))

  w.factory("EMu_Eff[%f]"%(config['emuEff']))
  w.factory("EMu_BR[1e-8,-1e-7,1e-7]")

  if config['norm'] is 'pipi':
    w.factory("Norm_Eff[%f]"%(config['pipiEff']))
    w.factory("Norm_BR[%f]"%(config['pipiBR'][0]))
    w.obj("Norm_BR").setError(config['pipiBR'][1])
  elif config['norm'] is 'kpi':
    w.factory("Norm_Eff[%f]"%(config['kpiEff']))
    w.factory("Norm_BR[%f]"%(config['kpiBR'][0]))
    w.obj("Norm_BR").setError(config['kpiBR'][1])

    w.factory("RooFormulaVar::N_PiPi('Norm_N_Sig*(%f)',{Norm_N_Sig})"%(config['pipiAsEmuEff']*config['pipiBR'][0]/config['kpiBR'][0]/config['kpiEff'],))

  w.factory("RooFormulaVar::EMu_N_Sig('abs(Norm_N_Sig*((EMu_BR*EMu_Eff)/(Norm_BR*Norm_Eff)))',{Norm_BR,EMu_BR,EMu_Eff,Norm_Eff,Norm_N_Sig})")

  w.factory("{EMu_D0M_Min[1815],EMu_D0M_Max[1915]}")

  w.factory("RooGaussian::Norm_Constraint(Norm_N_Sig,%f,%f)"%(config["normEvents"][0],config["normEvents"][1]))

  #  D0_Mass Combinatorical
  w.factory("RooGenericPdf::BDT_D0M_Blind('(D0_Mass<1700||D0_Mass>1900)',{D0_Mass})")
  w.factory("RooGenericPdf::BDT_D0M_Range('(D0_Mass>EMu_D0M_Min&&D0_Mass<EMu_D0M_Max)',{D0_Mass,EMu_D0M_Min,EMu_D0M_Max})")
  w.factory("RooChebychev::BDT_D0M_Bkg(D0_Mass,{BDT_D0M_Bkg_Cheby_1[-0.7,-3.0,0.0],BDT_D0M_Bkg_Cheby_2[-0.2,-3.0,0.0]})")
  w.factory("PROD::BDT_D0M_Bkg_Blind(BDT_D0M_Bkg,BDT_D0M_Blind)")

  #  Del_Mass Combinatorical
  w.factory("RooDstD0BG::BDT_DelM_Bkg(Del_Mass,BDT_DelM_Bkg_m0[139.5,137.5,140.5],BDT_DelM_Bkg_c[40,7,350],BDT_DelM_Bkg_a[-20,-100,-1],BDT_DelM_Bkg_b[-0.1,-2,1])"%({"n":n}))

  w.factory("{BDT_D0M_Sig_CB1_alphaleft[0.3,0,1]}")
  w.factory("{BDT_D0M_Sig_CB2_alpharight[-0.5,-5,0]}")
  for n in (1,2,3):
    if n is not 3:
      w.factory("RooFormulaVar::BDT%(n)i_N_Sig('EMu_N_Sig*BDT%(n)i_Sig_Eff',{EMu_N_Sig,BDT%(n)i_Sig_Eff})"%({"n":n}))
    else:
      w.factory("RooFormulaVar::BDT%(n)i_N_Sig('EMu_N_Sig*(1-(BDT1_Sig_Eff+BDT2_Sig_Eff))',{EMu_N_Sig,BDT1_Sig_Eff,BDT2_Sig_Eff})"%({"n":n}))

    #  D0_Mass Signal
    w.factory("{BDT%(n)i_D0M_Sig_CB2_alpharight[-0.5,-5,0],BDT%(n)i_D0M_Sig_CB1_alphaleft[0.3,0,1]}"%({"n":n}))
    
    w.factory("RooCBShape:BDT%(n)i_D0M_Sig_CB1(D0_Mass, BDT%(n)i_D0M_Sig_CB_Mean[1850,1750,1900], BDT%(n)i_D0M_Sig_CB1_Sigma[10,1,30], BDT_D0M_Sig_CB1_alphaleft, BDT%(n)i_D0M_Sig_CB1_n[2,0,10])"%({"n":n}))
    w.factory("RooCBShape:BDT%(n)i_D0M_Sig_CB2(D0_Mass, BDT%(n)i_D0M_Sig_CB_Mean, BDT%(n)i_D0M_Sig_CB2_Sigma[3,1,30], BDT_D0M_Sig_CB2_alpharight, BDT%(n)i_D0M_Sig_CB2_n[5,0,50])"%({"n":n}))
    w.factory("SUM::BDT%(n)i_D0M_Sig(BDT%(n)i_D0M_Sig_CB1_Frac[0.8,0,1]*BDT%(n)i_D0M_Sig_CB1,BDT%(n)i_D0M_Sig_CB2)"%({"n":n}))

    #  Del_Mass signal
    w.factory("{BDT%(n)i_DelM_Sig_Gaus1_Frac[0.75,0,1]}"%({"n":n}))
    w.factory("RooGaussian::BDT%(n)i_DelM_Sig_Gaus1(Del_Mass,BDT%(n)i_DelM_Sig_Gaus_Mean[145.5,143,148],BDT%(n)i_DelM_Sig_Gaus_Sigma1[1,0,5] )"%({"n":n}))
    w.factory("RooGaussian::BDT%(n)i_DelM_Sig_Gaus2(Del_Mass,BDT%(n)i_DelM_Sig_Gaus_Mean,BDT%(n)i_DelM_Sig_Gaus_Sigma2[.1,0,2] )"%({"n":n}))
    #w.factory("{BDT%(n)i_DelM_Sig_Gaus3_Frac[0.05,0,0.1],BDT%(n)i_DelM_Sig_Gaus_Mean_2[148,143,152],BDT%(n)i_DelM_Sig_Gaus_Sigma3[10,0,20]}"%({"n":n}))
    w.factory("RooGaussian::BDT%(n)i_DelM_Sig_Gaus3(Del_Mass,BDT%(n)i_DelM_Sig_Gaus_Mean_3[148,143,152],BDT%(n)i_DelM_Sig_Gaus_Sigma3[10,0,20] )"%({"n":n}))
    w.factory("SUM::BDT%(n)i_DelM_Sig(BDT%(n)i_DelM_Sig_Gaus3_Frac[0.05,0,0.1]*BDT%(n)i_DelM_Sig_Gaus3,BDT%(n)i_DelM_Sig_Gaus2_Frac[0.2,0,1]*BDT%(n)i_DelM_Sig_Gaus2,BDT%(n)i_DelM_Sig_Gaus1)"%({"n":n}))
    #w.factory("SUM::BDT%(n)i_DelM_Sig(BDT%(n)i_DelM_Sig_Gaus2_Frac[0.2,0,1]*BDT%(n)i_DelM_Sig_Gaus2,BDT%(n)i_DelM_Sig_Gaus1)"%({"n":n}))

    w.factory("PROD::BDT%(n)i_Sig(BDT%(n)i_DelM_Sig,BDT%(n)i_D0M_Sig)"%({"n":n}))
    w.factory("PROD::BDT%(n)i_Comb_Blind(BDT_DelM_Bkg,BDT_D0M_Bkg_Blind)"%({"n":n}))
    w.factory("PROD::BDT%(n)i_Comb(BDT_DelM_Bkg,BDT_D0M_Bkg)"%({"n":n}))

  w.factory("{BDT1_PiPi_Eff[0.5,0,1],BDT2_PiPi_Eff[0.3,0,1]}")
  w.factory("{BDT_D0M_PiPi_CB2_alpharight[-0.5,-5,0],BDT_D0M_PiPi_CB1_alphaleft[0.8,0,3]}")
  for n in (1,2,3):
    if n is not 3:
      w.factory("RooFormulaVar::BDT%(n)i_N_PiPi('N_PiPi*BDT%(n)i_PiPi_Eff',{N_PiPi,BDT%(n)i_PiPi_Eff})"%({"n":n}))
    else:
      w.factory("RooFormulaVar::BDT%(n)i_N_PiPi('N_PiPi*(1-(BDT1_PiPi_Eff+BDT2_PiPi_Eff))',{N_PiPi,BDT1_PiPi_Eff,BDT2_PiPi_Eff})"%({"n":n}))

    #  D0_Mass PiPi
    w.factory("{BDT%(n)i_D0M_PiPi_CB2_alpharight[-0.5,-5,0],BDT%(n)i_D0M_PiPi_CB1_alphaleft[0.8,0,3]}"%({"n":n}))
    w.factory("RooCBShape:BDT%(n)i_D0M_PiPi_CB1(D0_Mass, BDT%(n)i_D0M_PiPi_CB_Mean[1850,1750,1900], BDT%(n)i_D0M_PiPi_CB1_Sigma[10,1,30], BDT_D0M_PiPi_CB1_alphaleft, BDT%(n)i_D0M_PiPi_CB1_n[2,0,10])"%({"n":n}))
    w.factory("RooCBShape:BDT%(n)i_D0M_PiPi_CB2(D0_Mass, BDT%(n)i_D0M_PiPi_CB_Mean, BDT%(n)i_D0M_PiPi_CB2_Sigma[3,1,30], BDT_D0M_PiPi_CB2_alpharight, BDT%(n)i_D0M_PiPi_CB2_n[5,0,50])"%({"n":n}))
    w.factory("SUM::BDT%(n)i_D0M_PiPi(BDT%(n)i_D0M_PiPi_CB1_Frac[0.8,0,1]*BDT%(n)i_D0M_PiPi_CB1,BDT%(n)i_D0M_PiPi_CB2)"%({"n":n}))

    #  Del_Mass signal
    w.factory("{BDT%(n)i_DelM_PiPi_Gaus1_Frac[0.75,0,1]}"%({"n":n}))
    w.factory("RooGaussian::BDT%(n)i_DelM_PiPi_Gaus1(Del_Mass,BDT%(n)i_DelM_PiPi_Gaus_Mean[145.5,143,148],BDT%(n)i_DelM_PiPi_Gaus_Sigma1[1,0,5] )"%({"n":n}))
    w.factory("RooGaussian::BDT%(n)i_DelM_PiPi_Gaus2(Del_Mass,BDT%(n)i_DelM_PiPi_Gaus_Mean_2[145.5,143,148],BDT%(n)i_DelM_PiPi_Gaus_Sigma2[.1,0,2] )"%({"n":n}))
    #w.factory("{BDT%(n)i_DelM_PiPi_Gaus3_Frac[0.05,0,0.1],BDT%(n)i_DelM_PiPi_Gaus_Mean_2[148,143,152],BDT%(n)i_DelM_PiPi_Gaus_Sigma3[10,0,20]}"%({"n":n}))
    w.factory("RooGaussian::BDT%(n)i_DelM_PiPi_Gaus3(Del_Mass,BDT%(n)i_DelM_PiPi_Gaus_Mean_3[148,143,152],BDT%(n)i_DelM_PiPi_Gaus_Sigma3[10,0,20] )"%({"n":n}))
    w.factory("SUM::BDT%(n)i_DelM_PiPi(BDT%(n)i_DelM_PiPi_Gaus3_Frac[0.05,0,0.1]*BDT%(n)i_DelM_PiPi_Gaus3,BDT%(n)i_DelM_PiPi_Gaus2_Frac[0.2,0,1]*BDT%(n)i_DelM_PiPi_Gaus2,BDT%(n)i_DelM_PiPi_Gaus1)"%({"n":n}))
    #w.factory("SUM::BDT%(n)i_DelM_Sig(BDT%(n)i_DelM_PiPi_Gaus2_Frac[0.2,0,1]*BDT%(n)i_DelM_PiPi_Gaus2,BDT%(n)i_DelM_PiPi_Gaus1)"%({"n":n}))


    w.factory("PROD::BDT%(n)i_PiPi(BDT%(n)i_DelM_PiPi,BDT%(n)i_D0M_PiPi)"%({"n":n}))

    #w.factory("SUM::BDT%(n)i_Final_PDF_Blind(BDT%(n)i_N_Sig*BDT%(n)i_Sig,BDT%(n)i_N_Comb[1000,0,10000]*BDT%(n)i_Comb_Blind)"%({"n":n}))
    #w.factory("SUM::BDT%(n)i_Final_PDF(BDT%(n)i_N_Sig*BDT%(n)i_Sig,BDT%(n)i_N_Comb*BDT%(n)i_Comb)"%({"n":n}))

    w.factory("SUM::BDT%(n)i_Final_PDF_Blind(BDT%(n)i_N_Sig*BDT%(n)i_Sig,BDT%(n)i_N_Comb[1000,0,10000]*BDT%(n)i_Comb_Blind,BDT%(n)i_N_PiPi*BDT%(n)i_PiPi)"%({"n":n}))
    w.factory("SUM::BDT%(n)i_Final_PDF(BDT%(n)i_N_Sig*BDT%(n)i_Sig,BDT%(n)i_N_Comb*BDT%(n)i_Comb,BDT%(n)i_N_PiPi*BDT%(n)i_PiPi)"%({"n":n}))

    w.factory("PROD::BDT%(n)i_Final_PDF_Constrained(BDT%(n)i_Final_PDF,Norm_Constraint)"%({"n":n}))




  #w.obj('Norm_D0M_Sig_Gaus1_Frac').setMin(0.0) ; w.obj('Norm_D0M_Sig_Gaus1_Frac').setMax(1.0)
  #w.obj('Norm_D0M_Sig_Gaus1_Frac').setVal(0.429624062534) ; w.obj('Norm_D0M_Sig_Gaus1_Frac').setError(0.0289511133792)
  #w.obj('Norm_D0M_Sig_Gaus1_Frac').setConstant(False)
  #w.obj('Norm_D0M_Sig_Gaus_Mean').setMin(1850.0) ; w.obj('Norm_D0M_Sig_Gaus_Mean').setMax(1880.0)
  #w.obj('Norm_D0M_Sig_Gaus_Mean').setVal(1867.01515277) ; w.obj('Norm_D0M_Sig_Gaus_Mean').setError(0.0296569841856)
  #w.obj('Norm_D0M_Sig_Gaus_Mean').setConstant(False)
  #w.obj('Norm_D0M_Sig_Gaus1_Sigma').setMin(0.0) ; w.obj('Norm_D0M_Sig_Gaus1_Sigma').setMax(10.0)
  #w.obj('Norm_D0M_Sig_Gaus1_Sigma').setVal(6.92118344347) ; w.obj('Norm_D0M_Sig_Gaus1_Sigma').setError(0.117795059995)
  #w.obj('Norm_D0M_Sig_Gaus1_Sigma').setConstant(False)
  #w.obj('Norm_D0M_Sig_Gaus2_Sigma').setMin(5.0) ; w.obj('Norm_D0M_Sig_Gaus2_Sigma').setMax(20.0)
  #w.obj('Norm_D0M_Sig_Gaus2_Sigma').setVal(10.3140938882) ; w.obj('Norm_D0M_Sig_Gaus2_Sigma').setError(0.117955520203)
  #w.obj('Norm_D0M_Sig_Gaus2_Sigma').setConstant(False)
  #w.obj('Norm_DelM_Bkg_a').setMin(-100.0) ; w.obj('Norm_DelM_Bkg_a').setMax(-1.0)
  #w.obj('Norm_DelM_Bkg_a').setVal(-16.1932460031) ; w.obj('Norm_DelM_Bkg_a').setError(0.43302849663)
  #w.obj('Norm_DelM_Bkg_a').setConstant(False)
  #w.obj('Norm_DelM_Bkg_b').setMin(-0.5) ; w.obj('Norm_DelM_Bkg_b').setMax(2.0)
  #w.obj('Norm_DelM_Bkg_b').setVal(0.178920942238) ; w.obj('Norm_DelM_Bkg_b').setError(0.0376477247211)
  #w.obj('Norm_DelM_Bkg_b').setConstant(False)
  #w.obj('Norm_DelM_Bkg_c').setMin(7.0) ; w.obj('Norm_DelM_Bkg_c').setMax(350.0)
  #w.obj('Norm_DelM_Bkg_c').setVal(36.1602832374) ; w.obj('Norm_DelM_Bkg_c').setError(5.19925002062)
  #w.obj('Norm_DelM_Bkg_c').setConstant(False)
  #w.obj('Norm_DelM_Bkg_m0').setMin(137.5) ; w.obj('Norm_DelM_Bkg_m0').setMax(140.5)
  #w.obj('Norm_DelM_Bkg_m0').setVal(139.316358242) ; w.obj('Norm_DelM_Bkg_m0').setError(5.10021351516e-05)
  #w.obj('Norm_DelM_Bkg_m0').setConstant(False)
  #w.obj('Norm_DelM_Sig_Gaus1_Frac').setMin(0.0) ; w.obj('Norm_DelM_Sig_Gaus1_Frac').setMax(1.)
  #w.obj('Norm_DelM_Sig_Gaus1_Frac').setVal(0.279248861884) ; w.obj('Norm_DelM_Sig_Gaus1_Frac').setError(0.0191547718614)
  #w.obj('Norm_DelM_Sig_Gaus1_Frac').setConstant(False)
  #w.obj('Norm_DelM_Sig_Gaus_Mean').setMin(145.0) ; w.obj('Norm_DelM_Sig_Gaus_Mean').setMax(146.0)
  #w.obj('Norm_DelM_Sig_Gaus_Mean').setVal(145.448069656) ; w.obj('Norm_DelM_Sig_Gaus_Mean').setError(0.00294967951486)
  #w.obj('Norm_DelM_Sig_Gaus_Mean').setConstant(False)
  #w.obj('Norm_DelM_Sig_Gaus1_Sigma').setMin(0.0) ; w.obj('Norm_DelM_Sig_Gaus1_Sigma').setMax(1.0)
  #w.obj('Norm_DelM_Sig_Gaus1_Sigma').setVal(0.429900766218) ; w.obj('Norm_DelM_Sig_Gaus1_Sigma').setError(0.0119155696871)
  #w.obj('Norm_DelM_Sig_Gaus1_Sigma').setConstant(False)
  #w.obj('Norm_DelM_Sig_Gaus2_Sigma').setMin(0.1) ; w.obj('Norm_DelM_Sig_Gaus2_Sigma').setMax(2.0)
  #w.obj('Norm_DelM_Sig_Gaus2_Sigma').setVal(0.827483577936) ; w.obj('Norm_DelM_Sig_Gaus2_Sigma').setError(0.00898522299303)
  #w.obj('Norm_DelM_Sig_Gaus2_Sigma').setConstant(False)




  if config['mode'] == 'mc':
    w.factory("SIMUL::Final_PDF(DataSet,BDT1=BDT1_Sig,BDT2=BDT2_Sig,BDT3=BDT3_Sig)")
    #w.obj("Final_PDF").Print("v")
    #w.obj("BDT1_Sig").Print("v")

  elif config['mode'] == 'mcpipi':
    w.factory("SIMUL::Final_PDF(DataSet,BDT1=BDT1_PiPi,BDT2=BDT2_PiPi,BDT3=BDT3_PiPi)")

  elif config['mode'] == 'datapretoy':
    w.factory("SIMUL::Final_PDF(DataSet,BDT1=BDT1_Comb_Blind,BDT2=BDT2_Comb_Blind,BDT3=BDT3_Comb_Blind)")

  elif config['mode'] == 'toy':
    w.factory("SIMUL::Final_PDF(DataSet,Norm=Norm_Final_PDF,BDT1=BDT1_Final_PDF,BDT2=BDT2_Final_PDF,BDT3=BDT3_Final_PDF)")
    w.factory("SIMUL::Final_PDF_Background(DataSet,Norm=Norm_Final_PDF,BDT1=BDT1_Comb,BDT2=BDT2_Comb,BDT3=BDT3_Comb)")
    w.factory("SIMUL::Final_PDF_Constrained(DataSet,BDT1=BDT1_Final_PDF_Constrained,BDT2=BDT2_Final_PDF_Constrained,BDT3=BDT3_Final_PDF_Constrained)")

  elif config['mode'] == 'mcnorm':
    w.factory("SIMUL::Final_PDF(DataSet,Norm=Norm_Sig)")

  elif config['mode'] == 'norm':
    #w.factory("SUM::Norm_Final_PDF(Norm_N_Sig[65000,20000,110000]*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb,Norm_N_MisId[1300,100,3000]*Norm_MisId,Norm_N_MisId_Prompt[500,10,1000]*Norm_MisId_Prompt)")
    #w.factory("SUM::Norm_Final_PDF(Norm_N_Sig[65000,20000,110000]*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb,Norm_N_MisId[1300,100,3000]*Norm_MisId)")
    #w.factory("SUM::Norm_Final_PDF(Norm_N_Sig[65000,20000,110000]*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb,Norm_N_MisId_Prompt[500,10,1000]*Norm_MisId_Prompt)")
    #w.factory("SUM::Norm_Final_PDF(Norm_N_Sig*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb,Norm_N_MisRecod*Norm_MisRecod)")
    w.factory("SUM::Norm_Final_PDF(Norm_N_Sig*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb)")
    
    w.factory("SIMUL::Final_PDF(DataSet,Norm=Norm_Final_PDF)")

  elif config['mode'] == 'data':
    #w.factory("SUM::Norm_Final_PDF(Norm_N_Sig[65000,20000,110000]*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb,Norm_N_MisId[1300,100,3000]*Norm_MisId,Norm_N_MisId_Prompt[500,10,1000]*Norm_MisId_Prompt)")
    #w.factory("SUM::Norm_Final_PDF(Norm_N_Sig[65000,20000,110000]*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb,Norm_N_MisId[1300,100,3000]*Norm_MisId)")
    #w.factory("SUM::Norm_Final_PDF(Norm_N_Sig[65000,20000,110000]*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb,Norm_N_MisId_Prompt[500,10,1000]*Norm_MisId_Prompt)")
    w.factory("SUM::Norm_Final_PDF(Norm_N_Sig*Norm_Sig,Norm_N_Prompt[35000,20000,60000]*Norm_Prompt,Norm_N_Comb[67000,1000,90000]*Norm_Comb)")
    
    w.factory("SIMUL::Final_PDF(DataSet,Norm=Norm_Final_PDF,BDT1=BDT1_Final_PDF,BDT2=BDT2_Final_PDF,BDT3=BDT3_Final_PDF)")
    w.factory("SIMUL::Final_PDF_Background(DataSet,Norm=Norm_Final_PDF,BDT1=BDT1_Comb,BDT2=BDT2_Comb,BDT3=BDT3_Comb)")
    w.factory("SIMUL::Final_PDF_Constrained(DataSet,BDT1=BDT1_Final_PDF_Constrained,BDT2=BDT2_Final_PDF_Constrained,BDT3=BDT3_Final_PDF_Constrained)")



    w.obj('Norm_N_Comb').setMin(2000.0*config["normScale"]) ; w.obj('Norm_N_Comb').setMax(15000.0*config["normScale"])
    w.obj('Norm_N_Comb').setVal(7850.56516616*config["normScale"]) ; w.obj('Norm_N_Comb').setError(177.821454726/sqrt(config["normScale"]))
    w.obj('Norm_N_MisRecod').setMin(100.0*config["normScale"]) ; w.obj('Norm_N_MisRecod').setMax(40000.0*config["normScale"])
    w.obj('Norm_N_MisRecod').setVal(20316.944222*config["normScale"]) ; w.obj('Norm_N_MisRecod').setError(248.324102117/sqrt(config["normScale"]))
    w.obj('Norm_N_Prompt').setMin(6000.0*config["normScale"]) ; w.obj('Norm_N_Prompt').setMax(60000.0*config["normScale"])
    w.obj('Norm_N_Prompt').setVal(29326.825063*config["normScale"]) ; w.obj('Norm_N_Prompt').setError(247.656992623/sqrt(config["normScale"]))
    w.obj('Norm_N_Sig').setMin(2000.0*config["normScale"]) ; w.obj('Norm_N_Sig').setMax(270000.0*config["normScale"])
    w.obj('Norm_N_Sig').setVal(135370.*config["normScale"]) ; w.obj('Norm_N_Sig').setError(430./sqrt(config["normScale"]))


  if mode_later_than('mcnorm',config['mode']):

    # nll analyse, nlls up to 1610.0 on Thu Jul 31 15:14:35 2014 run on fitResult.norm_kpi_2011_6.0.0.4.root
    #
    # WARNING  derivitive_ratio bottom is zero 169 689.330300 696.763943 696.763943
    # INFO     extrapolate lower edge [False, -0.2368609160806532, 1610.0]
    # INFO     extrapolate upper edge [False, 0.300022797868122, 1610.0]
    w.obj('Norm_D0M_Bkg_Exp_c').setMin(-0.236860916081) ; w.obj('Norm_D0M_Bkg_Exp_c').setMax(0.300022797868) ; w.obj('Norm_D0M_Bkg_Exp_c').setVal(-0.0221074305011) ; w.obj('Norm_D0M_Bkg_Exp_c').setError(0.00127007751403)
    # WARNING  derivitive_ratio bottom is zero 169 5199.217924 5509.102918 5509.102918
    w.obj('Norm_D0M_Sig_Gaus1_Sigma').setMin(5.8) ; w.obj('Norm_D0M_Sig_Gaus1_Sigma').setMax(8.6) ; w.obj('Norm_D0M_Sig_Gaus1_Sigma').setVal(7.2) ; w.obj('Norm_D0M_Sig_Gaus1_Sigma').setError(0.0305815254416)
    # WARNING  derivitive_ratio bottom is zero 119 62.077791 62.077791 62.077791
    # WARNING  Dont want to expand max range 99.112383 too far
    # INFO     extrapolate upper edge [False, 10.5, 1610.0]
    # WARNING  upper edge 10.500000 hits limit 5.000000
    w.obj('Norm_D0M_Sig_Gaus1_alpha').setMin(1.14) ; w.obj('Norm_D0M_Sig_Gaus1_alpha').setMax(5.0) ; w.obj('Norm_D0M_Sig_Gaus1_alpha').setVal(2.298) ; w.obj('Norm_D0M_Sig_Gaus1_alpha').setError(0.0393012987558)
    # WARNING  Dont want to expand max range 899.409174 too far
    # INFO     extrapolate upper edge [False, 35.0, 1610.0]
    # WARNING  upper edge 35.000000 hits limit 20.000000
    w.obj('Norm_D0M_Sig_Gaus1_n').setMin(0.3375) ; w.obj('Norm_D0M_Sig_Gaus1_n').setMax(20.0) ; w.obj('Norm_D0M_Sig_Gaus1_n').setVal(2.30375) ; w.obj('Norm_D0M_Sig_Gaus1_n').setError(0.537418026352)
    # WARNING  derivitive_ratio bottom is zero 127 1374.893616 1418.388895 1418.388895
    # INFO     extrapolate upper edge [False, 10.856461576572277, 1610.0]
    w.obj('Norm_D0M_Sig_Gaus2_Sigma_Diff').setMin(1.25) ; w.obj('Norm_D0M_Sig_Gaus2_Sigma_Diff').setMax(10.8564615766) ; w.obj('Norm_D0M_Sig_Gaus2_Sigma_Diff').setVal(5.09258463063) ; w.obj('Norm_D0M_Sig_Gaus2_Sigma_Diff').setError(0.115261989641)
    # WARNING  derivitive_ratio bottom is zero 100 768.841852 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 101 768.841850 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 102 768.841850 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 103 768.841850 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 104 768.841850 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 105 768.841850 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 106 768.841850 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 107 768.841850 768.841850 768.841850
    # WARNING  derivitive_ratio bottom is zero 108 768.841850 768.841850 768.841850
    # INFO     extrapolate upper edge [False, 10.11481217459233, 1610.0]
    # WARNING  upper edge 10.114812 hits limit 5.000000
    w.obj('Norm_D0M_Sig_Gaus2_alpha').setMin(1.44) ; w.obj('Norm_D0M_Sig_Gaus2_alpha').setMax(5.0) ; w.obj('Norm_D0M_Sig_Gaus2_alpha').setVal(2.152) ; w.obj('Norm_D0M_Sig_Gaus2_alpha').setError(0.0415387821092)
    # WARNING  derivitive_ratio bottom is zero 230 629.750229 630.182190 630.182190
    # INFO     extrapolate lower edge [False, -0.9760496583225814, 1610.0]
    # WARNING  Dont want to expand max range 50.491612 too far
    # INFO     extrapolate upper edge [False, 35.0, 1610.0]
    # WARNING  lower edge -0.976050 hits limit 0.000000
    # WARNING  upper edge 35.000000 hits limit 20.000000
    w.obj('Norm_D0M_Sig_Gaus2_n').setMin(0.0) ; w.obj('Norm_D0M_Sig_Gaus2_n').setMax(20.0) ; w.obj('Norm_D0M_Sig_Gaus2_n').setVal(1.0) ; w.obj('Norm_D0M_Sig_Gaus2_n').setError(0.0563707589481)
    # WARNING  derivitive_ratio bottom is zero 102 100475.575388 104489.200281 104489.200281
    w.obj('Norm_D0M_Sig_Gaus_Mean').setMin(1864.1) ; w.obj('Norm_D0M_Sig_Gaus_Mean').setMax(1868.6) ; w.obj('Norm_D0M_Sig_Gaus_Mean').setVal(1866.35) ; w.obj('Norm_D0M_Sig_Gaus_Mean').setError(0.0282504176865)
    # WARNING  derivitive_ratio bottom is zero 102 950.574510 1090.331482 1090.331482
    # INFO     extrapolate upper edge [False, 8.675242367234118, 1610.0]
    w.obj('Norm_DelM_Bkg_a').setMin(-30.7) ; w.obj('Norm_DelM_Bkg_a').setMax(8.67524236723) ; w.obj('Norm_DelM_Bkg_a').setVal(-14.9499030531) ; w.obj('Norm_DelM_Bkg_a').setError(0.352110679985)
    # WARNING  derivitive_ratio bottom is zero 286 2509.484557 2524.607389 2524.607389
    # INFO     extrapolate lower edge [False, 135.51700895240305, 1610.0]
    w.obj('Norm_DelM_Bkg_m0').setMin(135.517008952) ; w.obj('Norm_DelM_Bkg_m0').setMax(140.245) ; w.obj('Norm_DelM_Bkg_m0').setVal(139.29940179) ; w.obj('Norm_DelM_Bkg_m0').setError(0.00278162353152)
    # WARNING  derivitive_ratio bottom is zero 168 12637.921551 12941.900194 12941.900194
    w.obj('Norm_DelM_Sig_Gaus1_Sigma').setMin(0.275) ; w.obj('Norm_DelM_Sig_Gaus1_Sigma').setMax(0.58) ; w.obj('Norm_DelM_Sig_Gaus1_Sigma').setVal(0.4275) ; w.obj('Norm_DelM_Sig_Gaus1_Sigma').setError(0.00623690681335)
    # WARNING  derivitive_ratio bottom is zero 140 7646.478871 7794.222379 7794.222379
    w.obj('Norm_DelM_Sig_Gaus2_Sigma_Diff').setMin(0.145) ; w.obj('Norm_DelM_Sig_Gaus2_Sigma_Diff').setMax(0.56) ; w.obj('Norm_DelM_Sig_Gaus2_Sigma_Diff').setVal(0.311) ; w.obj('Norm_DelM_Sig_Gaus2_Sigma_Diff').setError(0.00961908230633)
    # WARNING  derivitive_ratio bottom is zero 135 7889.258317 7968.149060 7968.149060
    w.obj('Norm_DelM_Sig_Gaus3_Mean').setMin(144.385) ; w.obj('Norm_DelM_Sig_Gaus3_Mean').setMax(147.52) ; w.obj('Norm_DelM_Sig_Gaus3_Mean').setVal(145.9525) ; w.obj('Norm_DelM_Sig_Gaus3_Mean').setError(0.0297743321414)
    # WARNING  derivitive_ratio bottom is zero 127 1441.937761 1456.115731 1456.115731
    # INFO     extrapolate lower edge [False, -1.562458158266192, 1610.0]
    # INFO     extrapolate upper edge [False, 3.2886360831918586, 1610.0]
    # WARNING  lower edge -1.562458 hits limit 0.000000
    w.obj('Norm_DelM_Sig_Gaus3_Sigma_Diff').setMin(0.0) ; w.obj('Norm_DelM_Sig_Gaus3_Sigma_Diff').setMax(3.28863608319) ; w.obj('Norm_DelM_Sig_Gaus3_Sigma_Diff').setVal(0.657727216638) ; w.obj('Norm_DelM_Sig_Gaus3_Sigma_Diff').setError(0.037812360311)
    # WARNING  derivitive_ratio bottom is zero 102 17487.965272 18067.587218 18067.587218
    w.obj('Norm_DelM_Sig_Gaus_Mean').setMin(145.25) ; w.obj('Norm_DelM_Sig_Gaus_Mean').setMax(145.6) ; w.obj('Norm_DelM_Sig_Gaus_Mean').setVal(145.425) ; w.obj('Norm_DelM_Sig_Gaus_Mean').setError(0.00389207378424)
    # WARNING  derivitive_ratio bottom is zero 171 1440.310455 1466.512994 1466.512994
    # INFO     extrapolate lower edge [False, -1161.7298062300902, 1610.0]
    # INFO     extrapolate upper edge [False, 6502.909990291508, 1610.0]
    # WARNING  lower edge -1161.729806 hits limit 0.000000
    w.obj('Norm_N_Comb').setMin(0.0*config["normScale"]) ; w.obj('Norm_N_Comb').setMax(6502.90999029*config["normScale"]) ; w.obj('Norm_N_Comb').setVal(1300.58199806*config["normScale"]) ; w.obj('Norm_N_Comb').setError(69.7188799676/sqrt(config["normScale"]))
    # WARNING  derivitive_ratio bottom is zero 142 1629.344232 1679.974917 1679.974917
    # INFO     extrapolate lower edge [False, 10931.649121116747, 1610.0]
    w.obj('Norm_N_Prompt').setMin(10931.6491211*config["normScale"]) ; w.obj('Norm_N_Prompt').setMax(30995.7616494*config["normScale"]) ; w.obj('Norm_N_Prompt').setVal(18957.2941324*config["normScale"]) ; w.obj('Norm_N_Prompt').setError(247.513270145/sqrt(config["normScale"]))
    # WARNING  derivitive_ratio bottom is zero 148 1585.358526 1642.672043 1642.672043
    # INFO     extrapolate lower edge [False, 64907.007351854576, 1610.0]
    w.obj('Norm_N_Sig').setMin(64907.0073519*config["normScale"]) ; w.obj('Norm_N_Sig').setMax(99148.5248*config["normScale"]) ; w.obj('Norm_N_Sig').setVal(82027.7660759*config["normScale"]) ; w.obj('Norm_N_Sig').setError(349.170253164/sqrt(config["normScale"]))



    #w.obj('Norm_DelM_Bkg_b').setVal(0)
    #w.obj('Norm_DelM_Bkg_b').setConstant(True)

    w.obj('Norm_D0M_Sig_Gaus1_Frac').setVal(0.7)
    #w.obj('Norm_D0M_Sig_Gaus3_Frac').setVal(0.35)
    w.obj('Norm_DelM_Sig_Gaus1_Frac').setVal(0.25)
    w.obj('Norm_DelM_Sig_Gaus3_Frac').setVal(0.15)

    w.obj('Norm_D0M_Sig_Gaus1_Frac').setConstant(True)
    #w.obj('Norm_D0M_Sig_Gaus3_Frac').setConstant(True)
    w.obj('Norm_DelM_Sig_Gaus1_Frac').setConstant(True)
    w.obj('Norm_DelM_Sig_Gaus3_Frac').setConstant(True)



  config['postHook'](w)
  return w
Esempio n. 9
0
fitfunc = TF1("fitfunc","[0]*exp( ((x-[1])<[3])*(-0.5*(x-[1])^2/[2]^2) + ((x-[1])>=[3])*(-0.5*[3]^2/[2]^2-(x-[1]-[3])/[4]))",-50,50)
fitfunc.SetParName(0,"Amplitude")
fitfunc.SetParName(1,"Mean")
fitfunc.SetParName(2,"Sigma")
fitfunc.SetParName(3,"Tail Z")
fitfunc.SetParName(4,"Tail length")


w = RooWorkspace("w")
w.factory("{0}[0,0.1]".format("uncM"))
w.factory("uncVZ[-100,100]")
w.factory("uncP[0,10]")
w.factory("cut[0,1]")

w.defineSet("myVars","{0},uncVZ".format("uncM"))

events = infile.Get("cut")
eventsrad = radfile.Get("ntuple")
dataset = RooDataSet("data","data",events,w.set("myVars"),"")

w.factory("Gaussian::vtx_model(uncVZ,mean[-50,50],sigma[0,50])")
gauss_pdf = w.pdf("vtx_model")
w.factory("EXPR::gaussExp('exp( ((@0-@1)<@3)*(-0.5*(@0-@1)^2/@2^2) + ((@0-@1)>=@3)*(-0.5*@3^2/@2^2-(@0-@1-@3)/@4))',uncVZ,gauss_mean[-5,-20,20],gauss_sigma[5,1,50],exp_breakpoint[10,0,50],exp_length[3,0.5,20])")
gaussexp_pdf = w.pdf("gaussExp")
w.defineSet("obs_1d","uncVZ")
obs=w.set("obs_1d")
uncVZ = w.var("uncVZ")
uncVZ.setBins(200)
gauss_params = gauss_pdf.getParameters(obs)
gaussexp_params = gaussexp_pdf.getParameters(obs)
#!/usr/bin/env python

from ROOT import TFile, TCanvas
from ROOT import RooDataSet, RooWorkspace, RooArgSet

tf = TFile.Open('AnalysisOut.root')
tree = tf.Get('AnalysisTree')

ws = RooWorkspace("w","w")
observables = RooArgSet()
ws.defineSet("observables",observables)

ws.factory("mass[5050,6000]")
getattr(ws,'set')("observables").add(ws.var("mass"))
ws.factory("gamgams_pt[0,40e3]")
getattr(ws,'set')("observables").add(ws.var("gamgams_pt"))


mc = RooDataSet('mc','',getattr(ws,'set')('observables'))
data = RooDataSet('data','',getattr(ws,'set')('observables'))

for ev in range(tree.GetEntries()):
  tree.GetEntry(ev)
  if tree.itype != -88 and tree.itype!=72 and tree.itype!=82: continue
  if tree.bdtoutput<0.2: continue
  if tree.B0_MM < ws.var("mass").getMin() or tree.B0_MM > ws.var("mass").getMax(): continue

  ws.var("mass").setVal(tree.B0_MM)
  ws.var("gamgams_pt").setVal(tree.gamgams_PT)

  if tree.itype == -88:
Esempio n. 11
0
class Wjj2DFitter:

    def __init__ (self, pars):
        self.pars = pars
        self.ws = RooWorkspace('wjj2dfitter')
        self.utils = Wjj2DFitterUtils(self.pars)
        self.useImportPars = False

        self.rangeString = None
        obs = []
        for v in self.pars.var:

            try:
                vName = self.pars.varNames[v]
            except AttributeError:
                vName = v

            obs.append(vName)
            var1 = self.ws.factory('%s[%f,%f]' % (vName, 
                                                  self.pars.varRanges[v][1], 
                                                  self.pars.varRanges[v][2])
                                   )
            var1.setUnit('GeV')
            try:
                var1.SetTitle(self.pars.varTitles[v])
            except AttributeError:
                var1.SetTitle('m_{jj}')
            var1.setPlotLabel(var1.GetTitle())
            if len(self.pars.varRanges[v][3]) > 1:
                vbinning = RooBinning(len(self.pars.varRanges[v][3]) - 1, 
                                   array('d', self.pars.varRanges[v][3]),
                                   '%sBinning' % vName)
                var1.setBinning(vbinning)
            else:
                var1.setBins(self.pars.varRanges[v][0])
            var1.Print()
            if v in self.pars.exclude:
                var1.setRange('signalRegion', self.pars.exclude[v][0],
                              self.pars.exclude[v][1])
                var1.setRange('lowSideband', var1.getMin(), 
                              self.pars.exclude[v][0])
                var1.setRange('highSideband', self.pars.exclude[v][1],
                              var1.getMax())
                self.rangeString = 'lowSideband,highSideband'
        self.ws.defineSet('obsSet', ','.join(obs))

    def loadDataFromWorkspace(self, other, cut = None):
        #pull unbinned data from other workspace
        unbinnedData = other.data('data_unbinned')
        if not unbinnedData:
            unbinnedData = other.data('data_obs')

        if cut:
            unbinnedData = unbinnedData.reduce(cut)

        unbinnedData.Print()
        if self.pars.binData:
            #bin and import data
            unbinnedData.SetName('data_unbinned')
            getattr(self.ws, 'import')(unbinnedData)
            data = RooDataHist('data_obs', 'data_obs', other.set('obsSet'), 
                               unbinnedData)
            getattr(self.ws, 'import')(data)
        else:
            #just import data
            unbinnedData.SetName('data_obs')
            getattr(self.ws, 'import')(unbinnedData)

    def loadHistogramsFromWorkspace(self, other):
        #pull RooHist pdfs from other workspace
        pdfs = other.allPdfs()
        pdfIter = pdfs.createIterator()
        pdf = pdfIter.Next()
        while pdf:
            if pdf.IsA().InheritsFrom('RooHistPdf'):
                print 'importing',pdf.GetName(),'from old workspace'
                getattr(self.ws, 'import')(pdf)
            pdf = pdfIter.Next()

    def loadWorkspaceFromFile(self, filename, wsname = 'w', 
                              getFloatPars = True):
        print 'loading data workspace %s from file %s' % (wsname, filename)
        fin = TFile.Open(filename)
        if not fin:
            print 'failed to open the file',filename
            import os
            print 'cwd:',os.getcwd()
            print 'access of',filename,os.access(filename, os.R_OK)
            print 'list of root files in cwd'
            for f in os.listdir(os.getcwd()):
                if f[-5:] == '.root':
                    print f,len(f),len(filename)
            fin = TFile.Open(os.getcwd() + '/' + filename)
            assert(fin)

        other = fin.Get(wsname)

        #pull unbinned data from other workspace
        self.loadDataFromWorkspace(other)

        #pull in histogram pdfs to save time
        self.loadHistogramsFromWorkspace(other)

        if getFloatPars and other.loadSnapshot('fitPars'):
            self.useImportPars = True
            self.ws.saveSnapshot('importParams', other.set('floatingParams'), 
                                 True)

        # self.ws.Print()
    
    # put together a fitting model and return the pdf
    def makeFitter(self, useAlternateModels = False):
        if self.ws.pdf('total'):
            return self.ws.pdf('total')

        compPdfs = []

        for component in self.pars.backgrounds:
            # print 'getting compModels'
            compModels = getattr(self.pars, '%sModels' % component)
            if hasattr(self.pars, '%sConvModels' % component):
                convModels = getattr(self.pars, '%sConvModels' % component)
            else:
                convModels = None
            if useAlternateModels:
                print 'loading Alternate Models'
                compModels = getattr(self.pars, '%sModelsAlt' % component)
                convModels = getattr(self.pars, '%sConvModelsAlt' % component)
            # print 'compModels = %s' % compModels
            compFiles = getattr(self.pars, '%sFiles' % component)
            compPdf = self.makeComponentPdf(component, compFiles, compModels,
                                            useAlternateModels, convModels)
                
            norm = self.ws.factory('prod::f_%s_norm' % component + \
                                       '(n_%s[0.,1e6],' % component + \
                                       '%s_nrm[1.,-0.5,5.])' % component)
            self.ws.var('n_%s' % component).setConstant(True)
            if hasattr(self, '%sExpected' % component):
                self.ws.var('n_%s' % component).setVal(
                    getattr(self, '%sExpected' % component))
            compPdfs.append(
                self.ws.factory('RooExtendPdf::%s_extended(%s,%s)' % \
                                    (compPdf.GetName(), 
                                     compPdf.GetName(),
                                     norm.GetName())
                                )
                )
                                    
        self.ws.factory('r_signal[0., -200., 200.]')
        self.ws.var('r_signal').setConstant(False)

        try:
            obs = [ self.pars.varNames[x] for x in self.pars.var ]
        except AttributeError:
            obs = self.pars.var

        for component in self.pars.signals:
            compFile = getattr(self.pars, '%sFiles' % component)
            compModels = getattr(self.pars, '%sModels' % component)
            if hasattr(self.pars, '%sConvModels' % component):
                convModels = getattr(self.pars, '%sConvModels' % component)
            else:
                convModels = None
            compPdf = self.makeComponentPdf(component, compFiles, compModels,
                                            useAlternateModels, convModels)
            norm = self.ws.factory(
                "prod::f_%s_norm(n_%s[0., 1e6],r_signal)" % \
                    (component, component)
                )
            self.ws.var('n_%s' % component).setConstant(True)
            if hasattr(self, '%sExpected' % component):
                self.ws.var('n_%s' % component).setVal(
                    getattr(self, '%sExpected' % component))
            pdf = self.ws.factory('RooExtendPdf::%s_extended(%s,%s)' % \
                                      (compPdf.GetName(), 
                                       compPdf.GetName(),
                                       norm.GetName())
                                  )
            
            if (hasattr(self.pars, '%sInterference' % component)) and \
                    getattr(self.pars, '%sInterference' % component):
                getattr(self.ws, 'import') \
                    (pdf, RooFit.RenameAllNodes('interf_%sUp' % component),
                     RooFit.RenameAllVariablesExcept('interf_%sUp' % component,
                                                     ','.join(obs)),
                     RooFit.Silence()
                     )
                getattr(self.ws, 'import') \
                    (pdf, RooFit.RenameAllNodes('interf_%sDown' % component),
                     RooFit.RenameAllVariablesExcept('interf_%sDown'%component,
                                                     ','.join(obs)),
                     RooFit.Silence()
                     )
            if self.pars.includeSignal:
                compPdfs.append(pdf)

        #print compPdfs
        
        prodList = [ '%s' % (pdf.GetName()) \
                         for (idx, pdf) in enumerate(compPdfs) ]
        comps = RooArgList(self.ws.argSet(','.join(prodList)))
        getattr(self.ws, 'import')(RooAddPdf('total', 'total', comps))

        return self.ws.pdf('total')

    # define the constraints on the yields, etc that will be part of the fit.
    def makeConstraints(self):

        if self.ws.set('constraintSet'):
            return self.ws.set('constraintSet')

        constraints = []
        constrainedParameters = []
        for constraint in self.pars.yieldConstraints:
            theYield = self.ws.var('%s_nrm' % constraint)
            if not theYield.isConstant():
                self.ws.factory('RooGaussian::%s_const(%s, 1.0, %f)' % \
                                    (constraint, theYield.GetName(),
                                     self.pars.yieldConstraints[constraint])
                                )
                constraints.append('%s_const' % constraint)
                constrainedParameters.append(theYield.GetName())

        if hasattr(self.pars, 'constrainShapes'):
            for component in self.pars.constrainShapes:
                pc = self.ws.pdf(component).getParameters(self.ws.set('obsSet'))
                parIter = pc.createIterator()
                par = parIter.Next()
                while par:
                    if not par.isConstant():
                        theConst = self.ws.factory('RooGaussian::%s_const' % \
                                                       (par.GetName()) + \
                                                       '(%s, %f, %f)' % \
                                                       (par.GetName(),
                                                        par.getVal(),
                                                        par.getError())
                                                   )
                        constraints.append(theConst.GetName())
                        constrainedParameters.append(par.GetName())
                    par = parIter.Next()
                pc.IsA().Destructor(pc)

        self.ws.defineSet('constraintSet', ','.join(constraints))
        self.ws.defineSet('constrainedSet', ','.join(constrainedParameters))

        return self.ws.set('constraintSet')

    # fit the data using the pdf
    def fit(self, keepParameterValues = False):
        print 'construct fit pdf ...'
        fitter = self.makeFitter()

        print 'load data ...'
        data = self.loadData()

        self.resetYields()

        constraintSet = self.makeConstraints()

        if not keepParameterValues:
            self.readParametersFromFile()

        self.resetYields()
        # print constraints, self.pars.yieldConstraints
        print '\nfit constraints'
        constIter = constraintSet.createIterator()
        constraint = constIter.Next()
        constraints = []
        while constraint:
            constraint.Print()
            constraints.append(constraint.GetName())
            constraint = constIter.Next()
            
        constraintCmd = RooCmdArg.none()
        if constraintSet.getSize() > 0:
            constraints.append(fitter.GetName())
            fitter = self.ws.pdf('totalFit_const')
            if not fitter:
                fitter = self.ws.factory('PROD::totalFit_const(%s)' % \
                                             (','.join(constraints))
                                         )
            constraintCmd = RooFit.Constrained()
            # constraintCmd = RooFit.ExternalConstraints(self.ws.set('constraintSet'))

        if self.useImportPars:
            self.ws.loadSnapshot('importParams')
        self.ws.Print()

        # for constraint in pars.constraints:
        #     self.ws.pdf(constraint).Print()
        # print

        rangeCmd = RooCmdArg.none()
        if self.rangeString and self.pars.doExclude:
            rangeCmd = RooFit.Range(self.rangeString)

        print 'fitting ...'
        fr = fitter.fitTo(data, RooFit.Save(True),
                          RooFit.Extended(True),
                          RooFit.Minos(False),
                          RooFit.PrintEvalErrors(-1),
                          RooFit.Warnings(False),
                          constraintCmd,
                          rangeCmd)
        fr.Print()

        

        return fr

    # determine the fitting model for each component and return them
    def makeComponentPdf(self, component, files, models, useAlternateModels,
                         convModels):
        print 'making ComponentPdf %s' % component
        # print 'models = %s' % models
        # print 'files = %s' % files
        if convModels and not (convModels[0] == -1):
            thePdf = self.makeConvolvedPdf(component, files, models, useAlternateModels, convModels)
        elif (models[0] == -1):
            thePdf = self.makeComponentHistPdf(component, files)
        elif (models[0] == -2):
            thePdf = self.makeMorphingPdf(component, useAlternateModels, convModels)
        elif (models[0] == -3):
            pass
        else:
            thePdf = self.makeComponentAnalyticPdf(component, models, useAlternateModels)

        return thePdf

    #create a simple 2D histogram pdf
    def makeComponentHistPdf(self, component, files):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        compHist = self.utils.newEmptyHist('hist%s' % component)
        sumYields = 0.
        sumxsec = 0.
        sumExpected = 0.
        for (idx,fset) in enumerate(files):
            if hasattr(self.pars, '%scuts' % component):
                cutOverride = getattr(self.pars, '%scuts' % component)
            else:
                cutOverride = None
            filename = fset[0]
            tmpHist = self.utils.File2Hist(filename, 
                                           'hist%s_%i' % (component, idx),
                                           False,cutOverride,False,True,0)
            sumYields += tmpHist.Integral()
            sumxsec += fset[2]
            compHist.Add(tmpHist, self.pars.integratedLumi*fset[2]/fset[1])
            sumExpected += tmpHist.Integral()*fset[2]* \
                self.pars.integratedLumi/fset[1]
            print filename,'acc x eff: %.3g' % (tmpHist.Integral()/fset[1])
            print filename,'N_expected: %.1f' % \
                (tmpHist.Integral()*fset[2]*self.pars.integratedLumi/fset[1])
            #tmpHist.Print()

        #compHist.Print()
        print '%s acc x eff: %.3g' % \
            (component, sumExpected/sumxsec/self.pars.integratedLumi)
        print 'Number of expected %s events: %.1f' % (component, sumExpected)
        setattr(self, '%sExpected' % component, sumExpected)

        return self.utils.Hist2Pdf(compHist, component, 
                                   self.ws, self.pars.order)
    #create a pdf which is a convolution of any two pdf
    def makeConvolvedPdf(self, component, files, models, useAlternateModels, convModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        #If a morphing model is selected, then convolve each individual component first and then morph
        if (models[0] == -2):
            return self.makeMorphingPdf(component, useAlternateModels, convModels)

        basePdf = self.makeComponentPdf('%s_base' % component, files, models, useAlternateModels, [-1])
        convComponent = 'Global' ##Overwrite to use the same convolution model for all Pdfs
        convModel = getattr(self.pars, '%sConvModels' % convComponent)
        if useAlternateModels:
            convModel = getattr(self.pars, '%sConvModelsAlt' % convComponent)
        convPdf = self.makeComponentPdf('%s_conv' % convComponent, files, convModel, useAlternateModels, [-1])
        var = self.pars.var[0]
        try:
            vName = self.pars.varNames[var]
        except AttributeError:
            vName = var
        self.ws.factory('RooFFTConvPdf::%s(%s,%s,%s)' % \
                        (component, vName, basePdf.GetName(),
                         convPdf.GetName()))
        return self.ws.pdf(component)


    # create a pdf using the "template morphing" technique
    def makeMorphingPdf(self, component, useAlternateModels, convModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)
        
        filesNom = getattr(self.pars, '%s_NomFiles' % component)
        modelsNom = getattr(self.pars, '%s_NomModels' % component)
        filesMU = getattr(self.pars, '%s_MUFiles' % component)
        modelsMU = getattr(self.pars, '%s_MUModels' % component)
        filesMD = getattr(self.pars, '%s_MDFiles' % component)
        modelsMD = getattr(self.pars, '%s_MDModels' % component)
        filesSU = getattr(self.pars, '%s_SUFiles' % component)
        modelsSU = getattr(self.pars, '%s_SUModels' % component)
        filesSD = getattr(self.pars, '%s_SDFiles' % component)
        modelsSD = getattr(self.pars, '%s_SDModels' % component)
        if useAlternateModels:
            modelsNom = getattr(self.pars, '%s_NomModelsAlt' % component)
            modelsMU = getattr(self.pars, '%s_MUModelsAlt' % component)
            modelsMD = getattr(self.pars, '%s_MDModelsAlt' % component)
            modelsSU = getattr(self.pars, '%s_SUModelsAlt' % component)
            modelsSD = getattr(self.pars, '%s_SDModelsAlt' % component)

        # Adds five (sub)components for the component with suffixes Nom, MU, MD, SU, SD
        NomPdf = self.makeComponentPdf('%s_Nom' % component, filesNom, modelsNom, False, convModels)
        if hasattr(self, '%s_NomExpected' % component):
            setattr(self, '%sExpected' % component,
                    getattr(self, '%s_NomExpected' % component))
        MUPdf = self.makeComponentPdf('%s_MU' % component, filesMU, modelsMU, False, convModels)
        MDPdf = self.makeComponentPdf('%s_MD' % component, filesMD, modelsMD, False, convModels)
        SUPdf = self.makeComponentPdf('%s_SU' % component, filesSU, modelsSU, False, convModels)
        SDPdf = self.makeComponentPdf('%s_SD' % component, filesSD, modelsSD, False, convModels)

        fMU_comp = self.ws.factory("fMU_%s[0., -1., 1.]" % component)
        fSU_comp = self.ws.factory("fSU_%s[0., -1., 1.]" % component)

        fMU = RooFormulaVar("f_fMU_%s" % component, "1.0*@0*(@0 >= 0.)", 
                            RooArgList( fMU_comp ) )
        fMD = RooFormulaVar("f_fMD_%s" % component, "-1.0*@0*(@0 < 0.)", 
                            RooArgList( fMU_comp ) )
        fSU = RooFormulaVar("f_fSU_%s" % component, "@0*(@0 >= 0.)", 
                            RooArgList( fSU_comp ) )
        fSD = RooFormulaVar("f_fSD_%s" % component, "@0*(-1)*(@0 < 0.)", 
                            RooArgList( fSU_comp ) )
        fNom = RooFormulaVar("f_fNom_%s" % component, "(1.-abs(@0)-abs(@1))", 
                             RooArgList(fMU_comp,fSU_comp) )
        morphPdf = RooAddPdf(component,component, 
                             RooArgList(MUPdf,MDPdf,SUPdf,SDPdf,NomPdf),
                             RooArgList(fMU, fMD, fSU, fSD, fNom))
        morphPdf.SetName(component)
        getattr(self.ws, 'import')(morphPdf)
        return self.ws.pdf(component)

    # create a pdf using an analytic function.
    def makeComponentAnalyticPdf(self, component, models, useAlternateModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        pdfList = []
        for (idx,model) in enumerate(models):
            var = self.pars.var[idx]
            try:
                vName = self.pars.varNames[var]
            except AttributeError:
                vName = var

            auxModel = None
            if useAlternateModels:
                if hasattr(self.pars, '%sAuxModelsAlt' % component):
                    auxModel = getattr(self.pars, '%sAuxModelsAlt' % component)[idx]
            else:
                if hasattr(self.pars, '%sAuxModels' % component):
                    auxModel = getattr(self.pars, '%sAuxModels' % component)[idx]

            pdfList.append(self.utils.analyticPdf(self.ws, vName, model, 
                                                  '%s_%s'%(component,vName), 
                                                  '%s_%s'%(component,vName),
                                                  auxModel
                                                  )
                           )
        
        pdfListNames = [ pdf.GetName() for pdf in pdfList ]
        if len(pdfList) > 1:
            self.ws.factory('PROD::%s(%s)' % \
                                (component, ','.join(pdfListNames)))
        else:
            pdfList[0].SetName(component)
                        
        return self.ws.pdf(component)

    def loadData(self, weight = False):
        if self.ws.data('data_obs'):
            return self.ws.data('data_obs')

        unbinnedName = 'data_obs'
        if self.pars.binData:
            unbinnedName = 'data_unbinned'
        data = self.utils.File2Dataset(self.pars.DataFile, unbinnedName, 
                                       self.ws, weighted = weight)
        if self.pars.binData:
            data = RooDataHist('data_obs', 'data_obs', self.ws.set('obsSet'), 
                               data)
            getattr(self.ws, 'import')(data)
            data = self.ws.data('data_obs')

        return data

    def stackedPlot(self, var, logy = False, pdfName = None, Silent = False):
        if not pdfName:
            pdfName = 'total'

        xvar = self.ws.var(var)
        nbins = xvar.getBins()
        if hasattr(self.pars, 'plotRanges'):
            xvar.setRange('plotRange', self.pars.plotRanges[var][1],
                          self.pars.plotRanges[var][2])
            xvar.setBins(self.pars.plotRanges[var][0], 'plotBins')
        else:
            xvar.setRange('plotRange', xvar.getMin(), xvar.getMax())
            xvar.setBins(nbins, 'plotBins')

        sframe = xvar.frame()
        sframe.SetName("%s_stacked" % var)
        pdf = self.ws.pdf(pdfName)

        if isinstance(pdf, RooAddPdf):
            compList = RooArgList(pdf.pdfList())
        else:
            compList = None

        data = self.ws.data('data_obs')
        nexp = pdf.expectedEvents(self.ws.set('obsSet'))

        if not Silent:
            print pdf.GetName(),'expected: %.0f' % (nexp)
            print 'data events: %.0f' % (data.sumEntries())

        if nexp < 1:
            nexp = data.sumEntries()
        theComponents = [] 
        if self.pars.includeSignal:
            theComponents += self.pars.signals
        theComponents += self.pars.backgrounds
        data.plotOn(sframe, RooFit.Invisible(),
                    RooFit.Binning('plotBins'))
        # dataHist = RooAbsData.createHistogram(data,'dataHist_%s' % var, xvar,
        #                                       RooFit.Binning('%sBinning' % var))
        # #dataHist.Scale(1., 'width')
        # invData = RooHist(dataHist, 1., 1, RooAbsData.SumW2, 1.0, False)
        # #invData.Print('v')
        # sframe.addPlotable(invData, 'pe', True, True)
        for (idx,component) in enumerate(theComponents):
            if not Silent:
                print 'plotting',component,'...',
            if hasattr(self.pars, '%sPlotting' % (component)):
                plotCharacteristics = getattr(self.pars, '%sPlotting' % \
                                                  (component))
            else:
                plotCharacteristics = {'color' : colorwheel[idx%6],
                                       'title' : component }

            compCmd = RooCmdArg.none()
            if compList:
                compSet = RooArgSet(compList)
                if compSet.getSize() > 0:
                    compCmd = RooFit.Components(compSet)
                removals = compList.selectByName('%s*' % component)
                compList.remove(removals)

            if not Silent:
                print 'events', self.ws.function('f_%s_norm' % component).getVal()
                sys.stdout.flush()
            if abs(self.ws.function('f_%s_norm' % component).getVal()) >= 1.:
                pdf.plotOn(sframe, #RooFit.ProjWData(data),
                           RooFit.DrawOption('LF'), RooFit.FillStyle(1001),
                           RooFit.FillColor(plotCharacteristics['color']),
                           RooFit.LineColor(plotCharacteristics['color']),
                           RooFit.VLines(),
                           RooFit.Range('plotRange'),
                           RooFit.NormRange('plotRange'),
                           RooFit.Normalization(nexp, RooAbsReal.NumEvent),
                           compCmd
                           )
                tmpCurve = sframe.getCurve()
                tmpCurve.SetName(component)
                tmpCurve.SetTitle(plotCharacteristics['title'])
                if 'visible' in plotCharacteristics:
                    sframe.setInvisible(component, 
                                        plotCharacteristics['visible'])

        data.plotOn(sframe, RooFit.Name('theData'),
                    RooFit.Binning('plotBins'))
        sframe.getHist('theData').SetTitle('data')
        # theData = RooHist(dataHist, 1., 1, RooAbsData.SumW2, 1.0, True)
        # theData.SetName('theData')
        # theData.SetTitle('data')
        # sframe.addPlotable(theData, 'pe')

        if (logy):
            sframe.SetMinimum(0.01)
            sframe.SetMaximum(1.0e6)
        else:
            sframe.SetMaximum(sframe.GetMaximum()*1.35)
            pass

        excluded = (var in self.pars.exclude)
        bname = var
        if not excluded:
            for v in self.pars.exclude:
                if hasattr(self.pars, 'varNames') and \
                       (self.pars.varNames[v] == var):
                    excluded = True
                    bname = v
        if excluded:
            blinder = TBox(self.pars.exclude[bname][0], sframe.GetMinimum(),
                           self.pars.exclude[bname][1], sframe.GetMaximum())
            # blinder.SetName('blinder')
            # blinder.SetTitle('signal region')
            blinder.SetFillColor(kBlack)
            if self.pars.blind:  
                blinder.SetFillStyle(1001)
            else:
                blinder.SetFillStyle(0)
            blinder.SetLineStyle(2)
            sframe.addObject(blinder)
        elif self.pars.blind:
            if not Silent:
                print "blind but can't find exclusion region for", var
                print 'excluded',excluded,self.pars.exclude
                print 'hiding data points'
            sframe.setInvisible('theData', True)

        #sframe.GetYaxis().SetTitle('Events / GeV')
        # dataHist.IsA().Destructor(dataHist)
        if not Silent:
            print

        xvar.setBins(nbins)

        return sframe

    def readParametersFromFile(self, fname=None):
        if (not fname):
            fname = self.pars.initialParametersFile
        
        if isinstance(fname, str):
            flist = [ fname ]
        else:
            flist = fname

        for tmpName in flist:
            if len(tmpName) > 0:
                print 'loading parameters from file',tmpName
                self.ws.allVars().readFromFile(tmpName)

    def expectedFromPars(self):
        components = self.pars.signals + self.pars.backgrounds
        for component in components:
            theYield = self.ws.var('n_%s' % component)
            setattr(self, '%sExpected' % component, theYield.getVal())

    def initFromExplicitVals(self,opts):
        #,init_diboson= -1.0,init_WpJ=-1.0,init_top=-1.0,init_ZpJ=-1.0,init_QCD=-1.0
        components = ['diboson', 'top', 'WpJ', 'ZpJ', 'QCD', 'WHbb']
        for component in components:
            #double init
            init = getattr(opts, 'ext%s' % component)
            #init = -2.0
            #setattr(self,init, 'init_%s' % component)
            #init = init_%s % component
            #print "init=", init
            #init = self.ws.var('init_%s' % component)
            #init.setVal(100.0)
            #init.setVal('init_%s' % component)
            #init = theYield.getVal()
            if (init>0.):
                print 'setting initial value for ',component,' to ',init
                setattr(self, '%sInitial' % component, init)


    def resetYields(self):
        if self.ws.data('data_obs'):
            Ndata = self.ws.data('data_obs').sumEntries()
        else:
            Ndata = 10000.
        print 'resetting yields...'
        components = self.pars.signals + self.pars.backgrounds
        for component in components:
            theYield = self.ws.var('n_%s' % component)
            theNorm = self.ws.var('%s_nrm' % component)
            if hasattr(self, '%sInitial' % component):
                print 'explicitly setting initial value for ',component
                theYield.setVal(getattr(self, '%sInitial' % component))
                theNorm.setVal(1.0)
                theNorm.setConstant()
            else:
                fracofdata = -1.
                if hasattr(self.pars, '%sFracOfData' % component):
                    fracofdata = getattr(self.pars, '%sFracOfData' % component)
                if (fracofdata >= 0.):
                    print 'explicitly setting ', component,' yield to be', fracofdata,' of data'
                    theYield.setVal(fracofdata*Ndata)
                elif hasattr(self, '%sExpected' % component):
                    theYield.setVal(getattr(self, '%sExpected' % component))
                else:
                    print 'no expected value for',component
                    theYield.setVal(Ndata/len(components))
            if theNorm and not theNorm.isConstant():
                theNorm.setVal(1.0)
            if component in self.pars.yieldConstraints:
                theYield.setError(theYield.getVal() * \
                                  self.pars.yieldConstraints[component])
                if theNorm:
                    theNorm.setError(self.pars.yieldConstraints[component])
            else:
                theYield.setError(sqrt(theYield.getVal()))
            theYield.Print()

    def generateToyMCSet(self,var,inputPdf,outFileName,NEvts):
        fMC = TFile(outFileName, "RECREATE");
#        thevar = self.ws.var(var);
        print 'thevar='
        print var
#        print thevar
        print '...'
#        varList = RooArgList()
#        varList.add(self.ws.var(var))
        toymc = inputPdf.generate(RooArgSet(self.ws.var(var)),NEvts);
        tMC = toymc.tree();
        fMC.cd();
        tMC.Write();
        fMC.Close();

    


    def legend4Plot(plot, left = False):
        if left:
            theLeg = TLegend(0.2, 0.62, 0.55, 0.92, "", "NDC")
        else:
            theLeg = TLegend(0.60, 0.62, 0.92, 0.92, "", "NDC")
        theLeg.SetName('theLegend')

        theLeg.SetBorderSize(0)
        theLeg.SetLineColor(0)
        theLeg.SetFillColor(0)
        theLeg.SetFillStyle(0)
        theLeg.SetLineWidth(0)
        theLeg.SetLineStyle(0)
        theLeg.SetTextFont(42)
        theLeg.SetTextSize(.045)

        entryCnt = 0
        for obj in range(0, int(plot.numItems())):
            objName = plot.nameOf(obj)
            if (not plot.getInvisible(objName)):
                theObj = plot.getObject(obj)
                objTitle = theObj.GetTitle()
                if len(objTitle) < 1:
                    objTitle = objName
                dopts = plot.getDrawOptions(objName).Data()
                # print 'obj:',theObj,'title:',objTitle,'opts:',dopts,'type:',type(dopts)
                if theObj.IsA().InheritsFrom('TNamed'):
                    theLeg.AddEntry(theObj, objTitle, dopts)
                    entryCnt += 1
        theLeg.SetY1NDC(0.9 - 0.05*entryCnt - 0.005)
        theLeg.SetY1(theLeg.GetY1NDC())
        return theLeg

    legend4Plot = staticmethod(legend4Plot)
Esempio n. 12
0
def main(options, args):

    cfg = options.config
    workspaceName = cfg.get('Global', 'workspace')

    ws = RooWorkspace(workspaceName)

    #ws.Print("v")

    setupWorkspace(ws, options)

    #create -log(likelihood)

    theNLL = ws.pdf('TopLevelPdf').createNLL(
        ws.data('allcountingdata'), RooFit.NumCPU(1),
        RooFit.ConditionalObservables(ws.set('condObs')), RooFit.Verbose(True))

    ws.saveSnapshot('standardmodel', ws.allVars())

    minuit = ROOT.RooMinuit(theNLL)
    minuit.setPrintLevel(1)
    minuit.setPrintEvalErrors(-1)
    minuit.setErrorLevel(.5)

    #find the values of the parameters that minimize the likelihood
    minuit.setStrategy(2)
    minuit.simplex()
    minuit.migrad()
    minuit.hesse()

    #ws.var('err_gl').setConstant(True)
    #ws.var('err_gs').setConstant(True)
    #ws.var('err_gb').setConstant(True)

    ws.defineSet(
        'POI',
        ROOT.RooArgSet(
            ws.var('%s_%s' % (cfg.get(
                'Global', 'par1Name'), cfg.get('Global', 'couplingType'))),
            ws.var('%s_%s' % (cfg.get(
                'Global', 'par2Name'), cfg.get('Global', 'couplingType')))))

    ws.saveSnapshot('%s_fitresult' % cfg.get('Global', 'couplingType'),
                    ws.allVars())

    #create profile likelihood
    level_68 = ROOT.TMath.ChisquareQuantile(
        .68, 2) / 2.0  # delta NLL for 68% confidence level for -log(LR)
    level_95 = ROOT.TMath.ChisquareQuantile(
        .95, 2) / 2.0  # delta NLL for 95% confidence level for -log(LR)

    print
    print '68% CL Delta-NLL 2 DOF=', level_68
    print '95% CL Delta-NLL 2 DOF=', level_95

    minuit.setPrintLevel(1)
    minuit.setPrintEvalErrors(-1)

    minuit.migrad()
    minuit.minos(ws.set('POI'))

    thePlot = minuit.contour(
        ws.var('%s_%s' % (cfg.get(
            'Global', 'par1Name'), cfg.get('Global', 'couplingType'))),
        ws.var('%s_%s' % (cfg.get(
            'Global', 'par2Name'), cfg.get('Global', 'couplingType'))),
        sqrt(2 * level_95), sqrt(2 * level_68))  # here the error is in sigmas

    thePlot.SetName(
        '%s_%s_%s_contour' %
        (cfg.get('Global', 'par1Name'), cfg.get(
            'Global', 'par2Name'), cfg.get('Global', 'couplingType')))

    thePlot.SetTitle('68% & 95% CL on the Best Fit Values of ' +
                     cfg.get('Global', 'par1Name') + ' and ' +
                     cfg.get('Global', 'par2Name'))
    legend = ROOT.TLegend(2.01612903225806439e-01, 7.86016949152542388e-01,
                          7.15725806451612989e-01, 9.13135593220338992e-01)
    legend.SetNColumns(2)
    thePlot.addObject(legend)

    # 1-D Limits

    level_95 = ROOT.TMath.ChisquareQuantile(
        .95, 1) / 2.0  # delta NLL for -log(LR) with 1 dof
    print '95% CL Delta-NLL 1 DOF=', level_95
    minuit.setErrorLevel(level_95)

    #set 1-D limits on parameter 1 with parameter 2 == 0
    ws.var('%s_%s' % (cfg.get(
        'Global', 'par2Name'), cfg.get('Global', 'couplingType'))).setVal(0.0)
    ws.var('%s_%s' % (cfg.get('Global', 'par2Name'),
                      cfg.get('Global', 'couplingType'))).setConstant(True)
    minuit.minos(ws.set('POI'))

    parm1 = ws.var(
        '%s_%s' %
        (cfg.get('Global', 'par1Name'), cfg.get('Global', 'couplingType')))

    print 'parameter 1 value: ' + str(parm1.getVal())

    if not (0 < parm1.getVal() + parm1.getErrorHi()
            and 0 > parm1.getVal() + parm1.getErrorLo()):
        print '95% CL does not cover SM for parameter 1'
    else:
        print '95% CL covers SM for parameter 1'

    par1Line = ROOT.TLine(parm1.getVal() + parm1.getErrorLo(), 0,
                          parm1.getVal() + parm1.getErrorHi(), 0)
    par1Line.SetLineWidth(2)
    par1Line.SetLineColor(ROOT.kRed)

    thePlot.addObject(par1Line)

    #set 1-D limits on parameter 2 with parameter 1 == 0
    ws.var('%s_%s' % (cfg.get('Global', 'par2Name'),
                      cfg.get('Global', 'couplingType'))).setConstant(False)
    ws.var('%s_%s' % (cfg.get(
        'Global', 'par1Name'), cfg.get('Global', 'couplingType'))).setVal(0.0)
    ws.var('%s_%s' % (cfg.get('Global', 'par1Name'),
                      cfg.get('Global', 'couplingType'))).setConstant(True)
    minuit.minos(ws.set('POI'))

    parm2 = ws.var(
        '%s_%s' %
        (cfg.get('Global', 'par2Name'), cfg.get('Global', 'couplingType')))

    print 'parameter 2 value: ' + str(parm2.getVal())

    if not (0 < parm2.getVal() + parm2.getErrorHi()
            and 0 > parm2.getVal() + parm2.getErrorLo()):
        print '95% CL does not cover SM for parameter 2'
    else:
        print '95% CL covers SM for parameter 2'

    par2Line = ROOT.TLine(0,
                          parm2.getVal() + parm2.getErrorLo(), 0,
                          parm2.getVal() + parm2.getErrorHi())
    par2Line.SetLineWidth(2)
    par2Line.SetLineColor(ROOT.kRed)

    thePlot.addObject(par2Line)

    ws.var('%s_%s' % (cfg.get('Global', 'par1Name'),
                      cfg.get('Global', 'couplingType'))).setConstant(False)

    #construct likelihood scan histograms
    plot = parm1.frame()
    parm1.setBins(200)
    parm2.setBins(200)

    scanHist = ROOT.TH2F('scan2d_plot', '2D Scan of the Likelihood', 200,
                         parm1.getMin(), parm1.getMax(), 200, parm2.getMin(),
                         parm2.getMax())

    for i in range(200):
        for j in range(200):
            parm1.setVal(parm1.getMin() + (i + .5) *
                         (parm1.getMax() - parm1.getMin()) / 200)
            parm2.setVal(parm2.getMin() + (j + .5) *
                         (parm2.getMax() - parm2.getMin()) / 200)
            scanHist.SetBinContent(i + 1, j + 1, theNLL.getVal())

    profNLL_par1 = theNLL.createProfile(RooArgSet(parm1))
    profNLL_par1_plot = parm1.frame()
    profNLL_par1.plotOn(profNLL_par1_plot)

    profNLL_par2 = theNLL.createProfile(RooArgSet(parm2))
    profNLL_par2_plot = parm2.frame()
    profNLL_par2.plotOn(profNLL_par2_plot)

    initCMSStyle()

    output = TFile.Open(workspaceName + '.root', 'RECREATE')

    ws.Write()
    contCanvas = ROOT.TCanvas('contour_canvas', '', 500, 500)
    thePlot.Draw()
    prettyContour(contCanvas, cfg)
    contCanvas.Write()
    thePlot.Write()

    scanCanvas2D = ROOT.TCanvas('scan2d_canvas', '', 500, 500)
    scanHist.Draw('colz')
    prettyScan(scanCanvas2D, cfg)
    scanCanvas2D.Write()
    scanHist.Write()

    par1ScanCanvas = ROOT.TCanvas('scan1d_par1', '', 500, 500)
    par1ScanCanvas.cd()
    profNLL_par1_plot.Draw()
    par1ScanCanvas.Write()
    profNLL_par1_plot.Write()

    par2ScanCanvas = ROOT.TCanvas('scan1d_par2', '', 500, 500)
    par2ScanCanvas.cd()
    profNLL_par2_plot.Draw()
    par2ScanCanvas.Write()
    profNLL_par2_plot.Write()

    prettyObsPlots(ws, cfg)

    output.Close()

    if options.makeCards:
        print
        print "Creating cards for Higgs Combined Limit calculator!"
        makeHCLCards(ws, cfg)

    return 0
Esempio n. 13
0
def setup_workspace():

  import ROOT
  from ROOT import RooWorkspace, gROOT, gStyle, RooAbsReal, RooMsgService, RooFit
  #from ROOT import RooFit, gROOT, gDirectory, gStyle, gPad, TTree, RooCmdArg,RooBinning
  #from ROOT import RooRealVar, RooMappedCategory, RooCategory, RooFormulaVar, RooAbsData
  #from ROOT import RooBMixDecay, RooMCStudy, RooAddModel, RooEffProd, RooMsgService
  #from ROOT import RooWorkspace, TCanvas, TFile, kFALSE, kTRUE, RooDataSet, TStopwatch
  #from ROOT import RooArgSet, RooArgList, RooRandom, RooMinuit, RooAbsReal, RooDataHist
  #from ROOT import TBrowser, TH2F, TF1, TH1F, RooGenericPdf, RooLinkedList

  gROOT.SetStyle("Plain")
  gStyle.SetPalette(1)
  gStyle.SetOptStat(0)
  gStyle.SetOptFit(0)
  gStyle.SetOptStat(1111)
  gStyle.SetOptFit(10111)
  gStyle.SetOptTitle(1)

  #RooAbsReal.defaultIntegratorConfig().Print()
  #RooAbsReal.defaultIntegratorConfig().setEpsAbs(1e-10)
  #RooAbsReal.defaultIntegratorConfig().setEpsRel(1e-10)
  RooAbsReal.defaultIntegratorConfig().Print()

  print "Numeric integration set up" #TODO: is the integration acceptable?

  ##This controls the logging output from RooFit
  #RooMsgService.instance().addStream(RooFit.DEBUG,RooFit.Topic(RooFit.Fitting))
  RooMsgService.instance().deleteStream(1)
  #RooMsgService.instance().addStream(RooFit.INFO,RooFit.Topic(RooFit.Generation + RooFit.Minization + RooFit.Plotting + RooFit.Fitting + RooFit.Integration + RooFit.LinkStateMgmt + RooFit.Eval + RooFit.Caching + RooFit.Optimization + RooFit.ObjectHandling + RooFit.InputArguments + RooFit.Tracing + RooFit.Contents + RooFit.DataHandling + RooFit.NumericIntegration))
  RooMsgService.instance().addStream(RooFit.INFO,RooFit.Topic(RooFit.LinkStateMgmt + RooFit.Caching + RooFit.ObjectHandling + RooFit.InputArguments + RooFit.Tracing))
  RooMsgService.instance().Print()


  print "Message service set up"

  w = RooWorkspace("w",False)

  w.factory("RAND[0,1]")
  D0_M = w.factory("D0_M[1800,1930]") #TODO: define mass ranges slightly better
  Del_M = w.factory("Del_M[139,155]")
  D0_M.setUnit("MeV")
  Del_M.setUnit("MeV")

  for dst_side in ["", "dstsig", "dsthigh", "dstlow"]:
    for d_side in ["", "dsig", "dhigh", "dlow"]:
      name = dst_side+d_side
      if dst_side == "dsthigh":
        Del_M.setRange(name,148.,155.)
      elif dst_side == "dstsig":
        Del_M.setRange(name,143.,148.)
      elif dst_side == "dstlow":
        Del_M.setRange(name,139.,143.)
        
      if d_side == "dhigh":
        Del_M.setRange(name,1885.,1930.)
      elif d_side == "dsig":
        Del_M.setRange(name,1835.,1885.)
      elif d_side == "dlow":
        Del_M.setRange(name,1800.,1835.)




  w.defineSet("args","D0_M,Del_M")
  w.defineSet("argsPreCut","D0_M,Del_M,RAND")

  w.factory("RooGaussian::D0M_Sig_Gaus1(D0_M,D0M_Sig_Gaus_Mean[1865,1850,1880],D0M_Sig_Gaus_Sigma1[10,1,30])")
  w.factory("RooGaussian::D0M_Sig_Gaus2(D0_M,D0M_Sig_Gaus_Mean,D0M_Sig_Gaus_Sigma2[3,1,30])")
  w.factory("SUM::D0M_Sig_Gaus(D0M_Sig_Gaus1_Frac[0.8,0,1]*D0M_Sig_Gaus1,D0M_Sig_Gaus2)")
  
  
  w.factory("RooGaussian::D0M_MisId_Gaus1(D0_M,D0M_MisId_Gaus_Mean[1800,1740,1820],D0M_Sig_Gaus_Sigma1)")
  w.factory("RooGaussian::D0M_MisId_Gaus2(D0_M,D0M_MisId_Gaus_Mean,D0M_Sig_Gaus_Sigma2)")
  w.factory("SUM::D0M_MisId_Gaus(D0M_Sig_Gaus1_Frac*D0M_MisId_Gaus1,D0M_MisId_Gaus2)")
  
  
  w.factory("RooChebychev::D0M_Bkg_Poly(D0_M,{D0M_Bkg_Poly_a1[0,-1,1]})")
  


  w.factory("RooGaussian::DelM_Sig_Gaus1(Del_M,DelM_Sig_Gaus_Mean[145.5,143,148],DelM_Sig_Gaus_Sigma1[1,0,5] )")
  w.factory("RooGaussian::DelM_Sig_Gaus2(Del_M,DelM_Sig_Gaus_Mean,DelM_Sig_Gaus_Sigma2[.1,0,2] )")
  w.factory("SUM::DelM_Sig_Gaus(DelM_Sig_Gaus1_Frac[0.8,0,1]*DelM_Sig_Gaus1,DelM_Sig_Gaus2)")

  w.factory("RooDstD0BG::DelM_Bkg(Del_M,DelM_Bkg_m0[139.5,134,144],DelM_Bkg_c[80,0,1000],DelM_Bkg_a[-1,-100,10],DelM_Bkg_b[0.2,-0.2,10])")

  w.factory("PROD::Sig(DelM_Sig_Gaus,D0M_Sig_Gaus)")
  w.factory("PROD::Comb(DelM_Bkg,D0M_Bkg_Poly)")
  w.factory("PROD::MisId(DelM_Sig_Gaus,D0M_MisId_Gaus)")
  w.factory("PROD::Prompt(DelM_Bkg,D0M_Sig_Gaus)")
  

  w.factory("SUM::Final_PDF(N_Sig[10000,0,50000]*Sig,N_Prompt[5000,0,20000]*Prompt,N_Comb[10000,0,50000]*Comb,N_MisId[500,0,5000]*MisId)")


  return w
Esempio n. 14
0
def main(options,args):

    cfg = options.config
    workspaceName = cfg.get('Global','workspace')        
    
    ws = RooWorkspace(workspaceName)    

    #ws.Print("v")
    
    setupWorkspace(ws,options)        

    #create -log(likelihood)
    
    theNLL = ws.pdf('TopLevelPdf').createNLL(ws.data('allcountingdata'),
                                             RooFit.NumCPU(1),
                                             RooFit.ConditionalObservables(ws.set('condObs')),
                                             RooFit.Verbose(True))

    ws.saveSnapshot('standardmodel',ws.allVars())
    
    minuit = ROOT.RooMinuit(theNLL)
    minuit.setPrintLevel(1)
    minuit.setPrintEvalErrors(-1)
    minuit.setErrorLevel(.5)
    
    #find the values of the parameters that minimize the likelihood
    minuit.setStrategy(2)
    minuit.simplex()
    minuit.migrad()
    minuit.hesse()

    #ws.var('err_gl').setConstant(True)
    #ws.var('err_gs').setConstant(True)
    #ws.var('err_gb').setConstant(True)

    ws.defineSet('POI',
                 ROOT.RooArgSet(ws.var('%s_%s'%(cfg.get('Global','par1Name'),cfg.get('Global','couplingType'))),
                                ws.var('%s_%s'%(cfg.get('Global','par2Name'),cfg.get('Global','couplingType')))))

    ws.saveSnapshot('%s_fitresult'%cfg.get('Global','couplingType'),
                    ws.allVars())
        
    #create profile likelihood       
    level_68 = ROOT.TMath.ChisquareQuantile(.68,2)/2.0 # delta NLL for 68% confidence level for -log(LR)
    level_95 = ROOT.TMath.ChisquareQuantile(.95,2)/2.0 # delta NLL for 95% confidence level for -log(LR)

    print
    print '68% CL Delta-NLL 2 DOF=',level_68
    print '95% CL Delta-NLL 2 DOF=',level_95
    
    
    minuit.setPrintLevel(1)
    minuit.setPrintEvalErrors(-1)

    minuit.migrad()
    minuit.minos(ws.set('POI'))

    thePlot = minuit.contour(ws.var('%s_%s'%(cfg.get('Global','par1Name'),cfg.get('Global','couplingType'))),
                             ws.var('%s_%s'%(cfg.get('Global','par2Name'),cfg.get('Global','couplingType'))),
                             sqrt(2*level_95),sqrt(2*level_68)) # here the error is in sigmas 

    thePlot.SetName('%s_%s_%s_contour'%(cfg.get('Global','par1Name'),
                                        cfg.get('Global','par2Name'),
                                        cfg.get('Global','couplingType')))    
    
    thePlot.SetTitle('68% & 95% CL on the Best Fit Values of '+cfg.get('Global','par1Name')+' and '+cfg.get('Global','par2Name'))
    legend = ROOT.TLegend(2.01612903225806439e-01,7.86016949152542388e-01,
                          7.15725806451612989e-01,9.13135593220338992e-01)
    legend.SetNColumns(2)
    thePlot.addObject(legend)

    # 1-D Limits
    
    level_95 = ROOT.TMath.ChisquareQuantile(.95,1)/2.0 # delta NLL for -log(LR) with 1 dof
    print '95% CL Delta-NLL 1 DOF=',level_95
    minuit.setErrorLevel(level_95)

    #set 1-D limits on parameter 1 with parameter 2 == 0
    ws.var('%s_%s'%(cfg.get('Global','par2Name'),cfg.get('Global','couplingType'))).setVal(0.0)
    ws.var('%s_%s'%(cfg.get('Global','par2Name'),cfg.get('Global','couplingType'))).setConstant(True)
    minuit.minos(ws.set('POI'))

    parm1 = ws.var('%s_%s'%(cfg.get('Global','par1Name'),cfg.get('Global','couplingType')))

    print  'parameter 1 value: '+str(parm1.getVal())

    if not (0 < parm1.getVal()+parm1.getErrorHi() and 0 > parm1.getVal()+parm1.getErrorLo()):
        print '95% CL does not cover SM for parameter 1'
    else:
        print '95% CL covers SM for parameter 1'

    par1Line = ROOT.TLine(parm1.getVal()+parm1.getErrorLo(),0,
                          parm1.getVal()+parm1.getErrorHi(),0)
    par1Line.SetLineWidth(2)
    par1Line.SetLineColor(ROOT.kRed)
    
    thePlot.addObject(par1Line)

    #set 1-D limits on parameter 2 with parameter 1 == 0
    ws.var('%s_%s'%(cfg.get('Global','par2Name'),cfg.get('Global','couplingType'))).setConstant(False)
    ws.var('%s_%s'%(cfg.get('Global','par1Name'),cfg.get('Global','couplingType'))).setVal(0.0)
    ws.var('%s_%s'%(cfg.get('Global','par1Name'),cfg.get('Global','couplingType'))).setConstant(True)
    minuit.minos(ws.set('POI'))

    parm2 = ws.var('%s_%s'%(cfg.get('Global','par2Name'),cfg.get('Global','couplingType')))

    print  'parameter 2 value: '+str(parm2.getVal())

    if not (0 < parm2.getVal()+parm2.getErrorHi() and 0 > parm2.getVal()+parm2.getErrorLo()):
        print '95% CL does not cover SM for parameter 2'
    else:
        print '95% CL covers SM for parameter 2'

    par2Line = ROOT.TLine(0,parm2.getVal()+parm2.getErrorLo(),
                          0,parm2.getVal()+parm2.getErrorHi())
    par2Line.SetLineWidth(2)
    par2Line.SetLineColor(ROOT.kRed)
    
    thePlot.addObject(par2Line)
    
    ws.var('%s_%s'%(cfg.get('Global','par1Name'),cfg.get('Global','couplingType'))).setConstant(False)

    #construct likelihood scan histograms
    plot = parm1.frame()
    parm1.setBins(200)
    parm2.setBins(200)
    
    scanHist = ROOT.TH2F('scan2d_plot','2D Scan of the Likelihood',
                         200,parm1.getMin(),parm1.getMax(),
                         200,parm2.getMin(),parm2.getMax())                         
    
    for i in range(200):
        for j in range(200):
            parm1.setVal(parm1.getMin() + (i+.5)*(parm1.getMax()-parm1.getMin())/200)
            parm2.setVal(parm2.getMin() + (j+.5)*(parm2.getMax()-parm2.getMin())/200)
            scanHist.SetBinContent(i+1,j+1,theNLL.getVal())

    profNLL_par1 = theNLL.createProfile(RooArgSet(parm1))
    profNLL_par1_plot = parm1.frame()
    profNLL_par1.plotOn(profNLL_par1_plot)

    profNLL_par2 = theNLL.createProfile(RooArgSet(parm2))
    profNLL_par2_plot = parm2.frame()
    profNLL_par2.plotOn(profNLL_par2_plot)

    initCMSStyle()
    
    output = TFile.Open(workspaceName+'.root','RECREATE')
    
    ws.Write()
    contCanvas = ROOT.TCanvas('contour_canvas','',500,500)
    thePlot.Draw()
    prettyContour(contCanvas,cfg)
    contCanvas.Write()
    thePlot.Write()
    
    scanCanvas2D = ROOT.TCanvas('scan2d_canvas','',500,500)
    scanHist.Draw('colz')
    prettyScan(scanCanvas2D,cfg)
    scanCanvas2D.Write()
    scanHist.Write()

    par1ScanCanvas = ROOT.TCanvas('scan1d_par1','',500,500)
    par1ScanCanvas.cd()
    profNLL_par1_plot.Draw()
    par1ScanCanvas.Write()
    profNLL_par1_plot.Write()

    par2ScanCanvas = ROOT.TCanvas('scan1d_par2','',500,500)
    par2ScanCanvas.cd()
    profNLL_par2_plot.Draw()
    par2ScanCanvas.Write()
    profNLL_par2_plot.Write()

    prettyObsPlots(ws,cfg)
    
    output.Close()

    if options.makeCards:
        print
        print "Creating cards for Higgs Combined Limit calculator!"
        makeHCLCards(ws,cfg)

    return 0
Esempio n. 15
0
    turnon = sys.argv[6]  #fitted turn on type!!!
    truth = sys.argv[7]  #truth model type!!!

    bs = RooWorkspace('bias_study')

    bs.factory("procWeight[0]")
    bs.factory("puWeight[0]")
    bs.factory("weight[0]")
    bs.factory("Mzg[100,180]")
    bs.var("Mzg").setRange("ROI", mass - 1.5, mass + 1.5)
    bs.var("Mzg").setBins(40000, "cache")
    bs.factory("Mz[0]")
    #bs.factory("dMzg[0,25]")
    #bs.factory("dMz[0,25]")
    bs.factory("r94cat[cat1=1,cat2=2,cat3=3,cat4=4]")
    bs.defineSet("observables", "Mzg,Mz,r94cat,procWeight,puWeight")
    bs.defineSet("observables_weight",
                 "Mzg,Mz,r94cat,procWeight,puWeight,weight")

    prepare_truth_models(bs, category, mass, channel, turnon, truth)

    build_fitting_models(bs, category, mass, order, turnon)

    gen_data_and_fit(bs, ntoys, category, mass, channel, turnon, truth)

    out_f = TFile.Open(
        "bias_study_%s_%s_%s_ntoys%i_cat%i_m%s_order%i.root" %
        (channel, turnon, truth, ntoys, category, str(mass).replace(
            '.', 'p'), order), "recreate")
    bs.Write()
    out_f.Close()
Esempio n. 16
0
    turnon = sys.argv[6] #fitted turn on type!!!
    truth = sys.argv[7] #truth model type!!!
    
    bs = RooWorkspace('bias_study')

    bs.factory("procWeight[0]")
    bs.factory("puWeight[0]")
    bs.factory("weight[0]")
    bs.factory("Mzg[100,180]")
    bs.var("Mzg").setRange("ROI",mass-1.5,mass+1.5)
    bs.var("Mzg").setBins(40000,"cache")
    bs.factory("Mz[0]")
    #bs.factory("dMzg[0,25]")
    #bs.factory("dMz[0,25]")
    bs.factory("r94cat[cat1=1,cat2=2,cat3=3,cat4=4]")
    bs.defineSet("observables",
                 "Mzg,Mz,r94cat,procWeight,puWeight")
    bs.defineSet("observables_weight",
                 "Mzg,Mz,r94cat,procWeight,puWeight,weight")

    prepare_truth_models(bs,category,mass,channel,turnon,truth)
    
    build_fitting_models(bs,category,mass,order,turnon)

    gen_data_and_fit(bs, ntoys, category,mass,channel,turnon,truth)

    out_f = TFile.Open("bias_study_%s_%s_%s_ntoys%i_cat%i_m%s_order%i.root"%(channel,turnon,truth,ntoys,
                                                                             category,
                                                                             str(mass).replace('.','p'),
                                                                             order),
                       "recreate")
    bs.Write()
Esempio n. 17
0
candHist=TH1D("candidates","candidates",n_massbins,xedges)
fcLowerHist=TH2D("fcLowerLimit","fcLowerLimit",n_massbins,xedges,n_epsbins,yedges)
fcUpperHist=TH2D("fcUpperLimit","fcUpperLimit",n_massbins,xedges,n_epsbins,yedges)
plrPvalHist=TH2D("plrPval","plrPval",n_massbins,xedges,n_epsbins,yedges)
plrSigHist=TH2D("plrSig","plrSig",n_massbins,xedges,n_epsbins,yedges)
logplrHist=TH2D("logplr","logplr",n_massbins,xedges,n_epsbins,yedges)
candRescaledHist=TH1D("candidates_rescaled","candidates_rescaled",100,0,1.0)
candRescaled2DHist=TH2D("candidates_rescaled_2d","candidates_rescaled_2d",n_massbins,xedges,100,0,1.0)

w = RooWorkspace("w")
w.factory("{0}[0,0.18]".format(massVar))
w.factory("{0}[-100,100]".format(vtxVar))
w.factory("uncP[0,10]")
w.factory("cut[0,1]")

w.defineSet("myVars","{0},{1}".format(massVar,vtxVar))

dataset = RooDataSet("data","data",events,w.set("myVars"),"")

w.factory("Gaussian::vtx_model({0},mean[-50,50],sigma[0,50])".format(vtxVar))
gauss_pdf = w.pdf("vtx_model")
w.factory("EXPR::gaussExp('exp( ((@0-@1)<@3)*(-0.5*(@0-@1)^2/@2^2) + ((@0-@1)>=@3)*(-0.5*@3^2/@2^2-(@0-@1-@3)/@4))',{0},gauss_mean[0,-20,20],gauss_sigma[5,1,50],exp_breakpoint[10,0,50],exp_length[3,0.5,20])".format(vtxVar))
gaussexp_pdf = w.pdf("gaussExp")
w.defineSet("obs_1d",vtxVar)
obs=w.set("obs_1d")
vtxZRefitUnc = w.var(vtxVar)
vtxZRefitUnc.setBins(200)
gauss_params = gauss_pdf.getParameters(obs)
gaussexp_params = gaussexp_pdf.getParameters(obs)

exppol4=TF1("exppol4","exp(pol4(0))",0,100)
Esempio n. 18
0
candHist=TH1D("candidates","candidates",n_massbins,xedges)
fcLowerHist=TH2D("fcLowerLimit","fcLowerLimit",n_massbins,xedges,n_epsbins,yedges)
fcUpperHist=TH2D("fcUpperLimit","fcUpperLimit",n_massbins,xedges,n_epsbins,yedges)
plrPvalHist=TH2D("plrPval","plrPval",n_massbins,xedges,n_epsbins,yedges)
plrSigHist=TH2D("plrSig","plrSig",n_massbins,xedges,n_epsbins,yedges)
logplrHist=TH2D("logplr","logplr",n_massbins,xedges,n_epsbins,yedges)
candRescaledHist=TH1D("candidates_rescaled","candidates_rescaled",100,0,1.0)
candRescaled2DHist=TH2D("candidates_rescaled_2d","candidates_rescaled_2d",n_massbins,xedges,100,0,1.0)

w = RooWorkspace("w")
w.factory("{0}[0,0.1]".format(massVar))
w.factory("uncVZ[-100,100]")
w.factory("uncP[0,10]")
w.factory("cut[0,1]")

w.defineSet("myVars","{0},uncVZ".format(massVar))

dataset = RooDataSet("data","data",events,w.set("myVars"),"")

w.factory("Gaussian::vtx_model(uncVZ,mean[-50,50],sigma[0,50])")
gauss_pdf = w.pdf("vtx_model")
w.factory("EXPR::gaussExp('exp( ((@0-@1)<@3)*(-0.5*(@0-@1)^2/@2^2) + ((@0-@1)>=@3)*(-0.5*@3^2/@2^2-(@0-@1-@3)/@4))',uncVZ,gauss_mean[-5,-20,20],gauss_sigma[5,1,50],exp_breakpoint[10,0,50],exp_length[3,0.5,20])")
gaussexp_pdf = w.pdf("gaussExp")
w.defineSet("obs_1d","uncVZ")
obs=w.set("obs_1d")
uncVZ = w.var("uncVZ")
uncVZ.setBins(200)
gauss_params = gauss_pdf.getParameters(obs)
gaussexp_params = gaussexp_pdf.getParameters(obs)

exppol4=TF1("exppol4","exp(pol4(0))",-5,100)
Esempio n. 19
0
                   n_epsbins, yedges)
plrPvalHist = TH2D("plrPval", "plrPval", n_massbins, xedges, n_epsbins, yedges)
plrSigHist = TH2D("plrSig", "plrSig", n_massbins, xedges, n_epsbins, yedges)
logplrHist = TH2D("logplr", "logplr", n_massbins, xedges, n_epsbins, yedges)
candRescaledHist = TH1D("candidates_rescaled", "candidates_rescaled", 100, 0,
                        1.0)
candRescaled2DHist = TH2D("candidates_rescaled_2d", "candidates_rescaled_2d",
                          n_massbins, xedges, 100, 0, 1.0)

w = RooWorkspace("w")
w.factory("{0}[0,0.17]".format(massVar))
w.factory("uncVZ[-100,100]")
w.factory("uncP[0,10]")
w.factory("cut[0,1]")

w.defineSet("myVars", "{0},uncVZ".format(massVar))

dataset = RooDataSet("data", "data", events, w.set("myVars"), "")

w.factory("Gaussian::vtx_model(uncVZ,mean[-50,50],sigma[0,50])")
gauss_pdf = w.pdf("vtx_model")
w.factory(
    "EXPR::gaussExp('exp( ((@0-@1)<@3)*(-0.5*(@0-@1)^2/@2^2) + ((@0-@1)>=@3)*(-0.5*@3^2/@2^2-(@0-@1-@3)/@4))',uncVZ,gauss_mean[-5,-20,20],gauss_sigma[5,1,50],exp_breakpoint[10,0,50],exp_length[3,0.5,20])"
)
gaussexp_pdf = w.pdf("gaussExp")
w.defineSet("obs_1d", "uncVZ")
obs = w.set("obs_1d")
uncVZ = w.var("uncVZ")
uncVZ.setBins(200)
gauss_params = gauss_pdf.getParameters(obs)
gaussexp_params = gaussexp_pdf.getParameters(obs)
Esempio n. 20
0
class Wjj2DFitter:

    def __init__ (self, pars):
        self.pars = pars
        self.ws = RooWorkspace('wjj2dfitter')
        self.utils = Wjj2DFitterUtils(self.pars)
        self.useImportPars = False

        self.rangeString = None
        obs = []
        for v in self.pars.var:

            try:
                vName = self.pars.varNames[v]
            except AttributeError:
                vName = v

            obs.append(vName)
            var1 = self.ws.factory('%s[%f,%f]' % (vName, 
                                                  self.pars.varRanges[v][1], 
                                                  self.pars.varRanges[v][2])
                                   )
            var1.setUnit('GeV')
            try:
                var1.SetTitle(self.pars.varTitles[v])
            except AttributeError:
                var1.SetTitle('m_{jj}')
            var1.setPlotLabel(var1.GetTitle())
            if len(self.pars.varRanges[v][3]) > 1:
                vbinning = RooBinning(len(self.pars.varRanges[v][3]) - 1, 
                                   array('d', self.pars.varRanges[v][3]),
                                   '%sBinning' % vName)
                var1.setBinning(vbinning)
            else:
                var1.setBins(self.pars.varRanges[v][0])
            var1.Print()
            if v in self.pars.exclude:
                var1.setRange('signalRegion', self.pars.exclude[v][0],
                              self.pars.exclude[v][1])
                var1.setRange('lowSideband', var1.getMin(), 
                              self.pars.exclude[v][0])
                var1.setRange('highSideband', self.pars.exclude[v][1],
                              var1.getMax())
                self.rangeString = 'lowSideband,highSideband'

            if hasattr(self.pars, 'plotRanges'):
                var1.setRange('plotRange', self.pars.plotRanges[v][1],
                              self.pars.plotRanges[v][2])
                var1.setBins(self.pars.plotRanges[v][0], 'plotBins')
            else:
                var1.setRange('plotRange', var1.getMin(), var1.getMax())
                var1.setBins(var1.getBins(), 'plotBins')

        self.ws.defineSet('obsSet', ','.join(obs))

    def loadDataFromWorkspace(self, other, cut = None):
        #pull unbinned data from other workspace
        unbinnedData = other.data('data_unbinned')
        if not unbinnedData:
            unbinnedData = other.data('data_obs')

        if cut:
            unbinnedData = unbinnedData.reduce(cut)

        unbinnedData.Print()
        if self.pars.binData:
            #bin and import data
            unbinnedData.SetName('data_unbinned')
            getattr(self.ws, 'import')(unbinnedData)
            data = RooDataHist('data_obs', 'data_obs', other.set('obsSet'), 
                               unbinnedData)
            getattr(self.ws, 'import')(data)
        else:
            #just import data
            unbinnedData.SetName('data_obs')
            getattr(self.ws, 'import')(unbinnedData)

    def loadHistogramsFromWorkspace(self, other):
        #pull RooHist pdfs from other workspace
        pdfs = other.allPdfs()
        pdfIter = pdfs.createIterator()
        pdf = pdfIter.Next()
        while pdf:
            if pdf.IsA().InheritsFrom('RooHistPdf'):
                print 'importing',pdf.GetName(),'from old workspace'
                getattr(self.ws, 'import')(pdf)
            pdf = pdfIter.Next()

    def loadWorkspaceFromFile(self, filename, wsname = 'w', 
                              getFloatPars = True):
        print 'loading data workspace %s from file %s' % (wsname, filename)
        fin = TFile.Open(filename)
        if not fin:
            print 'failed to open the file',filename
            import os
            print 'cwd:',os.getcwd()
            print 'access of',filename,os.access(filename, os.R_OK)
            print 'list of root files in cwd'
            for f in os.listdir(os.getcwd()):
                if f[-5:] == '.root':
                    print f,len(f),len(filename)
            fin = TFile.Open(os.getcwd() + '/' + filename)
            assert(fin)

        other = fin.Get(wsname)

        #pull unbinned data from other workspace
        self.loadDataFromWorkspace(other)

        #pull in histogram pdfs to save time
        self.loadHistogramsFromWorkspace(other)

        if getFloatPars and other.loadSnapshot('fitPars'):
            self.useImportPars = True
            self.ws.saveSnapshot('importParams', other.set('floatingParams'), 
                                 True)

        # self.ws.Print()
    
    # put together a fitting model and return the pdf
    def makeFitter(self, useAlternateModels = False):
        if self.ws.pdf('total'):
            return self.ws.pdf('total')

        compPdfs = []

        for component in self.pars.backgrounds:
            # print 'getting compModels'
            compModels = getattr(self.pars, '%sModels' % component)
            if hasattr(self.pars, '%sConvModels' % component):
                convModels = getattr(self.pars, '%sConvModels' % component)
            else:
                convModels = None
            if useAlternateModels:
                print 'loading Alternate Models'
                compModels = getattr(self.pars, '%sModelsAlt' % component)
                convModels = getattr(self.pars, '%sConvModelsAlt' % component)
            # print 'compModels = %s' % compModels
            compFiles = getattr(self.pars, '%sFiles' % component)
            compPdf = self.makeComponentPdf(component, compFiles, compModels,
                                            useAlternateModels, convModels)
                
            norm = self.ws.factory('prod::f_%s_norm' % component + \
                                       '(n_%s[0.,1e6],' % component + \
                                       '%s_nrm[1.,-0.5,5.])' % component)
            self.ws.var('n_%s' % component).setConstant(True)
            if hasattr(self, '%sExpected' % component):
                self.ws.var('n_%s' % component).setVal(
                    getattr(self, '%sExpected' % component))
            compPdfs.append(
                self.ws.factory('RooExtendPdf::%s_extended(%s,%s)' % \
                                    (compPdf.GetName(), 
                                     compPdf.GetName(),
                                     norm.GetName())
                                )
                )
                                    
        self.ws.factory('r_signal[0., -200., 200.]')
        self.ws.var('r_signal').setConstant(False)

        try:
            obs = [ self.pars.varNames[x] for x in self.pars.var ]
        except AttributeError:
            obs = self.pars.var

        for component in self.pars.signals:
            compFile = getattr(self.pars, '%sFiles' % component)
            compModels = getattr(self.pars, '%sModels' % component)
            if hasattr(self.pars, '%sConvModels' % component):
                convModels = getattr(self.pars, '%sConvModels' % component)
            else:
                convModels = None
            compPdf = self.makeComponentPdf(component, compFiles, compModels,
                                            useAlternateModels, convModels)
            norm = self.ws.factory(
                "prod::f_%s_norm(n_%s[0., 1e6],r_signal)" % \
                    (component, component)
                )
            self.ws.var('n_%s' % component).setConstant(True)
            if hasattr(self, '%sExpected' % component):
                self.ws.var('n_%s' % component).setVal(
                    getattr(self, '%sExpected' % component))
            pdf = self.ws.factory('RooExtendPdf::%s_extended(%s,%s)' % \
                                      (compPdf.GetName(), 
                                       compPdf.GetName(),
                                       norm.GetName())
                                  )
            
            if (hasattr(self.pars, '%sInterference' % component)) and \
                    getattr(self.pars, '%sInterference' % component):
                getattr(self.ws, 'import') \
                    (pdf, RooFit.RenameAllNodes('interf_%sUp' % component),
                     RooFit.RenameAllVariablesExcept('interf_%sUp' % component,
                                                     ','.join(obs)),
                     RooFit.Silence()
                     )
                getattr(self.ws, 'import') \
                    (pdf, RooFit.RenameAllNodes('interf_%sDown' % component),
                     RooFit.RenameAllVariablesExcept('interf_%sDown'%component,
                                                     ','.join(obs)),
                     RooFit.Silence()
                     )
            if self.pars.includeSignal:
                compPdfs.append(pdf)

        #print compPdfs
        
        prodList = [ '%s' % (pdf.GetName()) \
                         for (idx, pdf) in enumerate(compPdfs) ]
        comps = RooArgList(self.ws.argSet(','.join(prodList)))
        getattr(self.ws, 'import')(RooAddPdf('total', 'total', comps))

        return self.ws.pdf('total')

    # define the constraints on the yields, etc that will be part of the fit.
    def makeConstraints(self):

        if self.ws.set('constraintSet'):
            return self.ws.set('constraintSet')

        constraints = []
        constrainedParameters = []
        for constraint in self.pars.yieldConstraints:
            theYield = self.ws.var('%s_nrm' % constraint)
            if not theYield.isConstant():
                self.ws.factory('RooGaussian::%s_const(%s, 1.0, %f)' % \
                                    (constraint, theYield.GetName(),
                                     self.pars.yieldConstraints[constraint])
                                )
                constraints.append('%s_const' % constraint)
                constrainedParameters.append(theYield.GetName())

        if hasattr(self.pars, 'constrainShapes'):
            for component in self.pars.constrainShapes:
                pc = self.ws.pdf(component).getParameters(self.ws.set('obsSet'))
                parIter = pc.createIterator()
                par = parIter.Next()
                while par:
                    if not par.isConstant():
                        theConst = self.ws.factory('RooGaussian::%s_const' % \
                                                       (par.GetName()) + \
                                                       '(%s, %f, %f)' % \
                                                       (par.GetName(),
                                                        par.getVal(),
                                                        par.getError())
                                                   )
                        constraints.append(theConst.GetName())
                        constrainedParameters.append(par.GetName())
                    par = parIter.Next()
                pc.IsA().Destructor(pc)

        self.ws.defineSet('constraintSet', ','.join(constraints))
        self.ws.defineSet('constrainedSet', ','.join(constrainedParameters))

        return self.ws.set('constraintSet')

    # make the constrained fitter
    def makeConstrainedFitter(self):
        if self.ws.pdf('totalFit_const'):
            return self.ws.pdf('totalFit_const')

        constraintSet = self.makeConstraints()
        fitter = self.makeFitter()

        print '\nfit constraints'
        constIter = constraintSet.createIterator()
        constraint = constIter.Next()
        constraints = []
        while constraint:
            constraint.Print()
            constraints.append(constraint.GetName())
            constraint = constIter.Next()

        if constraintSet.getSize() > 0:
            constraints.append(fitter.GetName())
            fitter = self.ws.factory('PROD::totalFit_const(%s)' % \
                                     (','.join(constraints))
                                     )
        return fitter

    # fit the data using the pdf
    def fit(self, keepParameterValues = False, overrideRangeCmd = False):
        print 'construct fit pdf ...'
        fitter = self.makeFitter()

        print 'load data ...'
        data = self.loadData()

        self.resetYields()

        constraintSet = self.makeConstraints()

        if not keepParameterValues:
            self.readParametersFromFile()

        self.resetYields()
        # print constraints, self.pars.yieldConstraints
            
        constraintCmd = RooCmdArg.none()
        if constraintSet.getSize() > 0:
            fitter = self.makeConstrainedFitter()
            constraintCmd = RooFit.Constrained()
            # constraintCmd = RooFit.ExternalConstraints(self.ws.set('constraintSet'))

        if self.useImportPars:
            self.ws.loadSnapshot('importParams')
        self.ws.Print()

        # for constraint in pars.constraints:
        #     self.ws.pdf(constraint).Print()
        # print

        rangeCmd = RooCmdArg.none()
        if self.rangeString and self.pars.doExclude and not overrideRangeCmd:
            rangeCmd = RooFit.Range(self.rangeString)

        # print 'scanning parameter values...'
        # fitter.fitTo(data, RooFit.Minos(False),
        #              RooFit.PrintEvalErrors(-1),
        #              RooFit.Warnings(False),
        #              RooFit.Minimizer("Minuit2", "scan"),
        #              RooFit.PrintLevel(0),
        #              constraintCmd,
        #              rangeCmd)

        print 'fitting ...'
        fr = fitter.fitTo(data, RooFit.Save(True),
                          # RooFit.Extended(True),
                          RooFit.Minos(False),
                          RooFit.PrintEvalErrors(-1),
                          RooFit.Warnings(False),
                          RooFit.Minimizer("Minuit2", "minimize"),
                          constraintCmd,
                          rangeCmd
                          )
        fr.Print('v')

        return fr

    # determine the fitting model for each component and return them
    def makeComponentPdf(self, component, files, models, useAlternateModels,
                         convModels):
        print 'making ComponentPdf %s' % component
        # print 'models = %s' % models
        # print 'files = %s' % files
        if convModels and not (convModels[0] == -1):
            thePdf = self.makeConvolvedPdf(component, files, models, useAlternateModels, convModels)
        elif (models[0] == -1):
            thePdf = self.makeComponentHistPdf(component, files)
        elif (models[0] == -2):
            thePdf = self.makeMorphingPdf(component, useAlternateModels, convModels)
        elif (models[0] == -3):
            pass
        else:
            thePdf = self.makeComponentAnalyticPdf(component, models, useAlternateModels)

        return thePdf

    #create a simple 2D histogram pdf
    def makeComponentHistPdf(self, component, files):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        compHist = self.utils.newEmptyHist('hist%s' % component)
        sumYields = 0.
        sumxsec = 0.
        sumExpected = 0.
        for (idx,fset) in enumerate(files):
            if hasattr(self.pars, '%scuts' % component):
                cutOverride = getattr(self.pars, '%scuts' % component)
            else:
                cutOverride = None
            filename = fset[0]
            tmpHist = self.utils.File2Hist(filename, 
                                           'hist%s_%i' % (component, idx),
                                           False,cutOverride,False,True,0)
            sumYields += tmpHist.Integral()
            sumxsec += fset[2]
            compHist.Add(tmpHist, self.pars.integratedLumi*fset[2]/fset[1])
            sumExpected += tmpHist.Integral()*fset[2]* \
                self.pars.integratedLumi/fset[1]
            print filename,'acc x eff: %.3g' % (tmpHist.Integral()/fset[1])
            print filename,'N_expected: %.1f' % \
                (tmpHist.Integral()*fset[2]*self.pars.integratedLumi/fset[1])
            #tmpHist.Print()

        #compHist.Print()
        print '%s acc x eff: %.3g' % \
            (component, sumExpected/sumxsec/self.pars.integratedLumi)
        print 'Number of expected %s events: %.1f' % (component, sumExpected)
        setattr(self, '%sExpected' % component, sumExpected)

        return self.utils.Hist2Pdf(compHist, component, 
                                   self.ws, self.pars.order)
    #create a pdf which is a convolution of any two pdf
    def makeConvolvedPdf(self, component, files, models, useAlternateModels, convModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        #If a morphing model is selected, then convolve each individual component first and then morph
        if (models[0] == -2):
            return self.makeMorphingPdf(component, useAlternateModels, convModels)

        basePdf = self.makeComponentPdf('%s_base' % component, files, models, useAlternateModels, [-1])
        convComponent = 'Global' ##Overwrite to use the same convolution model for all Pdfs
        convModel = getattr(self.pars, '%sConvModels' % convComponent)
        if useAlternateModels:
            convModel = getattr(self.pars, '%sConvModelsAlt' % convComponent)
        convPdf = self.makeComponentPdf('%s_conv' % convComponent, files, convModel, useAlternateModels, [-1])
        var = self.pars.var[0]
        try:
            vName = self.pars.varNames[var]
        except AttributeError:
            vName = var
        self.ws.factory('RooFFTConvPdf::%s(%s,%s,%s)' % \
                        (component, vName, basePdf.GetName(),
                         convPdf.GetName()))
        return self.ws.pdf(component)


    # create a pdf using the "template morphing" technique
    def makeMorphingPdf(self, component, useAlternateModels, convModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)
        
        filesNom = getattr(self.pars, '%s_NomFiles' % component)
        modelsNom = getattr(self.pars, '%s_NomModels' % component)
        filesMU = getattr(self.pars, '%s_MUFiles' % component)
        modelsMU = getattr(self.pars, '%s_MUModels' % component)
        filesMD = getattr(self.pars, '%s_MDFiles' % component)
        modelsMD = getattr(self.pars, '%s_MDModels' % component)
        filesSU = getattr(self.pars, '%s_SUFiles' % component)
        modelsSU = getattr(self.pars, '%s_SUModels' % component)
        filesSD = getattr(self.pars, '%s_SDFiles' % component)
        modelsSD = getattr(self.pars, '%s_SDModels' % component)
        if useAlternateModels:
            modelsNom = getattr(self.pars, '%s_NomModelsAlt' % component)
            modelsMU = getattr(self.pars, '%s_MUModelsAlt' % component)
            modelsMD = getattr(self.pars, '%s_MDModelsAlt' % component)
            modelsSU = getattr(self.pars, '%s_SUModelsAlt' % component)
            modelsSD = getattr(self.pars, '%s_SDModelsAlt' % component)

        # Adds five (sub)components for the component with suffixes Nom, MU, MD, SU, SD
        NomPdf = self.makeComponentPdf('%s_Nom' % component, filesNom, modelsNom, False, convModels)
        if hasattr(self, '%s_NomExpected' % component):
            setattr(self, '%sExpected' % component,
                    getattr(self, '%s_NomExpected' % component))
        MUPdf = self.makeComponentPdf('%s_MU' % component, filesMU, modelsMU, False, convModels)
        MDPdf = self.makeComponentPdf('%s_MD' % component, filesMD, modelsMD, False, convModels)
        SUPdf = self.makeComponentPdf('%s_SU' % component, filesSU, modelsSU, False, convModels)
        SDPdf = self.makeComponentPdf('%s_SD' % component, filesSD, modelsSD, False, convModels)

        fMU_comp = self.ws.factory("fMU_%s[0., -1., 1.]" % component)
        fSU_comp = self.ws.factory("fSU_%s[0., -1., 1.]" % component)

        fMU = RooFormulaVar("f_fMU_%s" % component, "1.0*@0*(@0 >= 0.)", 
                            RooArgList( fMU_comp ) )
        fMD = RooFormulaVar("f_fMD_%s" % component, "-1.0*@0*(@0 < 0.)", 
                            RooArgList( fMU_comp ) )
        fSU = RooFormulaVar("f_fSU_%s" % component, "@0*(@0 >= 0.)", 
                            RooArgList( fSU_comp ) )
        fSD = RooFormulaVar("f_fSD_%s" % component, "@0*(-1)*(@0 < 0.)", 
                            RooArgList( fSU_comp ) )
        fNom = RooFormulaVar("f_fNom_%s" % component, "(1.-abs(@0)-abs(@1))", 
                             RooArgList(fMU_comp,fSU_comp) )
        morphPdf = RooAddPdf(component,component, 
                             RooArgList(MUPdf,MDPdf,SUPdf,SDPdf,NomPdf),
                             RooArgList(fMU, fMD, fSU, fSD, fNom))
        morphPdf.SetName(component)
        getattr(self.ws, 'import')(morphPdf)
        return self.ws.pdf(component)

    # create a pdf using an analytic function.
    def makeComponentAnalyticPdf(self, component, models, useAlternateModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        pdfList = []
        systMult = None
        if ( hasattr(self.pars, '%sInterference' % component) and \
             getattr(self.pars, '%sInterference' % component) and \
             hasattr(self.pars, "%sdoSystMult" % component) and \
             getattr(self.pars, "%sdoSystMult" % component) ):
            systMult = getattr(self.pars, "%sSystMult" % component)

        for (idx,model) in enumerate(models):
            var = self.pars.var[idx]
            try:
                vName = self.pars.varNames[var]
            except AttributeError:
                vName = var

            auxModel = None
            if useAlternateModels:
                if hasattr(self.pars, '%sAuxModelsAlt' % component):
                    auxModel = getattr(self.pars, '%sAuxModelsAlt' % component)[idx]
            else:
                if hasattr(self.pars, '%sAuxModels' % component):
                    auxModel = getattr(self.pars, '%sAuxModels' % component)[idx]

            pdfList.append(self.utils.analyticPdf(self.ws, vName, model, 
                                                  '%s_%s'%(component,vName), 
                                                  '%s_%s'%(component,vName),
                                                  auxModel, systMult
                                                  )
                           )
        
        pdfListNames = [ pdf.GetName() for pdf in pdfList ]
        if len(pdfList) > 1:
            self.ws.factory('PROD::%s(%s)' % \
                                (component, ','.join(pdfListNames)))
        else:
            pdfList[0].SetName(component)
                        
        return self.ws.pdf(component)

    def loadData(self, weight = False):
        if self.ws.data('data_obs'):
            return self.ws.data('data_obs')

        unbinnedName = 'data_obs'
        if self.pars.binData:
            unbinnedName = 'data_unbinned'
        data = self.utils.File2Dataset(self.pars.DataFile, unbinnedName, 
                                       self.ws, weighted = weight)
        if self.pars.binData:
            data = RooDataHist('data_obs', 'data_obs', self.ws.set('obsSet'), 
                               data)
            getattr(self.ws, 'import')(data)
            data = self.ws.data('data_obs')

        return data

    def stackedPlot(self, var, logy = False, pdfName = None, Silent = False):
        if not pdfName:
            pdfName = 'total'

        xvar = self.ws.var(var)
        nbins = xvar.getBins()
        # if hasattr(self.pars, 'plotRanges') and not xvar.hasRange('plotRange'):
        #     xvar.setRange('plotRange', self.pars.plotRanges[var][1],
        #                   self.pars.plotRanges[var][2])
        #     xvar.setBins(self.pars.plotRanges[var][0], 'plotBins')
        # elif not xvar.hasRange('plotRange'):
        #     xvar.setRange('plotRange', xvar.getMin(), xvar.getMax())
        #     xvar.setBins(nbins, 'plotBins')

        sframe = xvar.frame(RooFit.Range('plotRange'),
                            RooFit.Bins(xvar.getBins('plotBins')))
        sframe.SetName("%s_stacked" % var)
        pdf = self.ws.pdf(pdfName)

        if isinstance(pdf, RooAddPdf):
            compList = RooArgList(pdf.pdfList())
        else:
            compList = None

        data = self.ws.data('data_obs')
        nexp = pdf.expectedEvents(self.ws.set('obsSet'))

        if not Silent:
            print pdf.GetName(),'expected: %.0f' % (nexp)
            print 'data events: %.0f' % (data.sumEntries())

        if nexp < 1:
            nexp = data.sumEntries()
        theComponents = [] 
        if self.pars.includeSignal:
            theComponents += self.pars.signals
        theComponents += self.pars.backgrounds
        data.plotOn(sframe, RooFit.Invisible(),
                    RooFit.Binning('plotBins'))
        # dataHist = RooAbsData.createHistogram(data,'dataHist_%s' % var, xvar,
        #                                       RooFit.Binning('%sBinning' % var))
        # #dataHist.Scale(1., 'width')
        # invData = RooHist(dataHist, 1., 1, RooAbsData.SumW2, 1.0, False)
        # #invData.Print('v')
        # sframe.addPlotable(invData, 'pe', True, True)
        for (idx,component) in enumerate(theComponents):
            if not Silent:
                print 'plotting',component,'...',
            if hasattr(self.pars, '%sPlotting' % (component)):
                plotCharacteristics = getattr(self.pars, '%sPlotting' % \
                                                  (component))
            else:
                plotCharacteristics = {'color' : colorwheel[idx%6],
                                       'title' : component }

            compCmd = RooCmdArg.none()
            if compList:
                compSet = RooArgSet(compList)
                if compSet.getSize() > 0:
                    compCmd = RooFit.Components(compSet)
                removals = compList.selectByName('%s*' % component)
                compList.remove(removals)

            if not Silent:
                print 'events', self.ws.function('f_%s_norm' % component).getVal()
                sys.stdout.flush()
            if abs(self.ws.function('f_%s_norm' % component).getVal()) >= 1.:
                pdf.plotOn(sframe, #RooFit.ProjWData(data),
                           RooFit.DrawOption('LF'), RooFit.FillStyle(1001),
                           RooFit.FillColor(plotCharacteristics['color']),
                           RooFit.LineColor(plotCharacteristics['color']),
                           RooFit.VLines(),
                           RooFit.Range('plotRange'),
                           RooFit.NormRange('plotRange'),
                           RooFit.Normalization(nexp, RooAbsReal.NumEvent),
                           compCmd
                           )
                tmpCurve = sframe.getCurve()
                tmpCurve.SetName(component)
                tmpCurve.SetTitle(plotCharacteristics['title'])
                if 'visible' in plotCharacteristics:
                    sframe.setInvisible(component, 
                                        plotCharacteristics['visible'])

        data.plotOn(sframe, RooFit.Name('theData'),
                    RooFit.Binning('plotBins'))
        sframe.getHist('theData').SetTitle('data')
        # theData = RooHist(dataHist, 1., 1, RooAbsData.SumW2, 1.0, True)
        # theData.SetName('theData')
        # theData.SetTitle('data')
        # sframe.addPlotable(theData, 'pe')

        if (logy):
            sframe.SetMinimum(0.01)
            sframe.SetMaximum(1.0e6)
        else:
            sframe.SetMaximum(sframe.GetMaximum()*1.35)
            pass

        excluded = (var in self.pars.exclude)
        bname = var
        if not excluded:
            for v in self.pars.exclude:
                if hasattr(self.pars, 'varNames') and \
                       (self.pars.varNames[v] == var):
                    excluded = True
                    bname = v
        if excluded:
            blinder = TBox(self.pars.exclude[bname][0], sframe.GetMinimum(),
                           self.pars.exclude[bname][1], sframe.GetMaximum())
            # blinder.SetName('blinder')
            # blinder.SetTitle('signal region')
            blinder.SetFillColor(kBlack)
            if self.pars.blind:  
                blinder.SetFillStyle(1001)
            else:
                blinder.SetFillStyle(0)
            blinder.SetLineStyle(2)
            sframe.addObject(blinder)
        elif self.pars.blind:
            if not Silent:
                print "blind but can't find exclusion region for", var
                print 'excluded',excluded,self.pars.exclude
                print 'hiding data points'
            sframe.setInvisible('theData', True)
        else:
            sframe.setInvisible('theData', False)

        #sframe.GetYaxis().SetTitle('Events / GeV')
        # dataHist.IsA().Destructor(dataHist)
        if not Silent:
            print

        xvar.setBins(nbins)

        return sframe

    def readParametersFromFile(self, fname=None):
        if (not fname):
            fname = self.pars.initialParametersFile
        
        if isinstance(fname, str):
            flist = [ fname ]
        else:
            flist = fname

        for tmpName in flist:
            if len(tmpName) > 0:
                print 'loading parameters from file',tmpName
                self.ws.allVars().readFromFile(tmpName)

    def expectedFromPars(self):
        components = self.pars.signals + self.pars.backgrounds
        for component in components:
            theYield = self.ws.var('n_%s' % component)
            setattr(self, '%sExpected' % component, theYield.getVal())

    def initFromExplicitVals(self,opts):
        #,init_diboson= -1.0,init_WpJ=-1.0,init_top=-1.0,init_ZpJ=-1.0,init_QCD=-1.0
        components = ['diboson', 'top', 'WpJ', 'ZpJ', 'QCD', 'WHbb']
        for component in components:
            #double init
            init = getattr(opts, 'ext%s' % component)
            #init = -2.0
            #setattr(self,init, 'init_%s' % component)
            #init = init_%s % component
            #print "init=", init
            #init = self.ws.var('init_%s' % component)
            #init.setVal(100.0)
            #init.setVal('init_%s' % component)
            #init = theYield.getVal()
            if (init>0.):
                print 'setting initial value for ',component,' to ',init
                setattr(self, '%sInitial' % component, init)


    def resetYields(self):
        if self.ws.data('data_obs'):
            Ndata = self.ws.data('data_obs').sumEntries()
        else:
            Ndata = 10000.
        print 'resetting yields...'
        components = self.pars.signals + self.pars.backgrounds
        for component in components:
            theYield = self.ws.var('n_%s' % component)
            theNorm = self.ws.var('%s_nrm' % component)
            if hasattr(self, '%sInitial' % component):
                print 'explicitly setting initial value for ',component
                theYield.setVal(getattr(self, '%sInitial' % component))
                theNorm.setVal(1.0)
                theNorm.setConstant()
            else:
                fracofdata = -1.
                if hasattr(self.pars, '%sFracOfData' % component):
                    fracofdata = getattr(self.pars, '%sFracOfData' % component)
                if (fracofdata >= 0.):
                    print 'explicitly setting ', component,' yield to be', fracofdata,' of data'
                    theYield.setVal(fracofdata*Ndata)
                elif hasattr(self, '%sExpected' % component):
                    theYield.setVal(getattr(self, '%sExpected' % component))
                else:
                    print 'no expected value for',component
                    theYield.setVal(Ndata/len(components))
            if theNorm and not theNorm.isConstant():
                theNorm.setVal(1.0)
            if component in self.pars.yieldConstraints:
                theYield.setError(theYield.getVal() * \
                                  self.pars.yieldConstraints[component])
                if theNorm:
                    theNorm.setError(self.pars.yieldConstraints[component])
            else:
                theYield.setError(sqrt(theYield.getVal()))
            theYield.Print()

    def generateToyMCSet(self,var,inputPdf,outFileName,NEvts):
        fMC = TFile(outFileName, "RECREATE");
#        thevar = self.ws.var(var);
        print 'thevar='
        print var
#        print thevar
        print '...'
#        varList = RooArgList()
#        varList.add(self.ws.var(var))
        toymc = inputPdf.generate(RooArgSet(self.ws.var(var)),NEvts);
        tMC = toymc.tree();
        fMC.cd();
        tMC.Write();
        fMC.Close();

    


    def legend4Plot(plot, left = False):
        if left:
            theLeg = TLegend(0.2, 0.62, 0.55, 0.92, "", "NDC")
        else:
            theLeg = TLegend(0.60, 0.62, 0.92, 0.92, "", "NDC")
        theLeg.SetName('theLegend')

        theLeg.SetBorderSize(0)
        theLeg.SetLineColor(0)
        theLeg.SetFillColor(0)
        theLeg.SetFillStyle(0)
        theLeg.SetLineWidth(0)
        theLeg.SetLineStyle(0)
        theLeg.SetTextFont(42)
        theLeg.SetTextSize(.045)

        entryCnt = 0
        for obj in range(0, int(plot.numItems())):
            objName = plot.nameOf(obj)
            if (not plot.getInvisible(objName)):
                theObj = plot.getObject(obj)
                objTitle = theObj.GetTitle()
                if len(objTitle) < 1:
                    objTitle = objName
                dopts = plot.getDrawOptions(objName).Data()
                # print 'obj:',theObj,'title:',objTitle,'opts:',dopts,'type:',type(dopts)
                if theObj.IsA().InheritsFrom('TNamed'):
                    theLeg.AddEntry(theObj, objTitle, dopts)
                    entryCnt += 1
        theLeg.SetY1NDC(0.9 - 0.05*entryCnt - 0.005)
        theLeg.SetY1(theLeg.GetY1NDC())
        return theLeg

    legend4Plot = staticmethod(legend4Plot)
    # dataHist = utils.File2Hist(params.MCDirectory + \
    #                                'RD_mu_HWWMH250_CMSSW525_private.root',
    #                            'dataHist')
    # dataHist.Print()
    # dataHist.Draw('colz')
    # gPad.Update()
    # gPad.WaitPrimitive()

    theWS = RooWorkspace()
    theWS.factory('%s[%f,%f]' %
                  (params.var[0], params.varRanges[params.var[0]][1],
                   params.varRanges[params.var[0]][2]))
    theWS.factory('%s[%f,%f]' %
                  (params.var[1], params.varRanges[params.var[1]][1],
                   params.varRanges[params.var[1]][2]))
    theWS.defineSet('obsSet', ','.join(params.var))

    #theWS.Print()
    # utils.Hist2Pdf(dataHist, "H250SignalHist", theWS)
    #theWS.Print()

    # dataset = utils.File2Dataset(params.MCDirectory + \
    #                                  'RD_mu_HWWMH250_CMSSW525_private.root',
    #                              "H250SignalData", theWS)
    # dataset.Print()

    print

    for model in range(10):
        utils.analyticPdf(theWS, params.var[0], model, 'pdf_%i' % model,
                          '%i_%s' % (model, params.var[0]))