I am facing the following problem: I have multiple histograms which I would like to fit with the same function. Some of the parameters should be tied together, while some other should be fitted independently. I can’t find a way to do that. Can somebody help me?
to fit multiple histograms you can create a combined data set (using the ROOT::Fit::BinData class )and then fit. If you have different parameters for the histograms you would need to create then separate chi2 (or likelihood) objects and then create a combined one which can be minimized.
If you are interested I can write you an example on how to do this. RooFit also provides some tools for doing simultaneous fits
I have attached two examples. In the first one a fit is done using a common function on two histograms, in the second one different function are used and one parameter is shared between the two functions. In this case a combined chi2 is built and used for fitting the two data sets.
Hmm, I think there is a small error in the combinedFit.C, or I’m doing something wrong:
/home/lewhoo/WAF/sample/./combinedFit.C: In function ‘void combinedFit()’:
/home/lewhoo/WAF/sample/./combinedFit.C:105: error: no match for call to ‘(ROOT::Fit::DataRange) ()’
/opt/pi/ext/dload/root/include/Fit/DataRange.h:97: note: candidates are: std::pair<double, double> ROOT::Fit::DataRange::operator()(unsigned int) const
Thank you for spotting this. The macro worked with my development version which was not yet committed in ROOT. Now these changes are in the trunk and it should work. For older versions (revision < 36558) the changes suggested before should be applied.
thanks for providing these examples! I managed to get the combinedFit.C macro running with ACliC in ROOT 5.26. However, when adopting these lines of code for my analysis executable, which is build using g++ and a MakeFile pointing to the cflags and libs from root-config, I am getting the following compiler error:
‘FillData’ is not a member of ‘ROOT::Fit’
If understand the documentation (*) correctly, including “Fit/SparseData.h” should provide access to the FillData methods in the ROOT::Fit namespace. I have tried including this and several other related headers but I was not able to get rid of the compiler error.
Inside the example it says: “this macro must be compiled with ACliC”. Does this means it will work only with ACliC???
Thanks a lot, Lorenzo, for the quick reply last week! Including the HFitInterface header indeed did the trick. I guess this is one example for those cases in which the auto-generated documentation is not able to tell users the necessary include(s) for all methods listed on a common documentation page (here corresponding to the ROOT::Fit namespace), right?
I have two further, slightly related questions…
1.) Is it possible to increase the verbosity of the ROOT::Fit::Fitter using some simple option parameter? I am currently getting a segmentation violation during the fit and thought that some additional printout before the crash would help me debugging.
2.) Is it true that there are no default constructors defined for ROOT::Fit::Chi2Function and
ROOT::Math::WrappedMultiTF1? If this is the case: What are the reasons for not providing them? I missed the default constructors when trying to build arrays of objects from these classes.
The Chi2Function class is designed to work with a function and a data set pointer, which are stored internally as references. It is not possible to have a default constructor.
I could add a default one for the ROOT::Math::WrappedMultiTF1 if you really need.
Why you don’t create a vector of object pointers ? IN this case you solve the problem of the default constructor.
Thanks! This is helpful. Now I see that my crash occurs directly after:
FIRST CALL TO USER FUNCTION AT NEW START POINT, WITH IFLAG=4.
From the stack trace (attached) I see that the seg fault happens within WrappedMultiTF1::DoEvalPar. Playing around with some cout statements, I saw that the crash happens when calling (*fChi2_1)(p1), i.e. when evaluating the first of those two functions inside my GlobalChi2 object, although there are no crashes when evaluating this WrappedMultiTF1 with the same parameter settings outside the GlobalChi2 object. And I saw that the crash happens before actually entering my user defined function that I put into the WrappedMultiTF1, i.e. before really starting to calculate a function value.
What does WrappedMultiTF1::DoEvalPar do before actually calculating the function value?
For which x value will the function value be calculated first? The lower bound of the range that was set using ROOT::Fit::DataRange?
Sorry for asking for support with such vague problem description but it would take me some time to create a minimal example from my analysis macro.
your crash will most probably happen in TF1::EvalPar because the array of parameter you are passing is not of the right size. The size of the array p1 used in (*fChi2_1)(p1) must be equal to the number of parameter of the function (TF1::GetNpar()).
To help you more I would need then to see the code,
Everything seemed fine when creating the functions like this and I was able to set their parameters and to calculate function values. Just when including these functions in the combined fit, it crashed since all functions but the very last one in the array were invalid. I solved this by giving individual names to all functions when creating them: