Ejemplo n.º 1
0
def fit_real_data(label):
    '''
    Fit dataset specified by the label: "data" (full 2011A+B),
    "2011A" or "2011B".
    '''
    fit_result = pm.fitTo(data[label], roo.Range('fit'),  roo.NumCPU(8),
                             roo.Timer(), # roo.Verbose()
                             roo.InitialHesse(True), roo.Minos(),
                             roo.Save(), 
        )
    w.Import(fit_result, 'fitresult_' + label)
Ejemplo n.º 2
0
    's_{fit}: %.3f #pm %.3f %%' % (phoScale.getVal(), phoScale.getError()),
    's_{fit} - s_{shape}: %.4f #pm %.4f %%' % (
        phoScale.getVal() - t2pdf.s0val,
        phoScale.getError()
        ),
    'r_{shape}: %.3f %%' % t2pdf.r0val,
    'r_{fit}: %.3f #pm %.3f %%' % (phoRes.getVal(), phoRes.getError()),
    'r_{fit}/r_{shape}: %.4f #pm %.4f' % (
        phoRes.getVal() / t2pdf.r0val,
        phoRes.getError() / t2pdf.r0val),
    ], position=(0.2, 0.75)).draw()

canvases.update()

t.setRange(*t1range)
xtpdf.fitTo(xtdata, roo.NumCPU(8), roo.Verbose(True), roo.Timer(True),
            roo.SumW2Error(True), roo.Minos(ROOT.RooArgSet(phoRes)))

## Plot fXT(t|s,r) fitted to data
## canvases.next('tpdf').SetGrid()
## t.setRange(5, 10)
## t.SetTitle('log(m_{#mu#mu#gamma}^{2} - m_{#mu#mu}^{2})')
## tpdf.fitTo(tdata, roo.Range(5.5, 9.5))
## plot = t.frame(roo.Range(6, 9))
## tdata.plotOn(plot)
## tpdf.plotOn(plot)
## tpdf.paramOn(plot)
## plot.Draw()
canvases.update()
sw.Stop()
print 'CPU time:', sw.CpuTime(), 's, real time:', sw.RealTime(), 's'
Ejemplo n.º 3
0
unitg = w.factory('Gaussian::unitg(pull[-5,5],zero[0],unit[1])')
pull = w.var('pull')

defaultd = ROOT.RooDataSet('defaultd', 'defaultd', ROOT.RooArgSet(pull))
bind = ROOT.RooDataSet('bind', 'bind', ROOT.RooArgSet(pull))
mediand = ROOT.RooDataSet('mediand', 'mediand', ROOT.RooArgSet(pull))
pdgd = ROOT.RooDataSet('pdgd', 'pdgd', ROOT.RooArgSet(pull))

## Build the model
# model = w.factory('Gaussian::gaus(x[-5,5],mean[0,-6,6],sigma[1,0.5,2])')
model = w.factory('RooSechPdf::sech(x[-5,5],mean[0,-6,6],sigma[1,0.5,2])')
x = w.factory('x')

for itoy in range(ntoys):
    ## Use the model to generate a toy dataset
    data = model.generate(ROOT.RooArgSet(x), nentries, roofit.NumCPU(numCPU))

    ## Fit the model to the generated data
    model.fitTo(data, roofit.NumCPU(numCPU), roofit.Verbose(False))

    ## Get custom binning
    nevents = data.tree().Draw(x.GetName(), '', 'goff')
    bins = DataDrivenBinning(nevents,
                             data.tree().GetV1(), minBinContent, maxBinContent)
    binning = bins.binning(ROOT.RooBinning())
    ubinning = bins.uniformBinning(ROOT.RooUniformBinning())

    ## Make sure that there are at least 1./epsilonPerBin curve points
    ## in each bin.  The RooChi2Calculator fails if there is none perhaps
    ## due to a bug in RooCurve::average?  Reason is not understood yet.
    epsilon = epsilonPerBin * ubinning.binWidth(0) / bins.length()
