Skip to content

Parse CDS units with Unit 'cds' format. - #7348

Merged
taldcroft merged 7 commits into
astropy:masterfrom
kyleaoman:cds-tables-units
Aug 22, 2018
Merged

taldcroft merged 7 commits into
astropy:masterfrom
kyleaoman:cds-tables-units

Conversation

@kyleaoman

Copy link
Copy Markdown
Contributor

The astropy.units.Unit class has an option 'format' in the constructor which accepts a parameter 'cds' so that units formatted conforming to the CDS standard can be parsed correctly. This change sets the column units of the read table using this feature. Previously, the columns of the read table would have units of type UnrecognizedUnit (basically a glorified string) in many cases - I stumbled on this when trying to read a table with a column in GMsun (giga-solar-masses). I believe this should be fully backwards-compatible from a user point of view.

The following snippet will fail before this change, and succeed after:

from astropy.io import ascii
import astropy.units as u

reader = ascii.get_reader(ascii.Cds, readme='ftp://cdsarc.u-strasbg.fr/pub/cats/J/AJ/152/157/ReadMe')
SPARC = reader.read('ftp://cdsarc.u-strasbg.fr/pub/cats/J/AJ/152/157/table1.dat')
print(SPARC['MHI'].to(u.solMass))

@astropy-bot

astropy-bot Bot commented Apr 4, 2018 •

Copy link
Copy Markdown

Hi there @kyleaoman 👋 - thanks for the pull request! I'm just a friendly 🤖 that checks for issues related to the changelog and making sure that this pull request is milestoned and labeled correctly. This is mainly intended for the maintainers, so if you are not a maintainer you can ignore this, and a maintainer will let you know if any action is required on your part 😃.

Everything looks good from my point of view! 👍

If there are any issues with this message, please report them here.

@bsipocz bsipocz added this to the v3.1 milestone Apr 4, 2018
@astrofrog
astrofrog requested a review from taldcroft August 4, 2018 12:38
@astrofrog

Copy link
Copy Markdown
Member

@kyleaoman - can you add the example you mention as a unit test for the CDS reader?

@kyleaoman

Copy link
Copy Markdown
Contributor Author

Added a test. I merged changes from astropy/master in my branch a while ago, which I now see from the instructions was a bad idea.

@kyleaoman

Copy link
Copy Markdown
Contributor Author

The change to the cds unit parsing seems to break some other tests, this will need to be looked into...

@bsipocz

bsipocz commented Aug 7, 2018

Copy link
Copy Markdown
Member

@kyleaoman - If you could rebase that would be the way to get rid of the merge issues. I'm happy to help with it if needed, just ping me on slack.

@kyleaoman
kyleaoman force-pushed the cds-tables-units branch 2 times, most recently from 53eddbc to 9701dc9 Compare August 7, 2018 15:04
@kyleaoman

Copy link
Copy Markdown
Contributor Author

@astrofrog added the test, checked that it fails before and passes after. Also cleaned up a bit with help from @bsipocz . There are a couple of other tests that now fail, which I'm having some trouble diagnosing. If one of you can help, or can ping someone else who can, that would be much appreciated.

kyleaoman added a commit to kyleaoman/astropy that referenced this pull request Aug 8, 2018
Corrects a failed test after changes in PR astropy#7348. The CDS
specification accepts both 'arcs' and 'arcsec' for arcseconds (and
similarly for arcminutes), see
http://vizier.u-strasbg.fr/cgi-bin/Unit. 'arcsec' seems to be the
preferred form (http://cds.u-strasbg.fr/doc/catstd-3.2.htx, but
an argument could be made the other way via 'rule 2' on that page)
so make that the default string representation.
@kyleaoman

Copy link
Copy Markdown
Contributor Author

Seem to have sorted out the issues with failing tests. Looks like all that's missing is a review from @taldcroft.

Comment thread astropy/io/ascii/cds.py Outdated
col.unit = None # "---" is the marker for no unit in CDS table
else:
try:
col.unit = Unit(unit, format='cds')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure we should fail on the unit not parsing correctly - that forces the user to edit the files they downloaded. Instead, I would suggest to follow the fits example and just add parse_strict='warn' or even parse_strict='silent' (which means one get UnrecognizedUnit after all, but of course only for those units that are, in fact, not recognized).

But best to cc @taldcroft, since he will have a better idea about what the standard is in io.ascii (perhaps there is a keyword argument already for it??).

@kyleaoman

Copy link
Copy Markdown
Contributor Author

I agree that a warning makes more sense than an error if a unit fails to parse. A user can always suppress a warning if they want it to be silent. @taldcroft hopefully this is ready for merge now?

@kyleaoman

Copy link
Copy Markdown
Contributor Author

Hm, this 'coverage/coveralls' check is new to me... what exactly should be done to fix that?

assert iers_tab['UT1_UTC'].unit is u.second
assert iers_tab['PM_x'].unit is u.arcsecond
assert iers_tab['PM_y'].unit is u.arcsecond
assert (iers_tab['UT1_UTC'].unit / u.second).is_unity()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Humm, this is slightly disconcerting. I see the nice commit description that points to why this change was made. For example:

