<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://sunpy.org/</id>
  <title>Blog</title>
  <updated>2026-04-16T16:25:21.812945+00:00</updated>
  <link href="https://sunpy.org/"/>
  <link href="https://sunpy.org/blog/atom.xml" rel="self"/>
  <generator uri="https://ablog.readthedocs.io/" version="0.11.13">ABlog</generator>
  <entry>
    <id>https://sunpy.org/posts/2026/artemis_2_eclipse/</id>
    <title>Artemis II Solar Eclipse</title>
    <updated>2026-04-09T00:00:00+00:00</updated>
    <author>
      <name>Albert Y. Shih</name>
    </author>
    <content type="html">&lt;section id="artemis-ii-solar-eclipse"&gt;

&lt;p&gt;The Artemis II mission launched on the 1st April 2026; this launch date allowed the crew to observe a solar eclipse on the 6th April(EDT) / 7th April (UTC) after transiting the far side of the moon.&lt;/p&gt;
&lt;figure class="align-default" id="id1"&gt;
&lt;img alt="Artemis 2 Solar Eclipse with Capsule" src="https://sunpy.org/_images/art2_eclipse_ship.jpg" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;Image credit NASA&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We on the SunPy blog &lt;a class="reference internal" href="../posts/2024/2024-04-03-eclipse/#2024-04-03-eclipse"&gt;&lt;span class="std std-ref"&gt;rarely miss the opportunity&lt;/span&gt;&lt;/a&gt; to talk &lt;a class="reference external" href="https://github.com/sunpy/solar-eclipse/"&gt;about a solar eclipse&lt;/a&gt;.
So when we saw the stunning photos taken by the astronauts on Artemis II, we wanted to use SunPy to compare them to other photos of the solar corona.
I do highly recommend watching the recording of the eclipse &lt;a href="https://youtu.be/dS9qqzSF3mI?si=NFfli3b7f0tYoVDP&amp;t=1683"&gt;on YouTube&lt;/a&gt;; the reactions and descriptions of the astronauts are worth it.&lt;/p&gt;
&lt;p&gt;Amongst the many amazing photos downlinked during the mission was this image of the solar eclipse:&lt;/p&gt;
&lt;figure class="align-default" id="id2"&gt;
&lt;img alt="Artemis 2 Solar Eclipse, showing the moon lit by Earthshine, multiple planets and a star field." src="https://sunpy.org/_images/art002e009301~large.jpg" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;Image credit NASA&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This image is particularly good for comparing to other solar data because the limb of the moon is clearly visible, and there are stars and planets in the image we can use as references.
These features will allow us to determine exactly where and at what angle the camera was pointing.
At the end of the post you will be able to see how we can overlay on this photo images taken by solar observing satellites.&lt;/p&gt;
&lt;section id="fitting-coordinate-information"&gt;
&lt;h2&gt;Fitting Coordinate Information&lt;/h2&gt;
&lt;p&gt;To be able to compare this image with other observations of the Sun, we need to identify where the camera was pointed and how it was rotated.
To do this we perform the following steps:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Extract the time information from the metadata stored in the image.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the time information to lookup the exact position of Artemis II.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fit the edge of the moon to identify the location of the center of the moon, and the size of the moon in the image.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the three planets visible in the lower right of the image to identify the rotation angle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the planets to fit the distortion of the lens.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All the code for this example is in &lt;span class="xref std std-ref"&gt;The sunpy Gallery&lt;/span&gt;.&lt;/p&gt;
&lt;section id="finding-the-position-of-artemis-ii"&gt;
&lt;h3&gt;Finding the position of Artemis II&lt;/h3&gt;
&lt;p&gt;The first step is to know the time the image is taken; we can extract this from the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Exif"&gt;EXIF metadata&lt;/a&gt;.
Once we have this we query &lt;a class="reference external" href="https://ssd.jpl.nasa.gov/horizons/"&gt;JPL Horizons&lt;/a&gt; for the position of Artemis II.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.coordinates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_horizons_coord&lt;/span&gt;

&lt;span class="n"&gt;artemis2_naif_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;-1024&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;artemis2_coord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_horizons_coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;artemis2_naif_id&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;2026-04-07 01:06:19&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can also use the positions returned by JPL Horizons and the coordinates packages in sunpy and astropy to visualize what part of the Artemis II trajectory was in eclipse.
To see the details of how this was done see &lt;a class="reference external" href="https://sunpy--8574.org.readthedocs.build/en/8574/generated/gallery/showcase/artemis-ii-trajectory.html"&gt;this example in the SunPy gallery&lt;/a&gt;.&lt;/p&gt;
&lt;figure class="align-default" id="id3"&gt;
&lt;img alt="Artemis 2 trajectory showing when the solar eclipse occurred." src="https://sunpy.org/_images/artemis2-corot-traj.png" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;Visualization of the Artemis II trajectory with the eclipse highlighted.&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section id="moon-limb-fitting"&gt;
&lt;h3&gt;Moon Limb Fitting&lt;/h3&gt;
&lt;p&gt;The next step is to find a known location in the image, a reference point.
The easiest one for us to use is the center of the moon, which we find by doing edge detection and Hough filtering, using &lt;a class="reference external" href="https://scikit-image.org/"&gt;scikit-image&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;skimage.feature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;canny&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;peak_local_max&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;skimage.transform&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hough_circle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hough_circle_peaks&lt;/span&gt;

&lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;canny&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eclipse_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sigma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;eclipse_image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;radii&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;hough_res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hough_circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radii&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hough_circle_peaks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hough_res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radii&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_num_peaks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;figure class="align-default" id="id4"&gt;
&lt;img alt="A cropped image of the moon showing edge detection and Hough filtering in three panes." src="https://sunpy.org/_images/figure_2.svg" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;A cropped view of the Moon, showing the results of the canny edge detection algorithm and the Hough filter.&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section id="calculating-image-scale"&gt;
&lt;h3&gt;Calculating Image Scale&lt;/h3&gt;
&lt;p&gt;Based on the determined center of the moon is and its radius in the image we can construct a coordinate system for the image.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.coordinates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.units&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;u&lt;/span&gt;

&lt;span class="n"&gt;moon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;moon&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;artemis_ii&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;R_moon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.2725076&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R_earth&lt;/span&gt;  &lt;span class="c1"&gt;# IAU mean radius&lt;/span&gt;
&lt;span class="n"&gt;dist_moon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;artemis_ii&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;separation_3d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;moon_angular_width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arcsin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R_moon&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;dist_moon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arcsec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;im_radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rad&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;
&lt;span class="n"&gt;plate_scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;moon_angular_width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;im_radius&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Using this information we can build a sunpy map (see the gallery example for details).
Plotting this alongside the locations of the planets results in:&lt;/p&gt;
&lt;figure class="align-default" id="id5"&gt;
&lt;img alt="Initial coordinate system fit, showing the lunar center, limb and expected locations of Mercury, Mars and Saturn, which are offset from their positions in the picture." src="https://sunpy.org/_images/figure_4.svg" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;Initial coordinate system fit to image, notice that the locations of the highlighted planets are incorrect.&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section id="fitting-roll-angle"&gt;
&lt;h3&gt;Fitting Roll Angle&lt;/h3&gt;
&lt;p&gt;It’s clear from the previous image that the image is rotated around the center of the moon.
We can solve for this rotation by using a peak finding algorithm to locate the planets in the image and comparing these positions to the planets coordinates extracted from JPL Horizons.
Doing this results in a &lt;span class="math notranslate nohighlight"&gt;\(-21.2^\circ\)&lt;/span&gt; roll angle which we can add to our Maps metadata.&lt;/p&gt;
&lt;figure class="align-default" id="id6"&gt;
&lt;img alt="Image showing the expected positions of the planets and the detected (peaks) positions of the planets." src="https://sunpy.org/_images/figure_5.svg" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;Image showing the expected positions of the planets and the detected (peaks) positions of the planets, from which the roll angle is calculated.&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section id="fitting-lens-distortion"&gt;
&lt;h3&gt;Fitting Lens Distortion&lt;/h3&gt;
&lt;p&gt;The final correction to apply to our fitted coordinate system is the distortion of the camera lens (a Nikkor AF 135mm f/2D DC).
This makes objects distant from the centre of the image appear even more distant than they should.
We can quantify exactly how much the image has been distorted through comparing the expected vs actual positions of Mars and Mercury (not Saturn as it is too close to the center of the image).
We add this distortion to our coordinate system and our planets now appear in the correct place.&lt;/p&gt;
&lt;figure class="align-default" id="id7"&gt;
&lt;img alt="Coordinate system fit with additional correction for lens distortion, the expected positions of the planets now match the image." src="https://sunpy.org/_images/figure_7.svg" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;Coordinate system fit to with additional correction for lens distortion.&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="overplotting-coronagraph-images"&gt;
&lt;h2&gt;Overplotting Coronagraph Images&lt;/h2&gt;
&lt;p&gt;Now that we have fit a coordinate system to the eclipse photo we can compare this observation of the corona to other data.
To do this we are going to use the coronagraph on the &lt;a class="reference external" href="https://soho.nascom.nasa.gov/"&gt;Solar and Heliospheric Observatory (SOHO)&lt;/a&gt; which is located around the Sun-Earth L1 point.
We reproject (or re-grid) these images to the fitted coordinate system of the Artemis II image to compensate for differences in satellite location and point of view, and then crop them to the limb of the moon.&lt;/p&gt;
&lt;figure class="align-default" id="id8"&gt;
&lt;img alt="The Artemis II solar eclipse photo with the positions of Mercury, Mars and Saturn highlighted, and coronagraph images from SOHO's LASCO instrument plotted over the disc of the moon." src="https://sunpy.org/_images/figure_9.svg" style="width: 100%;" /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;span class="caption-text"&gt;The Artemis II solar eclipse photo with the positions of Mercury, Mars and Saturn highlighted, and coronagraph images from SOHO’s LASCO instrument plotted over the disc of the moon.&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We hope you have found this post interesting.
The full code for this post can be found in &lt;span class="xref std std-ref"&gt;The sunpy Gallery&lt;/span&gt;.
Remember, that if you are lucky enough to observe the total solar eclipse which will be visible from parts of Europe in August 2026 and you take a photo, you can try this type of analysis with your own photos, by following our &lt;a class="reference internal" href="../posts/2024/2024-04-03-eclipse/#2024-04-03-eclipse"&gt;&lt;span class="std std-ref"&gt;previous blog post&lt;/span&gt;&lt;/a&gt;!&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2026/artemis_2_eclipse/"/>
    <summary>The Artemis II mission launched on the 1st April 2026; this launch date allowed the crew to observe a solar eclipse on the 6th April(EDT) / 7th April (UTC) after transiting the far side of the moon.</summary>
    <category term="eclipse" label="eclipse"/>
    <published>2026-04-09T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2024/2024-08-09-anaconda/</id>
    <title>Anaconda packages are not “free”</title>
    <updated>2024-08-09T00:00:00+00:00</updated>
    <author>
      <name>Nabil Freij</name>
    </author>
    <content type="html">&lt;section id="anaconda-packages-are-not-free"&gt;

