Intermittent `ValueError` when converting from TEME to GCRS
- 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
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