Repository: sunpy/sunpy

Issue:
Calling `.resample()` on HMI submap reverses sign on x- and y-axis 
I don't know whether this is a bug or I am just not understanding what is going on here. 

I understand that HMI data is rotated 180 deg. (relative to say, AIA) (per #1847). When a submap is created, the results are expected, with just the direction of the axes reversed. However, when the same submap is resampled, the x and y axes change signs though the ROI is the same. See example below.
## MWE

``` Python
from sunpy.net import vso
from sunpy.map import Map
client = vso.VSOClient()
result_hmi = client.query(
   vso.attrs.Time((2011, 2, 14, 20, 34, 0), (2011, 2, 14, 21, 0, 0)), 
   vso.attrs.Instrument('HMI'),              
   vso.attrs.Physobs('LOS_magnetic_field'),  
   vso.attrs.Sample(4000 * u.s)
 )
data_hmi = client.get(result_hmi, methods=('URL-FILE_Rice', 'URL-FILE')).wait()
hmi_map = sunpy.map.Map(data_hmi[0])
hmi_submap = hmi_map.submap(u.Quantity([50,300]*u.arcsec),u.Quantity([-350,-100]*u.arcsec))
hmi_submap_resampled = hmi_submap.resample(u.Quantity([20,20]*u.pixel),method='linear')
hmi_map.peek()
hmi_submap.peek()
him_submap_resampled.peek()
```

![image](https://cloud.githubusercontent.com/assets/8676141/17190836/f04656f2-540c-11e6-989e-40fc6ffd4fb2.png)
![image](https://cloud.githubusercontent.com/assets/8676141/17191092/08f00b20-540e-11e6-9fe5-f7e94424ee62.png)
![image](https://cloud.githubusercontent.com/assets/8676141/17191095/0d2af04c-540e-11e6-8135-61d5f8daa7db.png)



Discussion:
I think this was raised in IRC on Monday. It smells of bug.

~~For what it's worth, if you first resample and then crop, this problem does **not** occur.~~

**EDITED**: Sign change does not show up in `.peek()` when resampling and then cropping, but using `xrange` and `yrange` attributes shows that they are indeed still the wrong sign. 

ok, so there is something wonky in the resample code.

I knew this day would come. It is time to work out what `map.center` does because it's broken: https://github.com/sunpy/sunpy/blob/master/sunpy/map/mapbase.py#L446

According to this: https://github.com/sunpy/sunpy/blob/master/sunpy/wcs/wcs.py#L80 it "returns the centre of the image in data coordinates", so is that not the same as doing `map.pixel_to_data(map.dimensions/2)` ?? 

To add to the confusion, this problem does not _seem_ to show up in AIA maps. So maybe this is a result of the reversal of the HMI axes to account for the 180 deg. rotation?

Is submap making an assumption about axis orientation?  See beginning at line 1146 of mapbase.py

@larrymanley that seems likely since calling `.rotate(angle=180.*u.degree)` on the HMI map before resampling/cropping (in either order) fixes this problem. 


Resolving patch:
diff --git a/sunpy/map/mapbase.py b/sunpy/map/mapbase.py
--- a/sunpy/map/mapbase.py
+++ b/sunpy/map/mapbase.py
@@ -444,13 +444,11 @@ def yrange(self):
 
     @property
     def center(self):
-        """The offset between the center of the Sun and the center of the map."""
-        return Pair(wcs.get_center(self.dimensions[0], self.scale.x,
-                                   self.reference_pixel.x,
-                                   self.reference_coordinate.x),
-                    wcs.get_center(self.dimensions[1], self.scale.y,
-                                   self.reference_pixel.y,
-                                   self.reference_coordinate.y))
+        """
+        Return the world (data) coordinates of the center pixel of the array.
+        """
+        center = u.Quantity(self.dimensions) / 2.
+        return Pair(*self.pixel_to_data(*center))
 
     @property
     def shifted_value(self):


Test patch:
diff --git a/sunpy/physics/tests/test_solar_rotation.py b/sunpy/physics/tests/test_solar_rotation.py
--- a/sunpy/physics/tests/test_solar_rotation.py
+++ b/sunpy/physics/tests/test_solar_rotation.py
@@ -42,15 +42,15 @@ def aia171_test_mapcube(aia171_test_submap):
 # Known displacements for these mapcube layers when the layer index is set to 0
 @pytest.fixture
 def known_displacements_layer_index0():
-    return {'x': np.asarray([1.222134e-12, -9.142634e+00, -1.830314e+01]),
-            'y': np.asarray([1.506351e-12, 1.955316e-01, 3.805245e-01])}
+    return {'x': np.asarray([ -2.64321898e-12, -9.10078156e+00, -1.82203188e+01]),
+            'y': np.asarray([ -3.35376171e-12,  2.06812274e-01,  4.03135364e-01])}
 
 
 # Known displacements for these mapcube layers when the layer index is set to 1
 @pytest.fixture
 def known_displacements_layer_index1():
-    return {'x': np.asarray([9.123862e+00, 6.821210e-13, -9.142596e+00]),
-            'y': np.asarray([-2.061722e-01, 9.663381e-13, 1.956522e-01])}
+    return {'x': np.asarray([9.08112778e+00, 5.62749847e-12, -9.10074423e+00]),
+            'y': np.asarray([-2.17404844e-01, 7.16227078e-12, 2.06935463e-01])}
 
 
 def test_calculate_solar_rotate_shift(aia171_test_mapcube, known_displacements_layer_index0, known_displacements_layer_index1):
diff --git a/sunpy/tests/figure_hashes.json b/sunpy/tests/figure_hashes.json
--- a/sunpy/tests/figure_hashes.json
+++ b/sunpy/tests/figure_hashes.json
@@ -5,11 +5,11 @@
     "sunpy.map.tests.test_mapbase.test_peek_grid_limb_aia171": "bae14540bbd09f72cb8034846f902c5b775c67f9cd1dca195aaa8dcc8990263f",
     "sunpy.map.tests.test_mapbase.test_peek_limb_aia171": "ec483ad90b262e498c0f8f058d85b3b8328a525e315829d7e691527236cc122d",
     "sunpy.map.tests.test_mapbase.test_plot_aia171": "a317599f56bbabb7ed72d70293237bb857d49071b86d0d361db2da7db4d068e1",
-    "sunpy.map.tests.test_mapbase.test_plot_aia171_nowcsaxes": "886c049b133c344f4b00a33c2968cc4bec2c9539e995db15f51a9da4cc21a57a",
-    "sunpy.map.tests.test_mapbase.test_plot_aia171_superpixel": "5403e3e32f0385a13ce40f70e1f3865ac5a115640c2744c2ea803b1e0cd192f4",
-    "sunpy.map.tests.test_mapbase.test_plot_aia171_superpixel_nowcsaxes": "474674a5f313993e7e77c97bf579f9cf4aae739a2f0e7b97ae5980116437076d",
+    "sunpy.map.tests.test_mapbase.test_plot_aia171_nowcsaxes": "689607c83e86db4dac013d3e4799a9e3c6b599a0290ed3fea09f06491dd83971",
+    "sunpy.map.tests.test_mapbase.test_plot_aia171_superpixel": "86573ef5cb243956e7446902aee90b022278e29def4b8e4af8446cf0be32590c",
+    "sunpy.map.tests.test_mapbase.test_plot_aia171_superpixel_nowcsaxes": "12c3afea9de36e6ca9afb3a7ebf086152e4d9ec60241526f664712dee3b966e8",
     "sunpy.map.tests.test_mapbase.test_plot_masked_aia171": "342eb99d3c3f0eaf04f736d2548820d55f0db516d40c7a5ed37244d8a04e7959",
-    "sunpy.map.tests.test_mapbase.test_plot_masked_aia171_nowcsaxes": "f2df8eb49af90f65002d808b7937fd002649f13037f74f80dfc506a38eeccacb",
-    "sunpy.map.tests.test_mapbase.test_plot_masked_aia171_superpixel": "58c1413f193987d213663bc830a4443f5ad764ac5e1fe52d23c82e2ffbc474b7",
-    "sunpy.map.tests.test_mapbase.test_plot_masked_aia171_superpixel_nowcsaxes": "43220f3e0f2409b8500d6e35a1c21dc2fc7720c73b3ad756b6786f747962ab66"
+    "sunpy.map.tests.test_mapbase.test_plot_masked_aia171_nowcsaxes": "a823252de99f184db8fe19ddf7cf98003f03d1df0208eafc4ea108fa4435be72",
+    "sunpy.map.tests.test_mapbase.test_plot_masked_aia171_superpixel": "0b88531db75dd88e40e45c9c087939e68371e83b07b9edac099da070ea641580",
+    "sunpy.map.tests.test_mapbase.test_plot_masked_aia171_superpixel_nowcsaxes": "fa646ffbbf645b992724a64f084f740b94a679a772bef5a5a1e9a9be28723130"
 }
\ No newline at end of file