def import_fitresult(inCard, fitResult, toDrop=[]):
    # First convert the card and open workspace
    execute_cmd(
        'text2workspace.py -b %s -o morphedWorkspace.root --channel-masks --X-no-jmax'
        % inCard)
    w_f = ROOT.TFile.Open('morphedWorkspace.root', 'UPDATE')
    w = w_f.Get('w')
    # Open fit result we want to import
    print('Importing %s...' % fitResult)
    fr_f = ROOT.TFile.Open(fitResult)
    fr = fr_f.Get('fit_b')  # b-only fit result (fit_s for s+b)
    myargs = fr.floatParsFinal()
    outargs = ROOT.RooArgSet()

    _cache = []  # to avoid seg faults
    for i in range(myargs.getSize()):
        var = myargs.at(i)
        if var.GetName() in toDrop: continue

        if not w.allVars().contains(var):
            print('WARNING: Could not find %s' % var.GetName())
            continue

        outargs.add(var)
        _cache.append(var)

    w.saveSnapshot('morphedModel', outargs, True)
    w_f.WriteTObject(w, 'w', "Overwrite")
    w_f.Close()
def _runMLfit(cardOrW,
              blinding,
              verbosity,
              rMin,
              rMax,
              setParams,
              usePreviousFit=False,
              extra=''):
    if usePreviousFit: param_options = ''
    else: param_options = '--text2workspace "--channel-masks" '
    params_to_set = ','.join(['mask_%s_SIG=1' % r for r in blinding] +
                             ['%s=%s' % (p, v)
                              for p, v in setParams.items()] + ['r=1'])
    param_options += '--setParameters ' + params_to_set

    fit_cmd = 'combine -M FitDiagnostics {card_or_w} {param_options} --saveWorkspace --cminDefaultMinimizerStrategy 0 --rMin {rmin} --rMax {rmax} -v {verbosity} {extra}'
    fit_cmd = fit_cmd.format(
        card_or_w='initifalFitWorkspace.root --snapshotName initialFit'
        if usePreviousFit else cardOrW,
        param_options=param_options,
        rmin=rMin,
        rmax=rMax,
        verbosity=verbosity,
        extra=extra)

    with open('FitDiagnostics_command.txt', 'w') as out:
        out.write(fit_cmd)

    if os.path.isfile('fitDiagnosticsTest.root'):
        execute_cmd('rm fitDiagnosticsTest.root')

    execute_cmd(fit_cmd, out='FitDiagnostics.log')
Exemple #3
0
def nuis_pulls():
    diffnuis_cmd = 'python $CMSSW_BASE/src/HiggsAnalysis/CombinedLimit/test/diffNuisances.py fitDiagnosticsTest.root --abs -g nuisance_pulls.root'
    execute_cmd(diffnuis_cmd)
    # Make a PDF of the nuisance_pulls.root
    if os.path.exists('nuisance_pulls.root'):
        nuis_file = ROOT.TFile.Open('nuisance_pulls.root')
        nuis_can = nuis_file.Get('nuisances')
        nuis_can.Print('nuisance_pulls.pdf','pdf')
        nuis_file.Close()
Exemple #4
0
def gen_post_fit_shapes():
    fit_result_file = ROOT.TFile.Open('fitDiagnosticsTest.root')
    goodFitTags = _get_good_fit_results(fit_result_file)
    for t in goodFitTags:
        if os.path.exists('higgsCombineTest.FitDiagnostics.mH120.root'):
            workspace_file = 'higgsCombineTest.FitDiagnostics.mH120.root'
        else:
            workspace_file = 'higgsCombineTest.FitDiagnostics.mH120.123456.root'
        shapes_cmd = 'PostFit2DShapesFromWorkspace -w {w} -o postfitshapes_{t}.root -f fitDiagnosticsTest.root:fit_{t} --postfit --samples 100 --print 2> PostFitShapes2D_stderr_{t}.txt'.format(t=t,w=workspace_file)
        execute_cmd(shapes_cmd)
    fit_result_file.Close()
    def _setupProjDir(self):
        '''Create the directory structure where results will be stored.
        '''
        if not os.path.isdir(self.tag + '/'):
            if self.options.overwrite:
                execute_cmd('rm -rf ' + self.tag)
            print('Making dir ' + self.tag + '/')
            os.mkdir(self.tag + '/')

        if self.options.plotTemplateComparisons and not os.path.isdir(
                self.tag + '/UncertPlots/'):
            os.mkdir(self.tag + '/UncertPlots/')
