Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds feature "plot current sheet" #143

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
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/143.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added a method to plot a current sheet via :meth:`~sunkit_pyvista.plotter.SunpyPlotter.plot_current_sheet`.
49 changes: 26 additions & 23 deletions examples/field_lines.py → examples/field_lines_current_sheets.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
"""
======================================
Plotting Field Lines from sunkit-magex
======================================
=========================================================
Plotting field lines and current sheets from sunkit-magex
=========================================================

``sunkit-pyvista`` can be used to plot field lines from ``sunkit-magex``.

This example requires the `streamtracer <https://streamtracer.readthedocs.io/en/stable/>`__ package.

This example uses specific sample data from ``sunkit-magex`` to demonstrate the plotting of field lines and current sheets.
If you want to adapt this, you have to make sure that the input magnetic field data has the same date as the AIA image.
"""

import astropy.units as u
Expand All @@ -24,33 +27,16 @@
from sunkit_pyvista.sample import LOW_RES_AIA_193

###############################################################################
# We will be using an AIA 193 image from the sunpy sample data as the base image.

# sphinx_gallery_defer_figures

# Start by creating a plotter
plotter = SunpyPlotter()

# Plot a map
plotter.plot_map(LOW_RES_AIA_193, clip_interval=[1, 99] * u.percent, assume_spherical_screen=False)
# Add an arrow to show the solar rotation axis
plotter.plot_solar_axis()

###############################################################################
# We now need to do the magnetic field extrapolation using ``sunkit-magex``.

# sphinx_gallery_defer_figures
# We will start by doing the magnetic field extrapolation using ``sunkit-magex``.

# We load a gong_map from sunkit-magex
gong_fname = get_gong_map()
gong_map = sunpy.map.Map(gong_fname)
# Now we plot the Gong Map to fill in the farside.
plotter.plot_map(gong_map, cmap="hmimag", clip_interval=[1, 99] * u.percent)

# Create points spaced between lat={-90, 90} degrees
# Create points spaced between lat={-89, 89} degrees
lat = np.linspace(-np.pi / 2, np.pi / 2, 32, endpoint=False)
# Create 32 points spaced between long={0, 360} degrees
lon = np.linspace(0, 2 * np.pi, 32, endpoint=False)
lon = np.linspace(1, 2 * np.pi, 32, endpoint=False)
# Make a 2D grid from these 1D points
lat, lon = np.meshgrid(lat, lon, indexing="ij")
# Create lon, lat and radial coordinate values by using a sunkit-magex
Expand All @@ -65,6 +51,21 @@
tracer = tracing.FortranTracer()
field_lines = tracer.trace(seeds, output_)

###############################################################################
# We will be using an AIA 193 image from the sunpy sample data as the base image.

# sphinx_gallery_defer_figures

# Start by creating a plotter
plotter = SunpyPlotter()

# Plot the AIA map
plotter.plot_map(LOW_RES_AIA_193, clip_interval=[1, 99] * u.percent, assume_spherical_screen=False)
# Add an arrow to show the solar rotation axis
plotter.plot_solar_axis()
# Now we plot the Gong Map to fill in the farside.
plotter.plot_map(gong_map, cmap="hmimag", clip_interval=[1, 99] * u.percent)

###############################################################################
# We can also specify a color function while plotting the field lines.
# This function takes a single field line, and returns a color either
Expand All @@ -80,6 +81,8 @@ def my_fline_color_func(field_line):

# Plotting the field lines
plotter.plot_field_lines(field_lines, color_func=my_fline_color_func)
# Plotting the current sheet
plotter.plot_current_sheet(output_)

