Fix Disk_on_sphere.evaluate() call with units #242
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
@PreisTo pointed out in the #238 that the following code using
dev(d756924) returns an unexpected result:It should be either
[1.04494972e+03 1.02116376e+01 9.97919231e-02] 1 / (keV s cm2 sr)or
[3.18309886e-01 3.11064269e-03 3.03983581e-05] 1 / (keV s cm2 deg2)The core of the bug is that the
Disk_on_spheredefinition::implies a conversion from a radius in degrees to rad, such that the result is in 1/sr. Because the extra factor (180/pi)^2 doesn't have units --i.e. deg2/sr-- astropy cannot get the right result by itself.
I modified the
Disk_on_sphere.evaluate()to recognize if the inputs have unit and perform the necessary conversion.Now the results are:
This fixes the bug when called with units, while keeping it backward compatible when called without units -- I think the (180/pi)^2 shouldn't even be there, but I wanted to keep thing backwards compatible. Maybe this could be fixed in a future major release.
I also did various tricks to limit the overhead from allowing input with and without units, as well as the overhead when actually calling with with unit. This is the benchmark:

And this the new version calling it without units (<10% overhead) and using units (almost 2x, mostly from

Quantity.__new__()). It's a small overhead on an already cheap operation, and it will be negligible for a call with multiple values.I think this shows that
Function.__call__()shouldn't be the one handling the units for performance reasons, but instead leaving it to the child classes to do it appropriately. I think it's less error prone and it's just as fast.Lastly, while this PR fixes the individual issue that @PreisTo brought up, the original issue in #238 remains:
ExtendedSourceis returning units of 1/sr by default, while the documentation and default units say it should be 1/deg2.