Skip to content

scalar Time + multidimensional Quantity = error #3039

Closed

Description

@bnordgren

Adding a Time and Quantity works when the Quantity is a scalar and a 1D vector. If the Quantity array is reshaped to a 2D array, an OperandTypeError is thrown.

import astropy.coordinates as c
import astropy.time as t
import astropy.units as u
import numpy as np
base_date = t.Time('2014-01-01')
offsets = np.arange(0,10) * u.day
offsets
Out[7]: <Quantity [ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.] d>
base_date + offsets
Out[8]: 
<Time object: scale='utc' format='iso' value=['2014-01-01 00:00:00.000' '2014-01-02 00:00:00.000'
 '2014-01-03 00:00:00.000' '2014-01-04 00:00:00.000'
 '2014-01-05 00:00:00.000' '2014-01-06 00:00:00.000'
 '2014-01-07 00:00:00.000' '2014-01-08 00:00:00.000'
 '2014-01-09 00:00:00.000' '2014-01-10 00:00:00.000']>
offsets.reshape( (2,5))
Out[9]: 
<Quantity [[ 0., 1., 2., 3., 4.],
       [ 5., 6., 7., 8., 9.]] d>
base_date + offsets.reshape((2,5))
---------------------------------------------------------------------------
OperandTypeError                          Traceback (most recent call last)
<ipython-input-10-4402dbceaf11> in <module>()
----> 1 base_date + offsets.reshape((2,5))

C:\Users\bnordgren\AppData\Local\Enthought\Canopy\User\lib\site-packages\astropy\time\core.pyc in __add__(self, other)
    993                 other = TimeDelta(other)
    994             except:
--> 995                 raise OperandTypeError(self, other, '+')
    996 
    997         # Tdelta + something is dealt with in TimeDelta, so we have

OperandTypeError: Unsupported operand type(s) for +: 'Time' and 'Quantity' 

Activity

  1. cheekujodhpur commented on Oct 19, 2014

    @cheekujodhpur

    Not too hard to solve by modifying the init for class TimeDelta. There are however two ways where your ideal output could go:

    1. An array of Time objects, each corresponding to a row in offsets
    2. A single Time object with value as a 2x5 array

    No.1 seems more intuitive to me. But I feel a discussion would help

  2. bnordgren commented on Oct 19, 2014

    @bnordgren
    ContributorAuthor

    I was expecting No. 2 because (as a user), I thought that Time should be able to do anything that Quantity (and other numpy ndarrays) can do. In any case, the above error message is not at all helpful. I was tracking all over my code trying to figure out what broke this equation (which I didn't touch.)

    The big win with No. 2 is the ability to write array equations which are the same regardless of dimensionality. For instance, a function or method which calculates something for a point does not need to be rewritten for use on a vector, and also does not need to be rewritten for use on a grid. For me, at least, I test equations using a point, then apply them to vector or grid data. Writing special cases for different dimensionality is irritating busywork, and leads to less maintainable code should you discover an error after you've implemented 3 versions. :)

    My workaround is to reshape the offset array into a vector, then three or four steps later reshape a Quantity vector back into the original shape. This is OK if it can all be handled inside the same function/method, but is likely to lead to buggy code if the function/method has to return a Time vector without an indicator of the original shape.

    The application, in this case, is an implementation of Meeus's rise/set/transit algorithm from "Astronomical Algorithms", 2nd ed. Each observing location (row) has three times (columns) associated with it. I discovered this issue when I tried to make the code work with a vector of observing locations instead of a single point.

  3. mhvk commented on Oct 19, 2014

    @mhvk
    Contributor

    @bnordgren - the problem here is that Time does not allow multidimensional data:

    In [1]: from astropy.units import Quantity; from astropy.time import TimeDelta
    
    In [2]: q = Quantity([[2., 3., 4.], [5., 6., 7.]], 's')
    
    In [3]: q
    Out[3]: 
    <Quantity [[ 2., 3., 4.],
               [ 5., 6., 7.]] s>
    
    In [4]: TimeDelta(q)
    .
    .
    .
    TypeError: Input val must be zero or one dimensional
    

    In principle, this should not be that difficult to change, as the times are internally stored as two-part julian dates, jd1 and jd2, which are both ndarray and thus can have arbitrary dimension. The main issue is that it needs some thought on how to pass higher-dimensional arrays to the ERFA routines that do the actual conversion between timescales, etc. Still, with suitable .ravel() and .reshape calls this should be do-able...

    @eteq, @taldcroft - will #2992 help with this?

  4. cheekujodhpur commented on Oct 19, 2014

    @cheekujodhpur

    Yes, I did not realize the suitability to specific applications.

    I would like to start workin' on this, testin' a few ideas while we wait for more input

  5. mhvk commented on Oct 19, 2014

    @mhvk
    Contributor

    @cheekujodhpur - would be great! The actual check is done in _make_1d_array in astropy/time/core.py. Unless the new erfa routines can take multidimensional arrays (perhaps unlikely), all the calls to erfa need to be wrapped. As an example, the first place would be at
    https://github.com/astropy/astropy/blob/master/astropy/time/core.py#L389 - where one would probably replace the line with

    jd1, jd2 = self._time.jd1.ravel(), self._time.jd2.ravel()
    

    and then before the new time is initialized, at https://github.com/astropy/astropy/blob/master/astropy/time/core.py#L409, set the old shape back, as in:

    jd1.shape = jd2.shape = self._time.jd1.shape
    self._time = self.FORMATS[self.format](jd1, jd2, scale, self.precision,
       ...
    

    and similar changes in other locations where erfa is used

  6. taldcroft commented on Oct 20, 2014

    @taldcroft
    Member

    In principle I'm fine with relaxing the restriction on having 1-d arrays. The original motivation was that it kept things simple and that we could wait until someone actually raised the issue. If there is a need, and someone to do the implementation then it sounds good.

  7. eteq commented on Oct 20, 2014

    @eteq
    Member

    @mhvk - I don't think #2992 will impact this too much - this is more about how Time views itself, and ideally #2992 will be a transparent change for time.

  8. mhvk commented on Oct 20, 2014

    @mhvk
    Contributor

    @eteq - but I see discussions about broadcasting in #2992, which, if this is true broadcasting as for normal numpy operations, implies there will have to be no changes to Time. Am I misunderstanding?

  9. mhvk commented on Oct 21, 2014

    @mhvk
    Contributor

    @cheekujodhpur - now looked at #2992 a bit more and I do think this will solve the broadcasting for us, so I would hold off on experimenting too much here.

  10. mhvk commented on Nov 21, 2014

    @mhvk
    Contributor

    @cheekujodhpur - With #2992 merged, I think it will now be quite trivial to ensure Time can handle multidimensional data; in fact, all that may be needed is to remove the check on the dimension! Let me know if you are you still interested in trying this (if not, I'll try myself).

  11. mhvk commented on Nov 24, 2014

    @mhvk
    Contributor

    @cheekujodhpur - I started with converting Time so that scalars are dealt with better and it turned out that this also made the multi-dimensions work. Should have a PR with it shortly, but thought I would let you know so that we don't duplicate each other.

  12. mhvk commented on Nov 24, 2014

    @mhvk
    Contributor

    p.s. See #3135 for an ERFA bug that needs to be fixed before I can send my PR...

  13. mhvk commented on Dec 18, 2014

    @mhvk
    Contributor

    This now is solved by #3138, so I'll close this. @bnordgren, thanks for reporting this issue, it will no longer be one in 1.0! @cheekujodhpur, thanks for your offer to help, even if here it ended up being taken over by events.

  14. added this to the v1.0.0 milestone on Dec 18, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions