def generate(histList, varName, varLow, varHigh, histSig="", weightSig=0.):
    """
    Generate toy data

    @param histList List of histograms
    @param varname Variable name to use
    @param varLow Lower edge of left bin
    @param varHigh Upper edge of right bin
    @param histSig Optional signal histogram
    @param weightSig Optional signal weight
    """
    
    testHist_pred = TH1D()
    for (iHist, hist) in enumerate(histList):
        if not iHist:
            testHist_pred = hist.Clone("hPRED")
        else:
            testHist_pred.Add(hist)

    testHist_pred_ds = TH1D("hPSDATA", "hPSDATA", testHist_pred.GetNbinsX(), testHist_pred.GetXaxis().GetBinLowEdge(1), testHist_pred.GetXaxis().GetBinUpEdge(testHist_pred.GetNbinsX()))

    nEvents_pred = int(testHist_pred.Integral())
    print "nEvents_pred = %d" % nEvents_pred

    var = RooRealVar(varName, varName, varLow, varHigh)

    dh_pred = RooDataHist("dhPSDATA", "dhPSDATA", RooArgList(var), RooFit.Import(testHist_pred))

    ph_pred = RooHistPdf("phPSDATA", "phPSDATA", RooArgSet(var), dh_pred)

    ds_pred = ph_pred.generate(RooArgSet(var), nEvents_pred)

    testHist_pred_ds = ds_pred.fillHistogram(testHist_pred_ds, RooArgList(var))

    return testHist_pred_ds
Exemplo n.º 2
0
def performFitInLeptonAbsEta(data_histogram, signal_histogram, bkg1_histogram,
                             bkg2_histogram):
    N_Data = data_histogram.Integral()
    N_signal = signal_histogram.Integral()
    N_bkg1 = bkg1_histogram.Integral()
    N_bkg2 = bkg2_histogram.Integral()
    leptonAbsEta = RooRealVar("leptonAbsEta", "leptonAbsEta", 0., 3.)
    variables = RooArgList()
    variables.add(leptonAbsEta)
    variable_set = RooArgSet()
    variable_set.add(leptonAbsEta)

    lowerBound = 0
    upperBound = N_Data * 2

    data_RooDataHist = RooDataHist("data", "dataset with leptonAbsEta",
                                   variables, data_histogram)
    signal_RooDataHist = RooDataHist("rh_signal", "signal", variables,
                                     signal_histogram)
    bkg1_RooDataHist = RooDataHist("rh_bkg1", "bkg1", variables,
                                   bkg1_histogram)
    bkg2_RooDataHist = RooDataHist("rh_bkg2", "bkg2", variables,
                                   bkg2_histogram)

    signal_RooHistPdf = RooHistPdf("pdf_signal", "Signal PDF", variable_set,
                                   signal_RooDataHist, 0)
    signal_RooHistPdf = RooHistPdf("pdf_signal", "Signal PDF", variable_set,
                                   signal_RooDataHist, 0)
Exemplo n.º 3
0
 def generate_hist(self, hist, varname, n):
     _var = RooRealVar(varname, varname, hist.GetMean())
     _dh = RooDataHist("dh", "dh", RooArgList(_var), hist)
     _pdf = RooHistPdf("pdf", "pdf", RooArgSet(_var), _dh)
     _ds = _pdf.generateBinned(RooArgSet(_var), n)
     _h = _ds.createHistogram('hist', _var)
     #_h.Draw()
     #raw_input('press <enter> to continue...')
     return copy.deepcopy(_h)
Exemplo n.º 4
0
 def generate_hist(self, hist, varname, n):
     _var = RooRealVar(varname, varname, hist.GetMean())
     _dh = RooDataHist("dh", "dh", RooArgList(_var), hist)
     _pdf = RooHistPdf("pdf", "pdf", RooArgSet(_var), _dh)
     _ds = _pdf.generateBinned(RooArgSet(_var), n)
     _h = _ds.createHistogram('hist', _var)
     #_h.Draw()
     #raw_input('press <enter> to continue...')
     return copy.deepcopy(_h)
Exemplo n.º 5
0
def makeHistPdf(hist, ws, x):
    theVars = RooArgList(x)
    v = RooArgSet(x)
    dataHist = RooDataHist(hist.GetName() + '_dh', 'dataHist', theVars, hist)
    hpdf = RooHistPdf(hist.GetName() + '_pdf', 'hist pdf', v, dataHist)
    getattr(ws, 'import')(hpdf)
    return hpdf
Exemplo n.º 6
0
def get_roofit_model( histograms, fit_boundaries, name = 'model' ):
    data_label = 'data'
    samples = sorted( histograms.keys() )
    samples.remove( data_label )
    roofit_histograms = {}
    roofit_pdfs = {}
    roofit_variables = {}
    variables = RooArgList()
    variable_set = RooArgSet()

    fit_variable = RooRealVar( name , name, fit_boundaries[0], fit_boundaries[1] )
    variables.add( fit_variable )
    variable_set.add( fit_variable )
    
    roofit_histograms[data_label] = RooDataHist( data_label,
                                                     data_label,
                                                     variables,
                                                     histograms[data_label] )
    
    pdf_arglist = RooArgList()
    variable_arglist = RooArgList()
    N_total = histograms[data_label].Integral() * 2
    N_min = 0
    for sample in samples:
        roofit_histogram = RooDataHist( sample, sample, variables, histograms[sample] )
        roofit_histograms[sample] = roofit_histogram
        roofit_pdf = RooHistPdf ( 'pdf' + sample, 'pdf' + sample, variable_set, roofit_histogram, 0 )
        roofit_pdfs[sample] = roofit_pdf
        roofit_variable = RooRealVar( sample, "number of " + sample + " events", histograms[sample].Integral(), N_min, N_total, "event" )
        roofit_variables[sample] = roofit_variable
        pdf_arglist.add( roofit_pdf )
        variable_arglist.add( roofit_variable )
        
    model = RooAddPdf( name, name, pdf_arglist, variable_arglist )
    return model, roofit_histograms, fit_variable
Exemplo n.º 7
0
    def _make_underlying_model(self):
        self.pdfs = {}
        self.yields = {}  # yields are plain floats
        self.ryields = {}  # keep track of roofit objects for memory management
        nbins, xmin, xmax = self.plot.histos[0].GetBinning()
        self.xvar = RooRealVar("x", "x", xmin, xmax)
        self.xvar.setBins(nbins)
        self.pdfs = {}
        self.hists = []
        pdfs = RooArgList()
        yields = RooArgList()
        for compname, comp in self.plot.histosDict.iteritems():
            if comp.weighted.Integral() == 0:
                continue
            assert (isinstance(comp, Histogram))
            hist = RooDataHist(compname, compname, RooArgList(self.xvar),
                               comp.weighted)
            SetOwnership(hist, False)
            # self.hists.append(hist)
            pdf = RooHistPdf(compname, compname, RooArgSet(self.xvar), hist)
            self.pdfs[compname] = pdf
            # self.pdfs[compname].Print()
            pdfs.add(pdf)
            nevts = comp.Integral(xmin=xmin, xmax=xmax)
            nmin = min(0, nevts * (1 - comp.uncertainty))
            nmax = nevts * (1 + comp.uncertainty)
            theyield = RooRealVar('n{}'.format(compname),
                                  'n{}'.format(compname), nevts, nmin, nmax)
            self.ryields[compname] = theyield
            self.yields[compname] = nevts
            yields.add(theyield)

        self.underlying_model = RooAddPdf('model', 'model', pdfs, yields)
Exemplo n.º 8
0
	def fit(self, save_to, signal_name=None, fix_p3=False, fit_range=[300., 1200.], fit_strategy=1):
		# Run a RooFit fit

		# Create background PDF
		p1 = RooRealVar('p1','p1',args.p1,0.,100.)
		p2 = RooRealVar('p2','p2',args.p2,0.,60.)
		p3 = RooRealVar('p3','p3',args.p3,-10.,10.)
		if args.fix_p3:
			p3.setConstant()
		background_pdf = RooGenericPdf('background_pdf','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(self.collision_energy,self.collision_energy,self.collision_energy),RooArgList(self.mjj_,p1,p2,p3))
		background_pdf.Print()
		data_integral = data_histogram.Integral(data_histogram.GetXaxis().FindBin(float(fit_range[0])),data_histogram.GetXaxis().FindBin(float(fit_range[1])))
		background_norm = RooRealVar('background_norm','background_norm',data_integral,0.,1e+08)
		background_norm.Print()

		# Create signal PDF and fit model
		if signal_name:
			signal_pdf = RooHistPdf('signal_pdf', 'signal_pdf', RooArgSet(self.mjj_), self.signal_roohistograms_[signal_name])
			signal_pdf.Print()
			signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+05,1e+05)
			signal_norm.Print()
			model = RooAddPdf("model","s+b",RooArgList(background_pdf,signal_pdf),RooArgList(background_norm,signal_norm))
		else:
			model = RooAddPdf("model","b",RooArgList(background_pdf),RooArgList(background_norm))

		# Run fit
		res = model.fitTo(data_, RooFit.Save(kTRUE), RooFit.Strategy(fit_strategy))

		# Save to workspace
		self.workspace_ = RooWorkspace('w','workspace')
		#getattr(w,'import')(background,ROOT.RooCmdArg())
		getattr(self.workspace_,'import')(background_pdf,RooFit.Rename("background"))
		getattr(self.workspace_,'import')(background_norm,ROOT.RooCmdArg())
		getattr(self.workspace_,'import')(self.data_roohistogram_,RooFit.Rename("data_obs"))
		getattr(self.workspace_, 'import')(model, RooFit.Rename("model"))
		if signal_name:
			getattr(self.workspace_,'import')(signal_roohistogram,RooFit.Rename("signal"))
			getattr(self.workspace_,'import')(signal_pdf,RooFit.Rename("signal_pdf"))
			getattr(self.workspace_,'import')(signal_norm,ROOT.RooCmdArg())
	
		self.workspace_.Print()
		self.workspace_.writeToFile(save_to)
		if signal_name:
			roofit_results[signal_name] = save_to
		else:
			roofit_results["background"] = save_to
Exemplo n.º 9
0
def get_num_sig_bkg(hist_DataTemplate, hist_SignalTemplate,
                    hist_BackgdTemplate, fit_range_min, fit_range_max):
    '''Given 3 input histograms (TH1F), and a fit range, this function finds
    the amount of signal and background that sum up to the data histogram.
    It does histogram fits.'''
    # Find range of data template
    data_min = hist_DataTemplate.GetXaxis().GetXmin()
    data_max = hist_DataTemplate.GetXaxis().GetXmax()

    # Create basic variables
    x = RooRealVar("x", "x", data_min, data_max)
    x.setBins(hist_DataTemplate.GetXaxis().GetNbins())  # Binned x values
    nsig = RooRealVar("nsig", "number of signal events", 0,
                      hist_DataTemplate.Integral())
    nbkg = RooRealVar("nbkg", "number of background events", 0,
                      hist_DataTemplate.Integral())

    # Create RooDataHists from input TH1Fs
    dh = RooDataHist("dh", "dh", RooArgList(x), hist_DataTemplate)
    ds = RooDataHist("ds", "ds", RooArgList(x), hist_SignalTemplate)
    db = RooDataHist("db", "db", RooArgList(x), hist_BackgdTemplate)

    # Create Probability Distribution Functions from Monte Carlo
    sigPDF = RooHistPdf("sigPDF", "sigPDF", RooArgSet(x), ds)
    bkgPDF = RooHistPdf("bkgPDF", "bkgPDF", RooArgSet(x), db)

    model = RooAddPdf("model", "(g1+g2)+a", RooArgList(bkgPDF, sigPDF),
                      RooArgList(nbkg, nsig))

    # Find the edges of the bins that contain the fit range min/max
    data_min = hist_DataTemplate.GetXaxis().GetBinLowEdge(
        hist_DataTemplate.GetXaxis().FindFixBin(fit_range_min))
    data_max = hist_DataTemplate.GetXaxis().GetBinUpEdge(
        hist_DataTemplate.GetXaxis().FindFixBin(fit_range_max))

    r = model.fitTo(dh, RooFit.Save(), RooFit.Minos(0),
                    RooFit.PrintEvalErrors(0), RooFit.Extended(),
                    RooFit.Range(data_min, data_max))
    r.Print("v")

    #print nsig.getVal(), nsig.getError(), nbkg.getVal(), nbkg.getError()
    return [nsig.getVal(), nsig.getError(), nbkg.getVal(), nbkg.getError()]
Exemplo n.º 10
0
def generate(histList, varName, varLow, varHigh, histSig="", weightSig=0.):
    """
    Generate toy data

    @param histList List of histograms
    @param varname Variable name to use
    @param varLow Lower edge of left bin
    @param varHigh Upper edge of right bin
    @param histSig Optional signal histogram
    @param weightSig Optional signal weight
    """

    testHist_pred = TH1D()
    for (iHist, hist) in enumerate(histList):
        if not iHist:
            testHist_pred = hist.Clone("hPRED")
        else:
            testHist_pred.Add(hist)

    testHist_pred_ds = TH1D(
        "hPSDATA", "hPSDATA", testHist_pred.GetNbinsX(),
        testHist_pred.GetXaxis().GetBinLowEdge(1),
        testHist_pred.GetXaxis().GetBinUpEdge(testHist_pred.GetNbinsX()))

    nEvents_pred = int(testHist_pred.Integral())
    print "nEvents_pred = %d" % nEvents_pred

    var = RooRealVar(varName, varName, varLow, varHigh)

    dh_pred = RooDataHist("dhPSDATA", "dhPSDATA", RooArgList(var),
                          RooFit.Import(testHist_pred))

    ph_pred = RooHistPdf("phPSDATA", "phPSDATA", RooArgSet(var), dh_pred)

    ds_pred = ph_pred.generate(RooArgSet(var), nEvents_pred)

    testHist_pred_ds = ds_pred.fillHistogram(testHist_pred_ds, RooArgList(var))

    return testHist_pred_ds
Exemplo n.º 11
0
def generate(histList,varName,varLow,varHigh,histSig="",weightSig=0.):
    testHist_pred = TH1D()
    for (iHist,hist) in enumerate(histList):
        if not iHist:
            testHist_pred = hist.Clone("hPRED")
        else:
            testHist_pred.Add(hist)

    testHist_pred_ds = TH1D("hPSDATA","hPSDATA",testHist_pred.GetNbinsX(),testHist_pred.GetXaxis().GetBinLowEdge(1),testHist_pred.GetXaxis().GetBinUpEdge(testHist_pred.GetNbinsX()))

    nEvents_pred = int(testHist_pred.Integral())
    print "nEvents_pred = %d" % nEvents_pred

    var = RooRealVar(varName,varName,varLow,varHigh)

    dh_pred = RooDataHist("dhPSDATA","dhPSDATA",RooArgList(var),RooFit.Import(testHist_pred))

    ph_pred = RooHistPdf("phPSDATA","phPSDATA",RooArgSet(var),dh_pred)

    ds_pred = ph_pred.generate(RooArgSet(var),nEvents_pred)

    testHist_pred_ds = ds_pred.fillHistogram(testHist_pred_ds,RooArgList(var))

    return testHist_pred_ds
Exemplo n.º 12
0
def makePDFs(Files, pdf_list, evntCount):
    for (inputMass, inputFilename) in Files:
        histo = load_histos(inputFilename)
        evntCount.append(histo.Integral())
        # could construct name and title from inputmass
        if 'nom' in inputFilename:
            myString = inputFilename.partition("230_")[2].partition(
                "_result")[0] + str(inputMass)
        else:
            myString = inputFilename.partition("jes_")[2].partition(
                "_result")[0] + str(inputMass)
        # Convert the TH1F Histogram (data_hist) into a RooDataHist object
        data_hist = RooDataHist(myString, myString, RooArgList(x), histo)
        # Turn the RooDataHist object into a RooHistPdf object
        pdf = RooHistPdf(myString, myString, RooArgSet(x), data_hist)
        # both the data_hist and pdf must survive
        pdf_list.append([data_hist, pdf])
    def Hist2Pdf(self, hist, pdfName, ws, order=0):
        if ws.pdf(pdfName):
            return ws.pdf(pdfName)

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

        varList = RooArgList()
        for v in obs:
            varList.add(ws.var(v))
        newHist = RooDataHist(pdfName + '_hist', pdfName + '_hist', varList,
                              hist)

        thePdf = RooHistPdf(pdfName, pdfName, RooArgSet(varList), newHist,
                            order)
        getattr(ws, 'import')(thePdf)

        return ws.pdf(pdfName)
Exemplo n.º 14
0
    def _make_underlying_model(self):
        self.pdfs = {}
        self.yields = {}  # yields are plain floats
        self.ryields = {}  # keep track of roofit objects for memory management
        h = self._histos[0]
        nbins = h.GetXaxis().GetNbins()
        xmin = h.GetXaxis().GetXmin()
        xmax = h.GetXaxis().GetXmax()
        self.xvar = RooRealVar("x", "x", xmin, xmax)
        self.xvar.setBins(nbins)
        self.pdfs = {}
        self.hists = []
        pdfs = RooArgList()
        yields = RooArgList()
        for histo in self._histos:
            if histo.Integral() == 0:
                continue
            compname = histo.GetName()
            hist = RooDataHist(compname, compname, RooArgList(self.xvar),
                               histo)
            SetOwnership(hist, False)
            # self.hists.append(hist)
            pdf = RooHistPdf(compname, compname, RooArgSet(self.xvar), hist)
            self.pdfs[compname] = pdf
            # self.pdfs[compname].Print()
            pdfs.add(pdf)
            nevts = histo.Integral()
            uncertainty = self._uncertainty
            nmin = min(0, nevts * (1 - uncertainty))
            nmax = nevts * (1 + uncertainty)
            theyield = RooRealVar('n{}'.format(compname),
                                  'n{}'.format(compname), nevts, nmin, nmax)
            self.ryields[compname] = theyield
            self.yields[compname] = nevts
            yields.add(theyield)

        self.underlying_model = RooAddPdf('model', 'model', pdfs, yields)
Exemplo n.º 15
0
def broadenspec(ms, E_0):
    spec = decayspec(ms, E_0)
    smear = core(E_0_center)
    newspec = TH1D("", "", spec.GetNbinsX(), -17.5, 17.5)
    for i in range(1, spec.GetNbinsX() + 1):
        newspec.SetBinContent(i, spec.GetBinContent(i))

    #x = RooRealVar("x","x",-30+E_0_center, 5+E_0_center)
    x = RooRealVar("x", "x", -17.5, 17.5)
    data = RooDataHist("", "", RooArgList(x), newspec)
    specpdf = RooHistPdf("", "", RooArgSet(x), data)
    #y = RooRealVar("y","y",-30, 5)
    x.setBins(10000)
    smearpdf = RooFit.bindPdf(smear, x)
    fft = RooFFTConvPdf("tt", "tt", x, specpdf, smearpdf)
    #fft.setShift(0, -18574)
    #c1 = TCanvas()
    #frame = x.frame()
    #fft.plotOn(frame)
    #frame.Draw()
    tf = fft.asTF(RooArgList(x))
    tf.SetNpx(10000)
    rtf = tf.Clone()
    return rtf
Exemplo n.º 16
0
# Not to be included in the Moment Morphing (just a check)
file3 = R.TFile(f3)
hist3 = file3.Get('my_model_hist')
hist3.SetDirectory(0)
hist3_events = hist3.Integral()

# Setup Workspace and frame
w = R.RooWorkspace('w')
x = w.factory('x[70,230]')
x.setBins(32)
frame = x.frame()

# Z = 125 GeV
data_hist1 = RooDataHist('dhist1', 'dhist1', RooArgList(x), hist1)
pdf1 = RooHistPdf('phist1', 'phist1', RooArgSet(x), data_hist1)
pdf1.plotOn(frame, RooFit.LineColor(R.kGreen),
            RooFit.Normalization(hist1_events))
# Z = 175 GeV
data_hist2 = RooDataHist('dhist2', 'dhist2', RooArgList(x), hist2)
pdf2 = RooHistPdf('phist2', 'phist2', RooArgSet(x), data_hist2)
pdf2.plotOn(frame, RooFit.LineColor(R.kGreen),
            RooFit.Normalization(hist2_events))

# Not to be included in the Moment Morphing (just a check)
data_hist3 = RooDataHist('dhist3', 'dhist3', RooArgList(x), hist3)
pdf3 = RooHistPdf('phist3', 'phist3', RooArgSet(x), data_hist3)
pdf3.plotOn(frame, RooFit.LineColor(R.kBlue),
            RooFit.Normalization(hist3_events))
data_hist3.plotOn(frame)
# Create a RooArgList to store pdfs and fill it
        mmgMassFunc = w.factory('''FormulaVar::mmgMassFunc(
            "((mmgMass - mmgMode) / mmgScale + mmgMode)  - fPho*phoScale/100.",
            {mmgMass, mmgMode[91.2,70,110], mmgScale[1.,0.1,5], fPho, phoScale}
            )''')
        mmgMode = w.var('mmgMode')
        mmgScale = w.var('mmgScale')

        ## Get the nominal model for translation, use rho=2
        model = RooKeysPdf('model', 'model', mmgMass, mmgData, RooKeysPdf.NoMirror, 2)

        ## Sample nominal model to binned data, no Poisson fluctuation
        modelHist = model.createHistogram('mmgMass', 10000)
        modelDH = RooDataHist('modelDH', 'modelDH', RooArgList(mmgMass), modelHist)

        ## Use the sampled model to build a transformed model, interpolation order=2
        tmodel = RooHistPdf('tmodel', 'tmodel', RooArgList(mmgMassFunc),
                            RooArgList(mmgMass), modelDH, 2)


        ## Find the mode of the tmodel.
        mmgMode.setVal(modelHist.GetBinCenter(modelHist.GetMaximumBin()))
        mmgMode.setConstant(True)
        fPho.setConstant(True)

        ## Fit the photon scale
        phoScale.setConstant(False)
        mmgScale.setConstant(True)

        fac, s = 1, 0

        mmgMass.SetTitle('scaledMmgMass3(%f, mmgMass, mmMass)' % fac)
        phoPtRangeMod = (phoPtRange[0] * fac, phoPtRange[1] * fac)
Exemplo n.º 18
0
full_ch.Add("/mnt/home/kklimaszewski/LHCb/Bs2JpsieePhi/M_Bs_Fits/mc/DVNtuples_Bs2JpsieePhi_13154001_MCfull_R14ac_TupleBsDetached_PIDCorr_S21_NewSel_tupleB.root")
# Run selection
ch = full_ch.CopyTree("sigmam>0. && sigmam<250. && time>0.3 && time<14. && sigmat<0.12 && BDT_response_NewSel>0.2 && eminus_bremmult==0 && eplus_bremmult==0")
#fit.mass.setBins(_comp['config']['bins'])
# Create hist PDF
data = RooDataSet(
        'data_set',
        '',
        RooArgSet(x),
        RooFit.Import(ch)
        )
hist = data.binnedClone()
p1 = RooHistPdf(
        'histpdf',
        '',
        RooArgSet(x),
        hist,
        2  # Order of interpolation function
        )
#p2 = RooGaussian(
p2 = RooGaussModel(
    "comp_2",
    "",
    x,
    mean,
    sigma
    )

#pdf = RooNumConvPdf("pdf", 'convolution', x, p1, p2)
x.setBins(10000,"fft") ;
pdf = RooFFTConvPdf("pdf", 'convolution', x, p2, p1)
Exemplo n.º 19
0
cf_p = TCanvas('cf_p', 'fit, parametrized')

cf_p_frame = x.frame()
data.plotOn(cf_p_frame)
model.plotOn(cf_p_frame)
cf_p_frame.Draw()


######### model definition, template  

nsig_tpl = 10000
nbgd_tpl = 1000000

exp_sig_data = sig.generate(RooArgSet(x), nsig_tpl)
exp_sig_hist = exp_sig_data.binnedClone()
tsig = RooHistPdf('tsig', 'tsig', RooArgSet(x), exp_sig_hist)

exp_bgd_data = bgd.generate(RooArgSet(x), nbgd_tpl)
exp_bgd_hist = exp_bgd_data.binnedClone()
tbgd = RooHistPdf('tbgd', 'tbgd', RooArgSet(x), exp_bgd_hist)

