Astropy: get_moon does not support non-scalar times

Created on 10 Jun 2016  ·  3Comments  ·  Source: astropy/astropy

get_moon is only tested with scalar times, and fails for non-scalar times,

In [16]: import numpy as np

In [17]: from astropy.coordinates import get_moon

In [18]: from astropy.time import Time

In [19]: import astropy.units as u

In [20]: get_moon(Time.now() + np.linspace(0, 1)*u.day)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-7d6db65d30c7> in <module>()
----> 1 get_moon(Time.now() + np.linspace(0, 1)*u.day)

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/solar_system.py in get_moon(time, location, ephemeris)
    376     """
    377
--> 378     return get_body('moon', time, location=location, ephemeris=ephemeris)
    379
    380 get_moon.__doc__ += indent(_EPHEMERIS_NOTE)[4:]

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/solar_system.py in get_body(body, time, location, ephemeris)
    336         location = time.location
    337
--> 338     cartrep = _get_apparent_body_position(body, time, ephemeris)
    339     icrs = ICRS(cartrep)
    340     if location is not None:

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/solar_system.py in _get_apparent_body_position(body, time, ephemeris)
    283     # used.
    284     if ephemeris == 'builtin' and body.lower() == 'moon':
--> 285         return get_body_barycentric(body, time, ephemeris)
    286
    287     # Calculate position given approximate light travel time.

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/solar_system.py in get_body_barycentric(body, time, ephemeris)
    214             cartesian_position_body = earth_pv_bary[..., 0, :]
    215         elif body == 'moon':
--> 216             cartesian_position_body = calc_moon(time).cartesian.xyz.to(u.au).value
    217         else:
    218             sun_bary = earth_pv_bary[..., 0, :] - earth_pv_helio[..., 0, :]

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/orbital_elements.py in calc_moon(t)
    245                                           equinox=t)
    246
--> 247     return SkyCoord(ecliptic_coo.transform_to(ICRS))

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/baseframe.py in transform_to(self, new_frame)
    847             msg = 'Cannot transform from {0} to {1}'
    848             raise ConvertError(msg.format(self.__class__, new_frame.__class__))
--> 849         return trans(self, new_frame)
    850
    851     def is_transformable_to(self, new_frame):

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/transformations.py in __call__(self, fromcoord, toframe)
    913
    914             curr_toframe = t.tosys(**frattrs)
--> 915             curr_coord = t(curr_coord, curr_toframe)
    916
    917         # this is safe even in the case where self.transforms is empty, because

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/transformations.py in __call__(self, fromcoord, toframe)
    704
    705     def __call__(self, fromcoord, toframe):
--> 706         res = self.func(fromcoord, toframe)
    707         if not isinstance(res, self.tosys):
    708             raise TypeError('the transformation function yielded {0} but '

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/builtin_frames/ecliptic_transforms.py in geoecliptic_to_gcrs(from_coo, gcrs_frame)
     42 @frame_transform_graph.transform(FunctionTransform, GeocentricTrueEcliptic, GCRS)
     43 def geoecliptic_to_gcrs(from_coo, gcrs_frame):
---> 44     rmat = _ecliptic_rotation_matrix(from_coo.equinox)
     45     newrepr = cartrepr_from_matmul(rmat, from_coo, transpose=True)
     46     gcrs = GCRS(newrepr, obstime=from_coo.equinox)

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/builtin_frames/ecliptic_transforms.py in _ecliptic_rotation_matrix(equinox)
     27     rnpb = erfa.pnm06a(jd1, jd2)
     28     obl = erfa.obl06(jd1, jd2)*u.radian
---> 29     return np.asarray(np.dot(rotation_matrix(obl, 'x'), rnpb))
     30
     31

/Users/bmmorris/anaconda/lib/python3.5/site-packages/astropy-1.2.dev15671-py3.5-macosx-10.5-x86_64.egg/astropy/coordinates/angles.py in rotation_matrix(angle, axis, unit)
    716         return np.matrix(((1, 0, 0),
    717                           (0, c, s),
--> 718                           (0, -s, c)))
    719     else:
    720         axis = np.asarray(axis)

/Users/bmmorris/anaconda/lib/python3.5/site-packages/numpy/matrixlib/defmatrix.py in __new__(subtype, data, dtype, copy)
    268
    269         # now convert data to an array
--> 270         arr = N.array(data, dtype=dtype, copy=copy)
    271         ndim = arr.ndim
    272         shape = arr.shape

ValueError: setting an array element with a sequence.

This is a blocker on the astroplan switch from PyEphem to astropy solar system ephemerides (i.e. astropy/astroplan#35).

cc @StuartLittlefair @eteq

Affects-dev Bug coordinates

All 3 comments

@bmorris3 - in the mean time, to avoid this being a blocker, maybe you could make a wrapper around astropy's get_moon to automatically transform scalar times to 1-element arrays, then slice the result?

@bmorris3 I've submitted a PR to fix this issue (#5085). You may still find that you have issues because you cannot currently use non-scalar times and a non-geocentric observer. i.e

In [1]: times = Time(["2015-08-28 03:30", "2015-09-05 10:30"])

In [2]: coord.get_moon(times)
Out[2]: 
<SkyCoord (GCRS: obstime=['2015-08-28 03:30:00.000' '2015-09-05 10:30:00.000'], obsgeoloc=[ 0.  0.  0.] m, obsgeovel=[ 0.  0.  0.] m / s): (ra, dec, distance) in (deg, deg, AU)
    [(312.90593078, -13.48302806, 0.00243266),
     (71.86378932, 17.3464189, 0.0025424)]>

works fine, but

In [3]: lapalma = coord.EarthLocation.of_site('lapalma')

In [4]: coord.get_moon(times, location=lapalma)
-----------------------------------------------------------------
ValueError                      Traceback (most recent call last)
<ipython-input-4-b157ecbc7846> in <module>()
----> 1 coord.get_moon(times, location=lapalma)

/usr/local/lib/python3.5/site-packages/astropy/coordinates/solar_system.py in get_moon(time, location, ephemeris)
    378     """
    379 
