Repository: sunpy/sunpy

Issue:
SXTMap requires test data and tests.
<!--
We know asking good questions takes effort, and we appreciate your time.
Thank you.

Please be aware that everyone has to follow our code of conduct:
https://sunpy.org/coc

These comments are hidden when you submit this github issue.

Please have a search on our GitHub repository to see if a similar issue has already been posted.
If a similar issue is closed, have a quick look to see if you are satisfied by the resolution.
If not please go ahead and open an issue!
-->

### Description
Based on #3440 and the PR #2056, we don't have SXTMap data. 
Although `Map.quicklook()` bugs out, the map can be plotted by `Map.plot()`.
Tests for this file are to be added.
The map's`wavelength` is also in `str` and `GenericMap` handles `wavelnth` in `Quantity`
Find and improve all instances of defaulting the Sun-Earth distance to 1 AU
If I remember correctly we do this in a few places in Map, such as in SXT as was pointed out here: https://github.com/sunpy/sunpy/pull/4926#discussion_r569631042

@ayshih Do we still do this anywhere in coordinates?


Discussion:
@nabobalis the SXT's `wavelength` is in str and is `Al.1`, should this be defaulted as `0`?
All other sources have separate quantities as wavelength.
As @wafels noted on Element, SXT takes images with different filters, with two of the filters being different thicknesses of aluminum (hence, "Al").  It'd be unclear how to convert each the filter to a quantified wavelength.  If you don't have a really good understanding of SXT data, stay away from trying to fix `SXTMap`.
Just so we have a note of it, information on SXT and Yohkoh can be found at http://ylstone.physics.montana.edu/ylegacy/mission_cal_papers.html
I'm pretty sure `sunpy.coordinates` is all safe.

I just tried using `grep` to find instances anywhere else, and the only one I can find is that SXT one.  (A private function in `sunpy.instr.goes` has it as a default if a date is not provided, but the public function that calls it should always provide a date.)  However, there may be insidious implementations that I missed with my `grep` pattern.
Here's a subtle one.  If you request the alternate output of `synodic` from `sunpy.physics.differential_rotation.diff_rot()`, it calculates the synodic rotation – the apparent amount of rotation for as seen by an Earth observer – by assuming that the Earth is always at 1 AU.
https://github.com/sunpy/sunpy/blob/0c1a5fd078768e37226ab6fe74cd115e9d7d8d8d/sunpy/physics/differential_rotation.py#L130-L134

Resolving patch:
diff --git a/sunpy/map/mapbase.py b/sunpy/map/mapbase.py
--- a/sunpy/map/mapbase.py
+++ b/sunpy/map/mapbase.py
@@ -786,7 +786,7 @@ def nickname(self, n):
 
     def _get_date(self, key):
         time = self.meta.get(key, None)
-        if time is None:
+        if not time:
             return
 
         # Get the time scale
@@ -1127,12 +1127,12 @@ def coordinate_system(self):
         If not present, defaults to (HPLN-TAN, HPLT-TAN), and emits a warning.
         """
         ctype1 = self.meta.get('ctype1', None)
-        if ctype1 is None:
+        if not ctype1:
             warn_metadata("Missing CTYPE1 from metadata, assuming CTYPE1 is HPLN-TAN")
             ctype1 = 'HPLN-TAN'
 
         ctype2 = self.meta.get('ctype2', None)
-        if ctype2 is None:
+        if not ctype2:
             warn_metadata("Missing CTYPE2 from metadata, assuming CTYPE2 is HPLT-TAN")
             ctype2 = 'HPLT-TAN'
 
diff --git a/sunpy/map/sources/yohkoh.py b/sunpy/map/sources/yohkoh.py
--- a/sunpy/map/sources/yohkoh.py
+++ b/sunpy/map/sources/yohkoh.py
@@ -3,14 +3,14 @@
 __author__ = "Jack Ireland"
 __email__ = "jack.ireland@nasa.gov"
 
-import numpy as np
 
+import astropy.units as u
+from astropy.coordinates import ITRS, SphericalRepresentation
 from astropy.visualization import PowerStretch
 from astropy.visualization.mpl_normalize import ImageNormalize
 
 from sunpy.map import GenericMap
 from sunpy.map.sources.source_type import source_stretch
-from sunpy.sun import constants
 
 __all__ = ['SXTMap']
 
@@ -18,17 +18,18 @@
 class SXTMap(GenericMap):
     """Yohkoh SXT Image Map
 