# modelsig = RooAddPdf("modelsig", "modelsig", RooArgList(tsig), RooArgList(vysig))
# tmodel = RooAddPdf("tmodel", "tmodel", RooArgList(tsig), RooArgList(vysig))
tmodel = RooAddPdf("tmodel", "tmodel", RooArgList(tsig, tbgd),
                   RooArgList(vysig, vybgd))

######### data generation, template 

tdata = tmodel.generate(RooArgSet(x), ndata)

######### fit, template
Exemplo n.º 20
0
def shapeCards(datahistosFile, histosFile, signalFile, signalSample, hist,
               signalMass, minMass, maxMass, outputName, outputFileTheta):
    """function to run Roofit and save workspace for RooStats"""
    warnings.filterwarnings(
        action='ignore',
        category=RuntimeWarning,
        message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >')

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

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

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

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

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

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

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

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

    hPseudo = createPseudoExperiment(hBkg, bkgAcc)

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

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

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

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

    hBkgSyst = {}
    hBkgSystDataHist = {}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    print ws
    
    aset = RooArgSet(mass)

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

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


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

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

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

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

        
        del cdf
        del pdf
    

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    args = parser.parse_args()

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

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

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

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

    # sort masses
    masses.sort()

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

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

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

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

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

    sqrtS = args.sqrtS

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

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

    for mass in masses:

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

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

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

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

        if args.fixP3: p3.setConstant()

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

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

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

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

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

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

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

        #Extend PDFs

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        beffUnc = 0.3
        boffUnc = 0.06

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

    print '>> Datacards and workspaces created and stored in %s/' % (
        os.path.join(os.getcwd(), args.output_path))
Exemplo n.º 23
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    parser.add_argument("-p", "--pulser", help="is Pulser")
    parser.add_argument("-e", "--energy", help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    isPulser = False
    if args.pulser:
        print "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser = True

    if args.energy:
        print 'Setting beam energy to ' + args.energy
        beamEnergy = float(args.energy)
        myhist.setEnergyScales(beamEnergy)

#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax = 10
    nTrkMin = 2
    nPosMax = 3
    ######  two tracks (e+/e-) exactly
    #    nTrkMax=2
    #    nTrkMin=2
    #    nPosMax=1
    ###### more than 1 electron
    #    nTrkMax=10
    #    nTrkMin=3
    #    nPosMax=1
    ###################
    #v0 cuts
    v0Chi2 = 10
    #ESum -- full region
    v0PzMax = 1.2 * beamEnergy
    v0PzMin = 0.55 * beamEnergy
    #ESum -- Radiative region
    #    v0PzMax=1.2
    #    v0PzMin=0.80

    v0PyMax = 0.2  #absolute value
    v0PxMax = 0.2  #absolute value
    v0VzMax = 25.0  # mm from target
    v0VyMax = 1.0  # mm from target
    v0VxMax = 2.0  # mm from target
    #  track quality cuts
    trkChi2 = 10
    beamCut = 0.8 * beamEnergy
    minPCut = 0.05
    trkPyMax = 0.2
    trkPxMax = 0.2
    #    slopeCut=0.03
    slopeCut = 0.0
    trkDeltaT = 4  #ns
    cluDeltaT = 2  #ns
    cluTrkDeltaT = 4  #ns
    ##############
    #  ESum slices; upper limits
    nSlicesESum = 5
    esumMin = 0.55
    esumMax = 1.2
    sliceSizeESum = 0.1  #100MeV starting at esumMin
    ##############
    trackKiller = False
    tkThreshold = 0.5  #GeV, below this start killing tracks
    tkThreshEff = 1.0
    tkLowPoint = 0.20
    tkLowPointEff = 0.40
    #    tkSlope=2.6
    #    tkIntercept=-0.04
    #calculate tkSlope and Intercept
    tkSlope = (tkThreshEff - tkLowPointEff) / (tkThreshold - tkLowPoint)
    tkIntercept = tkThreshEff - tkSlope * tkThreshold

    ##############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = False
    useGBL = True

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0
    nPassV0Cuts = 0
    nPassTrkCuts = 0
    nPassNCand = 0
    nPassECalMatch = 0
    nFakeTri = 0

    if 1 == 0:
        extraElectronProb = 0.0
        dataNele = 170.0
        btNele = 1.4
        hf = ROOT.TFile(
            "OutputHistograms/Data/hps_005772_pass6_useGBL_ECalMatch_SuperFiducialCut.root"
        )
        hfMC = ROOT.TFile(
            "OutputHistograms/MC/beam-tri_HPS-EngRun2015-Nominal-v4-4_pass6_useGBL_ECalMatch_SuperFiducialCut.root"
        )
        pele = ROOT.RooRealVar("pele", "pele", 0, 1)
        peleHist = hf.Get("raweleMom")
        peleMCHist = hfMC.Get("raweleMom")
        peleHist.Scale(1 / dataNele)
        peleMCHist.Scale(1 / btNele)
        peleHist.Add(
            peleMCHist, -1.0
        )  #subtract the MC from the data to get the distribution of extra tracks...this is cheating!
        for i in xrange(0, peleHist.GetNbinsX()):
            print "Electron Momentum bin i = " + str(peleHist.GetBinContent(i))
            if peleHist.GetBinContent(i) < 0:
                peleHist.SetBinContent(i, 0)
        peleHist.Print("V")
        peleDH = RooDataHist("peleDH", "peleDH", ROOT.RooArgList(pele),
                             peleHist)
        peleDH.Print("V")
        extraElectronPdf = RooHistPdf("extraElectronPdf", "extraElectronPdf",
                                      ROOT.RooArgSet(pele), peleDH)
        print 'pdf is made...printing info'
        extraElectronPdf.Print("V")
        #    if isMC and random.random()<extraElectronProb :
        #add an extra electron based on electron momentum
        print 'generating events'
        newElePData = extraElectronPdf.generate(ROOT.RooArgSet(pele),
                                                1000000.0, True, False)
        newElePData.Print("V")

    seedCnt = 0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):

        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser:
            continue
        nEvents += 1
        addFakeEle = False
        if 1 == 0:
            if isMC and random.random() < extraElectronProb:
                #add an extra electron based on electron momentum
                addFakeEle = True
                newEleP = newElePData.get(seedCnt).find("pele").getVal()
                seedCnt = seedCnt + 1
                #            print 'Inserting an electron with momentum = '+str(newEleP)
                #            newEleCluster=hps_event.addEcalCluster();
                #            newEleTrack=hps_event.addTrack();
                #            print 'numbe of HpsParticles before = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                #            newEle=hps_event.addParticle(HpsParticle.FINAL_STATE_PARTICLE)
                #            print 'numbe of HpsParticles after = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                newEle = HpsParticle()
                newEle.setCharge(-1)
                newEle.setPDG(11)
                newEle.setEnergy(newEleP)
                sign = 1
                if random.random() < 0.5:
                    sign = -1
                newEleMom = [
                    math.sin(0.03) * newEleP, sign * math.sin(0.04) * newEleP,
                    math.cos(0.04) * newEleP
                ]
                newEle.setMomentum(np.array(newEleMom))
                #fake track info
                newEleTrack = SvtTrack()
                newEleTrack.setTrackParameters(0.0, 0.03, 0.0001, sign * 0.04,
                                               0.0)
                newEleTrack.setTrackTime(40.0)
                newEleTrack.setParticle(newEle)
                newEleTrack.setChi2(3.0)
                newEleTrack.setPositionAtEcal(
                    np.array([300.0, sign * 50.0, 1350.0]))
                #fake cluster info
                newEleCluster = EcalCluster()
                newEleCluster.setEnergy(newEleP)
                foobar = [300.0, sign * 50.0, 1350.0]
                newEleCluster.setPosition(np.array(foobar, dtype='float32'))
                newEle.addTrack(newEleTrack)
                newEle.addCluster(newEleCluster)
#            print 'fake electron cluster x ' + str(newEle.getClusters().First().getPosition()[0])

# Loop over all tracks in the event
        npositrons = 0
        n_tracks = 0
        for track_n in xrange(0, hps_event.getNumberOfTracks()):
            track = hps_event.getTrack(track_n)
            if track is None:
                continue
#            if useGBL and track.getParticle().getType()<32  : continue
#            if not useGBL and track.getParticle().getType()>31  : continue
            if trkMatchAndFiducial(
                    track.getParticle(),
                    requireECalSuperFiducial) and trkMomentum(
                        track, minPCut, beamCut
                    ):  # count only matched tracks in defined fiducial region
                n_tracks += 1
                if track.getCharge() > 0:
                    npositrons += 1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else:
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))
#                    findWABPair(track.getParticle(),hps_event)

        if addFakeEle:
            myhist.raweleMom.Fill(newEle.getEnergy())
            n_tracks = n_tracks + 1
#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
#        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
#        if n_tracks/2.0<2:  continue
        myhist.nTrk.Fill(n_tracks)
        myhist.nPos.Fill(npositrons)
        myhist.nEle.Fill(n_tracks - npositrons)
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks > nTrkMax: continue
        if n_tracks < nTrkMin: continue
        if npositrons < 1 or npositrons > nPosMax: continue
        nPassBasicCuts += 1
        #        print "passed basic cuts"
        candidateList = []
        bestCandidate = -99
        nCandidate = 0
        # loop over all v0 candidates...
        for uc_index in xrange(
                0,
                hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE,
                                             uc_index)
            if useGBL and particle.getType() < 32: continue
            if not useGBL and particle.getType() > 31: continue
            #            print "found one..."
            vchi2 = particle.getVertexFitChi2()
            vposition = particle.getVertexPosition()
            vmomentum = particle.getMomentum()
            if vchi2 > v0Chi2: continue
            # use the measured sum of momentum
            #            if vmomentum[2]>v0PzMax : continue
            #            if vmomentum[2]<v0PzMin : continue
            #recon'ed vertex position cuts
            if abs(vposition[0]) > v0VxMax: continue
            if abs(vposition[1]) > v0VyMax: continue

            #            if abs(vposition[2])>v0VzMax :continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2: continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge() * daughter_particles.At(
                    1).getCharge() > 0:
                continue
            #            print "Passed daughter number cuts"

            electron = daughter_particles.At(0)
            positron = daughter_particles.At(1)

            if daughter_particles.At(0).getCharge() > 0:
                electron = daughter_particles.At(1)
                positron = daughter_particles.At(0)

            pEle = electron.getMomentum()
            pPos = positron.getMomentum()

            v0Sum = pMag(pSum(pEle, pPos))
            #total momentum sum cuts
            if v0Sum > v0PzMax: continue
            if v0Sum < v0PzMin: continue
            nPassV0Cuts += 1
            #            print "Passed v0 cuts"
            #############   tracking cuts
            #momentum cuts...get rid of very soft or very hard tracks
            if pMag(pEle) > beamCut or pMag(pPos) > beamCut: continue
            if pMag(pEle) < minPCut or pMag(pPos) < minPCut: continue
            #top+bottom requirement
            if pEle[1] * pPos[1] > 0: continue

            #            print 'looking at tracks now'
            #            print len(electron.getTracks())

            if len(electron.getTracks()) == 0 or len(
                    positron.getTracks()) == 0:
                continue
            eleTrk = electron.getTracks().At(0)
            posTrk = positron.getTracks().At(0)
            if eleTrk is None or posTrk is None: continue
            #            eleTrk.Print("v")
            #track timing
            if eleTrk.getTrackTime() - posTrk.getTrackTime() > trkDeltaT:
                continue
            #track slope (if any cut)
            if abs(eleTrk.getTanLambda()) < slopeCut or abs(
                    posTrk.getTanLambda()) < slopeCut:
                continue
