Get name of RooRealVar from pdf fit

Hi all!
I’m not able to retrieve the name of RooRealVars from a pdf fit, obtained as:

result = pdf_model.fitTo(pseudo_data, RF.Save(R.kTRUE))

The closest thing I found is printing str(result.floatParsFinal().at(1)), obtaining 'RooRealVar::n_Bp2pipipi_D0b = 1.47685e+06 +/- 1344.09 L(0 - 1e+10) \n', so what I’m doing now is:

for idx in range(len(all_decays)):
        yield_X = result.floatParsFinal().at(idx).getValV()
        erryield_X = result.floatParsFinal().at(idx).getError()
        name_X=name_X.replace("RooRealVar::n_"," ")
        name_X=name_X.replace("L(0 - 1e+10)", " ")
        print(f"The fitted yield of {name_X}  => sigmaN/N = {100*erryield_X/yield_X:.1f}%\n")

for i in range(len(all_decays)):
    print(f"The initial yields of {all_decays[i]} = {yields[i]}\n")

with this output:

The fitted yield of  Bcp2taup2pipipi = 2467.6 +/- 78.9564    
  => sigmaN/N = 3.2%

The fitted yield of  Bp2pipipi_D0b = 1.47685e+06 +/- 1344.09    
  => sigmaN/N = 0.1%

The fitted yield of  Bp2taup2pipipi = 40408.8 +/- 881.765    
  => sigmaN/N = 2.2%

The fitted yield of  Dp2taup2pipipi = 1.35906e+06 +/- 2285.85    
  => sigmaN/N = 0.2%

The fitted yield of  Dsp2taup2pipipi = 2.35918e+06 +/- 2634.05    
  => sigmaN/N = 0.1%

The initial yields of Bcp2taup2pipipi = 2461 

The initial yields of Bp2taup2pipipi = 38668 

The initial yields of Dp2taup2pipipi = 1355818 

The initial yields of Dsp2taup2pipipi = 2362444 

The initial yields of Bp2pipipi_D0b = 1478159 

I would like to reduce it to just one for loop, but as you can see for some reason the order of the yields are different in the fit result. So I need either the order to be the same or at least to be able to retrieve the name of the RooRealVar.
Is there a function for result that can give me the name of the variable? I haven’t found it here ROOT: RooRealVar Class Reference

I hope my problem is clear!


Hi @mdgalati,

I think the methods that continue to help here are RooRealVar::GetName() such that you can get the name directly as result.floatParsFinal().at(idx).GetName() instead of doing the string stuff.

To reduce things to one loop, I would use RooAbsCollection::find() to get the right yield parameter from floatParsFinal(). I think the full code would look like this then:

for i in range(len(all_decays)):
    real_var = result.floatParsFinal().find("n_" + all_decays[i])
    fitted_yield = 100*real_var.getError()/real_var.getVal()
    print(f"The fitted yield of {all_decays[i]}  => sigmaN/N = {fitted_yield:.1f}%\n")
    print(f"The initial yields of {all_decays[i]} = {yields[i]}\n")

Hope this helps!


1 Like

I forgot to mention: you should use getVal() and not getValV() to get the value of a variable.

Thanks @jonas! I had tried with result.floatParsFinal().at(0).getName() and now I see why it wasn’t working, the G was supposed to be capital :sweat_smile:
The find() function was really useful, thanks a lot for your help!

What’s the difference between these two?

The RooAbsReal::getVal() function is the one that the user is actually supposed to call. It wraps around the virtual getValV() function, which is overridden in the different RooFit classes. It’s like this such that there can be some optimizations and checks done independently of how getValV() is overridden in the child classes.

1 Like

cool, thanks!