Problem with landau fit on root

I made a landau and gaus fit on my histogram, and I don’t understand if it’s correct or not (I am using root since one month).
acq32.C (2.3 KB) Here there is my code with data gaussy.txt (905 Bytes) , and the plot that I got. In file “acq32a” I used “WL” weighted log likelihood method. The landau fit looks really weird. i don’t understand if my data doesn’t follow at all like a landau distribution or if i’ve done something wrong…
In file “fitgiusto” I used “W” option but I think it’s not correct 'cause this option sets all weights to 1, and in my histogram each point has a diferrent weight.
What do you think? fitgiusto.pdf (17.8 KB) acq32a.pdf (18.1 KB)

Hi @alinasoflau,

I am inviting @jonas, one of our RooFit experts, to this topic. I am sure he can help you with this.


Thank you!!

Dear @alinasoflau,

sorry for the late reply! In your code, you didn’t use RooFit but the basic fitting of histograms in ROOT.

Your usecase looks like some classic physics lab experiment with a radioactive source and a detector, where you expect to see the convolution of a Landau signal with a Gaussian resolution function :smiley: So fitting only a Landau, a Gaussian or their sum like you attempted in the script you uploaded is not enough.

This is a classic RooFit example, there is even a tutorial for that. I wrote a script where I show you how you can do the fit:
acq32_roofit.C (1.9 KB)

RooFit is very flexible, you can easily add more Gaussians and Landaus or fit something completely different if you want. In your case, I think the Gaussian (x) Landau convolution is already excellent: I get a reduced Chi^2 test statistic of 1.05667 in the fitting range 64 to 150.

Please let me know if you are fine with this solution or if you have any further questions!


Thank you so much! The laboratory experience was about the calculation of the gain of two photomultipliers. the plot is the charge spectrum of two PMTs positioned one meter away from each other, parallel and alligned, so that they can only measure non-inclined muons from cosmic rays. professor told us that the curve in theory should be a convolution of two landau but in our case the photomultipliers were not perfectly alligned so I guess that your convolution is the best. Thank you again!
I have to ask you another question, how can I see the parameters of the convolution? I need the MPV of this fit and sigma.


You can see the parameters and their uncertainty somewhere in the minimizer output, but the most convenient way to take a access the best-fit parameters and their errors is to get the fit results as a RooFitResult and print them.

To do this, you can replace the line with fitTo with this code:

    auto result = std::unique_ptr<RooFitResult>(
            model.fitTo(dataHist,Range("r1"), Save(true), PrintLevel(-1)));

I also added the PrintLevel(-1) argument to silence the minimizer output for the fit. Then you can better see what corresponds to result->Print().

Another nice RooFit feature you can use is RooAbsPdf::paramOn to show the fit parameters directly on your plot:

    RooArgSet params = RooArgList(
        landauMean, landauSigma, gaussMean, gaussSigma
    ) ;  
    ) ;

I hope this helps, let me know if you have further questions!

So there is no way to see the parameters of the convolution curve (like the sigma of the resultant fit)? only the parameters of the components of the convolution (landau and gaussian)?

Thank you very much! I’ve already done two programs with roofit and it is great!

Ah okay, now I understand better! Just to make sure: with sigma you mean the standard deviation of the distribution? Because sometimes people use different sigmas, like for example the central 68 % interval around the mean.

Yes, I mean the standard deviation of the distribution! Also the MPV.

Definition of Landau PDF in ROOT

You can use RooAbsReal::mean and RooAbsReal::sigma to get mean and sigma for arbitrary pdfs:

    auto fullMean = model.mean(canale)->getVal();
    auto fullSigma = model.sigma(canale)->getVal();
    std::cout << "mean of full model: " << fullMean << std::endl;
    std::cout << "sigma of full model: " << fullSigma << std::endl;

Is this what you are looking for?


Thank you! I need the MPV=most probable value, so the peak of the convolution. I tried to do this with maxVal but I have this problem:
/Users/alinasoflau/Desktop/plateau/acq32_roofit1.C:72:36: error: no viable conversion from ‘RooRealVar’ to ‘Int_t’ (aka ‘int’)

auto maxVal = model.maxVal(canale)->getmaxVal();

I am really sorry for the trouble.

Hi @alinasoflau,

you should better not use maxVal. This is a more internal function to optimize the MC event generation.

There is not direct way of finding the most probable value (MPV, also called the “mode”) of a RooFit function, but you can easily convert your model to a TF1 with RooAbsReal::asTF and find the MPV with TF1::getMaximumX:

    TF1 * f = model.asTF( canale );
    double canaleMax = f->GetMaximumX(); 

    std::cout << canaleMax << std::endl;

I found this trick in another forum post.

1 Like

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