# Set the camera coordinate to view the plot correctly
camera_coord = SkyCoord(
Expand Down
26 changes: 26 additions & 0 deletions sunkit_pyvista/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from astropy.visualization import AsymmetricPercentileInterval
from astropy.visualization.wcsaxes import Quadrangle
from matplotlib import colors
from sunkit_magex.pfss.coords import strum2cart
from sunpy.coordinates import HeliocentricInertial, Helioprojective
from sunpy.coordinates.utils import get_rectangle_coordinates
from sunpy.map.maputils import all_corner_coords_from_map
Expand Down Expand Up @@ -509,6 +510,31 @@ def color_func(field_line):

self._add_mesh_to_dict(block_name="field_lines", mesh=spline)

def plot_current_sheet(self, pfss_out, **kwargs):
"""
Plot current sheet "(Br=0)".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the definition of a current sheet in a PFSS model?


Parameters
----------
pfss_out : `sunkit_magex.pfss.output.Output`
Magnetic field calculated by `sunkit_magex`.
**kwargs :
Keyword arguments are passed to `pyvista.Plotter.add_mesh`.
"""
sc_vect = pfss_out.grid.sc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the way we are loading the output here the same as in #72?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure but it should be looked at. I would hope we can that code instead.

If we can expand the code in 72 to work for all frames and return all the surfaces, we can then change this to plot a surface based on user input.

pc_vect = np.insert(pfss_out.grid.pc, 0, pfss_out.grid.pc[-1])
rg_vect = pfss_out.grid.rg
coord = SkyCoord((pfss_out.input_map.meta["crval1"] * u.deg).to(u.rad), 0.0 * u.rad, frame=HeliocentricInertial)
coord = coord.transform_to(self.coordinate_frame)
bc_r = np.insert(pfss_out.bc[0], 0, pfss_out.bc[0][-1], axis=0)
[s_arr, p_arr, r_arr] = np.meshgrid(sc_vect, pc_vect, rg_vect)
x_arr, y_arr, z_arr = strum2cart(r_arr, s_arr, p_arr + coord.lon.to(u.rad).value)
pfss_out_pv = pv.StructuredGrid(x_arr, y_arr, z_arr)
pfss_out_pv["Br"] = bc_r.ravel("F")
isos_br = pfss_out_pv.contour(isosurfaces=1, rng=[0, 0])
self.plotter.add_mesh(isos_br, **kwargs)
self._add_mesh_to_dict(block_name="current_sheet", mesh=isos_br)

def save(self, filepath, *, overwrite=False):
"""
Save all the meshes.
Expand Down
28 changes: 25 additions & 3 deletions sunkit_pyvista/tests/test_magex.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
This file contains tests for any methods that use sunkit-magex.
"""

import astropy.constants as const
import astropy.units as u
import matplotlib.pyplot as plt
Expand All @@ -10,6 +14,8 @@

from sunkit_pyvista import SunpyPlotter

pv.OFF_SCREEN = True


def test_field_lines_figure(aia171_test_map, plotter, verify_cache_image):
pfss = pytest.importorskip("sunkit_magex.pfss")
Expand All @@ -26,7 +32,7 @@
lat, lon = np.meshgrid(lat, lon, indexing="ij")
lat, lon = lat.ravel() * u.rad, lon.ravel() * u.rad
radius = 1.2
tracer = tracing.PythonTracer()
tracer = tracing.FortranTracer()
input_ = pfss.Input(gong_map, nrho, rss)
output_ = pfss.pfss(input_)
seeds = SkyCoord(lon, lat, radius * const.R_sun, frame=gong_map.coordinate_frame)
Expand All @@ -42,7 +48,7 @@
plotter.show(cpos=(0, 1, 0), before_close_callback=verify_cache_image)


def test_field_lines_and_color_func(plotter):
def test_field_lines_and_color_func(plotter, verify_cache_image):
pfss = pytest.importorskip("sunkit_magex.pfss")

from sunkit_magex.pfss import tracing
Expand All @@ -57,7 +63,7 @@
lat, lon = np.meshgrid(lat, lon, indexing="ij")
lat, lon = lat.ravel() * u.rad, lon.ravel() * u.rad
radius = 1.2
tracer = tracing.PythonTracer()
tracer = tracing.FortranTracer()
input_ = pfss.Input(gong_map, nrho, rss)
output_ = pfss.pfss(input_)
seeds = SkyCoord(lon, lat, radius * const.R_sun, frame=gong_map.coordinate_frame)
Expand All @@ -72,3 +78,19 @@

plotter = SunpyPlotter()
plotter.plot_field_lines(field_lines, color_func=color_func)
plotter.show(before_close_callback=verify_cache_image)

Check warning on line 81 in sunkit_pyvista/tests/test_magex.py

View check run for this annotation

Codecov / codecov/patch

sunkit_pyvista/tests/test_magex.py#L81

Added line #L81 was not covered by tests


def test_current_sheet_figure(plotter, verify_cache_image):
pfss = pytest.importorskip("sunkit_magex.pfss")

from sunkit_magex.pfss.sample_data import get_gong_map

gong_fname = get_gong_map()
gong_map = smap.Map(gong_fname)
nrho = 35
rss = 2.5
input_ = pfss.Input(gong_map, nrho, rss)
output_ = pfss.pfss(input_)
plotter.plot_current_sheet(output_)
plotter.show(before_close_callback=verify_cache_image)
6 changes: 3 additions & 3 deletions sunkit_pyvista/tests/test_plotting.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
"""
This file contains figure comparison tests.
This file contains tests for the main plotting routines.
"""

import astropy.constants as const
import astropy.units as u
import pytest
import pyvista
import pyvista as pv
import sunpy.data.test as test
import sunpy.map as smap
from astropy.coordinates import SkyCoord
from sunpy.coordinates import frames

from sunkit_pyvista import SunpyPlotter

pyvista.OFF_SCREEN = True
pv.OFF_SCREEN = True


@pytest.fixture()
Expand Down
Loading