#            print 'satisfied timing cuts...'
##############
# track killer part
            if isMC and trackKiller:
                if pMag(pEle) < tkThreshold:  #electron
                    tkEff = tkSlope * pMag(pEle) + tkIntercept
                    if random.random() > tkEff:
                        continue
                elif random.random(
                ) > tkThreshEff:  #allow for a flat killer above threshold
                    continue
                if pMag(pPos) < tkThreshold:  # positron
                    tkEff = tkSlope * pMag(pPos) + tkIntercept
                    if random.random() > tkEff:
                        continue
                elif random.random(
                ) > tkThreshEff:  #allow for a flat killer above threshold
                    continue
            #  end of track killer
            ##############
            nPassTrkCuts += 1

            ##############
            #   ECAL matching and timing cuts...also fiducial region cuts...
            if requireECalMatch:
                if positron.getClusters().GetEntries() == 0:
                    continue
                if electron.getClusters().GetEntries() == 0:
                    continue
                posCluster = positron.getClusters().First()
                eleCluster = electron.getClusters().First()

                if eleCluster.getClusterTime() - posCluster.getClusterTime(
                ) > cluDeltaT:
                    continue

                if eleTrk.getTrackTime() - eleCluster.getClusterTime(
                ) + 43.5 > cluTrkDeltaT:
                    continue

                if posTrk.getTrackTime() - posCluster.getClusterTime(
                ) + 43.5 > cluTrkDeltaT:
                    continue

                if requireECalFiducial:
                    #ANTI-fiducial cut
                    #                    if  myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                    #                        continue
                    #                    if  myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                    #                        continue
                    #Fiducial cut
                    if not myhist.inFiducialRegion(
                            posCluster.getPosition()[0],
                            posCluster.getPosition()[1]):
                        continue
                    if not myhist.inFiducialRegion(
                            eleCluster.getPosition()[0],
                            eleCluster.getPosition()[1]):
                        continue
                if requireECalSuperFiducial:
                    if not myhist.inSuperFiducialRegion(
                            posCluster.getPosition()[0],
                            posCluster.getPosition()[1]):
                        continue
                    if not myhist.inSuperFiducialRegion(
                            eleCluster.getPosition()[0],
                            eleCluster.getPosition()[1]):
                        continue
            nPassECalMatch += 1
            ##############
            #Passed the cuts..append the candidate index
            findWABPair(electron, hps_event)
            candidateList.append(uc_index)

        numCands = len(candidateList)
        if addFakeEle:
            for track_n in xrange(0, hps_event.getNumberOfTracks()):
                track = hps_event.getTrack(track_n)
                if track is None:
                    continue
                if trkMatchAndFiducial(track.getParticle()) and trkMomentum(
                        track, minPCut, beamCut
                ) and track.getCharge > 0 and newEle.getMomentum(
                )[1] * track.getMomentum(
                )[1] < 0:  # get positron in fudicial region; make sure it's in opposite quadrant
                    myhist.eSum.Fill(newEle.getEnergy() +
                                     pMag(track.getMomentum()))
                    numCands += 1
                    if len(candidateList) == 0:
                        #                        print 'made a new trident event'
                        nFakeTri += 1

        myhist.nCand.Fill(numCands)

        #########################
        #   found some candidates...lets fill plots...
        #########################
        for index in range(0, len(candidateList)):
            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE,
                                             candidateList[index])
            myhist.fillCandidateHistograms(particle)
            myhist.nTrkCand.Fill(n_tracks)
            myhist.nPosCand.Fill(npositrons)
            myhist.nEleCand.Fill(n_tracks - npositrons)
            myhist.nClustCand.Fill(hps_event.getNumberOfEcalClusters())

#    if(nPassTrkCuts>0):
    myhist.saveHistograms(output_file)

    print "******************************************************************************************"
    print "Number of Events:\t\t", nEvents, "\t\t\t", float(
        nEvents) / nEvents, "\t\t\t", float(nEvents) / nEvents
    print "N(particle) Cuts:\t\t", nPassBasicCuts, "\t\t\t", float(
        nPassBasicCuts) / nEvents, "\t\t\t", float(nPassBasicCuts) / nEvents
    print "V0 Vertex   Cuts:\t\t", nPassV0Cuts, "\t\t\t", float(
        nPassV0Cuts) / nPassBasicCuts, "\t\t\t", float(nPassV0Cuts) / nEvents
    print "Tracking    Cuts:\t\t", nPassTrkCuts, "\t\t\t", float(
        nPassTrkCuts) / nPassV0Cuts, "\t\t\t", float(nPassTrkCuts) / nEvents
    print "ECal Match  Cuts:\t\t", nPassECalMatch, "\t\t\t", float(
        nPassECalMatch) / nPassTrkCuts, "\t\t\t", float(
            nPassECalMatch) / nEvents

    print "Number of Fake Events Added:  \t\t", nFakeTri, "\t\t\t", float(
        nFakeTri) / nPassECalMatch
Exemplo n.º 24
0
def get_fitted_normalisation_from_ROOT(channel, input_files, variable,
                                       met_type, b_tag_bin):
    results = {}
    initial_values = {}
    templates = {}

    for variable_bin in variable_bins_ROOT[variable]:
        histograms = get_histograms(channel,
                                    input_files,
                                    variable=variable,
                                    met_type=met_type,
                                    variable_bin=variable_bin,
                                    b_tag_bin=b_tag_bin,
                                    rebin=measurement_config.rebin)
        # create signal histograms
        h_eta_signal = histograms['TTJet'] + histograms['SingleTop']

        N_ttbar_before_fit = histograms['TTJet'].Integral()
        N_SingleTop_before_fit = histograms['SingleTop'].Integral()
        N_vjets_before_fit = histograms['V+Jets'].Integral()
        N_qcd_before_fit = histograms['QCD'].Integral()
        N_signal_before_fit = N_ttbar_before_fit + N_SingleTop_before_fit

        N_ttbar_error_before_fit = sum(histograms['TTJet'].errors())
        N_SingleTop_error_before_fit = sum(histograms['SingleTop'].errors())
        N_vjets_error_before_fit = sum(histograms['V+Jets'].errors())
        N_QCD_error_before_fit = sum(histograms['QCD'].errors())

        if (N_SingleTop_before_fit != 0):
            TTJet_SingleTop_ratio = N_ttbar_before_fit / N_SingleTop_before_fit
        else:
            print 'Bin ', variable_bin, ': ttbar/singleTop ratio undefined for %s channel! Setting to 0.' % channel
            TTJet_SingleTop_ratio = 0

        leptonAbsEta = RooRealVar("leptonAbsEta", "leptonAbsEta", 0., 2.4)
        # this has to move to dps.utils.Fitting.py
        vars = RooArgList()
        vars.add(leptonAbsEta)
        vars_set = RooArgSet()
        vars_set.add(leptonAbsEta)
        n_event_obs = histograms['data'].Integral()

        lowerBound = 0.
        upperBound = n_event_obs + 10 * sqrt(n_event_obs)
        n_init = n_event_obs / 2.

        data = RooDataHist("data", "dataset with leptonAbsEta", vars,
                           histograms['data'])
        rh_vj = RooDataHist("rh_vj", "vj", vars, histograms['V+Jets'])
        rh_qcd = RooDataHist("rh_qcd", "qcd", vars, histograms['QCD'])
        rh_signal = RooDataHist("rh_signal", "signal", vars, h_eta_signal)

        pdf_vj = RooHistPdf("pdf_vj", "V+Jets pdf", vars_set, rh_vj, 0)
        pdf_qcd = RooHistPdf("pdf_qcd", "QCD pdf ", vars_set, rh_qcd, 0)
        pdf_signal = RooHistPdf("pdf_signal", "single top pdf", vars_set,
                                rh_signal, 0)

        # RooRealVar(const char *name, const char *title, Double_t value, Double_t minValue, Double_t maxValue, const char *unit) :
        nSignal = RooRealVar("nSignal", "number of single top + ttbar events",
                             N_signal_before_fit, lowerBound, upperBound,
                             "event")
        nvj = RooRealVar("nvj", "number of V+Jets bgnd events",
                         N_vjets_before_fit, lowerBound, upperBound, "event")
        nqcd = RooRealVar("nqcd", "number of QCD bgnd events",
                          N_QCD_error_before_fit, lowerBound, upperBound,
                          "event")

        model = RooAddPdf("model", "sig+vj+qcd",
                          RooArgList(pdf_signal, pdf_vj, pdf_qcd),
                          RooArgList(nSignal, nvj, nqcd))
        vj_constraint = RooGaussian("nvj_constraint", "nvj_constraint", nvj,
                                    RooFit.RooConst(N_vjets_before_fit),
                                    RooFit.RooConst(0.5 * N_vjets_before_fit))
        qcd_constraint = RooGaussian("nqcd_constraint", "nqcd_constraint",
                                     nqcd, RooFit.RooConst(N_qcd_before_fit),
                                     RooFit.RooConst(2 * N_qcd_before_fit))
        model_with_constraints = RooProdPdf(
            "model_with_constraints", "model with gaussian constraints",
            RooArgSet(model, vj_constraint, qcd_constraint), RooLinkedList())
        model_with_constraints.fitTo(data, RooFit.Minimizer(
            "Minuit2",
            "Migrad"))  #WARNING: number of cores changes the results!!!
        #         nll = model.createNLL(data, RooFit.NumCPU(2))
        #         RooMinuit(nll).migrad()
        #         frame1 = nSignal.frame(RooFit.Bins(100), RooFit.Range(lowerBound, n_event_obs), RooFit.Title("LL and profileLL in nSignal"))
        #         nll.plotOn(frame1, RooFit.ShiftToZero())
        #         frame2 = nvj.frame(RooFit.Bins(100), RooFit.Range(lowerBound, n_event_obs), RooFit.Title("LL and profileLL in nvj"))
        #         nll.plotOn(frame2, RooFit.ShiftToZero())
        #         frame3 = nqcd.frame(RooFit.Bins(100), RooFit.Range(lowerBound, n_event_obs), RooFit.Title("LL and profileLL in nqcd"))
        #         nll.plotOn(frame3, RooFit.ShiftToZero())
        #
        #         pll_nSignal = nll.createProfile(nSignal)
        #         pll_nSignal.plotOn(frame1, RooFit.LineColor(2))
        #         frame1.SetMinimum(0)
        #         frame1.SetMaximum(3)
        #
        #         pll_nvj = nll.createProfile(nvj)
        #         pll_nvj.plotOn(frame2, RooFit.LineColor(2))
        #         frame2.SetMinimum(0)
        #         frame2.SetMaximum(3)
        #
        #         pll_nqcd = nll.createProfile(nqcd)
        #         pll_nqcd.plotOn(frame3, RooFit.LineColor(2))
        #         frame3.SetMinimum(0)
        #         frame3.SetMaximum(3)
        #         c = TCanvas("profilell","profilell",1200, 400)
        #         c.Divide(3)
        #         c.cd(1)
        #         frame1.Draw()
        #         c.cd(2)
        #         frame2.Draw()
        #         c.cd(3)
        #         frame3.Draw()
        #         c.SaveAs('profileLL.png')
        #         model.fitTo(data, RooFit.Minimizer("Minuit2", "Migrad"), RooFit.NumCPU(1))#WARNING: number of cores changes the results!!!
        fit_results = {}
        fit_results['signal'] = (nSignal.getVal(), nSignal.getError())
        fit_results['QCD'] = ufloat(nqcd.getVal(), nqcd.getError())
        fit_results['V+Jets'] = ufloat(nvj.getVal(), nvj.getError())

        N_ttbar, N_SingleTop = decombine_result(fit_results['signal'],
                                                TTJet_SingleTop_ratio)
        fit_results['signal'] = ufloat(nSignal.getVal(), nSignal.getError())
        fit_results['TTJet'] = ufloat(N_ttbar)
        fit_results['SingleTop'] = ufloat(N_SingleTop)

        if results == {}:  # empty
            for sample in fit_results.keys():
                results[sample] = [fit_results[sample]]
        else:
            for sample in fit_results.keys():
                results[sample].append(fit_results[sample])

    return results, None, None
mmgMassFunc = w.factory('''FormulaVar::mmgMassFunc(
    "((mmgMass - mmgMode) / mmgScale + mmgMode)  - fPho*phoScale/100.",
    {mmgMass, mmgMode[91.2,70,110], mmgScale[1.,0.1,5], fPho, phoScale}
    )''')
mmgMode = w.var('mmgMode')
mmgScale = w.var('mmgScale')

## Get the nominal model for translation, use rho=2
model = RooKeysPdf('model', 'model', mmgMass, mmgData, RooKeysPdf.NoMirror, 2)

## Sample nominal model to binned data, no Poisson fluctuation
modelHist = model.createHistogram('mmgMass', 10000)
modelDH = RooDataHist('modelDH', 'modelDH', RooArgList(mmgMass), modelHist)

