Repository: sunpy/sunpy

Issue:
Change the name of `Helioprojective.calculate_distance()`
`Helioprojective.calculate_distance()` is used to convert a 2D HPC coordinate into a 3D HPC coordinate by filling in the `distance` attribute with the distance from the observer to the surface of the Sun.  I have issues with the name of the method:

- The name suggests that it is used to calculate the distance to something user-supplied (e.g., a la `SkyCoord.separation_3d()`).
- A user might expect it to return some distance value, not a new `Helioprojective` frame.

I think a better name for this method would be along the lines of `make_3d()` or `convert_to_3d()`.  Discuss.


Discussion:
@Cadair What exactly is our deprecation policy?  Say that we decided today that the eventual name for this method should be `make_3d()`.  That means (I think):

- In 2.0, `make_3d` is available, and `calculate_distance()` is also available but emits a deprecation warning.
- in 3.0, `make_3d` is the only method available, and `calculate_distance()` no longer exists.

What about 1.1, if anything?  Is 2.0 the first time that `make_3d` can be available and the first time that `calculate_distance()` can emit a deprecation warning?
The SEP isn't merged yet, but the requirement is that we emit a deprecation warning for at least one LTS (x.0) release. So we would have to have `calculate_distance` work until 2.0 is released, we could then remove it in 2.1.

Resolving patch:
diff --git a/sunpy/coordinates/frames.py b/sunpy/coordinates/frames.py
--- a/sunpy/coordinates/frames.py
+++ b/sunpy/coordinates/frames.py
@@ -20,7 +20,7 @@
 
 from .frameattributes import TimeFrameAttributeSunPy, ObserverCoordinateAttribute
 
-from sunpy.util.decorators import add_common_docstring
+from sunpy.util.decorators import add_common_docstring, deprecated
 from sunpy.time.time import _variables_for_parse_time_docstring
 
 _J2000 = Time('J2000.0', scale='tt')
@@ -440,17 +440,16 @@ class Helioprojective(SunPyBaseCoordinateFrame):
     rsun = Attribute(default=_RSUN.to(u.km))
     observer = ObserverCoordinateAttribute(HeliographicStonyhurst, default="earth")
 
-    def calculate_distance(self):
+    def make_3d(self):
         """
         This method calculates the third coordinate of the Helioprojective
-        frame. It assumes that the coordinate point is on the disk of the Sun
-        at the rsun radius.
+        frame. It assumes that the coordinate point is on the surface of the Sun.
 
         If a point in the frame is off limb then NaN will be returned.
 
         Returns
         -------
-        new_frame : `~sunpy.coordinates.frames.HelioProjective`
+        new_frame : `~sunpy.coordinates.frames.Helioprojective`
             A new frame instance with all the attributes of the original but
             now with a third coordinate.
         """
@@ -460,9 +459,9 @@ def calculate_distance(self):
             return self
 
         if not isinstance(self.observer, BaseCoordinateFrame):
-            raise ConvertError("Cannot calculate distance to the solar disk "
-                               "for observer '{}' "
-                               "without `obstime` being specified.".format(self.observer))
+            raise ConvertError("Cannot calculate distance to the Sun "
+                               f"for observer '{self.observer}' "
+                               "without `obstime` being specified.")
 
         rep = self.represent_as(UnitSphericalRepresentation)
         lat, lon = rep.lat, rep.lon
@@ -477,6 +476,10 @@ def calculate_distance(self):
                                                           lat=lat,
                                                           distance=d))
 
+    # Support the previous name for make_3d for now
+    calculate_distance = deprecated('1.1', name="calculate_distance",
+                                    alternative="make_3d")(make_3d)
+
 
 @add_common_docstring(**_frame_parameters())
 class HeliocentricEarthEcliptic(SunPyBaseCoordinateFrame):
diff --git a/sunpy/coordinates/transformations.py b/sunpy/coordinates/transformations.py
--- a/sunpy/coordinates/transformations.py
+++ b/sunpy/coordinates/transformations.py
@@ -249,7 +249,7 @@ def hpc_to_hcc(heliopcoord, heliocframe):
                            "heliocentric coordinates for observer '{}' "
                            "without `obstime` being specified.".format(heliopcoord.observer))
 
-    heliopcoord = heliopcoord.calculate_distance()
+    heliopcoord = heliopcoord.make_3d()
 
     # Permute/swap axes from HPC equivalent Cartesian to HCC
     newrepr = heliopcoord.cartesian.transform(matrix_transpose(_matrix_hcc_to_hpc()))


Test patch:
diff --git a/sunpy/coordinates/tests/test_frames.py b/sunpy/coordinates/tests/test_frames.py
--- a/sunpy/coordinates/tests/test_frames.py
+++ b/sunpy/coordinates/tests/test_frames.py
@@ -143,7 +143,7 @@ def test_hpc_distance():
     assert hpc1.Tx == 0 * u.arcsec
     assert hpc1.Ty == 0 * u.arcsec
 
-    hpc2 = hpc1.calculate_distance()
+    hpc2 = hpc1.make_3d()
 
     assert isinstance(hpc2._data, SphericalRepresentation)
 
@@ -160,7 +160,7 @@ def test_hpc_distance_cartesian():
     assert isinstance(hpc1, Helioprojective)
     assert isinstance(hpc1._data, CartesianRepresentation)
 
-    assert hpc1.calculate_distance() is hpc1
+    assert hpc1.make_3d() is hpc1
 
 
 def test_hpc_distance_off_limb():
@@ -175,7 +175,7 @@ def test_hpc_distance_off_limb():
     assert hpc1.Tx == 1500 * u.arcsec
     assert hpc1.Ty == 0 * u.arcsec
 
-    hpc2 = hpc1.calculate_distance()
+    hpc2 = hpc1.make_3d()
 
     assert isinstance(hpc2._data, SphericalRepresentation)
 
@@ -196,7 +196,7 @@ def test_hpc_distance_3D():
     assert hpc1.Tx == 1500 * u.arcsec
     assert hpc1.Ty == 0 * u.arcsec
 
-    hpc2 = hpc1.calculate_distance()
+    hpc2 = hpc1.make_3d()
 
     assert hpc2 is hpc1
 
@@ -405,12 +405,12 @@ def test_hcc_default_observer():
                                               {'representation_type': 'unitspherical'})])
 def test_skycoord_hpc(args, kwargs):
     """
-    Test that when instantiating a HPC frame with SkyCoord calculate distance
+    Test that when instantiating a HPC frame with SkyCoord that make_3d
     still works.
     """
 
     sc = SkyCoord(*args, **kwargs, frame="helioprojective", obstime="2011-01-01T00:00:00")
-    # Test the transform to HGS because it will force a `calculate_distance` call.
+    # Test the transform to HGS because it will force a `make_3d` call.
     hgs = sc.transform_to("heliographic_stonyhurst")
 
     assert isinstance(hgs.frame, HeliographicStonyhurst)