def plcLimit(obs_, poi_, model, ws, data, CL=0.95, verbose=False): # obs : observable variable or RooArgSet of observables # poi : parameter of interest or RooArgSet of parameters # model : RooAbsPdf of model to consider including any constraints # data : RooAbsData of the data # CL : confidence level for interval # returns a dictionary with the upper and lower limits for the first/only # parameter in poi_ as well as the interval object and status flag obs = RooArgSet(obs_) obs.setName('observables') poi = RooArgSet(poi_) poi.setName('poi') poi.setAttribAll('Constant', False) nuis = model.getParameters(obs) nuis.remove(poi) nuis.remove(nuis.selectByAttrib('Constant', True)) nuis.setName('nuisance') if verbose: print 'observables' obs.Print('v') print 'parameters of interest' poi.Print('v') print 'nuisance parameters' nuis.Print('v') mc = RooStats.ModelConfig('mc') mc.SetWorkspace(ws) mc.SetPdf(model) mc.SetObservables(obs) mc.SetParametersOfInterest(poi) mc.SetNuisanceParameters(nuis) plc = RooStats.ProfileLikelihoodCalculator(data, mc) plc.SetConfidenceLevel(CL) interval = plc.GetInterval() upperLimit = Double(999.) lowerLimit = Double(0.) Limits = {} paramIter = poi.createIterator() param = paramIter.Next() while param: ok = interval.FindLimits(param, lowerLimit, upperLimit) Limits[param.GetName()] = { 'ok': ok, 'upper': float(upperLimit), 'lower': float(lowerLimit) } param = paramIter.Next() if verbose: print '%.0f%% CL limits' % (interval.ConfidenceLevel() * 100) print Limits Limits['interval'] = interval return Limits
def GetPLRInterval(filename="workspace.root", wsname='myWS', interactive=False): # this function loads a workspace and computes # a Bayesian upper limit pInFile = ROOT.TFile(filename, "read") # load workspace pWs = pInFile.Get(wsname) if not pWs: print "workspace ", wsname, " not found" return -1 # printout workspace content pWs.Print() # load and print data from workspace data = pWs.data("data") data.Print() # load and print S+B Model Config pSbHypo = pWs.obj("SbHypo") pSbHypo.Print() # create RooStats Profiled Likelihood ratio calculator and set parameters bCalc = RooStats.ProfileLikelihoodCalculator(data, pSbHypo) bCalc.SetConfidenceLevel(0.95) # estimate credible interval # NOTE: unfortunate notation: the UpperLimit() name refers # to the upper boundary of an interval, # NOT to the upper limit on the parameter of interest # (it just happens to be the same for the one-sided # interval starting at 0) pSInt = bCalc.GetInterval() upper_bound = pSInt.UpperLimit(pWs.var('xsec')) lower_bound = pSInt.LowerLimit(pWs.var('xsec')) print "one-sided 95%.C.L. interval for xsec: ", "[", lower_bound, ", ", upper_bound, "]" # make posterior PDF plot for POI c1 = ROOT.TCanvas("plr", "likelihood furnction") pPlot = RooStats.LikelihoodIntervalPlot(pSInt) pPlot.SetRange(0., 0.006) pPlot.SetMaximum(5.) pPlot.SetNPoints(50) pPlot.Draw() ROOT.gPad.Update() c1.SaveAs("plr_plot.pdf") if interactive: raw_input("\npress <enter> to continue")
def plotProfiles(): f = TFile("./data/fitWorkspace.root") fitWorkspace = f.Get("fitWorkspace") fData = fitWorkspace.allData().front() fEnergy = fitWorkspace.var("energy_keV") model = fitWorkspace.pdf("model") fitResult = fitWorkspace.allGenericObjects().front() fitValsFinal = getRooArgDict(fitResult.floatParsFinal()) print "Fit Cov Qual:", fitResult.covQual() nameList = ["amp-axion"] # nameList = [] # for key in sorted(fitValsFinal): # if "amp-" in key: # nameList.append(key) print "Generating profiles ..." c = TCanvas("c", "c", 800, 600) for name in nameList: fitVal = fitValsFinal[name] thisVar = fitWorkspace.var(name) # Brian & Clint method plc = RS.ProfileLikelihoodCalculator(fData, model, ROOT.RooArgSet(thisVar)) plc.SetConfidenceLevel(0.90) interval = plc.GetInterval() lower = interval.LowerLimit(thisVar) upper = interval.UpperLimit(thisVar) print "%-10s = lo %-7.3f best %-7.3f hi %.3f" % (name, lower, fitVal, upper) plot = RS.LikelihoodIntervalPlot(interval) # p1, pltHi = fitVal - 1.5*(fitVal - lower), fitVal + 1.5*(upper - fitVal) # plot.SetRange(pltLo,pltHi) plot.SetTitle("%s: lo %.3f fit %.3f hi %.3f" % (name, lower, fitVal, upper)) plot.SetNPoints(50) plot.Draw("tf1") """ # Lukas method # note: lukas uses ModelConfig, to explicitly set observables, constraints, and nuisance parameters # https://root-forum.cern.ch/t/access-toy-datasets-generated-by-roostat-frequentistcalculator/24465/8 mc = RS.ModelConfig('mc', fitWorkspace) mc.SetPdf( model ) mc.SetParametersOfInterest( ROOT.RooArgSet(thisVar) ) mc.SetObservables( ROOT.RooArgSet(fEnergy) ) # lukas example # mc.SetConstraintParameters( ROOT.RooArgSet(mean, sigma) ) # mc.SetNuisanceParameters( ROOT.RooArgSet(mean, sigma, n_bkg) ) # mc.SetGlobalObservables( ROOT.RooArgSet(mean_obs, sigma_obs) ) # need to make some RooArgSets from RooRealVars # constraints, nuisances, globalobs = ROOT.RooArgSet(), ROOT.RooArgSet(), ROOT.RooArgSet() # for parName in sorted(fitValsFinal): # rrv = fitWorkspace.var(parName) # if parName != name: # constraints.add(rrv) # # .. etc. # pl = RS.ProfileLikelihoodCalculator(fData, mc) # pl.SetConfidenceLevel(0.683) # lukas used 0.90 # interval = pl.GetInterval() # plot = RS.LikelihoodIntervalPlot(interval) # plot.SetNPoints(50) # plot.Draw("") """ c.Print("./plots/profile_%s.pdf" % name)
def getProfile(idx=None, update=False): from ROOT import TFile, TCanvas from ROOT import RooStats as RS f = TFile("%s/data/fitWorkspace.root" % dsi.latSWDir) fitWorkspace = f.Get("fitWorkspace") fData = fitWorkspace.allData().front() hitE = fitWorkspace.var("trapENFCal") model = fitWorkspace.pdf("model") fitResult = fitWorkspace.allGenericObjects().front() fPars = fitResult.floatParsFinal() nPars = fPars.getSize() # === get fit results: {name : [nCts, err]} === fitVals = {} for i in range(nPars): fp = fitResult.floatParsFinal() name = fp.at(i).GetName() fitVal, fitErr = fp.at(i).getValV(), fp.at(i).getError() if "amp" in name: # fitVals[name.split('-')[1]] = [fitVal, fitErr] fitVals[name] = [fitVal, fitErr, name.split('-')[1]] # for f in fitVals: # print(f, fitVals[f]) # === get "true" counts (reverse efficiency correction based on fit value) === hAx = getHistList("axion") x, y, xpb = wl.npTH1D(hAx) x, y = normPDF(x, y, eLo, eHi) nCts, nErr, _ = fitVals["amp-axion"] # fit result yc = nCts * getEffCorr(x, y, inv=True) nCorr = np.sum(yc) effCorr = nCorr / nCts print("nCts %d nCorr %.2f effCorr %.2f" % (nCts, nCorr, effCorr)) # thesis plot, don't delete # plt.step(x, y * nCts * (epb/xpb), c='r', lw=2, label="Eff-weighted: %.1f" % (nCts)) # plt.step(x, yc * (epb/xpb), c='b', lw=2, label="True counts: %.1f" % (nCorr)) # plt.xlabel("Energy (keV)", ha='right', x=1) # plt.ylabel("Counts / keV", ha='right', y=1) # plt.legend(loc=1) # plt.tight_layout() # plt.show() tMode = "UPDATE" if update else "RECREATE" tOut = TFile("%s/data/rs-plc.root" % dsi.latSWDir, "UPDATE") start = time.clock() name = "amp-axion" fitVal = fitVals[name][0] thisVar = fitWorkspace.var(name) pCL = 0.9 plc = RS.ProfileLikelihoodCalculator(fData, model, ROOT.RooArgSet(thisVar)) plc.SetConfidenceLevel(0.90) interval = plc.GetInterval() lower = interval.LowerLimit(thisVar) upper = interval.UpperLimit(thisVar) plot = RS.LikelihoodIntervalPlot(interval) plot.SetNPoints(50) plot.Draw("tf1") pName = "hP_%d" if idx is not None else "hP" hProfile = plot.GetPlottedObject() hProfile.SetName(pName) hProfile.SetTitle("PL %.2f %s lo %.3f mid %.3f hi %.3f eC %.3f" % (pCL, name, lower, fitVal, upper, effCorr)) hProfile.Write() print(hProfile.GetTitle()) tOut.Close() print("elapsed:", time.clock() - start)
def configure(self, ws, items, section, debug = 0): print self.legend, 'configuring Profile Likelihood calculator...' _items = items[section] # check mandatory parameters # dataset name in the workspace _dataset_name = self.check_value(items, section, 'data') if _dataset_name == None: print self.legend, 'ERROR: dataset is not specified, cannot configure' return else: if ws.data(_dataset_name) != None: _data = ws.data(_dataset_name) else: print legend, 'Error: dataset', _dataset_name, 'is not defined, cannot configure' return # model config name in the workspace self._model_config_name = self.check_value(items, section, 'model_config') if self._model_config_name == None: print self.legend, 'ERROR: Model Config name is not specified, cannot configure' return else: if self.check_generic_object(ws, self._model_config_name, debug): _mconf = ws.obj(self._model_config_name.strip()) else: print self.legend, 'Error: model config object is not found, cannot configure' return # check optional parameters, set defaults if not specified # desired confidence level _conf_level = self.check_value(items, section, 'confidence_level') if _conf_level == None: print self.legend, 'no confidence level specified, setting to 0.95' _conf_level = 0.95 # whether to make the posterior plot or not self._scan_plot = self.check_value(items, section, 'make_scan_plot') if self._scan_plot == None: print self.legend, 'likelihood intervalscan plot is not requested' self._scan_plot = False elif self._scan_plot == 'True': self._scan_plot = True else: print self.legend, 'invalid assignment make_scan_plot =', self._scan_plot print self.legend, 'likelihood interval scan plot will not be made' self._scan_plot = False # plot format if self._scan_plot: self._plot_format = self.check_value(items, section, 'plot_format') if self._plot_format == None: print self.legend, 'no plot format specified, setting to PNG' self._plot_format = png # configuring now... self._plc = RooStats.ProfileLikelihoodCalculator(_data,_mconf) self._plc.SetConfidenceLevel( float(_conf_level) ) print legend, 'Profile Likelihood calculator is configured' # import the calculator into the Workspace #getattr(ws, 'import')(self._plc, 'exostMcmcCalc') #print legend, 'Markov chain MC calculator', 'exostMcmcCalc', 'is added to workspace', ws.GetName() #print legend, 'done' ws.Print() # flag that the action is configured successfully self.configured = True return {'do_scan_plot':self._scan_plot}
#bInt = bc.GetInterval() # make plots #c1 = TCanvas("c1") #bplot = bc.GetPosteriorPlot() #bplot . Draw() #c1 . SaveAs("posterior_pdf.png") # query interval #print "Bayesian interval on s = [", #print bInt.LowerLimit( ), ",", #print bInt.UpperLimit( ), "]" # Profile Likelihood Calculator plc = RooStats.ProfileLikelihoodCalculator(data, modelConfig) # run Profile Likelihood Calculator plc.SetConfidenceLevel(0.95) plInt = plc.GetInterval(); # make plots c1 = TCanvas("c1") lrplot = RooStats.LikelihoodIntervalPlot(plInt) lrplot.Draw() c1 . SaveAs("likelihood_interval.png") # query interval plc_lower = plInt.LowerLimit( wspace.var("s") ) plc_upper = plInt.UpperLimit( wspace.var("s") ) print "Profile Likelihood interval on s = [",
def main(): # ROOT settings ROOT.Math.MinimizerOptions.SetDefaultMinimizer('Minuit') # Workspace w = ROOT.RooWorkspace('w') # Observable E = w.factory('E[0.,100.]') # Constrained parameters and constraint PDF mean = w.factory('mean[50.,49.,51.]') mean_obs = w.factory('mean_obs[50.,49.,51.]') mean_obs.setConstant(True) mean_err = w.factory('mean_err[0.2]') cpdf_mean = w.factory('Gaussian::cpdf_mean(mean,mean_obs,mean_err)') print type(mean), type(mean_obs), type(mean_err), type(cpdf_mean) return sigma = w.factory('sigma[1.,0.5,1.5]') sigma_obs = w.factory('sigma_obs[1.,0.5,1.5]') sigma_obs.setConstant(True) sigma_err = w.factory('sigma_err[0.1]') cpdf_sigma = w.factory('Gaussian::cpdf_sigma(sigma,sigma_obs,sigma_err)') # Signal n_sig = w.factory('n_sig[0.,0.,10.]') pdf_sig = w.factory('Gaussian::pdf_sig(E,mean,sigma)') # Background n_bkg = w.factory('n_bkg[10.,0.,50.]') pdf_bkg = w.factory('Polynomial::pdf_bkg(E,{})') # PDF pdf_sum = w.factory('SUM::pdf_sum(n_sig*pdf_sig,n_bkg*pdf_bkg)') pdf_const = w.factory('PROD::pdf_const({pdf_sum,cpdf_mean,cpdf_sigma})') # ModelConfig mc = RS.ModelConfig('mc', w) mc.SetPdf(pdf_const) mc.SetParametersOfInterest(ROOT.RooArgSet(n_sig)) mc.SetObservables(ROOT.RooArgSet(E)) mc.SetConstraintParameters(ROOT.RooArgSet(mean, sigma)) mc.SetNuisanceParameters(ROOT.RooArgSet(mean, sigma, n_bkg)) mc.SetGlobalObservables(ROOT.RooArgSet(mean_obs, sigma_obs)) # Create empty dataset data = ROOT.RooDataSet('data', 'data', ROOT.RooArgSet(E)) # Profile Likelihood pl = RS.ProfileLikelihoodCalculator(data, mc) pl.SetConfidenceLevel(0.90) interval = pl.GetInterval() print(interval.LowerLimit(n_sig), interval.UpperLimit(n_sig)) plot = RS.LikelihoodIntervalPlot(interval) plot.SetNPoints(50) c = ROOT.TCanvas("c", "c", 800, 1100) plot.Draw("") c.Print("plotLukasPLC.pdf")