## Use the sampled model to build a transformed model, interpolation order=2
tmodel = RooHistPdf('tmodel', 'tmodel', RooArgList(mmgMassFunc),
                    RooArgList(mmgMass), modelDH, 2)


## Find the mode of the tmodel.
mmgMode.setVal(modelHist.GetBinCenter(modelHist.GetMaximumBin()))
mmgMode.setConstant(True)
fPho.setConstant(True)

## Fit the photon scale
phoScale.setConstant(False)
mmgScale.setConstant(True)

## Make plots
canvases.next('nominal')
mmgFrame = mmgMass.frame(Range(60,120))
mmgData.plotOn(mmgFrame)
DTF_D0sPi_M.setMin(2000)

varset_small = RooArgSet("varset_small")
varset_small.add(LOG_D0_IPCHI2_OWNPV)
varset_small.add(Dst_DTF_D0_CTAU)
varset_small.add(DTF_D0sPi_M)

#Create histogram for time bin 0
dataset_RS_0 = wsp.data("dataset_RS")
dataset_RS_0.SetName("dataset_RS_0")
print "dataset_RS_0 extraction took  "+str(datetime.now()-start)+" \n"
start = datetime.now()
hist_RS_0 = RooDataHist("hist_RS_0","hist_RS_0", RooArgSet(LOG_D0_IPCHI2_OWNPV), dataset_RS_0)
print "RooDataHist creation took  "+str(datetime.now()-start)+" \n"
start = datetime.now()
shape_RS_0 = RooHistPdf("shape_RS_0", "shape_RS_0", RooArgSet(LOG_D0_IPCHI2_OWNPV), hist_RS_0)
print "RooHistPdf creation took  "+str(datetime.now()-start)+" \n"
h_0 = hist_RS_0.createHistogram("LOG_D0_IPCHI2_OWNPV", 100)

#Fage function used to fit signal distribution
#Fix asymmetry paramters from 0 bin, leave mean and width float.
fage_mu = RooRealVar("fage_mu", "fage_mu", 0.5, 0., 1.)
fage_sigma = RooRealVar("fage_sigma", "fage_sigma", 2.0, 0.5, 5.)
fage_epsilon = RooRealVar("fage_epsilon", "fage_epsilon", 0., -1., 1.)
fage_rhol = RooRealVar("fage_rhol", "fage_rhol", 1., 0.1, 10)
fage_rhor = RooRealVar("fage_rhor", "fage_rhor", 1., 0.1, 10)
s_fage = ROOT.fage("s_fage", "s_fage", LOG_D0_IPCHI2_OWNPV, fage_mu, fage_sigma, fage_epsilon, fage_rhol, fage_rhor)
fit_hists_0 = s_fage.fitTo(hist_RS_0,RooFit.SumW2Error(True),RooFit.Save())
fage_epsilon.setConstant(True)
fage_rhol.setConstant(True)
fage_rhor.setConstant(True)
Exemplo n.º 27
0
w.var('gm').setVal(-3.)
w.var('gs').setVal(2)
data2 = g.generate(ArgSet(x), 10000)

w.var('gm').setVal(0.)
w.var('gs').setVal(1.)

## 3. Use data 1 to build Keys PDF k1(x|s1,m1)
k = KeysPdf('k', 'k', x, data1, KeysPdf.NoMirror, 2)

## 4. Use k to build HistPDF with _transformed_ x variable t = (x-m)/s
##    h1((x-hm)/hs|m1,s1)
t = w.factory('FormulaVar::t("(x - hm) / hs", {x, hm[0,-5,5], hs[1,0.1,3]})')
hist = k.createHistogram('x', 10000)
dh = DataHist('dh', 'dh', ArgList(x), hist)
h = HistPdf('h', 'h', ArgList(t), ArgList(x), dh, 2)

## 5. Plot results
f1 = x.frame()
f1.SetTitle('Training Data')
data1.plotOn(f1)
g.plotOn(f1)
k.plotOn(f1, LineColor(kRed), LineStyle(kDashed))
h.plotOn(f1, LineColor(kBlack), LineStyle(kDashed))
canvases.next('Training_Data')
f1.Draw()

## 6. Fit h1 to data2 to simulate a "measurement" of m2, s2.
h.fitTo(data2)

f2 = x.frame()
Exemplo n.º 28
0
def getMistagBinBounds(config, mistag, mistagdistrib):
    """
    suggest a binning for turning per-event mistag into mistag categories

    This routine takes a mistag observable and a PDF or data set, and suggests
    a number of mistag category boundaries which have approximately equal
    statistics in each category.

    config          -- config dictionary
    mistag          -- mistag observable (eta)
    mistagdistrib   -- a PDF or a RooDataSet

    returns a (python) list of mistag category bin bounds

    relevant configuration dictionary keys:
    'NMistagCategories':
        number of mistag categories for which to suggest a set of bin bounds
    """
    mistag.setBins(1000, 'MistagBinBounds')
    from ROOT import RooArgSet, RooHistPdf, RooDataHist
    if (mistagdistrib.InheritsFrom('RooAbsData') and not
            mistagdistrib.InheritsFrom('RooDataHist')):
        # ok, unbinned data set, get only tagged events, and form a binned clone
        argset = RooArgSet(mistag)
        mistagdistrib = mistagdistrib.reduce(
                RooFit.SelectVars(argset), RooFit.cut('0 != qt'))
        ROOT.SetOwnership(mistagdistrib, True)
        dhist = RooDataHist(
                '%s_binned' % mistagdistrib.GetName(),
                '%s_binned' % mistagdistrib.GetName(),
                mistagdistrib.get(), 'MistagBinBounds')
        dhist.add(mistagdistrib)
        mistagdistrib = dhist
    if mistagdistrib.InheritsFrom('RooAbsData'):
        # convert a binned dataset to a RooHistPdf
        dhist = mistagdistrib
        mistagdistrib = RooHistPdf('%s_pdf' % dhist.GetName(),
                '%s_pdf' % dhist.GetName(), RooArgSet(mistag), dhist)
    if (mistagdistrib.InheritsFrom('RooAbsPdf')):
        # use createCdf to obtain the CDF
        cdfroofit = mistagdistrib.createCdf(
                RooArgSet(mistag), RooArgSet(mistag))
        ROOT.SetOwnership(cdfroofit, True)
        def cdf(x):
            oldval = mistag.getVal()
            mistag.setVal(x)
            retVal = cdfroofit.getVal()
            mistag.setVal(oldval)
            return retVal
    if (mistagdistrib.InheritsFrom('RooHistPdf') and
            (abs(cdf(mistag.getMin())) > 1e-9 or
                abs(cdf(mistag.getMax()) - 1.) > 1e-9)):
        # createCdf does not work properly for RooHistPdf in older ROOT
        # versions because RooHistPdf does not support integrals over
        # subranges, so we have to fake this functionality until it's
        # supported by RooFit upstream
        #
        # capture histogram bin boundaries and contents
        print 'WARNING: Your version of RooFit still has buggy analytical ' \
                'integrals for RooHistPdf - activating workaround.'
        binboundlist = mistagdistrib.binBoundaries(
                mistag, mistag.getMin(), mistag.getMax())
        ROOT.SetOwnership(binboundlist, True)
        binbounds = [ v for v in binboundlist ]
        del binboundlist
        bincontents = [ ]
        oldval = mistag.getVal()
        for i in xrange(0, len(binbounds) - 1):
            mistag.setVal(0.5 * (binbounds[i] + binbounds[i + 1]))
            bincontents.append(mistagdistrib.getValV(RooArgSet(mistag)))
        mistag.setVal(oldval)
        # build CDF from histogram
        def cdf(x):
            s = 0.
            for i in xrange(0, len(binbounds) - 1):
                if x < binbounds[i]:
                    break
                elif x >= binbounds[i + 1]:
                    s += bincontents[i]
                else:
                    s += (bincontents[i] * (x - binbounds[i]) /
                                (binbounds[i + 1] - binbounds[i]))
                    break
            return s
    # find x for which f(x) = y by bisection
    def mybisect(y, f, lo, hi):
        initdx = abs(hi - lo)
        flo, fhi = f(lo) - y, f(hi) - y
        if 0. == flo: return lo
        elif 0. == fhi: return hi
        mid = .5 * (lo + hi)
        while (abs(hi - lo) > 1e-15 and abs(hi - lo) / initdx > 1e-15):
            fmid = f(mid) - y
            if 0. == fmid: break
            elif flo * fmid < 0.: hi, fhi = mid, fmid
            elif fmid * fhi < 0.: lo, flo = mid, fmid
            else: raise ValueError('no sign change in f(x) between %g and %g'
                    % (lo, hi))
            mid = .5 * (lo + hi)
        return mid
    # find binning with roughly same stats by inverting the CDF by bisection
    lo, hi, binsum = mistag.getMin(), mistag.getMax(), cdf(mistag.getMax())
    retVal = [ lo ]
    for i in xrange(1, config['NMistagCategories']):
        retVal.append(mybisect(binsum *
            float(i) / float(config['NMistagCategories']), cdf, lo, hi))
    retVal.append(hi)
    print 'INFO: suggested mistag category bounds: %s' % str(retVal)
    return retVal
Exemplo n.º 29
0
            args.signal_model, int(mass))

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

        p1 = RooRealVar('p1', 'p1', args.p1, 0., 100.)
        p2 = RooRealVar('p2', 'p2', args.p2, 0., 60.)
        p3 = RooRealVar('p3', 'p3', args.p3, -10., 10.)
        if args.fixP3: p3.setConstant()

        background = RooGenericPdf(
            'background',
            '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
            (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p1, p2, p3))
Exemplo n.º 30
0
nqcd = RooRealVar("nqcd", "number of qcd events", n_qcd, n_qcd, n_qcd)
#k2nqcd = RooFormulaVar("k2nqcd","number of qcd events"," ",RooArgList(k2,nqcd))

data = RooDataHist("data", "data set with (x)", RooArgList(x), h_data_m3HistS)
ttbar = RooDataHist("ttbar", "data set with (x)", RooArgList(x),
                    h_ttbar_m3HistS)
background = RooDataHist("background", "data set with (x)", RooArgList(x),
                         h_background_m3Hist)

qcd = RooDataHist("qcd", "data set with (x)", RooArgList(x),
                  h_qcd_data_m3HistS)
# RooHistPdf::RooHistPdf(const char* name, const char* title, const RooArgSet& vars, const RooDataHist& dhist, int intOrder = 0) =>
#print "ttbar type: "+str(type(ttbar))
#print "rooArglist(x):"+str(type(RooArgList(x)))

ttbarpdf = RooHistPdf("ttbarpdf", "ttbarpdf", RooArgList(x), RooArgList(x),
                      ttbar)
backgroundpdf = RooHistPdf("backgroundpdf", "backgroundpdf", RooArgList(x),
                           RooArgList(x), background)
qcdpdf = RooHistPdf("qcdpdf", "qcdpdf", RooArgList(x), RooArgList(x), qcd)

#ttbarpdf      = RooHistPdf(ttbar,"ttbarpdf")
#backgroundpdf = RooHistPdf(background,"backgroundpdf")

model = RooAddPdf("model", "model", RooArgList(ttbarpdf, backgroundpdf),
                  RooArgList(k1))
model2 = RooAddPdf("model2", "model2", RooArgList(model), RooArgList(k2nmc))
model3 = RooAddPdf("model3", "model3", RooArgList(model2, qcdpdf),
                   RooArgList(k2nmc, nqcd))
#model3 = RooAddPdf("model3", "model3",RooArgList( model, qcdpdf), RooArgList(k2nmc,k2nqcd))

