def func_vetoJpsiX(args):
    """ Remvoe LSB from Fit region """
    dataReaderCfg = deepcopy(dataCollection.dataReaderCfg)
    dataReaderCfg.update({
        'preloadFile': None
    })
    dataReader = DataReader(dataReaderCfg)
    dataReader.customize = types.MethodType(
        functools.partial(dataCollection.customizeOne,
                          targetBMassRegion=['altFit_vetoJpsiX'],
                          extraCuts=cut_kshortWindow),
        dataReader
    )
    fitterCfg = deepcopy(fitCollection.setupFinalFitter)
    fitterCfg.update({
        'data': "dataReader.altFit_vetoJpsiX",
        'saveToDB': False
    })
    fitter = StdFitter(fitterCfg)
    p.setSequence([
        pdfCollection.stdWspaceReader,
        dataReader,
        fitter,
    ])

    try:
        p.beginSeq()
        p.runSeq()

        updateToDB_altShape(args, "vetoJpsiX")
    finally:
        p.endSeq()
def func_altSP(args):
    """ Set fs to 5% instead of 0% """
    setupFinalAltSPFitter = deepcopy(fitCollection.setupFinalFitter)
    setupFinalAltSPFitter.update({
        'argAliasInDB': {'afb': 'afb_altSP', 'fl': 'fl_altSP', 'fs': 'fs_altSP', 'as': 'as_altSP'},
        'saveToDB': False,
    })
    finalAltSPFitter = StdFitter(setupFinalAltSPFitter)
    def _preFitSteps_vetoSmallFs_altSP(self):
        """ fs is usually negligible, set the alternative fraction to 0.05 """
        if "fs" in self.cfg.get('argPattern'):
            fs = self.args.find("fs")
            transAs = self.args.find("transAs")
            fs.setVal(0.05)
            fs.setConstant(True)
            transAs.setVal(0)
            transAs.setConstant(False)

    finalAltSPFitter._preFitSteps_vetoSmallFs = types.MethodType(_preFitSteps_vetoSmallFs_altSP, finalAltSPFitter)

    p.setSequence([
        pdfCollection.stdWspaceReader,
        dataCollection.dataReader,
        finalAltSPFitter,
    ])

    try:
        p.beginSeq()
        p.runSeq()

        updateToDB_altShape(args, "altSP")
    finally:
        p.endSeq()
def func_altSigM(args):
    """ Not used """
    setupFinalAltSigMFitter = deepcopy(fitCollection.setupFinalFitter)
    setupFinalAltSigMFitter.update({
        'argAliasInDB': {'afb': 'afb_altSigM', 'fl': 'fl_altSigM', 'fs': 'fs_altSigM', 'as': 'as_altSigM'},
        'saveToDB': False,
    })
    finalAltSigMFitter = StdFitter(setupFinalAltSigMFitter)
    def _preFitSteps_altSigM(self):
        StdFitter._preFitSteps(self)
        sigM_frac = self.args.find("sigM_frac")
        sigM_frac.setVal(0)
    finalAltSigMFitter._preFitSteps = types.MethodType(_preFitSteps_altSigM, finalAltSigMFitter)

    p.setSequence([
        pdfCollection.stdWspaceReader,
        dataCollection.dataReader,
        finalAltSigMFitter,
    ])

    try:
        p.beginSeq()
        p.runSeq()

        updateToDB_altShape(args, "altSigM")
    finally:
        p.endSeq()
def func_altEffi(args):
    """ Typically less than 1% """
    setupFinalAltEffiFitter = deepcopy(fitCollection.setupFinalFitter)
    setupFinalAltEffiFitter.update({
        'argAliasInDB': {'afb': 'afb_altEffi', 'fl': 'fl_altEffi', 'fs': 'fs_altEffi', 'as': 'as_altEffi'},
        'saveToDB': False,
    })
    finalAltEffiFitter = StdFitter(setupFinalAltEffiFitter)
    def _preFitSteps_altEffi(self):
        StdFitter._preFitSteps(self)
        hasXTerm = self.args.find("hasXTerm")
        hasXTerm.setVal(0)
    finalAltEffiFitter._preFitSteps = types.MethodType(_preFitSteps_altEffi, finalAltEffiFitter)

    p.setSequence([
        pdfCollection.stdWspaceReader,
        dataCollection.dataReader,
        finalAltEffiFitter,
    ])

    try:
        p.beginSeq()
        p.runSeq()

        updateToDB_altShape(args, "altEffi")
    finally:
        p.endSeq()
def func_altBkgCombM(args):
    """ Not used """
    setupFinalAltBkgCombMFitter = deepcopy(fitCollection.setupFinalFitter)
    setupFinalAltBkgCombMFitter.update({
        'pdf': "f_finalAltBkgCombM",
        'argAliasInDB': {'afb': 'afb_altBkgCombM', 'fl': 'fl_altBkgCombM', 'fs': 'fs_altBkgCombM', 'as': 'as_altBkgCombM'},
        'saveToDB': False,
    })
    finalAltBkgCombMFitter = StdFitter(setupFinalAltBkgCombMFitter)
    p.setSequence([
        pdfCollection.stdWspaceReader,
        dataCollection.dataReader,
        finalAltBkgCombMFitter,
    ])

    try:
        p.beginSeq()
        p.runSeq()

        updateToDB_altShape(args, "altBkgCombM")
    finally:
        p.endSeq()
        'sigMGauss2_sigma': 'sigMGauss2_sigma_bkgJpsi',
        'sigMGauss_mean': 'sigMGauss_mean_bkgJpsi',
        'sigM_frac': 'sigM_frac_bkgJpsi'
    },
})
bkgJpsiMFitter = StdFitter(setupBkgJpsiMFitter)

setupBkgPsi2sMFitter = deepcopy(setupBkgJpsiMFitter)
setupBkgPsi2sMFitter.update({
    'name': "bkgPsi2sMFitter",
    'data': "bkgPsi2sMCReader.Fit_noResVeto",
    'argAliasInDB': {
        'sigMGauss1_sigma': 'sigMGauss1_sigma_bkgPsi2s',
        'sigMGauss2_sigma': 'sigMGauss2_sigma_bkgPsi2s',
        'sigMGauss_mean': 'sigMGauss_mean_bkgPsi2s',
        'sigM_frac': 'sigM_frac_bkgPsi2s'
    },
})
bkgPsi2sMFitter = StdFitter(setupBkgPsi2sMFitter)

if __name__ == '__main__':
    #  p.setSequence([dataCollection.effiHistReader, pdfCollection.stdWspaceReader, effiFitter])
    #  p.setSequence([dataCollection.sigMCReader, pdfCollection.stdWspaceReader, sigMFitter])
    #  p.setSequence([dataCollection.sigMCReader, pdfCollection.stdWspaceReader, sig2DFitter])
    #  p.setSequence([dataCollection.bkgJpsiMCReader, pdfCollection.stdWspaceReader, bkgJpsiMFitter])
    #  p.setSequence([dataCollection.bkgPsi2sMCReader, pdfCollection.stdWspaceReader, bkgPsi2sMFitter])
    #  p.setSequence([dataCollection.dataReader, pdfCollection.stdWspaceReader, bkgCombAFitter])
    p.beginSeq()
    p.runSeq()
    p.endSeq()
