Examples#
This example gallery using the best practices and illustrates functionality throughout asilib. These are complete examples that are also included in the asilib/examples/
directory on GitHub.
Fisheye Lens View of an Arc#
A bright auroral arc that was analyzed by Imajo et al. 2021 “Active auroral arc powered by accelerated electrons from very high altitudes”
from datetime import datetime
import matplotlib.pyplot as plt
import asilib.asi
location_code = 'RANK'
time = datetime(2017, 9, 15, 2, 34, 0)
asi = asilib.asi.themis(location_code, time=time)
ax, im = asi.plot_fisheye()
plt.colorbar(im)
ax.axis('off')
plt.show()
from datetime import datetime
import matplotlib.pyplot as plt
import asilib
asi_array_code = 'THEMIS'
location_code = 'RANK'
time = datetime(2017, 9, 15, 2, 34, 0)
# A bright auroral arc that was analyzed by Imajo et al., 2021 "Active
# auroral arc powered by accelerated electrons from very high altitudes"
image_time, image, ax, im = asilib.plot_fisheye(
asi_array_code, location_code, time, color_norm='log', redownload=False
)
plt.colorbar(im)
ax.axis('off')
plt.show()
STEVE projected onto a map#
Maps an image of STEVE (the thin band). Reproduced from http://themis.igpp.ucla.edu/nuggets/nuggets_2018/Gallardo-Lacourt/fig2.jpg
from datetime import datetime
import matplotlib.pyplot as plt
import asilib.asi
import asilib.map
ax = asilib.map.create_map(lon_bounds=(-127, -100), lat_bounds=(45, 65))
asi = asilib.asi.themis('ATHA', time=datetime(2010, 4, 5, 6, 7, 0), alt=110)
asi.plot_map(ax=ax)
plt.tight_layout()
plt.show()
from datetime import datetime
import matplotlib.pyplot as plt
import asilib
ax = asilib.make_map(lon_bounds=(-127, -100), lat_bounds=(45, 65))
image_time, image, skymap, ax, p = asilib.plot_map(
'THEMIS', 'ATHA', datetime(2010, 4, 5, 6, 7, 0), 110, ax=ax
)
plt.tight_layout()
plt.show()
Auroral arc projected onto a map#
The first breakup of an auroral arc during a substorm analyzed by Donovan et al. 2008 “Simultaneous THEMIS in situ and auroral observations of a small substorm”
from datetime import datetime
import matplotlib.pyplot as plt
import asilib
import asilib.map
import asilib.asi
time = datetime(2007, 3, 13, 5, 8, 45)
location_codes = ['FSIM', 'ATHA', 'TPAS', 'SNKQ']
map_alt = 110
min_elevation = 2
ax = asilib.map.create_simple_map(lon_bounds=(-140, -60), lat_bounds=(40, 82))
_imagers = []
for location_code in location_codes:
_imagers.append(asilib.asi.themis(location_code, time=time, alt=map_alt))
asis = asilib.Imagers(_imagers)
asis.plot_map(ax=ax, overlap=False, min_elevation=min_elevation)
ax.set_title('Donovan et al. 2008 | First breakup of an auroral arc')
plt.show()
from datetime import datetime
import matplotlib.pyplot as plt
import asilib
time = datetime(2007, 3, 13, 5, 8, 45)
asi_array_code = 'THEMIS'
location_codes = ['FSIM', 'ATHA', 'TPAS', 'SNKQ']
map_alt = 110
min_elevation = 2
ax = asilib.make_map(lon_bounds=(-160, -52), lat_bounds=(40, 82))
for location_code in location_codes:
asilib.plot_map(
asi_array_code, location_code, time, map_alt, ax=ax, min_elevation=min_elevation
)
ax.set_title('Donovan et al. 2008 | First breakup of an auroral arc')
plt.show()
A keogram of STEVE#
A keogram with a STEVE event that moved towards the equator. This event was analyzed in Gallardo-Lacourt et al. 2018 “A statistical analysis of STEVE”
import matplotlib.pyplot as plt
import asilib.asi
location_code = 'LUCK'
time_range = ['2017-09-27T07', '2017-09-27T09']
map_alt_km = 230
fig, ax = plt.subplots(figsize=(8, 6))
asi = asilib.asi.rego(location_code, time_range=time_range, alt=map_alt_km)
ax, p = asi.plot_keogram(ax=ax, color_bounds=(300, 800), aacgm=True)
plt.colorbar(p, label='Intensity')
ax.set_xlabel('UTC')
ax.set_ylabel(f'Magnetic Latitude [deg]\nEmission altitude={map_alt_km} km')
plt.tight_layout()
plt.show()
import matplotlib.pyplot as plt
import asilib
asi_array_code = 'REGO'
location_code = 'LUCK'
time_range = ['2017-09-27T07', '2017-09-27T09']
map_alt_km = 230
fig, ax = plt.subplots(figsize=(8, 6))
ax, im = asilib.plot_keogram(
asi_array_code,
location_code,
time_range,
ax=ax,
map_alt=map_alt_km,
color_bounds=(300, 800),
)
plt.colorbar(im, label='Intensity')
ax.set_xlabel('UTC')
ax.set_ylabel(f'Emission Latitude [deg] at {map_alt_km} km')
plt.tight_layout()
plt.show()
Keogram of a field line resonance#
A field line resonance studied in: Gillies, D. M., Knudsen, D., Rankin, R., Milan, S., & Donovan, E. (2018). A statistical survey of the 630.0-nm optical signature of periodic auroral arcs resulting from magnetospheric field line resonances. Geophysical Research Letters, 45(10), 4648-4655.
import matplotlib.pyplot as plt
import asilib.asi
location_code = 'GILL'
time_range = ['2015-02-02T10', '2015-02-02T11']
asi = asilib.asi.rego(location_code, time_range=time_range, alt=230)
ax, p = asi.plot_keogram(color_map='Greys_r')
plt.xlabel('Time')
plt.ylabel('Geographic Latitude [deg]')
plt.colorbar(p)
plt.tight_layout()
plt.show()
import matplotlib.pyplot as plt
import asilib
asi_array_code = 'REGO'
location_code = 'GILL'
time_range = ['2015-02-02T10', '2015-02-02T11']
fig, ax = plt.subplots(figsize=(8, 6))
ax, im = asilib.plot_keogram(
asi_array_code,
location_code,
time_range,
ax=ax,
map_alt=230,
pcolormesh_kwargs={'cmap': 'Greys_r'},
)
plt.xlabel('Time')
plt.ylabel('Geographic Latitude [deg]')
plt.colorbar(im)
plt.tight_layout()
plt.show()
Fisheye Movie#
from datetime import datetime
import asilib.asi
location_code = 'FSMI'
time_range = (datetime(2015, 3, 26, 6, 7), datetime(2015, 3, 26, 6, 30))
asi = asilib.asi.themis(location_code, time_range=time_range)
asi.animate_fisheye()
print(f'Animation saved in {asilib.config["ASI_DATA_DIR"] / "animations" / asi.animation_name}')
from datetime import datetime
import asilib
asi_array_code = 'THEMIS'
location_code = 'FSMI'
time_range = (datetime(2015, 3, 26, 6, 7), datetime(2015, 3, 26, 6, 30))
asilib.animate_fisheye(asi_array_code, location_code, time_range, overwrite=True)
print(f'Movie saved in {asilib.config["ASI_DATA_DIR"] / "animations"}')
Map movie#
from datetime import datetime
import asilib.asi
import asilib.map
time_range = (datetime(2015, 3, 26, 6, 7), datetime(2015, 3, 26, 6, 12))
location_code = 'FSMI'
asi = asilib.asi.themis(location_code, time_range=time_range, alt=110)
lat_bounds = (asi.meta['lat'] - 7, asi.meta['lat'] + 7)
lon_bounds = (asi.meta['lon'] - 20, asi.meta['lon'] + 20)
ax = asilib.map.create_map(lon_bounds=lon_bounds, lat_bounds=lat_bounds)
asi.animate_map(ax=ax)
print(f'Animation saved in {asilib.config["ASI_DATA_DIR"] / "animations" / asi.animation_name}')
from datetime import datetime
import asilib
time_range = (datetime(2015, 3, 26, 6, 7), datetime(2015, 3, 26, 6, 12))
asi_array_code = 'THEMIS'
location_code = 'FSMI'
# We need the skymap only to center the map on the projected image.
skymap = asilib.load_skymap(asi_array_code, location_code, time_range[0])
lat_bounds = (skymap['SITE_MAP_LATITUDE']-7, skymap['SITE_MAP_LATITUDE']+7)
lon_bounds = (skymap['SITE_MAP_LONGITUDE']-20, skymap['SITE_MAP_LONGITUDE']+20)
ax = asilib.make_map(lon_bounds=lon_bounds, lat_bounds=lat_bounds)
asilib.animate_map(asi_array_code, location_code, time_range, 110, overwrite=True, ax=ax)
print(f'Movie saved in {asilib.config["ASI_DATA_DIR"] / "animations"}')
Animate Mosaic#
import asilib
import asilib.asi
time_range = ('2021-11-04T06:55', '2021-11-04T07:05')
asis = asilib.Imagers(
[asilib.asi.trex_rgb(location_code, time_range=time_range)
for location_code in ['LUCK', 'PINA', 'GILL', 'RABB']]
)
asis.animate_map(lon_bounds=(-115, -85), lat_bounds=(43, 63), overwrite=True)
ASI-satellite conjunction movie#
A comprehensive example that maps a hypothetical satellite track to an image and calculates the mean ASI intensity in a 20x20 km box around the satellite’s 100 km altitude footprint.
from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt
import asilib
import asilib.asi
# ASI parameters
location_code = 'RANK'
alt=110 # km
time_range = (datetime(2017, 9, 15, 2, 32, 0), datetime(2017, 9, 15, 2, 35, 0))
fig, ax = plt.subplots(
3, 1, figsize=(7, 10), gridspec_kw={'height_ratios': [4, 1, 1]}, constrained_layout=True
)
asi = asilib.asi.themis(location_code, time_range=time_range, alt=alt)
# Create the fake satellite track coordinates: latitude, longitude, altitude (LLA).
# This is a north-south satellite track oriented to the east of the THEMIS/RANK
# imager.
n = int((time_range[1] - time_range[0]).total_seconds() / 3) # 3 second cadence.
lats = np.linspace(asi.meta["lat"] + 5, asi.meta["lat"] - 5, n)
lons = (asi.meta["lon"] - 0.5) * np.ones(n)
alts = alt * np.ones(n) # Altitude needs to be the same as the skymap.
sat_lla = np.array([lats, lons, alts]).T
# Normally the satellite time stamps are not the same as the ASI.
# You may need to call Conjunction.interp_sat() to find the LLA coordinates
# at the ASI timestamps.
sat_time = asi.data.time
conjunction_obj = asilib.Conjunction(asi, (sat_time, sat_lla))
# Map the satellite track to the imager's azimuth and elevation coordinates and
# image pixels. NOTE: the mapping is not along the magnetic field lines! You need
# to install IRBEM and then use conjunction.lla_footprint() before
# calling conjunction_obj.map_azel.
sat_azel, sat_azel_pixels = conjunction_obj.map_azel()
# Calculate the auroral intensity near the satellite and mean intensity within a 10x10 km area.
nearest_pixel_intensity = conjunction_obj.intensity(box=None)
area_intensity = conjunction_obj.intensity(box=(10, 10))
area_mask = conjunction_obj.equal_area(box=(10,10))
# Need to change masked NaNs to 0s so we can plot the rectangular area contours.
area_mask[np.where(np.isnan(area_mask))] = 0
# Initiate the animation generator function.
gen = asi.animate_fisheye_gen(
ax=ax[0], azel_contours=True, overwrite=True, cardinal_directions='NE'
)
for i, (time, image, _, im) in enumerate(gen):
# Plot the entire satellite track, its current location, and a 20x20 km box
# around its location.
ax[0].plot(sat_azel_pixels[:, 0], sat_azel_pixels[:, 1], 'red')
ax[0].scatter(sat_azel_pixels[i, 0], sat_azel_pixels[i, 1], c='red', marker='o', s=50)
ax[0].contour(area_mask[i, :, :], levels=[0.99], colors=['yellow'])
if 'vline1' in locals():
vline1.remove() # noqa: F821
vline2.remove() # noqa: F821
text_obj.remove() # noqa: F821
else:
# Plot the ASI intensity along the satellite path
ax[1].plot(sat_time, nearest_pixel_intensity)
ax[2].plot(sat_time, area_intensity)
vline1 = ax[1].axvline(time, c='b')
vline2 = ax[2].axvline(time, c='b')
# Annotate the location_code and satellite info in the top-left corner.
location_code_str = (
f'THEMIS/{location_code} '
f'LLA=({asi.meta["lat"]:.2f}, '
f'{asi.meta["lon"]:.2f}, {asi.meta["alt"]:.2f})'
)
satellite_str = f'Satellite LLA=({sat_lla[i, 0]:.2f}, {sat_lla[i, 1]:.2f}, {sat_lla[i, 2]:.2f})'
text_obj = ax[0].text(
0,
1,
location_code_str + '\n' + satellite_str,
va='top',
transform=ax[0].transAxes,
color='red',
)
ax[1].set(ylabel='ASI intensity\nnearest pixel [counts]')
ax[2].set(xlabel='Time', ylabel='ASI intensity\n10x10 km area [counts]')
print(f'Animation saved in {asilib.config["ASI_DATA_DIR"] / "animations" / asi.animation_name}')
from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt
import asilib
# ASI parameters
asi_array_code = 'THEMIS'
location_code = 'RANK'
time_range = (datetime(2017, 9, 15, 2, 32, 0), datetime(2017, 9, 15, 2, 35, 0))
fig, ax = plt.subplots(
2, 1, figsize=(7, 10), gridspec_kw={'height_ratios': [4, 1]}, constrained_layout=True
)
# Load the skymap calibration data. This is only necessary to create a fake satellite track.
skymap_dict = asilib.load_skymap(asi_array_code, location_code, time_range[0])
# Create the fake satellite track coordinates: latitude, longitude, altitude (LLA).
# This is a north-south satellite track oriented to the east of the THEMIS/RANK
# imager.
n = int((time_range[1] - time_range[0]).total_seconds() / 3) # 3 second cadence.
lats = np.linspace(skymap_dict["SITE_MAP_LATITUDE"] + 5, skymap_dict["SITE_MAP_LATITUDE"] - 5, n)
lons = (skymap_dict["SITE_MAP_LONGITUDE"] - 0.5) * np.ones(n)
alts = 110 * np.ones(n)
lla = np.array([lats, lons, alts]).T
# Map the satellite track to the imager's azimuth and elevation coordinates and
# image pixels. NOTE: the mapping is not along the magnetic field lines! You need
# to install IRBEM and then use asilib.lla2footprint() before
# lla2azel() is called.
sat_azel, sat_azel_pixels = asilib.lla2azel(asi_array_code, location_code, time_range[0], lla)
# Initiate the movie generator function. Any errors with the data will be raised here.
movie_generator = asilib.animate_fisheye_generator(
asi_array_code, location_code, time_range, azel_contours=True, overwrite=True, ax=ax[0]
)
# Use the generator to get the images and time stamps to estimate mean the ASI
# brightness along the satellite path and in a (20x20 km) box.
image_data = movie_generator.send('data')
# Calculate what pixels are in a box_km around the satellite, and convolve it
# with the images to pick out the ASI intensity in that box.
area_box_mask = asilib.equal_area(
asi_array_code, location_code, time_range[0], lla, box_km=(20, 20)
)
asi_brightness = np.nanmean(image_data.images * area_box_mask, axis=(1, 2))
area_box_mask[np.isnan(area_box_mask)] = 0 # To play nice with plt.contour()
for i, (time, image, _, im) in enumerate(movie_generator):
# Note that because we are drawing different data in each frame (a unique ASI
# image in ax[0] and the ASI time series + a guide in ax[1], we need
# to redraw everything at every iteration.
ax[1].clear() # ax[0] cleared by asilib.animate_fisheye_generator()
# Plot the entire satellite track, its current location, and a 20x20 km box
# around its location.
ax[0].plot(sat_azel_pixels[:, 0], sat_azel_pixels[:, 1], 'red')
ax[0].scatter(sat_azel_pixels[i, 0], sat_azel_pixels[i, 1], c='red', marker='o', s=50)
ax[0].contour(area_box_mask[i, :, :], levels=[0.99], colors=['yellow'])
# Plot the time series of the mean ASI intensity along the satellite path
ax[1].plot(image_data.time, asi_brightness)
ax[1].axvline(time, c='k')
# Annotate the location_code and satellite info in the top-left corner.
location_code_str = (
f'{asi_array_code}/{location_code} '
f'LLA=({skymap_dict["SITE_MAP_LATITUDE"]:.2f}, '
f'{skymap_dict["SITE_MAP_LONGITUDE"]:.2f}, {skymap_dict["SITE_MAP_ALTITUDE"]:.2f})'
)
satellite_str = f'Satellite LLA=({lla[i, 0]:.2f}, {lla[i, 1]:.2f}, {lla[i, 2]:.2f})'
ax[0].text(
0,
1,
location_code_str + '\n' + satellite_str,
va='top',
transform=ax[0].transAxes,
color='red',
)
ax[1].set(xlabel='Time', ylabel='Mean ASI intensity [counts]')
print(f'Movie saved in {asilib.config["ASI_DATA_DIR"] / "animations"}')