This is the core processing library used by Here GOES Radiotelescope (2020), a sculptural ground station for the GRB downlink of the NOAA weather satellite GOES-16. The library renders basic ABI and SUVI imagery from netCDF, and offers some useful functions for navigating and projecting ABI data. Some additional convenience functions for working with 2D NumPy arrays are provided in util. To optimize for the real-time processing needs of Here GOES Radiotelescope, array functions are accelerated using Numba with parallelism controlled by environmental variables.
Clone this repository and install the Conda environment. For Intel machines, use heregoes-env-intel.yml which uses MKL for acceleration. For other architectures, including ARM64 (e.g. Raspberry Pi 5), use heregoes-env-other.yml which installs with OpenBLAS.
conda env create -f heregoes-env-intel.yml
conda activate heregoes-env
Optional environmental variables:
HEREGOES_ENV_PARALLEL
: Defaults toFalse
HEREGOES_ENV_NUM_CPUS
: Number of CPUs to use ifHEREGOES_ENV_PARALLEL
isTrue
. Defaults to the number of CPUs reported by the OSHEREGOES_ENV_IREMIS_DIR
: Directory path of the UW CIMSS IREMIS dataset which can be downloaded here
The load
function in the heregoes library takes an ABI or SUVI netCDF file and returns either ABIObject
or SUVIObject
extensions of the NCInterface
to browse and interact with the netCDF contents. It mimicks the structure and behavior of a netCDF4 Dataset
object, except small variables are all stored in memory and larger variables are lazy-loaded from disk when accessed with an index.
With an ABI L1b radiance netCDF file abi_nc
, print netCDF data for the Rad variable:
from heregoes import load
abi_data = load(abi_nc)
print(abi_data['Rad'])
Which returns:
<class 'heregoes.ncinterface._NCVar'>
int16 Rad(y, x)
var_name: Rad
long_name: ABI L1b Radiances
standard_name: toa_outgoing_radiance_per_unit_wavelength
sensor_band_bit_depth: 12
valid_range: [ 0 4094]
scale_factor: 0.15859237
add_offset: -20.289911
units: W m-2 sr-1 um-1
resolution: y: 0.000014 rad x: 0.000014 rad
coordinates: band_id band_wavelength t y x
grid_mapping: goes_imager_projection
cell_methods: t: point area: point
ancillary_variables: DQF
ndim: 2
shape: (6000, 10000)
size: 60000000
dtype: int16
dimensions: (<class 'heregoes.ncinterface._NCDim'>: name = 'y', size = 6000, <class 'heregoes.ncinterface._NCDim'>: name = 'x', size = 10000)
With an L1b SUVI netCDF file suvi_nc
, view the exposure time in seconds:
from heregoes import load
suvi_data = load(suvi_nc)
print(suvi_data["CMD_EXP"][...])
Which returns:
[1.]
The heregoes library renders standard imagery for the GOES-R ABI and SUVI instruments following available literature wherever possible. To reduce memory utilization, subsets of ABI images can be processed by specifying either an array index or continuous slice with the index
argument, or with a latitude and longitude bounding box: lat_bounds=[ul_lat, lr_lat]
and lon_bounds=[ul_lon, lr_lon]
.
SUVI L1b netCDF files with 1-second exposure times can be rendered into images:
from heregoes import image
suvi_image = image.SUVIImage(suvi_nc)
suvi_image.save('suvi.jpg')
With an ABI L1b radiance netCDF file abi_nc
, render the L2 CMI product:
from heregoes import image
abi_image = image.ABIImage(abi_nc, gamma=0.75)
abi_image.save('abi.jpg')
With ABI L1b radiance files for the 0.64 μm (red_nc
), 0.86 μm (green_nc
), and 0.47 μm (blue_nc
) components:
from heregoes import image
abi_rgb = image.ABINaturalRGB(red_nc, green_nc, blue_nc, gamma=0.75)
abi_rgb.save('rgb.jpg')
With the abi_rgb
object from the previous step:
from heregoes import projection
abi_projection = projection.ABIProjection(abi_rgb.abi_data)
abi_projection.resample2cog(abi_rgb.bv, 'rgb.tiff')
Navigation routines for ABI return useful geometry on the ABI Fixed Grid: pixel latitude and longitude, pixel area, and look angles for Sun and satellite.
With an ABI L1b radiance netCDF file abi_nc
:
from heregoes import load, navigation
abi_data = load(abi_nc)
abi_navigation = navigation.ABINavigation(abi_data)
abi_navigation.lat_deg #latitude array
abi_navigation.lon_deg #longitude array
With the abi_navigation
object from the previous step:
abi_navigation.area_m #area of each pixel in square meters
With the abi_navigation
object from the previous step:
abi_navigation.sun_za #solar zenith angle
abi_navigation.sun_az #solar azimuth in North-clockwise convention
abi_navigation.sat_za #satellite zenith angle
abi_navigation.sat_az #satellite azimuth in North-clockwise convention
With an ABI L1b radiance netCDF file abi_nc
:
from heregoes import load, navigation
abi_data = load(abi_nc)
abi_navigation = navigation.ABINavigation(abi_data, lat_bounds=[44.731495, 44.602596], lon_bounds=[-93.01798, -92.85648])
abi_navigation.index #nearest (y, x) index or slice of the ABI image at provided latitude and longitude bounds
The heregoes library can project georeferenced datasets from WGS84 to the ABI Fixed Grid and vice versa.
With an ABI L1b radiance netCDF file abi_nc
:
import cv2
from heregoes import ancillary, load
abi_data = load(abi_nc)
water = ancillary.WaterMask(abi_data, rivers=True)
cv2.imwrite('water.jpg', water.data['water_mask'] * 255)
With an ABI L1b radiance netCDF file for 3.9 μm c07_nc
:
import cv2
from heregoes import ancillary, load, util
c07_data = load(c07_nc)
iremis = ancillary.IREMIS(c07_data)
cv2.imwrite('iremis.jpg', util.minmax(iremis.data['c07_land_emissivity']) * 255)