Closed hannahberg closed 3 years ago
To be more specific, if the lowest energy bin for the experimental NLD is larger than zero (ie. nld.E[0] > 0) then the interpolation made with https://github.com/oslocyclotronlab/ompy/blob/5166b6dc4156e8041c7716ed2a73d827e814bc27/ompy/normalizer_gsf.py#L591
will fail since the integration goes from 0 to Sn.
A quick workaround could be:
fexp = None
if nld.E[0] > 0:
fexp = log_interp1d(np.concatenate(([0], nld.E)),
np.concatenate(([0], nld.values)))
else:
fexp = log_interp1d(nld.E, nld.values)
but is not very elegant
I'd say that this is not a bu, but a feature :), somehow at least. I think the question/problem is: You need nld(Ex=0)
, otherwise, how do you normalize gsf
with Gg
?
So you somehow need to make up values for nld(Ex=0)
.
A quick workaround could be:
fexp = None if nld.E[0] > 0: fexp = log_interp1d(np.concatenate(([0], nld.E)), np.concatenate(([0], nld.values))) else: fexp = log_interp1d(nld.E, nld.values)
but is not very elegant
I agree, this is a quick fix, but I'm not sure I would want to make it a feature, instead of maybe having a few open issue and a "galleri" of different ways to fix this. Don't know what you think about it.
I'd say that this is not a bu, but a feature :), somehow at least. I think the question/problem is: You need
nld(Ex=0)
, otherwise, how do you normalizegsf
withGg
?So you somehow need to make up values for
nld(Ex=0)
.
Both yes and no. I'm thinking about the case where your first bin are at say 0.1 MeV, then you will get this error. Although I guess it is kinda bad choice of binning if the first bin is at 0.1 MeV?
To be more specific: I think that it is more clear if you do something along the lines of what Vetle suggested above ((np.concatenate(([0], nld.E, np.concatenate(([0], nld.values)=
) -- but in the main script. So one does it before sending it to NormalizerNLD(nld=...)
or so.
A quick workaround could be:
fexp = None if nld.E[0] > 0: fexp = log_interp1d(np.concatenate(([0], nld.E)), np.concatenate(([0], nld.values))) else: fexp = log_interp1d(nld.E, nld.values)
but is not very elegant
I agree, this is a quick fix, but I'm not sure I would want to make it a feature, instead of maybe having a few open issue and a "galleri" of different ways to fix this. Don't know what you think about it.
Might be smart, but the error message should be more descriptive. Maybe give a link to the issue on GitHub?
I'd say that this is not a bu, but a feature :), somehow at least. I think the question/problem is: You need
nld(Ex=0)
, otherwise, how do you normalizegsf
withGg
? So you somehow need to make up values fornld(Ex=0)
.Both yes and no. I'm thinking about the case where your first bin are at say 0.1 MeV, then you will get this error. Although I guess it is kinda bad choice of binning if the first bin is at 0.1 MeV?
So anyhow it will depend both on what is you central value and the bin width.
Might be smart, but the error message should be more descriptive. Maybe give a link to the issue on GitHub?
Yep, thought about this, too, when I wrote it :+1: !
Maybe something like
ValueError: nld does not extend to 0 MeV. Please see https://github.com/oslocyclotronlab/ompy/issues/170 for more info.
I can make a suggestion and write up a small example of how I would include it in the main script.
So one solution if you miss e.g. the lowest bin is to come up with a value for it (interpolate / find from known levels / ...).
fill_value = np.array([0, 0]) # (Ex, value)
for nld in extractor.nld:
nld.E = np.concatenate(([fill_value[0]], nld.E))
nld.values = np.concatenate(([fill_value[1]], nld.values))
# diff = np.diff(nld.E)
# assert len(set(diff)) == 1, "nld does not have equal energy spacing (anymore)"
You may want to make sure that you preserve a linear energy spacing, so maybe you have to all several bins, and not just one. For example, you may (have to) append [0, 10]
and [200, 20]
to the nld
(with the given value, assumes that the nld is 10 at 0 and 20 at 200.)
Alternatively, one can create a child class from NormalizerGSF
and simply change the functions fnld
and/or fgsf
. There one can e.g. pass arguments for loginterpolate
, which bases on scipy.interpolate.interp1D
file fill_value= 0
or fill_value=extrapolate
-- or create more complex functions.
Maybe reopen so that it's visible?
Alternatively, one can create a child class from
NormalizerGSF
and simply change the functionsfnld
and/orfgsf
. There one can e.g. pass arguments forloginterpolate
, which bases onscipy.interpolate.interp1D
filefill_value= 0
orfill_value=extrapolate
-- or create more complex functions.
Example:
import ompy as om
class MyNormalizerGSF(om.NormalizerGSF):
@staticmethod
def fnld(E, nld, nld_model):
fexp = log_interp1d(nld.E, nld.values, fill_value=(0, np.max(nld.values), bounds_error=False)
conds = [E <= nld.E[-1], E > nld.E[-1]]
return np.piecewise(E, conds, [fexp, nld_model(E[conds[-1]])])
nldnorm = MyNormalizerGSF(...)
Maybe reopen so that it's visible?
People get an explicit link to this issue now, so I don't think that this is necessary.
One reason this may happen could be that when running the extractor the extracted nld/gsf may become nan
for energies above 0 MeV. Maybe add a check at the end of the Extractor.decompose
method that issues a warning whenever the extracted NLD has nan
for excitation energies at or above 0 MeV.
Good idea. I will add it.
With my data, I do not have data for the NLD at E=0 MeV. When I try to normalize my gSF, the extrapolation fails as it is out of bounds. OMpy version '1.1.0.dev0+ce29c32'.