-    The Yohkoh Soft X-ray Telescope (SXT) the full solar disk
-    (42 x 42 arcminutes)in the 0.25 - 4.0 keV range.
-    It consists of a glancing incidence mirror and a CCD sensor and
+    The Yohkoh Soft X-ray Telescope (SXT) observed the full solar disk
+    (42 x 42 arcminutes) in the 0.25 - 4.0 keV range.
+    It consisted of a glancing incidence mirror and a CCD sensor and
     used thin metallic filters to acquire images in restricted
-    portions of its energy range. SXT could resolve features down to 2.5
-    arcseconds. Information about the temperature and density of the plasma
+    portions of its energy range.
+    SXT could resolve features down to 2.5 arcseconds.
+    Information about the temperature and density of the plasma
     emitting the observed x-rays was obtained by comparing images acquired with
-    the different filters. Images could be obtained every 2 to 8 seconds.
+    the different filters.
+    Images could be obtained every 2 to 8 seconds.
     Smaller images with a single filter could be obtained as frequently as
     once every 0.5 seconds.
-
     Yohkoh was launched on 30 August 1991 and ceased operations on
     14 December 2001.
 
@@ -46,6 +47,16 @@ def __init__(self, data, header, **kwargs):
         self.plot_settings['norm'] = ImageNormalize(
             stretch=source_stretch(self.meta, PowerStretch(0.5)), clip=False)
 
+    @property
+    def _supported_observer_coordinates(self):
+        return [(('long', 'lat', 'radius'), {'lon': self.meta.get('long'),
+                                             'lat': self.meta.get('lat'),
+                                             'distance': self.meta.get('radius'),
+                                             'unit': (u.deg, u.deg, u.km),
+                                             'representation_type': SphericalRepresentation,
+                                             'frame': ITRS, })
+                ] + super()._supported_observer_coordinates
+
     @property
     def observatory(self):
         return "Yohkoh"
@@ -54,27 +65,6 @@ def observatory(self):
     def detector(self):
         return "SXT"
 
-    @property
-    def dsun(self):
-        """
-        For Yohkoh Maps, DSUN_OBS is not always defined. In this case the
-        SOLAR_R keyword is used to calculate dsun.
-        """
-
-        # 2012/12/19 - the SXT headers do not have a value of the distance from
-        # the spacecraft to the center of the Sun.  The FITS keyword 'DSUN_OBS'
-        # appears to refer to the observed diameter of the Sun.  Until such
-        # time as that is calculated and properly included in the file, we will
-        # use simple trigonometry to calculate the distance of the center of
-        # the Sun from the spacecraft.  Note that the small angle approximation
-        # is used, and the solar radius stored in SXT FITS files is in arcseconds.
-
-        if 'solar_r' in self.meta:
-            dsun = constants.radius / (np.deg2rad(self.meta['solar_r'] / 3600.0))
-        else:
-            dsun = constants.au
-        return self.meta.get('dsun_obs', dsun)
-
     @property
     def measurement(self):
         s = self.meta.get('wavelnth', '')


