Skip to content

Conversation

@mhvk
Copy link
Contributor

@mhvk mhvk commented Apr 25, 2020

This is a follow-up of #9857 (EDIT: and builds upon it, hence the many commits), making also representations mutable. As commented there, representations themselves have no reason not to be mutable, since the behaviour of setting is well defined (in a way, they are just glorified quantities). Now that coordinates have become mutable, it makes little sense to keep the representations immutable.

I hope to follow this up with an DataInfo class such that representations can also be added to tables; without this, they would be second-class citizens. EDIT: now added

fixes #6447 (as a side effect)

@mhvk mhvk added this to the v4.1 milestone Apr 25, 2020
@astropy-bot astropy-bot bot added the table label Apr 25, 2020
@mhvk mhvk force-pushed the representations-mutable branch from 5d1ae83 to 6f60fa0 Compare April 25, 2020 11:02
@mhvk
Copy link
Contributor Author

mhvk commented Apr 25, 2020

@taldcroft - I think this is ready! Could you review? Especially the stuff related to table integration (i.e., info, small changes in operations.py and yaml.py).

@mhvk mhvk requested review from adrn, eteq and taldcroft April 26, 2020 15:39
Copy link
Member

@taldcroft taldcroft left a comment

Choose a reason for hiding this comment

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

This looks great from the table perspective, mostly minor comments.

return result


def representation_equal(rep1, rep2):
Copy link
Member

Choose a reason for hiding this comment

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

