Both intensity (e.g. MJy/sr) and flux (e.g. mJy) unit flavors are prevalent among the spectra PAHFIT encounters.
To simplify unit conversion and support a variety of spectral input units, we have adopted "standardized internal units" from #259. Re-stating:
PAHFIT working units summary:
Type
Working Unit
Wavelength/FWHM/spectral_axis
µm
Temperature
K
Flux density
mJy
Flux power
1e-22 W/m2
— OR —
Surface Brightness/Intensity
MJy/sr
Surface Brightness Power
1e-10 W/m2/sr
Input spectra (Spectrum1D) can be tagged with any units compatible with these. They will be converted to these units before being handed to a Fitter, or e.g. for guess algorithms, etc. Output powers will be in the associated "power" unit. Fitter's can do anything they want with units internally, but need to speak these units outside.
But actually, we want a bit more than this:
We don't want any Fitter to have to branch on the unit flavor anywhere. Ideally they'd be flavor-agnostic whatever spectra they are asked to fit should "just work" as-is.
We want flexibility to later apply a flux-flavored model to an intensity-flavored spectrum.
To solve 1, we could update the above units such that the density/power ratio is the same. This would make converting between amplitude and power (e.g. for Drudes and Gaussians) independent of spectral flavor. It's not clear if this would also solve 2.
One idea for a solution to both of these comes from the comment at the end of units.py:
# Note: integrated power units of 1e-22 W/m^2 (from flux) corresponds
# to the unit 1e-10 W/m^2/sr (from intensity) if it occurs uniformly
# over a solid angle 0.21" on a side (about a small JWST IFU pixel)
The idea is, we could further standardize on intensity-flavored units as primary, and add a:
units.canonical_solid_angle = 7.38413463e-11 # solid angle of spherical cap of radius 1 arcsec in steradians
for converting between flavors. For any flux-flavored units presented to Model, we'd use this canonical solid angle to convert them internally to intensity form, before passing to Fitter.fit|guess|etc. All the powers would be output from Fitter in intensity form.
But Model would keep track of the unit flavor of its most recently fitted spectrum, and always plot and print itself in that flavor, using units.canonical_solid_angle to convert between if needed. This would also allow a Model saved in one flavor of unit to be directly applied to another, since unit flavor only affected the printed representation.
One potential problem: users of flux spectra directly inspecting the saved Model file might be surprised to see (e.g.) W/m^2/sr units in there (or worse, not even notice). To fix that, we could have Model convert the entire Features table into the desired units, and save itself in those units. So if you save a Model which has last fit a flux-spectrum, powers will be W/m^2. You can then apply this to an intensity spectrum if you want, with the canonical solid angle providing the translation (possibly with a warning). The drawback here is every re-use of the Fitter means re-translating the Features table.
Both intensity (e.g.
MJy/sr
) and flux (e.g.mJy
) unit flavors are prevalent among the spectra PAHFIT encounters.To simplify unit conversion and support a variety of spectral input units, we have adopted "standardized internal units" from #259. Re-stating:
PAHFIT working units summary:
Input spectra (
Spectrum1D
) can be tagged with any units compatible with these. They will be converted to these units before being handed to aFitter
, or e.g. forguess
algorithms, etc. Output powers will be in the associated "power" unit.Fitter
's can do anything they want with units internally, but need to speak these units outside.But actually, we want a bit more than this:
Fitter
to have to branch on the unit flavor anywhere. Ideally they'd be flavor-agnostic whatever spectra they are asked to fit should "just work" as-is.To solve 1, we could update the above units such that the density/power ratio is the same. This would make converting between amplitude and power (e.g. for Drudes and Gaussians) independent of spectral flavor. It's not clear if this would also solve 2.
One idea for a solution to both of these comes from the comment at the end of
units.py
:The idea is, we could further standardize on intensity-flavored units as primary, and add a:
for converting between flavors. For any flux-flavored units presented to
Model
, we'd use this canonical solid angle to convert them internally to intensity form, before passing toFitter.fit|guess|etc
. All the powers would be output fromFitter
in intensity form.But
Model
would keep track of the unit flavor of its most recently fitted spectrum, and always plot and print itself in that flavor, usingunits.canonical_solid_angle
to convert between if needed. This would also allow aModel
saved in one flavor of unit to be directly applied to another, since unit flavor only affected the printed representation.One potential problem: users of flux spectra directly inspecting the saved
Model
file might be surprised to see (e.g.)W/m^2/sr
units in there (or worse, not even notice). To fix that, we could haveModel
convert the entireFeatures
table into the desired units, and save itself in those units. So if you save aModel
which has last fit a flux-spectrum, powers will beW/m^2
. You can then apply this to an intensity spectrum if you want, with the canonical solid angle providing the translation (possibly with a warning). The drawback here is every re-use of theFitter
means re-translating theFeatures
table.