Test patch:
diff --git a/sunpy/data/test/YohkohSXT.header b/sunpy/data/test/YohkohSXT.header
new file mode 100644
--- /dev/null
+++ b/sunpy/data/test/YohkohSXT.header
@@ -0,0 +1,113 @@
+SIMPLE  =                    T / Written by IDL:  Wed May 25 11:26:25 2016      
+BITPIX  =                  -32 /Real*4 (floating point)                         
+NAXIS   =                    2 /                                                
+NAXIS1  =                  256 /                                                
+NAXIS2  =                  256 /                                                
+INDEX_VE=                 4113 / gen:                                           
+TIME    =             40224018 / gen: Time (millisec of day) Derived from DP_Tim
+DAY     =                 4692 / gen: Day (since 1-Jan-79) Derived from DP_Time 
+DP_MODE =                  141 / gen: DP Mode W50 F2                            
+DP_RATE =                   64 / gen: DP Rate W48 F15                           
+FLARE_CO=                    5 / gen: Flare flag control (active triggers) W50 F
+RBM_STAT=                    0 / gen: Radiation Belt Montitor Status W50 F61    
+TELEMETR=                   21 / gen: Telemetry source information W7 in 16 byte
+CAL_STAT=                   64 / gen: CAL status W51 F55                        
+PNTG_TRA=                    1 / gen: Information on how pointing was derived Fr
+PNTG_JIT=                    0 / gen: Magnitude of pointing change From Mainfram
+DATA_QUA=                    0 / gen: Data quality Ground Info                  
+NMISSSAM=                    0 / gen: Number of missing bytes (due to telemetry 
+STARTSAM=                    0 / gen: Starting sample number of good data Ground
+DATA_WOR=                    4 / gen: Data word type (byte, integer*2, real...) 
+NINDEXST=                    0 / gen: Number of "extra" index structures followi
+NINDEXBY=                  352 / gen: Number of bytes in the index records      
+NDATABYT=               262144 / gen: Number of byte in the data section        
+SXT_POW_=                  251 / gen: Power Status (0=off, 1=on) W48 F25        
+BCS_POW_=                  238 / gen: BCS Power status W112 F32n+3              
+HXT_POW_=                  240 / gen: HXT Power status W48 F32+1                
+WBS_POW_=                   98 / gen: Power status W48 F32n+2                   
+SXT_CONT=                  192 / gen: SXT Control Status W114 F32               
+SINDEX_V=                12307 / sxt:                                           
+PFI_FFI =                    1 / sxt: Image information                         
+PERIPH  =                  209 / sxt: Aspect/shutter/filter information W114 F08
+EXPLEVMO=                    4 / sxt: Exposure mode/level W114 F09/03           
+IMGPARAM=                    2 / sxt: Image parameter information W114 F24/18   
+FLUSH   =                  133 / sxt: Flush information W114 F40/34             
+EXPLAT  =                 2489 / sxt: Exposure latency (mailbox value) W114 F10,
+EXPDUR  =                23971 / sxt: Exposure duration (mailbox value) W114 F42
+SHAPE_C1=                  256 / sxt: Commanded image shape (nx by ny) W114 F57,
+SHAPE_C2=                  256 / sxt: Commanded image shape (nx by ny) W114 F57,
+CORNE_C1=                    0 / sxt: Commanded starting corner (x0, y0) W114 F2
+CORNE_C2=                    0 / sxt: Commanded starting corner (x0, y0) W114 F2
+PIX_SIZE=              2.00000 / his: pixel size from index.his.pixel_size      
+FOV_VER =                    0 / sxt: Information on how solution was derived Gr
+OBSREGIO=                   96 / sxt: Observing region Number W114 F50          
+SEQ_NUM =                   11 / sxt: Sequence Number (1-13) W114 F59/55        
+SEQ_TAB_=                  186 / sxt: Sequence table serial used Ground Info    
+SERIAL_N=                 8583 / sxt: Serial number of image W115 F18,34,50/16,3
+POW_STAT=                  251 / sxt: Power Status (0=off, 1=on) W48 F25        
+SW_STAT =                  176 / sxt: Active Software (1=active) W114 F12       
+SSXT_CON=                  192 / sxt: SXT Control Status W114 F32               
+SXTFMT  =                   12 / sxt: SXT Format info 8:2 or 2:8 W115 F00       
+TEMP_CCD=                   95 / sxt: CCD Temperature W113 F52                  
+J_REGIST=                   68 / sxt: Which buffer is used W114 F33?            
+IMG_MAX =                  255 / sxt: Maximum intensity Derived                 
+IMG_AVG =                    1 / sxt: Average intensity of whole image Derived  
+IMG_DEV =                   34 / sxt: Standard deviation of the whole image Deri
+PERCENTD=                  239 / sxt: Percentage of data present Derived        
+PERCENTO=                    0 / sxt: Percentage of data over [N] counts Derived
+AEC_STAT=                    0 / sxt: AEC Status W114 F44                       
+EXTRA   =                    0 / sxt: Information used by secondary programs    
+LAT     =              10.9955 / Yoh Orb: Spacecraft Lattitude                  
+LONG    =              315.861 / Yoh Orb: Spacecraft Longitude                  
+HEIGHT  =              777.563 / Yoh Orb: Spacecrft Altitude (Km)               
+RADIUS  =              7154.83 / Yoh Orb: Radius                                
+RIG     =              10.2560 / Yoh Orb: Rigidity                              
+TIM2FMS =                  985 / Seconds Since FMS                              
+TIM2NITE=                 2764 / Seconds Until LMS                              
+IN_SAA  =                    0 / Yohkoh in SAA?                                 
+DATE    = '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+MJD     =                48565 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+TIME_OBS= '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+DATE_OBS= '1991-11-05T11:10:24.018' / ssw: http://www.lmsal.com/solarsoft/ssw_st
+DATE-OBS= '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+FILENAME= 'sxtf_19911105_111024_221.fts' / ssw: http://www.lmsal.com/solarsoft/s
+ORIGIN  = '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+TELESCOP= 'Yohkoh  '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+INSTRUME= 'SXT     '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+OBJECT  = '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+SCI_OBJ = '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+OBS_PROG= '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+EXPTIME =              1.00000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+WAVELNTH= 'Al.1    '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CTYPE1  = '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CTYPE2  = '        '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CUNIT1  = 'arcsec  '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CUNIT2  = 'arcsec  '           / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CRPIX1  =              107.613 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CRPIX2  =              165.908 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CRVAL1  =              0.00000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CRVAL2  =              0.00000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CDELT1  =              9.82000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CDELT2  =              9.82000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+XCEN    =              205.115 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+YCEN    =             -367.342 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CROTA1  =             0.793083 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+CROTA2  =             0.793083 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+SOLAR_R =              967.151 / ssw: Solar radius in arcsec (geocentric)       
+SOLAR_B0=              3.95366 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+SOLAR_L0=              0.00000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+SOLAR_P =              0.00000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+DSUN_OBS=          1.48331E+11 / ssw: Sun-Earth distance in meter               
+HGLN_OBS=              0.00000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+HGLT_OBS=              0.00000 / ssw: http://www.lmsal.com/solarsoft/ssw_standar
+HISTORY Dark Subtraction: (dark_sub,Ver: 3.280) One Img      1-NOV-91  16:09:20 
+HISTORY DC Orbit Correction: Enabled                                            
+HISTORY Despiked: (sxt_clean.pro) Level/N_Sigma =   3.0                         
+HISTORY Leak Subtraction:  NONE PERFORMED                                       
+HISTORY Image Deconvolution?    NONE                                            
+HISTORY Composite Creation:NONE PERFORMED                                       
+HISTORY Vignette Correction: NONE PERFORMED                                     
+HISTORY Registration: NONE                                                      
+HISTORY Exposure Duration (millisec):   Original=         38.7   New=       1000
+HISTORY Pixel Resolution:    Original= Qrtr   New= Qrtr                         
+HISTORY Intensity units:   DN/Image-Pixel/Exposure-Duration                     
\ No newline at end of file
diff --git a/sunpy/map/sources/tests/test_sxt_source.py b/sunpy/map/sources/tests/test_sxt_source.py
new file mode 100644
--- /dev/null
+++ b/sunpy/map/sources/tests/test_sxt_source.py
@@ -0,0 +1,66 @@
+"""
+Test cases for Yohkoh SXTMap subclass
+"""
+import pytest
+
+import astropy.units as u
+
+from sunpy.data.test import get_dummy_map_from_header, get_test_filepath
+from sunpy.map.sources.yohkoh import SXTMap
+from sunpy.util.exceptions import SunpyMetadataWarning
+
+
+@pytest.fixture
+def sxt_map():
+    with pytest.warns(SunpyMetadataWarning, match='Missing CTYPE'):
+        return get_dummy_map_from_header(get_test_filepath("YohkohSXT.header"))
+
+
+def test_fits_to_sxt(sxt_map):
+    """Tests the creation of SXTMap using FITS."""
+    assert isinstance(sxt_map, SXTMap)
+
+
+def test_is_datasource_for(sxt_map):
+    """Test the is_datasource_for method of SXTMap.
+    Note that header data to be provided as an argument
+    can be a MetaDict object."""
+    assert sxt_map.is_datasource_for(sxt_map.data, sxt_map.meta)
+
+
+def test_observatory(sxt_map):
+    """Tests the observatory property of the SXTMap object."""
+    assert sxt_map.observatory == "Yohkoh"
+
+
+def test_detector(sxt_map):
+    """Tests the detector property of the SXTMap object"""
+    assert sxt_map.detector == "SXT"
+
+
+def test_measurement(sxt_map):
+    """Tests the measurement property of the SXTMap object."""
+    assert sxt_map.measurement == 'Al01'
+
+
+def test_wavelength(sxt_map):
+    """Tests that the wavelength of the SXTMap is always None"""
+    assert sxt_map.wavelength is None
+
+
+def test_heliographic_longitude(sxt_map):
+    assert u.allclose(sxt_map.heliographic_longitude, 0.002357818089886795 * u.deg)
+
+
+def test_heliographic_latitude(sxt_map):
+    assert u.allclose(sxt_map.heliographic_latitude, 3.955251457847305 * u.deg)
+
+
+def test_dsun(sxt_map):
+    assert u.allclose(sxt_map.dsun, 148328341.63429108 * u.km)
+
+
+def test_wcs(sxt_map):
+    # Smoke test that WCS is valid and can transform from pixels to world coordinates
+    with pytest.warns(SunpyMetadataWarning, match='Missing CTYPE'):
+        sxt_map.pixel_to_world(0*u.pix, 0*u.pix)