#!/usr/bin/env python
# -*- coding: utf-8 -*-
# DOI: 10.5281/zenodo.15102100
# Full license can be found in License.md
#
# DISTRIBUTION STATEMENT A: Approved for public release. Distribution is
# unlimited.
# -----------------------------------------------------------------------------
"""Satellite instrument support functions."""
import numpy as np
[docs]
def get_auroral_slice(time_data, glat_data, glon_data, int_data,
clean_mask=None, start_time=None, hemisphere=1,
min_colat=45):
"""Retrieve an auroral image slice that spans the desired lat range.
Parameters
----------
time_data : array-like
1D array of time indexes
glat_data : array-like
2D array of geographic latitudes
glon_data : array-like
2D array of geographic longitudes
int_data : array-like
2D array of intensity values
clean_mask : array-like or NoneType
None to create a mask of finite values or 2D mask array specifying
good values (default=None)
start_time : dt.datetime or NoneType
Start time to search from or None to start from beginning of
available data (default=None)
hemisphere : int
Hemisphere to consider, where 1 is North and -1 is South (default=1)
min_colat : int or float
Absolute value of the most equatorward latitude to include (default=45)
Returns
-------
intensity : array-like
Array with dimensions of time x sweep-locations containing the
rectified intensity at the auroral daytime pierce point
glat : array-like
Array with dimensions of time x sweep-locations containing the
geodetic latitude
glon : array-like
Array with dimensions of time x sweep-locations containing the
geographic longitude
sweep_times : array-like
Array with the starting and ending times of the auroral sweep. Gives
the start and end times searched if no sweep is found.
Raises
------
ValueError
If imager data does not have the same shape
"""
# Set the start time
if start_time is None:
start_time = time_data[0]
itime = 0
else:
start_time = np.datetime64(start_time)
time_data = np.asarray(time_data).astype(np.datetime64)
itime = int(abs(start_time - time_data).argmin())
if time_data[itime] < start_time:
itime += 1
# Create the data mask, if desired
if clean_mask is None:
clean_mask = np.isfinite(int_data)
# Ensure the data arrays are shaped as expected
if np.asarray(time_data).shape[0] != int_data.shape[0]:
raise ValueError('first dimension of intensity data differs from time')
if int_data.shape != glat_data.shape or int_data.shape != glon_data.shape:
raise ValueError('intensity and location input shapes differ')
if clean_mask.shape != int_data.shape:
raise ValueError('clean mask shape differs from intensity data')
# Find the start of an auroral sweep
while itime < len(time_data):
if (glat_data[itime] * hemisphere >= min_colat).any():
if clean_mask[itime].any():
# If there is no clean data at this time, keep looking
break
# Cycle to the next time
itime += 1
if itime < len(time_data):
# Prepare the output
time_inds = list()
sweep_times = list()
# Found an auroral sweep in the correct hemisphere
while itime < len(time_data) and np.any(
glat_data[itime] * hemisphere >= min_colat):
if clean_mask[itime].any():
time_inds.append(itime)
if len(sweep_times) < 2:
sweep_times.append(time_data[itime])
else:
sweep_times[-1] = time_data[itime]
# Cycle the time index
itime += 1
# If the sweep ended without capturing sufficient data, set the stop
# time
if len(sweep_times) < 2:
if itime >= len(time_data):
itime = -1
sweep_times.append(time_data[itime])
# The sweep has ended, select the desired time indices
intensity = np.asarray(int_data[time_inds])
glat = np.asarray(glat_data[time_inds])
glon = np.asarray(glon_data[time_inds])
sweep_times = np.asarray(sweep_times)
else:
intensity = np.asarray([])
glat = np.asarray([])
glon = np.asarray([])
sweep_times = np.asarray([start_time, time_data[-1]])
return intensity, glat, glon, sweep_times