Aligning AIA and HMI Data with Reproject

A common case when using data from multiple sources, is aligning so they have the same reference frame. It is also possible to use reproject to align data, by reprojecting one image to the WCS of another. This is a very generic way of aligning data, and can be very accurate.

You will need reproject v0.6 or higher installed.

import matplotlib.pyplot as plt
from reproject import reproject_interp

import astropy.units as u

import sunpy.map
from sunpy.net import Fido
from sunpy.net import attrs as a

In this example we are going to make a lot of side by side figures, so let’s change the default figure size.

plt.rcParams['figure.figsize'] = (16, 8)

We are going to download one AIA and one HMI magnetogram image.

time = (a.vso.Sample(24 * u.hour) &
        a.Time('2010-08-19', '2010-08-19T00:10:00', '2010-08-19') &
        a.vso.Extent(0, 0, 0, 0, "FULLDISK"))
aia = a.Instrument('AIA') & a.Wavelength(17 * u.nm, 18 * u.nm)
hmi = a.Instrument('HMI') & a.vso.Physobs("LOS_magnetic_field")


res = Fido.search(time, aia | hmi)

files = Fido.fetch(res[:, 0])

Out:

/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/parfive/downloader.py:100: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.http_queue = asyncio.Queue(loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/parfive/downloader.py:101: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.http_tokens = asyncio.Queue(maxsize=self.max_conn, loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/parfive/downloader.py:102: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.ftp_queue = asyncio.Queue(loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/parfive/downloader.py:103: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.ftp_tokens = asyncio.Queue(maxsize=self.max_conn, loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)

Files Downloaded:   0%|          | 0/2 [00:00<?, ?file/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/parfive/downloader.py:312: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  done, _ = await asyncio.wait(futures, loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/aiohttp/locks.py:21: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._event = asyncio.Event(loop=loop)



hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   0%|          | 0.00/15.0M [00:00<?, ?B/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(


aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   0%|          | 0.00/12.3M [00:00<?, ?B/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(



hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   0%|          | 100/15.0M [00:00<36:26:05, 114B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   0%|          | 49.3k/15.0M [00:01<25:25:26, 163B/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   0%|          | 100/12.3M [00:00<31:54:52, 107B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   1%|          | 101k/15.0M [00:01<17:44:16, 233B/s] 

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   0%|          | 46.9k/12.3M [00:01<22:15:29, 153B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   1%|1         | 199k/15.0M [00:01<12:20:08, 332B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   2%|1         | 271k/15.0M [00:01<8:35:41, 475B/s] 

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   1%|          | 110k/12.3M [00:01<15:30:11, 219B/s] 

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   2%|1         | 195k/12.3M [00:01<10:46:39, 312B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   3%|2         | 398k/15.0M [00:01<5:57:56, 678B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   4%|3         | 581k/15.0M [00:01<4:07:27, 968B/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   2%|2         | 261k/12.3M [00:01<7:30:19, 446B/s] 


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   5%|4         | 686k/15.0M [00:01<2:52:00, 1.38kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   3%|3         | 384k/12.3M [00:01<5:12:05, 637B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   6%|5         | 866k/15.0M [00:01<1:58:55, 1.97kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   5%|4         | 572k/12.3M [00:01<3:35:02, 910B/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   7%|7         | 1.07M/15.0M [00:01<1:22:03, 2.82kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   6%|5         | 732k/12.3M [00:01<2:28:31, 1.30kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:   9%|8         | 1.29M/15.0M [00:01<56:34, 4.03kB/s]  

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   8%|8         | 1.01M/12.3M [00:01<1:41:30, 1.86kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  11%|#         | 1.59M/15.0M [00:02<38:45, 5.75kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:   9%|9         | 1.16M/12.3M [00:02<1:10:08, 2.65kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  13%|#2        | 1.91M/15.0M [00:02<26:29, 8.21kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  12%|#2        | 1.48M/12.3M [00:02<47:42, 3.79kB/s]  


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  15%|#4        | 2.23M/15.0M [00:02<18:06, 11.7kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  18%|#8        | 2.72M/15.0M [00:02<12:12, 16.7kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  14%|#4        | 1.77M/12.3M [00:02<32:30, 5.41kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  21%|##        | 3.11M/15.0M [00:02<08:17, 23.8kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  17%|#7        | 2.10M/12.3M [00:02<22:03, 7.72kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  23%|##3       | 3.50M/15.0M [00:02<05:37, 33.9kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  20%|##        | 2.48M/12.3M [00:02<14:53, 11.0kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  27%|##6       | 4.01M/15.0M [00:02<03:46, 48.4kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  23%|##3       | 2.85M/12.3M [00:02<10:02, 15.7kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  30%|###       | 4.54M/15.0M [00:02<02:31, 68.8kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  26%|##6       | 3.25M/12.3M [00:02<06:44, 22.4kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  34%|###3      | 5.03M/15.0M [00:02<01:41, 97.6kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  30%|##9       | 3.67M/12.3M [00:02<04:31, 31.9kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  37%|###6      | 5.49M/15.0M [00:03<01:08, 138kB/s] 

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  33%|###3      | 4.11M/12.3M [00:02<03:00, 45.4kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  40%|###9      | 5.92M/15.0M [00:03<00:46, 195kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  37%|###6      | 4.55M/12.3M [00:03<02:00, 64.6kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  43%|####2     | 6.41M/15.0M [00:03<00:31, 274kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  41%|####      | 5.03M/12.3M [00:03<01:19, 91.6kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  47%|####6     | 6.97M/15.0M [00:03<00:20, 383kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  44%|####3     | 5.41M/12.3M [00:03<00:53, 130kB/s] 


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  50%|#####     | 7.50M/15.0M [00:03<00:14, 529kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  48%|####7     | 5.90M/12.3M [00:03<00:35, 183kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  54%|#####4    | 8.13M/15.0M [00:03<00:09, 726kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  51%|#####1    | 6.30M/12.3M [00:03<00:23, 256kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  59%|#####8    | 8.81M/15.0M [00:03<00:06, 981kB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  55%|#####5    | 6.82M/12.3M [00:03<00:15, 357kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  62%|######2   | 9.32M/15.0M [00:03<00:04, 1.29MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  60%|#####9    | 7.35M/12.3M [00:03<00:10, 495kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  66%|######5   | 9.86M/15.0M [00:03<00:03, 1.67MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  64%|######4   | 7.90M/12.3M [00:03<00:06, 675kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  70%|######9   | 10.4M/15.0M [00:03<00:02, 2.11MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  68%|######7   | 8.34M/12.3M [00:03<00:04, 904kB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  74%|#######3  | 11.0M/15.0M [00:04<00:01, 2.47MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  71%|#######1  | 8.78M/12.3M [00:04<00:03, 1.18MB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  79%|#######8  | 11.8M/15.0M [00:04<00:01, 2.99MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  75%|#######5  | 9.27M/12.3M [00:04<00:02, 1.52MB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  83%|########3 | 12.5M/15.0M [00:04<00:00, 3.59MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  79%|#######9  | 9.77M/12.3M [00:04<00:01, 1.92MB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  87%|########7 | 13.0M/15.0M [00:04<00:00, 3.97MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  83%|########3 | 10.2M/12.3M [00:04<00:00, 2.32MB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  91%|######### | 13.6M/15.0M [00:04<00:00, 4.27MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  87%|########6 | 10.7M/12.3M [00:04<00:00, 2.72MB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  94%|#########4| 14.1M/15.0M [00:04<00:00, 4.49MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  91%|######### | 11.2M/12.3M [00:04<00:00, 3.13MB/s]


hmi_m_45s_2010_08_19_00_01_30_tai_magnetogram.fits:  98%|#########8| 14.7M/15.0M [00:04<00:00, 4.65MB/s]

aia_lev1_171a_2010_08_19t00_00_00_34z_image_lev1.fits:  95%|#########5| 11.7M/12.3M [00:04<00:00, 3.52MB/s]


                                                                                                        
Files Downloaded:  50%|#####     | 1/2 [00:06<00:06,  6.20s/file]

                                                                                                           
Files Downloaded: 100%|##########| 2/2 [00:06<00:00,  3.10s/file]

We create a map for each image and resample each one just to reduce the computation time.

map_aia, map_hmi = [m.resample((1024, 1024)*u.pix) for m in sunpy.map.Map(sorted(files))]
# Why do we have to do this?
map_hmi.plot_settings['cmap'] = "hmimag"
map_hmi.plot_settings['norm'] = plt.Normalize(-2000, 2000)

Out:

/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/asyncio/base_events.py:654: ResourceWarning: unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=False>
  _warn(f"unclosed event loop {self!r}", ResourceWarning, source=self)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER1 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER2 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER1 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER2 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,

Plot both images side by side.

fig = plt.figure()

ax1 = fig.add_subplot(1, 2, 1, projection=map_aia)
map_aia.plot(axes=ax1)

ax2 = fig.add_subplot(1, 2, 2, projection=map_hmi)
map_hmi.plot(axes=ax2)
AIA $171 \; \mathrm{\mathring{A}}$ 2010-08-19 00:00:00, HMI magnetogram 2010-08-19 00:00:39

Out:

/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER1 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER2 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,

<matplotlib.image.AxesImage object at 0x7fe6f9ef5130>

We can now reproject the HMI image to the WCS of the AIA image. We are using the fast reproject_interp, however the slower but most accurate reproject_exact would also work well here. The reproject_exact function only works when reprojecting between two WCSes with the same observer, which makes it well suited to aligning data.

output, footprint = reproject_interp(map_hmi, map_aia.wcs, map_aia.data.shape)

Out:

/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER1 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:464: FITSFixedWarning: CRDER2 = 'nan '
a floating-point value was expected.
  wcsprm = _wcs.Wcsprm(header=header_bytes, key=key,

Construct an output map and set some nice plotting defaults.

out_hmi = sunpy.map.Map(output, map_aia.wcs)
out_hmi.plot_settings['cmap'] = "hmimag"
out_hmi.plot_settings['norm'] = plt.Normalize(-1500, 1500)

fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1, projection=map_aia)
map_aia.plot(axes=ax1)
ax2 = fig.add_subplot(1, 2, 2, projection=out_hmi)
out_hmi.plot(axes=ax2)
AIA $171 \; \mathrm{\mathring{A}}$ 2010-08-19 00:00:00,  $0 \; \mathrm{}$ 2010-08-19 00:00:00

Out:

/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/v1.1.4/lib/python3.8/site-packages/astropy/wcs/wcs.py:684: FITSFixedWarning: 'datfix' made the change 'Set DATE-REF to '1858-11-17' from MJD-REF'.
  warnings.warn(

<matplotlib.image.AxesImage object at 0x7fe6faa9cb80>

As both of these images are now on the same pixel grid we can directly plot them over one another, by setting the transparency of the HMI plot.

fig = plt.figure(figsize=(20, 15))
ax1 = fig.add_subplot(1, 1, 1, projection=map_aia)
map_aia.plot(axes=ax1)
out_hmi.plot(axes=ax1, alpha=0.5)

plt.show()
$0 \; \mathrm{}$ 2010-08-19 00:00:00

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

Gallery generated by Sphinx-Gallery