Makes me wonder if this should be __eq__ on the class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it should be, but I thought to leave that for another PR (#10154??), in particular as I am not quite sure yet what to do with class mismatches.

@taldcroft
Copy link
Member

None of this should be considered a blocker for this PR, but there are outstanding issues related to serialization that should either be fixed (as long as you are in the code) or transferred to separate issues:

The differentials are still not being serialized at all in a SkyCoord:

>>> yaml.load(yaml.dump(sc))  # Loses the differential
<SkyCoord (ICRS): (ra, dec, distance) in (deg, deg, Mpc)
    [(270., 30., 10.)]>

>>> sc = SkyCoord([270] * u.deg, [30] * u.deg, [10] * u.Mpc, radial_velocity=[20] * u.km / u.s)
>>> t = Table([sc])
>>> t.write('junk.ecsv', overwrite=True)
>>> t2 = Table.read('junk.ecsv')
>>> t2['col0']
<SkyCoord (ICRS): (ra, dec, distance) in (deg, deg, Mpc)
    [(270., 30., 10.)]>
>>> t['col0']
<SkyCoord (ICRS): (ra, dec, distance) in (deg, deg, Mpc)
    [(270., 30., 10.)]
 (radial_velocity) in km / s
    [(20.,)]>

For a representation in a table the differential is being serialized as an encoded binary numpy instead of getting dropped in as a SerializedColumn. From a quick look we would need a deeper structure for the column name like col0.differentials.s.d_x. What is confusing is that the x differential is called v_x on input but d_x in the differential. No idea what's happening there.

>>> sc = SkyCoord(x=[1]*u.pc, y=[2]*u.pc, z=[3]*u.pc,
... ...      v_x=[4]*u.km/u.s, v_y=[5]*u.km/u.s, v_z=[6]*u.km/u.s,
... ...      representation_type=CartesianRepresentation,
... ...      differential_type=CartesianDifferential)
...
>>> t = Table([sc.frame.data])
>>> t.write('junk_repr.ecsv', overwrite=True)
>>> cat junk_repr.ecsv
# %ECSV 0.9
# ---
# datatype:
# - {name: col0.x, unit: pc, datatype: float64}
# - {name: col0.y, unit: pc, datatype: float64}
# - {name: col0.z, unit: pc, datatype: float64}
# meta: !!omap
# - __serialized_columns__:
#     col0:
#       __class__: astropy.coordinates.representation.CartesianRepresentation
#       __info__: {unit: pc}
#       differentials:
#         s: !astropy.coordinates.CartesianDifferential
#           d_x: !astropy.units.Quantity
#             unit: !astropy.units.Unit {unit: km / s}
#             value: !numpy.ndarray
#               buffer: !!binary |
#                 QUFBQUFBQUFFRUE9
#               dtype: float64
#               order: C
#               shape: !!python/tuple [1]
#           d_y: !astropy.units.Quantity
#             unit: !astropy.units.Unit {unit: km / s}
#             value: !numpy.ndarray
#               buffer: !!binary |
#                 QUFBQUFBQUFGRUE9
#               dtype: float64
#               order: C
#               shape: !!python/tuple [1]
#           d_z: !astropy.units.Quantity
#             unit: !astropy.units.Unit {unit: km / s}
#             value: !numpy.ndarray
#               buffer: !!binary |
#                 QUFBQUFBQUFHRUE9
#               dtype: float64
#               order: C
#               shape: !!python/tuple [1]
#       x: !astropy.table.SerializedColumn
#         __class__: astropy.units.quantity.Quantity
#         unit: &id001 !astropy.units.Unit {unit: pc}
#         value: !astropy.table.SerializedColumn {name: col0.x}
#       y: !astropy.table.SerializedColumn
#         __class__: astropy.units.quantity.Quantity
#         unit: *id001
#         value: !astropy.table.SerializedColumn {name: col0.y}
#       z: !astropy.table.SerializedColumn
#         __class__: astropy.units.quantity.Quantity
#         unit: *id001
#         value: !astropy.table.SerializedColumn {name: col0.z}
# schema: astropy-2.0
col0.x col0.y col0.z
1.0 2.0 3.0

@mhvk
Copy link
Contributor Author

mhvk commented Apr 28, 2020

Thanks, I had started to notice that something was odd with differentials, but hadn't quite understood what was happening yet, so this is very helpful.

p.s. There also seems to be a strange problem with partial name clashes in serialized columns. If I can confirm that, I'll make it a separate issue, since it would need back-porting.

@mhvk
Copy link
Contributor Author

mhvk commented Apr 29, 2020

@taldcroft - OK, with your fix, I now could get the round-tripping in FITS/HDF5/ECSV to work. I think I also addressed all your comments, except that I couldn't easily get SkyCoord with differentials to work (or rather, I got half-way, but found that even when there is just a radial_velocity, magic pm_ra_cosdec and pm_dec appear; since this PR is big as is, I thought I better leave it as a separate issue...).

Copy link
Member

@adrn adrn left a comment

Choose a reason for hiding this comment

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

So far have only had a quick look, but 👍 to the idea! No obvious big comments from first look, and may not have time to do a deeper dive before end of tomorrow...

@mhvk
Copy link
Contributor Author

mhvk commented May 1, 2020

The failures are due to a strange but clearly temporary ability to fetch extension_helpers. I'll have another look at my own work here, and after that will restart CI just to be sure, and then merge.

Thanks, @adrn and @taldcroft for reviews. @eteq - time to speak up if you disagree with representations becoming settable is now...

@taldcroft
Copy link
Member

I'm seeing the same weird CI problems.

@pllim
Copy link
Member

pllim commented May 1, 2020

Re: CI -- downgrade doctestplus to 0.5 + pytest 5.3

@mhvk
Copy link
Contributor Author

mhvk commented May 1, 2020

@pllim - ah, good to know. Is it now fixed (is it you who restarted circle-ci? I don't seem to have permission myself)

@pllim
Copy link
Member

pllim commented May 1, 2020

I didn't touch it. 😄

@bsipocz
Copy link
Member

bsipocz commented May 1, 2020

ah, good to know. Is it now fixed (is it you who restarted circle-ci? I don't seem to have permission myself)

I think everyone with write access should have the power for circleCI. But you need to log-in with github to circleCI, and maybe also watch the repo.

There should not be any failure any more as part of an upstream hackery I reverted the doctestplus release that was causing the trouble.

@mhvk
Copy link
Contributor Author

mhvk commented May 1, 2020

Darn, the windows run consistently hangs in test_io_fast_c_reader. Anybody any ideas?

@pllim
Copy link
Member

pllim commented May 1, 2020

windows run consistently hangs

Try run it with pytest-faulthandler.

@mhvk mhvk force-pushed the representations-mutable branch from 3aaa7d6 to d271991 Compare May 2, 2020 00:34
@mhvk
Copy link
Contributor Author

mhvk commented May 2, 2020

OK, travis is now running (and logging out and back in again to circle-CI meant I could indeed cancel).

@mhvk
Copy link
Contributor Author

mhvk commented May 2, 2020

And now I have to wait for the travis time-out... I hope this isn't going to take a number of iterations!

@mhvk
Copy link
Contributor Author

mhvk commented May 2, 2020

Hmm, that didn't help: still get

..\..\.tox\py37-test-alldeps\lib\site-packages\astropy\io\ascii\tests\test_c_reader.py x [ 17%]

..x.x.x.x.x.x.x.x.x.x.x.x...x................x.x.x.x.x.x.x.

No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.

Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#build-times-out-because-no-output-was-received

The build has been terminated

From trying to count tests, I think it is

def test_fast_reader():

so I'll go ahead and just try skipping this.

This is painful! I hate windows and hard-to-debug stuff due to compiled code!

@mhvk mhvk force-pushed the representations-mutable branch from d271991 to 27983b5 Compare May 2, 2020 00:58
@mhvk
Copy link
Contributor Author

mhvk commented May 2, 2020

OK, I'm getting too annoyed and tired for my own good, so leaving this to tomorrow. It was approved already so hopefully this can be treated as "bug fix" (wish I even had a clue why the fast c reader cared about anything I did...)

@pllim

This comment has been minimized.

@pllim

This comment has been minimized.

@pllim

This comment has been minimized.

@pllim
Copy link
Member

pllim commented May 2, 2020

p.s. I don't think remote data failures are related but you should double check.

@mhvk
Copy link
Contributor Author

mhvk commented May 2, 2020

Wow, @pllim, that was some dedicated sleuthing! Thanks, so much!

As you note, the remote-date failures are all unrelated, so I'll go ahead and merge. It must still be friday somewhere...

@mhvk mhvk merged commit 5ff936b into astropy:master May 2, 2020
@mhvk mhvk deleted the representations-mutable branch May 2, 2020 08:43
@taldcroft
Copy link
Member

taldcroft commented May 2, 2020

@mhvk - this PR is breaking my local astropy. I get this from a clean build of astropy with this PR merged, and do not see a problem beforehand. This is with numpy 1.18.1.

In [1]: astro                                                                                                                                                 
astropy=4.1.dev1333+g27983b59c
/Users/aldcroft/git/astropy/astropy/table/column.py:1020: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
  result = getattr(super(), op)(other)
Downloading https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat
|========================================================================================================================| 1.3k/1.3k (100.00%)         0s
Downloading https://www.ietf.org/timezones/data/leap-seconds.list
|========================================================================================================================|  10k/ 10k (100.00%)         0s
WARNING: IERSStaleWarning: leap-second file is expired. [astropy.utils.iers.iers]
Darwin-19.2.0-x86_64-i386-64bit
Python 3.6.10 |Anaconda, Inc.| (default, Jan  7 2020, 15:01:53) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
Numpy 1.18.1
astropy 4.1.dev1494+g5ff936bd2
Scipy 1.4.1

Slightly OT, but the whole leap second download stuff still seems to be a source of really inscrutable problems. I really think it would be worth something like a config option to say "Don't ever try leap second downloads". I use astropy on mission-critical and non-networked computers, and I don't want it failing on that account.

@pllim
Copy link
Member

pllim commented May 2, 2020

Re: FutureWarning -- Hmm, why didn't the CI catch it?

@taldcroft
Copy link
Member

Another manifestation:

(astropy) ➜  astropy git:(5ff936bd2) pytest astropy/io/ascii
==================================================================== test session starts =====================================================================
platform darwin -- Python 3.6.10, pytest-5.3.5, py-1.8.1, pluggy-0.13.1

Running tests with Astropy version 4.1.dev1494+g5ff936bd2.
Running tests in astropy/io/ascii.

Date: 2020-05-02T11:53:44

Platform: Darwin-19.2.0-x86_64-i386-64bit

Executable: /Users/aldcroft/miniconda3/envs/astropy/bin/python

Full Python Version: 
3.6.10 |Anaconda, Inc.| (default, Jan  7 2020, 15:01:53) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]

encodings: sys: utf-8, locale: UTF-8, filesystem: utf-8
byteorder: little
float info: dig: 15, mant_dig: 15

Package versions: 
Numpy: 1.18.1
Scipy: 1.4.1
Matplotlib: 3.1.3
h5py: 2.10.0
Pandas: 1.0.0
Cython: not available
Scikit-image: 0.16.2
asdf: 2.6.0

Using Astropy options: remote_data: none.

rootdir: /Users/aldcroft/git/astropy, inifile: setup.cfg
plugins: arraydiff-0.3, remotedata-0.3.2, hypothesis-5.4.1, openfiles-0.4.0, xdist-1.31.0, filter-subpackage-0.1.1, forked-1.1.3, doctestplus-0.5.0, astropy-header-0.1.2, cov-2.8.1, asdf-2.6.0
collected 576 items / 1 error / 575 selected                                                                                                                 

=========================================================================== ERRORS ===========================================================================
_______________________________________________________ ERROR collecting astropy/io/ascii/__init__.py ________________________________________________________
astropy/time/core.py:2592: in update_leap_seconds
    table = iers.LeapSeconds.auto_open(files)
astropy/utils/iers/iers.py:1027: in auto_open
    warn('leap-second file is expired.', IERSStaleWarning)
E   astropy.utils.iers.iers.IERSStaleWarning: leap-second file is expired.

During handling of the above exception, another exception occurred:
astropy/io/ascii/__init__.py:7: in <module>
    from .core import (InconsistentTableError,
astropy/io/ascii/core.py:30: in <module>
    from astropy.table import Table
astropy/table/__init__.py:54: in <module>
    from .serialize import SerializedColumn, represent_mixins_as_columns
astropy/table/serialize.py:10: in <module>
    from astropy.coordinates import representation as coorep
astropy/coordinates/__init__.py:16: in <module>
    from .builtin_frames import *
astropy/coordinates/builtin_frames/__init__.py:29: in <module>
    from .fk5 import FK5
astropy/coordinates/builtin_frames/fk5.py:8: in <module>
    from astropy.coordinates import earth_orientation as earth
astropy/coordinates/earth_orientation.py:19: in <module>
    jd1950 = Time('B1950').jd
astropy/time/core.py:395: in __new__
    update_leap_seconds()
astropy/time/core.py:2597: in update_leap_seconds
    f"exception: {exc!r}", AstropyWarning)
E   astropy.utils.exceptions.AstropyWarning: leap-second auto-update failed due to the following exception: IERSStaleWarning('leap-second file is expired.',)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
====================================================================== 1 error in 1.86s ======================================================================

@taldcroft
Copy link
Member

So the question is if anyone else can reproduce this or if it's just me.

@mhvk
Copy link
Contributor Author

mhvk commented May 2, 2020

I don't see how this could be related to this PR - but agree with the sentiment that the LeapSecond stuff is too fragile -- #9479. I'd very much appreciate help in trying to get it better!! While writing it, I found myself in an awful circular import morass between iers needing Time, and Time needing iers. I think for tests we should silence the stale-warning, since it is now turned into an error (which didn't use to be the case when I wrote the stuff).

It is possible to avoid any download with iers.config.auto_download=False (but this has to be done in the astropy config, since even importing iers already causes problems...).

from .column import Column
from .table import Table, QTable, has_info_class
from astropy.units.quantity import QuantityInfo
from astropy.coordinates import representation as coorep
Copy link
Member

Choose a reason for hiding this comment

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

After much flailing I finally figured out that this line is what is breaking things and causing all the confusing problems for me with warnings and test fails and leap seconds re-downloading every time. It is tricky because of circular imports, so the problem only shows up in a certain import order. You should be able to reproduce with a single import astropy.io.ascii without anything first. But import astropy.coordinates; import astropy.io.ascii is fine. And import astropy.table first gives /Users/aldcroft/git/astropy/astropy/table/column.py:1020: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison result = getattr(super(), op)(other)

This is latter warning is from the leap second stuff, and goes away if I remove this line here in serialize.py.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Darn, that must be because it imports Time - I'm sorry that I've caught all this mess, @pllim already had to move other imports inline to get things to pass.

Copy link
Member

Choose a reason for hiding this comment

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

I suggest a quick workaround to hardcode as strings all the representations currently in astropy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, will make a PR. Clearly trying to be clever comes back to haunt oneself...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See #10282

astrofrog added a commit that referenced this pull request Aug 17, 2021
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.

Differential frame attributes can't be serialized to YAML

5 participants