&lt;p&gt;We wanted to inform the wider community about &lt;a class="reference external" href="https://www.anaconda.com/"&gt;Anaconda Inc.&lt;/a&gt; and if you are legally allowed to use their products for free.&lt;/p&gt;
&lt;p&gt;What is not commonly known is that Anaconda Inc. has implemented specific clauses in its software licenses which determine if one is able to use Anaconda or Anaconda Navigator for free, based on the organization you work for.
For example, &lt;a class="reference external" href="https://www.theregister.com/2024/08/08/anaconda_puts_the_squeeze_on/"&gt;The Register&lt;/a&gt; has reported that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Research and academic organizations are just now finding out that they will have to pay for software made by Anaconda, when for years these groups were under the impression it could be used at no cost.&lt;/p&gt;
&lt;p&gt;A source who works at a medium-size non-profit academic research institution told The Register about being on the end of a legal demand to purchase a commercial license for the Anaconda-built software they had been using for free.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.anaconda.com/blog/is-conda-free"&gt;Anaconda themselves summarize this in a really detailed blog post&lt;/a&gt;, which we use here to form the basis of this post.&lt;/p&gt;
&lt;section id="glossary"&gt;
&lt;h2&gt;Glossary&lt;/h2&gt;
&lt;p&gt;I want to define a few words which will be used heavily below:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt;&lt;/code&gt;: This refers to the binary tool that a user calls on the command line.
It is a package installation and environment management software.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;channel or conda channel: It is a centralized repository of packages (python or not) which one can install with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;distribution: It is an installer that will install &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt;&lt;/code&gt; and configure a default channel to use.
For anaconda, this is the “defaults” channel whereas for conda-forge this is the “conda-forge “ channel.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="what-is-free-to-use"&gt;
&lt;h2&gt;What is free to use?&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt;&lt;/code&gt; binary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;mamba&lt;/span&gt;&lt;/code&gt; an alternative to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anything that is provided by the &lt;a class="reference external" href="https://conda-forge.org/"&gt;conda-forge project&lt;/a&gt; which means their packages, the channels they maintain and any distribution they provide.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="what-is-not-free-to-use"&gt;
&lt;h2&gt;What is not free to use?&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Anaconda’s “defaults” channel, which is used for the base environment.
It is used if one installs the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Anaconda&lt;/span&gt;&lt;/code&gt; distribution or the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;miniconda&lt;/span&gt;&lt;/code&gt; distribution.
Anything that is “curated, built, maintained, and served by Anaconda’s engineers on its secure cloud infrastructure”, has these licenses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.anaconda.com/navigator/"&gt;Anaconda Navigator&lt;/a&gt; which is a Graphical User Interface (GUI) that many people use to manage their Anaconda install.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Using the defaults channel or Anaconda Navigator can lead to you becoming legally required to pay Anaconda Inc. for their use.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you want to use these for free, you have to meet the following conditions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Your organization has less than 200 people, or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your organization has 200 or more people, but qualifies as an exempt organization in Anaconda’s terms of service:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Students and educational entities may use our free offerings in curriculum-based courses.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.linkedin.com/posts/pzwang_hi-everyone-recently-there-has-been-discussion-activity-7229549723462905856-rQH-/"&gt;Following the publication of the Register article, the CEO of Anaconda, Peter Wang posted on Linkedin.&lt;/a&gt;
He says that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;I want to be very clear: Anaconda’s installers &amp;amp; package repos are free for teaching, learning, and research at accredited educational institutions worldwide.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Our legal team is taking a comprehensive look at the wording in our current ToS, EULA, and related documents, with a focus on clarity for academic and academic research use.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;In addition, we’re looking into a flexible pricing structure for non-profit organizations with over 200 full-time employees&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Hopefully, by the end of the year with these changes in place, users will have a clear understanding if they are allowed to use Anaconda Inc. products for free.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-is-the-alternative"&gt;
&lt;h2&gt;What is the alternative?&lt;/h2&gt;
&lt;p&gt;The answer from the SunPy Project is the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use the “conda-forge” channel provided by the conda-forge project.
conda-forge is a community-led project which creates recipes, hosts infrastructure and distributions for use with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt;&lt;/code&gt;.
They provide a distribution (similar to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;miniconda&lt;/span&gt;&lt;/code&gt;) called &lt;a class="reference external" href="https://github.com/conda-forge/miniforge"&gt;miniforge&lt;/a&gt; is configured to use the “conda-forge” channel by default.
It is also the only way to &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/tutorial/installation.html#installing-miniforge-and-conda"&gt;install any SunPy Project library&lt;/a&gt; via &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Never setup or use the “defaults” channel if you install &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;miniforge&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A blog post written by Tim de Jager &amp;amp; Ruben Arts &lt;a class="reference external" href="https://prefix.dev/blog/towards_a_vendor_lock_in_free_conda_experience"&gt;summarizes how conda-forge is free and avoids any vendor lock in.&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="i-have-anaconda-or-anaconda-navigator-already-what-should-i-do"&gt;
&lt;h2&gt;I have Anaconda or Anaconda Navigator already - What should I do?&lt;/h2&gt;
&lt;p&gt;Though, you could get rid of the default channel(s) using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conda&lt;/span&gt; &lt;span class="pre"&gt;config&lt;/span&gt;&lt;/code&gt; command as shown &lt;a class="reference external" href="https://stackoverflow.com/a/67708768"&gt;in this Stack Overflow answer about switching channels from anaconda to conda-forge&lt;/a&gt;.
This is good for new environments but it doesn’t remove what you’ve got already installed (e.g., the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;base&lt;/span&gt;&lt;/code&gt; environment) and you may be still infringing the Terms of Services for Anaconda.
If you have Anaconda Navigator, you have to remove it unless you know that you are not violating the license requirements.&lt;/p&gt;
&lt;p&gt;Therefore, the cleanest method is to completely remove Anaconda and Anaconda Navigator and install &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/tutorial/installation.html#installing-miniforge-and-conda"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;miniforge&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;.
Unfortunately, there is no automated way of recreating all of your environments, and &lt;a class="reference external" href="https://it.martinos.org/help/migrating-anaconda-miniconda-install-to-a-miniforge-install/"&gt;this post about migrating from Anaconda to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;miniforge&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; details the steps that one has to follow to migrate.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2024/2024-08-09-anaconda/"/>
    <summary>We wanted to inform the wider community about Anaconda Inc. and if you are legally allowed to use their products for free.</summary>
    <published>2024-08-09T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2024/2024-06-19-groupaward/</id>
    <title>SunPy Development Team wins a NASA Group Achievement Award!</title>
    <updated>2024-06-19T00:00:00+00:00</updated>
    <author>
      <name>Laura Hayes</name>
    </author>
    <content type="html">&lt;section id="sunpy-development-team-wins-a-nasa-group-achievement-award"&gt;

&lt;p&gt;We are delighted to announce that the SunPy development team has been awarded with a NASA Group Achievement Award!&lt;/p&gt;
&lt;p&gt;The award was given to our team for “developing and continually improving free and reliable open-source software that supports NASA missions and the analysis of NASA’s vast archives of solar physics data”.&lt;/p&gt;
&lt;p&gt;This award is a collective achievement, and we share it with everyone who has contributed to SunPy!
We look forward to continuing our mission of supporting solar physics research and making impactful contributions to the scientific community.&lt;/p&gt;
&lt;p&gt;&lt;img alt="SunPy Award" src="https://sunpy.org/_images/sunpy_award.jpg" /&gt;&lt;/p&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2024/2024-06-19-groupaward/"/>
    <summary>We are delighted to announce that the SunPy development team has been awarded with a NASA Group Achievement Award!</summary>
    <published>2024-06-19T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2024/2024-04-03-eclipse/</id>
    <title>Process Your Solar Eclipse Photos with SunPy!</title>
    <updated>2024-04-03T00:00:00+00:00</updated>
    <author>
      <name>Stuart Mumford</name>
    </author>
    <content type="html">&lt;div class="admonition note"&gt;
&lt;p&gt;This blog post was written in a &lt;a class="reference external" href="https://github.com/sunpy/sunpy.org/blob/main/posts/2024/2024-04-03-eclipse.ipynb"&gt;Jupyter notebook&lt;/a&gt;.
Click here for an interactive version:
&lt;span class="raw-html"&gt;&lt;a href="https://mybinder.org/v2/gh/sunpy/sunpy.org/main?filepath=posts/2024/2024-04-03-eclipse.ipynb"&gt;&lt;img alt="Binder badge" src="https://mybinder.org/badge.svg" style="vertical-align:text-bottom"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;section id="Process-Your-Solar-Eclipse-Photos-with-SunPy!"&gt;

&lt;p&gt;On April 8th, 2024, &lt;a class="reference external" href="https://science.nasa.gov/eclipses/"&gt;a total solar eclipse will pass over North America&lt;/a&gt;. A total solar eclipse happens when the Moon passes between the Sun and Earth, completely blocking the face of the Sun. Only during totality, when the bright disk is completely obscured, is it possible to see with the naked eye the solar corona, the outermost layer of the Sun’s atmosphere. The total solar eclipse will give millions across North America the chance to see and photograph
the solar corona.&lt;/p&gt;
&lt;p&gt;In this blog post, we will show how you can use SunPy to process your photos of the eclipse. To do this, we will use an image from the 2017 solar eclipse that also passed over North America, the so-called “Great American Eclipse”. We will walk through processing this image with SunPy as well as other Python libraries, so that you can generate a coordinate system for your image. As we will show, this allows you to combine your eclipse images with solar observations such as those from NASA’s
&lt;em&gt;Solar Dynamics Observatory&lt;/em&gt;.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[1]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;pathlib&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.units&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;u&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;exifread&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;matplotlib.image&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;plt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.coordinates&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.coordinates.sun&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.constants&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;R_earth&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.coordinates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CartesianRepresentation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EarthLocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;

&lt;span class="c1"&gt;# We have defined a few helper functions in this `eclipse_helpers.py` file.&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;eclipse_helpers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SOLAR_ECLIPSE_IMAGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_camera_metadata&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;matplotlib.patches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Circle&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;scipy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ndimage&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;skimage.color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rgb2gray&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;skimage.feature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;peak_local_max&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;skimage.transform&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hough_circle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hough_circle_peaks&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.map.header_helper&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;make_fitswcs_header&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.net&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fido&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.net&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;attrs&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parse_time&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;section id="Read-in-Your-Eclipse-Photo"&gt;
&lt;h2&gt;Read in Your Eclipse Photo&lt;/h2&gt;
&lt;p&gt;The first step is to read in our image. As mentioned above, we will be using an image taken during the 2017 eclipse taken with a consumer-grade camera. When reading in our image data, we’ll invert the y-axis and convert it to a grayscale image.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[2]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;im_rgb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flipud&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matplotlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SOLAR_ECLIPSE_IMAGE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;im&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rgb2gray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im_rgb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area stderr docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
/Users/nabil/micromamba/envs/sunpy-dev/lib/python3.13/site-packages/skimage/color/colorconv.py:984: RuntimeWarning: divide by zero encountered in matmul
  return rgb @ coeffs
/Users/nabil/micromamba/envs/sunpy-dev/lib/python3.13/site-packages/skimage/color/colorconv.py:984: RuntimeWarning: overflow encountered in matmul
  return rgb @ coeffs
/Users/nabil/micromamba/envs/sunpy-dev/lib/python3.13/site-packages/skimage/color/colorconv.py:984: RuntimeWarning: invalid value encountered in matmul
  return rgb @ coeffs
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[3]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;lower&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;gray&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_6_0.png" src="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_6_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In order to be able to align our image with solar images from NASA, we will also need some additional metadata from our image. The two most important things we need to know are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;the GPS coordinates of where the photo was taken and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the time the image was taken&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can pull this metadata from the file and then use an additional function we wrote to process this metadata into a Python dictionary.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[4]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SOLAR_ECLIPSE_IMAGE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;rb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exifread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;process_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[5]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_camera_metadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As it turns out, the time on the camera used to take this eclipse photo was wrong, we have to manually correct it.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[6]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2017-08-21 17:27:13&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Find-the-Moon"&gt;
&lt;h2&gt;Find the Moon&lt;/h2&gt;
&lt;p&gt;Now that we’ve loaded our image and accompanying metadata, the next step is to locate the edge of the Moon in our image. This allows us to find the center of the Moon, which is needed when aligning our data, as well as allowing us to determine the scale of the Moon in the image. In order to do this we are going to use several different image manipulation techniques.&lt;/p&gt;
&lt;p&gt;We start with applying a &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Gaussian_filter"&gt;Gaussian blur&lt;/a&gt; to help segment the lunar disk from the corona and mask all parts of the image above a given threshold.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[7]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;blur_im&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ndimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gaussian_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blur_im&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;blur_im&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_14_0.png" src="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_14_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We then label those masked regions and select only the parts of the image that correspond to the bright, diffuse corona.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[8]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;label_im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nb_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ndimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;slice_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slice_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ndimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_objects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label_im&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;roi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blur_im&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;slice_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slice_x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The next step is to detect the inner edge of the bright corona. To do this, we apply a &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Sobel_operator"&gt;Sobel filter&lt;/a&gt; in both the x and y directions, and then calculate a single image from the two directions.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[9]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;sx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ndimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sobel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;constant&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ndimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sobel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;constant&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hypot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we use scikit-image to apply the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Hough_transform"&gt;Hough Transform&lt;/a&gt; to identify circles in the image. We then use this to extract the size in pixels of the lunar disk and its center.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[10]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;hough_radii&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;hough_res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hough_circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sob&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;hough_radii&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Select the most prominent circle&lt;/span&gt;
&lt;span class="n"&gt;accums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radii&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hough_circle_peaks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hough_res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hough_radii&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_num_peaks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As shown below, we now have a list of pixel coordinates corresponding to the solar limb in our image. The first frame is the cropped original image. The middle frame is the Sobel filtered image used to apply the Hough transform. The right frame is the fitted circle on the original image.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[11]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ncols&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nrows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;9.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;slice_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slice_x&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Original&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sob&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Sobel&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;circ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;radii&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;facecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edgecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linewidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;dashed&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Hough fit&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;slice_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slice_x&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;circ&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Original with fit&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_22_0.png" src="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_22_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Lastly, let’s add units to our circle that we fit the lunar limb.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[12]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;im_cx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;slice_x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;
&lt;span class="n"&gt;im_cy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;slice_y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;
&lt;span class="n"&gt;im_radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;radii&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Make-a-SunPy-Map"&gt;
&lt;h2&gt;Make a SunPy &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;At this point, we have our image data, it’s metadata and we’ve located the Moon. Now we are ready to load our eclipse photograph into a SunPy &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt;! A &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt; allows us to carry around both the data and metadata of our image together and, importantly, makes it easy to combine solar observations from multiple observatories.&lt;/p&gt;
&lt;p&gt;First, we define the observer location (i.e., where on Earth did we take our picture?) and the orientation of the Sun in the sky. For the observer location, we can use the GPS coordinates from our image metadata.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[13]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EarthLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;gps&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;lon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;gps&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;gps&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_itrs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Second, we determine the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Angular_diameter"&gt;angular size&lt;/a&gt; of the Moon using its radius and its distance from the observer.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[14]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;moon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coordinates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_body_heliographic_stonyhurst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;moon&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;R_moon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.2725076&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;R_earth&lt;/span&gt;  &lt;span class="c1"&gt;# IAU mean radius&lt;/span&gt;
&lt;span class="n"&gt;dist_moon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;separation_3d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;moon_obs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arcsin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R_moon&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;dist_moon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;arcsec&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moon_obs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area stderr docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
2025-06-23 09:08:55 - sunpy - INFO: Apparent body location accounts for 1.23 seconds of light travel time
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
INFO: Apparent body location accounts for 1.23 seconds of light travel time [sunpy.coordinates.ephemeris]
975.9073137731282 arcsec
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Combining this angular radius with the radius of the lunar disk in pixels gives us the angular size of the pixels in the image. In the parlance of astronomical imaging, this is often referred to as the &lt;em&gt;plate scale&lt;/em&gt;.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[15]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;plate_scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;moon_obs&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;im_radius&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plate_scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
4.356729079344322 arcsec / pix
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We also use the observer location to calculate the orientation of the Sun as seen from that location on Earth. This gives us a rotation angle between our image coordinate system and the solar north pole. If your camera is not perfectly horizontal then you may need to fudge this value slightly.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[16]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;solar_rotation_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coordinates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;solar_rotation_angle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
-54d19m44.13467961s
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally we have all the information we need to build a sunpy &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt; for our eclipse image.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[17]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coordinates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Helioprojective&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obstime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;moon_hpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;moon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_fitswcs_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;moon_hpc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reference_pixel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;im_cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;im_cy&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;plate_scale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plate_scale&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="n"&gt;rotation_angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;solar_rotation_angle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exposure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exposure_time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instrument&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;camera_model&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;observatory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;author&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[18]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[19]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_38_0.png" src="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_38_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Find-a-Star"&gt;
&lt;h2&gt;Find a Star&lt;/h2&gt;
&lt;p&gt;Though we already have all of the metadata we need to make a SunPy &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt;, we can further improve the accuracy by locating a known star in the image and using that to determine the rotation angle. In the case of the 2017 eclipse the very bright star (magnitude 1.4) &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Regulus"&gt;Regulus&lt;/a&gt; was close to the Sun and in the field of view of our photograph. For the 2024 eclipse, no such bright star will be visible, which may make this method of aligning your image
challenging. The best candidate looks to be &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Alpha_Piscium"&gt;Alpha Piscium&lt;/a&gt; which is a binary system with a combined magnitude of 3.82, significantly dimmer than Regulus. You can see the stars close to the Sun by using &lt;a class="reference external" href="https://stellarium-web.org/skysource/Sun?fov=1.1092&amp;amp;date=2024-04-08T18:30:47Z&amp;amp;lat=28.86&amp;amp;lng=-100.53&amp;amp;elev=0"&gt;Stellarium&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As Regulus is a well known star, we can create a coordinate object for it, including its distance.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[20]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;regulus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ra&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;10h08m22.311s&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;11d58m01.95s&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;79.3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lightyear&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;icrs&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regulus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
&amp;lt;SkyCoord (ICRS): (ra, dec, distance) in (deg, deg, lyr)
    (152.0929625, 11.96720833, 79.3)&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can then plot the expected location of Regulus on our eclipse image. We set the scaling such that it make Regulus more visible and zoom in on the relevant part of the field of view. You can see that the expected location and the actual location are quite different.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[21]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clip_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot_coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;regulus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;o&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markeredgewidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markeredgecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markerfacecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;None&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markersize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Regulus&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_43_0.png" src="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_43_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Given this offset, we want to fix our image metadata such that the actual and expected locations of Regulus are line up. We can calculate the expected distance from the center of the Sun to Regulus in pixels.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[22]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;regulus_pixel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CartesianRepresentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wcs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;world_to_pixel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regulus&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;
