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 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_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 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 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_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
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)
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) ###########################################
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_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
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'
# 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()
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(