I have a data-histogram that I am fitting with a pdf. How can I take the ratio of data-histogram with pdf in each bin? If I convert the pdf into a TF1 then it would be easy to do it, but how can I convert my roofit-pdf into a TF1?
check out RooAbsReal::asTF1, which creates a TF1 that goes back to the original RooFit object when you ask it for its values.
Make sure that you get observables and parameters right. Otherwise, the TF1 will not do the right thing. (I.e. if you plot the pdf versus x, x is the observable. The rest are parameters.)
It works well and prints the parameter of new TF1, but when I draw it.
RxFunc->Draw();
It breaks with seg fault.
*** Break *** segmentation violation
There was a crash.
This is the entire stack trace of all threads:
#0 0x00007fa49da37b3c in __libc_waitpid (pid=40902, stat_loc=stat_loc
entry=0x7ffc4dcfdd20, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:31
#1 0x00007fa49d9bf12b in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:148
#2 0x00007fa49f707e44 in Exec (shellcmd=<optimized out>, this=<optimized out>) at /home/uhlig/root/source/root/core/unix/src/TUnixSystem.cxx:2156
#3 TUnixSystem::StackTrace (this=0x1795e20) at /home/uhlig/root/source/root/core/unix/src/TUnixSystem.cxx:2403
#4 0x00007fa49f709efc in TUnixSystem::DispatchSignals (this=0x1795e20, sig=kSigSegmentationViolation) at /home/uhlig/root/source/root/core/unix/src/TUnixSystem.cxx:1279
#5 <signal handler called>
#6 0x00007fa499443913 in RooRealBinding::loadValues (this=this
entry=0x3f646d0, xvector=0x3f647a0) at /home/uhlig/root/source/root/roofit/roofitcore/src/RooRealBinding.cxx:187
#7 0x00007fa499443933 in RooRealBinding::operator() (this=0x3f646d0, xvector=<optimized out>) at /home/uhlig/root/source/root/roofit/roofitcore/src/RooRealBinding.cxx:201
#8 0x00007fa49bffa032 in operator() (this=0x3f105a0, p=0x0, x=0x0) at /home/uhlig/root/source/root/math/mathcore/inc/Math/ParamFunctor.h:292
#9 TF1::EvalPar (this=<optimized out>, x=<optimized out>, params=<optimized out>) at /home/uhlig/root/source/root/hist/hist/src/TF1.cxx:1546
#10 0x00007fa49c003265 in TF1::Paint (this=0x3f647f0, option=0x3f655f9 "") at /home/uhlig/root/source/root/hist/hist/src/TF1.cxx:2863
#11 0x00007fa497c490d9 in TPad::PaintModified (this=0x3f65e90) at /home/uhlig/root/source/root/graf2d/gpad/src/TPad.cxx:3124
#12 0x00007fa497c1afdc in TCanvas::Update (this=0x3f10370) at /home/uhlig/root/source/root/graf2d/gpad/src/TCanvas.cxx:2127
#13 0x00007fa49f6cfb61 in TCint::UpdateAllCanvases () at /home/uhlig/root/source/root/core/meta/src/TCint.cxx:2210
#14 0x00007fa49f6cfc61 in TCint::ProcessLine (this=0x1799b20, line=0x7fa49f9f65b3 "TRint::EndOfLineAction();", error=0x0) at /home/uhlig/root/source/root/core/meta/src/TCint.cxx:539
#15 0x00007fa49e562b97 in TRint::Run (this=0x1917c40, retrn=<optimized out>) at /home/uhlig/root/source/root/core/rint/src/TRint.cxx:419
#16 0x0000000000401000 in main (argc=1, argv=0x7ffc4dd02868) at /home/uhlig/root/source/root/main/src/rmain.cxx:29
>The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
#6 0x00007fa499443913 in RooRealBinding::loadValues (this=this
entry=0x3f646d0, xvector=0x3f647a0) at /home/uhlig/root/source/root/roofit/roofitcore/src/RooRealBinding.cxx:187
#7 0x00007fa499443933 in RooRealBinding::operator() (this=0x3f646d0, xvector=<optimized out>) at /home/uhlig/root/source/root/roofit/roofitcore/src/RooRealBinding.cxx:201
#8 0x00007fa49bffa032 in operator() (this=0x3f105a0, p=0x0, x=0x0) at /home/uhlig/root/source/root/math/mathcore/inc/Math/ParamFunctor.h:292
#9 TF1::EvalPar (this=<optimized out>, x=<optimized out>, params=<optimized out>) at /home/uhlig/root/source/root/hist/hist/src/TF1.cxx:1546
#10 0x00007fa49c003265 in TF1::Paint (this=0x3f647f0, option=0x3f655f9 "") at /home/uhlig/root/source/root/hist/hist/src/TF1.cxx:2863
#11 0x00007fa497c490d9 in TPad::PaintModified (this=0x3f65e90) at /home/uhlig/root/source/root/graf2d/gpad/src/TPad.cxx:3124
#12 0x00007fa497c1afdc in TCanvas::Update (this=0x3f10370) at /home/uhlig/root/source/root/graf2d/gpad/src/TCanvas.cxx:2127
#13 0x00007fa49f6cfb61 in TCint::UpdateAllCanvases () at /home/uhlig/root/source/root/core/meta/src/TCint.cxx:2210
[I used triple ` to convert your code listings].
This looks like the dimensionality of the function is wrong. If you plot this on a 2D plane, you e.g. need two observables.
Alternatively, could it be that the parameters that you pass are not parameters of the PDF?
You could get them using: getParameters()
Note that in the fit result, you might have copies of those parameters, and not the actual parameters of the PDF.
Ok, this wasnât easy to diagnose without running it myself, but itâs logical once you understand whatâs going on:
You create a model on the stack inside the function.
You create the TF1, which uses pointers to the original model to do the computation.
The function ends, your model gets destroyed.
The Canvas where the model is drawn, as well as the TF1 still exist, though. --> Crash.
Solution:
--- /tmp/testMacro.C 2020-08-27 10:51:26.000000000 +0200
+++ /tmp/testMacro2.C 2020-08-27 10:50:46.000000000 +0200
@@ -21,7 +21,7 @@
{
-TFile *fIn = TFile::Open("inputFile.root");
+TFile *fIn = TFile::Open("/tmp/inputFile.root");
TH1F * xHist = (TH1F*)fIn->Get("xHist");
//xHist->Draw();
@@ -72,14 +72,13 @@
// Code for TF1
double ppp[8] = {0.0}; // to store 8-parmas
-//RooRealVar var2("var2","var2",-10e6,10e6);
-RooArgList obs(PsProperDL,"obs");
-RooArgSet RxPars ;
-RxPars=Rx->getParameters(PsProperDL);
-//RooArgList * RxPars = (RooArgList*)fitRx->floatParsFinal();
+RooArgSet* copyOfEverything = RooArgSet(*Rx).snapshot(true); // True means copy the PDF and everything it depends on
+auto& copiedPdf = static_cast<RooAbsPdf&>((*copyOfEverything)["Rx"]); // Get back the copied pdf. It lives in the RooArgSet "copyOfEverything"
+RooArgSet* obs = copiedPdf.getObservables(hist);
+RooArgSet* RxPars = copiedPdf.getParameters(*obs);
-TF1 * RxFunc = (TF1*)Rx->asTF(obs,RxPars);
+TF1 * RxFunc = copiedPdf.asTF(*obs,*RxPars);
//RxFunc->Eval(2.3);
RxFunc->GetParameters(ppp) ;
Note that now, both the PDF and the TF1 will leak out of the function. If you just want to see them, thatâs fine, but donât call this function 10k times in a loop.
error: cannot initialize a variable of type âRooArgSet *â with an rvalue of type 'RooAbsCollection â
RooArgSet copyOfEverything = RooArgSet(*Rx).snapshot(true); // True means copy the PDF and everything it depends on