&lt;span class="n"&gt;sun_pixel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CartesianRepresentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wcs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;world_to_pixel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SkyCoord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arcsec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arcsec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;regulus_r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regulus_pixel&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;sun_pixel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regulus_r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
1084.0811009031981 pix
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We then use this to find Regulus in our image, by filtering out all pixels which are closer to the Sun than this.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[23]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;pix_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;sun_pixel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="n"&gt;pix_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;sun_pixel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="n"&gt;xx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;meshgrid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pix_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pix_y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xx&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;filter_r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;regulus_r&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regulus_r&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;masked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;masked&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;filter_r&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;masked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Having masked out most of the Sun and its corona, we now find the highest peak remaining, which should be Regulus.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[24]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;regulus_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;regulus_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;peak_local_max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;masked&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min_distance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num_peaks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;actual_regulus_pixel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CartesianRepresentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regulus_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;regulus_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can now compare the identified pixel coordinates of Regulus to the expected coordinates assuming the camera was exactly horizontal.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[25]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual_regulus_pixel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regulus_pixel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
(372., 247., 0.) pix
(339.45349652, 307.65804366, 0.) pix
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we calculate the angular offset between our expected location and our identified location and then add this difference to correct our solar rotation angle.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[26]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vec_expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;regulus_pixel&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;sun_pixel&lt;/span&gt;
&lt;span class="n"&gt;vec_actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;actual_regulus_pixel&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;sun_pixel&lt;/span&gt;
&lt;span class="n"&gt;fudge_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arccos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vec_expected&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vec_actual&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vec_expected&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;vec_actual&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fudge_angle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
-3.5738144694153595 deg
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We then use this correction factor to build a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt; for our image with updated metadata.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[27]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_fitswcs_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;moon_hpc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reference_pixel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;im_cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;im_cy&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;plate_scale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plate_scale&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="n"&gt;rotation_angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;solar_rotation_angle&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fudge_angle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exposure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exposure_time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;instrument&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;camera_metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;camera_model&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[28]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Plotting our image again, we now find that the identified location of Regulus and our image line up much better.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[29]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clip_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot_coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;regulus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;o&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markeredgewidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markeredgecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markerfacecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;None&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markersize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Regulus&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_58_0.png" src="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_58_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Combine-your-Image-with-NASA-Data"&gt;
&lt;h2&gt;Combine your Image with NASA Data&lt;/h2&gt;
&lt;p&gt;As mentioned above, one of the main advantages of having data in a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt; is that it is then easy to combine observations from multiple different sources. Let’s overlay an AIA image from the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Solar_Dynamics_Observatory"&gt;SDO&lt;/a&gt; satellite. We’ll choose an image that shows extreme ultraviolet emission from the corona, revealing plasma that is around one million degrees. Fortunately, all SDO data is publicly available and SunPy provides a convenient interface for
searching for and downloading this data.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[30]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;aia_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Fido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2017-08-21 17:27:00&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;2017-08-21 17:45:00&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Instrument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;AIA&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wavelength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;171&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Angstrom&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aia_result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
Results from 1 Provider:

1 Results from the VSOClient:
Source: https://sdac.virtualsolar.org/cgi/search
Data retrieval status: https://docs.virtualsolar.org/wiki/VSOHealthReport
Total estimated size: 67.789 Mbyte

       Start Time               End Time        Source Instrument   Wavelength   Provider  Physobs  Wavetype Extent Width Extent Length Extent Type   Size
                                                                     Angstrom                                                                        Mibyte
----------------------- ----------------------- ------ ---------- -------------- -------- --------- -------- ------------ ------------- ----------- --------
2017-08-21 17:27:09.000 2017-08-21 17:27:10.000    SDO        AIA 171.0 .. 171.0     JSOC intensity   NARROW         4096          4096    FULLDISK 64.64844