In [5]: u.s is u.Unit('s')
Out[5]: True

In [6]: u.s is u.Unit('s', format='cds')
Out[6]: False

In [7]: u.s / u.s
Out[7]: Unit(dimensionless)

In [8]: u.s / u.Unit('s', format='cds')
Out[8]: Unit("s / s")

I had imagined that the unit format implies how to parse the unit string (or combinations thereof), but that the fundamental units coming out were the same thing. Not so apparently?

So this does imply some risk of breaking code with this PR. Thoughts @mhvk?

@taldcroft

Copy link
Copy Markdown
Member

@kyleaoman - I think for this change it is not necessary to include the two new (large-ish) test files. You could instead just modify the following one to set a unit of GMsun for the Fit column.

https://github.com/astropy/astropy/blob/master/astropy/io/ascii/tests/t/cds.dat#L27

You should rebase away those files (basically git rebase -i .. and squash away 9701dc9, then re-add your new test using the existing (but modified cds.dat). That way you can keep all the original commits and messages. Let me know if this isn't clear.

@taldcroft

Copy link
Copy Markdown
Member

As noted by the bot, you need to put in a changelog entry for this. I am labeling this as a bug fix because CDS units should be correctly parsed by the CDS reader, so the entry would go in the bug fix section.

However, it is not obvious to me that this is fully backwards compatible because of the issue with units, so as it stands this should NOT be backported.

@taldcroft

Copy link
Copy Markdown
Member

@kyleaoman - apart from the little technical issues, this looks good, thanks for the contribution!

@mhvk

mhvk commented Aug 21, 2018

Copy link
Copy Markdown
Contributor

That cds s is not the same as regular s is really annoying, and should be fixed! I am traveling so don't immediately have time to investigate, but:

In [4]: u.s / u.Unit(str(u.Unit('s', format='cds')))
Out[4]: Unit(dimensionless)

@taldcroft - could you raise a new issue?

@taldcroft

Copy link
Copy Markdown
Member

@mhvk - OK, issue raised in #7751. If that can fixed then this PR would truly be back-compatible and could presumably be back-ported (assuming the #7751 fix could be back-ported as well).

kyleaoman added a commit to kyleaoman/astropy that referenced this pull request Aug 21, 2018
Corrects a failed test after changes in PR astropy#7348. The CDS
specification accepts both 'arcs' and 'arcsec' for arcseconds (and
similarly for arcminutes), see
http://vizier.u-strasbg.fr/cgi-bin/Unit. 'arcsec' seems to be the
preferred form (http://cds.u-strasbg.fr/doc/catstd-3.2.htx, but
an argument could be made the other way via 'rule 2' on that page)
so make that the default string representation.
@kyleaoman

Copy link
Copy Markdown
Contributor Author

@taldcroft Alright, think all the requested changes are handled, and everything checks out on the automated tests now.

Comment thread astropy/io/ascii/setup_package.py Outdated
't/fixed_width_2_line.txt',
't/cds/description/ReadMe',
't/cds/description/table.dat',
't/cds/units/ReadMe',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This needs to be reverted.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reverted.

Corrects a failed test after changes in PR astropy#7348. The CDS
specification accepts both 'arcs' and 'arcsec' for arcseconds (and
similarly for arcminutes), see
http://vizier.u-strasbg.fr/cgi-bin/Unit. 'arcsec' seems to be the
preferred form (http://cds.u-strasbg.fr/doc/catstd-3.2.htx, but
an argument could be made the other way via 'rule 2' on that page)
so make that the default string representation.
Comparisons fail with some units parsed from strings, some
examples are below. I think the last should be preferred.
u.Unit('s') is u.Unit('second') # True
u.Unit('s') is u.Unit('sec', format='cds') # False
u.Unit('s') is u.Unit('sec', format='cds').represents # True
u.ms is u.Unit('ms', format='cds').represents # False
(u.ms / u.Unit('ms', format='cds')).is_unity() # True
Added a bogus unit to an existing sample CDS format file to test
parsing of cds-formatted units. Adjusted unrelated test which
uses the same file.
@kyleaoman

Copy link
Copy Markdown
Contributor Author

@taldcroft and done.

@taldcroft taldcroft left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @kyleaoman ! Definitely appreciate getting help here to get the details just right.

@taldcroft
taldcroft merged commit 7fe4970 into astropy:master Aug 22, 2018
@kyleaoman
kyleaoman deleted the cds-tables-units branch August 22, 2018 11:30
astromancer pushed a commit to astromancer/astropy that referenced this pull request Sep 18, 2018
Corrects a failed test after changes in PR astropy#7348. The CDS
specification accepts both 'arcs' and 'arcsec' for arcseconds (and
similarly for arcminutes), see
http://vizier.u-strasbg.fr/cgi-bin/Unit. 'arcsec' seems to be the
preferred form (http://cds.u-strasbg.fr/doc/catstd-3.2.htx, but
an argument could be made the other way via 'rule 2' on that page)
so make that the default string representation.
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.

5 participants