Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for gc2gde and gd2gce erfa functions in units. #14729

Merged
merged 2 commits into from May 5, 2023

Conversation

cmarmo
Copy link
Member

@cmarmo cmarmo commented May 1, 2023

Description

This pull request adds support for gc2gde and gd2gce erfa functions in units.
Tests are added.

Follows the suggestion in #14714 (review).

Towards #11170.

Thanks for considering it.

This work is funded by the Europlanet 2024 Research Infrastructure (RI) Grant.

@github-actions
Copy link

github-actions bot commented May 1, 2023

Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.

  • Do the proposed changes actually accomplish desired goals?
  • Do the proposed changes follow the Astropy coding guidelines?
  • Are tests added/updated as required? If so, do they follow the Astropy testing guidelines?
  • Are docs added/updated as required? If so, do they follow the Astropy documentation guidelines?
  • Is rebase and/or squash necessary? If so, please provide the author with appropriate instructions. Also see "When to rebase and squash commits".
  • Did the CI pass? If no, are the failures related? If you need to run daily and weekly cron jobs as part of the PR, please apply the "Extra CI" label. Codestyle issues can be fixed by the bot.
  • Is a change log needed? If yes, did the change log check pass? If no, add the "no-changelog-entry-needed" label. If this is a manual backport, use the "skip-changelog-checks" label unless special changelog handling is necessary.
  • Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied?
  • Is a milestone set? Milestone must be set but we cannot check for it on Actions; do not let the green checkmark fool you.
  • At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate "backport-X.Y.x" label(s) before merge.

@cmarmo
Copy link
Member Author

cmarmo commented May 2, 2023

Note that I can't reproduce the coverage failure locally ... any suggestion is welcome! Thanks!

@pllim pllim added this to the v6.0 milestone May 2, 2023
@pllim pllim requested a review from mhvk May 2, 2023 04:21
@pllim
Copy link
Member

pllim commented May 2, 2023

The coverage failure was because coverage report upload fails. Happens once in a while.

Still needs a change log. Thanks!

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! A few comments on the implementation...

@@ -117,6 +134,24 @@ def helper_gd2gc(f, nounit, unit1, unit2, unit3):
)


def helper_gd2gce(f, unit1, dimensionless_unscaled, unit2, unit3, unit4):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it should just enumerate all units - including that for flattening.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks and sorry, now I better understand what dimensionless_unscaled is...

try:
return [
get_converter(unit1, m),
None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and then here add get_converter(unit2, dimensionless_unscaled)

], (m, None)
except Exception as exc:
raise UnitTypeError(
f"Can only apply '{f.__name__}' function to lon, lat "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking through the other functions in this file, I see that normally no try/except was done. I think the only reason I did it for the gc2gd and gd2gc ones is that those functions are special in that they also take an integer, i.e., not a Quantity. So, I think it is actually fine to remove the try/except here and just let the get_converter functions give out their own error messages as needed. (As done for helper_s2pv, e.g.)

@@ -98,6 +99,22 @@ def helper_gc2gd(f, nounit, unit1):
)


def helper_gc2gde(f, unit1, dimensionless_unscaled, unit2):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like below, enumerate all units, and have get_converter(unit2, dimensionless_unscaled) below.

By the way, feel free to give the units more meaningful names - I know I didn't do it for many functions but I changed later (see, e.g., helper_s2pv).

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, a few more comments. Some noting that really the existing code can use a bit of improvement... Sigh...

def helper_gc2gde(f, unit_r, unit_flat, unit_xyz):
from astropy.units.si import m, radian

if unit_r is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is necessary - just let get_converter handle this!

I realize the error messages may not be ideal, but I think it may be better in that case to try to improve get_converter -- but in a different PR!

def helper_gd2gce(f, unit_r, unit_flat, unit_long, unit_lat, unit_h):
from astropy.units.si import m, radian

if unit_r is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, just keep it simple!


if unit_r is None:
raise UnitTypeError("Equatorial radius should have length units.")
unit_flat = unit_r / unit_r
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary? You are overriding the input unit (which might be, say, u.percent, which could be converted to dimensionless_unscaled)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, understood: this was the reason of the error on unit_r being managed separately.
I'm going to remove it then the check on unit_r will go too.

self.lat,
self.height,
)
msg = "'NoneType' object has no attribute '_get_converter'"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually a pretty terrible error message! I think I definitely see a point now of trying to do better - but let's do so in a different PR!

@cmarmo
Copy link
Member Author

cmarmo commented May 2, 2023

@mhvk I just realized that the erfa.eform function (which I need to retrieve the ellipsoid parameters from the standard string, when addressing the item .2.) does not have its own helper.
I'm going to add it here too if this is ok for you.