&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[31]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;aia_result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[31]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area rendered_html docutils container"&gt;
&lt;i&gt;QueryResponseRow index=0&lt;/i&gt;
&lt;table id="table5781630928"&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Start Time&lt;/th&gt;&lt;th&gt;End Time&lt;/th&gt;&lt;th&gt;Source&lt;/th&gt;&lt;th&gt;Instrument&lt;/th&gt;&lt;th&gt;Wavelength&lt;/th&gt;&lt;th&gt;Provider&lt;/th&gt;&lt;th&gt;Physobs&lt;/th&gt;&lt;th&gt;Wavetype&lt;/th&gt;&lt;th&gt;Extent Width&lt;/th&gt;&lt;th&gt;Extent Length&lt;/th&gt;&lt;th&gt;Extent Type&lt;/th&gt;&lt;th&gt;Size&lt;/th&gt;&lt;th&gt;fileid&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Angstrom&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Mibyte&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Time&lt;/th&gt;&lt;th&gt;Time&lt;/th&gt;&lt;th&gt;str3&lt;/th&gt;&lt;th&gt;str3&lt;/th&gt;&lt;th&gt;float64[2]&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str9&lt;/th&gt;&lt;th&gt;str6&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str8&lt;/th&gt;&lt;th&gt;float64&lt;/th&gt;&lt;th&gt;str24&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;2017-08-21 17:27:09.000&lt;/td&gt;&lt;td&gt;2017-08-21 17:27:10.000&lt;/td&gt;&lt;td&gt;SDO&lt;/td&gt;&lt;td&gt;AIA&lt;/td&gt;&lt;td&gt;171.0 .. 171.0&lt;/td&gt;&lt;td&gt;JSOC&lt;/td&gt;&lt;td&gt;intensity&lt;/td&gt;&lt;td&gt;NARROW&lt;/td&gt;&lt;td&gt;4096&lt;/td&gt;&lt;td&gt;4096&lt;/td&gt;&lt;td&gt;FULLDISK&lt;/td&gt;&lt;td&gt;64.64844&lt;/td&gt;&lt;td&gt;aia__lev1:171:1282411667&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[32]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Fido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aia_result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;NSO&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;script type="application/vnd.jupyter.widget-view+json"&gt;{"model_id": "e1bb25088ab040349b6cd148fdea0e89", "version_major": 2, "version_minor": 0}&lt;/script&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[33]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[33]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
&amp;lt;parfive.results.Results object at 0x158950690&amp;gt;
[&amp;#39;/Users/nabil/sunpy/data/aia.lev1.171A_2017_08_21T17_27_09.35Z.image_lev1.fits&amp;#39;]
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Having downloaded this data we create a SunPy &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt; and then plot it on top of our eclipse image. Note that despite not being in the same coordinate system, our AIA &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt; is automatically transformed to the coordinate system of our image before plotting.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[34]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;aia_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[35]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;eclipse_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;aia_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;autoalign&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;aia_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;draw_grid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area stderr docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
2025-06-23 09:09:07 - sunpy - INFO: Using mesh-based autoalignment
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
INFO: Using mesh-based autoalignment [sunpy.map.mapbase]
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_66_2.png" src="https://sunpy.org/_images/posts_2024_2024-04-03-eclipse_66_2.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this blog post, we demonstrated how to read your eclipse images into a SunPy &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/code&gt; and how to combine your own photographs with data from NASA observations of the Sun. Though this post used data from the 2017 eclipse, you should be able to use the same techniques to process your 2024 eclipse observations. Happy eclipse viewing!&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2024/2024-04-03-eclipse/"/>
    <summary>On 8 April 2024, a total solar eclipse will pass over Mexico, the United States, and Canada, allowing millions of people to see the highly-structured solar corona with their own eyes. Along the path of totality, many will be taking their own pictures of the eclipse. In this post we demonstrate how you can use SunPy to process your own eclipse photos!</summary>
    <category term="eclipse" label="eclipse"/>
    <category term="outreach" label="outreach"/>
    <category term="tutorials" label="tutorials"/>
    <published>2024-04-03T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2024/2024-01-24-pyopensci/</id>
    <title>pyOpenSci and sunpy</title>
    <updated>2024-01-24T00:00:00+00:00</updated>
    <author>
      <name>Nabil Freij</name>
    </author>
    <content type="html">&lt;section id="pyopensci-and-sunpy"&gt;

&lt;p&gt;&lt;img alt="pyOpenSci logo" src="https://avatars.githubusercontent.com/u/28938222?s=200&amp;amp;v=4" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.pyopensci.org/"&gt;pyOpenSci&lt;/a&gt; is a “diverse community of people interested in building a community of practice around scientific software written in Python”.
They are an exciting community working on improving the information around the packaging and tooling used by the scientific Python community as well to provide support for package maintainers.
There is a review process to become a pyOpenSci accepted package which comes with two reviews from independent members of the wider community.&lt;/p&gt;
&lt;p&gt;With this in mind, the SunPy Project decided to submit the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt; package to pyOpenSci to ensure that it is aligned with the community that pyOpenSci is building, and increase visibility of SunPy.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/pyOpenSci/software-submission/issues/147"&gt;The review&lt;/a&gt; was started on the &lt;a class="reference external" href="https://github.com/pyOpenSci/software-submission"&gt;pyOpenSci software-submission repository&lt;/a&gt;.
The entire review process is open, with one editor and two reviewers and the entire exchange between the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt; maintainers and the reviewers are on that issue.
This process was incredibly helpful as it highlighted areas of our documentation which could be improved and some technical choices that were made several years ago but now were redundant or not best practice.&lt;/p&gt;
&lt;p&gt;After these issues were fixed, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt; was accepted into pyOpenSci and we added the badge to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt; readme.
The plan in future is to submit more SunPy Project packages as well as integrate more closely with pyOpenSci to replace our own affiliated package system.
Our hope is that by aligning with pyOpenSci we can help to contribute back to the wider community.&lt;/p&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2024/2024-01-24-pyopensci/"/>
    <summary>pyOpenSci logo</summary>
    <published>2024-01-24T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2023/2023-05-10-timeseries_sdg/</id>
    <title>The future of time series data in sunpy</title>
    <updated>2023-05-10T00:00:00+00:00</updated>
    <author>
      <name>David Stansby</name>
    </author>
    <content type="html">&lt;section id="the-future-of-time-series-data-in-sunpy"&gt;

&lt;p&gt;In late 2022 I got a &lt;a class="reference external" href="https://numfocus.org/programs/small-development-grants"&gt;small development grant&lt;/a&gt; from &lt;a class="reference external" href="https://numfocus.org/"&gt;NumFocus&lt;/a&gt; to scope the future of time series data in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt;.
The successful application &lt;a class="reference external" href="https://github.com/sunpy/sunpy/wiki/2022-Timeseries-Small-Development-Grant"&gt;can be read on the sunpy wiki&lt;/a&gt;.
The application contains context that I won’t repeat here.
This blog post is the key outcome of this grant, with a record of what I did, the recommendations I made, and any decisions we came to as a community.&lt;/p&gt;
&lt;section id="user-requirements"&gt;
&lt;h2&gt;User requirements&lt;/h2&gt;
&lt;p&gt;The first stage of my work investigated what the user requirements are for a sunpy data container for time series data. As part of this I used my own experience and the following community engagement:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Discussion at one of the weekly sunpy community meetings in December 2022&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://groups.google.com/g/pyhc-list/c/ujnZEZcsI_k/m/gNfYrIJdBgAJ"&gt;Discussion on the Python in Heliophysics mailing list&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://community.openastronomy.org/t/choosing-a-future-data-container-for-timeseries-data/556?u=dstansby"&gt;Discussion on the SunPy forum&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From these discsusions came the following list of requirements:&lt;/p&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Requirement&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Notes&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Store data that is a function of time&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;This means the time column should be treated as the index or coordinates to the data, and be stored as a time-like type.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Handle different time scales&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Data can have times defined in a variety of different time scales (e.g. UTC, TAI)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Store multi-dimensional data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Although time is a common index to timeseries data, it isn’t always the only one. As an example, velocity distribution functions measured in the solar wind are 4D datasets, with data as a function of time and three dimensions in velocity space.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Handle time scales with leapseconds&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Some timescales can contain timestamps that occur within a leapsecond.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Store and use physical units with the data and any non-time indices&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Store data in a format that can be used with scientific Python libraries&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Support for storing out-of memory datasets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Store metadata alongside actual data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Have a way to store an observer coordinate alongside the time index&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Have an easy way to do common data manipulation tasks&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;e.g. interpolating, resampling, rebinning&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Have a way to combine multiple timeseries objects, and keep track of metadata&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Ability to convert to other common time series objects (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas.DataFrame&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Functionality for loading and saving out to common file formats&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="existing-options-for-a-data-container"&gt;
&lt;h2&gt;Existing options for a data container&lt;/h2&gt;
&lt;p&gt;The next step was to identify a set of possible data containers that could be used to store time- series data in sunpy.
The identified options were:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.timeseries.TimeSeries&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas.DataFrame&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt; (or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataSet&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;numpy.ndarray&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndcube&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="what-do-other-projects-use"&gt;
&lt;h3&gt;What do other projects use?&lt;/h3&gt;
&lt;p&gt;I also looked at what &lt;a class="reference external" href="https://heliopython.org/projects/"&gt;Python in Heliophysics projects&lt;/a&gt; use (as of writing, in Jan 2023):&lt;/p&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Package&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Container&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/sunpy/sunpy/"&gt;sunpy&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Custom &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;TimeSeries&lt;/span&gt;&lt;/code&gt; object, backed by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas.DataFrame&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hapi-server/client-python"&gt;HAPI Client&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;numpy.ndarray&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/spedas/pyspedas"&gt;pySPEDAS&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Not clear if users can access the data itself&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/spacepy/spacepy"&gt;spacepy&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unclear if there is any specific timeseries container object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://gitlab.com/aidaspace/aidapy"&gt;aidapy&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/MAVENSDC/cdflib"&gt;cdflib&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;numpy.ndarray&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/sunpy/ndcube"&gt;NDCube&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NDCube&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/MAVENSDC/pytplot"&gt;pytplot&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/jgieseler/solo-epd-loader"&gt;solo-epd-loader&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas.DataFrame&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/SciQLop/speasy"&gt;speasy&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Custom &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DataContainer&lt;/span&gt;&lt;/code&gt; object, backed by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;numpy.ndarray&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;There is no common container used, with only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.TimeSeries&lt;/span&gt;&lt;/code&gt; not represented out of the possible options above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-datasets-does-sunpy-currently-support"&gt;
&lt;h3&gt;What datasets does sunpy currently support?&lt;/h3&gt;
&lt;p&gt;sunpy currently has built in support for reading CDF files that conform to the &lt;a class="reference external" href="https://spdf.gsfc.nasa.gov/sp_use_of_cdf.html"&gt;Space Physics Guidelines for CDF&lt;/a&gt;, as long as the dataset is one- or two- dimensional.
Alongside this several custom data readers have been written to support different data sources:&lt;/p&gt;
&lt;p&gt;(links point to the data source information web page)&lt;/p&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Data product(s)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;File format&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://lasp.colorado.edu/eve/data_access/eve_data/products/level1/esp/2020/"&gt;SDO EVE/ESP L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FITS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://lasp.colorado.edu/home/eve/data/"&gt;SDO EVE/ESP L0CS&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Text file&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://fermi.gsfc.nasa.gov/ssc/data/access/"&gt;FERMI GBM summary&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FITS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;GOES XRS&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FITS, netCDF&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;PROBA-2 LYRA ligthcurve&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FITS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.swpc.noaa.gov/products/solar-cycle-progression"&gt;NOAA solar cycle monthly indices&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;JSON&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.swpc.noaa.gov/products/solar-cycle-progression"&gt;NOAA solar cycle predicted indices&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;JSON&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://solar.nro.nao.ac.jp/norh/archive.html"&gt;NoRH radio&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FITS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;RHESSI x-ray summary&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FITS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="evaluating-options"&gt;
&lt;h2&gt;Evaluating options&lt;/h2&gt;
&lt;p&gt;Having found possible options, in this section I’ve evaluated them against the criteria set out above.&lt;/p&gt;
&lt;section id="numpy-ndarray"&gt;
&lt;h3&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;numpy.ndarray&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Time-like index data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Can store datetime64 data, but no support for indexes&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Different time scales&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Multi-dimensional data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Physical units&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Interop with scientific Python&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Out of memory&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;numpy arrays are always in memory&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Metadata&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Observer coordinates&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Easy data manipulation&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;I/O&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Can save to binary .npy format or text file&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="pandas-dataframe"&gt;
&lt;h3&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas.DataFrame&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Time-like index data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Different time scales&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Multi-dimensional data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Possible, but &lt;a class="reference external" href="https://pandas.pydata.org/docs/getting_started/install.html#computation"&gt;recommended to use xarray instead&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Physical units&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No native support (&lt;a class="reference external" href="https://github.com/pandas-dev/pandas/issues/10349"&gt;tracking issue&lt;/a&gt;), could be possible with &lt;a class="reference external" href="https://github.com/hgrecco/pint-pandas"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pint-pands&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Interop with scientific Python&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Out of memory&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;pandas DataFrames are always in memory&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Metadata&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Possible to &lt;a class="reference external" href="https://pandas.pydata.org/pandas-docs/stable/development/extending.html#define-original-properties"&gt;add additional properties&lt;/a&gt; to a DataFrame&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Observer coordinates&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Easy data manipulation&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Many built in methods for manipulating time-like data&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;I/O&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html"&gt;Lots of I/O options&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="xarray-dataarray"&gt;
&lt;h3&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Time-like index data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Different time scales&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Multi-dimensional data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Physical units&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No native support (&lt;a class="reference external" href="https://github.com/pydata/xarray/issues/525"&gt;tracking issue&lt;/a&gt;), could be possible with &lt;a class="reference external" href="https://pint-xarray.readthedocs.io/en/stable/"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pint-xarray&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Interop with scientific Python&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Out of memory&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Support for &lt;a class="reference external" href="https://docs.xarray.dev/en/stable/user-guide/dask.html"&gt;computing using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dask&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Metadata&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Possible to &lt;a class="reference external" href="https://docs.xarray.dev/en/stable/get-help/faq.html#what-is-your-approach-to-metadata"&gt;add metadata&lt;/a&gt; to a DataArray&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Observer coordinates&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Support for adding &lt;a class="reference external" href="https://docs.xarray.dev/en/stable/user-guide/data-structures.html#coordinates"&gt;“non-dimensional” coordinates&lt;/a&gt; (e.g. longitude/latitude), but not clear if storing astropy SkyCoord would work&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Easy data manipulation&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Many built in methods for manipulating time-like data&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;I/O&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.xarray.dev/en/stable/user-guide/io.html"&gt;Lots of I/O options&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="astropy-timeseries-timeseries"&gt;
&lt;h3&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.timeseries.TimeSeries&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Time-like index data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Different time scales&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Multi-dimensional data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Physical units&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Interop with scientific Python&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Out of memory&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Apparently there is some support, but this is undocumented.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Metadata&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Can store on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;.meta&lt;/span&gt;&lt;/code&gt; attribute&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Observer coordinates&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Easy data manipulation&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;I/O&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;I/O is done via &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.table.Table&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="ndcube"&gt;
&lt;h3&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NDCube&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Time-like index data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Different time scales&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Multi-dimensional data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Physical units&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Interop with scientific Python&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Out of memory&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Seems to be supported in theory, but little docs&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Metadata&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Can store arbitrary FITS metadata&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Observer coordinates&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No support for extra coordinates&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Easy data manipulation&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Very few manipulation methods implemented&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;I/O&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="initial-recommendations"&gt;
&lt;h2&gt;Initial recommendations&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;numpy.ndarray&lt;/span&gt;&lt;/code&gt; doesn’t implement several key features, and these are almost certainly out of scope for future &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndarray&lt;/span&gt;&lt;/code&gt; development, so I suggest &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndarray&lt;/span&gt;&lt;/code&gt; is discounted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt; builds on top of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas.DataFrame&lt;/span&gt;&lt;/code&gt; with additional features that would be useful to us, I suggest &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas.DataFrame&lt;/span&gt;&lt;/code&gt; is discounted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NDCube&lt;/span&gt;&lt;/code&gt; is designed specifically to store data that is associated with a FITS world coordinate system (WCS). While some solar timeseries data is already in the FITS format, a large portion is in CDF format which is tabular, which FITS is not primarily designed to represent. So I suggest &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NDCube&lt;/span&gt;&lt;/code&gt; is discounted.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At a SunPy community meeting there was a consensus agreement that going forward we should consider &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.TimeSeries&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt; as the two options to consider.&lt;/p&gt;
&lt;p&gt;These two options have the following comparison:&lt;/p&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.TimeSeries&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Time-like index data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Different time scales&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Multi-dimensional data&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Physical units&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🛑&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Interop with scientific Python&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Out of memory&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Metadata&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Observer coordinates&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Easy data manipulation&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟠&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;I/O&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;🟩&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;My initial recommendation would be to adopt &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt;, as the two red items have a strong possibility of being solved with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DataArray&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It &lt;em&gt;should&lt;/em&gt; (I haven’t confirmed this) be possible to convert times in different time scales (including ones with leap seconds) to a single timescale that doesn’t have leap seconds, and store this in an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray.DataArray&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Although there is not native support for units in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DataArray&lt;/span&gt;&lt;/code&gt; currently, there is interest and ongoing development to support them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is unclear to me (because I did not have time to investigate) how hard it would be to implement support for storing rich coordinates (ie. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.SkyCoord&lt;/span&gt;&lt;/code&gt;) in the extra_coords part of xarray data structures.&lt;/p&gt;
&lt;p&gt;In contrast I think implementing multi-dimensional data in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.TimeSeries&lt;/span&gt;&lt;/code&gt;, adding documentation for out of memory datasets, and implementing easy data manipulation methods would take significantly more effor than this.
Finally, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt; has a much bigger development community than &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.TimeSeries&lt;/span&gt;&lt;/code&gt;, so implementing bug fixes and new features would probably be much easier with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="putting-astropy-objects-in-xarray-structures"&gt;
&lt;h2&gt;Putting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy&lt;/span&gt;&lt;/code&gt; objects in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt; structures&lt;/h2&gt;
&lt;p&gt;For the final part of the small development grant, I investigated the changes needed to put &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy&lt;/span&gt;&lt;/code&gt; objects in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt; structures.&lt;/p&gt;
&lt;p&gt;As a model for doing this, it is currently possible to store unitful data created with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pint&lt;/span&gt;&lt;/code&gt; in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt; structures.
Support for doing this has two components:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt; &lt;a class="reference external" href="https://docs.xarray.dev/en/stable/internals/duck-arrays-integration.html"&gt;natively supports storing duck arrays&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray-pint&lt;/span&gt;&lt;/code&gt; provides a set of accessors that can be used to serialise and deserialise unitful data so that it can be saved to a file and loaded again.
It does this by converting the unit data into metadata, with strings representing units.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is not currently possible to store &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.Quantity&lt;/span&gt;&lt;/code&gt; objects in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt; structures, as they inherit directly from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndarray&lt;/span&gt;&lt;/code&gt;, and get coerced from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Quantity&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndarray&lt;/span&gt;&lt;/code&gt; during the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;xarray&lt;/span&gt;&lt;/code&gt; structure initialisation. I think fixing this is (at least initially) a one line change, changing (what was xarray/core/variable.py#L288 on commit hash 51554f2638bc9e4a527492136fe6f54584ffa75d) from&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asarray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asarray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Before moving forward with this it needs to be possible to run the full unit tests in xarray with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy.Quantity&lt;/span&gt;&lt;/code&gt;.
I started work on this in these two PRs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/pydata/xarray/pull/7799"&gt;https://github.com/pydata/xarray/pull/7799&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/pydata/xarray/pull/7800"&gt;https://github.com/pydata/xarray/pull/7800&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2023/2023-05-10-timeseries_sdg/"/>
    <summary>In late 2022 I got a small development grant from NumFocus to scope the future of time series data in sunpy.
The successful application can be read on the sunpy wiki.
The application contains context that I won’t repeat here.
This blog post is the key outcome of this grant, with a record of what I did, the recommendations I made, and any decisions we came to as a community.</summary>
    <published>2023-05-10T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2022/2022-01-06-aiapy-demo/</id>
    <title>aiapy: A SunPy affiliated package for analyzing data from the Atmospheric Imaging Assembly</title>
    <updated>2022-01-06T00:00:00+00:00</updated>
    <author>
      <name>Mark Cheung"</name>
    </author>
    <content type="html">&lt;div class="admonition note"&gt;
&lt;p&gt;This blog post was written in a &lt;a class="reference external" href="https://github.com/sunpy/sunpy.org/blob/main/posts/2022/2022-01-06-aiapy-demo.ipynb"&gt;Jupyter notebook&lt;/a&gt;.
Click here for an interactive version:
&lt;span class="raw-html"&gt;&lt;a href="https://mybinder.org/v2/gh/sunpy/sunpy.org/main?filepath=posts/2022/2022-01-06-aiapy-demo.ipynb"&gt;&lt;img alt="Binder badge" src="https://mybinder.org/badge.svg" style="vertical-align:text-bottom"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;section id="aiapy:-A-SunPy-affiliated-package-for-analyzing-data-from-the-Atmospheric-Imaging-Assembly"&gt;

&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[1]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;aiapy&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.units&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;u&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;matplotlib&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;mpl&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;plt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.map&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;aiapy.calibrate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;correct_degradation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;degradation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;estimate_error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fetch_spikes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;respike&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;update_pointing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;aiapy.calibrate.util&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_correction_table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_error_table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_pointing_table&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;aiapy.psf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;deconvolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;psf&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;aiapy.response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Channel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.coordinates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;astropy.visualization&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ImageNormalize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogStretch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_support&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.net&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fido&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.net&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;attrs&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sunpy.time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parse_time&lt;/span&gt;

&lt;span class="c1"&gt;# Increases the figure size in this notebook.&lt;/span&gt;
&lt;span class="n"&gt;mpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rcParams&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;savefig.dpi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;
&lt;span class="n"&gt;mpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rcParams&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;figure.dpi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The Atmospheric Imaging Assembly (AIA) instrument onboard the NASA Solar Dynamics Observatory (SDO) spacecraft has observed the full- disk of the Sun, nearly continuously, for the last ten years. It is one of three instruments on SDO, along with the Helioseismic and Magnetic Imager (HMI) and the Extreme Ultraviolet Variability Experiment (EVE). AIA is a narrowband imaging instrument comprised of four separate telescopes that collectively observe the full-disk of the Sun at ten different
wavelengths: seven extreme ultraviolet (EUV) wavelengths, two far UV wavelengths, and one visible wavelength.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt; is a SunPy-affiliated Python package for analyzing calibrated (level 1) imaging data from AIA. It includes capabilities for aligning images between channels, deconvolving images with the instrument point-spread function (PSF), computing channel sensitivity as a function of wavelength, and correcting images for telescope degradation, among others. These capabilities are divided between the three subpackages of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.calibrate&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.psf&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.response&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this blog post, we will demonstrate the functions in each of these subpackages on a set of example level 1 AIA images.&lt;/p&gt;
&lt;p&gt;Before we begin, we make a note of what versions of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;astropy&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt; were used in the writing of this blog post.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[2]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;astropy v&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;astropy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__version__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sunpy v&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__version__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aiapy v&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;aiapy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__version__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
astropy v7.0.1
sunpy v6.1.1
aiapy v0.10.1
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="Obtaining-AIA-Data"&gt;
&lt;h2&gt;Obtaining AIA Data&lt;/h2&gt;
&lt;p&gt;First, we will use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Fido&lt;/span&gt;&lt;/code&gt; client to fetch two AIA images from the VSO: one from the 171 Å channel and one from the 211 Å channel.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[3]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2017-09-10T20:00:00&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;search_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Fido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Instrument&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wavelength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;171&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;angstrom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wavelength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;211&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;angstrom&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;search_results&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[3]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area rendered_html docutils container"&gt;
Results from 2 Providers:&lt;/br&gt;&lt;/br&gt;1 Results from the VSOClient:&lt;/br&gt;&lt;div&gt;&lt;i&gt;VSOQueryResponseTable length=1&lt;/i&gt;
&lt;table id="table123890739989328" class="table-striped table-bordered table-condensed"&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Start Time&lt;/th&gt;&lt;th&gt;End Time&lt;/th&gt;&lt;th&gt;Source&lt;/th&gt;&lt;th&gt;Instrument&lt;/th&gt;&lt;th&gt;Wavelength&lt;/th&gt;&lt;th&gt;Provider&lt;/th&gt;&lt;th&gt;Physobs&lt;/th&gt;&lt;th&gt;Wavetype&lt;/th&gt;&lt;th&gt;Extent Width&lt;/th&gt;&lt;th&gt;Extent Length&lt;/th&gt;&lt;th&gt;Extent Type&lt;/th&gt;&lt;th&gt;Size&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Angstrom&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Mibyte&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Time&lt;/th&gt;&lt;th&gt;Time&lt;/th&gt;&lt;th&gt;str3&lt;/th&gt;&lt;th&gt;str3&lt;/th&gt;&lt;th&gt;float64[2]&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str9&lt;/th&gt;&lt;th&gt;str6&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str8&lt;/th&gt;&lt;th&gt;float64&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;2017-09-10 20:00:09.000&lt;/td&gt;&lt;td&gt;2017-09-10 20:00:10.000&lt;/td&gt;&lt;td&gt;SDO&lt;/td&gt;&lt;td&gt;AIA&lt;/td&gt;&lt;td&gt;171.0 .. 171.0&lt;/td&gt;&lt;td&gt;JSOC&lt;/td&gt;&lt;td&gt;intensity&lt;/td&gt;&lt;td&gt;NARROW&lt;/td&gt;&lt;td&gt;4096&lt;/td&gt;&lt;td&gt;4096&lt;/td&gt;&lt;td&gt;FULLDISK&lt;/td&gt;&lt;td&gt;64.64844&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/br&gt;1 Results from the VSOClient:&lt;/br&gt;&lt;div&gt;&lt;i&gt;VSOQueryResponseTable length=1&lt;/i&gt;
&lt;table id="table123890739990096" class="table-striped table-bordered table-condensed"&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Start Time&lt;/th&gt;&lt;th&gt;End Time&lt;/th&gt;&lt;th&gt;Source&lt;/th&gt;&lt;th&gt;Instrument&lt;/th&gt;&lt;th&gt;Wavelength&lt;/th&gt;&lt;th&gt;Provider&lt;/th&gt;&lt;th&gt;Physobs&lt;/th&gt;&lt;th&gt;Wavetype&lt;/th&gt;&lt;th&gt;Extent Width&lt;/th&gt;&lt;th&gt;Extent Length&lt;/th&gt;&lt;th&gt;Extent Type&lt;/th&gt;&lt;th&gt;Size&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Angstrom&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Mibyte&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Time&lt;/th&gt;&lt;th&gt;Time&lt;/th&gt;&lt;th&gt;str3&lt;/th&gt;&lt;th&gt;str3&lt;/th&gt;&lt;th&gt;float64[2]&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str9&lt;/th&gt;&lt;th&gt;str6&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str4&lt;/th&gt;&lt;th&gt;str8&lt;/th&gt;&lt;th&gt;float64&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;2017-09-10 20:00:12.000&lt;/td&gt;&lt;td&gt;2017-09-10 20:00:13.000&lt;/td&gt;&lt;td&gt;SDO&lt;/td&gt;&lt;td&gt;AIA&lt;/td&gt;&lt;td&gt;211.0 .. 211.0&lt;/td&gt;&lt;td&gt;JSOC&lt;/td&gt;&lt;td&gt;intensity&lt;/td&gt;&lt;td&gt;NARROW&lt;/td&gt;&lt;td&gt;4096&lt;/td&gt;&lt;td&gt;4096&lt;/td&gt;&lt;td&gt;FULLDISK&lt;/td&gt;&lt;td&gt;64.64844&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/br&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[4]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Fido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;script type="application/vnd.jupyter.widget-view+json"&gt;{"model_id": "d8b6c39ce7f4421d96dec6d99c42e848", "version_major": 2, "version_minor": 0}&lt;/script&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can then create &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy.map.Map&lt;/span&gt;&lt;/code&gt; objects from the downloaded files.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[5]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_211&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[6]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;peek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vmin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;peek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vmin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_12_0.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_12_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_12_1.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_12_1.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that both the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt; documentation pages include more detailed examples of how to obtain AIA data from the JSOC as well&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.sunpy.org/en/stable/tutorial/acquiring_data/jsoc.html"&gt;sunpy: Querying and Downloading Data from JSOC&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.sunpy.org/en/stable/generated/gallery/acquiring_data/downloading_cutouts.html"&gt;sunpy: Requesting cutouts of AIA images from the JSOC&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/generated/gallery/skip_download_specific_data.html"&gt;aiapy: Requesting specific AIA images from the JSOC&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More complex queries (e.g. searching by exposure time or quality keyword) can be constructed by searching the JSOC directly via the &lt;a class="reference external" href="https://docs.sunpy.org/projects/drms/en/stable/"&gt;drms&lt;/a&gt; package. See the last example listed above for an example of this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="PSF-Deconvolution"&gt;
&lt;h2&gt;PSF Deconvolution&lt;/h2&gt;
&lt;p&gt;AIA images are subject to convolution with the instrument PSF due to effects introduced by the filter mesh of the telescope and the CCD, among others. This has the effect of “blurring” the image. The PSF diffraction pattern may also be particularly noticeable during the impulsive phase of a flare where the intensity enhancement is very localized. To remove these artifacts, the PSF must be deconvolved from the level 1 image. This is because the PSF itself is defined on the pixel grid of the CCD.&lt;/p&gt;
&lt;p&gt;We’ll calculate the PSF for the 171 Å channel using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;psf&lt;/span&gt;&lt;/code&gt; function in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.psf&lt;/span&gt;&lt;/code&gt; subpackage. The PSF model accounts for several different effects, including diffraction from the mesh grating of the filters, charge spreading, and jitter. This implementation of the PSF calculation follows &lt;a class="reference external" href="https://hesperia.gsfc.nasa.gov/ssw/sdo/aia/idl/psf/DOC/psfreport.pdf"&gt;Grigis et al (2012)&lt;/a&gt;. Further details on how the PSF is calculated can be found in that document. Currently, this only works
for &lt;span class="math notranslate nohighlight"&gt;\(4096\times4096\)&lt;/span&gt; full frame images.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The following cell will be &lt;em&gt;significantly&lt;/em&gt; slower (many minutes) if you do not have a NVIDIA GPU and the &lt;a class="reference external" href="https://docs.cupy.dev/en/stable/"&gt;cupy&lt;/a&gt; package installed. The GPU-enabled calculation has been benchmarked at ~5 s on an NVIDIA RTX 4090. Use of the GPU can be explicitly disabled by setting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_gpu=False&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[7]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;psf_171&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;psf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can then visualize the PSF. The diffraction “arms” extending from the center pixel can often be seen in flare observations due to the intense, small-scale brightening.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[8]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;psf_171&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;lower&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ImageNormalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vmax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1e-6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stretch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;LogStretch&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;colorbar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[8]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
&amp;lt;matplotlib.colorbar.Colorbar at 0x70adf80b3ed0&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_19_1.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_19_1.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can then use the calculated PSF to deconvolve our 171 Å image using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;deconvolve&lt;/span&gt;&lt;/code&gt; function in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.psf&lt;/span&gt;&lt;/code&gt;. This deconvolution algorithm is an implementation of the well-known &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Richardson%E2%80%93Lucy_deconvolution"&gt;Richardson-Lucy algorithm&lt;/a&gt;. If the PSF is not explicitly passed in, the PSF for that wavelength will be computed automatically. When deconvolving many images, it is highly recommend to precompute the PSF function for each desired wavelength.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The deconvolution of the image can also be optionally accelerated with a NVIDIA GPU and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cupy&lt;/span&gt;&lt;/code&gt;. On a Titan RTX, deconvolution of a full &lt;span class="math notranslate nohighlight"&gt;\(4096\times4096\)&lt;/span&gt; image has been benchmarked at &lt;span class="math notranslate nohighlight"&gt;\(\le1\)&lt;/span&gt; s. On a CPU, the equivalent operation should take ~25 s.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[9]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171_deconvolved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deconvolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;psf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;psf_171&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area stderr docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
2025-03-03 14:31:50 - sunpy - INFO: Using a GPU via cupy
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
INFO: Using a GPU via cupy [aiapy.psf.deconvolve]
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can now zoom in on some loop structures that extend off the limb to examine the differences between our image before and after deconvolution.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[10]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;blc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SkyCoord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;375&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;arcsec&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coordinate_frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fov&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;width&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arcsec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;height&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arcsec&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;m_171_cutout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;fov&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m_171_deconvolved&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;fov&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[11]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_171_cutout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_171_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Before Deconvolution&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;After Deconvolution&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_axislabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_24_0.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_24_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that comparing the images on the left and right, deconvolving with the PSF removes the appearance of the diffraction pattern near the bright looptop. This also brings out more detail in the strands of the post-flare arcade.&lt;/p&gt;
&lt;p&gt;We can see this more clearly by plotting the intensity of the original and deconvolved images across the top of the looptop.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[12]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.59&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ones&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[13]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_coordinates_from_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_cutout&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tx&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Original&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171_deconvolved_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Deconvolved&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Intensity [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m_171_cutout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Helioprojective Longitude [arcsec]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;upper center&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ncol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frameon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bbox_to_anchor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.15&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tight_layout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_27_0.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_27_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Respiking-Level-1-Images"&gt;
&lt;h2&gt;Respiking Level 1 Images&lt;/h2&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.calibrate&lt;/span&gt;&lt;/code&gt; module contains a number of useful functions, including the ability to “respike” images through the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;respike&lt;/span&gt;&lt;/code&gt; function. AIA level 1 images have been corrected for hot-pixels (commonly referred to as “spikes”) using an automated correction algorithm which detects them, removes them, and replaces the “holes” left in the image via interpolation. However, for certain research topics, this automated hot-pixel removal process may result in unwanted removal of bright points
which may be physically meaningful. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;respike&lt;/span&gt;&lt;/code&gt; function allows you to revert this removal by putting back all the removed pixel values. This corresponds to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aia_respike.pro&lt;/span&gt;&lt;/code&gt; IDL procedure as described in the &lt;a class="reference external" href="https://www.lmsal.com/sdodocs/doc/dcur/SDOD0060.zip/zip/entry/index.html"&gt;SDO Analysis Guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We will create a “respiked” version of our level 1 171 Å image. This function will query the JSOC for the relevant “spikes” file which contains the locations (in pixel coordinates) and associate intensities for each of the hot pixels. The hot pixel values are then replaced in the image at the appropriate locations.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[14]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171_respiked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;respike&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[15]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Despiked (Level &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processing_level&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.0f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_171_respiked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_171_respiked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Respiked (Level &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m_171_respiked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processing_level&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_axislabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_32_0.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_32_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Looking at the two images, it is not obvious by visual inspection what the differences are between the despiked and respiked maps. We can use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fetch_spikes&lt;/span&gt;&lt;/code&gt; functions (which is called automatically by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;respike&lt;/span&gt;&lt;/code&gt;) to find the intensity values and the associated pixel coordinates&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[16]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;pix_coords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fetch_spikes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can then use the pixel coordinates to find the “despiked” intensity values and plot the distributions of the “despiked” and “respiked” values.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[17]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vals_despiked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pix_coords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pix_coords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[18]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;scott&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;histtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;step&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Respiked&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vals_despiked&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;scott&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;histtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;step&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Despiked&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Intensity [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Number of Pixels&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[18]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
Text(0, 0.5, &amp;#39;Number of Pixels&amp;#39;)
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_37_1.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_37_1.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Additionally, we can plot the coordinates of each of our hot pixels on our “respiked” map. We can convert the above pixel coordinates to world coordinates using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;.pixel_to_world()&lt;/span&gt;&lt;/code&gt; method on our level 1 map. Note that we can also return the world coordinates from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fetch_spikes&lt;/span&gt;&lt;/code&gt; function automatically by passing in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;as_coords=True&lt;/span&gt;&lt;/code&gt; keyword argument.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[19]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;spike_coords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pixel_to_world&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pix_coords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pix_coords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[20]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_171_respiked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_171_respiked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot_coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spike_coords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;markersize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[20]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
[&amp;lt;matplotlib.lines.Line2D at 0x70ad8c28a0d0&amp;gt;]
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_40_1.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_40_1.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For a more detailed example of respiking level 1 images, see &lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/generated/gallery/replace_hot_pixels.html"&gt;the respiking example in the aiapy example gallery&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="Transforming-Level-1-Images-to-Level-1.5"&gt;
&lt;h2&gt;Transforming Level 1 Images to Level 1.5&lt;/h2&gt;
&lt;p&gt;One of the most common operations performed on level 1 AIA images is “aiaprep,” commonly performed with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aia_prep.pro&lt;/span&gt;&lt;/code&gt; procedure in IDL. This prep process, which promotes level 1 images to level 1.5, is a combination of two steps:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;update pointing and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image registration.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first step is accomplished through the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;update_pointing&lt;/span&gt;&lt;/code&gt; function in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.calibrate&lt;/span&gt;&lt;/code&gt;. This function queries the 3-hourly master pointing table stored at the JSOC to update relevant FITS keywords.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[21]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_pointing_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;JSOC&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_range&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;m_171_up&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update_pointing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pointing_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can verify this step by examining the reference pixel before and after the pointing update.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[22]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reference_pixel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[22]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
PixelPair(x=&amp;lt;Quantity 2052.300049 pix&amp;gt;, y=&amp;lt;Quantity 2048.280029 pix&amp;gt;)
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[23]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171_up&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reference_pixel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[23]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
PixelPair(x=&amp;lt;Quantity 2052.33252 pix&amp;gt;, y=&amp;lt;Quantity 2048.275391 pix&amp;gt;)
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The second step is accomplished through &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;register&lt;/span&gt;&lt;/code&gt; function in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.calibrate&lt;/span&gt;&lt;/code&gt;. This function performs an affine transform on the level 1 pixel grid to remove the roll angle, scale the image to resolution of 0.6 arcseconds-per-pixel, and shift the center of the image to the center of the Sun. The original intensity values are then reinterpolated onto this transformed grid.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[24]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171_l15&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_up&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can verify that the image has been transformed appropriately by comparing at the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;scale&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rotation_matrix&lt;/span&gt;&lt;/code&gt; attributes before and after registration. Note that the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rotation_matrix&lt;/span&gt;&lt;/code&gt; is now diagonalized, meaning that the world and pixel grids are aligned.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[25]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_up&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_up&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rotation_matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
SpatialPair(axis1=&amp;lt;Quantity 0.599489 arcsec / pix&amp;gt;, axis2=&amp;lt;Quantity 0.599489 arcsec / pix&amp;gt;)
[[ 9.99999944e-01 -3.35522089e-04]
 [ 3.35522089e-04  9.99999944e-01]]
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[26]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rotation_matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
SpatialPair(axis1=&amp;lt;Quantity 0.6 arcsec / pix&amp;gt;, axis2=&amp;lt;Quantity 0.6 arcsec / pix&amp;gt;)
[[ 1.00000000e+00 -5.90601768e-20]
 [-2.18097419e-20  1.00000000e+00]]
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that we can also combine these two operations into a “prep” function to imitate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiaprep.pro&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[27]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;prep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;smap&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_pointing_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;JSOC&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_range&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;smap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;smap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update_pointing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;smap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pointing_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[28]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_211_l15&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Applying this “prep” procedure means that our 171 Å and 211 Å images are now interpolated to the same pixel grid.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[29]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rotation_matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
SpatialPair(axis1=&amp;lt;Quantity 0.6 arcsec / pix&amp;gt;, axis2=&amp;lt;Quantity 0.6 arcsec / pix&amp;gt;)
[[1.00000000e+00 5.18338069e-20]
 [5.18338069e-20 1.00000000e+00]]
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Before performing any operations between two maps from different channels, one should always register each image such that the pixel grids of each image are aligned. For more information on transforming level 1 images to level 1.5, see the following example in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt; example gallery:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/generated/gallery/prepping_level_1_data.html"&gt;Registering and aligning level 1 data&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="Degradation-Correction"&gt;
&lt;h2&gt;Degradation Correction&lt;/h2&gt;
&lt;p&gt;The performance of the AIA telescope is unfortunately degrading over time, leading to the resulting images becoming increasingly dim. We can correct for this by modeling the degradation over time using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;degradation&lt;/span&gt;&lt;/code&gt; function. This function calculates the degradation factor &lt;span class="math notranslate nohighlight"&gt;\(d(t)\)&lt;/span&gt; as,&lt;/p&gt;
&lt;div class="math notranslate nohighlight"&gt;
\[d(t) = \frac{A_{eff}(t_{e})}{A_{eff}(t_0)}(1 + p_1\delta t + p_2\delta t^2 + p_3\delta t^3),\]&lt;/div&gt;
&lt;p&gt;where the leading coefficient is the ratio between the effective area at some epoch time &lt;span class="math notranslate nohighlight"&gt;\(t_e\)&lt;/span&gt; and the initial time &lt;span class="math notranslate nohighlight"&gt;\(t_0\)&lt;/span&gt;. The term in the parentheses represents an interpolation from &lt;span class="math notranslate nohighlight"&gt;\(t_e\)&lt;/span&gt; to the selected time &lt;span class="math notranslate nohighlight"&gt;\(t\)&lt;/span&gt;, where &lt;span class="math notranslate nohighlight"&gt;\(\delta t=t-t_e\)&lt;/span&gt;. &lt;span class="math notranslate nohighlight"&gt;\(p_1,p_2,p_3\)&lt;/span&gt; as well as &lt;span class="math notranslate nohighlight"&gt;\(A_{eff}(t_e)\)&lt;/span&gt; and &lt;span class="math notranslate nohighlight"&gt;\(A_{eff}(t_0)\)&lt;/span&gt; are retrieved from the JSOC (by default) or a user-supplied table.&lt;/p&gt;
&lt;p&gt;We can use this function to calculate the degradation of the 211 Å channel from the start of the SDO mission to now.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[30]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;t_begin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2010-03-25T00:00:00&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;astropy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;time_window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t_begin&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;t_begin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;First, we’ll query the degradation calibration table from the JSOC. Doing this ahead of time avoids repeated network calls when we want to repeatedly calculate the degradation.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[31]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_correction_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;JSOC&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can then calculate the 211 Å degradation using the above correction table.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[32]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;d_211&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;degradation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that we can also use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;.date&lt;/span&gt;&lt;/code&gt; attribute on our 211 Å map to compute the degradation at the time of that map&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[33]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;d_211_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;degradation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The degradation calibration is routinely updated (e.g. using data from sounding rocket flights), with new versions added to the table returned from the JSOC. We can look at older versions of the calibration to see how the predicted degradation has changed using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;calibration_version&lt;/span&gt;&lt;/code&gt; keyword argument. Note that the default version in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt; &lt;span class="pre"&gt;v0.10.0&lt;/span&gt;&lt;/code&gt; is 10.&lt;/p&gt;
&lt;p&gt;And compare the two degradation curves as a function of time over the lifetime of the mission.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[34]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;time_support&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;jyear&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time_window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d_211&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;v10&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d_211_map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;o&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;C0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iso&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Degradation 211 Å&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[34]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
&amp;lt;matplotlib.legend.Legend at 0x70ad7e10a210&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_70_1.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_70_1.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Additionally, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.calibrate&lt;/span&gt;&lt;/code&gt; also includes the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;correct_degradation&lt;/span&gt;&lt;/code&gt; function which accepts a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy.map.Map&lt;/span&gt;&lt;/code&gt;, calculates the degradation factor, divides the image data by this degradation factor, and returns a new corrected map.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[35]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_211_corrected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;correct_degradation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[36]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2.5e3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Uncorrected&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_211_corrected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m_211_corrected&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2.5e3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Corrected&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_axislabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_73_0.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_73_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Computing-Uncertainties"&gt;
&lt;h2&gt;Computing Uncertainties&lt;/h2&gt;
&lt;p&gt;One of the newest additions to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt; is the function for computing uncertainties on AIA intensities. This is done through the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;estimate_error&lt;/span&gt;&lt;/code&gt; function in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.calibrate&lt;/span&gt;&lt;/code&gt;. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;estimate_error&lt;/span&gt;&lt;/code&gt; is an exact port of the SSWIDL function &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aia_bp_estimate_error.pro&lt;/span&gt;&lt;/code&gt;. This calculation includes errors from the shot noise, read noise, quantization, and onboard compression. The calculation can also optionally include contributions from the photometric calibration and errors in the atomic data.&lt;/p&gt;
&lt;p&gt;We can pass in the (unitful) data array attached to our 171 Å map and compute the intensities.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[37]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;error_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_error_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SSW&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;errors_171&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;estimate_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;error_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area stderr docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
/home/nabil/.micromamba/envs/solar/lib/python3.13/site-packages/astropy/units/quantity.py:658: RuntimeWarning: invalid value encountered in sqrt
  result = super().__array_ufunc__(function, method, *arrays, **kwargs)
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To easily visualize the spatial distribution of these uncertainties, we can create a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy.map.Map&lt;/span&gt;&lt;/code&gt; object from these errors.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[38]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171_errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sunpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errors_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[39]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171_errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;peek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ImageNormalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vmax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_80_0.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_80_0.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can also use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;include_chianti&lt;/span&gt;&lt;/code&gt; flag to understand how the presence of atomic data errors from CHIANTI affect the uncertainty.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[40]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;errors_171_chianti&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;estimate_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include_chianti&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;error_table&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area stderr docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
/home/nabil/.micromamba/envs/solar/lib/python3.13/site-packages/astropy/units/quantity.py:658: RuntimeWarning: invalid value encountered in sqrt
  result = super().__array_ufunc__(function, method, *arrays, **kwargs)
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Similarly, we can look at how the photometric calibration, using the calibration from EVE, affects the uncertainties.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[41]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;errors_171_eve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;estimate_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include_eve&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;error_table&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can then look at the distribution of these uncertainties with these different combinations of keyword arguments to understand how these different options affect the resulting distribution of errors. Note that the inclusion of the atomic data results in the largest errors because there is an additional 25% (for 171 Å) uncertainty assumed on the input intensities.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[42]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;hist_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bins&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;histtype&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;step&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;log&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errors_171&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;hist_params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Nominal&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errors_171_chianti&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;hist_params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CHIANTI&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errors_171_eve&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;hist_params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Photometric (EVE)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Uncertainty [ct/pix]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Number of Pixels&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;log&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frameon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[42]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
&amp;lt;matplotlib.legend.Legend at 0x70ad8dd0f9d0&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_86_1.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_86_1.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Exposure-Time-Normalization"&gt;
&lt;h2&gt;Exposure Time Normalization&lt;/h2&gt;
&lt;p&gt;For normalizing images by the exposure time:&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[43]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;m_171_norm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m_171_l15&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;m_171_l15&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exposure_time&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This option still properly accounts for the change in units but does &lt;strong&gt;not&lt;/strong&gt; reset the exposure time.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[44]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_norm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
DN / s
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[45]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_171_norm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exposure_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
2.000169 s
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="Wavelength-Response-Functions"&gt;
&lt;h2&gt;Wavelength Response Functions&lt;/h2&gt;
&lt;p&gt;Lastly, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy.response&lt;/span&gt;&lt;/code&gt; subpackage includes the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Channel&lt;/span&gt;&lt;/code&gt; object for computing the wavelength response function of each channel as well as providing various pieces of metadata for each channel.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[46]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[47]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;telescope_number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
211.0 Angstrom
2
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The wavelength response is a combination of the (wavelength-dependent) effective area and the gain of the telescope such that &lt;span class="math notranslate nohighlight"&gt;\(R(\lambda,t) = A_{eff}(\lambda)G(\lambda)\)&lt;/span&gt;. According to Section 2 of &lt;a class="reference external" href="https://ui.adsabs.harvard.edu/abs/2012SoPh..275...41B/abstract"&gt;Boerner et al. (2012)&lt;/a&gt;, the effective area is given by,&lt;/p&gt;
&lt;div class="math notranslate nohighlight"&gt;
\[A_{eff}(\lambda) = A_{geo}R_P(\lambda)R_S(\lambda)T_E(\lambda)T_F(\lambda)D(\lambda)Q(\lambda),\]&lt;/div&gt;
&lt;p&gt;where &lt;span class="math notranslate nohighlight"&gt;\(A_{geo}\)&lt;/span&gt; is the geometrical collecting area, &lt;span class="math notranslate nohighlight"&gt;\(R_{P,S}\)&lt;/span&gt; are the reflectances of the primary and secondary mirrors, respectively, &lt;span class="math notranslate nohighlight"&gt;\(T_{E,F}\)&lt;/span&gt; are the transmission efficiency of the entrance and focal-plane filters, respectively, &lt;span class="math notranslate nohighlight"&gt;\(D\)&lt;/span&gt; is the contaminant transmittance of the optics and &lt;span class="math notranslate nohighlight"&gt;\(Q\)&lt;/span&gt; is the quantum efficiency of the CCD.&lt;/p&gt;
&lt;p&gt;We can compute the wavelength response for the 211 Å channel using the following method.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[48]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_correction_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;JSOC&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each of the individual components of the effective area are also available as properties on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Channel&lt;/span&gt;&lt;/code&gt; object.&lt;/p&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[49]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;geometrical_collecting_area&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;primary_reflectance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;focal_plane_filter_efficiency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contamination&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantum_efficiency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
83.0 cm2
[1.0735452e-05 1.0784249e-05 1.0833047e-05 ... 2.8031474e-01 2.8032130e-01
 2.8032786e-01]
[5.95474e-01 5.93567e-01 5.91666e-01 ... 3.08021e-05 3.06914e-05
 3.05812e-05]
[0.96578515 0.96544755 0.9651096  ... 0.4387496  0.4387496  0.4387496 ]
[0.8513821  0.8509894  0.8506473  ... 0.09263941 0.09265867 0.09267791]
[7.42477    7.39518913 7.36584303 ... 0.20628946 0.20626652 0.20624361] DN / ph
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;.wavelength_response&lt;/span&gt;&lt;/code&gt; method also includes several keyword arguments for including the effects of degradation and EVE cross-calibration in the computation of the wavelength response function.&lt;/p&gt;
&lt;div class="nbinput nblast docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[ ]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;r_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obstime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r_time_eve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obstime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m_211&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include_eve_correction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;correction_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nbinput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[61]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="input_area highlight-ipython3 notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Uncorrected&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Degradation&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wavelength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r_time_eve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Degradation + EVE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlim&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;240&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylim&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.75&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;$\lambda$ [Å]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;rf&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;$R(\lambda)$ [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latex_inline&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frameon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput docutils container"&gt;
&lt;div class="prompt highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;[61]:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;
&amp;lt;matplotlib.legend.Legend at 0x70ad6e166c10&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nboutput nblast docutils container"&gt;
&lt;div class="prompt empty docutils container"&gt;
&lt;/div&gt;
&lt;div class="output_area docutils container"&gt;
&lt;img alt="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_102_1.png" src="https://sunpy.org/_images/posts_2022_2022-01-06-aiapy-demo_102_1.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that these wavelength responses, when combined with atomic data (e.g. from CHIANTI), can be used to compute the temperature response functions of each AIA channel using Section 2.5 of Boerner et al. (2012). More information about this subpackage can be found in the &lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/generated/gallery/calculate_response_function.html#sphx-glr-generated-gallery-calculate-response-function-py"&gt;Computing wavelength response functions&lt;/a&gt; example in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt; example
gallery.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="Resources"&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;p&gt;In addition to this blog post, there are also a number of resources for learning more about &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://gitlab.com/LMSAL_HUB/aia_hub/aiapy"&gt;Source code on GitLab&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/"&gt;Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/generated/gallery/index.html"&gt;Example Gallery&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://joss.theoj.org/papers/10.21105/joss.02801"&gt;Paper in the Journal of Open Source Software (JOSS)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;aiapy&lt;/span&gt;&lt;/code&gt; is under active development and, just as with the core &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt; package and all other affilitated packages, contributions from the community are always welcome. To report a bug, request a feature, or simply ask a question, feel free to open an issue on &lt;a class="reference external" href="https://gitlab.com/LMSAL_HUB/aia_hub/aiapy/-/issues"&gt;GitLab&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2022/2022-01-06-aiapy-demo/"/>
    <summary>aiapy is a SunPy affiliated package for analyzing EUV image data from the Atmospheric Imaging Assembly (AIA). It includes a number of of functions for calibrating images, correcting metadata, and analyzing the filter bandpasses. In this post, we show some examples of the different capabilities of version 0.6.3 of the aiapy package.</summary>
    <category term="affiliated-package" label="affiliated-package"/>
    <category term="instrument" label="instrument"/>
    <published>2022-01-06T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2021/2021-10-08_nasa_osftl_grant/</id>
    <title>SunPy Awarded NASA Grant</title>
    <updated>2021-11-03T00:00:00+00:00</updated>
    <author>
      <name>Stuart Mumford</name>
    </author>
    <content type="html">&lt;section id="sunpy-awarded-nasa-grant"&gt;

&lt;p&gt;&lt;strong&gt;As part of the NASA “Open Source Tools, Frameworks, and Libraries” program, the SunPy proposal “Strengthening the Foundations of the SunPy Ecosystem” has been funded for the next three years.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This proposal was submitted in January 2021, and sought funding for both the core &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/reference/sunpy.html#module-sunpy" title="(in sunpy v4.13.0)"&gt;&lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; package and wider goals of the project.
After &lt;a class="reference external" href="https://github.com/sunpy/sunpy-project/issues/9"&gt;early community input was collected&lt;/a&gt;, Albert Shih led the proposal itself, with NASA GSFC as the primary institution.
&lt;a class="reference external" href="https://docs.google.com/document/d/1_gf1HM7iIUVqgHAdDUFQfCUHzHkrEFUTJZP8O3PEoqw"&gt;The proposed effort&lt;/a&gt; focuses on three main areas:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Improving the technical infrastructure.&lt;/p&gt;
&lt;p&gt;This focuses on the tools that the wider project needs to scale up as we adopt more coordinated and affiliated packages.
To support multiple active projects with a common development workflow, more tooling and infrastructure is needed, both for maintainers of existing packages and developers new to writing affiliated packages.
As part of this work templates for setting up new packages will be improved, documentation will be written, and new automation and monitoring bots will be developed to ease the burden on the SunPy maintainers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Augmenting science-enabling functionality.&lt;/p&gt;
&lt;p&gt;This section aims to improve the tools provided by the core package to better support future challenges in solar physics data.
The two main components of this are supporting multi-point observations with improvements to the &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/reference/coordinates/index.html#module-sunpy.coordinates" title="(in sunpy v4.13.0)"&gt;&lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy.coordinates&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; package, and improving the support for very large datasets in &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/reference/sunpy.html#module-sunpy" title="(in sunpy v4.13.0)"&gt;&lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; and sponsored packages by leveraging the scaling and parallelism tools available from &lt;a class="reference external" href="https://dask.org"&gt;Dask&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Providing training and outreach&lt;/p&gt;
&lt;p&gt;This section will improve example galleries across both &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/reference/sunpy.html#module-sunpy" title="(in sunpy v4.13.0)"&gt;&lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; core and affiliated packages, develop training materials for solar physics graduate students, and perform outreach activities with instrument teams and package developers.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="what-will-the-money-pay-for"&gt;
&lt;h2&gt;What will the money pay for?&lt;/h2&gt;
&lt;p&gt;The money awarded to this proposal will pay for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Albert Shih will manage the project and augment parts of &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/reference/coordinates/index.html#module-sunpy.coordinates" title="(in sunpy v4.13.0)"&gt;&lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy.coordinates&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stuart Mumford will work on infrastructure for all sponsored and affiliated packages as discussed in &lt;a class="reference external" href="https://github.com/sunpy/sunpy-project/issues/2"&gt;sunpy/sunpy-project#2&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Will Barnes will work on the training/outreach and large-dataset-support components of the project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="finally"&gt;
&lt;h2&gt;Finally&lt;/h2&gt;
&lt;p&gt;This is a major milestone for SunPy - it is the first significant amount of funding dedicated to directly working on the long term sustainability of the project.
This funding will help to significantly grow SunPy, both the core package and the ecosystem of associated packages.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2021/2021-10-08_nasa_osftl_grant/"/>
    <summary>As part of the NASA “Open Source Tools, Frameworks, and Libraries” program, the SunPy proposal “Strengthening the Foundations of the SunPy Ecosystem” has been funded for the next three years.</summary>
    <category term="sunpy" label="sunpy"/>
    <published>2021-11-03T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2021/2021-10-29_sunpy_31_ndcube_20/</id>
    <title>October Release Announcements</title>
    <updated>2021-10-29T00:00:00+00:00</updated>
    <author>
      <name>Stuart Mumford</name>
    </author>
    <content type="html">&lt;section id="october-release-announcements"&gt;

&lt;p&gt;Today we have a quadruple release announcement for you!
It’s been a very busy week in SunPy land getting both the core and ndcube releases over the line; I hope you enjoy them!&lt;/p&gt;
&lt;section id="sunpy-3-1"&gt;
&lt;h2&gt;sunpy 3.1&lt;/h2&gt;
&lt;p&gt;The next scheduled release of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sunpy&lt;/span&gt;&lt;/code&gt; core package actually comes &lt;em&gt;a week&lt;/em&gt; early according to our &lt;a class="reference external" href="https://github.com/sunpy/sunpy/wiki/Release-Calendar"&gt;release calendar&lt;/a&gt;, but we couldn’t resist bringing you this end of month release party.&lt;/p&gt;
&lt;p&gt;The 3.1 release contains many new features and improvements, having merged 145 pull requests from 16 people including 8 new contributors.&lt;/p&gt;
&lt;p&gt;Some of the highlights from the &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/whatsnew/3.1.html#whatsnew-3-1" title="(in sunpy v4.13.0)"&gt;&lt;span&gt;What’s New in SunPy 3.1?&lt;/span&gt;&lt;/a&gt; page are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Increased in-situ data support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new limb drawing function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new WISPR map source&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Propagating solar-surface coordinates in time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convenient reprojection of maps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSOC keyword filtering with Fido&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Arithmetic operations with maps&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My personal favourites being the new &lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;limb&lt;/span&gt; &lt;span class="pre"&gt;drawing&lt;/span&gt; &lt;span class="pre"&gt;function&lt;/span&gt;&lt;/code&gt;
and the &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/generated/api/sunpy.map.GenericMap.html#sunpy.map.GenericMap.reproject_to" title="(in sunpy v4.13.0)"&gt;&lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;reproject_to&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; method on all maps.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ndcube-2-0"&gt;
&lt;h2&gt;ndcube 2.0&lt;/h2&gt;
&lt;p&gt;Even more excitingly, for me personally, is the long awaited 2.0 release of ndcube.&lt;/p&gt;
&lt;p&gt;ndcube is the sunpy sponsored package for working with multi-dimensional data with an associated WCS object.
For an introduction to ndcube and motivation for the 2.0 rework see &lt;a class="reference external" href="https://docs.sunpy.org/projects/ndcube/en/stable/introduction.html#ndcube-introduction" title="(in ndcube v2.4.0)"&gt;&lt;span&gt;An introduction to ndcube&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We started working on ndcube 2.0 back in 2019 when we had Yash Sharma do the initial work of porting the code base to use the &lt;a class="reference external" href="https://zenodo.org/record/1188875"&gt;APE 14&lt;/a&gt; APIs as his &lt;a class="reference external" href="https://yashrsharma44.medium.com/google-summer-of-code-2019-final-report-openastronomy-ndcube-65068b8571d8"&gt;Google Summer of Code project&lt;/a&gt;.
Little did any of us think that it would take over two years from that point to hit the final release.&lt;/p&gt;
&lt;p&gt;The road to ndcube 2.0 has been long and arduous; all involved have put in a lot of work and what we have made is something that I am personally very proud of.
ndcube 2.0 would not have happened without Dan Ryan, who as the co-maintainer for ndcube has spent many hours on video calls with me designing APIs, and many more hours besides working out problems you would only encounter in one in a million WCS objects!
I would also be remiss if I didn’t specifically thank the DKIST data center who have, by paying for my time, funded a lot of the development work on ndcube 2.0, even when the scope increased beyond their direct requirements.&lt;/p&gt;
&lt;p&gt;I hope that many packages will start using ndcube 2.0 as the base for their code.
There are already many who have helped to shape the release such as the &lt;a class="reference external" href="https://github.com/DKISTDC/dkist"&gt;DKIST User Tools&lt;/a&gt;, &lt;a class="reference external" href="https://github.com/astropy/specutils"&gt;specutils&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/sunpy/sunraster"&gt;sunraster&lt;/a&gt; as well as others I know are in the works.&lt;/p&gt;
&lt;p&gt;For all the gory details of the changes in ndcube 2.0 see &lt;a class="reference external" href="https://docs.sunpy.org/projects/ndcube/en/stable/whatsnew/changelog.html#id11"&gt;the changelog&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="pfsspy-1-0"&gt;
&lt;h2&gt;pfsspy 1.0&lt;/h2&gt;
&lt;p&gt;The SunPy-affiliated potential field source surface extrapolation package &lt;a class="reference external" href="https://pfsspy.readthedocs.io/"&gt;pfsspy&lt;/a&gt; maintained by &lt;a class="reference external" href="https://github.com/dstansby/"&gt;David Stansby&lt;/a&gt; has had a 1.0 release, which includes promises of API stability.
You can read about all the changes in &lt;a class="reference external" href="https://pfsspy.readthedocs.io/en/stable/changes.html"&gt;the changelog&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="aiapy-0-6"&gt;
&lt;h2&gt;aiapy 0.6&lt;/h2&gt;
&lt;p&gt;The SunPy-affiliated aiapy package, which provides tools for working with SDO/AIA data and is maintained by the AIA instrument team, has a new 0.6 release which includes support for sunpy core 3.1.
In addition to a number of bug fixes, v0.6 also includes the ability to calculate uncertainties on AIA images via the &lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/api/aiapy.calibrate.estimate_error.html#aiapy.calibrate.estimate_error" title="(in aiapy v0.12.0)"&gt;&lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;estimate_error&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; function.
A complete list of changes is available &lt;a class="reference external" href="https://aiapy.readthedocs.io/en/stable/whatsnew/changelog.html"&gt;in the changelog&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2021/2021-10-29_sunpy_31_ndcube_20/"/>
    <summary>Today we have a quadruple release announcement for you!
It’s been a very busy week in SunPy land getting both the core and ndcube releases over the line; I hope you enjoy them!</summary>
    <category term="sunpy" label="sunpy"/>
    <published>2021-10-29T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://sunpy.org/posts/2020/2020-08-17_affiliated_packages/</id>
    <title>The What, Why, and How of SunPy Affiliated Packages</title>
    <updated>2020-08-18T00:00:00+00:00</updated>
    <author>
      <name>Laura Hayes</name>
    </author>
    <content type="html">&lt;section id="the-what-why-and-how-of-sunpy-affiliated-packages"&gt;

&lt;section id="what-are-sunpy-affiliated-packages"&gt;
&lt;h2&gt;What are SunPy affiliated packages?&lt;/h2&gt;
&lt;p&gt;SunPy affiliated packages are well-maintained, open-source software packages that build upon or extend the functionality of the SunPy core library.
The main idea behind affiliated packages is to provide additional tools and functionality to the solar physics community that is considered outside the scope of the SunPy core library, but builds upon it.
Affiliated packages are aimed to integrate well with the SunPy ecosystem and together with the core library offer a diverse software ecosystem for which to perform solar data analysis.
Affiliated packages are reviewed and registered with the SunPy project.&lt;/p&gt;
&lt;p&gt;There are two types of affiliated packages - &lt;em&gt;sponsored&lt;/em&gt; and &lt;em&gt;non-sponsored&lt;/em&gt;.
A sponsored affiliated package is an affiliated package that is maintained and overseen by the SunPy project, examples of these include &lt;a class="reference external" href="https://docs.sunpy.org/en/stable/"&gt;sunpy core&lt;/a&gt; and &lt;a class="reference external" href="https://docs.sunpy.org/projects/ndcube/en/stable/"&gt;ndcube&lt;/a&gt;.
Non-sponsored affiliated packages on the other hand remain under the control and maintenance of the original developers, but must meet a set of standards.
Examples of non-sponsored affiliated packages would be instrument-specific affiliated packages such as &lt;a class="reference external" href="https://pypi.org/project/aiapy/"&gt;AIApy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this blog post we want to outline our new streamline process for becoming an affiliated package and we want to encourage package developers, particularly instrument teams interested in developing a Python package, to submit their package for review for SunPy affiliate status!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="why-would-a-package-want-to-become-an-affiliated-package"&gt;
&lt;h2&gt;Why would a package want to become an affiliated package?&lt;/h2&gt;
&lt;p&gt;SunPy supports the development of affiliated packages through our community development efforts and by providing our package template.
The SunPy project will also ensure that affiliated packages are publicized to encourage community development.
For example, affiliated packages are listed on the SunPy website, and SunPy adverstises them at conferences and workshops.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="call-to-instrument-mission-teams"&gt;
&lt;h2&gt;Call to instrument/mission teams!&lt;/h2&gt;
&lt;p&gt;We invite instrument and mission teams that are interested in developing a Python package to become a SunPy affiliated package.
Integrating mission/instrument-specific software within the SunPy ecosystem will be of great benefit to the solar community and will allow for a simplified and unified process for users to perform solar data analysis.
For example, a package may consist of instrument-specific calibration routines which would be outside the scope of SunPy core package, but could build upon the functionality provided by core such as the data containers and file readers.
Developing a mission/instrument specific package as a SunPy affiliated package will allow the code to live and integrate within the SunPy ecosystem.&lt;/p&gt;
&lt;p&gt;Furthermore, for mission/instrument teams that would like to begin developing specific Python software, the SunPy project offers support through our package template and community resources for the package to be ‘incubated’ until it is at the level of affiliate status.
We would really like to encourage instrument/mission teams to reach out!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="package-template"&gt;
&lt;h2&gt;Package template&lt;/h2&gt;
&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: INFO/1 (&lt;span class="docutils literal"&gt;/home/docs/checkouts/readthedocs.org/user_builds/sunpyorg/checkouts/489/posts/2020/2020-08-17_affiliated_packages.rst&lt;/span&gt;, line 7); &lt;em&gt;&lt;a href="#id1"&gt;backlink&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Duplicate implicit target name: “package template”.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;The SunPy project is currently developing a &lt;a class="reference external" href="https://github.com/sunpy/package-template"&gt;package template&lt;/a&gt; that is designed to help developers create new Python packages within the SunPy ecosystem.
The template is still in development, and we are working towards creating more documentation to make it accessible for developers to use.
The idea is that this template will provide a simplified way to standardized packaging, testing, and documentation using the same framework as the SunPy core package.
The SunPy package template will make it easier for package developers to meet the standards required by SunPy to become an affiliated package!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="how-does-a-package-become-an-affiliated-package"&gt;
&lt;h2&gt;How does a package become an affiliated package?&lt;/h2&gt;
&lt;p&gt;To become a SunPy affiliated package, a set of criteria need to be met to ensure that affiliated packages provide useful functionality to the community at a standard of quality similar to the core SunPy package.
We now have a new review process for becoming an affiliated package, aimed at being open, approachable and streamlined!&lt;/p&gt;
&lt;p&gt;The reviews are performed as an open process through GitHub issues on the &lt;code class="xref py py-obj docutils literal notranslate"&gt;&lt;span class="pre"&gt;https://github.com/sunpy/sunpy.org&lt;/span&gt;&lt;/code&gt; repository.
To submit a package for review to become an affiliated package, an issue should be opened on this repository.
We now have an &lt;a class="reference external" href="https://github.com/sunpy/sunpy.org/issues/new?assignees=Cadair&amp;amp;labels=Affiliated+Package+Review&amp;amp;template=new_affiliated_package.md"&gt;issue template&lt;/a&gt; for submitting a package for review to make it easier to provide all the required information and to start a dialogue about the process.&lt;/p&gt;
&lt;p&gt;Once an issue is open, the Affiliate Package Liaison will check that the package meets the baseline requirements of an affiliated package.
These include checking to see that it is compatible with the SunPy &lt;a class="reference external" href="https://sunpy.org/coc"&gt;Code of Conduct&lt;/a&gt;,  has an appropriate licence, provides a Python interface, is on PyPI, and is useful to the solar physics community.
Following this, a reviewer independent to the package is assigned and a review is undertaken based on the criteria listed below.&lt;/p&gt;
&lt;p&gt;The review criteria that are assessed are listed as follows with the associated gradings:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Functionality&lt;/strong&gt;  Does the package provide functionality that is useful and relevant to the solar physics community?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration&lt;/strong&gt;  - Does that package integrate well within the SunPy ecosystem? for example does it make use of all appropriate features in the core library, including the applicable data structures and dependencies?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt;  - Does the package have satisfactory documentation that is up to the standard of the core sunpy library including a user guide and examples?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt; - Does the package use a testing suite to verify the code functionality within its codebase? Does it provide integration tests?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Duplication&lt;/strong&gt; - Does the package duplicate functionality within sunpy core or any of the other affiliated packages or other relevant packages?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community&lt;/strong&gt;  - Is the package openly developed with active input and engagement from users within the community? Does the package have a code of conduct and does this reflect the same values as the SunPy project?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Development Status&lt;/strong&gt; - Is the package well maintained? Are contribution responded to by developers? Is the package still under development with large API changes?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These criteria are reviewed on a ‘traffic light’ system and ranked ‘green’, ‘orange’, or ‘red’ based on the submitted package.
For full details of how each of criteria are ranked please check out the &lt;a class="reference external" href="https://sunpy.org/affiliated#affiliated-package-review"&gt;Review Criteria&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For a submitted package to be accepted to affiliate package status, the package must be ‘green’ in &lt;strong&gt;Functionality&lt;/strong&gt;, and one other category.
It must also not list any ‘red’ scores.&lt;/p&gt;
&lt;p&gt;If the package in its current state does not pass the criteria, it can be listed as &lt;em&gt;Provisional&lt;/em&gt; once it does not list ‘red’ in the &lt;strong&gt;Functionality&lt;/strong&gt;, &lt;strong&gt;Duplication&lt;/strong&gt; or &lt;strong&gt;Community&lt;/strong&gt; criteria.
The idea is that the package can be listed as Provisional as it is working towards addressing the criteria for which it did not pass the review in.&lt;/p&gt;
&lt;p&gt;We would really like to encourage packages interested in becoming an affiliated SunPy package to please submit an issue and open up a review dialogue.
We will have an Affiliated Package Liaison that will help you through each step of this process :).
Even if you are unsure about whether you want to submit a package, please feel free to open an issue and informally discuss your package.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="reach-out"&gt;
&lt;h2&gt;Reach out!&lt;/h2&gt;
&lt;p&gt;If you are a developer of a package that you think fits nicely into the SunPy ecosystem and will of benefit to the solar physics community and want to chat to us about it please reach out!
This can be of course regardless of how far along the package is - from concept to maturity!
Join us our live chat &lt;a class="reference external" href="https://app.element.io/#/room/#sunpy:openastronomy.org"&gt;Matrix room&lt;/a&gt; or join in on the SunPy weekly community meetings which occur each Wednesday (see &lt;a class="reference external" href="https://calendar.google.com/calendar?cid=ZzljOWVha2c5OGI1Y2JvZ2Q3bTV0YTZoOHNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ"&gt;our calendar&lt;/a&gt; for the time in your timezone) and are hosted on &lt;a class="reference external" href="https://sunpy.org/meeting"&gt;jitsi&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://sunpy.org/posts/2020/2020-08-17_affiliated_packages/"/>
    <summary>SunPy affiliated packages are well-maintained, open-source software packages that build upon or extend the functionality of the SunPy core library.
The main idea behind affiliated packages is to provide additional tools and functionality to the solar physics community that is considered outside the scope of the SunPy core library, but builds upon it.
Affiliated packages are aimed to integrate well with the SunPy ecosystem and together with the core library offer a diverse software ecosystem for which to perform solar data analysis.
Affiliated packages are reviewed and registered with the SunPy project.</summary>
    <category term="sunpy" label="sunpy"/>
    <published>2020-08-18T00:00:00+00:00</published>
  </entry>
</feed>