model3.fitTo(data)
def morph(hist1, hist2, mass1, mass2, targetMass, debug = False):
    from ROOT import gROOT, RooRealVar, RooIntegralMorph,\
        kRed,kBlue,kViolet, RooDataHist, RooArgSet,\
        RooArgList, RooHistPdf, RooAbsReal, RooFit
    
    import re

    if mass1<mass2:
        histLow = hist1
        massLow = mass1
        histHigh = hist2
        massHigh = mass2
    else:
        histLow = hist2
        massLow = mass2
        histHigh = hist1
        massHigh = mass1

    x = RooRealVar("x", "x", histLow.GetXaxis().GetXmin(), histLow.GetXaxis().GetXmax())
    mAlpha = 1.0 - float(targetMass-massLow)/float(massHigh-massLow)
    print 'alpha:',mAlpha,
    newIntegral = histLow.Integral() + \
        (targetMass - massLow) * \
        (histHigh.Integral()-histLow.Integral()) / \
        (massHigh-massLow)
    print 'low integral:', histLow.Integral(), \
        'high integral:', histHigh.Integral(), \
        'new integral:', newIntegral



    newHistLow = RooDataHist("sigHistLow_hist", "sigHistLow_hist", RooArgList(x), histLow);
    sigHistLow = RooHistPdf("sigHistLow", "sigHistLow", RooArgList(x),
				 RooArgList(x), newHistLow);

    newHistHigh = RooDataHist("sigHistHigh_hist", "sigHistHigh_hist", RooArgList(x), histHigh);
    sigHistHigh = RooHistPdf("sigHistHigh", "sigHistHigh", RooArgList(x),
				 RooArgList(x), newHistHigh);
    
      
    #x.Print("v")
    x.setBins( histLow.GetNbinsX(), "cache")
    alpha_morph = RooRealVar("alpha_morph", "#alpha_{morph}", mAlpha, 0., 1.)
    alpha_morph.setBins(10,"cache") ;

    sigModel = RooIntegralMorph("sigModel", "sigModel", sigHistLow, 
                                sigHistHigh, x, alpha_morph)


    if (debug):
        from ROOT import gPad, RooFit
        frame = x.frame()
        sigHistLow.plotOn(frame, RooFit.LineColor(kRed+1),
                          RooFit.LineStyle(2))
        sigHistHigh.plotOn(frame, RooFit.LineColor(kBlue+1),
                           RooFit.LineStyle(2))
        sigModel.plotOn(frame, RooFit.LineColor(kViolet+1),
                        RooFit.LineStyle(9))
        frame.Draw()
        gPad.Update()
        gPad.WaitPrimitive()

    morphHist = sigModel.createHistogram(re.sub(r'\d+', '%i' % targetMass,
                                                hist1.GetName()), x, RooFit.Binning(histLow.GetNbinsX()))
    morphHist.Scale(newIntegral/morphHist.Integral())
    morphHist.SetName(re.sub(r'\d+', '%i' % targetMass, hist1.GetName()))
    
    # if debug:
    #     morphHist.Print()

    return morphHist
## mmgMass.setRange(mmgMass.getMin() - mmgMassRangeMean,
##                  mmgMass.getMax() - mmgMassRangeMean)
phoEResFuncOfMMGMassShifted = w.factory(
    """FormulaVar::phoEResFuncOfMMGMassShifted(
        "(mmgMassShifted - phoMean)/phoWidth + ({mcscale})",
        {{mmgMassShifted, phoMean, phoWidth}}
        )""".format(
        mcscale=phoEScaleMC
    )
)

# phoEResFuncOfMMGMass = w.factory('FormulaVar::phoEResFuncOfMMGMass2("mmgMass ", {mmgMass})')

## Plug in the mass smering mean and width into the smearing shape
phoSmear = RooHistPdf(
    "phoSmear", "phoSmear", RooArgList(phoEResFuncOfMMGMassShifted), RooArgList(phoERes), phoEResDataHist, 2
)
## TODO: use RooCustomizer to transform phoEResShape
## Define the transform such that the phoEResShape is always evaluated
## inside of it's boundaries.
cust = RooCustomizer(phoEResShape, "transformed")
cust.replaceArg(phoERes, phoEResFuncOfMMGMassShifted)
phoSmear2 = cust.build()

w.Import(phoSmear)

## Apply photon smearing to the theory
mmgMassShifted.setRange(-30, 30)
mmgMassShifted.setBins(10000, "fft")
theoryXphoSmear = w.factory("FCONV::theoryXphoSmear(mmgMassShifted, phoSmear, theory)")
## mmgMassPhoGenEFunc = w.factory('FormulaVar::mmgMassPhoGenEFunc("mmgMass", {mmgMass})')
Exemplo n.º 33
0
    def fit(self):
        fit_variable = RooRealVar("fit_variable", "fit_variable",
                                  self.fit_boundaries[0],
                                  self.fit_boundaries[1])
        fit_variable.setBins(self.histograms[self.data_label].nbins())
        variables = RooArgList()
        variables.add(fit_variable)
        variable_set = RooArgSet()
        variable_set.add(fit_variable)

        roofit_histograms = {}
        roofit_pdfs = {}
        roofit_variables = {}

        N_min = 0.
        N_max = self.normalisation[self.data_label] * 2.
        pdf_arglist = RooArgList()
        variable_arglist = RooArgList()

        roofit_histograms[self.data_label] = RooDataHist(
            self.data_label, self.data_label, variables,
            self.histograms[self.data_label])
        for sample in self.samples:
            roofit_histogram = RooDataHist(sample, sample, variables,
                                           self.histograms[sample])
            roofit_histograms[sample] = roofit_histogram
            roofit_pdf = RooHistPdf('pdf' + sample, 'pdf' + sample,
                                    variable_set, roofit_histogram)
            roofit_pdfs[sample] = roofit_pdf
            roofit_variable = RooRealVar(sample, sample + " events",
                                         self.normalisation[sample], N_min,
                                         N_max)
            roofit_variables[sample] = roofit_variable
            pdf_arglist.add(roofit_pdf)
            variable_arglist.add(roofit_variable)

        model = RooAddPdf('model', 'sum of all known', pdf_arglist,
                          variable_arglist)
        use_model = model
        if self.constraints:
            arg_set = RooArgSet(model)
            constraints = self.get_fit_normalisation_constraints(
                model, roofit_variables)
            for constraint in constraints:
                arg_set.add(constraint)
            model_with_constraints = RooProdPdf(
                "model_with_constraints", "model  with gaussian constraints",
                arg_set, RooLinkedList())
            use_model = model_with_constraints

        if self.method == 'TMinuit':
            #WARNING: number of cores changes the results!!!
            self.saved_result = use_model.fitTo(
                roofit_histograms[self.data_label],
                RooFit.Minimizer("Minuit2", "Migrad"),
                RooFit.NumCPU(1),
                RooFit.Extended(),
                RooFit.Save(),
            )

        results = {}
        for sample in self.samples:
            results[sample] = (roofit_variables[sample].getVal(),
                               roofit_variables[sample].getError())
        self.results = results
## Shift the mass range to be symmetric around zero
## mmgMassRangeMean = 0.5 * (mmgMass.getMin() + mmgMass.getMax())
## mmgMass.setRange(mmgMass.getMin() - mmgMassRangeMean,
##                  mmgMass.getMax() - mmgMassRangeMean)
phoEResFuncOfMMGMassShifted = w.factory(
    '''FormulaVar::phoEResFuncOfMMGMassShifted(
        "(mmgMassShifted - phoMean)/phoWidth + ({mcscale})",
        {{mmgMassShifted, phoMean, phoWidth}}
        )'''.format(mcscale = phoEScaleMC))

#phoEResFuncOfMMGMass = w.factory('FormulaVar::phoEResFuncOfMMGMass2("mmgMass ", {mmgMass})')

## Plug in the mass smering mean and width into the smearing shape
phoSmear = RooHistPdf('phoSmear', 'phoSmear',
                      RooArgList(phoEResFuncOfMMGMassShifted),
                      RooArgList(phoERes), phoEResDataHist, 2)

w.Import(phoSmear)

## Apply photon smearing to the theory
mmgMassShifted.setRange(-30, 30)
mmgMassShifted.setBins(10000, 'fft')
theoryXphoSmear = w.factory('FCONV::theoryXphoSmear(mmgMassShifted, phoSmear, theory)')
## mmgMassPhoGenEFunc = w.factory('FormulaVar::mmgMassPhoGenEFunc("mmgMass", {mmgMass})')
## theoryXphoSmear = RooFFTConvPdf('theoryXphoSmear', 'theoryXphoSmear',
##                                 mmgMassPhoGenEFunc, mmgMassPhoGenE, theory, phoSmear)

## Fit Smeared theory to data
#theoryXphoSmear.fitTo(mmgData, Range(70,110))
Exemplo n.º 35
0
def change_dataset_to_histpdf(workspace,x,dataset):
  datahist = dataset.binnedClone(dataset.GetName()+"_binnedClone",dataset.GetName()+"_binnedClone")
  histpdf  = RooHistPdf(dataset.GetName()+"_histpdf",dataset.GetName()+"_histpdf",RooArgSet(x),datahist)
  getattr(workspace,'import')(histpdf)
