I am having difficulties calibrating an energy spectrum.
I have a vector ENERGY which I fill an histogram with. The result looks fine (uncal.pdf).
However, after I apply the calibration ENERGY_CAL[i] = channel2Energy(ENERGY[i]),
where channel2Energy is a linear function, I fill another histogram with ENERGY_CAL and get a weird looking result (cal.pdf).
I already tried using a different binning for the second histogram but I cannot get it to look nice.
Hi Christoph, it is because you pass from integer values (channel) to continuous values (energy). To smooth your spectrum, in your function channel2Energy, you should add a random number (between 0 and 1) to the channel value.
Doing so smooths your calibrated spectrum because when you have channel with value 10, the “exact” value is between 10 and 11. Adding a random value solves this “issue”.
Actually ENERGY does not have integer values. The function channel2Energy is named very badly, I know. It was used to convert channels once, that’s why it is still called like that.
Some examples:
Ok, but this effect comes clearly from the fact you started with integer values that you converted to continuous values. So, if you do not have the channel values anymore, maybe you can try what @Wile_E_Coyote has proposed.
I looked at your link and tried out the scaling for histograms with fixed size. Explicitly I did
TH1F* hSpectrumCalibrated = (TH1F*) hSpectrumUncalibrated->Clone("hSpectrumCalibrated");
auto a = hSpectrumCalibrated->GetXaxis();
a->Set( a->GetNbins(), 0, channel2Energy(fCalibration, a->GetXmax()) );
which produces exactly the spectrum I want! very nice.
Sadly this does break something further down in my code, what could I have changed?
Why should I create a histogram with variable bin size? At least something seems to have been fixed with this approach.
In your current approach, you should use (instead of “0”): channel2Energy(fCalibration, a->GetXmin())
and in the end you need to add: hSpectrumCalibrated->ResetStats();
If at some point your “channel2Energy” function is no longer linear then the energy bins’ widths will not be constant / equal (so you will need a histogram with variable bin sizes).
BTW. If “+ dE” didn’t work well then you might try “- dE” (or e.g. “+ dE / 2.0” or “- dE / 2.0”).
Thank you very much!
The problem has already been solved by your previous answer. The crash was my fault.
However, now the number of entries has been reduced even though I did ResetStats() and everything looks fine now.
Something else also still bothers me. I don’t understand why it should make a difference if I calculate ENERGY_CAL and fill a histogram with it, or if I simply scale an axis if I use the same calibration/scaling function in both cases. I have constructed an example creating a histogram hSpectrumCalibrated2 which displays the difference in both cases (see attached pdfs):
In the meantime, print (just to make sure that it is less than about 1.6777e7): hSpectrumUncalibrated->GetBinContent(hSpectrumUncalibrated->GetMaximumBin())