This PR addresses a number of things that have turned up in various imsim/roman_sim runs related to the SED classes. The initial impetus for this work was to let the SEDs we get from skyCatalogs to be picklable, so image.nproc would work correctly, and other use cases as well would not be quite so finicky about pickling.
The main solution for this problem was to have mul_sed try to return a tabulated sed if possible. I.e. when either (or both) of them uses a lookup table.
Another thing that helps for some cases is to not try to pickle the derived SEDs in chromatic objects that have the SED as a lazy_property. It's not very inefficient to remove them from the dictionary before pickling and remake them if needed. (Indeed it might be usually more efficient, since there is less serialization and communication involved.)
While I was at it I addressed issue #1187, making it generally fine to use spline interpolation for Bandpass and SED objects. The default in these classes is still linear (e.g. when reading from a file), but now it's not inefficient to build an SED with a regular LookupTable using the default interpolant='spline'.
Given the above, I added an interpolant option to these classes so if you want to read from a file using spline interpolation, it is now possible.
I added a clip_neg option to DistDeviate to clip any negative values in the probability distribution to 0. This is now used in sampleWavelengths, since spline interpolations can lead to slightly negative values in some cases. Rather than try to avoid it in the SED class, it seems more sensible to just allow DistDeviate to gracefully ignore those negative values. The default behavior of DistDeviate is unchanged -- with the default clip_neg=False, it raises an error if there are any negative probabilities.
The hardest thing for getting spline to work well was to get the thin() algorithm to work correctly with a spline table. I couldn't find an O(N) algorithm for that, so it uses the slower algorithm, but I think it's basically working now.
Along the way I found two bugs in the new EmissionLine class, which I fixed. First, the atRedshift function was wrong. It both set the redshift value and changed the wavelength of the line. The nominal wavelength shouldn't change, since the given spectrum is supposed to define the rest-frame SED, not the observed SED.
Also, in some use cases, the 0 at the edge of the emission line could turn into a 1.e-16 kind of number. When integrating from there to "infinity", that could lead to crazy bolometric fluxes. My fix for this was to add a second 0 another fwhm away on either size to really force it to zero when not near the line.
Related to that, I changed out definition of infinity in bolometric fluxes from 1.e100 to 1.e30 (nm). That's still 1.e21 meters, which is way past any conceivable radio wave wavelength. But it allows functions of wave with some modest power like wave**3 to not blow up.
Finally, I added an interpolant option to our trapz function to make it easier do the integral in the thin_tabulated function using the specified interpolant. I didn't end up using it in as many places as I originally expected to, but still, I think it's a useful enough feature, so I kept it.
This PR addresses a number of things that have turned up in various imsim/roman_sim runs related to the SED classes. The initial impetus for this work was to let the SEDs we get from skyCatalogs to be picklable, so image.nproc would work correctly, and other use cases as well would not be quite so finicky about pickling.
interpolant
option to these classes so if you want to read from a file using spline interpolation, it is now possible.atRedshift
function was wrong. It both set the redshift value and changed the wavelength of the line. The nominal wavelength shouldn't change, since the given spectrum is supposed to define the rest-frame SED, not the observed SED.