Exemplo n.º 36
0
def shapeCards( process, isData, datahistosFile, histosFile, signalHistosFile, signalSample, hist, signalMass, minMass, maxMass, jesValue, jerValue, lumiUnc, outputName ):
	"""function to run Roofit and save workspace for RooStats"""
	warnings.filterwarnings( action='ignore', category=RuntimeWarning, message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >' )
	
	hSignal = signalHistosFile.Get(hist+'_'+signalSample)
	hSignal.Rebin(10)
	htmpSignal = hSignal.Clone()
	#htmpSignal.Scale(100)
	signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-'+str(signalMass) )
	#hSignal.Scale( lumi*signalXS / hSignal.Integral())

	massAve = RooRealVar( 'massAve', 'massAve', minMass, maxMass  )
	rooSigHist = RooDataHist( 'rooSigHist', 'rooSigHist', RooArgList(massAve), hSignal )
	rooSigHist.Print()

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

	hBkg = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
	#hBkg = histosFile.Get(hist+'_QCDPtAll_BCD')
	bkgAcc = round(hBkg.Integral( hBkg.GetXaxis().FindBin( minMass ), hBkg.GetXaxis().FindBin( maxMass )))
	#hBkg.Scale(1/hBkg.Integral())
	hPseudo = hBkg.Clone()
	hPseudo.Reset()
        #background_norm = RooRealVar('background_norm','background_norm',bkgAcc,0.,1e+07)
        background_norm = RooRealVar('background_norm','background_norm',1.,0.,1e+07)
        background_norm.Print()

	if 'template' in process:
		rooBkgHist = RooDataHist( 'rooBkgHist', 'rooBkgHist', RooArgList(massAve), hBkg )
		rooBkgHist.Print()
		background = RooHistPdf('background','background',RooArgSet(massAve),rooBkgHist)
		background.Print()

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

		background = RooGenericPdf('background','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(1300,1300,1300),RooArgList(massAve,p1,p2,p3))
		background.Print()
		### S+B model

	if not isData:
		newNumEvents = random.randint( bkgAcc-round(TMath.Sqrt(bkgAcc)), bkgAcc+round(TMath.Sqrt(bkgAcc)) )
		print 'Events in MC:', bkgAcc, ', in PseudoExperiment:', newNumEvents
		hPseudo.FillRandom( hBkg, newNumEvents ) 
		#hPseudo.Scale(1/hPseudo.Integral())

	#hData = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_ABCDProj')
	hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
	#hData = histosFile.Get(hist+'_QCDPtAll_A')
	#hData.Add(htmpSignal)
	#hData.Scale(1/hData.Integral())
        rooDataHist = RooDataHist('rooDatahist','rooDatahist',RooArgList(massAve), hData if isData else hPseudo )
        rooDataHist.Print()

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

	############# JES and JER uncertainties
        hSigSyst = {}
        hSigSystDataHist = {}
        signalCDF = TGraph(hSignal.GetNbinsX()+1)

        # JES and JER uncertainties
	if args.jesUnc or args.jerUnc:
		signalCDF.SetPoint(0,0.,0.)
		integral = 0.
		for i in range(1, hSignal.GetNbinsX()+1):
			x = hSignal.GetXaxis().GetBinLowEdge(i+1)
			integral = integral + hSignal.GetBinContent(i)
			signalCDF.SetPoint(i,x,integral)

		if args.jesUnc:
			print ' |---> Adding JES'
			hSigSyst['JESUp'] = hSignal.Clone()
			hSigSyst['JESDown'] = hSignal.Clone()

		if args.jerUnc:
			print ' |---> Adding JER'
			hSigSyst['JERUp'] = hSignal.Clone()
			hSigSyst['JERDown'] = hSignal.Clone()

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

        # produce JES signal shapes
        if args.jesUnc:
		for q in range(1, hSignal.GetNbinsX()+1):
			xLow = hSignal.GetXaxis().GetBinLowEdge(q)
			xUp = hSignal.GetXaxis().GetBinLowEdge(q+1)
			jes = 1. - jesValue
			xLowPrime = jes*xLow
			xUpPrime = jes*xUp
			hSigSyst['JESUp'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
			jes = 1. + jesValue
			xLowPrime = jes*xLow
			xUpPrime = jes*xUp
			hSigSyst['JESDown'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
		hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp','hSignalJESUp',RooArgList(massAve),hSigSyst['JESUp'])
		hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown','hSignalJESDown',RooArgList(massAve),hSigSyst['JESDown'])

        # produce JER signal shapes
	if args.jerUnc:
		for i in range(1, hSignal.GetNbinsX()+1):
			xLow = hSignal.GetXaxis().GetBinLowEdge(i)
			xUp = hSignal.GetXaxis().GetBinLowEdge(i+1)
			jer = 1. - jerValue
			xLowPrime = jer*(xLow-float(signalMass))+float(signalMass)
			xUpPrime = jer*(xUp-float(signalMass))+float(signalMass)
			hSigSyst['JERUp'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
			jer = 1. + jerValue
			xLowPrime = jer*(xLow-float(signalMass))+float(signalMass)
			xUpPrime = jer*(xUp-float(signalMass))+float(signalMass)
			hSigSyst['JERDown'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
		hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp','hSignalJERUp',RooArgList(massAve),hSigSyst['JERUp'])
		hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown','hSignalJERDown',RooArgList(massAve),hSigSyst['JERDown'])

	myWS = RooWorkspace("myWS")
	getattr(myWS,'import')(rooSigHist,RooFit.Rename("signal"))
        getattr(myWS,'import')(rooBkgHist,RooFit.Rename("background"))
        #getattr(myWS,'import')(signal_norm)
        getattr(myWS,'import')(background_norm)
        if args.jesUnc:
		getattr(myWS,'import')(hSigSystDataHist['JESUp'],RooFit.Rename("signal__JESUp"))
		getattr(myWS,'import')(hSigSystDataHist['JESDown'],RooFit.Rename("signal__JESDown"))
        if args.jerUnc:
		getattr(myWS,'import')(hSigSystDataHist['JERUp'],RooFit.Rename("signal__JERUp"))
		getattr(myWS,'import')(hSigSystDataHist['JERDown'],RooFit.Rename("signal__JERDown"))
        getattr(myWS,'import')(rooDataHist,RooFit.Rename("data_obs"))
        myWS.Print()
	outputRootFile = currentDir+'/Rootfiles/workspace_'+outputName+'.root'
        myWS.writeToFile(outputRootFile, True)
	print ' |----> Workspace created in root file:\n', outputRootFile
 # -----------------------------------------
        # write a datacard

	dataCardName = currentDir+'/Datacards/datacard_'+outputName+'.txt'
        datacard = open( dataCardName ,'w')
        datacard.write('imax 1\n')
        datacard.write('jmax 1\n')
        datacard.write('kmax *\n')
        datacard.write('---------------\n')
        if args.jesUnc or args.jerUnc or args.lumiUnc or args.normUnc or args.unc: 
		datacard.write('shapes * * '+outputRootFile+' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n')
	else: datacard.write("shapes * * "+outputRootFile+" myWS:$PROCESS \n")
        datacard.write('---------------\n')
        datacard.write('bin 1\n')
        datacard.write('observation -1\n')
        datacard.write('------------------------------\n')
        datacard.write('bin          1          1\n')
        datacard.write('process      signal     background\n')
        datacard.write('process      0          1\n')
        datacard.write('rate         -1         -1\n')
        datacard.write('------------------------------\n')
	if args.lumiUnc: datacard.write('lumi  lnN    %f         -\n'%(lumiUnc))
        if args.jesUnc: datacard.write('JES  shape   1          -\n')
	if args.jerUnc: datacard.write('JER  shape   1          -\n')
        #flat parameters --- flat prior
	if args.normUnc: datacard.write('background_norm  flatParam\n')
        #datacard.write('p1  flatParam\n')
        datacard.close()
	print ' |----> Datacard created:\n', dataCardName
Exemplo n.º 37
0
def main():
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    parser.add_argument("-p", "--pulser",  help="is Pulser")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True


    isPulser=False
    if args.pulser:
        print  "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser=True




#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax=10
    nTrkMin=2
    nPosMax=3
######  two tracks (e+/e-) exactly
#    nTrkMax=2
#    nTrkMin=2
#    nPosMax=1
###### more than 1 electron
#    nTrkMax=10
#    nTrkMin=3
#    nPosMax=1
###################
    #v0 cuts   
    v0Chi2=10
    #ESum -- full region
    v0PzMax=1.2
    v0PzMin=0.55
    #ESum -- Radiative region
#    v0PzMax=1.2
#    v0PzMin=0.80

    v0PyMax=0.2 #absolute value
    v0PxMax=0.2 #absolute value
    v0VzMax=25.0# mm from target
    v0VyMax=1.0# mm from target
    v0VxMax=2.0# mm from target
 #  track quality cuts
    trkChi2=10
    beamCut=0.8
    minPCut=0.05
    trkPyMax=0.2
    trkPxMax=0.2
#    slopeCut=0.03
    slopeCut=0.0
    trkDeltaT=4#ns
    cluDeltaT=2#ns
    cluTrkDeltaT=4#ns
##############
#  ESum slices; upper limits    
    nSlicesESum=5 
    esumMin=0.55
    esumMax=1.2
    sliceSizeESum=0.1 #100MeV starting at esumMin
##############
    trackKiller=False
    tkThreshold=0.5 #GeV, below this start killing tracks
    tkThreshEff=1.0
    tkLowPoint=0.20
    tkLowPointEff=0.40
#    tkSlope=2.6 
#    tkIntercept=-0.04
    #calculate tkSlope and Intercept   
    tkSlope=(tkThreshEff-tkLowPointEff)/(tkThreshold-tkLowPoint)
    tkIntercept=tkThreshEff-tkSlope*tkThreshold

##############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = True
    useGBL=True


     # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    
    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))



    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassNCand=0
    nPassECalMatch=0;
    nFakeTri=0


    if 1==0 : 
        extraElectronProb=0.0
        dataNele=170.0;
        btNele=1.4;
        hf=ROOT.TFile("OutputHistograms/Data/hps_005772_pass6_useGBL_ECalMatch_SuperFiducialCut.root")
        hfMC=ROOT.TFile("OutputHistograms/MC/beam-tri_HPS-EngRun2015-Nominal-v4-4_pass6_useGBL_ECalMatch_SuperFiducialCut.root")
        pele=ROOT.RooRealVar("pele","pele",0,1)
        peleHist=hf.Get("raweleMom")
        peleMCHist=hfMC.Get("raweleMom")
        peleHist.Scale(1/dataNele)
        peleMCHist.Scale(1/btNele)
        peleHist.Add(peleMCHist,-1.0)  #subtract the MC from the data to get the distribution of extra tracks...this is cheating!
        for i in xrange(0,peleHist.GetNbinsX()) :
            print "Electron Momentum bin i = " +str( peleHist.GetBinContent(i) )
            if peleHist.GetBinContent(i) <0 :
                peleHist.SetBinContent(i,0)
        peleHist.Print("V")
        peleDH=RooDataHist("peleDH","peleDH",ROOT.RooArgList(pele),peleHist)
        peleDH.Print("V")
        extraElectronPdf=RooHistPdf("extraElectronPdf","extraElectronPdf",ROOT.RooArgSet(pele),peleDH)
        print 'pdf is made...printing info' 
        extraElectronPdf.Print("V")
        #    if isMC and random.random()<extraElectronProb : 
        #add an extra electron based on electron momentum
        print 'generating events' 
        newElePData=extraElectronPdf.generate(ROOT.RooArgSet(pele),1000000.0,True, False)
        newElePData.Print("V")
    
    seedCnt=0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 
                 
        # Print the event number every 500 events
        if (entry+1)%10000 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue
        nEvents+=1
        addFakeEle=False
        if 1==0 :
            if isMC and random.random()<extraElectronProb : 
        #add an extra electron based on electron momentum
                addFakeEle=True
                newEleP=newElePData.get(seedCnt).find("pele").getVal()
                seedCnt=seedCnt+1
                #            print 'Inserting an electron with momentum = '+str(newEleP)
                #            newEleCluster=hps_event.addEcalCluster();
                #            newEleTrack=hps_event.addTrack();
                #            print 'numbe of HpsParticles before = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                #            newEle=hps_event.addParticle(HpsParticle.FINAL_STATE_PARTICLE)
                #            print 'numbe of HpsParticles after = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                newEle=HpsParticle()
                newEle.setCharge(-1)
                newEle.setPDG(11)
                newEle.setEnergy(newEleP)
                sign=1
                if random.random()<0.5 : 
                    sign=-1
                newEleMom=[math.sin(0.03)*newEleP,sign*math.sin(0.04)*newEleP,math.cos(0.04)*newEleP]
                newEle.setMomentum(np.array(newEleMom))
            #fake track info
                newEleTrack=SvtTrack()
                newEleTrack.setTrackParameters(0.0,0.03,0.0001,sign*0.04,0.0)
                newEleTrack.setTrackTime(40.0)
                newEleTrack.setParticle(newEle)
                newEleTrack.setChi2(3.0)
                newEleTrack.setPositionAtEcal(np.array([300.0,sign*50.0,1350.0]))
            #fake cluster info
                newEleCluster=EcalCluster()
                newEleCluster.setEnergy(newEleP)
                foobar=[300.0,sign*50.0,1350.0]
                newEleCluster.setPosition(np.array(foobar,dtype='float32'))
                newEle.addTrack(newEleTrack)
                newEle.addCluster(newEleCluster)
#            print 'fake electron cluster x ' + str(newEle.getClusters().First().getPosition()[0])            
                                                                           

        # Loop over all tracks in the event
        npositrons=0
        n_tracks=0
        for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
            track = hps_event.getTrack(track_n)
            if track is None : 
                continue
#            if useGBL and track.getParticle().getType()<32  : continue
#            if not useGBL and track.getParticle().getType()>31  : continue
            if trkMatchAndFiducial(track.getParticle()) and trkMomentum(track,minPCut,beamCut): # count only matched tracks in defined fiducial region
                n_tracks+=1
                if track.getCharge()>0 :
                    npositrons+=1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else :
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))
#                    findWABPair(track.getParticle(),hps_event)

        if addFakeEle :
            myhist.raweleMom.Fill(newEle.getEnergy())
            n_tracks=n_tracks+1
#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
#        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
#        if n_tracks/2.0<2:  continue        
        myhist.nTrk.Fill(n_tracks);
        myhist.nPos.Fill(npositrons);
        myhist.nEle.Fill(n_tracks-npositrons);
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks>nTrkMax : continue  
        if n_tracks<nTrkMin:  continue        
        if npositrons<1 or npositrons>nPosMax : continue
        nPassBasicCuts+=1
#        print "passed basic cuts"
        candidateList=[]
        bestCandidate=-99
        nCandidate=0
        # loop over all v0 candidates...
        for uc_index in xrange(0, hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, uc_index)
            if useGBL and  particle.getType()<32  : continue
            if not useGBL and  particle.getType()>31  : continue
#            print "found one..."
            vchi2=particle.getVertexFitChi2();
            vposition=particle.getVertexPosition();
            vmomentum=particle.getMomentum();
            if vchi2>v0Chi2 :  continue
            # use the measured sum of momentum 
#            if vmomentum[2]>v0PzMax : continue
#            if vmomentum[2]<v0PzMin : continue
             #recon'ed vertex position cuts
            if abs(vposition[0])>v0VxMax : continue
            if abs(vposition[1])>v0VyMax :continue

#            if abs(vposition[2])>v0VzMax :continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2 : continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge()*daughter_particles.At(1).getCharge() > 0 : continue
#            print "Passed daughter number cuts"

            electron =  daughter_particles.At(0)
            positron =  daughter_particles.At(1)
            
            if daughter_particles.At(0).getCharge()>0:
                electron =  daughter_particles.At(1)
                positron =  daughter_particles.At(0)

            pEle=electron.getMomentum()
            pPos=positron.getMomentum()

            v0Sum=pMag(pSum(pEle,pPos))
            #total momentum sum cuts
            if v0Sum>v0PzMax : continue
            if v0Sum<v0PzMin : continue
            nPassV0Cuts+=1
            print "Passed v0 cuts"
#############   tracking cuts
            #momentum cuts...get rid of very soft or very hard tracks
            if pMag(pEle)>beamCut or pMag(pPos)>beamCut : continue
            if pMag(pEle)<minPCut or pMag(pPos)<minPCut : continue   
            #top+bottom requirement
            if pEle[1]*pPos[1]>0 : continue

            print 'looking at tracks now' 
            print len(electron.getTracks())
            
            if  len(electron.getTracks()) == 0 or  len(positron.getTracks()) == 0: continue
            eleTrk=electron.getTracks().At(0)
            posTrk=positron.getTracks().At(0)
            if eleTrk is None or posTrk is None : continue
            eleTrk.Print("v")
            #track timing
            if eleTrk.getTrackTime() - posTrk.getTrackTime()> trkDeltaT :
                continue
            #track slope (if any cut)
            if abs(eleTrk.getTanLambda())<slopeCut or abs(posTrk.getTanLambda())<slopeCut :
                continue
            print 'satisfied timing cuts...'
            ##############
            # track killer part
            if isMC and trackKiller : 
                if pMag(pEle) <tkThreshold : #electron
                    tkEff=tkSlope*pMag(pEle)+tkIntercept 
                    if random.random()>tkEff  :
                        continue
                elif random.random()>tkThreshEff :  #allow for a flat killer above threshold
                    continue
                if pMag(pPos) <tkThreshold :   # positron
                    tkEff=tkSlope*pMag(pPos)+tkIntercept 
                    if random.random()>tkEff  :
                        continue
                elif random.random()>tkThreshEff : #allow for a flat killer above threshold
                    continue
            #  end of track killer
            ##############
            nPassTrkCuts+=1

            ##############
            #   ECAL matching and timing cuts...also fiducial region cuts...
            if requireECalMatch: 
                if positron.getClusters().GetEntries() == 0 :
                    continue
                if electron.getClusters().GetEntries() == 0 :
                    continue
                posCluster=positron.getClusters().First()
                eleCluster=electron.getClusters().First()
                
                if eleCluster.getClusterTime()- posCluster.getClusterTime() > cluDeltaT:
                    continue
                
                if eleTrk.getTrackTime() - eleCluster.getClusterTime()+43.5 > cluTrkDeltaT : 
                    continue

                if posTrk.getTrackTime() - posCluster.getClusterTime()+43.5 > cluTrkDeltaT : 
                    continue
                
                if requireECalFiducial:
                    #ANTI-fiducial cut
                    #                    if  myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                    #                        continue
                    #                    if  myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                    #                        continue
                    #Fiducial cut
                    if not myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                        continue
                    if not myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                        continue
                if requireECalSuperFiducial :
                    if not myhist.inSuperFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                        continue
                    if not myhist.inSuperFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                        continue
            nPassECalMatch+=1
            ##############
            #Passed the cuts..append the candidate index
            findWABPair(electron,hps_event)
            candidateList.append(uc_index)
      

        numCands=len(candidateList)
        if addFakeEle :
            for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
                track = hps_event.getTrack(track_n)
                if track is None : 
                    continue
                if trkMatchAndFiducial(track.getParticle()) and trkMomentum(track,minPCut,beamCut) and track.getCharge>0 and newEle.getMomentum()[1]*track.getMomentum()[1]<0: # get positron in fudicial region; make sure it's in opposite quadrant
                    myhist.eSum.Fill(newEle.getEnergy()+pMag(track.getMomentum()))
                    numCands+=1
                    if len(candidateList) == 0 : 
                        print 'made a new trident event' 
                        nFakeTri+=1
                    
        myhist.nCand.Fill(numCands)
      
        #########################        
        #   found some candidates...lets fill plots...
        #########################        
        for index in range(0,len(candidateList)) :
            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index])
            myhist.fillCandidateHistograms(particle)
            myhist.nTrkCand.Fill(n_tracks);
            myhist.nPosCand.Fill(npositrons);
            myhist.nEleCand.Fill(n_tracks-npositrons);
            myhist.nClustCand.Fill(hps_event.getNumberOfEcalClusters())
            