@cmarmo cmarmo changed the title Add support for gc2gde and gd2gce erfa functions in units. Add support for eform, gc2gde and gd2gce erfa functions in units. May 3, 2023
def helper_eform(f, nounit):
if nounit is not None:
raise UnitTypeError("Ellipsoid cannot be a quantity.")
return [None], (None, None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to add coverage for eform too! But this doesn't seem right: the equatorial radius and flattening do have units: (m, dimensionless_unscaled) (and from astropy.units.si import m above)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my first try... I couldn't make it work.
No matter how I changed the output dimensions, eform always gives me a-dimensional outputs...
I have pushed the "dimensional" version for you to check... I'm probably missing something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it actually makes sense - I should have thought of this! The overrides only work if one puts in a Quantityas input (or output). Without that, the ufunc has no way to know a Quantity is expected and therefore just acts as if it regular ndarray input. We can actually not change this in astropy in any simple way.

In principle, the helper function will only be called if you put in a Quantity to hold the output. This is not in itself bad, but also not super useful. Perhaps the simplest right now is to just remove this again from the PR, and then in the next PR just work with the raw version, i.e., call it and then turn the output into Quantity there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the simplest right now is to just remove this again from the PR, and then in the next PR just work with the raw version, i.e., call it and then turn the output into Quantity there.

Thanks for your explanation! Makes sense... :)
Just to be sure: you mean I should go back to 34b642f or completely remove eform from the helpers? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove it altogether for now - I think it needs more thought, but is not essential for BodyLocation, but rather an implementation detail.

@cmarmo cmarmo changed the title Add support for eform, gc2gde and gd2gce erfa functions in units. Add support for gc2gde and gd2gce erfa functions in units. May 4, 2023
@cmarmo
Copy link
Member Author

cmarmo commented May 4, 2023

I have removed eform from this pull request, synchronized with main and squashed the commits.
Thanks for your patience.

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, really, thanks for your patience! I have some final nitpicks, but am approving already, since things look good!


msg = "'NoneType' object has no attribute '_get_converter'"
xyz = np.array([self.x_value, self.y_value, self.z_value]) << self.length_unit
status = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to set status = 0 beforehand, since you're not passing it in. Indeed, since we're just looking for the error message, you can just call the ufunc without assigning to any outputs.

"""Test unit errors when dimensionless parameters are used"""

msg = "'NoneType' object has no attribute '_get_converter'"
xyz = np.array([self.x_value, self.y_value, self.z_value]) << self.length_unit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Real nitpick, but might as well do xyz = np.stack([self.x, self.y, self.z]).
Indeed, since you use it multiple times, might as well define it in setup_class

self.lat,
self.height,
)
xyz = np.array([self.x_value, self.y_value, self.z_value])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continuing with nitpicks, how about removing this and instead do xyz.value in the call below?

@cmarmo
Copy link
Member Author

cmarmo commented May 4, 2023

nitpicks addressed... :)

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, all good now - let get it in! Thanks!!

@mhvk mhvk merged commit 96df795 into astropy:main May 5, 2023
24 of 25 checks passed
@cmarmo
Copy link
Member Author

cmarmo commented May 5, 2023

Wonderful! Thanks! 🤗 🥳

@cmarmo cmarmo deleted the erfa-ufunc-units branch May 5, 2023 18:32
@pllim
Copy link
Member

pllim commented May 6, 2023

From the sidelines, I really appreciate all these non-trivial fixes both in FITS and coordinates, @cmarmo ! Looking forward to more. 👏

@pllim
Copy link
Member

pllim commented May 6, 2023

Europlanet 2024 Research Infrastructure (RI) Grant

This is amazing! I am so glad to see more grants agreeing to invest dev time into the Project. cc @astropy/coordinators

@cmarmo
Copy link
Member Author

cmarmo commented May 6, 2023

This is amazing! I am so glad to see more grants agreeing to invest dev time into the Project

This was possible thanks to @Erard and the involvement of the Observatoire de Paris in the Europlanet project. 🙏

@hamogu
Copy link
Member

hamogu commented Jun 12, 2023

This work is funded by the Europlanet 2024 Research Infrastructure (RI) Grant.

It's great that funded projects contribute to astropy. That's exactly how Open source is supposed to work and we welcome your contributions. I'm just commenting here to let you know that you of course you are also welcome to connect on slack, on the astropy-dev mailing list or by email to the Coordination Committee if you ever need something "official looking" for e.g. a grant proposal.

@cmarmo
Copy link
Member Author

cmarmo commented Jun 14, 2023

Thanks @hamogu!
Apparently I cannot create an account on slack as I don´t have the right domain... :)
I may need an invitation? Thanks!

@hamogu
Copy link
Member

hamogu commented Jun 14, 2023

Maybe the slack link expired. I'll check with the slack admins and get back to you.

@hamogu
Copy link
Member

hamogu commented Jun 14, 2023

Can you try: http://joinslack.astropy.org/ ?

@cmarmo
Copy link
Member Author

cmarmo commented Jun 14, 2023

That worked! Thanks a lot!

Maybe the slack link expired.

...my bad for being off-line for some time...

@hamogu
Copy link
Member

hamogu commented Jun 14, 2023

I think I just linked the wrong link in #14729 (comment)
Since I'm signed up already, I did not notice the difference between sign-in and sign-up. Sorry ;-)
But I'm glad it worked!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants