lsst.afw.coord.Coord classes are going away

The lsst.afw.coord.Coord classes are going away, in favor of using lsst.afw.geom.SpherePoint for all spherical coordinates. This was decided in RFC-353 and implemented in ticket DM-11162.

Fundamental differences between the Coord classes and SpherePoint:

  • SpherePoint has no coordinate system. Thus it has none of the methods associated with converting from one coordinate system to another.

    Our convention (which is enforced by SkyWcs) is that sky coordinates are always ICRS (never FK5, Galactic, etc.). If you want to work with other coordinate systems please do it in Python using astropy. That said, SpherePoint can represent any sort of spherical point. For example VisitInfo.boresightAzAlt is a SpherePoint.

  • SpherePoint is immutable.

    As a result, those methods that mutated the object in place must now return a new object. This applies to rotate (now called rotated) and offset. Warning old code that calls offset will now silently do nothing!

    Also there is no clone method, since it would be pointless.

  • SpherePoint is not polymorphic, so there is no special C++ support for std::shared_ptr<SpherePoint>.

    In particular:

    • lsst.afw.coord.makeCoord has no SpherePoint equivalent.
    • lsst.afw.geom.averageSpherePoint takes a vector of SpherePoint and returns a SpherePoint, unlike coord.averageCoord, which takes a vector of std::shared_ptr<Coord> and returns a std::shared_ptr<Coord>. This change is only visible in C++.

In detail, change the following, noting that the Coord classes are in lsst.afw.coord and SpherePoint is in lsst.afw.geom:

  • [X]Coord (Coord, IcrsCoord, etc.) to SpherePoint
  • [X]Coord(Point2D, units) -> SpherePoint(long, lat, units)
  • assertCoord... -> assertSpherePoint..., and the maxDiff argument is renamed to maxSep
  • angularSeparation -> separation
  • getOffsetFrom -> separation, bearingTo for the first, second returned Angle, respectively
  • SpherePoint.getPosition(units) requires a units argument (the Coord version defaulted to degrees). Also, both components are returned in the specified units, unlike Coord.getPosition(hours) which returns the longitude in hours and the latitude in degrees.
  • offset -> offset, but it returns the offset point instead of modifying the existing point
  • rotate -> rotated, which returns a new SpherePoint
  • averageCoord -> averageSpherePoint. In C++ averageSpherePoint takes a std::vector<SpherePoint> and returns a SpherePoint, unlike averageCoord, which takes a vector of shared_ptr and returns a shared_ptr. The Python interface is unchanged.

Things that are not available:

  • makeCoord (as explained above)
  • [X]Coord(string, string) constructor
  • Coord methods:
    • clone
    • convert
    • getClassName
    • getCoordSystem
    • getEpoch
    • getLatitudeStr
    • getLongitudeStr
    • reset
    • toEcliptic
    • toFk5
    • toGalactic
    • toIcrs
    • toTopocentric
    • toString
    • transform

CoordKey in afw.table now takes and returns SpherePoint. Table schemas and data remain unchanged. CoordKey uses field name suffixes _ra and _dec, so it is intended for ICRS sky coordinates. My recommendation for storing other longitude, latitude pairs, such as azimuth, altitude, is to use two scalar keys with appropriate field name suffixes (e.g. _az and _alt).

2 Likes

Excellent! Nice work!

While doing a quick review for part of DM-11162, I came across this lovely example showing how the newly expanded SpherePoint makes our code clearer and our lives easier. Great work!

-    coord = Coord(afwGeom.Angle(ra_degrees, units=afwGeom.degrees),
-                  afwGeom.Angle(dec_degrees, units=afwGeom.degrees))
+    coord = lsst.afw.geom.SpherePoint(ra_degrees, dec_degrees, afwGeom.degrees)