Fitting multiple TH1D onto another TH1D

Hi,

What I’m trying to do is the following:

  • I have a measured spectrum saved as a TH1D in a ROOT file and I have a few simulated spectra also saved as TH1Ds in a number of ROOT files.

  • I’m hoping to fit the simulated spectra to the measured spectrum, i.e.: my fitting function should look like [0]*simulated_spec_0 + [1]*simulated_spec_1 + …

  • The fitted spectrum should then be drawn onto the canvas and the fitting parameters ([0], [1], [2], …) should then be written in a txt file.

Could anyone point to me the correct way I should go about tackling this task (esp. the histogram fitting part)? From what I’ve seen(or understood from the documentation), there seem to be no method to fit TH1D objects, only TF objects, or am I mistaken?

Thanks in advance!

Hi,
to know how to fit a TH1*, you should have a look to this tutorial: myfit.C.

To achieve, what you want to do, follow these steps:

  1. Open the first simulated spectrum
  2. Fit it and save the parameter of the fit
  3. Open the second simulated spectrum and apply the step 2.
  4. Do it for all simulated spectra
  5. Open your experimental spectrum
  6. Define a global TF1 that will be used to fit your experimental spectrum
  7. Set as initial values, the values that you got from the simulated spectra (the ones you saved at step 2).
  8. Fit your experimental spectrum
  9. Get the parameters of the fit and save them in a text file.
1 Like

Hi,

I don’t quite understand what you mean by Step 2: to fit the simulated spectrum, I would need to have the experimental spectrum opened already so that there would be something to fit the simulated spectrum onto, no?

And how would one go about fitting the TH1*? If I understand the code in “myfit.C”, the imported histogram (hpx) is in a TF1 format, not a TH1* format. Would the same method work?

In myfit.C, “hpx” is a TH1F object (it corresponds to the blue line on the figure). And you fit it using “func” that is a TF1 object (it is the red line on the figure).

About the rest, could you attach a picture to see how both simulated and experimental spectra look like?

Hi, sure. I attached the screenshot I have from my ROOT terminal (I thought that it would be more helpful with the file types there, or should I attach the histograms drawn?")

Screenshot%20from%202019-06-24%2011-09-44

Yes, what is useful is the histograms drawn. Thanks in advance.

1 Like

Hi pamputt,

attached are the pictures of the histograms. And thank you!

measured sim

Thank you, can you tell me which one is the simulated (I guess, the bottom one) and which ont is the experimental spectrum (I guess the top one)?

Hi pamputt,

my bad: the bottom is the simulated data and the above one is the measured spectrum.

I would ideally like to learn to scale the bottom TH1D .root file to best fit the one above. As you might already infer, this is where the other spectra would come into play. My goal is to, in the end, be able to read off from the fit parameters the contribution of each spectra (which corresponds to a certain radioisotope) after the fit has been applied.

I know it might sound a bit superficial after so many instances, but I can’t help myself from thanking you again for your patience and willingness to help!

If all your simulated spectra contain only one peak so it is rather easy to fit them with a Gaussian like in the myfit.C tutorial. Indeed, you need to find the maximum of the histogram to find the position of the peak. If more than 1 peak is present, you will need to use a peak search algorithm (see ShowPeaks for example).

And then, you can follow the steps I described above.
About the step 2, the idea is to determine the parameters of the Gaussian peak with which you fitted your simulated spectrum. And at the end, you can set these parameters for a global fit of your experimental spectrum (the position and the width of the peak should not change that much; only the amplitude is free).

Hi pamputt,

ooof, I think I haven’t worded what I wanted to do properly.

My idea of a “fit” was to fit one TH1D onto another TH1D (i.e.: comparing both the histograms with each other and determine, for example, that the simulated histogram = 10e6 * measured histogram), and not fitting a curve onto it. My apologies if that’s not the correct wording for it (would appreciate learning the correct term).

Ok, in that case, you do not need to use TF1. You find the height of a the peak you are interested in in your experimental spectrum using the GetBinContent method. You do the same on the simulated spectrum. You can now compute the ratio of the two heights and using the Scale method, you can achieve what you want.

1 Like

Ah, ok.

Is it important in this case that both histograms have the same limits (I assume so)? And since I have a number of other spectra, which all have different scale factors, how would one go about obtaining the correct scale factor for all the other spectra?

You do not need to have the same limits. You can do a simple test to check

hexperimental->Draw();
hsimulated->Scale(1/1000.); //replace 1/1000. by your ratio
hsimulated->SetLineColor(kRed);
hsimulated->Draw("same");

Note that you can also divide the bin content of one histogram by those of another histogram: that gives you the ration distribution. See TH1::Divide(), https://root.cern.ch/doc/master/classTH1.html#ac782a09c31b4f7de40f8fd4f77efa090 or its overloads.

1 Like