def func_randEffi(args):
    """ Typically less than 5% """
    setupFinalRandEffiFitter = deepcopy(fitCollection.setupFinalFitter)
    setupFinalRandEffiFitter.update({
        'FitMinos': [False, ()],
        'argAliasInDB': {'afb': 'afb_randEffi', 'fl': 'fl_randEffi', 'fs': 'fs_randEffi', 'as': 'as_randEffi'},
        'saveToDB': False,
    })
    finalRandEffiFitter = StdFitter(setupFinalRandEffiFitter)

    def preFitSteps_randEffi(self):
        self.args = self.pdf.getParameters(self.data)
        self._preFitSteps_initFromDB()

        # Fluctuate cross-term correction
        effiArgs = ROOT.RooArgSet()
        FitterCore.ArgLooper(self.args, lambda iArg: effiArgs.add(iArg), targetArgs=[r"x\d{1,2}"])
        FitDBPlayer.fluctuateFromDB(self.process.dbplayer.odbfile, effiArgs, self.cfg['argAliasInDB'])

        self._preFitSteps_vetoSmallFs()
        self._preFitSteps_preFit()

    finalRandEffiFitter._preFitSteps = types.MethodType(preFitSteps_randEffi, finalRandEffiFitter)

    foutName = "syst_randEffi_{0}.root".format(q2bins[args.binKey]['label'])
    class effiStudier(AbsToyStudier):
        def _preSetsLoop(self):
            self.hist_afb = ROOT.TH1F("hist_afb", "", 300, -0.75, 0.75)
            self.hist_afb.GetXaxis().SetTitle("A_{{FB}}")
            self.hist_fl = ROOT.TH1F("hist_fl", "", 200, 0., 1.)
            self.hist_fl.GetXaxis().SetTitle("F_{{L}}")

        def _preRunFitSteps(self, setIndex):
            pass

        def _postRunFitSteps(self, setIndex):
            if self.fitter.fitResult["{0}.migrad".format(self.fitter.name)]['status'] == 0:
                afb = self.process.sourcemanager.get('afb')
                fl = self.process.sourcemanager.get('fl')
                self.hist_afb.Fill(afb.getVal())
                self.hist_fl.Fill(fl.getVal())

        def _postSetsLoop(self):
            fout = ROOT.TFile(foutName, "RECREATE")
            fout.cd()
            self.hist_afb.Write()
            self.hist_fl.Write()
            fout.Close()

        def getSubDataEntries(self, setIndex):
            return 1

        def getSubData(self):
            while True:
                yield self.data

    setupStudier = deepcopy(effiStudier.templateConfig())
    setupStudier.update({
        'name': "effiStudier",
        'data': "dataReader.Fit",
        'fitter': finalRandEffiFitter,
        'nSetOfToys': 200,
    })
    studier = effiStudier(setupStudier)

    p.setSequence([
        pdfCollection.stdWspaceReader,
        dataCollection.dataReader,
        studier,
    ])

    try:
        p.beginSeq()
        if os.path.exists("{0}".format(foutName)):
            print("{0} exists, skip fitting procedure".format(foutName))
        else:
            p.runSeq()

        fin = ROOT.TFile("{0}".format(foutName))

        hist_fl = fin.Get("hist_fl")
        gaus_fl = ROOT.TF1("gaus_fl", "gaus(0)", 0, 1)
        hist_fl.Fit(gaus_fl, "WI")

        hist_afb = fin.Get("hist_afb")
        gaus_afb = ROOT.TF1("gaus_afb", "gaus(0)", -0.75, 0.75)
        hist_afb.Fit(gaus_afb, "WI")

        syst_randEffi = {
            'syst_randEffi_fl': {
                'getError': gaus_fl.GetParameter(2),
                'getErrorHi': gaus_fl.GetParameter(2),
                'getErrorLo': -gaus_fl.GetParameter(2),
            },
            'syst_randEffi_afb': {
                'getError': gaus_afb.GetParameter(2),
                'getErrorHi': gaus_afb.GetParameter(2),
                'getErrorLo': -gaus_afb.GetParameter(2),
            }
        }
        print(syst_randEffi)

        if args.updatePlot:
            canvas = Plotter.canvas.cd()
            hist_afb.Draw("HIST")
            Plotter.latexCMSMark()
            Plotter.latexCMSExtra()
            Plotter.latexCMSSim()
            canvas.Print("syst_randEffi_afb_{0}.pdf".format(q2bins[args.binKey]['label']))

            hist_fl.GetXaxis().SetTitle("F_{{L}}")
            hist_fl.Draw("HIST")
            Plotter.latexCMSMark()
            Plotter.latexCMSExtra()
            Plotter.latexCMSSim()
            canvas.Print("syst_randEffi_fl_{0}.pdf".format(q2bins[args.binKey]['label']))

        if args.updateDB:
            FitDBPlayer.UpdateToDB(p.dbplayer.odbfile, syst_randEffi)
    finally:
        p.endSeq()