def _runLimit(blindData,
              verbosity,
              setParams,
              card_or_w='card.txt',
              condor=False):
    # card_or_w could be `morphedWorkspace.root --snapshotName morphedModel`
    param_options = ''
    if len(setParams) > 0:
        param_options = '--setParameters ' + ','.join(
            '%s=%s' % (k, v) for k, v in setParams.items())

    limit_cmd = 'combine -M AsymptoticLimits -d {card_or_w} --saveWorkspace --cminDefaultMinimizerStrategy 0 {param_opt} {blind_opt} -v {verb}'
    limit_cmd = limit_cmd.format(card_or_w=card_or_w,
                                 blind_opt='--run=blind' if blindData else '',
                                 param_opt=param_options,
                                 verb=verbosity)

    # Run combine if not on condor
    if not condor:
        with open('Limit_command.txt', 'w') as out:
            out.write(limit_cmd)
        execute_cmd(limit_cmd)

    return limit_cmd
Exemple #7
0
def plot_signalInjection(tag, subtag, injectedAmount, seed=123456, condor=False):
    with cd(tag+'/'+subtag):
        if condor:
            tmpdir = 'notneeded/tmp/'
            execute_cmd('mkdir '+tmpdir) 
            execute_cmd('cat %s_%s_sigInj_r%s_output_*.tgz | tar zxvf - -i --strip-components 2 -C %s'%(tag,subtag,injectedAmount,tmpdir))
            tree_fit_sb = ROOT.TChain('tree_fit_sb')
            tree_fit_sb.Add(tmpdir+'fitDiagnostics_sigInj_r{rinj}*.root'.format(rinj=injectedAmount)) 
            
        else:
            toyOutput = ROOT.TFile.Open('fitDiagnostics_sigInj_r{rinj}_{seed}.root'.format(rinj=injectedAmount,seed=seed))
            tree_fit_sb = toyOutput.Get('tree_fit_sb')

        ROOT.gROOT.SetBatch(True)
        ROOT.gStyle.SetOptStat(False)
        # Final plotting
        result_can = ROOT.TCanvas('sigpull_can','sigpull_can',800,700)

        tree_fit_sb.Draw("(r-{rinj})/(rHiErr*(r<{rinj})+rLoErr*(r>{rinj}))>>sigpull(20,-5,5)".format(rinj=injectedAmount),"fit_status>=0")
        hsigpull = ROOT.gDirectory.Get('sigpull')
        tree_fit_sb.Draw("(r-{rinj})>>sigstrength(20,-1,1)".format(rinj=injectedAmount),"fit_status>=0")
        hsignstrength = ROOT.gDirectory.Get('sigstrength')

        hsigpull.Fit("gaus","L")
        hsigpull.SetTitle('')
        hsigpull.GetXaxis().SetTitle('(r-%s)/rErr'%injectedAmount)
        result_can.cd()
        hsigpull.Draw('pe')
        result_can.Print('signalInjection_r%s_pull.png'%(str(injectedAmount).replace('.','p')),'png')

        hsignstrength.Fit("gaus","L")
        hsignstrength.SetTitle('')
        hsignstrength.GetXaxis().SetTitle('r-%s'%injectedAmount)
        result_can.cd()
        hsignstrength.Draw('pe')
        result_can.Print('signalInjection_r%s.png'%(str(injectedAmount).replace('.','p')),'png')

        execute_cmd('rm -r '+tmpdir)
Exemple #8
0
def plot_gof(tag, subtag, seed=123456, condor=False):
    with cd(tag+'/'+subtag):
        if condor:
            tmpdir = 'notneeded/tmp/'
            execute_cmd('mkdir '+tmpdir) 
            execute_cmd('cat %s_%s_gof_toys_output_*.tgz | tar zxvf - -i --strip-components 2 -C %s'%(tag,subtag,tmpdir))
            toy_limit_tree = ROOT.TChain('limit')
            if len(glob.glob(tmpdir+'higgsCombine_gof_toys.GoodnessOfFit.mH120.*.root')) == 0:
                raise Exception('No files found')
            toy_limit_tree.Add(tmpdir+'higgsCombine_gof_toys.GoodnessOfFit.mH120.*.root') 
            
        else:
            toyOutput = ROOT.TFile.Open('higgsCombine_gof_toys.GoodnessOfFit.mH120.{seed}.root'.format(seed=seed))
            toy_limit_tree = toyOutput.Get('limit')

        # Now to analyze the output
        # Get observation
        ROOT.gROOT.SetBatch(True)
        ROOT.gStyle.SetOptStat(False)
        gof_data_file = ROOT.TFile.Open('higgsCombine_gof_data.GoodnessOfFit.mH120.root')
        gof_limit_tree = gof_data_file.Get('limit')
        gof_limit_tree.GetEntry(0)
        gof_data = gof_limit_tree.limit

        # Get toys
        toy_limit_tree.Draw('limit>>hlimit','limit>1.0 && limit<%s && limit != %s'%(gof_data*2.0,gof_data)) 
        htoy_gof = ROOT.gDirectory.Get('hlimit')
        time.sleep(1) # if you don't sleep the code moves too fast and won't perform the fit
        htoy_gof.Fit("gaus")

        # Fit toys and derive p-value
        gaus = htoy_gof.GetFunction("gaus")
        pvalue = 1-(1/gaus.Integral(-float("inf"),float("inf")))*gaus.Integral(-float("inf"),gof_data)

        # Write out for reference
        with open('gof_results.txt','w') as out:
            out.write('Test statistic in data = '+str(gof_data))
            out.write('Mean from toys = '+str(gaus.GetParameter(1)))
            out.write('Width from toys = '+str(gaus.GetParameter(2)))
            out.write('p-value = '+str(pvalue))

        # Extend the axis if needed
        if htoy_gof.GetXaxis().GetXmax() < gof_data:
            print ('Axis limit greater than GOF p value')
            binwidth = htoy_gof.GetXaxis().GetBinWidth(1)
            xmin = htoy_gof.GetXaxis().GetXmin()
            new_xmax = int(gof_data*1.1)
            new_nbins = int((new_xmax-xmin)/binwidth)
            toy_limit_tree.Draw('limit>>hlimitrebin('+str(new_nbins)+', '+str(xmin)+', '+str(new_xmax)+')','limit>0.001 && limit<1500') 
            htoy_gof = ROOT.gDirectory.Get('hlimitrebin')
            htoy_gof.Fit("gaus")
            gaus = htoy_gof.GetFunction("gaus")

        # Arrow for observed
        arrow = ROOT.TArrow(gof_data,0.25*htoy_gof.GetMaximum(),gof_data,0)
        arrow.SetLineWidth(2)

        # Legend
        leg = ROOT.TLegend(0.1,0.7,0.4,0.9)
        leg.SetLineColor(ROOT.kWhite)
        leg.SetLineWidth(0)
        leg.SetFillStyle(0)
        leg.SetTextFont(42)
        leg.AddEntry(htoy_gof,"toy data","lep")
        leg.AddEntry(arrow,"observed = %.1f"%gof_data,"l")
        leg.AddEntry(0,"p-value = %.2f"%(pvalue),"")

        # Draw
        cout = ROOT.TCanvas('cout','cout',800,700)
        htoy_gof.SetTitle('')
        htoy_gof.Draw('pez')
        arrow.Draw()
        leg.Draw()

        cout.Print('gof_plot.pdf','pdf')
        cout.Print('gof_plot.png','png')
        execute_cmd('rm -r '+tmpdir)
    def Impacts(self,
                subtag,
                rMin=-15,
                rMax=15,
                cardOrW='initialFitWorkspace.root --snapshotName initialFit',
                extra=''):
        # param_str = '' if setParams == {} else '--setParameters '+','.join(['%s=%s'%(p,v) for p,v in setParams.items()])
        with cd(self.tag + '/' + subtag):
            subset = LoadLedger('')
            impact_nuis_str = '--named=' + ','.join(subset.GetAllSystematics())
            if cardOrW.endswith('.txt'):
                execute_cmd(
                    'text2workspace.py -b %s -o prefitWorkspace.root --channel-masks --X-no-jmax'
                    % cardOrW)
                card_or_w = 'prefitWorkspace.root'
            else:
                card_or_w = cardOrW

            base_opts = [
                '-M Impacts',
                '--rMin %s' % rMin,
                '--rMax %s' % rMax,
                '-d %s' % card_or_w,
                '--cminDefaultMinimizerStrategy 0 -m 0',
                impact_nuis_str,
                extra  #param_str,
                # '-t -1 --bypassFrequentistFit' if blindData else ''
            ]
            # Remove old runs if they exist
            execute_cmd('rm *_paramFit_*.root *_initialFit_*.root')
            # Step 1
            execute_cmd('combineTool.py %s --doInitialFit' %
                        (' '.join(base_opts)))
            # Dumb hack - combineTool --doFits will go looking for the wrong file if you run on a toy
            _combineTool_impacts_fix(
                'higgsCombine_initialFit_Test.MultiDimFit.mH0.root')

            # Step 2
            execute_cmd('combineTool.py %s --doFits' % (' '.join(base_opts)))
            # Dumb hack - combineTool next step will go looking for the wrong file if you run on a toy
            _combineTool_impacts_fix(
                'higgsCombine_paramFit_Test_*.MultiDimFit.mH0.root')

            # Grab the output
            execute_cmd('combineTool.py %s -o impacts.json' %
                        (' '.join(base_opts)))
            execute_cmd('plotImpacts.py -i impacts.json -o impacts')
    def SignalInjection(self,
                        subtag,
                        injectAmount,
                        ntoys,
                        blindData=True,
                        card_or_w='card.txt',
                        rMin=-5,
                        rMax=5,
                        seed=123456,
                        verbosity=0,
                        setParams={},
                        extra='',
                        condor=False,
                        eosRootfiles=None,
                        njobs=0):
        run_dir = self.tag + '/' + subtag
        _runDirSetup(run_dir)

        rinj = str(injectAmount).replace('.', 'p')
        param_str = '' if setParams == {} else '--setParameters ' + ','.join(
            ['%s=%s' % (p, v) for p, v in setParams.items()])

        with cd(run_dir):
            fit_cmd = [
                'combine -M FitDiagnostics', '-d ' + card_or_w,
                '--skipBOnlyFit', '--cminDefaultMinimizerStrategy 0',
                '-t {ntoys}', '--toysFrequentist',
                '--bypassFrequentistFit' if blindData else '', param_str,
                '-s {seed}',
                '--rMin %s' % rMin,
                '--rMax %s' % rMax,
                '-n _sigInj_r%s_{seed}' % rinj,
                '-v %s' % verbosity, extra
            ]

            fit_cmd = ' '.join(fit_cmd)

            if not condor:
                fit_cmd = fit_cmd.format(seed=seed, ntoys=ntoys)
                execute_cmd(fit_cmd)

            else:
                per_job_toys = int(round(ntoys / njobs))

                print(
                    'Running toys on condor... first cleaning potential duplicates...'
                )
                execute_cmd(
                    'rm fitDiagnostics_sigInj_r{rinj}_{seed}.root'.format(
                        rinj=rinj, seed=seed))

                fit_cmds = [
                    fit_cmd.format(ntoys=per_job_toys,
                                   seed=random.randint(0, 1000000))
                    for _ in range(njobs)
                ]

                condor = CondorRunner(
                    name=self.tag + '_' + subtag + '_sigInj_r' + rinj,
                    primaryCmds=fit_cmds,
                    toPkg=self.tag + '/',
                    runIn=run_dir,
                    toGrab='{run_dir}/fitDiagnostics_sigInj_r{rinj}*.root'.
                    format(run_dir=run_dir, rinj=rinj),
                    eosRootfileTarball=eosRootfiles,
                    remakeEnv=False)
                condor.submit()
    def GoodnessOfFit(self,
                      subtag,
                      ntoys,
                      card_or_w='card.txt',
                      freezeSignal=False,
                      seed=123456,
                      verbosity=0,
                      extra='',
                      condor=False,
                      eosRootfiles=None,
                      njobs=0):
        # NOTE: There's no way to blind data here - need to evaluate it to get the p-value
        # param_str = '' if setParams == {} else '--setParameters '+','.join(['%s=%s'%(p,v) for p,v in setParams.items()])

        run_dir = self.tag + '/' + subtag
        _runDirSetup(run_dir)

        with cd(run_dir):
            gof_data_cmd = [
                'combine -M GoodnessOfFit', '-d ' + card_or_w,
                '--algo=saturated',
                '' if not freezeSignal else '--fixedSignalStrength %s' %
                freezeSignal, '-n _gof_data',
                '-v %s' % verbosity, extra
            ]

            gof_toy_cmd = copy.deepcopy(gof_data_cmd)
            gof_toy_cmd.extend(
                ['--toysFrequentist', '-t {ntoys}', '-s {seed}'])

            gof_data_cmd = ' '.join(gof_data_cmd)
            gof_toy_cmd = ' '.join(gof_toy_cmd).replace(
                '-n _gof_data', '-n _gof_toys')

            execute_cmd(gof_data_cmd)

            if not condor:
                gof_toy_cmd = gof_toy_cmd.format(seed=seed, ntoys=ntoys)
                execute_cmd(gof_toy_cmd)

            else:
                per_job_toys = int(round(ntoys / njobs))

                print(
                    'Running toys on condor... first cleaning potential duplicates...'
                )
                execute_cmd(
                    'rm higgsCombine_gof_toys.GoodnessOfFit.mH120.*.root')

                gof_toy_cmds = [
                    gof_toy_cmd.format(ntoys=per_job_toys,
                                       seed=random.randint(0, 1000000))
                    for _ in range(njobs)
                ]

                condor = CondorRunner(
                    name=self.tag + '_' + subtag + '_gof_toys',
                    primaryCmds=gof_toy_cmds,
                    toPkg=self.tag + '/',
                    runIn=run_dir,
                    toGrab=run_dir +
                    '/higgsCombine_gof_toys.GoodnessOfFit.mH120.*.root',
                    eosRootfileTarball=eosRootfiles,
                    remakeEnv=False)
                condor.submit()
    def GenerateToys(self,
                     name,
                     subtag,
                     card=None,
                     workspace=None,
                     ntoys=1,
                     seed=123456,
                     expectSignal=0,
                     setParams={},
                     freezeParams=[]):
        if card == None and workspace == None:
            raise IOError(
                'Either card or workspace must be provided relative to the directory where the generation will be run.'
            )
        elif card != None and workspace != None:
            raise IOError('Only one of card or workspace can be provided.')

        if card:
            if isinstance(card, str):
                card_name = card
            elif isinstance(card, bool) and card == True:
                card_name = 'card.txt'
            workspace_file = '%s_gen_workspace.root' % (name)
            execute_cmd(
                'text2workspace.py -b {0}/{1} -o {0}/{2} --channel-masks --X-no-jmax'
                .format(self.tag + '/' + subtag, card_name, workspace_file))

            input_opt = '-d %s' % workspace_file

        elif workspace:
            if isinstance(workspace, str):
                workspace_file = workspace.split(':')
                input_opt = '-d %s --snapshotName %s' % (workspace.split(':'))
            elif isinstance(workspace, bool) and workspace == True:
                workspace_file = 'initialFitWorkspace.root'
                input_opt = '-d %s --snapshotName initialFit' % workspace_file

        run_dir = self.tag + '/' + subtag
        masks_off = [
            '%s=0' % mask
            for mask in self._getMasks(run_dir + '/' + workspace_file)
        ]

        with cd(run_dir):
            param_vals = ['%s=%s' % (k, v) for k, v in setParams.items()]
            param_vals.extend(masks_off)
            param_opt = ''
            if len(param_vals) > 0:
                param_opt = '--setParameters ' + ','.join(param_vals)

            freeze_opt = ''
            if len(freezeParams) > 0:
                freeze_opt = '--freezeParameters ' + ','.join(freezeParams)

            gen_command_pieces = [
                'combine -M GenerateOnly', input_opt, param_opt,
                '--toysFrequentist --bypassFrequentistFit',
                '-t %s' % ntoys,
                '--saveToys -s %s' % seed,
                '--expectSignal %s' % expectSignal,
                '-n _%s' % name, freeze_opt
            ]

            execute_cmd(' '.join(gen_command_pieces))

        toyfile_path = '%s/higgsCombine_%s.GenerateOnly.mH120.%s.root' % (
            self.tag + '/' + subtag + '/', name, seed)

        return toyfile_path