HMI PFSS solutions

Calculating a PFSS solution from a HMI synoptic map.

This example shows how to calcualte a PFSS solution from a HMI synoptic map. There are a couple of important things that this example shows:

  • HMI maps have non-standard metadata, so this needs to be fixed

  • HMI synoptic maps are very big (1440 x 3600), so need to be downsampled in order to calculate the PFSS solution in a reasonable time.

First import the required modules

import os

import astropy.units as u
import matplotlib.pyplot as plt
from import Fido
from import attrs as a

import pfsspy
import pfsspy.utils

Set up the search.

Note that for SunPy versions earlier than 2.0, a time attribute is needed to do the search, even if (in this case) it isn’t used, as the synoptic maps are labelled by Carrington rotation number instead of time

time = a.Time('2010/01/01', '2010/01/01')
series = a.jsoc.Series('hmi.synoptic_mr_polfil_720s')
crot = a.jsoc.PrimeKey('CAR_ROT', 2210)

Do the search.

If you use this code, please replace this email address with your own one, registered here:

result =, series, crot,
files = Fido.fetch(result)


Export request pending. [id=JSOC_20211110_1525_X_IN, status=2]
Waiting for 0 seconds...
1 URLs found for download. Full request totalling 6MB

Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:   0%|          | 0.00/6.17M [00:00<?, ?B/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:   0%|          | 100/6.17M [00:00<2:03:02, 835B/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:   0%|          | 24.1k/6.17M [00:00<00:51, 119kB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:   1%|1         | 92.1k/6.17M [00:00<00:18, 328kB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:   4%|4         | 254k/6.17M [00:00<00:07, 740kB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:  10%|#         | 626k/6.17M [00:00<00:03, 1.61MB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:  20%|#9        | 1.21M/6.17M [00:00<00:01, 2.73MB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:  34%|###4      | 2.10M/6.17M [00:00<00:00, 4.52MB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:  49%|####9     | 3.04M/6.17M [00:00<00:00, 5.95MB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:  68%|######7   | 4.17M/6.17M [00:01<00:00, 7.43MB/s]

hmi.synoptic_mr_polfil_720s.2210.Mr_polfil.fits:  85%|########5 | 5.27M/6.17M [00:01<00:00, 8.49MB/s]

Files Downloaded: 100%|##########| 1/1 [00:01<00:00,  1.30s/file]
Files Downloaded: 100%|##########| 1/1 [00:01<00:00,  1.30s/file]

Read in a file. This will read in the first file downloaded to a sunpy Map object

hmi_map =[0])
print('Data shape: ',


Data shape:  (1440, 3600)

Since this map is far to big to calculate a PFSS solution quickly, lets resample it down to a smaller size.

hmi_map = hmi_map.resample([360, 180] * u.pix)
print('New shape: ',


New shape:  (180, 360)

Now calculate the PFSS solution

nrho = 35
rss = 2.5
pfss_in = pfsspy.Input(hmi_map, nrho, rss)
pfss_out = pfsspy.pfss(pfss_in)

Using the Output object we can plot the source surface field, and the polarity inversion line.

ss_br = pfss_out.source_surface_br
# Create the figure and axes
fig = plt.figure()
ax = plt.subplot(projection=ss_br)

# Plot the source surface map
# Plot the polarity inversion line
# Plot formatting
ax.set_title('Source surface magnetic field')
Source surface magnetic field


/home/docs/checkouts/ UserWarning: Could not parse unit string "Mx/cm^2" as a valid FITS unit.
See for the FITS unit standards.
  warnings.warn(f'Could not parse unit string "{unit_str}" as a valid FITS unit.\n'
INFO: Missing metadata for solar radius: assuming the standard radius of the photosphere. []
/home/docs/checkouts/ SunpyMetadataWarning: Missing metadata for observer: assuming Earth-based observer.

  obs_coord = self.observer_coordinate
/home/docs/checkouts/ UserWarning: Could not parse unit string "Mx/cm^2" as a valid FITS unit.
See for the FITS unit standards.
  warnings.warn(f'Could not parse unit string "{unit_str}" as a valid FITS unit.\n'

Total running time of the script: ( 0 minutes 15.591 seconds)

Gallery generated by Sphinx-Gallery