#    if(nPassTrkCuts>0): 
    myhist.saveHistograms(output_file)   

    print "******************************************************************************************"
    print "Number of Events:\t\t",nEvents,"\t\t\t",float(nEvents)/nEvents,"\t\t\t",float(nEvents)/nEvents
    print "N(particle) Cuts:\t\t",nPassBasicCuts,"\t\t\t",float(nPassBasicCuts)/nEvents,"\t\t\t",float(nPassBasicCuts)/nEvents
    print "V0 Vertex   Cuts:\t\t",nPassV0Cuts,"\t\t\t",float(nPassV0Cuts)/nPassBasicCuts,"\t\t\t",float(nPassV0Cuts)/nEvents
    print "Tracking    Cuts:\t\t",nPassTrkCuts,"\t\t\t",float(nPassTrkCuts)/nPassV0Cuts,"\t\t\t",float(nPassTrkCuts)/nEvents
    print "ECal Match  Cuts:\t\t",nPassECalMatch,"\t\t\t",float(nPassECalMatch)/nPassTrkCuts,"\t\t\t",float(nPassECalMatch)/nEvents

    print "Number of Fake Events Added:  \t\t",nFakeTri,"\t\t\t",float(nFakeTri)/nPassECalMatch
Exemplo n.º 38
0
def morph(hist1, hist2, mass1, mass2, targetMass, debug=False):
    from ROOT import gROOT, RooRealVar, RooIntegralMorph,\
        kRed,kBlue,kViolet, RooDataHist, RooArgSet,\
        RooArgList, RooHistPdf, RooAbsReal, RooFit

    import re

    if mass1 < mass2:
        histLow = hist1
        massLow = mass1
        histHigh = hist2
        massHigh = mass2
    else:
        histLow = hist2
        massLow = mass2
        histHigh = hist1
        massHigh = mass1

    x = RooRealVar("x", "x",
                   histLow.GetXaxis().GetXmin(),
                   histLow.GetXaxis().GetXmax())
    mAlpha = 1.0 - float(targetMass - massLow) / float(massHigh - massLow)
    print 'alpha:', mAlpha,
    newIntegral = histLow.Integral() + \
        (targetMass - massLow) * \
        (histHigh.Integral()-histLow.Integral()) / \
        (massHigh-massLow)
    print 'low integral:', histLow.Integral(), \
        'high integral:', histHigh.Integral(), \
        'new integral:', newIntegral

    newHistLow = RooDataHist("sigHistLow_hist", "sigHistLow_hist",
                             RooArgList(x), histLow)
    sigHistLow = RooHistPdf("sigHistLow", "sigHistLow", RooArgList(x),
                            RooArgList(x), newHistLow)

    newHistHigh = RooDataHist("sigHistHigh_hist", "sigHistHigh_hist",
                              RooArgList(x), histHigh)
    sigHistHigh = RooHistPdf("sigHistHigh", "sigHistHigh", RooArgList(x),
                             RooArgList(x), newHistHigh)

    #x.Print("v")
    x.setBins(histLow.GetNbinsX(), "cache")
    alpha_morph = RooRealVar("alpha_morph", "#alpha_{morph}", mAlpha, 0., 1.)
    alpha_morph.setBins(10, "cache")

    sigModel = RooIntegralMorph("sigModel", "sigModel", sigHistLow,
                                sigHistHigh, x, alpha_morph)

    if (debug):
        from ROOT import gPad, RooFit
        frame = x.frame()
        sigHistLow.plotOn(frame, RooFit.LineColor(kRed + 1),
                          RooFit.LineStyle(2))
        sigHistHigh.plotOn(frame, RooFit.LineColor(kBlue + 1),
                           RooFit.LineStyle(2))
        sigModel.plotOn(frame, RooFit.LineColor(kViolet + 1),
                        RooFit.LineStyle(9))
        frame.Draw()
        gPad.Update()
        gPad.WaitPrimitive()

    morphHist = sigModel.createHistogram(
        re.sub(r'\d+', '%i' % targetMass, hist1.GetName()), x,
        RooFit.Binning(histLow.GetNbinsX()))
    morphHist.Scale(newIntegral / morphHist.Integral())
    morphHist.SetName(re.sub(r'\d+', '%i' % targetMass, hist1.GetName()))

    # if debug:
    #     morphHist.Print()

    return morphHist
Exemplo n.º 39
0
    frame.Draw()

    parsSig = signal.getParameters(roohistSig)
    parsSig.setAttribAll('Constant', True)

if histpdfSig:

    # -----------------------------------------
    # hist pdf signal
    canSname = 'can_Mjj' + str(mass)
    canS = TCanvas(canSname, canSname, 900, 600)
    gPad.SetLogy()

    roohistSig = RooDataHist('roohist', 'roohist', RooArgList(x), hSig)
    roohistSig.Print()
    signal = RooHistPdf('signal', 'signal', RooArgSet(x), roohistSig)
    signal.Print()
    frame = x.frame()
    roohistSig.plotOn(frame, RooFit.Binning(166))
    signal.plotOn(frame, RooFit.Binning(166), RooFit.LineColor(ROOT.kRed),
                  RooFit.LineWidth(2), RooFit.LineStyle(ROOT.kDashed))

    #frame.GetXaxis().SetRangeUser(1118,6099)
    frame.GetXaxis().SetRangeUser(minX_mass, maxX_mass)
    frame.GetXaxis().SetTitle('m_{jj} (GeV)')
    frame.Draw()

#    parsSig = signal.getParameters(roohistSig)
#    parsSig.setAttribAll('Constant', True)

if fitDat:
Exemplo n.º 40
0
def main(options, args):

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

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

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

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

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

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

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

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

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

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

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

    print ws

    aset = RooArgSet(mass)

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

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

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

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

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

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

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

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

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

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

        del cdf
        del pdf

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

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

    cdf = pdf.createCdf(aset)

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

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

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

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

    del cdf
    del pdf
    del helper.dsets

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        plot_ds.sumEntries()

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

        if "comb" in c:
            ip = 0

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

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

    from pprint import pprint
    pprint(helper)

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

    print "Done."
Exemplo n.º 41
0
    #eff_p4= acceptanceFile.Get("l1_p4").GetFunction("pol4").Eval(mass)
    eff_p4 = 0
    exppol4.SetParameters(eff_p0, eff_p1, eff_p2, eff_p3, eff_p4)
    exppol4.Draw()
    exppol4.GetYaxis().SetRangeUser(0, 2)

    fitfunc.SetParameters(1.0, mean, sigma, breakz, length)
    bkgHist.Reset()
    for binnum in xrange(1, nbins_histpdf + 1):
        bkgHist.SetBinContent(
            binnum, fitfunc.Eval(bkgHist.GetXaxis().GetBinCenter(binnum)))
#    bkgHist.Draw()
    bkgDataHist = RooDataHist("bkgDataHist_{0}".format(i),
                              "bkgDataHist_{0}".format(i),
                              RooArgList(w.set("obs_1d")), bkgHist)
    bkgPdf = RooHistPdf("bkgPdf_{0}".format(i), "bkgPdf_{0}".format(i),
                        w.set("obs_1d"), bkgDataHist)
    getattr(w, 'import')(bkgPdf, RooFit.Silence())

    #w.factory("Exponential::bkg_{0}(uncVZ,{0})".format(i,-1.0/length))
    #w.factory("EXPR::gaussExp_{0}('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)".format(i,mean,sigma,breakz,length))

    c.Clear()
    c.SetLogy()
    vtxZRefitUnc.setRange("fitRange", tailcut, 50)
    frame = vtxZRefitUnc.frame()
    frame.SetAxisRange(tailcut, 50)
    frame.SetTitle(name)
    frame.GetXaxis().SetTitle("Vertex Z [mm]")
    dataPastCut2.plotOn(frame)
    thispdf = w.pdf("bkgPdf_{0}".format(i))
    fitresult = thispdf.fitTo(dataPastCut2, RooFit.Range("fitRange"),
Exemplo n.º 42
0
def main():
    # usage description
    usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    args = parser.parse_args()

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

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

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

    # sort masses
    masses.sort()

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

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

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

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

    sqrtS = args.sqrtS

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

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

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

    for mass in masses:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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