Ejemplo n.º 4
0
def process_monte_carlo():
    '''
    Get, fit and plot monte carlo.
    '''
    global fitdata1
    fitdata1 = fit_calibrator.get_smeared_data(
        sfit, rfit, 'fitdata1', 'fitdata1', True
        )
    fitdata1.reduce(ROOT.RooArgSet(mmgMass, mmMass))
    fitdata1.append(data['zj1'])
    fitdata1.SetName('fitdata1')
    data['fit1'] = fitdata1

    if reduce_data == True:
        fitdata1 = fitdata1.reduce(roo.Range(reduced_entries,
                                           fitdata1.numEntries()))
    check_timer('3. get fit data (%d entries)' % fitdata1.numEntries())

    nll = pm.createNLL(fitdata1, roo.Range('fit'), roo.NumCPU(8))

    minuit = ROOT.RooMinuit(nll)
    minuit.setProfile()
    minuit.setVerbose()

    phoScale.setError(1)
    phoRes.setError(1)

    ## Initial HESSE
    status = minuit.hesse()
    fitres = minuit.save(name + '_fitres1_inithesse')
    w.Import(fitres, fitres.GetName())
    check_timer('4. initial hesse (status: %d)' % status)

    ## Minimization
    minuit.setStrategy(2)
    status = minuit.migrad()
    fitres = minuit.save(name + '_fitres2_migrad')
    w.Import(fitres, fitres.GetName())
    check_timer('5. migrad (status: %d)' % status)

    ## Parabolic errors
    status = minuit.hesse()
    fitres = minuit.save(name + '_fitres3_hesse')
    w.Import(fitres, fitres.GetName())
    check_timer('6. hesse (status: %d)' % status)

    ## Minos errors
    status = minuit.minos()
    fitres = minuit.save(name + '_fitres4_minos')
    w.Import(fitres, fitres.GetName())
    check_timer('7. minos (status: %d)' % status)

    #fres = pm.fitTo(fitdata1, roo.SumW2Error(True),
                    #roo.Range('fit'),
                    ## roo.Strategy(2),
                    #roo.InitialHesse(True),
                    #roo.Minos(),
                    #roo.Verbose(True),
                    #roo.NumCPU(8), roo.Save(), roo.Timer())

    signal_model._phorhist.GetXaxis().SetRangeUser(75, 105)
    signal_model._phorhist.GetYaxis().SetRangeUser(0, 15)
    signal_model._phorhist.GetXaxis().SetTitle('%s (%s)' % (mmgMass.GetTitle(),
                                                  mmgMass.getUnit()))
    signal_model._phorhist.GetYaxis().SetTitle('E^{#gamma} Resolution (%)')
    signal_model._phorhist.GetZaxis().SetTitle('Probability Density (1/GeV/%)')
    signal_model._phorhist.SetTitle(latex_title)
    signal_model._phorhist.GetXaxis().SetTitleOffset(1.5)
    signal_model._phorhist.GetYaxis().SetTitleOffset(1.5)
    signal_model._phorhist.GetZaxis().SetTitleOffset(1.5)
    signal_model._phorhist.SetStats(False)
    canvases.next(name + '_phorhist')
    signal_model._phorhist.Draw('surf1')

    global graph
    graph = signal_model.make_mctrue_graph()
    graph.GetXaxis().SetTitle('E^{#gamma} resolution (%)')
    graph.GetYaxis().SetTitle('m_{#mu^{+}#mu^{-}#gamma} effective #sigma (GeV)')
    graph.SetTitle(latex_title)
    canvases.next(name + '_mwidth_vs_phor').SetGrid()
    graph.Draw('ap')

    mmgMass.setBins(80)
    plot = mmgMass.frame(roo.Range('plot'))
    plot.SetTitle('Fall11 MC, ' + latex_title)
    fitdata1.plotOn(plot)
    pm.plotOn(plot, roo.Range('plot'), roo.NormRange('plot'))
    pm.plotOn(plot, roo.Range('plot'), roo.NormRange('plot'),
              roo.Components('*zj*'), roo.LineStyle(ROOT.kDashed))     
    canvases.next(name + '_fit').SetGrid()
    plot.Draw()
    ## Estimate the MC truth phos and phor:
    old_precision = set_default_integrator_precision(2e-9, 2e-9)
    calibrator0.s.setRange(-15, 15)
    calibrator0.r.setRange(0,25)
    calibrator0.phoEResPdf.fitTo(fitdata1, roo.Range(-50, 50), roo.Strategy(2))
    set_default_integrator_precision(*old_precision)
    set_mc_truth(calibrator0.s, calibrator0.r)

    ## Store the result in the workspace:
    w.saveSnapshot('mc_fit', ROOT.RooArgSet(phoScale, phoRes,
                                            phoScaleTrue, phoResTrue))
    ## Draw the results on the canvas:
    Latex([
        'E^{#gamma} Scale (%)',
        '  MC Truth: %.2f #pm %.2f' % (calibrator0.s.getVal(),
                                       calibrator0.s.getError()),
        '  MC Fit: %.2f #pm %.2f ^{+%.2f}_{%.2f}' % (
            phoScale.getVal(), phoScale.getError(), phoScale.getErrorHi(),
            phoScale.getErrorLo()
            ),
        '',
        'E^{#gamma} Resolution (%)',
        '  MC Truth: %.2f #pm %.2f' % (calibrator0.r.getVal(),
                                       calibrator0.r.getError()),
        '  MC Fit: %.2f #pm %.2f ^{+%.2f}_{%.2f}' % (
            phoRes.getVal(), phoRes.getError(), phoRes.getErrorHi(),
            phoRes.getErrorLo()
            ),
        '',
            'Signal Purity (%)',
            '  MC Truth: %.2f' % fsr_purity,
            '  MC Fit: %.2f #pm %.2f' % (
                100 * w.var('signal_f').getVal(),
                100 * w.var('signal_f').getError()
                )
        ],
        position=(0.2, 0.8)
        ).draw()
    
    check_timer('8. fast plots')
