Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/8470.trivial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Refactor coordinate-only helper functions by moving them from `sunpy.map.maputils` to `sunpy.coordinates.utils` for improved separation of responsibilitie.
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@

# Suppress warnings about overriding directives as we overload some of the
# doctest extensions.
suppress_warnings = ['app.add_directive', ]
suppress_warnings = ['app.add_directive','ref.ref' ]

# Wrap large function/method signatures
maximum_signature_line_length = 80
Expand Down Expand Up @@ -158,6 +158,7 @@
'sphinxcontrib.bibtex',
]


# Set automodapi to generate files inside the generated directory
automodapi_toctreedirnm = "generated/api"

Expand Down
5 changes: 5 additions & 0 deletions docs/nitpick-exceptions
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,8 @@ py:obj RendererBase
py:obj RuntimeError
py:obj text
py:obj Text

# Legacy references to map utilities moved to sunpy.coordinates.utils
# These appear in inherited docstrings and cannot be resolved after refactor.For issue #8445
py:obj sunpy.map.maputils
py:func sunpy.map.coordinate_is_on_solar_disk
3 changes: 3 additions & 0 deletions docs/reference/map.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ The result of a call to `~sunpy.map.Map` will be either a `~sunpy.map.mapbase.Ge
:skip: make_fitswcs_header
:skip: get_observer_meta
:skip: make_heliographic_header
:skip: coordinate_is_on_solar_disk
:skip: solar_angular_radius


Header helpers
==============
Expand Down
70 changes: 70 additions & 0 deletions sunpy/coordinates/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from astropy.coordinates.representation import CartesianRepresentation

from sunpy.coordinates import Heliocentric, HeliographicStonyhurst, get_body_heliographic_stonyhurst
from sunpy.coordinates.frames import Helioprojective
from sunpy.sun import constants

__all__ = ['GreatArc', 'get_rectangle_coordinates', 'solar_angle_equivalency', 'get_limb_coordinates', 'get_heliocentric_angle']
Expand Down Expand Up @@ -530,3 +531,72 @@ def get_heliocentric_angle(coordinate_on_solar_disk):
to_observer = CartesianRepresentation(0, 0, 1) * hcc.observer.radius - normal
heliocentric_angle = np.arctan2(normal.cross(to_observer).norm(), normal.dot(to_observer))
return heliocentric_angle.to(u.deg)

#---------------------------------------------------------#
def _verify_coordinate_helioprojective(coordinates):
"""
Raises an error if the coordinate is not in the
`~sunpy.coordinates.frames.Helioprojective` frame.

Parameters
----------
coordinates : `~astropy.coordinates.SkyCoord`, `~astropy.coordinates.BaseCoordinateFrame`
"""
frame = coordinates.frame if hasattr(coordinates, 'frame') else coordinates
if not isinstance(frame, Helioprojective):
raise ValueError(f"The input coordinate(s) is of type {type(frame).__name__}, "
"but must be in the Helioprojective frame.")

def solar_angular_radius(coordinates):
"""
Calculates the solar angular radius as seen by the observer.

The tangent vector from the observer to the edge of the Sun forms a
right-angle triangle with the radius of the Sun as the far side and the
Sun-observer distance as the hypotenuse. Thus, the sine of the angular
radius of the Sun is ratio of these two distances.

Parameters
----------
coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`
The input coordinate. The coordinate frame must be
`~sunpy.coordinates.Helioprojective`.

Returns
-------
angle : `~astropy.units.Quantity`
The solar angular radius.
"""
_verify_coordinate_helioprojective(coordinates)
rsun = coordinates.rsun
distance = coordinates.observer.radius

return np.arcsin((rsun / distance).to(u.dimensionless_unscaled))



@u.quantity_input
def coordinate_is_on_solar_disk(coordinates):
"""
Checks if the helioprojective Cartesian coordinates are on the solar disk.

The check is performed by comparing the coordinate's angular distance
to the angular size of the solar radius. The solar disk is assumed to be
a circle i.e., solar oblateness and other effects that cause the solar disk to
be non-circular are not taken in to account.

