We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add map.sample_at_coords()
Currently to sample the data in a map at a series of coordinates, one has to do (e.g. see [here](http://docs.sunpy.org/en/stable/generated/gallery/plotting/great_arc_example.html)):
```python
pixels = np.asarray(np.rint(m.world_to_pixel(great_arc.coordinates())), dtype=int)
x = pixels[0, :]
y = pixels[1, :]
intensity_along_arc = m.data[y, x]
```

It would be nice if there was a method `sample_at_coords(coords)` that automatically did this under the hood.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sunpy/map/maputils.py`
Content:
```
1 """
2 This submodule provides utility functions to act on `sunpy.map.GenericMap` instances.
3 """
4 from itertools import chain, product
5 
6 import numpy as np
7 
8 import astropy.units as u
9 from astropy.coordinates import SkyCoord
10 
11 from sunpy.coordinates import Helioprojective
12 
13 __all__ = ['all_pixel_indices_from_map', 'all_coordinates_from_map',
14            'map_edges', 'solar_angular_radius', 'contains_full_disk',
15            'is_all_off_disk', 'is_all_on_disk', 'contains_limb',
16            'coordinate_is_on_solar_disk', 'on_disk_bounding_coordinates']
17 
18 
19 def all_pixel_indices_from_map(smap):
20     """
21     Returns pixel pair indices of every pixel in a map.
22 
23     Parameters
24     ----------
25     smap : `~sunpy.map.GenericMap`
26         A SunPy map.
27 
28     Returns
29     -------
30     `~numpy.array`
31         A `numpy.array` with the all the pixel indices built from the
32         dimensions of the map.
33     """
34     return np.meshgrid(*[np.arange(v.value) for v in smap.dimensions]) * u.pix
35 
36 
37 def all_coordinates_from_map(smap):
38     """
39     Returns the coordinates of every pixel in a map.
40 
41     Parameters
42     ----------
43     smap : `~sunpy.map.GenericMap`
44         A SunPy map.
45 
46     Returns
47     -------
48     `~astropy.coordinates.SkyCoord`
49         An two-dimensional array of sky coordinates in the coordinate
50         system "coordinate_system".
51     """
52     x, y = all_pixel_indices_from_map(smap)
53     return smap.pixel_to_world(x, y)
54 
55 
56 def map_edges(smap):
57     """
58     Returns the pixel locations of the edges of an input map.
59 
60     Parameters
61     ----------
62     smap : `~sunpy.map.GenericMap`
63         A SunPy map.
64 
65     Returns
66     -------
67     top, bottom, left_hand_side, right_hand_side : `~astropy.units.Quantity`
68         Returns the pixel locations at the edge of the map;
69         the zeroth, first, second and third tuple values
70         return the top, bottom, left hand side and right
71         hand side pixel locations respectively of the input map.
72     """
73     # Calculate all the edge pixels
74     nx, ny = smap.dimensions.x.value, smap.dimensions.y.value
75     top = list(product(np.arange(nx), [ny - 1])) * u.pix
76     bottom = list(product(np.arange(nx), [0])) * u.pix
77     left_hand_side = list(product([0], np.arange(ny))) * u.pix
78     right_hand_side = list(product([nx - 1], np.arange(ny))) * u.pix
79     return top, bottom, left_hand_side, right_hand_side
80 
81 
82 @u.quantity_input
83 def solar_angular_radius(coordinates):
84     """
85     Calculates the solar angular radius as seen by the observer.
86 
87     The tangent of the angular size of the Sun is equal to the radius
88     of the Sun divided by the distance between the observer and the
89     center of the Sun.
90 
91     Parameters
92     ----------
93     coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`
94         The input coordinate. The coordinate frame must be
95         `~sunpy.coordinates.Helioprojective`.
96 
97     Returns
98     -------
99     angle : `~astropy.units.Quantity`
100         The solar angular radius.
101     """
102     return np.arctan(coordinates.rsun / coordinates.observer.radius)
103 
104 
105 def contains_full_disk(smap):
106     """
107     Checks if a map contains the full disk of the Sun.
108 
109     A map contains the full disk of the Sun if the following two
110     conditions are met: (1) all the coordinates at the edge of the map are
111     more than solar angular radius from the center of the Sun and, (2) the
112     map is not all off disk. If both these conditions are met, the
113     function returns `True`. Otherwise, the function returns `False`.
114 
115     Parameters
116     ----------
117     smap : `~sunpy.map.GenericMap`
118         A map in helioprojective Cartesian coordinates.
119 
120     Returns
121     -------
122     `~bool`
123         Returns `False` if any of the coordinates at the edge of the map
124          are less than one solar radius away from the center of the Sun.
125 
126     Notes
127     -----
128     This function checks if the image coordinates include the solar disk.
129     Therefore this function would return `True` for a coronagraph image
130     such as from LASCO/C3 or STEREO/SECCHI COR1 since the solar disk is
131     within the field of the view of the instrument (although no emission
132     from the disk itself is present in the data.)
133     """
134     # Calculate all the edge pixels
135     edges = map_edges(smap)
136     edge_pixels = list(chain.from_iterable([edges[0], edges[1], edges[2], edges[3]]))
137     x = [p[0] for p in edge_pixels] * u.pix
138     y = [p[1] for p in edge_pixels] * u.pix
139 
140     # Calculate the edge of the world
141     edge_of_world = smap.pixel_to_world(x, y)
142 
143     # Calculate the distance of the edge of the world in solar radii
144     coordinate_angles = np.sqrt(edge_of_world.Tx ** 2 + edge_of_world.Ty ** 2)
145 
146     # Test if all the edge pixels are more than one solar radius distant
147     # and that the whole map is not all off disk.
148     return np.all(coordinate_angles > solar_angular_radius(edge_of_world)) and ~is_all_off_disk(smap)
149 
150 
151 @u.quantity_input
152 def coordinate_is_on_solar_disk(coordinates):
153     """
154     Checks if the helioprojective Cartesian coordinates are on the solar disk.
155 
156     The check is performed by comparing the coordinate's angular distance
157     to the angular size of the solar radius.  The solar disk is assumed to be
158     a circle i.e., solar oblateness and other effects that cause the solar disk to
159     be non-circular are not taken in to account.
160 
161     Parameters
162     ----------
163     coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`
164         The input coordinate. The coordinate frame must be
165         `~sunpy.coordinates.Helioprojective`.
166 
167     Returns
168     -------
169     `~bool`
170         Returns `True` if the coordinate is on disk, `False` otherwise.
171     """
172 
173     if not isinstance(coordinates.frame, Helioprojective):
174         raise ValueError('The input coordinate(s) must be in the Helioprojective Cartesian frame.')
175     # Calculate the angle of every pixel from the center of the Sun and compare it the angular
176     # radius of the Sun.
177     return np.sqrt(coordinates.Tx ** 2 + coordinates.Ty ** 2) < solar_angular_radius(coordinates)
178 
179 
180 def is_all_off_disk(smap):
181     """
182     Checks if none of the coordinates in the `~sunpy.map.GenericMap` are on the solar disk.
183 
184     The check is performed by calculating the angle of every pixel from
185     the center of the Sun. If they are all greater than the angular
186     radius of the Sun, then the function returns `True`. Otherwise, the function
187     returns `False`.
188 
189     Parameters
190     ----------
191     smap : `~sunpy.map.GenericMap`
192         A map in helioprojective Cartesian coordinates.
193 
194     Returns
195     -------
196     `~bool`
197         Returns `True` if all map pixels have an angular radius greater than
198         the angular radius of the Sun.
199 
200     Notes
201     -----
202     For coronagraph images such as those from LASCO C2 and C3 the full disk is
203     within the field of view of the instrument, but the solar disk itself is not imaged.
204     For such images this function will return `False`.
205     """
206     return np.all(~coordinate_is_on_solar_disk(all_coordinates_from_map(smap)))
207 
208 
209 def is_all_on_disk(smap):
210     """
211     Checks if all of the coordinates in the `~sunpy.map.GenericMap` are on the solar disk.
212 
213     The check is performed by calculating the angle of every pixel from
214     the center of the Sun. If they are all less than the angular
215     radius of the Sun, then the function returns `True`. Otherwise, the function
216     returns `False`.
217 
218     Parameters
219     ----------
220     smap : `~sunpy.map.GenericMap`
221         A map in helioprojective Cartesian coordinates.
222 
223     Returns
224     -------
225     `~bool`
226         Returns `True` if all map coordinates have an angular radius less than
227         the angular radius of the Sun.
228     """
229     return np.all(coordinate_is_on_solar_disk(all_coordinates_from_map(smap)))
230 
231 
232 def contains_limb(smap):
233     """
234     Checks if a map contains any part of the solar limb or equivalently whether
235     the map contains both on-disk and off-disk pixels.
236 
237     The check is performed by calculating the angular distance of every pixel from
238     the center of the Sun.  If at least one pixel is on disk (less than the solar
239     angular radius) and at least one pixel is off disk (greater than the solar
240     angular distance), the function returns `True`. Otherwise, the function
241     returns `False`.
242 
243     Parameters
244     ----------
245     smap : `~sunpy.map.GenericMap`
246         A map in helioprojective Cartesian coordinates.
247 
248     Returns
249     -------
250     `~bool`
251         Returns `True` If at least one coordinate of the map is on disk and at
252         least one coordinate of the map is off disk.
253 
254     Notes
255     -----
256     For coronagraph images such as those from LASCO C2 and C3 the full disk is
257     within the field of view of the instrument, but the solar disk itself is not imaged.
258     For such images this function will return `True`.
259     """
260     on_disk = coordinate_is_on_solar_disk(all_coordinates_from_map(smap))
261     return np.logical_and(np.any(on_disk), np.any(~on_disk))
262 
263 
264 def on_disk_bounding_coordinates(smap):
265     """
266     Returns the the bottom left and top right coordinates of the smallest
267     rectangular region that contains all the on disk coordinates of the input map.
268 
269     Parameters
270     ----------
271     smap : `~sunpy.map.GenericMap`
272         A map in helioprojective Cartesian coordinates.
273 
274     Returns
275     -------
276     `~astropy.coordinates.SkyCoord`
277         A `~astropy.coordinates.SkyCoord` of length 2 such that the
278         first entry is the bottom left coordinate and the second entry is the
279         top right coordinate of the smallest rectangular region that contains
280         all the on-disk pixels in the input map.
281     """
282     # Check that the input map is not all off disk.
283     if is_all_off_disk(smap):
284         raise ValueError("The entire map is off disk.")
285 
286     # Get all the coordinates from the input map
287     coordinates = all_coordinates_from_map(smap)
288 
289     # Find which coordinates are on the disk
290     on_disk = coordinate_is_on_solar_disk(coordinates)
291     on_disk_coordinates = coordinates[on_disk]
292 
293     # The bottom left and top right coordinates that contain
294     # the on disk coordinates.
295     tx = on_disk_coordinates.Tx.value
296     ty = on_disk_coordinates.Ty.value
297     return SkyCoord([np.nanmin(tx), np.nanmax(tx)] * u.arcsec,
298                     [np.nanmin(ty), np.nanmax(ty)] * u.arcsec,
299                     frame=Helioprojective, observer=smap.observer_coordinate)
300
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sunpy/map/maputils.py b/sunpy/map/maputils.py
--- a/sunpy/map/maputils.py
+++ b/sunpy/map/maputils.py
@@ -11,9 +11,10 @@
 from sunpy.coordinates import Helioprojective
 
 __all__ = ['all_pixel_indices_from_map', 'all_coordinates_from_map',
-           'map_edges', 'solar_angular_radius', 'contains_full_disk',
-           'is_all_off_disk', 'is_all_on_disk', 'contains_limb',
-           'coordinate_is_on_solar_disk', 'on_disk_bounding_coordinates']
+           'map_edges', 'solar_angular_radius', 'sample_at_coords',
+           'contains_full_disk', 'is_all_off_disk', 'is_all_on_disk',
+           'contains_limb', 'coordinate_is_on_solar_disk',
+           'on_disk_bounding_coordinates']
 
 
 def all_pixel_indices_from_map(smap):
@@ -102,6 +103,27 @@
     return np.arctan(coordinates.rsun / coordinates.observer.radius)
 
 
+def sample_at_coords(smap, coordinates):
+    """
+    Samples the data in a map at given series of coordinates.
+    Uses nearest-neighbor interpolation of coordinates in map, as
+    it effectively uses array indexing.
+
+    Parameters
+    ----------
+    smap : `~sunpy.map.GenericMap`
+        A SunPy map.
+    coordinates : `~astropy.coordinates.SkyCoord`
+        Input coordinates.
+    Returns
+    -------
+    `numpy.array`
+        A `numpy.array` corresponding to the data obtained from the map,
+        at the input coordinates.
+    """
+    return smap.data[smap.wcs.world_to_array_index(coordinates)]
+
+
 def contains_full_disk(smap):
     """
     Checks if a map contains the full disk of the Sun.

{"golden_diff": "diff --git a/sunpy/map/maputils.py b/sunpy/map/maputils.py\n--- a/sunpy/map/maputils.py\n+++ b/sunpy/map/maputils.py\n@@ -11,9 +11,10 @@\n from sunpy.coordinates import Helioprojective\n \n __all__ = ['all_pixel_indices_from_map', 'all_coordinates_from_map',\n-           'map_edges', 'solar_angular_radius', 'contains_full_disk',\n-           'is_all_off_disk', 'is_all_on_disk', 'contains_limb',\n-           'coordinate_is_on_solar_disk', 'on_disk_bounding_coordinates']\n+           'map_edges', 'solar_angular_radius', 'sample_at_coords',\n+           'contains_full_disk', 'is_all_off_disk', 'is_all_on_disk',\n+           'contains_limb', 'coordinate_is_on_solar_disk',\n+           'on_disk_bounding_coordinates']\n \n \n def all_pixel_indices_from_map(smap):\n@@ -102,6 +103,27 @@\n     return np.arctan(coordinates.rsun / coordinates.observer.radius)\n \n \n+def sample_at_coords(smap, coordinates):\n+    \"\"\"\n+    Samples the data in a map at given series of coordinates.\n+    Uses nearest-neighbor interpolation of coordinates in map, as\n+    it effectively uses array indexing.\n+\n+    Parameters\n+    ----------\n+    smap : `~sunpy.map.GenericMap`\n+        A SunPy map.\n+    coordinates : `~astropy.coordinates.SkyCoord`\n+        Input coordinates.\n+    Returns\n+    -------\n+    `numpy.array`\n+        A `numpy.array` corresponding to the data obtained from the map,\n+        at the input coordinates.\n+    \"\"\"\n+    return smap.data[smap.wcs.world_to_array_index(coordinates)]\n+\n+\n def contains_full_disk(smap):\n     \"\"\"\n     Checks if a map contains the full disk of the Sun.\n", "issue": "Add map.sample_at_coords()\nCurrently to sample the data in a map at a series of coordinates, one has to do (e.g. see [here](http://docs.sunpy.org/en/stable/generated/gallery/plotting/great_arc_example.html)):\r\n```python\r\npixels = np.asarray(np.rint(m.world_to_pixel(great_arc.coordinates())), dtype=int)\r\nx = pixels[0, :]\r\ny = pixels[1, :]\r\nintensity_along_arc = m.data[y, x]\r\n```\r\n\r\nIt would be nice if there was a method `sample_at_coords(coords)` that automatically did this under the hood.\n", "before_files": [{"content": "\"\"\"\nThis submodule provides utility functions to act on `sunpy.map.GenericMap` instances.\n\"\"\"\nfrom itertools import chain, product\n\nimport numpy as np\n\nimport astropy.units as u\nfrom astropy.coordinates import SkyCoord\n\nfrom sunpy.coordinates import Helioprojective\n\n__all__ = ['all_pixel_indices_from_map', 'all_coordinates_from_map',\n           'map_edges', 'solar_angular_radius', 'contains_full_disk',\n           'is_all_off_disk', 'is_all_on_disk', 'contains_limb',\n           'coordinate_is_on_solar_disk', 'on_disk_bounding_coordinates']\n\n\ndef all_pixel_indices_from_map(smap):\n    \"\"\"\n    Returns pixel pair indices of every pixel in a map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A SunPy map.\n\n    Returns\n    -------\n    `~numpy.array`\n        A `numpy.array` with the all the pixel indices built from the\n        dimensions of the map.\n    \"\"\"\n    return np.meshgrid(*[np.arange(v.value) for v in smap.dimensions]) * u.pix\n\n\ndef all_coordinates_from_map(smap):\n    \"\"\"\n    Returns the coordinates of every pixel in a map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A SunPy map.\n\n    Returns\n    -------\n    `~astropy.coordinates.SkyCoord`\n        An two-dimensional array of sky coordinates in the coordinate\n        system \"coordinate_system\".\n    \"\"\"\n    x, y = all_pixel_indices_from_map(smap)\n    return smap.pixel_to_world(x, y)\n\n\ndef map_edges(smap):\n    \"\"\"\n    Returns the pixel locations of the edges of an input map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A SunPy map.\n\n    Returns\n    -------\n    top, bottom, left_hand_side, right_hand_side : `~astropy.units.Quantity`\n        Returns the pixel locations at the edge of the map;\n        the zeroth, first, second and third tuple values\n        return the top, bottom, left hand side and right\n        hand side pixel locations respectively of the input map.\n    \"\"\"\n    # Calculate all the edge pixels\n    nx, ny = smap.dimensions.x.value, smap.dimensions.y.value\n    top = list(product(np.arange(nx), [ny - 1])) * u.pix\n    bottom = list(product(np.arange(nx), [0])) * u.pix\n    left_hand_side = list(product([0], np.arange(ny))) * u.pix\n    right_hand_side = list(product([nx - 1], np.arange(ny))) * u.pix\n    return top, bottom, left_hand_side, right_hand_side\n\n\n@u.quantity_input\ndef solar_angular_radius(coordinates):\n    \"\"\"\n    Calculates the solar angular radius as seen by the observer.\n\n    The tangent of the angular size of the Sun is equal to the radius\n    of the Sun divided by the distance between the observer and the\n    center of the Sun.\n\n    Parameters\n    ----------\n    coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`\n        The input coordinate. The coordinate frame must be\n        `~sunpy.coordinates.Helioprojective`.\n\n    Returns\n    -------\n    angle : `~astropy.units.Quantity`\n        The solar angular radius.\n    \"\"\"\n    return np.arctan(coordinates.rsun / coordinates.observer.radius)\n\n\ndef contains_full_disk(smap):\n    \"\"\"\n    Checks if a map contains the full disk of the Sun.\n\n    A map contains the full disk of the Sun if the following two\n    conditions are met: (1) all the coordinates at the edge of the map are\n    more than solar angular radius from the center of the Sun and, (2) the\n    map is not all off disk. If both these conditions are met, the\n    function returns `True`. Otherwise, the function returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `False` if any of the coordinates at the edge of the map\n         are less than one solar radius away from the center of the Sun.\n\n    Notes\n    -----\n    This function checks if the image coordinates include the solar disk.\n    Therefore this function would return `True` for a coronagraph image\n    such as from LASCO/C3 or STEREO/SECCHI COR1 since the solar disk is\n    within the field of the view of the instrument (although no emission\n    from the disk itself is present in the data.)\n    \"\"\"\n    # Calculate all the edge pixels\n    edges = map_edges(smap)\n    edge_pixels = list(chain.from_iterable([edges[0], edges[1], edges[2], edges[3]]))\n    x = [p[0] for p in edge_pixels] * u.pix\n    y = [p[1] for p in edge_pixels] * u.pix\n\n    # Calculate the edge of the world\n    edge_of_world = smap.pixel_to_world(x, y)\n\n    # Calculate the distance of the edge of the world in solar radii\n    coordinate_angles = np.sqrt(edge_of_world.Tx ** 2 + edge_of_world.Ty ** 2)\n\n    # Test if all the edge pixels are more than one solar radius distant\n    # and that the whole map is not all off disk.\n    return np.all(coordinate_angles > solar_angular_radius(edge_of_world)) and ~is_all_off_disk(smap)\n\n\n@u.quantity_input\ndef coordinate_is_on_solar_disk(coordinates):\n    \"\"\"\n    Checks if the helioprojective Cartesian coordinates are on the solar disk.\n\n    The check is performed by comparing the coordinate's angular distance\n    to the angular size of the solar radius.  The solar disk is assumed to be\n    a circle i.e., solar oblateness and other effects that cause the solar disk to\n    be non-circular are not taken in to account.\n\n    Parameters\n    ----------\n    coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`\n        The input coordinate. The coordinate frame must be\n        `~sunpy.coordinates.Helioprojective`.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` if the coordinate is on disk, `False` otherwise.\n    \"\"\"\n\n    if not isinstance(coordinates.frame, Helioprojective):\n        raise ValueError('The input coordinate(s) must be in the Helioprojective Cartesian frame.')\n    # Calculate the angle of every pixel from the center of the Sun and compare it the angular\n    # radius of the Sun.\n    return np.sqrt(coordinates.Tx ** 2 + coordinates.Ty ** 2) < solar_angular_radius(coordinates)\n\n\ndef is_all_off_disk(smap):\n    \"\"\"\n    Checks if none of the coordinates in the `~sunpy.map.GenericMap` are on the solar disk.\n\n    The check is performed by calculating the angle of every pixel from\n    the center of the Sun. If they are all greater than the angular\n    radius of the Sun, then the function returns `True`. Otherwise, the function\n    returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` if all map pixels have an angular radius greater than\n        the angular radius of the Sun.\n\n    Notes\n    -----\n    For coronagraph images such as those from LASCO C2 and C3 the full disk is\n    within the field of view of the instrument, but the solar disk itself is not imaged.\n    For such images this function will return `False`.\n    \"\"\"\n    return np.all(~coordinate_is_on_solar_disk(all_coordinates_from_map(smap)))\n\n\ndef is_all_on_disk(smap):\n    \"\"\"\n    Checks if all of the coordinates in the `~sunpy.map.GenericMap` are on the solar disk.\n\n    The check is performed by calculating the angle of every pixel from\n    the center of the Sun. If they are all less than the angular\n    radius of the Sun, then the function returns `True`. Otherwise, the function\n    returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` if all map coordinates have an angular radius less than\n        the angular radius of the Sun.\n    \"\"\"\n    return np.all(coordinate_is_on_solar_disk(all_coordinates_from_map(smap)))\n\n\ndef contains_limb(smap):\n    \"\"\"\n    Checks if a map contains any part of the solar limb or equivalently whether\n    the map contains both on-disk and off-disk pixels.\n\n    The check is performed by calculating the angular distance of every pixel from\n    the center of the Sun.  If at least one pixel is on disk (less than the solar\n    angular radius) and at least one pixel is off disk (greater than the solar\n    angular distance), the function returns `True`. Otherwise, the function\n    returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` If at least one coordinate of the map is on disk and at\n        least one coordinate of the map is off disk.\n\n    Notes\n    -----\n    For coronagraph images such as those from LASCO C2 and C3 the full disk is\n    within the field of view of the instrument, but the solar disk itself is not imaged.\n    For such images this function will return `True`.\n    \"\"\"\n    on_disk = coordinate_is_on_solar_disk(all_coordinates_from_map(smap))\n    return np.logical_and(np.any(on_disk), np.any(~on_disk))\n\n\ndef on_disk_bounding_coordinates(smap):\n    \"\"\"\n    Returns the the bottom left and top right coordinates of the smallest\n    rectangular region that contains all the on disk coordinates of the input map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~astropy.coordinates.SkyCoord`\n        A `~astropy.coordinates.SkyCoord` of length 2 such that the\n        first entry is the bottom left coordinate and the second entry is the\n        top right coordinate of the smallest rectangular region that contains\n        all the on-disk pixels in the input map.\n    \"\"\"\n    # Check that the input map is not all off disk.\n    if is_all_off_disk(smap):\n        raise ValueError(\"The entire map is off disk.\")\n\n    # Get all the coordinates from the input map\n    coordinates = all_coordinates_from_map(smap)\n\n    # Find which coordinates are on the disk\n    on_disk = coordinate_is_on_solar_disk(coordinates)\n    on_disk_coordinates = coordinates[on_disk]\n\n    # The bottom left and top right coordinates that contain\n    # the on disk coordinates.\n    tx = on_disk_coordinates.Tx.value\n    ty = on_disk_coordinates.Ty.value\n    return SkyCoord([np.nanmin(tx), np.nanmax(tx)] * u.arcsec,\n                    [np.nanmin(ty), np.nanmax(ty)] * u.arcsec,\n                    frame=Helioprojective, observer=smap.observer_coordinate)\n", "path": "sunpy/map/maputils.py"}], "after_files": [{"content": "\"\"\"\nThis submodule provides utility functions to act on `sunpy.map.GenericMap` instances.\n\"\"\"\nfrom itertools import chain, product\n\nimport numpy as np\n\nimport astropy.units as u\nfrom astropy.coordinates import SkyCoord\n\nfrom sunpy.coordinates import Helioprojective\n\n__all__ = ['all_pixel_indices_from_map', 'all_coordinates_from_map',\n           'map_edges', 'solar_angular_radius', 'sample_at_coords',\n           'contains_full_disk', 'is_all_off_disk', 'is_all_on_disk',\n           'contains_limb', 'coordinate_is_on_solar_disk',\n           'on_disk_bounding_coordinates']\n\n\ndef all_pixel_indices_from_map(smap):\n    \"\"\"\n    Returns pixel pair indices of every pixel in a map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A SunPy map.\n\n    Returns\n    -------\n    `~numpy.array`\n        A `numpy.array` with the all the pixel indices built from the\n        dimensions of the map.\n    \"\"\"\n    return np.meshgrid(*[np.arange(v.value) for v in smap.dimensions]) * u.pix\n\n\ndef all_coordinates_from_map(smap):\n    \"\"\"\n    Returns the coordinates of every pixel in a map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A SunPy map.\n\n    Returns\n    -------\n    `~astropy.coordinates.SkyCoord`\n        An two-dimensional array of sky coordinates in the coordinate\n        system \"coordinate_system\".\n    \"\"\"\n    x, y = all_pixel_indices_from_map(smap)\n    return smap.pixel_to_world(x, y)\n\n\ndef map_edges(smap):\n    \"\"\"\n    Returns the pixel locations of the edges of an input map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A SunPy map.\n\n    Returns\n    -------\n    top, bottom, left_hand_side, right_hand_side : `~astropy.units.Quantity`\n        Returns the pixel locations at the edge of the map;\n        the zeroth, first, second and third tuple values\n        return the top, bottom, left hand side and right\n        hand side pixel locations respectively of the input map.\n    \"\"\"\n    # Calculate all the edge pixels\n    nx, ny = smap.dimensions.x.value, smap.dimensions.y.value\n    top = list(product(np.arange(nx), [ny - 1])) * u.pix\n    bottom = list(product(np.arange(nx), [0])) * u.pix\n    left_hand_side = list(product([0], np.arange(ny))) * u.pix\n    right_hand_side = list(product([nx - 1], np.arange(ny))) * u.pix\n    return top, bottom, left_hand_side, right_hand_side\n\n\n@u.quantity_input\ndef solar_angular_radius(coordinates):\n    \"\"\"\n    Calculates the solar angular radius as seen by the observer.\n\n    The tangent of the angular size of the Sun is equal to the radius\n    of the Sun divided by the distance between the observer and the\n    center of the Sun.\n\n    Parameters\n    ----------\n    coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`\n        The input coordinate. The coordinate frame must be\n        `~sunpy.coordinates.Helioprojective`.\n\n    Returns\n    -------\n    angle : `~astropy.units.Quantity`\n        The solar angular radius.\n    \"\"\"\n    return np.arctan(coordinates.rsun / coordinates.observer.radius)\n\n\ndef sample_at_coords(smap, coordinates):\n    \"\"\"\n    Samples the data in a map at given series of coordinates.\n    Uses nearest-neighbor interpolation of coordinates in map, as\n    it effectively uses array indexing.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A SunPy map.\n    coordinates : `~astropy.coordinates.SkyCoord`\n        Input coordinates.\n    Returns\n    -------\n    `numpy.array`\n        A `numpy.array` corresponding to the data obtained from the map,\n        at the input coordinates.\n    \"\"\"\n    return smap.data[smap.wcs.world_to_array_index(coordinates)]\n\n\ndef contains_full_disk(smap):\n    \"\"\"\n    Checks if a map contains the full disk of the Sun.\n\n    A map contains the full disk of the Sun if the following two\n    conditions are met: (1) all the coordinates at the edge of the map are\n    more than solar angular radius from the center of the Sun and, (2) the\n    map is not all off disk. If both these conditions are met, the\n    function returns `True`. Otherwise, the function returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `False` if any of the coordinates at the edge of the map\n         are less than one solar radius away from the center of the Sun.\n\n    Notes\n    -----\n    This function checks if the image coordinates include the solar disk.\n    Therefore this function would return `True` for a coronagraph image\n    such as from LASCO/C3 or STEREO/SECCHI COR1 since the solar disk is\n    within the field of the view of the instrument (although no emission\n    from the disk itself is present in the data.)\n    \"\"\"\n    # Calculate all the edge pixels\n    edges = map_edges(smap)\n    edge_pixels = list(chain.from_iterable([edges[0], edges[1], edges[2], edges[3]]))\n    x = [p[0] for p in edge_pixels] * u.pix\n    y = [p[1] for p in edge_pixels] * u.pix\n\n    # Calculate the edge of the world\n    edge_of_world = smap.pixel_to_world(x, y)\n\n    # Calculate the distance of the edge of the world in solar radii\n    coordinate_angles = np.sqrt(edge_of_world.Tx ** 2 + edge_of_world.Ty ** 2)\n\n    # Test if all the edge pixels are more than one solar radius distant\n    # and that the whole map is not all off disk.\n    return np.all(coordinate_angles > solar_angular_radius(edge_of_world)) and ~is_all_off_disk(smap)\n\n\n@u.quantity_input\ndef coordinate_is_on_solar_disk(coordinates):\n    \"\"\"\n    Checks if the helioprojective Cartesian coordinates are on the solar disk.\n\n    The check is performed by comparing the coordinate's angular distance\n    to the angular size of the solar radius.  The solar disk is assumed to be\n    a circle i.e., solar oblateness and other effects that cause the solar disk to\n    be non-circular are not taken in to account.\n\n    Parameters\n    ----------\n    coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`\n        The input coordinate. The coordinate frame must be\n        `~sunpy.coordinates.Helioprojective`.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` if the coordinate is on disk, `False` otherwise.\n    \"\"\"\n\n    if not isinstance(coordinates.frame, Helioprojective):\n        raise ValueError('The input coordinate(s) must be in the Helioprojective Cartesian frame.')\n    # Calculate the angle of every pixel from the center of the Sun and compare it the angular\n    # radius of the Sun.\n    return np.sqrt(coordinates.Tx ** 2 + coordinates.Ty ** 2) < solar_angular_radius(coordinates)\n\n\ndef is_all_off_disk(smap):\n    \"\"\"\n    Checks if none of the coordinates in the `~sunpy.map.GenericMap` are on the solar disk.\n\n    The check is performed by calculating the angle of every pixel from\n    the center of the Sun. If they are all greater than the angular\n    radius of the Sun, then the function returns `True`. Otherwise, the function\n    returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` if all map pixels have an angular radius greater than\n        the angular radius of the Sun.\n\n    Notes\n    -----\n    For coronagraph images such as those from LASCO C2 and C3 the full disk is\n    within the field of view of the instrument, but the solar disk itself is not imaged.\n    For such images this function will return `False`.\n    \"\"\"\n    return np.all(~coordinate_is_on_solar_disk(all_coordinates_from_map(smap)))\n\n\ndef is_all_on_disk(smap):\n    \"\"\"\n    Checks if all of the coordinates in the `~sunpy.map.GenericMap` are on the solar disk.\n\n    The check is performed by calculating the angle of every pixel from\n    the center of the Sun. If they are all less than the angular\n    radius of the Sun, then the function returns `True`. Otherwise, the function\n    returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` if all map coordinates have an angular radius less than\n        the angular radius of the Sun.\n    \"\"\"\n    return np.all(coordinate_is_on_solar_disk(all_coordinates_from_map(smap)))\n\n\ndef contains_limb(smap):\n    \"\"\"\n    Checks if a map contains any part of the solar limb or equivalently whether\n    the map contains both on-disk and off-disk pixels.\n\n    The check is performed by calculating the angular distance of every pixel from\n    the center of the Sun.  If at least one pixel is on disk (less than the solar\n    angular radius) and at least one pixel is off disk (greater than the solar\n    angular distance), the function returns `True`. Otherwise, the function\n    returns `False`.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~bool`\n        Returns `True` If at least one coordinate of the map is on disk and at\n        least one coordinate of the map is off disk.\n\n    Notes\n    -----\n    For coronagraph images such as those from LASCO C2 and C3 the full disk is\n    within the field of view of the instrument, but the solar disk itself is not imaged.\n    For such images this function will return `True`.\n    \"\"\"\n    on_disk = coordinate_is_on_solar_disk(all_coordinates_from_map(smap))\n    return np.logical_and(np.any(on_disk), np.any(~on_disk))\n\n\ndef on_disk_bounding_coordinates(smap):\n    \"\"\"\n    Returns the the bottom left and top right coordinates of the smallest\n    rectangular region that contains all the on disk coordinates of the input map.\n\n    Parameters\n    ----------\n    smap : `~sunpy.map.GenericMap`\n        A map in helioprojective Cartesian coordinates.\n\n    Returns\n    -------\n    `~astropy.coordinates.SkyCoord`\n        A `~astropy.coordinates.SkyCoord` of length 2 such that the\n        first entry is the bottom left coordinate and the second entry is the\n        top right coordinate of the smallest rectangular region that contains\n        all the on-disk pixels in the input map.\n    \"\"\"\n    # Check that the input map is not all off disk.\n    if is_all_off_disk(smap):\n        raise ValueError(\"The entire map is off disk.\")\n\n    # Get all the coordinates from the input map\n    coordinates = all_coordinates_from_map(smap)\n\n    # Find which coordinates are on the disk\n    on_disk = coordinate_is_on_solar_disk(coordinates)\n    on_disk_coordinates = coordinates[on_disk]\n\n    # The bottom left and top right coordinates that contain\n    # the on disk coordinates.\n    tx = on_disk_coordinates.Tx.value\n    ty = on_disk_coordinates.Ty.value\n    return SkyCoord([np.nanmin(tx), np.nanmax(tx)] * u.arcsec,\n                    [np.nanmin(ty), np.nanmax(ty)] * u.arcsec,\n                    frame=Helioprojective, observer=smap.observer_coordinate)\n", "path": "sunpy/map/maputils.py"}]}