def test_gini_dataset(filename, bounds, data_var, proj_attrs): """Test the dataset interface for GINI.""" f = GiniFile(get_test_data(filename)) ds = f.to_dataset() # Check our calculated x and y arrays x0, x1, y0, y1 = bounds x = ds.variables['x'] assert_almost_equal(x[0], x0, 4) assert_almost_equal(x[-1], x1, 4) # Because the actual data raster has the top row first, the maximum y value is y[0], # while the minimum y value is y[-1] y = ds.variables['y'] assert_almost_equal(y[-1], y0, 4) assert_almost_equal(y[0], y1, 4) xmin, xmax, ymin, ymax = ds.img_extent assert_almost_equal(xmin, x0, 4) assert_almost_equal(xmax, x1, 4) assert_almost_equal(ymin, y0, 4) assert_almost_equal(ymax, y1, 4) # Check the projection metadata proj_name = ds.variables[data_var].grid_mapping proj_var = ds.variables[proj_name] for attr, val in proj_attrs.items(): assert getattr(proj_var, attr) == val, 'Values mismatch for ' + attr # Check the lower left lon/lat corner assert_almost_equal(ds.variables['lon'][-1, 0], f.prod_desc.lo1, 4) assert_almost_equal(ds.variables['lat'][-1, 0], f.prod_desc.la1, 4)
def test_gini_mercator_upper_corner(): """Test that the upper corner of the Mercator coordinates is correct.""" f = GiniFile(get_test_data('HI-REGIONAL_4km_3.9_20160616_1715.gini')) ds = f.to_dataset() lat = ds.variables['lat'] lon = ds.variables['lon'] # 2nd corner lat/lon are at the "upper right" corner of the pixel, so need to add one # more grid point assert_almost_equal(lon[0, -1] + (lon[0, -1] - lon[0, -2]), f.proj_info.lo2, 4) assert_almost_equal(lat[0, -1] + (lat[0, -1] - lat[1, -1]), f.proj_info.la2, 4)
def test_gini_mercator_upper_corner(): """Test that the upper corner of the Mercator coordinates is correct.""" f = GiniFile(get_test_data('HI-REGIONAL_4km_3.9_20160616_1715.gini')) ds = f.to_dataset() lat = ds.variables['lat'] lon = ds.variables['lon'] # 2nd corner lat/lon are at the "upper right" corner of the pixel, so need to add one # more grid point assert_almost_equal(lon[-1, -1] + (lon[-1, -1] - lon[-1, -2]), f.proj_info.lo2, 4) assert_almost_equal(lat[-1, -1] + (lat[-1, -1] - lat[-2, -1]), f.proj_info.la2, 4)
def test_raw_gini(filename, pdb, pdb2, proj_info): """Test raw GINI parsing.""" f = GiniFile(get_test_data(filename)) assert f.prod_desc == pdb assert f.prod_desc2 == pdb2 assert f.proj_info == proj_info assert f.data.shape == (pdb.num_records, pdb.record_len)
def test_gini_xarray(filename, bounds, data_var, proj_attrs, image, dt): """Test that GINIFile can be passed to XArray as a datastore.""" f = GiniFile(get_test_data(filename)) ds = xr.open_dataset(f) # Check our calculated x and y arrays x0, x1, y0, y1 = bounds x = ds.variables['x'] assert_almost_equal(x[0], x0, 4) assert_almost_equal(x[-1], x1, 4) # Because the actual data raster has the top row first, the maximum y value is y[0], # while the minimum y value is y[-1] y = ds.variables['y'] assert_almost_equal(y[-1], y0, 4) assert_almost_equal(y[0], y1, 4) # Check the projection metadata proj_name = ds.variables[data_var].attrs['grid_mapping'] proj_var = ds.variables[proj_name] for attr, val in proj_attrs.items(): assert proj_var.attrs[attr] == val, 'Values mismatch for ' + attr # Check the lower left lon/lat corner assert_almost_equal(ds.variables['lon'][-1, 0], f.prod_desc.lo1, 4) assert_almost_equal(ds.variables['lat'][-1, 0], f.prod_desc.la1, 4) # Check a pixel of the image to make sure we're decoding correctly x_ind, y_ind, val = image assert val == ds.variables[data_var][x_ind, y_ind] # Check time decoding assert np.asarray(dt, dtype='datetime64[ms]') == ds.variables['time']
def get_closest_satellite_vis(time): """ Get the super national 8 km visible satellite image. The image closest to the requested time will be returned. time : datetime object of image """ catalog = TDSCatalog( 'http://thredds.ucar.edu/thredds/catalog/satellite/VIS/' 'SUPER-NATIONAL_8km/current/catalog.xml') # Figure out the closest image to the requested time in the catalog datasets = list(catalog.datasets) dt_stamps = [] for dataset in datasets: fmt = 'SUPER-NATIONAL_8km_VIS_%Y%m%d_%H%M.gini' dt_stamps.append(datetime.strptime(dataset, fmt)) closest_time = min(dt_stamps, key=lambda x: abs(x - time)) index = dt_stamps.index(closest_time) # Request that image and convert it to a netCDF like dataset satellite = list(catalog.datasets.values())[index] sat_data = GiniFile( urllib.request.urlopen(satellite.access_urls['HTTPServer'])) ds = sat_data.to_dataset() # Pull out the variables we need x = ds.variables['x'][:] y = ds.variables['y'][:] channel_data = ds.variables['Visible'] time_var = ds.variables['time'] proj_var = ds.variables[channel_data.grid_mapping] # Make a globe and projection for this dataset globe = ccrs.Globe(ellipse='sphere', semimajor_axis=proj_var.earth_radius, semiminor_axis=proj_var.earth_radius) proj = ccrs.Stereographic( central_longitude=proj_var.straight_vertical_longitude_from_pole, central_latitude=proj_var.latitude_of_projection_origin, true_scale_latitude=proj_var.standard_parallel, globe=globe) timestamp = netCDF4.num2date(time_var[:].squeeze(), time_var.units) return timestamp, globe, proj, x, y, channel_data
def test_gini_str(): """Test the str representation of GiniFile.""" f = GiniFile(get_test_data('WEST-CONUS_4km_WV_20151208_2200.gini')) truth = ('GiniFile: GOES-15 West CONUS WV (6.5/6.7 micron)\n' '\tTime: 2015-12-08 22:00:19\n\tSize: 1280x1100\n' '\tProjection: lambert_conformal\n' '\tLower Left Corner (Lon, Lat): (-133.4588, 12.19)\n\tResolution: 4km') assert str(f) == truth
def test_gini_pathlib(): """Test that GiniFile works with `pathlib.Path` instances.""" from pathlib import Path src = Path( get_test_data('WEST-CONUS_4km_WV_20151208_2200.gini', as_file_obj=False)) f = GiniFile(src) assert f.prod_desc.sector_id == 'West CONUS'
def test_unidata_composite(): """Test reading radar composites in GINI format made by Unidata.""" f = GiniFile(get_test_data('Level3_Composite_dhr_1km_20180309_2225.gini')) # Check the time stamp assert datetime(2018, 3, 9, 22, 25) == f.prod_desc.datetime # Check data value assert 66 == f.data[2160, 2130]
def get_closest_satellite_vis(time): """ Get the super national 8 km visible satellite image. The image closest to the requested time will be returned. time : datetime object of image """ catalog = TDSCatalog('http://thredds.ucar.edu/thredds/catalog/satellite/VIS/' 'SUPER-NATIONAL_8km/current/catalog.xml') # Figure out the closest image to the requested time in the catalog datasets = list(catalog.datasets) dt_stamps = [] for dataset in datasets: fmt = 'SUPER-NATIONAL_8km_VIS_%Y%m%d_%H%M.gini' dt_stamps.append(datetime.strptime(dataset, fmt)) closest_time = min(dt_stamps, key=lambda x: abs(x - time)) index = dt_stamps.index(closest_time) # Request that image and convert it to a netCDF like dataset satellite = list(catalog.datasets.values())[index] sat_data = GiniFile(urllib.request.urlopen(satellite.access_urls['HTTPServer'])) ds = sat_data.to_dataset() # Pull out the variables we need x = ds.variables['x'][:] y = ds.variables['y'][:] channel_data = ds.variables['Visible'] time_var = ds.variables['time'] proj_var = ds.variables[channel_data.grid_mapping] # Make a globe and projection for this dataset globe = ccrs.Globe(ellipse='sphere', semimajor_axis=proj_var.earth_radius, semiminor_axis=proj_var.earth_radius) proj = ccrs.Stereographic(central_longitude=proj_var.straight_vertical_longitude_from_pole, central_latitude=proj_var.latitude_of_projection_origin, true_scale_latitude=proj_var.standard_parallel, globe=globe) timestamp = netCDF4.num2date(time_var[:].squeeze(), time_var.units) return timestamp, globe, proj, x, y, channel_data
def test_gini_dataset(filename, bounds, data_var, proj_attrs, image, dt): """Test the dataset interface for GINI.""" f = GiniFile(get_test_data(filename)) with pytest.warns(MetpyDeprecationWarning): ds = f.to_dataset() # Check our calculated x and y arrays x0, x1, y0, y1 = bounds x = ds.variables['x'] assert_almost_equal(x[0], x0, 4) assert_almost_equal(x[-1], x1, 4) # Because the actual data raster has the top row first, the maximum y value is y[0], # while the minimum y value is y[-1] y = ds.variables['y'] assert_almost_equal(y[-1], y0, 4) assert_almost_equal(y[0], y1, 4) xmin, xmax, ymin, ymax = ds.img_extent assert_almost_equal(xmin, x0, 4) assert_almost_equal(xmax, x1, 4) assert_almost_equal(ymin, y0, 4) assert_almost_equal(ymax, y1, 4) # Check the projection metadata proj_name = ds.variables[data_var].grid_mapping proj_var = ds.variables[proj_name] for attr, val in proj_attrs.items(): assert getattr(proj_var, attr) == val, 'Values mismatch for ' + attr # Check the lower left lon/lat corner assert_almost_equal(ds.variables['lon'][-1, 0], f.prod_desc.lo1, 4) assert_almost_equal(ds.variables['lat'][-1, 0], f.prod_desc.la1, 4) # Check a pixel of the image to make sure we're decoding correctly x_ind, y_ind, val = image assert val == ds.variables[data_var][x_ind, y_ind] # Check that the decoded date time will work properly assert f.prod_desc.datetime == dt
def test_gini_dataset(filename, bounds, data_var, proj_attrs): """Test the dataset interface for GINI.""" f = GiniFile(get_test_data(filename)) ds = f.to_dataset() # Check our calculated x and y arrays x0, x1, y0, y1 = bounds x = ds.variables['x'] assert_almost_equal(x[0], x0, 4) assert_almost_equal(x[-1], x1, 4) y = ds.variables['y'] assert_almost_equal(y[0], y0, 4) assert_almost_equal(y[-1], y1, 4) # Check the projection metadata proj_name = ds.variables[data_var].grid_mapping proj_var = ds.variables[proj_name] for attr, val in proj_attrs.items(): assert getattr(proj_var, attr) == val, 'Values mismatch for ' + attr # Check the lon/lat corner assert_almost_equal(ds.variables['lon'][0, 0], f.prod_desc.lo1, 4) assert_almost_equal(ds.variables['lat'][0, 0], f.prod_desc.la1, 4)
def test_global(): """Test that we can set global extent.""" data = xr.open_dataset(GiniFile(get_test_data('NHEM-MULTICOMP_1km_IR_20151208_2100.gini'))) img = ImagePlot() img.data = data img.field = 'IR' panel = MapPanel() panel.area = 'global' panel.plots = [img] pc = PanelContainer() pc.panel = panel pc.draw() return pc.figure
def test_declarative_image(): """Test making an image plot.""" data = xr.open_dataset(GiniFile(get_test_data('NHEM-MULTICOMP_1km_IR_20151208_2100.gini'))) img = ImagePlot() img.data = data.metpy.parse_cf('IR') img.colormap = 'Greys_r' panel = MapPanel() panel.title = 'Test' panel.plots = [img] pc = PanelContainer() pc.panel = panel pc.draw() assert panel.ax.get_title() == 'Test' return pc.figure
from metpy.plots.ctables import registry from metpy.units import units from netCDF4 import num2date import scipy.ndimage as ndimage from siphon.catalog import TDSCatalog import xarray as xr ############################################## # Get satellite data and set projection based on that data. # Scan the catalog and download the data satcat = TDSCatalog('http://thredds.ucar.edu/thredds/catalog/satellite/' 'WV/WEST-CONUS_4km/current/catalog.xml') dataset = satcat.datasets[0] f = GiniFile(dataset.remote_open()) gini_ds = xr.open_dataset(f) # Pull parts out of the data file dat = gini_ds.metpy.parse_cf('WV') data_var = gini_ds.variables['WV'] x = gini_ds.variables['x'][:] y = gini_ds.variables['y'][:] timestamp = f.prod_desc.datetime ############################################## # Use Siphon to obtain data that is close to the time of the satellite file gfscat = TDSCatalog('http://thredds.ucar.edu/thredds/catalog/grib/' 'NCEP/GFS/Global_0p5deg/catalog.xml') dataset = gfscat.datasets['Best GFS Half Degree Forecast Time Series']
Use MetPy's support for GINI files to read in a water vapor satellite image and plot the data using CartoPy. """ import cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.pyplot as plt from metpy.cbook import get_test_data from metpy.io import GiniFile from metpy.plots import add_metpy_logo, add_timestamp, ctables ########################################### # Open the GINI file from the test data f = GiniFile(get_test_data('WEST-CONUS_4km_WV_20151208_2200.gini')) print(f) ########################################### # Get a Dataset view of the data (essentially a NetCDF-like interface to the # underlying data). Pull out the data, (x, y) coordinates, and the projection # information. ds = f.to_dataset() x = ds.variables['x'][:] y = ds.variables['y'][:] dat = ds.variables['WV'] proj_var = ds.variables[dat.grid_mapping] print(proj_var) ###########################################
import matplotlib.pyplot as plt from metpy.io import GiniFile from metpy.plots.ctables import registry from metpy.units import units from netCDF4 import num2date import scipy.ndimage as ndimage from siphon.catalog import TDSCatalog ############################################## # Get satellite data and set projection based on that data. # Scan the catalog and download the data satcat = TDSCatalog('http://thredds.ucar.edu/thredds/catalog/satellite/' 'WV/WEST-CONUS_4km/current/catalog.xml') dataset = satcat.datasets[0] gini_ds = GiniFile(dataset.remote_open()).to_dataset() # Pull parts out of the data file data_var = gini_ds.variables['WV'] x = gini_ds.variables['x'][:] y = gini_ds.variables['y'][:] time_var = gini_ds.variables['time'] proj_var = gini_ds.variables[data_var.grid_mapping] timestamp = num2date(time_var[:].squeeze(), time_var.units) # Set up the projection based on satellite projection globe = ccrs.Globe(ellipse='sphere', semimajor_axis=proj_var.earth_radius, semiminor_axis=proj_var.earth_radius) proj = ccrs.LambertConformal(
def test_gini_bad_size(): """Test reading a GINI file that reports a bad header size.""" f = GiniFile(get_test_data('NHEM-MULTICOMP_1km_IR_20151208_2100.gini')) pdb2 = f.prod_desc2 assert pdb2.pdb_size == 512 # Catching bad size
from metpy.io import GiniFile from metpy.plots.ctables import registry from metpy.units import units from netCDF4 import num2date import scipy.ndimage as ndimage from siphon.catalog import TDSCatalog from siphon.ncss import NCSS ############################################## # Get satellite data and set projection based on that data. # Scan the catalog and download the data satcat = TDSCatalog('http://thredds.ucar.edu/thredds/catalog/satellite/' 'WV/EAST-CONUS_4km/current/catalog.xml') dataset = satcat.datasets[list(satcat.datasets)[0]] gini_ds = GiniFile(urlopen(dataset.access_urls['HTTPServer'])).to_dataset() # Pull parts out of the data file data_var = gini_ds.variables['WV'] x = gini_ds.variables['x'][:] y = gini_ds.variables['y'][:] time_var = gini_ds.variables['time'] proj_var = gini_ds.variables[data_var.grid_mapping] # Set up the projection based on satellite projection globe = ccrs.Globe(ellipse='sphere', semimajor_axis=proj_var.earth_radius, semiminor_axis=proj_var.earth_radius) proj = ccrs.LambertConformal( central_longitude=proj_var.longitude_of_central_meridian,
def test_percent_normal(): """Test reading PCT products properly.""" f = GiniFile(get_test_data('PR-NATIONAL_1km_PCT_20200320_0446.gini')) assert f.prod_desc.channel == 'Percent Normal TPW'
======================== Use MetPy's support for GINI files to read in a water vapor satellite image and plot the data using CartoPy. """ import cartopy.crs as ccrs import matplotlib.pyplot as plt from metpy.cbook import get_test_data from metpy.io import GiniFile from metpy.plots import ctables ########################################### # Open the GINI file from the test data f = GiniFile(get_test_data('WEST-CONUS_4km_WV_20151208_2200.gini')) print(f) ########################################### # Get a Dataset view of the data (essentially a NetCDF-like interface to the # underlying data). Pull out the data, (x, y) coordinates, and the projection # information. ds = f.to_dataset() x = ds.variables['x'][:] y = ds.variables['y'][:] dat = ds.variables['WV'] proj_var = ds.variables[dat.grid_mapping] print(proj_var) ###########################################
# SPDX-License-Identifier: BSD-3-Clause """ Simple Plotting =============== Demonstrate the use of MetPy's simplified plotting interface. Plots a sample satellite image file. """ import xarray as xr from metpy.cbook import get_test_data from metpy.io import GiniFile from metpy.plots import ImagePlot, MapPanel, PanelContainer data = xr.open_dataset( GiniFile(get_test_data('NHEM-MULTICOMP_1km_IR_20151208_2100.gini'))) img = ImagePlot() img.data = data img.field = 'IR' img.colormap = 'Greys_r' panel = MapPanel() panel.plots = [img] pc = PanelContainer() pc.panels = [panel] pc.show()