Parameters
----------
coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`
The input coordinate. The coordinate frame must be
`~sunpy.coordinates.Helioprojective`.

Returns
-------
`~bool`
Returns `True` if the coordinate is on disk, `False` otherwise.
"""
_verify_coordinate_helioprojective(coordinates)
# Calculate the radial angle from the center of the Sun (do not assume small angles)
# and compare it to the angular radius of the Sun
return np.arccos(np.cos(coordinates.Tx) * np.cos(coordinates.Ty)) <= solar_angular_radius(coordinates)
2 changes: 2 additions & 0 deletions sunpy/map/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@
from sunpy.map.maputils import *
from .compositemap import CompositeMap
from .mapsequence import MapSequence
from sunpy.map.maputils import coordinate_is_on_solar_disk, solar_angular_radius
import sunpy.map.maputils
70 changes: 5 additions & 65 deletions sunpy/map/maputils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
from astropy.coordinates import SkyCoord
from astropy.visualization import AsymmetricPercentileInterval

from sunpy.coordinates import Helioprojective, sun
from sunpy.coordinates.utils import (
_verify_coordinate_helioprojective,
coordinate_is_on_solar_disk,
solar_angular_radius,
)

__all__ = ['all_pixel_indices_from_map', 'all_coordinates_from_map',
'all_corner_coords_from_map',
Expand Down Expand Up @@ -125,44 +129,6 @@ def map_edges(smap):
return top, bottom, left_hand_side, right_hand_side


def _verify_coordinate_helioprojective(coordinates):
"""
Raises an error if the coordinate is not in the
`~sunpy.coordinates.frames.Helioprojective` frame.

Parameters
----------
coordinates : `~astropy.coordinates.SkyCoord`, `~astropy.coordinates.BaseCoordinateFrame`
"""
frame = coordinates.frame if hasattr(coordinates, 'frame') else coordinates
if not isinstance(frame, Helioprojective):
raise ValueError(f"The input coordinate(s) is of type {type(frame).__name__}, "
"but must be in the Helioprojective frame.")


def solar_angular_radius(coordinates):
"""
Calculates the solar angular radius as seen by the observer.

The tangent vector from the observer to the edge of the Sun forms a
right-angle triangle with the radius of the Sun as the far side and the
Sun-observer distance as the hypotenuse. Thus, the sine of the angular
radius of the Sun is ratio of these two distances.

Parameters
----------
coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`
The input coordinate. The coordinate frame must be
`~sunpy.coordinates.Helioprojective`.

Returns
-------
angle : `~astropy.units.Quantity`
The solar angular radius.
"""
_verify_coordinate_helioprojective(coordinates)
return sun._angular_radius(coordinates.rsun, coordinates.observer.radius)


def sample_at_coords(smap, coordinates):
"""
Expand Down Expand Up @@ -260,32 +226,6 @@ def contains_solar_center(smap):
return contains_coordinate(smap, SkyCoord(0*u.arcsec, 0*u.arcsec, frame=smap.coordinate_frame))


@u.quantity_input
def coordinate_is_on_solar_disk(coordinates):
"""
Checks if the helioprojective Cartesian coordinates are on the solar disk.

The check is performed by comparing the coordinate's angular distance
to the angular size of the solar radius. The solar disk is assumed to be
a circle i.e., solar oblateness and other effects that cause the solar disk to
be non-circular are not taken in to account.

Parameters
----------
coordinates : `~astropy.coordinates.SkyCoord`, `~sunpy.coordinates.frames.Helioprojective`
The input coordinate. The coordinate frame must be
`~sunpy.coordinates.Helioprojective`.

Returns
-------
`~bool`
Returns `True` if the coordinate is on disk, `False` otherwise.
"""
_verify_coordinate_helioprojective(coordinates)
# Calculate the radial angle from the center of the Sun (do not assume small angles)
# and compare it to the angular radius of the Sun
return np.arccos(np.cos(coordinates.Tx) * np.cos(coordinates.Ty)) <= solar_angular_radius(coordinates)


def is_all_off_disk(smap):
"""
Expand Down
Loading