1 SunPy User Guide 3 1.1 Installation...... 3 1.2 A brief tour of SunPy...... 10 1.3 Acquiring Data with SunPy...... 16 1.4 Data Types in SunPy...... 42 1.5 Plotting in SunPy...... 52 1.6 Time in SunPy...... 54 1.7 Region of Interest...... 57 1.8 Customizing SunPy...... 57 1.9 Troubleshooting...... 58
Welcome to the SunPy documentation. SunPy is a community-developed, free and open-source solar data analysis environment for Python. You can find the official SunPy website at sunpy.org.
Contents 1 DemoDoc Documentation, Release
2 Contents CHAPTER 1
SunPy User Guide
Welcome to the SunPy User Guide. SunPy is a community-developed, free and open-source solar data analysis environment. It is meant to provide the core functionality and tools to analyze solar data with Python. This guide provides a walkthrough of the major features in SunPy. For more details checkout the API Reference.
Installation
SunPy is a Python package for solar physics. It relies on and enables the use of the wider ecosystem of scientific Python packages for solar physics. Therefore a working SunPy installation is more about installing the scientific Python ecosystem than SunPy itself. SunPy is Python 2.7.x, 3.4.x and 3.5.x compatible. If you are new to Python and scientific Python then continue to follow this guide to get setup with the whole envi- ronment. If you already have a working Python / Scientific Python environment then you can skip to the Advanced Installation Instructions section.
Installing Scientific Python and SunPy
If you do not currently have a working scientific Python distribution this guide will set you up with the Anaconda sci- entific Python distribution. Anaconda makes it easy to install and manage your scientific Python packages. Alternative scientific Python options exist and can be found later in the Advanced Installation Instructions section. Anaconda contains a free distribution of Python and a large number of common scientific packages. Anaconda is very powerful and easy to use. Installing Anaconda provides (almost) all the packages you need to use SunPy. To install the Anaconda Python distribution follow the instructions here. You will need to select the correct download for your platform and follow the install procedure. Note that although Anaconda makes it simple to switch between Python versions, we recommend that new users install the latest Python 3.x version of Anaconda. This is because Python 2.7 is scheduled to be deprecated in 2020.
3 DemoDoc Documentation, Release
Installing SunPy on top of Anaconda
To install SunPy launch a system command prompt or the ‘Anaconda Command Prompt’ (under Windows). First configure conda for sunpy downloads: conda config--add channels conda-forge to install SunPy: conda install sunpy
You now have a working SunPy installation. You can check your SunPy install by following the instructions in Testing SunPy.
Note: Currently Glymur / JPEG2000 support is not tested under Anaconda on any platforms. However, an external installation of openJPEG should work with the glymur installation in conda.
Updating SunPy to a New Version
When a new version of SunPy is released you can update to the latest version by running: conda update sunpy
Advanced SunPy Installation
If you do not wish to use Anaconda to install Scientific Python or you already have a scientific Python installation there are other options for installing SunPy.
Advanced Installation Instructions
This document provides details on things you need to know to install and manage your own scientific Python + SunPy installation. If you have never installed or used scientific Python we recommend that you follow the Anaconda installation instructions.
Alternative Scientific Python Installation Instructions
There are many alternatives to Anaconda as a way of installing a scientific Python environment, there are various other platform specific ways to install scientific Python:
Linux
Overview
Warning: We highly recommend that users use the Anaconda python distribution. Instructions are available here anaconda_install.
4 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
Almost all versions of Linux ship with a recent enough version of Python, so it is unlikely that you will need to install Python yourself. If you do not have python you can find the source at the Python official site. Install using sudo apt-get install python2.7-dev or a similar command, depending on your linux distro. Anything like python-dev provides you the required Python development headers.
Debian based (eg. Ubuntu)
On Ubuntu, most of the pre-reqs are available in the Ubuntu software repos and can be installed using apt-get: sudo apt-get install python-dev sudo apt-get install python-qt4 sudo apt-get install git-core sudo apt-get install python-numpy sudo apt-get install python-scipy sudo apt-get install python-matplotlib sudo apt-get update
Most Python distributions ship with a tool called easy_install which assists with installing Python packages. Although easy_install is capable of installing most of the dependencies needed for SunPy itself, a more powerful tool called pip provides a more flexible installation (including support for uninstalling, upgrading, and installing from remote sources such as GitHub) and should be used instead. Use easy_install to install pip: sudo easy_install pip
You are now ready to install SunPy and its dependencies.
Mac OS X
Overview
Warning: We highly recommend that users use the Anaconda python distribution. Instructions are available here anaconda_install.
Because of the wide variety of methods for setting up a Python environment on Mac OS X, users have a number of options with how to install SunPy and its dependencies. We have a number of solutions listed below. Choose the solution which best suits you. For users who wish to have more control over the installation of Python, several alternative installation methods are provided below, including instructions for Macports and Homebrew. The following instructions are not recommended for beginners. OS X comes pre-loaded with Python but each versions of OS X (Mountain Lion, Snow Leopard, etc.) ships with a different version of Python. In the instructions below, we therefore recommend that you install your own version of Python. You will then have two versions of Python living on your system at the same time. It can be confusing to make sure that when you install packages they are installed for the correct Python so beware.
Download and install the latest version of 32 bit Python 2.7.3 using their DMG installer. Next, choose your package installer of choice (either Macports or Homebrew) and follow the instructions below. If you do not have either go to their respective websites and install one of the other as needed.
XCode tools / Compiler
If you are using MacOS X, you will need to the XCode command line tools. One way to get them is to install XCode. If you are using OS X 10.7 (Lion) or later, you must also explicitly install the command line tools. You can do this by opening the XCode application, going to Preferences, then Downloads, and then under Components, click on the Install button to the right of Command Line Tools. Alternatively, on 10.7 (Lion) or later, you do not need to install XCode, you can download just the command line tools from https://developer.apple.com/downloads/index. action (requires an Apple developer account).
Homebrew
Homebrew is a tool for helping to automate the installation of a number of useful tools and libraries on Mac OS X. It is similar to Macports, but attempts to improve on some of the pitfalls of Macports. Note that if you have already installed either fink or Macports on your system, it is recommended that you uninstall them before using Homebrew. Next, install and update homebrew:
Most Python distributions ship with a tool called easy_install which assists with installing Python packages. Although easy_install is capable of installing most of the dependencies needed for SunPy itself, a more powerful tool called pip which provides a more flexible installation (including support for uninstalling, upgrading, and installing from remote sources such as GitHub) and should be used instead. Use easy_install to install pip:
sudo easy_install pip
You are now ready to install scipy, numpy, and matplotlib.
6 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
Scientific Libraries
If pip installed properly, then you can install NumPy simply with:
pip install numpy
Now under Lion, install the stable version of SciPy (0.10) by running:
pip install scipy
Mountain Lion users will need to install the development version of SciPy (0.11) by executing the following line: pip install -e git+https://github.com/scipy/scipy#egg=scipy-dev Now on to matplotlib On Lion, install matplotlib like any other package:
pip install matplotlib
Mountain Lion users will have to use the development version as of this writing:
Installing SunPy on top of an existing Scientific Python Environment
These instructions assume you have a scientific Python distribution with access to the pip command installed.
Prerequisites
You will need a compiler suite and the development headers for Python and Numpy in order to build SunPy. On Linux, using the package manager for your distribution will usually be the easiest route, while on MacOS X you will need the XCode command line tools. The instructions for building Numpy from source are also a good resource for setting up your environment to build Python packages.
Note: If you are using MacOS X, you will need to the XCode command line tools. One way to get them is to install XCode. If you are using OS X 10.7 (Lion) or later, you must also explicitly install the command line tools. You can do this by opening the XCode application, going to Preferences, then Downloads, and then under Components, click on the Install button to the right of Command Line Tools. Alternatively, on 10.7 (Lion) or later, you do not need to install XCode, you can download just the command line tools from the Apple developer site (requires an Apple developer account).
SunPy’s Requirements
SunPy consists of many submodules that each have their own requirements. You do not need to fulfil all the require- ments if you only intend on using parts of SunPy. It is however strongly recommended to have all the dependencies installed (with the potential exception of glymur). SunPy has the following strict requirements:
• Python 2.7 • NumPy 1.6.0 or later • SciPy 0.10.0 or later • AstroPy 1.0.0 or later SunPy also depends on other packages for optional features. However, note that these only need to be installed if those particular features are needed. SunPy will import even if these dependencies are not installed. • Matplotlib[ Highly Recommended] 1.3.0 or later: For ~sunpy.lightcurve, ~sunpy.map, ~sunpy.spectra, ~sunpy.instr and ~sunpy.visualization. • pandas 0.10 or later: For ~sunpy.lightcurve. • sqlalchemy: For the ~sunpy.database package. • suds-jurko: For ~sunpy.net. • beautifulsoup4: For ~sunpy.spectra.Callisto Spectrograms and ~sunpy.net.helio • requests: For the ~sunpy.net.jsoc submodule. • wcsaxes: For sunpy.map plotting improvements. • glymur 0.5.9 or later: To enable reading of JPEG2000 files. Glymur requires the installation of the OpenJPEG C library. • pytest: To run tests. The packages that will be installed as dependencies by default and are the ones required to import the core datatypes ~sunpy.map, ~sunpy.lightcurve and ~sunpy.spectra. These are the strict requirements and the following optional pack- ages:
Using pip
There are multiple options depending on how many optional dependencies you want to install: To install SunPy with pip including optional dependencies (recommended), simply run: pip install sunpy[all]
To install SunPy with no optional dependencies: pip install sunpy
To install SunPy with net-based dependencies (suds and beautifulsoup): pip install sunpy[net]
To install SunPy with database dependencies (sqlalchemy): pip install sunpy[database]
Warning: Users of the Anaconda python distribution should follow the instructions for anaconda_install.
Note: You will need a C compiler (e.g. gcc or clang) to be installed.
8 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
Note: If you get a PermissionError this means that you do not have the required administrative access to install new packages to your Python installation. In this case you may consider using the --user option to install the package into your home directory. You can read more about how to do this in the pip documentation. Alternatively, if you intend to do development on other software that uses SunPy, such as an affiliated package, consider installing SunPy into a virtualenv. Do not install SunPy or other third-party packages using sudo unless you are fully aware of the risks.
Testing SunPy
The easiest way to test your installed version of SunPy is running correctly is to use the sunpy.self_test() function: import sunpy sunpy.self_test(online=False) which will run many of the SunPy tests. The tests should run and print out any failures, which you can report at the SunPy issue tracker.
Installing the Development Version of SunPy
The latest (bleeding-edge) development version of SunPy can be cloned from github using this command: git clone git://github.com/sunpy/sunpy.git
Note: If you wish to participate in the development of SunPy, see developer-docs. This document covers only the basics necessary to install SunPy.
Once inside the source directory that has been clone from GitHub you can install SunPy using: python setup.py install
Note: This command will need access to system folders append –user to install SunPy into your home directory.
Troubleshooting
If you get an error mentioning that you do not have the correct permissions to install SunPy into the default site-packages directory, you should try installing with: pip install sunpy--user which will install into a default directory in your home directory.
Note: Building the documentation is in general not necessary unless you are writing new documentation or do not have internet access, because the latest (and archive) versions of SunPy’s documentation are available at docs.sunpy.org .
Building the documentation requires the SunPy source code and some additional packages: • Sphinx (and its dependencies) 1.0 or later • Graphviz
Note: Sphinx also requires a reasonably modern LaTeX installation to render equations. Per the Sphinx documenta- tion, for the TexLive distribution the following packages are required to be installed: • latex-recommended • latex-extra • fonts-recommended For other LaTeX distributions your mileage may vary. To build the PDF documentation using LaTeX, the fonts-extra TexLive package or the inconsolata CTAN package are also required.
There are two ways to build the SunPy documentation. The most straightforward way is to execute the command (from the sunpy source directory):
python setup.py build_sphinx-lo
The documentation will be built in the doc/build/html directory, and can be read by pointing a web browser to doc/build/html/index.html. The LaTeX documentation can be generated by using the command:
python setup.py build_sphinx-b latex
The LaTeX file SunPy.tex will be created in the doc/build/latex directory, and can be compiled using pdflatex. The above method builds the API documentation from the source code.
A brief tour of SunPy
This brief tutorial will walk you through some of the functionality offered by SunPy. Start by reading this tutorial and trying out some of the examples demonstrated. Once you’ve completed the tutorial check out the rest of the User Guide for a more thorough look at the functionality available.
Sample Data
This tour makes use of a number of sample data files which you will need to download. If have not already done so please follow the instruction here Downloading Sample Data.
10 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
Maps
Maps are the primary data type in SunPy they are spatially and / or temporally aware data arrays. There are maps for a 2D image, a time series of 2D images or temporally aligned 2D images. Creating a Map SunPy supports many different data products from various sources ‘out of the box’. We shall use SDO’s AIA instru- ment as an example in this tutorial. The general way to create a Map from one of the supported data products is with the ~sunpy.map.map() function from the ~sunpy.map submodule. ~sunpy.map.map() takes either a filename, a list of filenames or a data array and header. We can test map with: This returns a map named aia which can be manipulated with standard SunPy map commands. For more information about maps checkout the map guide and the SunPy map.
Lightcurve
SunPy handles time series data, fundamental to the study of any real world phenomenon, by creating a lightcurve object. A lightcurve consists of two parts; times and measurements taken at those times. The data can either be in your current Python session, alternatively within a local or remote file. Let’s create some fake data and pass it into a lightcurve object. Within LightCurve.create, we have a dictionary that contains a single entry with key “signal” containing a list of 1000 entries (0-999). The accompanying set of times is passed in via the index keyword argument. If no times are passed into index, a default set of time indices is generated. For more information about lightcurves, check out the lightcurve guide and the and the SunPy lightcurve.
Spectra
SunPy has spectral support for instruments which have such a capacity. CALLISTO, an international network of Solar Radio Spectrometers, is a specific example. For more information about spectra, check out the spectra guide and the SunPy spectra.
Plotting
SunPy uses a matplotlib like interface to it’s plotting so more complex plots can be built by combining SunPy with matplotlib. Let’s begin by creating a simple plot of an AIA image. To make things easy, SunPy includes several example files which are used throughout the docs. These files have names like sunpy.data.sample.AIA_171_IMAGE and sunpy.data.sample.RHESSI_IMAGE. Try typing the below example into your interactive Python shell. If everything has been configured properly you should see an AIA image with a red colormap, a colorbar on the right-hand side and a title and some labels. There is lot going on here, but we will walk you through the example. Briefly, the first line is just importing SunPy. On the second line we create a SunPy Map object which is basically just a spatially-aware image or data array. On the last line we then plot the map object, using the built in ‘quick plot’ function peek(). SunPy uses a matplotlib like interface to it’s plotting so more complex plots can be built by combining SunPy with matplotlib. For more information check out Plotting in SunPy.
1.2. A brief tour of SunPy 11 DemoDoc Documentation, Release
Solar Physical Constants
SunPy contains a convenient list of solar-related physical constants. Here is a short bit of code to get you started:
>>> from sunpy.sun import constants as con
# one astronomical unit (the average distance between the Sun and Earth) >>> print con.au Name = Astronomical Unit Value = 1.495978707e+11 Error = 0.0 Units = m Reference = IAU 2012 Resolution B2
# the solar radius >>> print con.radius Name = Solar radius Value = 695508000.0 Error = 26000.0 Units = m Reference = Allen's Astrophysical Quantities 4th Ed.
Not all constants have a shortcut assigned to them (as above). The rest of the constants are stored in a dictionary. The following code grabs the dictionary and gets all of the keys.:
You can also use the function sunpy.constants.print_all() to print out a table of all of the values available. These constants are provided as a convenience so that everyone is using the same (accepted) values. For more information check out SunPy sun.
Quantities and Units
Many capabilities in SunPy make use of physical quantities that are specified with units. SunPy uses ~astropy.units to implement this functionality. For example, the solar radius above is a physical quantity that can be expressed in length units. In the example above from sunpy.sun import constants as con con.radius
˓→"Allen's Astrophysical Quantities 4th Ed."> shows the solar radius in units of meters. It is simple to express the same physical quantity in different units: con.radius.to('km')
To get the numerical value of the solar radius in kilometers - without the unit information - use
12 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
con.radius.to('km').value 695508.0
Quantities and units are simple and powerful tools for keeping track of the units you’re working in, and make it easy to convert the same physical quantity into different units. To learn more about the capabilities of quantities and units, please consult the astropy tutorial. SunPy’s approach to the adoption of quantities and units in the codebase is described here. Here’s a simple example of the power of units. Suppose you have the radius of a circle and would like to calculate its area. The following code implements this
The first line imports numpy, and the second line imports astropy’s units module. The beginning of the third line (the “@” symbol) indicates that what follows is a Python decorator. In this case, the decorator allows us to specify what kind of unit the function input variable “radius” in the following function “circle_area” should have. In this case, it is meters. The decorator checks that the input is convertible to the units specified in the decorator. Calculating the area of a circle with radius 4 meters using the function defined above is simple circle_area(4 * u.m)
The units of the returned area are what we expect, namely the meters squared (m2). However, we can also use other units of measurement; for a circle with radius 4 kilometers circle_area(4 * u.km)
Even although the input value of the radius was not in meters, the function does not crash; this is because the input unit is convertible to meters. This also works across different systems of measurement, for example circle_area(4 * u.imperial.foot)
However, if the input unit is not convertible to meters, then an error is thrown
>>> circle_area(4 * u.second) ... UnitsError: Argument 'radius' to function 'circle_area' must be in units convertable
˓→to 'm'.
Also, if no unit is specified, an error is thrown
>>> circle_area(4) ... TypeError: Argument 'radius' to function has 'circle_area' no 'unit' attribute. You
˓→may want to pass in an astropy Quantity instead.
Using units allows the user to be explicit about what the function expects. Units also make conversions very easy to do. For example, if you want the area of a circle in square feet, but were given measurements in meters, then circle_area((4 * u.m).to(u.imperial.foot))
1.2. A brief tour of SunPy 13 DemoDoc Documentation, Release
or
>>> circle_area(4 * u.m).to(u.imperial.foot ** 2)
Astropy units and quantities are very powerful, and are used throughout SunPy. To find out more about units and quantities, please consult the the astropy tutorial and documentation
Working with Times
SunPy also contains a number of convenience functions for working with dates and times. Here is a short example:
>>> import sunpy.time
# parsing a standard time strings >>> sunpy.time.parse_time('2004/02/05 12:00') datetime.datetime(2004, 2, 5, 12, 0)
# This returns a datetime object. All SunPy functions which require # time as an input sanitize the input using parse_time. >>> sunpy.time.day_of_year('2004-Jul-05 12:00:02') 187.50002314814816
# the julian day >>> sunpy.time.julian_day((2010,4,30)) 2455316.5
# TimeRange objects are useful for representing ranges of time >>> time_range= sunpy.time.TimeRange('2010/03/04 00:10','2010/03/04 00:20') >>> time_range.center datetime.datetime(2010, 3, 4, 0, 15)
For more information about working with time in SunPy checkout the time guide.
Getting at Data
Querying the VSO
There are a couple different ways to query and download data from the VSO using SunPy. The method you should use depends first on your preference with respect to query style: the main method of querying uses a syntax that is unique to SunPy and may require some getting used to, but is extremely flexible and powerful. A second “legacy” API also exists which works is very much the same way as VSO_GET in IDL. Further, for each of the two query APIs there are interactive and non-interactive versions available, depending on the type of work you are doing. The below example demonstrates a simple query for SOHO EIT data using the non-interactive version of the main API:
>>> from sunpy.net import vso
# create a new VSOClient instance >>> client= vso.VSOClient()
# build our query >>> result= client.query(
14 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
# print the number of matches >>> print("Number of records found: {}".format(len(result))) Number of records found: 4
# download matches to /download/path >>> res= client.get(result, path="/download/path/ {file}").wait()
Note that specifying a path is optional and if you do not specify one the files will simply be downloaded into a temporary directory (e.g. /tmp/xyz). For more information about vso client checkout the vso guide.
Database Package
The database package offers the possibility to save retrieved data (e.g. via the :mod:’sunpy.net.vso’ package) onto a local or remote database. The database may be a single file located on a local hard drive (if a SQLite database is used) or a local or remote database server. This makes it possible to fetch required data from the local database instead of downloading it again from a remote server. Querying a database is straightforward, as this example using VSO, shows. The example demonstrates the useful feature which prevents storing the same data twice:
>>> from sunpy.database import Database >>> from sunpy.net.vso.attrs import Time, Instrument >>> db= Database('sqlite:///') >>> entries= db.fetch( ... Time('2012-08-05','2012-08-05 00:00:05'), ... Instrument('AIA')) >>> assert entries is None >>> len(db) 4 >>> entries= db.fetch( ... Time('2012-08-05','2012-08-05 00:00:05'), ... Instrument('AIA')) >>> entries is None False >>> len(entries) 4 >>> len(db) 4
Explanation: first, entries is None because the query has never been used for querying the database -> query the VSO, add new entries to database, remember query hash. In the second fetch, entries is not None because the query has already been used and returns a list of database entries. For more information check out the Using the database package.
Querying Helioviewer.org
SunPy can be used to make several basic requests using the The Helioviewer.org API including generating a PNG and downloading a JPEG 2000 image and loading it into a SunPy Map. A simple example of a helioviewer query and generating a plot of the result follows:
1.2. A brief tour of SunPy 15 DemoDoc Documentation, Release
>>> from sunpy.net.helioviewer import HelioviewerClient >>> import matplotlib.pyplot as plt >>> from matplotlib.image import imread >>> hv= HelioviewerClient() >>> file= hv.download_png('2099/01/01', 4.8,"[SDO,AIA,AIA,304,1,100]", x0=0, y0=0,
This downloads a PNG image of the latest AIA 304 image available on Helioviewer.org. In the ~sunpy.net.helioviewer.HelioviewerClient.download_png command the value, 4.8, refers to the image resolution in arcseconds per pixel (larger values mean lower resolution), x0 and y0 are the center points about which to focus and the width and height are the pixel values for the image dimensions. For more information checkout the helioviewer guide.
Acquiring Data with SunPy
Downloading Sample Data
SunPy provides a number of sample data files which are referenced in the documentation and examples. These files are available to download onto your local machine so that you can try out the code in the documentation. To download the sample data simply run the following command: import sunpy.data sunpy.data.download_sample_data()
With a bad Internet connection it helps to set the overwrite=False parameter in dowload_sample_data. This will download the data to your sample-data directory which can be customized by editing the sunpyrc file (see Customizing SunPy). After running this you can then import the sample data files shortcuts which are used below by simply importing the module like so: import sunpy.data.sample
If the sample files are not available for some reason that you will get an error on import.
Downloading Data from the VSO
The main interface which SunPy provides to search for and download data is provided by SunPy’s VSO module. This module provides an interface to the Virtual Solar Observatory (VSO) which is a service which presents a homogeneous interface to heterogeneous data-sets and services. Using the VSO, a user can query multiple data providers simulta- neously, and then download the relevant data. SunPy uses the VSO through the vso module, which was developed through support from the European Space Agency Summer of Code in Space (ESA-SOCIS) 2011.
Setup
SunPy’s VSO module is in sunpy.net. It can be imported as follows:
>>> from sunpy.net import vso >>> client=vso.VSOClient()
16 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
This creates your client object. Obtaining data via the VSO is a two-stage process. You first ask the VSO to find the data you want. The VSO queries various data-providers looking for your data. If there is any data that matches your request, you choose the data you want to download. The VSO client handles the particulars of how the data from the data provider is downloaded to your computer.
Searching the VSO
To search the VSO, your query needs at minimum a start time, an end time, and an instrument. Two styles of con- structing the query are supported by SunPy’s VSO module. The first style is very flexible, as it allows users to issue complex queries in a single command. This query style is described below. The second query style - known as the legacy query is useful for making quick VSO queries, and is based on the function call to SSWIDL’s VSO query client. The section below first describe the more flexible query style. The next section then describes the legacy query. The final section describes how to download data from those query results.
Constructing a Query
Let’s start with a very simple query. We could ask for all SOHO/EIT data between January 1st and 2nd, 2001.
The variable qr is a Python list of response objects, each one of which is a record found by the VSO. You can find how many records were found by typing
>>> len(qr) 122
To get a little bit more information about the records found, try
>>> print(qr) ...
Now, let’s break down the arguments of client.query to understand better what we’ve done. The first argument: vso.attrs.Time('2001/1/1', '2001/1/2') sets the start and end times for the query (any date/time format understood by SunPy’s parse_time function can be used to specify dates and time). The second argument: vso.attrs.Instrument('eit') sets the instrument we are looking for. The third argument: vso.attrs.Wave(142*u.AA, 123*u.AA) sets the values for wavelength i.e, for wavemax(maximum value) and similarly wavemin(for minimum value) for the query. Also the u.AA part comes from astropy.units.Quantity where AA is Angstrom. It should be noted that specifying spectral units in arguments is necessary or an error will be raised. To know more check astropy.units. So what is going on here? The notion is that a VSO query has a set of attribute objects - described in vso.attrs - that are specified to construct the query. For the full list of vso attributes, use
>>> help(vso.attrs)
1.3. Acquiring Data with SunPy 17 DemoDoc Documentation, Release
Note that due to a current bug in the VSO, we do not recommend that the extent object vso.attrs.Extent be in your query. Instead, we recommend that any extent filtering you need to do be done on the queries made without setting a value to the vso.attrs.Extent object. As we will see, this query style can take more than two arguments, each argument separated from the other by a comma. Each of those arguments are chained together using a logical AND. This query style allows you to combine these VSO attribute objects in complex ways that are not possible with the legacy query style. So, let’s look for the EIT and MDI data on the same day:
The two instrument types are joined together by the operator “|”. This is the OR operator. Think of the above query as setting a set of conditions which get passed to the VSO. Let’s say you want all the EIT data from two separate days:
Each of the arguments in this query style can be thought of as setting conditions that the returned records must satisfy. You can set the wavelength; for example, to return the 171 Angstrom EIT results
If you just need to do a quick query or don’t want to do anything too complicated you can use the legacy query style. Here is the first example from the above section executed using a legacy query. As before, we want EIT data between 2001/01/01 and 2001/01/02
which is almost identical to what you would type in SSWIDL. So, what’s happening with this command? The client is going out to the web to query the VSO to ask how many files EIT images are in the archive between the start of 2001/01/01 and the start of 2001/01/02. The same query can also be performed using a slightly different syntax. For example
both gives the same result. The variable qr is a Python list of response objects, each one of which is a record found by the VSO. How many records have been found? You can find that out be typing
>>> len(qr) 122
To get a little bit more information, try
18 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
>>> print(qr) ...
The Solarsoft legacy query has more keywords available: to find out more about the legacy query, type:
>>> help(client.query_legacy)
As an example, let’s say you just want the EIT 171 Angstrom files for that data. These files can be found by
which yields four results, the same as the VSO IDL client.
Downloading data
All queries return a query response list. This list can then used to get the data. This list can also be edited as you see fit. For example you can further reduce the number of results and only get those. So having located the data you want, you can download it using the following command:
This downloads the query results into the directory /ThisIs/MyPath/to/Data naming each downloaded file with the filename {file} obtained from the VSO , and appended with the suffix .fits. The {file} option uses the file name obtained by the VSO for each file. You can also use other properties of the query return to define the path where the data is saved. For example, to save the data to a subdirectory named after the instrument, use
If you have set your default download directory in your sunpyrc configuration file then you do not need to identify a path at all. All you data will be downloaded there. Note that the download process is spawned in parallel to your existing Python session. This means that the remainder of your Python script will continue as the download proceeds. This may cause a problem if the remainder of your script relies on the presence of the downloaded data. If you want to resume your script after all the data has been downloaded then append .wait() to the get command above, i.e.,
More information on the options available can be found through the standard Python help command.
Using SunPy’s HEK module
The Heliophysics Event Knowledgebase (HEK) is a repository of feature and event information about the Sun. Entries are generated both by automated algorithms and human observers. SunPy accesses this information through the hek module, which was developed through support from the European Space Agency Summer of Code in Space (ESA- SOCIS) 2011.
1. Setting up the client
SunPy’s HEK module is in sunpy.net. It can be imported into your session as follows:
1.3. Acquiring Data with SunPy 19 DemoDoc Documentation, Release
>>> from sunpy.net import hek >>> client= hek.HEKClient()
This creates a client that we will use to interact with the HEK.
2. A simple query
To search the HEK, you need a start time, an end time, and an event type. Times are specified as strings or Python date- time objects. Event types are specified as upper case, two letter strings, and are identical to the two letter abbreviations found at the HEK website, http://www.lmsal.com/hek/VOEvent_Spec.html.
The first line defines the search start and end times. The second line specifies the event type, in this ‘FL’ or flare. Line 4 goes out to the web, contacts the HEK, and queries it for the information you have requested. Event data for ALL flares available in the HEK within the time range 2011/08/09 07:23: 56 UT - 2011/08/09 12:40:20 UT will be returned, regardless of which feature recognition method used to detect the flare. Let’s break down the arguments of client.query. The first argument: hek.attrs.Time(tstart,tend) sets the start and end times for the query. The second argument: hek.attrs.EventType(event_type) sets the type of event to look for. Since we have defined event_type = ‘FL’, this sets the query to look for flares. We could have also set the flare event type using the syntax: hek.attrs.FL
There is more on the attributes of hek.attrs in section 4 of this guide.
3. The result
So, how many flare detections did the query turn up?
>>> len(result) 19
The object returned by the above query is a list of Python dictionary objects. Each dictionary consists of key-value pairs that exactly correspond to the parameters listed at http://www.lmsal.com/hek/VOEvent_Spec.html. You can inspect all the dictionary keys very simply:
20 Chapter 1. SunPy User Guide DemoDoc Documentation, Release and so on. Remember, the HEK query we made returns all the flares in the time-range stored in the HEK, regardless of the feature recognition method. The HEK parameter which stores the the feature recognition method is called “frm_name”. Using list comprehensions (which are very cool), it is easy to get a list of the feature recognition methods used to find each of the flares in the result object, for example:
It is likely each flare on the Sun was actually detected multiple times by many different methods.
4. More complex queries
The HEK client allows you to make more complex queries. There are two key features you need to know in order to make use of the full power of the HEK client. Firstly, the attribute module - hek.attrs - describes ALL the parame- ters stored by the HEK as listed in http://www.lmsal.com/hek/VOEvent_Spec.html, and the HEK client makes these parameters searchable. To explain this, let’s have a closer look at hek.attrs. The help command is your friend here; scroll down to section DATA you will see:
>>> help(hek.attrs) AR = Area = Bound = BoundBox = CC = CD = CE = CH = CJ = CR = CW = EF = ER = Event = FA = FE = FI = FL = FRM =
1.3. Acquiring Data with SunPy 21 DemoDoc Documentation, Release
etc etc...
The object hek.attrs knows the attributes of the HEK. You’ll see that one of the attributes is a flare object:
FL=
We can replace hek.attrs.EventType(‘FL’) with hek.attrs.FL - they do the same thing, setting the query to look for flare events. Both methods of setting the event type are provided as a convenience Let’s look further at the FRM attribute:
>>> help(hek.attrs.FRM) Help on FRM in module sunpy.net.hek.attrs object: class FRM(__builtin__.object) | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ------| Data and other attributes defined here: | | Contact = | | HumanFlag = | | Identifier = | | Institute = | | Name = | | ParamSet = | | SpecificID = | | URL = | | VersionNumber =
Let’s say I am only interested in those flares identified by the SSW Latest Events tool. I can retrieve those entries only from the HEK with the following command:
22 Chapter 1. SunPy User Guide DemoDoc Documentation, Release
We are using Python’s comparison operators to filter the returns from the HEK client. Other comparisons are possible. For example, let’s say I want all the flares that have a peak flux of over 4000.0:
Multiple comparisons can be included. For example, let’s say I want all the flares with a peak flux above 1000 AND west of 800 arcseconds from disk center of the Sun
Multiple comparison operators can be used to filter the results back from the HEK. The second important feature about the HEK client is that the comparisons we’ve made above can be combined using Python’s logical operators. This makes complex queries easy to create. However, some caution is advisable. Let’s say I want all the flares west of 50 arcseconds OR have a peak flux over 1000.0:
>>> [elem["event_coord1"] for elem in result] [51, 51, 51, 924, 924, 924, 69, 883.2, 883.2, 69, 69, 883.2, 883.2, 883.2,
1.3. Acquiring Data with SunPy 23 DemoDoc Documentation, Release
883.2, 883.2]
Note that some of the fluxes are returned as “None”. This is because some feature recognition methods for flares do not report the peak flux. However, because the location of event_coord1 is greater than 50, the entry from the HEK for that flare detection is returned. Let’s say we want all the flares west of 50 arcseconds AND have a peak flux over 1000.0:
˓→type), (hek.attrs.Event.Coord1> 50) and (hek.attrs.FL.PeakFlux> 1000.0))
>>> [elem["fl_peakflux"] for elem in result] [2326.86, 1698.83, 2360.49, 3242.64, 1375.93, 6275.98] >>> [elem["event_coord1"] for elem in result] [883.2, 883.2, 883.2, 883.2, 883.2, 883.2]
In this case none of the peak fluxes are returned with the value None. Since we are using an and logical operator we need a result from the (hek.attrs.FL.PeakFlux > 1000.0) filter. Flares that have None for a peak flux cannot provide this, and so are excluded. The None type in this context effectively means “Don’t know”; in such cases the client returns only those results from the HEK that definitely satisfy the criteria passed to it.
5. Getting data for your event
The ‘hek2vso’ module allows you to take an HEK event and acquire VSO records specific to that event.
>>> from sunpy.net import hek2vso >>> h2v= hek2vso.H2VClient()
There are several ways to use this capability. For example, you can pass in a list of HEK results and get out the corresponding VSO records. Here are the VSO records returned via the tenth result from the HEK query in Section 2 above:
Result 10 is an HEK entry generated by the “Flare Detective” automated flare detection algorithm running on the AIA 193 angstrom waveband. The VSO records are for full disk AIA 193 images between the start and end times of this event. The ‘translate_and_query’ function uses exactly that information supplied by the HEK in order to find the relevant data for that event. Note that the VSO does not generate records for all solar data, so it is possible that an HEK entry corresponds to data that is not accessible via the VSO. You can also go one step further back, passing in a list of HEK attribute objects to define your search, the results of which are then used to generate their corresponding VSO records:
>>> from sunpy.net import hek >>> q= h2v.full_query((hek.attrs.Time('2011/08/09 07:23:56','2011/08/09 12:40:29'),
˓→hek.attrs.EventType('FL')))
The full capabilities of the HEK query module can be used in this function (see above). Finally, for greater flexibility, it is possible to pass in a list of HEK results and create the corresponding VSO query attributes.
24 Chapter 1. SunPy User Guide DemoDoc Documentation, Release