Negative parameter of interest in AsymptoticCalculator

Dear Experts,

I would like to set one-sided limits on a parameter of interest called lambda. The twist is that unlike signal strength mu, lower lambda means a stronger signal, high lambda means weaker signal. What I have so far is:

calc = AsymptoticCalculator(data, bkg_modelConfig, sPlusB_modelConfig); # switched order for limits
calc.SetOneSidedDiscovery(True)

I do SetOneSidedDiscovery() instead of SetOneSided() because I want the p-value calculated from the low tail, not the high tail. Is this the correct way to do it, or is there a more straight forward way?

Thanks for any insight on this.

I would have to check the code, but if I had to bet, I would bet that this doesn’t work. What makes me bet this way is that for “discovery”, you test against lambda = 0, for “limit” you test against specific values of lambda.

There is a simple thing that could make everything much easier: RooLinearVar
Transform the lambda, which the likelihood model sees, to absLambda = -lambda, and run the limits on the high tail as usual. Like this, I’m sure that the asymptotic formulae work, and central values and errors will be correct.

Hi @StephanH,

Thanks very much for the reply. I tried providing a RooLinearVar as the poi for the modelConfig, but the AsymptoticCalculator complains:

[#0] ERROR:InputArguments -- AsymptoticCalculator::Initialize -  ModelConfig has not POI defined.

I’m setting the POI with h0_model.SetParametersOfInterest(RooArgSet(w.obj("lambdaInv"))) since w.var("lambdaInv") returns a null. Is there another way to set the POI?

Thanks

That could mean that the export/import didn’t work or that the two weren’t connected to the model in the proper way. I would do it like this (please excuse that it’s only pseudo-code, I’m typing from memory):

lambda = ROOT.RooRealVar("lambda", "lambda, the negative model parameter", -1, -10, 0)
absLambda = ROOT.RooLinearVar("absLambda", "positive lambda", lambda, ROOT.RooConst(-1), ROOT.RooConst(0.))
model = ROOT.WhateverModel("...", "...", (PDFs), (lambda, ...))
getattr(ws, 'import')(absLambda)
getattr(ws, 'import')(model)
modelConfig.SetPdf(model)
modelConfig.SetParametersOfInterest(absLambda)

Actually I think the problem w.var() only works with RooRealVar, so I used w.obj() instead.

w.obj() returns the RooLinearVar, and I do something similar to what you have:

    h0_model = ModelConfig("h0",w)
    h0_model.SetPdf(w.pdf("model"))
    h0_model.SetObservables(RooArgSet(x))
    w.obj("lambdaInv").setVal(0)
    h0_model.SetParametersOfInterest(RooArgSet(w.obj("lambdaInv")))

But on the last line, I get the complaint about the POI:

ModelConfig::SetParametersOfInterest ERROR: specified set contains non-parameters: (lambdaInv)

lambdaInv is in the workspace, and I can print it without any problem.

Oh, that’s because the ModelConfig can only accept parameters, not functions. The fitter wouldn’t know how to change the value of a function.

My suggestion should have been the inverse:

absLambda = RooRealVar (a true parameter, positive)
lambda = RooLinearVar (a function, the negative of absLambda)

The parameter goes into the ModelConfig, the function goes into the fit model.

Hi @StephanH, this seems to work! Thanks for the help.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.