Hello everybody!
I am quite a beginner with ROOT and I have some problems with the energy calibration of my gamma spectra. Hope you can help me.
I use PyROOT.
Below you can find the code I am using:

For reference, channels are 8191, while xmin=-0.5 and xmax=8190.5
And here is the result. As you can see some bins are empty. I have followed some suggestion about adding a random dE between 0 and 1 to the x_new values, but it does not work.

Note that the histogram’s bins’ numbers start at 1. Not at 0. The first bin of an histogram with nbins has the number 1 and the last bin has the number nbins. So xmin and the range you are using in the loop are not appropriate.

Instead of using GetBinCenter to compute xmin and xmax it might be more appropriate to use GetBinLowEdge and GetBinUpEdge.

The new histogram hcalib is filled at the positions z[1]+z[0]*i. It is not clear what z[0] and z[1] are. It could be that with this value you sometimes hit the bins’ borders and the filling may end up in the wrong bin. Or it could be that this computation gives a wrong result and some bins are skipped. The screen dump you posted is not enough to fully understand the logic.

Thank you very much for your reply and suggestions!
I was wrongly assuming the notation of the bins should start from the underflow ones.
I tried changing those things, but the result is still the same.

Sorry, you are right I didn’t specify what z[1] and z[0] are. Basically they are the coefficients of a linear fit I performed using the channel number of peaks in 60Co and 137Cs sources spectra and the corresponding energy. Parameters evaluated are such that the linear relations should be:
Energy=-2.8708+1.0035*channel.
One of the ‘empty’ bin in hcalib is for example 828.
I don’t know if I am gettin ROOT’s logic right, but if I take channel=827 and apply my calibration, it gives me Energy=826.99(…) , but then channel=828 gives Energy=828.00659(…): does this imply that the xrange between 827 and 828 is ‘missing’ and the bin is skipped? If so, is there a way to solve the computational issue?

A better idea is to “calibrate” the original histogram:

a = z[0]; b = z[1] # En = a * Ch + b ("channel to energy" calibration)
ax = h.GetXaxis() # an axis with fix bins (will be scaled with a linear function)
ax.Set(ax.GetNbins(), a * ax.GetXmin() + b, a * ax.GetXmax() + b)
h.ResetStats()