Ejemplo n.º 5
0
    def __init__(self,
                 name,
                 title,
                 mass,
                 phos,
                 phor,
                 data,
                 workspace,
                 phostarget,
                 phortargets,
                 rho=1.5,
                 mirror=ROOT.RooKeysPdf.NoMirror,
                 mrangetrain=(40, 140),
                 mrangenorm=(50, 130),
                 mrangefit=(60, 120)):
        '''PhosphorModel4(str name, str title, RooRealVar mass, RooRealVar phos,
            RooRealVar phor, RooDataSet data, float phostarget,
            [float] phortargets, float rho=1.5,
            int mirror=ROOT.RooKeysPdf.NoMirror)
        name - PDF name
        title - PDF title
        mass - mumugamma invariant mass (GeV), observable
        phos - photon energy scale (%), parameter
        phor - photon energy resolution (%), paramter
        data - (mmMass, mmgMass, phoERes = 100*(phoEreco/phoEgen - 1), dataset
            on which the shapes of reference PDFs are trained.
        phostarget - target reference value of the photon energy scale at which
            the model is being trained
        phortargetss - a list of target photon energy resolution values for the
            moment morphing
        rho - passed to trained RooKeysPdfs
        mirror - passed to trained RooKeysPdfs        
        '''
        ## Attach args.
        self._name = name
        self._title = title
        self._mass = mass
        self._phos = phos
        self._phor = phor
        self._data = data
        self._phostarget = phostarget
        self._phortargets = phortargets[:]
        self._rho = rho
        self._mirror = mirror
        ## Attach other attributes.
        self._massrange = (mass.getMin(), mass.getMax())
        self._sdata_list = []
        self._phostrue_list = []
        self._phortrue_list = []
        self._dm_dphos_list = []
        self._msubs_list = []
        self._keys_pdfs = []
        self._keys_modes = []
        self._keys_effsigmas = []
        self._keys_fitresults = []
        self._pdfs = []
        self._custs = []
        # self._pdfrefs = []
        self._mrefs = []
        self._phormorphs = []
        self._phorhists = []
        self._workspace = workspace
        ## self._workspace = ROOT.RooWorkspace(name + '_workspace',
        ##                                     title + ' workspace')
        w = self._workspace
        self.w = w
        ## Import important args in workspace.
        # w.Import(ROOT.RooArgSet(mass, phos, phor))
        w.Import(mass)
        w.Import(phos)
        w.Import(phor)
        w.Import(self._data)
        w.factory('ConstVar::{name}_phostarget({value})'.format(
            name=name, value=self._phostarget))
        ## Define the morphing parameter. This an identity with the
        ## photon resolution for now.
        mpar = self._mpar = w.factory(
            'expr::{name}_mpar("{phor}", {{{phor}}})'.format(
                ## 'expr::{name}_mpar("2 + sqrt(0.5^2 + 0.05 * {phor}^2)", {{{phor}}})'.format(
                ## 'expr::{name}_mpar("2.325+sqrt(0.4571 + (0.1608*{phor})^2)", {{{phor}}})'.format(
                name=name,
                phor=phor.GetName()))
        ## Define the formula for dlog(m)/dphos.
        self._dm_dphos_func = w.factory('''
            expr::dm_dphos_func("0.5 * (1 - mmMass^2 / mmgMass^2) * mmgMass",
                                   {mmMass, mmgMass})
            ''')
        ## Get the calibrator.
        self._calibrator = MonteCarloCalibrator(self._data)
        ## Loop over target reference photon energy resolutions in phortargets.
        for index, phortarget in enumerate(self._phortargets):
            ## Store the target photon resolution value.
            w.factory('ConstVar::{name}_phortarget_{index}({value})'.format(
                name=name, index=index, value=phortarget))

            ## Get the corresponding smeared RooDataSet sdata named
            ##     {name}_sdata_{index} and attach it to self._sdata
            sdata = self._calibrator.get_smeared_data(
                self._phostarget,
                phortarget,
                name + '_sdata_%d' % index,
                title + ' sdata %d' % index,
                ## Get the true scale and resolution with errors. (This can be
                ##     added to the calibrator and snapshots of
                ##     self._calibrator.s and self._calibrator.r stored as
                ##     {name}_sdata_{index}_sr in self._calibrator.w)
                dofit=True)
            self._sdata_list.append(sdata)
            w.Import(sdata)
            phostrue = ROOT.RooRealVar(self._calibrator.s,
                                       name + '_phostrue_%d' % index)
            phortrue = ROOT.RooRealVar(self._calibrator.r,
                                       name + '_phortrue_%d' % index)
            phostrue.setConstant(True)
            phortrue.setConstant(True)
            self._phostrue_list.append(phostrue)
            self._phortrue_list.append(phortrue)
            w.Import(phostrue)
            w.Import(phortrue)

            ## Calculate the dlogm/dphos {name}_dm_dphos_{index}
            ##     for the smeared dataset.
            sdata.addColumn(self._dm_dphos_func)
            dm_dphos = w.factory('''
                {name}_dm_dphos_{index}[{mean}, 0, 1]
                '''.format(name=name,
                           index=index,
                           mean=sdata.mean(sdata.get()['dm_dphos_func'])))
            dm_dphos.setConstant(True)
            self._dm_dphos_list.append(dm_dphos)

            ## Define the mass scaling {name}_msubs{i} introducing
            ##     the dependence on phos. This needs self._calibrator.s and
            ##     dm_dphos.
            ## msubs = w.factory(
            ##     '''
            ##     LinearVar::{msubs}(
            ##         {mass}, 1,
            ##         expr::{offset}(
            ##             "- 0.01 * {dm_dphos} * ({phos} - {phostrue})",
            ##             {{ {dm_dphos}, {phos}, {phostrue} }}
            ##             )
            ##         )
            ##     '''.format(msubs = name + '_msubs_%d' % index,
            ##                offset = name + '_msubs_offset_%d' % index,
            ##                mass = self._mass.GetName(),
            ##                dm_dphos = dm_dphos.GetName(),
            ##                phos = self._phos.GetName(),
            ##                phostrue = phostrue.GetName())
            ## )
            ## LinearVar cannot be persisted.
            msubs = w.factory('''
                expr::{msubs}(
                     "{mass} - 0.01 * {dm_dphos} * ({phos} - {phostrue})",
                     {{ {mass}, {dm_dphos}, {phos}, {phostrue} }}
                     )
                '''.format(msubs=name + '_msubs_%d' % index,
                           mass=self._mass.GetName(),
                           dm_dphos=dm_dphos.GetName(),
                           phos=self._phos.GetName(),
                           phostrue=phostrue.GetName()))
            self._msubs_list.append(msubs)

            ## Build the corresponding parametrized KEYS PDF {name}_kyes_{index}
            ##     with {name}_keys_mode_{index} and
            ##     {name}_keys_effsigma_{index}.
            keys_mode = w.factory(
                '{name}_keys_mode_{index}[91.2, 60, 120]'.format(name=name,
                                                                 index=index))
            keys_effsigma = w.factory(
                '{name}_keys_effsigma_{index}[3, 0.1, 60]'.format(name=name,
                                                                  index=index))
            mass.setRange(*mrangetrain)
            keys_pdf = ParametrizedKeysPdf(name + '_keys_pdf_%d' % index,
                                           name + '_keys_pdf_%d' % index,
                                           mass,
                                           keys_mode,
                                           keys_effsigma,
                                           sdata,
                                           rho=self._rho)
            self._keys_modes.append(keys_mode)
            self._keys_effsigmas.append(keys_effsigma)
            self._keys_pdfs.append(keys_pdf)

            ## Fit the KEYS PDF to the training data and save the result
            ##     {name}_keys_fitresult_{index} and parameter snapshots
            ##     {name}_keys_mctrue_{index}.
            mass.setRange(*mrangenorm)
            keys_fitresult = keys_pdf.fitTo(sdata, roo.Range(*mrangefit),
                                            roo.Strategy(2), roo.NumCPU(8),
                                            roo.Save(True))
            self._keys_fitresults.append(keys_fitresult)
            w.Import(keys_fitresult, name + '_keys_fitresult_%d' % index)
            w.saveSnapshot(
                name + '_mctrue_%d' % index, ','.join([
                    phostrue.GetName(),
                    phortrue.GetName(),
                    keys_mode.GetName(),
                    keys_effsigma.GetName()
                ]))

            ## Sample the fitted KEYS PDF to a histogram {name}_hist_{index}.
            mass.setRange(*mrangetrain)
            hist = keys_pdf.createHistogram(name + '_hist_%d' % index, mass,
                                            roo.Binning('cache'))

            ## Build a RooDataHist {name}_dhist{index} of the sampled histogram.
            dhist = ROOT.RooDataHist(name + '_dhist_%d' % index,
                                     name + '_dhist_%d' % index,
                                     ROOT.RooArgList(mass), hist)
            w.Import(dhist)

            ## Build a RooHistPdf {name}_pdf_{index} using the dhist and msubs.
            ## pdf = w.factory(
            pdf = w.factory('HistPdf::{name}({{{mass}}}, {dhist}, 1)'.format(
                name=name + '_pdf_%d' % index,
                msubs=msubs.GetName(),
                mass=mass.GetName(),
                dhist=dhist.GetName()))
            self._pdfs.append(pdf)
            mass.setRange(*self._massrange)

            ## Calculate morphing parameter reference values float mref[index].
            phorval = phor.getVal()
            phor.setVal(phortrue.getVal())
            self._mrefs.append(mpar.getVal())
            phor.setVal(phorval)
        ## End of loop over target phortargets

        ## Make the reference and cache binnings in phor
        self._check_phor_ranges()
        partitions = self._partition_binning(self._phor, 'cache', 'reference')

        ## Loop over phor reference bins and define pairwise RooMomentMorphs.
        for ilo in range(len(self._mrefs) - 1):
            ihi = ilo + 1
            mlo = self._mrefs[ilo]
            mhi = self._mrefs[ihi]
            pdflo = self._pdfs[ilo]
            pdfhi = self._pdfs[ihi]
            phormorph = w.factory('''
                MomentMorph::{name}_phormorph_{ilo}to{ihi}(
                    {mpar}, {{{mass}}}, {{{pdfs}}}, {{{mrefs}}}
                    )
                '''.format(name=name,
                           ilo=ilo,
                           ihi=ihi,
                           mpar=mpar.GetName(),
                           mass=mass.GetName(),
                           pdfs='%s, %s' % (pdflo.GetName(), pdfhi.GetName()),
                           mrefs='%f, %f' % (mlo, mhi)))
            self._phormorphs.append(phormorph)
            ## Sample the morph in a 2D histogram in mass and phor.
            phorhist = phormorph.createHistogram(
                name + '_phorhist_%dto%d' % (ilo, ihi), mass,
                roo.Binning('cache'),
                roo.YVar(phor, roo.Binning(partitions[ilo])))
            self._phorhists.append(phorhist)
        ## End of loop over phor reference bins.
        self._stitch_phorhists()
        self._phor_dhist = phor_dhist = ROOT.RooDataHist(
            name + '_phor_dhist', name + '_phor_dhist',
            ROOT.RooArgList(mass, phor), self._phorhist)

        average_index = (len(self._msubs_list) + 1) / 2
        msubs = self._msubs_list[average_index]

        ## self._model = model = ROOT.RooHistPdf(
        ##     name + '_phor_histpdf', name + '_phor_histpdf',
        ##     ROOT.RooArgList(msubs, phor), ROOT.RooArgList(mass, phor), phor_dhist, 2
        ##     )
        ## self._model = model = ROOT.RooPhosphorPdf(
        ##     name + '_phor_histpdf', name + '_phor_histpdf', mass, msubs, phor, phor_dhist, 2
        ##     )

        ## ## Quick hack to make things work.
        ## self._customizer = customizer = ROOT.RooCustomizer(model, 'msub')
        ## customizer.replaceArg(mass, msubs)
        ## model = customizer.build()

        # ROOT.RooHistPdf.__init__(self, model)
        ROOT.RooPhosphorPdf.__init__(self, name, title, mass, msubs, phos,
                                     phor, phor_dhist, 2)
        self.SetName(name)
        self.SetTitle(title)