astropy / astropy/astropy

Intermittent `ValueError` when converting from TEME to GCRS

Open
#13,447 2 comments 0 reactions 0 assignees View on GitHub
Bug coordinates utils.iers
Dominant language
Python
Stars
5.3k
Forks
2.2k
Avg merge
1d 18h
Merged PRs (30d)
74

Description

### Description
I get an intermittent `ValueError` when converting from `TEME` to `GCRS` only on Read the Docs, so this is a bit difficult to reproduce.

### Expected behavior
`TEME` to `GCRS` always works.

### Actual behavior
```python
ValueError Traceback (most recent call last)
Input In [17], in ()
9 plotter.plot_ephem(iss_ephem, color="#333", label="ISS", trail=True)
11 for debris_fragment in islice(
12 load_gp_from_celestrak(name="COSMOS 1408 DEB"), 25
13 ):
---> 14 debris_ephem = ephem_from_gp(debris_fragment, epochs)
15 plotter.plot_ephem(
16 debris_ephem, color="#666", label=debris_fragment.satnum, trail=True
17 )
19 plotter.show()

Input In [14], in ephem_from_gp(sat, times)
19 times = times[errors == 0]
21 cart_teme = CartesianRepresentation(
22 rs << u.km,
23 xyz_axis=-1,
(...)
27 ),
28 )
29 cart_gcrs = (
---> 30 TEME(cart_teme, obstime=times)
31 .transform_to(GCRS(obstime=times))
32 .cartesian
33 )
35 return Ephem(cart_gcrs, times, plane=Planes.EARTH_EQUATOR)

File ~/checkouts/readthedocs.org/user_builds/poliastro/envs/v0.17.0/lib/python3.9/site-packages/astropy/coordinates/baseframe.py:1205, in BaseCoordinateFrame.transform_to(self, new_frame)
1203 msg = 'Cannot transform from {0} to {1}'
1204 raise ConvertError(msg.format(self.__class__, new_frame.__class__))
-> 1205 return trans(self, new_frame)

File ~/checkouts/readthedocs.org/user_builds/poliastro/envs/v0.17.0/lib/python3.9/site-packages/astropy/coordinates/transformations.py:1479, in CompositeTransform.__call__(self, fromcoord, toframe)
1476 frattrs[inter_frame_attr_nm] = attr
1478 curr_toframe = t.tosys(**frattrs)
-> 1479 curr_coord = t(curr_coord, curr_toframe)
1481 # this is safe even in the case where self.transforms is empty, because
1482 # coordinate objects are immutable, so copying is not needed
1483 return curr_coord

File ~/checkouts/readthedocs.org/user_builds/poliastro/envs/v0.17.0/lib/python3.9/site-packages/astropy/coordinates/transformations.py:1012, in FunctionTransformWithFiniteDifference.__call__(self, fromcoord, toframe)
1009 halfdt = dt/2
1011 from_diffless = fromcoord.realize_frame(fromcoord.data.without_differentials())
-> 1012 reprwithoutdiff = supcall(from_diffless, toframe)
1014 # first we use the existing differential to compute an offset due to
1015 # the already-existing velocity, but in the new frame
1016 fromcoord_cart = fromcoord.cartesian

File ~/checkouts/readthedocs.org/user_builds/poliastro/envs/v0.17.0/lib/python3.9/site-packages/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py:257, in teme_to_itrs(teme_coo, itrs_frame)
254 @frame_transform_graph.transform(FunctionTransformWithFiniteDifference, TEME, ITRS)
255 def teme_to_itrs(teme_coo, itrs_frame):
256 # use the pmatrix to transform to ITRS in the source obstime
--> 257 pmat = teme_to_itrs_mat(teme_coo.obstime)
258 crepr = teme_coo.cartesian.transform(pmat)
259 itrs = ITRS(crepr, obstime=teme_coo.obstime)

File ~/checkouts/readthedocs.org/user_builds/poliastro/envs/v0.17.0/lib/python3.9/site-packages/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py:34, in teme_to_itrs_mat(time)
30 gst = erfa.gmst82(*get_jd12(time, 'ut1'))
32 # Polar Motion
33 # Do not include TIO locator s' because it is not used in Vallado 2006
---> 34 xp, yp = get_polar_motion(time)
35 pmmat = erfa.pom00(xp, yp, 0)
37 # rotation matrix
38 # c2tcio expects a GCRS->CIRS matrix as it's first argument.
39 # Here, we just set that to an I-matrix, because we're already
40 # in TEME and the difference between TEME and CIRS is just the
41 # rotation by the sidereal time rather than the Earth Rotation Angle

File ~/checkouts/readthedocs.org/user_builds/poliastro/envs/v0.17.0/lib/python3.9/site-packages/astropy/coordinates/builtin_frames/utils.py:48, in get_polar_motion(time)
46 # Get the polar motion from the IERS table
47 iers_table = iers.earth_orientation_table.get()
---> 48 xp, yp, status = iers_table.pm_xy(time, return_status=True)
50 wmsg = (
51 'Tried to get polar motions for times {} IERS data is '
52 'valid. Defaulting to polar motion from the 50-yr mean for those. '
(...)
55 'version if necessary.'
56 )
57 if np.any(status == iers.TIME_BEFORE_IERS_RANGE):

ValueError: not enough values to unpack (expected 3, got 0)
```

The problem seems to be that the line `xp, yp, status = iers_table.pm_xy(time, return_status=True)` fails because `iers_table.pm_xy` returns an empty container:

```
>>> def f():
... return []
...
>>> xp, yp, status = f()
Traceback (most recent call last):
File "", line 1, in
ValueError: not enough values to unpack (expected 3, got 0)
```

### Steps to Reproduce
Comes from https://readthedocs.org/projects/poliastro/builds/17406672/, still don't know how to reproduce 😓

### System Details

Python 3.9.13 on Ubuntu 22.04. Relevant dependencies:

```
numpy-1.22.4
pyerfa-2.0.0.1
astropy-5.1
scipy-1.8.1
matplotlib-3.5.2
astroquery-0.4.6
```

Contributor guide

Open the contributing guide

Research direction

Start with astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py and utils.py, especially teme_to_itrs_mat() and get_polar_motion(), then inspect the IERS table's pm_xy() behavior. Try the linked poliastro Read the Docs build or an equivalent TEME-to-GCRS conversion and add coverage for the observed failure; done means the conversion no longer raises the unpacking ValueError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.