Satellite Imagery
Notebook Python-AWIPS Tutorial Notebook
Objectives
Use python-awips to connect to an EDEX server
Investigate available satellite imagery
Define and filter request specifically for GOES mesoscale imagery
Access satellite data in gridded format
Create rendered images using Matplotlib
Table of Contents
1 Imports
The imports below are used throughout the notebook. Note the first import is coming directly from python-awips and allows us to connect to an EDEX server. The subsequent imports are for data manipulation and visualization.
from awips.dataaccess import DataAccessLayer
import cartopy.crs as ccrs
import cartopy.feature as cfeat
import matplotlib.pyplot as plt
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import datetime
2 EDEX Connection
First we establish a connection to Unidata’s public EDEX server. With that connection made, we can create a new data request object and set the data type to satellite.
# Create an EDEX data request
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest()
request.setDatatype("satellite")
3 Function: make_map()
In order to plot more than one image, it’s easiest to define common logic in a function. Here, a new function called make_map is defined. This function uses the matplotlib.pyplot package (plt) to create a figure and axis. The coastlines (continental boundaries) are added, along with lat/lon grids.
def make_map(bbox, projection=ccrs.PlateCarree()):
fig, ax = plt.subplots(figsize=(10,12),
subplot_kw=dict(projection=projection))
ax.set_extent(bbox)
ax.coastlines(resolution='50m')
gl = ax.gridlines(draw_labels=True)
gl.top_labels = gl.right_labels = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
return fig, ax
4 Investigate Available Data
To see what data are all available, let’s look at which optional identifiers satellite data uses.
# Get optional identifiers for satellite datatype
identifiers = set(DataAccessLayer.getOptionalIdentifiers(request))
print("Available Identifiers:")
for id in identifiers:
if id.lower() == 'datauri':
continue
print(" - " + id)
Available Identifiers:
- source
- physicalElement
- creatingEntity
- sectorID
4.1 Sources
# Show available sources
identifier = "source"
sources = DataAccessLayer.getIdentifierValues(request, identifier)
print(identifier + ":")
print(list(sources))
source:
['GTDO1', 'RAMMB', 'WCDAS', 'RBU', 'UCAR', 'NSOF', 'McIDAS']
4.2 Physical Elements
# Show available physicalElements
identifier = "physicalElement"
elements = DataAccessLayer.getIdentifierValues(request, identifier)
print(identifier + ":")
print(list(elements))
physicalElement:
['Imager 6.7-6.5 micron IR (WV)', 'CH-02-0.64um', 'VMP-151.30hPa', 'CTT', 'CH-07-3.90um', 'VTP-878.60hPa', 'VMP-706.60hPa', 'CH-12-9.61um', 'VMP-496.60hPa', 'SI', 'CH-06-2.25um', 'NTP', 'DVL', 'CL', 'VMP-71.50hPa', 'DustLow', 'VTP-931.50hPa', 'VTP-103.00hPa', 'LI', 'VMP-555.20hPa', 'Imager 12 micron IR', 'IceTemp', 'CF2', 'VMP-729.90hPa', 'VTP-407.50hPa', 'CAPE', 'HHC', 'VMP-1014.00hPa', 'VMP-535.20hPa', 'VTP-777.80hPa', 'VTP-535.20hPa', 'VTP-904.90hPa', 'CH-10-7.34um', 'VTP-1014.00hPa', 'ACTP', 'VTP-661.20hPa', 'IceAge3', 'VTP-9.51hPa', 'GLM_Flash_Extent_Density', 'GLM_Flash_Extent_Density_w5u1', 'CF3', 'VMP-852.80hPa', 'CSM', 'TT', 'IceAge8', 'VTP-706.60hPa', 'GLM_Minimum_Flash_Area_w5u1', 'SmokeMed', 'CH-09-6.95um', 'VMP-753.60hPa', 'VMP-878.60hPa', 'VTP-459.70hPa', 'DustMed', 'VMP-103.00hPa', 'CH-08-6.19um', 'VTP-151.30hPa', 'VTP-575.50hPa', 'VMP-407.50hPa', 'VMP-661.20hPa', 'VMP-777.80hPa', 'FDC Temp', 'DHR', 'IceMask', 'GLM_Total_Optical_Energy_w5u1_tile', 'CH-15-12.30um', 'VTP-29.12hPa', 'MVFR_Fog_Prob', 'CF5', 'VMP-359.00hPa', 'VMP-827.40hPa', 'VMP-986.10hPa', 'CTH', 'SSTF', 'VMP-201.00hPa', 'VMP-300.00hPa', 'FDC Power', 'VTP-852.80hPa', 'VMP-575.50hPa', 'CH-13-10.35um', 'Fog_Depth', 'TCF', 'CH-04-1.38um', 'DustHigh', 'VTP-683.70hPa', 'Imager Visible', 'GLM_Minimum_Flash_Area', 'VTP-729.90hPa', 'IFR_Fog_Prob', 'VMP-958.60hPa', 'VTP-753.60hPa', 'VMP-931.50hPa', 'VTP-555.20hPa', 'CH-05-1.61um', 'VTP-201.00hPa', 'RRQPE', 'LST', 'AOD', 'FSC', 'COD', 'VTP-827.40hPa', 'IceThickness', 'N1P', 'LIFR_Fog_Prob', 'VMP-596.30hPa', 'VTP-496.60hPa', 'TPW', 'VMP-904.90hPa', 'VMP-683.70hPa', 'VTP-802.40hPa', 'VTP-958.60hPa', 'VTP-596.30hPa', 'Fire_Mask', 'FDC Area', 'CH-11-8.50um', 'VMP-51.53hPa', 'EET', 'VTP-247.40hPa', 'VMP-802.40hPa', 'CTP', 'CH-01-0.47um', 'CH-16-13.30um', 'VMP-617.50hPa', 'VTP-51.53hPa', 'SST', 'VTP-617.50hPa', 'CF1', 'GLM_Total_Optical_Energy_tile', 'VMP-9.51hPa', 'VMP-247.40hPa', 'CF4', 'Imager 3.5-4.0 micron IR (Fog)', 'IceConc', 'SmokeHigh', 'KI', 'VTP-300.00hPa', 'VTP-20.92hPa', 'VTP-359.00hPa', 'Imager 11 micron IR', 'SmokeLow', 'VMP-20.92hPa', 'VMP-29.12hPa', 'VMP-459.70hPa', 'CH-03-0.87um', 'VTP-71.50hPa', 'CH-14-11.20um', 'VTP-986.10hPa']
4.3 Creating Entities
# Show available creatingEntities
identifier = "creatingEntity"
creatingEntities = DataAccessLayer.getIdentifierValues(request, identifier)
print(identifier + ":")
print(list(creatingEntities))
creatingEntity:
['GOES-18', 'GEOCOLR', 'GOES-16', 'NEXRCOMP', 'UNIWISC', 'CLDSNOW', 'DBRDUST']
4.4 Sectors
# Show available sectorIDs
identifier = "sectorID"
sectorIDs = DataAccessLayer.getIdentifierValues(request, identifier)
print(identifier + ":")
print(list(sectorIDs))
sectorID:
['EMESO-2', 'WCONUS', 'AKREGI', 'WMESO-1', 'WMESO-2', 'WFD', 'NEXRCOMP', 'ECONUS', 'AREA3100', 'Antarctic', 'PRREGI', 'EMESO-1', 'AREA3101', 'AREA0700', 'Arctic', 'AREA0600', 'EFD']
4.5 All Products
# Construct a full satellite product tree
for entity in creatingEntities:
print(entity)
request = DataAccessLayer.newDataRequest("satellite")
request.addIdentifier("creatingEntity", entity)
availableSectors = DataAccessLayer.getAvailableLocationNames(request)
availableSectors.sort()
for sector in availableSectors:
print(" - " + sector)
request.setLocationNames(sector)
availableProducts = DataAccessLayer.getAvailableParameters(request)
availableProducts.sort()
for product in availableProducts:
print(" - " + product)
GOES-18
- AKREGI
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- WCONUS
- ACTP
- AOD
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- CSM
- CTH
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- Fire_Mask
- Fog_Depth
- IFR_Fog_Prob
- KI
- LI
- LIFR_Fog_Prob
- LST
- MVFR_Fog_Prob
- SI
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
- VMP-1014.00hPa
- VMP-103.00hPa
- VMP-151.30hPa
- VMP-20.92hPa
- VMP-201.00hPa
- VMP-247.40hPa
- VMP-29.12hPa
- VMP-300.00hPa
- VMP-359.00hPa
- VMP-407.50hPa
- VMP-459.70hPa
- VMP-496.60hPa
- VMP-51.53hPa
- VMP-535.20hPa
- VMP-555.20hPa
- VMP-575.50hPa
- VMP-596.30hPa
- VMP-617.50hPa
- VMP-661.20hPa
- VMP-683.70hPa
- VMP-706.60hPa
- VMP-71.50hPa
- VMP-729.90hPa
- VMP-753.60hPa
- VMP-777.80hPa
- VMP-802.40hPa
- VMP-827.40hPa
- VMP-852.80hPa
- VMP-878.60hPa
- VMP-9.51hPa
- VMP-904.90hPa
- VMP-931.50hPa
- VMP-958.60hPa
- VMP-986.10hPa
- VTP-1014.00hPa
- VTP-103.00hPa
- VTP-151.30hPa
- VTP-20.92hPa
- VTP-201.00hPa
- VTP-247.40hPa
- VTP-29.12hPa
- VTP-300.00hPa
- VTP-359.00hPa
- VTP-407.50hPa
- VTP-459.70hPa
- VTP-496.60hPa
- VTP-51.53hPa
- VTP-535.20hPa
- VTP-555.20hPa
- VTP-575.50hPa
- VTP-596.30hPa
- VTP-617.50hPa
- VTP-661.20hPa
- VTP-683.70hPa
- VTP-706.60hPa
- VTP-71.50hPa
- VTP-729.90hPa
- VTP-753.60hPa
- VTP-777.80hPa
- VTP-802.40hPa
- VTP-827.40hPa
- VTP-852.80hPa
- VTP-878.60hPa
- VTP-9.51hPa
- VTP-904.90hPa
- VTP-931.50hPa
- VTP-958.60hPa
- VTP-986.10hPa
- WFD
- ACTP
- AOD
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- CSM
- CTH
- CTT
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- FSC
- Fire_Mask
- GLM_Flash_Extent_Density
- GLM_Flash_Extent_Density_w5u1
- GLM_Minimum_Flash_Area
- GLM_Minimum_Flash_Area_w5u1
- GLM_Total_Optical_Energy_tile
- GLM_Total_Optical_Energy_w5u1_tile
- IceAge3
- IceAge8
- IceConc
- IceMask
- IceTemp
- IceThickness
- KI
- LI
- LST
- RRQPE
- SI
- SST
- SSTF
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
- WMESO-1
- ACTP
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- CSM
- CTH
- CTT
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- Fire_Mask
- KI
- LI
- LST
- SI
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
- WMESO-2
- ACTP
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- CSM
- CTH
- CTT
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- Fire_Mask
- KI
- LI
- LST
- SI
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
GEOCOLR
- ECONUS
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- WCONUS
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
GOES-16
- ECONUS
- ACTP
- AOD
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- COD
- CSM
- CTH
- CTP
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- Fire_Mask
- Fog_Depth
- IFR_Fog_Prob
- KI
- LI
- LIFR_Fog_Prob
- LST
- MVFR_Fog_Prob
- SI
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
- VMP-1014.00hPa
- VMP-103.00hPa
- VMP-151.30hPa
- VMP-20.92hPa
- VMP-201.00hPa
- VMP-247.40hPa
- VMP-29.12hPa
- VMP-300.00hPa
- VMP-359.00hPa
- VMP-407.50hPa
- VMP-459.70hPa
- VMP-496.60hPa
- VMP-51.53hPa
- VMP-535.20hPa
- VMP-555.20hPa
- VMP-575.50hPa
- VMP-596.30hPa
- VMP-617.50hPa
- VMP-661.20hPa
- VMP-683.70hPa
- VMP-706.60hPa
- VMP-71.50hPa
- VMP-729.90hPa
- VMP-753.60hPa
- VMP-777.80hPa
- VMP-802.40hPa
- VMP-827.40hPa
- VMP-852.80hPa
- VMP-878.60hPa
- VMP-9.51hPa
- VMP-904.90hPa
- VMP-931.50hPa
- VMP-958.60hPa
- VMP-986.10hPa
- VTP-1014.00hPa
- VTP-103.00hPa
- VTP-151.30hPa
- VTP-20.92hPa
- VTP-201.00hPa
- VTP-247.40hPa
- VTP-29.12hPa
- VTP-300.00hPa
- VTP-359.00hPa
- VTP-407.50hPa
- VTP-459.70hPa
- VTP-496.60hPa
- VTP-51.53hPa
- VTP-535.20hPa
- VTP-555.20hPa
- VTP-575.50hPa
- VTP-596.30hPa
- VTP-617.50hPa
- VTP-661.20hPa
- VTP-683.70hPa
- VTP-706.60hPa
- VTP-71.50hPa
- VTP-729.90hPa
- VTP-753.60hPa
- VTP-777.80hPa
- VTP-802.40hPa
- VTP-827.40hPa
- VTP-852.80hPa
- VTP-878.60hPa
- VTP-9.51hPa
- VTP-904.90hPa
- VTP-931.50hPa
- VTP-958.60hPa
- VTP-986.10hPa
- EFD
- ACTP
- AOD
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- COD
- CSM
- CTH
- CTP
- CTT
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- FSC
- Fire_Mask
- GLM_Flash_Extent_Density
- GLM_Flash_Extent_Density_w5u1
- GLM_Minimum_Flash_Area
- GLM_Minimum_Flash_Area_w5u1
- GLM_Total_Optical_Energy_tile
- GLM_Total_Optical_Energy_w5u1_tile
- IceAge3
- IceAge8
- IceConc
- IceMask
- IceTemp
- IceThickness
- KI
- LI
- LST
- RRQPE
- SI
- SST
- SSTF
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
- EMESO-1
- ACTP
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- CSM
- CTH
- CTT
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- Fire_Mask
- KI
- LI
- LST
- SI
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
- EMESO-2
- ACTP
- CAPE
- CF1
- CF2
- CF3
- CF4
- CF5
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-11-8.50um
- CH-12-9.61um
- CH-13-10.35um
- CH-14-11.20um
- CH-15-12.30um
- CH-16-13.30um
- CL
- CSM
- CTH
- CTT
- DustHigh
- DustLow
- DustMed
- FDC Area
- FDC Power
- FDC Temp
- Fire_Mask
- KI
- LI
- LST
- SI
- SmokeHigh
- SmokeLow
- SmokeMed
- TCF
- TPW
- TT
- PRREGI
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- CH-04-1.38um
- CH-05-1.61um
- CH-06-2.25um
- CH-07-3.90um
- CH-08-6.19um
- CH-09-6.95um
- CH-10-7.34um
- CH-13-10.35um
- CH-15-12.30um
NEXRCOMP
- NEXRCOMP
- DHR
- DVL
- EET
- HHC
- N1P
- NTP
UNIWISC
- AREA0600
- Imager 6.7-6.5 micron IR (WV)
- AREA0700
- Imager 11 micron IR
- AREA3100
- Imager 11 micron IR
- AREA3101
- Imager 6.7-6.5 micron IR (WV)
- Antarctic
- Imager 11 micron IR
- Imager 12 micron IR
- Imager 3.5-4.0 micron IR (Fog)
- Imager 6.7-6.5 micron IR (WV)
- Imager Visible
- Arctic
- Imager 11 micron IR
- Imager 12 micron IR
- Imager 3.5-4.0 micron IR (Fog)
- Imager 6.7-6.5 micron IR (WV)
- Imager Visible
CLDSNOW
- ECONUS
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
- WCONUS
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
DBRDUST
- ECONUS
- CH-01-0.47um
- CH-02-0.64um
- CH-03-0.87um
Top
5 Render GOES East Mesoscale Sectors
Create specific requests defining the datatype, sector, and parameter. Use the data returned to create plots and print out useful information about the data (metadata).
# Define the sectors we want to plot -- here let's use GOES-East mesoscales
sectors = ["EMESO-1","EMESO-2"]
# For each sector render our plot
for i, sector in enumerate(sectors):
# Create a new request specfically for this data
request = DataAccessLayer.newDataRequest()
request.setDatatype("satellite")
request.setLocationNames(sector)
# Use Channel 13 as the data we want to render
request.setParameters("CH-13-10.35um")
# Filter results by time
utc = datetime.datetime.utcnow()
times = DataAccessLayer.getAvailableTimes(request)
hourdiff = utc - datetime.datetime.strptime(str(times[-1]),'%Y-%m-%d %H:%M:%S')
hours,days = hourdiff.seconds/3600,hourdiff.days
minute = str((hourdiff.seconds - (3600 * hours)) / 60)
offsetStr = ''
if hours > 0:
offsetStr += str(hours) + "hr "
offsetStr += str(minute) + "m ago"
if days > 1:
offsetStr = str(days) + " days ago"
response = DataAccessLayer.getGridData(request, [times[-1]])
grid = response[0]
data = grid.getRawData()
# Define the bounding box for the plot
lons,lats = grid.getLatLonCoords()
bbox = [lons.min(), lons.max(), lats.min(), lats.max()]
# Print out the time of the image we're using and where the data is
print("Latest image available: "+str(times[-1]) + " ("+offsetStr+")")
print("Image grid size: " + str(data.shape))
print("Image grid extent: " + str(list(bbox)))
# Create the new plots
fig, ax = make_map(bbox=bbox)
states = cfeat.NaturalEarthFeature(category='cultural',
name='admin_1_states_provinces_lines',
scale='50m', facecolor='none')
ax.add_feature(states, linestyle=':')
cs = ax.pcolormesh(lons, lats, data, cmap='coolwarm')
cbar = fig.colorbar(cs, shrink=0.6, orientation='horizontal')
# Set the colorbar label
cbar.set_label(sector + " " + grid.getParameter() + " " \
+ str(grid.getDataTime().getRefTime()))
Latest image available: 2024-01-30 21:20:28 (0.018333333333333333hr 0.0m ago)
Image grid size: (500, 500)
Image grid extent: [-81.83639, -68.16361, 32.285526, 45.709965]
Latest image available: 2024-01-30 21:20:55 (0.011666666666666667hr 0.0m ago)
Image grid size: (500, 500)
Image grid extent: [-95.20762, -80.19988, 30.912949, 44.27834]
6 See Also
6.2 Additional Documentation
python-awips
matplotlib