Skip to content

Intransitive behavior in calculating separation of alt-az coordinates #5650

Closed

Description

@lpsinger

I am finding that the following calculation of the separation of two AltAz coordinate objects works when one object is the left-hand side, but not the other way around:

In [1]: from astropy.time import Time
   ...: from astropy import coordinates as coord, units as u
   ...: from astropy.coordinates.tests.utils import randomly_sample_sphere
   ...: times = Time.now() + np.linspace(0,10,12)*u.day
   ...: lapalma = coord.EarthLocation.of_site('lapalma')
   ...: frame = coord.AltAz(obstime=times, location=lapalma)
   ...: moon = coord.get_moon(times)
   ...: coos = coord.SkyCoord(*(
   ...:     np.reshape(_, (-1, 1)) for _ in randomly_sample_sphere(3)))
   ...: altaz = coos.transform_to(frame)
   ...: moon_altaz = moon.transform_to(frame)
   ...: altaz.separation(moon_altaz) # this works
   ...: 
Out[1]: 
<Angle [[ 139.0388979 , 138.23843479, 135.06332784, 129.70181874,
          122.73431463, 114.85028243, 106.5549471 ,  98.05920802,
           89.34874134,  80.34706644,  71.1096006 ,  61.99276037],
        [  51.46208807,  61.70674564,  72.57274178,  83.92909374,
           95.47107488, 106.87666585, 117.98115975, 128.83409021,
          139.59927098, 150.28646499, 160.0375782 , 164.83114461],
        [  43.8953635 ,  52.06206336,  61.28994984,  71.29723246,
           81.68591216,  92.06381851, 102.20185075, 112.0833638 ,
          121.80899218, 131.38692475, 140.40763961, 147.5993305 ]] deg>

In [2]: moon_altaz.separation(altaz) # this raises an exception
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-5447e2eaa179> in <module>()
----> 1 moon_altaz.separation(altaz)

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/sky_coordinate.pyc in separation(self, other)
    676 
    677         if isinstance(other, SkyCoord):
--> 678             self_in_other_system = self.transform_to(other.frame)
    679         elif isinstance(other, BaseCoordinateFrame) and other.has_data:
    680             # it's a frame

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/sky_coordinate.pyc in transform_to(self, frame)
    437         # Do the transformation, returning a coordinate frame of the desired
    438         # final type (not generic).
--> 439         new_coord = trans(self.frame, generic_frame)
    440 
    441         # Finally make the new SkyCoord object from the `new_coord` and

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/transformations.pyc in __call__(self, fromcoord, toframe)
    905 
    906             curr_toframe = t.tosys(**frattrs)
--> 907             curr_coord = t(curr_coord, curr_toframe)
    908 
    909         # this is safe even in the case where self.transforms is empty, because

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/transformations.pyc in __call__(self, fromcoord, toframe)
    705 
    706     def __call__(self, fromcoord, toframe):
--> 707         res = self.func(fromcoord, toframe)
    708         if not isinstance(res, self.tosys):
    709             raise TypeError('the transformation function yielded {0} but '

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/builtin_frames/cirs_observed_transforms.pyc in altaz_to_altaz(from_coo, to_frame)
    131     # for now we just implement this through CIRS to make sure we get everything
    132     # covered
--> 133     return from_coo.transform_to(CIRS(obstime=from_coo.obstime)).transform_to(to_frame)

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/baseframe.pyc in transform_to(self, new_frame)
    986             msg = 'Cannot transform from {0} to {1}'
    987             raise ConvertError(msg.format(self.__class__, new_frame.__class__))
--> 988         return trans(self, new_frame)
    989 
    990     def is_transformable_to(self, new_frame):

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/transformations.pyc in __call__(self, fromcoord, toframe)
    905 
    906             curr_toframe = t.tosys(**frattrs)
--> 907             curr_coord = t(curr_coord, curr_toframe)
    908 
    909         # this is safe even in the case where self.transforms is empty, because

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/transformations.pyc in __call__(self, fromcoord, toframe)
    705 
    706     def __call__(self, fromcoord, toframe):
--> 707         res = self.func(fromcoord, toframe)
    708         if not isinstance(res, self.tosys):
    709             raise TypeError('the transformation function yielded {0} but '

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/builtin_frames/cirs_observed_transforms.pyc in cirs_to_altaz(cirs_coo, altaz_frame)
     81                                       distance=distance,
     82                                       copy=False)
---> 83     return altaz_frame.realize_frame(rep)
     84 
     85 

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/baseframe.pyc in realize_frame(self, representation)
    876                         for attr in self.get_frame_attr_names()
    877                         if attr not in self._attr_names_with_defaults])
--> 878         return self.__class__(representation, **frattrs)
    879 
    880     def represent_as(self, new_representation, in_frame_units=False):

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/builtin_frames/altaz.pyc in __init__(self, *args, **kwargs)
     94 
     95     def __init__(self, *args, **kwargs):
---> 96         super(AltAz, self).__init__(*args, **kwargs)
     97 
     98     @property

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/baseframe.pyc in __init__(self, *args, **kwargs)
    660                 # Validate attribute by getting it.  If the instance has data,
    661                 # this also checks its shape is OK.  If not, we do it below.
--> 662                 values[fnm] = getattr(self, fnm)
    663             else:
    664                 setattr(self, '_' + fnm, fdefault)

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/astropy/coordinates/baseframe.pyc in __get__(self, instance, frame_cls)
    233                         "attribute {0} should be scalar or have shape {1}, "
    234                         "but is has shape {2} and could not be broadcast."
--> 235                         .format(self.name, instance_shape, out.shape))
    236 
    237                 converted = True

ValueError: attribute obstime should be scalar or have shape (12,), but is has shape (3, 12) and could not be broadcast.

Activity

  1. eerovaher commented on Dec 13, 2023

    @eerovaher
    Member

    Is this still a problem after #15121?

  2. lpsinger commented on Dec 14, 2023

    @lpsinger
    ContributorAuthor

    No, this was fixed by #15121.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions