astropy icon indicating copy to clipboard operation
astropy copied to clipboard

Intermittent `ValueError` when converting from TEME to GCRS

Open astrojuanlu opened this issue 3 years ago • 2 comments

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

ValueError                                Traceback (most recent call last)
Input In [17], in <cell line: 11>()
      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 "<stdin>", line 1, in <module>
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

astrojuanlu avatar Jul 11 '22 10:07 astrojuanlu

xp, yp, status = iers_table.pm_xy(time, return_status=True)
...
ValueError: not enough values to unpack (expected 3, got 0)

I could get the same error but only if the function returns an empty string (not None nor a number). Under what condition would trigger such a return value? 🤔

pllim avatar Jul 11 '22 20:07 pllim

Okay, empty list or array would trigger the error too. Did you somehow got into this logic?

https://github.com/astropy/astropy/blob/19cc80471739bcb67b7e8099246b391c355023ee/astropy/utils/iers/iers.py#L400

pllim avatar Jul 11 '22 20:07 pllim