--> 380     return get_body('moon', time, location=location, ephemeris=ephemeris)
    381 
    382 get_moon.__doc__ += indent(_EPHEMERIS_NOTE)[4:]

/usr/local/lib/python3.5/site-packages/astropy/coordinates/solar_system.py in get_body(body, time, location, ephemeris)
    344         gcrs = icrs.transform_to(GCRS(obstime=time,
    345                                       obsgeoloc=obsgeoloc,
--> 346                                       obsgeovel=obsgeovel))
    347     else:
    348         gcrs = icrs.transform_to(GCRS(obstime=time))

/usr/local/lib/python3.5/site-packages/astropy/coordinates/baseframe.py in __init__(self, *args, **kwargs)
    540 
    541             # Validate input by getting the attribute here.
--> 542             getattr(self, fnm)
    543 
    544         args = list(args)  # need to be able to pop them

/usr/local/lib/python3.5/site-packages/astropy/coordinates/baseframe.py in __get__(self, instance, frame_cls)
    210             out = self.default
    211 
--> 212         out, converted = self.convert_input(out)
    213         if instance is not None and converted:
    214             setattr(instance, '_' + self.name, out)

/usr/local/lib/python3.5/site-packages/astropy/coordinates/baseframe.py in convert_input(self, value)
    333                 raise ValueError('The provided value has shape "{0}", but '
    334                                  'should have shape "{1}"'.format(value.shape,
--> 335                                                                   self.shape))
    336             if (oldvalue.unit == value.unit and hasattr(oldvalue, 'value') and
    337                 np.all(oldvalue.value == value.value)):

ValueError: The provided value has shape "(3, 2)", but should have shape "(3,)"

clearly does not. A fix for #4926 is needed for the case above to work. I'll start on that next.

Note that I checked and @bmorris3's example now works with #5085 merged. @bmorris3, if the problem #4926 is addressing is affecting you feel free to open another issue on that!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

funbaker picture funbaker  ·  3Comments

JWDobken picture JWDobken  ·  3Comments

emilydeibert picture emilydeibert  ·  3Comments

Iko-7 picture Iko-7  ·  3Comments

simontorres picture simontorres  ·  3Comments