1
|
|
|
# Copyright (c) 2008-2015 MetPy Developers. |
2
|
|
|
# Distributed under the terms of the BSD 3-Clause License. |
3
|
|
|
# SPDX-License-Identifier: BSD-3-Clause |
4
|
|
|
|
5
|
|
|
import logging |
6
|
|
|
from datetime import datetime |
7
|
|
|
|
8
|
|
|
from numpy.testing import assert_almost_equal |
9
|
|
|
import pytest |
10
|
|
|
|
11
|
|
|
from metpy.io.gini import GiniFile, GiniProjection |
12
|
|
|
from metpy.cbook import get_test_data |
13
|
|
|
|
14
|
|
|
log = logging.getLogger('metpy.io.gini') |
15
|
|
|
log.setLevel(logging.ERROR) |
16
|
|
|
|
17
|
|
|
# Reference contents of the named tuples from each file |
18
|
|
|
make_pdb = GiniFile.prod_desc_fmt.make_tuple |
19
|
|
|
make_pdb2 = GiniFile.prod_desc2_fmt.make_tuple |
20
|
|
|
raw_gini_info = [('WEST-CONUS_4km_WV_20151208_2200.gini', |
21
|
|
|
make_pdb(source=1, creating_entity='GOES-15', sector_id='West CONUS', |
22
|
|
|
channel='WV (6.5/6.7 micron)', num_records=1280, record_len=1100, |
23
|
|
|
datetime=datetime(2015, 12, 8, 22, 0, 19), |
24
|
|
|
projection=GiniProjection.lambert_conformal, nx=1100, ny=1280, |
25
|
|
|
la1=12.19, lo1=-133.4588), |
26
|
|
|
make_pdb2(scanning_mode=[False, False, False], lat_in=25.0, resolution=4, |
27
|
|
|
compression=0, version=1, pdb_size=512, nav_cal=0), |
28
|
|
|
GiniFile.lc_ps_fmt.make_tuple(reserved=0, lov=-95.0, dx=4.0635, dy=4.0635, |
29
|
|
|
proj_center=0)), |
30
|
|
|
('AK-REGIONAL_8km_3.9_20160408_1445.gini', |
31
|
|
|
make_pdb(source=1, creating_entity='GOES-15', sector_id='Alaska Regional', |
32
|
|
|
channel='IR (3.9 micron)', num_records=408, record_len=576, |
33
|
|
|
datetime=datetime(2016, 4, 8, 14, 45, 20), |
34
|
|
|
projection=GiniProjection.polar_stereographic, nx=576, ny=408, |
35
|
|
|
la1=42.0846, lo1=-175.641), |
36
|
|
|
make_pdb2(scanning_mode=[False, False, False], lat_in=0.0, resolution=8, |
37
|
|
|
compression=0, version=1, pdb_size=512, nav_cal=0), |
38
|
|
|
GiniFile.lc_ps_fmt.make_tuple(reserved=0, lov=210.0, dx=7.9375, dy=7.9375, |
39
|
|
|
proj_center=0)), |
40
|
|
|
('HI-REGIONAL_4km_3.9_20160616_1715.gini', |
41
|
|
|
make_pdb(source=1, creating_entity='GOES-15', sector_id='Hawaii Regional', |
42
|
|
|
channel='IR (3.9 micron)', num_records=520, record_len=560, |
43
|
|
|
datetime=datetime(2016, 6, 16, 17, 15, 18), |
44
|
|
|
projection=GiniProjection.mercator, nx=560, ny=520, |
45
|
|
|
la1=9.343, lo1=-167.315), |
46
|
|
|
make_pdb2(scanning_mode=[False, False, False], lat_in=20.0, resolution=4, |
47
|
|
|
compression=0, version=1, pdb_size=512, nav_cal=0), |
48
|
|
|
GiniFile.mercator_fmt.make_tuple(resolution=0, la2=28.0922, lo2=-145.878, |
49
|
|
|
di=0, dj=0)) |
50
|
|
|
] |
51
|
|
|
|
52
|
|
|
|
53
|
|
|
@pytest.mark.parametrize('filename,pdb,pdb2,proj_info', raw_gini_info, |
54
|
|
|
ids=['LCC', 'Stereographic', 'Mercator']) |
55
|
|
|
def test_raw_gini(filename, pdb, pdb2, proj_info): |
56
|
|
|
'Test of raw GINI parsing' |
57
|
|
|
f = GiniFile(get_test_data(filename)) |
58
|
|
|
assert f.prod_desc == pdb |
59
|
|
|
assert f.prod_desc2 == pdb2 |
60
|
|
|
assert f.proj_info == proj_info |
61
|
|
|
assert f.data.shape == (pdb.num_records, pdb.record_len) |
62
|
|
|
|
63
|
|
|
|
64
|
|
|
def test_gini_bad_size(): |
65
|
|
|
'Test reading a GINI file that reports a bad header size' |
66
|
|
|
f = GiniFile(get_test_data('NHEM-MULTICOMP_1km_IR_20151208_2100.gini')) |
67
|
|
|
pdb2 = f.prod_desc2 |
68
|
|
|
assert pdb2.pdb_size == 512 # Catching bad size |
69
|
|
|
|
70
|
|
|
|
71
|
|
|
# Reference information coming out of the dataset interface, coordinate calculations, |
72
|
|
|
# inclusion of correct projection metadata, etc. |
73
|
|
|
gini_dataset_info = [('WEST-CONUS_4km_WV_20151208_2200.gini', |
74
|
|
|
(-4226066.37649, 239720.12351, -832700.70519, 4364515.79481), 'WV', |
75
|
|
|
dict(grid_mapping_name='lambert_conformal_conic', standard_parallel=25.0, |
76
|
|
|
earth_radius=6371200., latitude_of_projection_origin=25.0, |
77
|
|
|
longitude_of_central_meridian=-95.0)), |
78
|
|
|
('AK-REGIONAL_8km_3.9_20160408_1445.gini', |
79
|
|
|
(-2286001.13195, 2278061.36805, -4762503.5992, -1531941.0992), 'IR', |
80
|
|
|
dict(grid_mapping_name='polar_stereographic', standard_parallel=60.0, |
81
|
|
|
earth_radius=6371200., latitude_of_projection_origin=90., |
82
|
|
|
straight_vertical_longitude_from_pole=210.0)), |
83
|
|
|
('HI-REGIONAL_4km_3.9_20160616_1715.gini', |
84
|
|
|
(0.0, 2236000.0, 980627.44738, 3056627.44738), 'IR', |
85
|
|
|
dict(grid_mapping_name='mercator', standard_parallel=20.0, |
86
|
|
|
earth_radius=6371200., latitude_of_projection_origin=9.343, |
87
|
|
|
longitude_of_projection_origin=-167.315)) |
88
|
|
|
] |
89
|
|
|
|
90
|
|
|
|
91
|
|
|
@pytest.mark.parametrize('filename,bounds,data_var,proj_attrs', gini_dataset_info, |
92
|
|
|
ids=['LCC', 'Stereographic', 'Mercator']) |
93
|
|
|
def test_gini_dataset(filename, bounds, data_var, proj_attrs): |
94
|
|
|
'Test the dataset interface for GINI' |
95
|
|
|
f = GiniFile(get_test_data(filename)) |
96
|
|
|
ds = f.to_dataset() |
97
|
|
|
|
98
|
|
|
# Check our calculated x and y arrays |
99
|
|
|
x0, x1, y0, y1 = bounds |
100
|
|
|
x = ds.variables['x'] |
101
|
|
|
assert_almost_equal(x[0], x0, 4) |
102
|
|
|
assert_almost_equal(x[-1], x1, 4) |
103
|
|
|
|
104
|
|
|
y = ds.variables['y'] |
105
|
|
|
assert_almost_equal(y[0], y0, 4) |
106
|
|
|
assert_almost_equal(y[-1], y1, 4) |
107
|
|
|
|
108
|
|
|
# Check the projection metadata |
109
|
|
|
proj_name = ds.variables[data_var].grid_mapping |
110
|
|
|
proj_var = ds.variables[proj_name] |
111
|
|
|
for attr, val in proj_attrs.items(): |
112
|
|
|
assert getattr(proj_var, attr) == val, 'Values mismatch for ' + attr |
113
|
|
|
|
114
|
|
|
# Check the lon/lat corner |
115
|
|
|
assert_almost_equal(ds.variables['lon'][0, 0], f.prod_desc.lo1, 4) |
116
|
|
|
assert_almost_equal(ds.variables['lat'][0, 0], f.prod_desc.la1, 4) |
117
|
|
|
|
118
|
|
|
|
119
|
|
|
def test_gini_mercator_upper_corner(): |
120
|
|
|
'Test that the upper corner of the Mercator coordinates is correct' |
121
|
|
|
f = GiniFile(get_test_data('HI-REGIONAL_4km_3.9_20160616_1715.gini')) |
122
|
|
|
ds = f.to_dataset() |
123
|
|
|
lat = ds.variables['lat'] |
124
|
|
|
lon = ds.variables['lon'] |
125
|
|
|
|
126
|
|
|
# 2nd corner lat/lon are at the "upper right" corner of the pixel, so need to add one |
127
|
|
|
# more grid point |
128
|
|
|
assert_almost_equal(lon[-1, -1] + (lon[-1, -1] - lon[-1, -2]), f.proj_info.lo2, 4) |
129
|
|
|
assert_almost_equal(lat[-1, -1] + (lat[-1, -1] - lat[-2, -1]), f.proj_info.la2, 4) |
130
|
|
|
|
131
|
|
|
|
132
|
|
|
def test_gini_str(): |
133
|
|
|
'Test the str representation of GiniFile' |
134
|
|
|
f = GiniFile(get_test_data('WEST-CONUS_4km_WV_20151208_2200.gini')) |
135
|
|
|
truth = ('GiniFile: GOES-15 West CONUS WV (6.5/6.7 micron)\n' |
136
|
|
|
'\tTime: 2015-12-08 22:00:19\n\tSize: 1280x1100\n' |
137
|
|
|
'\tProjection: lambert_conformal\n' |
138
|
|
|
'\tLower Left Corner (Lon, Lat): (-133.4588, 12.19)\n\tResolution: 4km') |
139
|
|
|
assert str(f) == truth |
140
|
|
|
|