BlackBody model: fix handling of scale units#12318
Conversation
| scale : float or `~astropy.units.Quantity` ['dimensionless'] | ||
| Scale factor | ||
| Scale factor. If dimensionless, input units will assumed | ||
| to be in Hz and output units in (erg / (cm ** 2 * s * Hz * sr). |
There was a problem hiding this comment.
Perhaps this just needs rewording for clarity. Let me explain the behavior and if everyone agrees on that, then let's revise the wording to make sure its clear: the input units (of x when calling evaluate, which are dictated by the input_units property) are assumed to be in Hz, as they were previously, if scale is either dimensionless, not provided, or equivalent to SNU units. The change is that now they will be assumed to be in Angstroms if the units on scale were equivalent to SLAM units to be consistent with the returned units. Otherwise the case I show in the description fails with ugly error messages during fitting with a Compound model (and I suspect might even give incorrect results when used alone unless you really mean to pass in frequencies without units and return wrt wavelength).
There was a problem hiding this comment.
Oh, I see... I misread it as "the scale factor, if dimensionless, is assumed to be in Hz" 😛
lpsinger
left a comment
There was a problem hiding this comment.
Please add a deprecation warning for non-dimensionless scale.
| if self.scale.unit is not None: | ||
| # Will be dimensionless at this point, but may not be dimensionless_unscaled | ||
| scale = self.scale.quantity.to(u.dimensionless_unscaled) | ||
| else: | ||
| scale = self.scale.value |
There was a problem hiding this comment.
| if self.scale.unit is not None: | |
| # Will be dimensionless at this point, but may not be dimensionless_unscaled | |
| scale = self.scale.quantity.to(u.dimensionless_unscaled) | |
| else: | |
| scale = self.scale.value | |
| if self.scale.unit is not None: | |
| # Will be dimensionless at this point, but may not be dimensionless_unscaled | |
| scale = self.scale.quantity.to(u.dimensionless_unscaled) |
The else: statement does nothing.
There was a problem hiding this comment.
This PR only fixes the two bugs mentioned in the description above, but does not deprecate non-dimensionless scale (although it does internally split off the units as that is needed for the logic to fix the second bug). The idea was to try to get these bugfixes independently of any longer-term decisions on full general handling of return units.
The else statement is needed to fallback on scale = self.scale.value. self.scale is stored as either a float or as a quantity with dimensionless units. The if block addresses the first bug (passing scale with units of cm **2 / Mpc **2) by converting dimensionless to dimensionless_unscaled, but the else is needed to handle the case where it is passed and stored as a float.
99735b8 to
3a7632b
Compare
|
Hello @kecnry 👋! It looks like you've made some changes in your pull request, so I've checked the code again for style. There are no PEP8 style issues with this pull request - thanks! 🎉 Comment last updated at 2022-03-08 21:16:27 UTC |
3a7632b to
1be0864
Compare
|
Please you rebase your PR onto main. |
|
Is there a PR coming to implement the strategy that we discussed in the telecon? |
9621f06 to
4bdb638
Compare
* dimensionless (but non-unscaled) scale is converted to dimensionless_unscaled before being applied * when scale is passed with units, the units are checked for validity and then stripped and stored in self._output_units. self.scale always contains the dimensionless factor that will be multiplied in both evaluate and bolometric flux. * expected input units (units on x if not provided when evaluating) still default to Hz, but will change to AA if the unit on scale is equivalent to erg / (cm ** 2 * s * AA *sr). The input array is still converted to Hz using the spectral equivalency for internal computation. This fixes the case where using BlackBody+Linear1D wrt BlackBody failed to fit due to unit consistency checks.
* both with and without internal units set
4bdb638 to
930ea38
Compare
…318-on-v5.0.x Backport PR #12318 on branch v5.0.x (BlackBody model: fix handling of scale units)
Description
This pull request (which is a stripped down version of #12304 that only includes minimal bug fixes and not deprecating support for units in
scaleor introduction of support for flux units) fixes the case where dimensionless (but not unscaled) units are passed toscale(#11547) and also changes the expectedinput_unitsbased on the units passed toscale(which control the returned units). This second change is necessary in order to handle fittingBlackBody(..) + Linear1D(...)with respect to wavelength, as BlackBody was previously forcing the unitless array to Hz which then failed unit consistency checks with Linear1D.Note that this does not address the second example in 11547 and that case remains ambiguous as
scaleis both providing a unitless scale factor and optionally responsible for determining the returned units. See #12304 for a possible solution to this by requiringscaleto be dimensionless and handling the request for output units as a separate argument.Revisiting the first case in #11547:
now returns the expected results (the passed scale with units of
cm ** 2 / Mpc **2are converted todimensionless_unscaledbefore being applied):The following case demonstrates the new treatment of
input_units:which shows all models have expected Hz input units and the fitter runs successfully (as previously). However, the wavelength case:
used to have x
input_unitsof Hz for the BlackBody model (but Angstrom for the other models), causing the following error during fitting:UnitConversionError: 'erg / (Angstrom2 cm2 s sr)' and 'erg / (Angstrom cm2 Hz s sr)' are not convertible, but now has expected input units for Angstrom for all models and fitting succeeds without errors.Fixes #11547
Checklist for package maintainer(s)
This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive.
Extra CIlabel.no-changelog-entry-neededlabel. If this is a manual backport, use theskip-changelog-checkslabel unless special changelog handling is necessary.astropy-botcheck might be missing; do not let the green checkmark fool you.backport-X.Y.xlabel(s) before merge.