Repository: sunpy/sunpy

Issue:
Improve missing metadata warning in Map
If some of the keys for observer metadata are missing it would be good to inform the user which ones they should add. See this comment https://github.com/sunpy/sunpy/pull/3115#discussion_r285666447 


Discussion:
 Is there any inherent logic for differentiating between `carrington` latitudes and longitudes and  `stonyhurst` latitudes and longitudes that may be used to figure out which ones the user may want?
If not can we not simply do a search in the meta to see what all may be missing?
From what I understand, `dsun_obs` will be the same for both and will be easy to verify if missng?
The way this works is that map sources can register any keywords they like to be interpreted as observer position. See [`AIAMap`](https://github.com/sunpy/sunpy/blob/master/sunpy/map/sources/sdo.py#L61) for an example.

In `GenericMap` we would need to support finding out what keys are missing based on the `_supported_observer_coordinates` property.
In your comment here you mentioned `work out what ones are missing, i.e. you could have a weird header with a mix of crln and hglt`, in this context is there some logic to discern one from the other or do we need to simply show all which are in the `_supported_observer_coordinates` list which would be missing in the `meta`?
[https://github.com/sunpy/sunpy/pull/3115#discussion_r285675087](url)
So each frame has 3 keys, if none of them match, then we ignore the frame as it's clearly not there. If some but not all of them match (and none match all 3) we should tell the user that we failed to read any of the half-present frames because of a specific missing key or two.

Does that make any sense?
Cool. I understand now. Thanks! :smiley: 
Can a frame have more than three meta? 

Resolving patch:
diff --git a/sunpy/map/mapbase.py b/sunpy/map/mapbase.py
--- a/sunpy/map/mapbase.py
+++ b/sunpy/map/mapbase.py
@@ -631,14 +631,18 @@ def observer_coordinate(self):
         """
         The Heliographic Stonyhurst Coordinate of the observer.
         """
+        missing_meta = {}
         for keys, kwargs in self._supported_observer_coordinates:
-            if all([k in self.meta for k in keys]):
+            meta_list = [k in self.meta for k in keys]
+            if all(meta_list):
                 return SkyCoord(obstime=self.date, **kwargs).heliographic_stonyhurst
+            elif any(meta_list) and not set(keys).isdisjoint(self.meta.keys()):
+                if not isinstance(kwargs['frame'], str):
+                    kwargs['frame'] = kwargs['frame'].name
+                missing_meta[kwargs['frame']] = set(keys).difference(self.meta.keys())
 
-        all_keys = [str(e[0]) for e in self._supported_observer_coordinates]
-        all_keys = '\n'.join(all_keys)
-        warning_message = ("Missing metadata for observer: assuming Earth-based observer."
-                           "The following sets of keys were checked:\n" + all_keys)
+        warning_message = "".join([f"For frame '{frame}' the following metadata is missing: {','.join(keys)}\n" for frame, keys in missing_meta.items()])
+        warning_message = "Missing metadata for observer: assuming Earth-based observer.\n" + warning_message
         warnings.warn(warning_message, SunpyUserWarning)
 
         return get_earth(self.date)


Test patch:
diff --git a/sunpy/map/tests/test_mapbase.py b/sunpy/map/tests/test_mapbase.py
--- a/sunpy/map/tests/test_mapbase.py
+++ b/sunpy/map/tests/test_mapbase.py
@@ -226,7 +226,17 @@ def test_remove_observers(aia171_test_map):
                       match='Missing metadata for observer: assuming Earth-based observer.*'):
         aia171_test_map.observer_coordinate
 
-
+def test_partially_missing_observers(generic_map):
+    generic_map.meta['hglt_obs'] = 0
+    generic_map.meta['hgln_obs'] = 0
+    generic_map.meta['crlt_obs'] = 0
+    generic_map.meta['crln_obs'] = 0
+    with pytest.warns(SunpyUserWarning,
+                      match="Missing metadata for observer: assuming Earth-based observer.\n" +
+                            "For frame 'heliographic_stonyhurst' the following metadata is missing: dsun_obs\n" +
+                            "For frame 'heliographic_carrington' the following metadata is missing: dsun_obs\n"):
+        generic_map.observer_coordinate
+    
 # ==============================================================================
 # Test Rotation WCS conversion
 # ==============================================================================