Completed
Push — master ( ab0a25...73ac07 )
by Ryan
16s
created

test_coriolis_warning()   A

Complexity

Conditions 3

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
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
"""Test the `basic` module."""
5
6
import numpy as np
7
import pytest
8
9
from metpy.calc import (add_height_to_pressure, add_pressure_to_height, coriolis_parameter,
10
                        get_wind_components, get_wind_dir, get_wind_speed, heat_index,
11
                        height_to_pressure_std, pressure_to_height_std, sigma_to_pressure,
12
                        windchill)
13
from metpy.testing import assert_almost_equal, assert_array_almost_equal, assert_array_equal
14
from metpy.units import units
15
16
17
def test_wind_comps_basic():
18
    """Test the basic wind component calculation."""
19
    speed = np.array([4, 4, 4, 4, 25, 25, 25, 25, 10.]) * units.mph
20
    dirs = np.array([0, 45, 90, 135, 180, 225, 270, 315, 360]) * units.deg
21
    s2 = np.sqrt(2.)
22
23
    u, v = get_wind_components(speed, dirs)
24
25
    true_u = np.array([0, -4 / s2, -4, -4 / s2, 0, 25 / s2, 25, 25 / s2, 0]) * units.mph
26
    true_v = np.array([-4, -4 / s2, 0, 4 / s2, 25, 25 / s2, 0, -25 / s2, -10]) * units.mph
27
28
    assert_array_almost_equal(true_u, u, 4)
29
    assert_array_almost_equal(true_v, v, 4)
30
31
32
def test_wind_comps_scalar():
33
    """Test wind components calculation with scalars."""
34
    u, v = get_wind_components(8 * units('m/s'), 150 * units.deg)
35
    assert_almost_equal(u, -4 * units('m/s'), 3)
36
    assert_almost_equal(v, 6.9282 * units('m/s'), 3)
37
38
39
def test_speed():
40
    """Test calculating wind speed."""
41
    u = np.array([4., 2., 0., 0.]) * units('m/s')
42
    v = np.array([0., 2., 4., 0.]) * units('m/s')
43
44
    speed = get_wind_speed(u, v)
45
46
    s2 = np.sqrt(2.)
47
    true_speed = np.array([4., 2 * s2, 4., 0.]) * units('m/s')
48
49
    assert_array_almost_equal(true_speed, speed, 4)
50
51
52
def test_dir():
53
    """Test calculating wind direction."""
54
    u = np.array([4., 2., 0., 0.]) * units('m/s')
55
    v = np.array([0., 2., 4., 0.]) * units('m/s')
56
57
    direc = get_wind_dir(u, v)
58
59
    true_dir = np.array([270., 225., 180., 270.]) * units.deg
60
61
    assert_array_almost_equal(true_dir, direc, 4)
62
63
64
def test_speed_dir_roundtrip():
65
    """Test round-tripping between speed/direction and components."""
66
    # Test each quadrant of the whole circle
67
    wspd = np.array([15., 5., 2., 10.]) * units.meters / units.seconds
68
    wdir = np.array([160., 30., 225., 350.]) * units.degrees
69
70
    u, v = get_wind_components(wspd, wdir)
71
72
    wdir_out = get_wind_dir(u, v)
73
    wspd_out = get_wind_speed(u, v)
74
75
    assert_array_almost_equal(wspd, wspd_out, 4)
76
    assert_array_almost_equal(wdir, wdir_out, 4)
77
78
79
def test_scalar_speed():
80
    """Test wind speed with scalars."""
81
    s = get_wind_speed(-3. * units('m/s'), -4. * units('m/s'))
82
    assert_almost_equal(s, 5. * units('m/s'), 3)
83
84
85
def test_scalar_dir():
86
    """Test wind direction with scalars."""
87
    d = get_wind_dir(3. * units('m/s'), 4. * units('m/s'))
88
    assert_almost_equal(d, 216.870 * units.deg, 3)
89
90
91
def test_windchill_scalar():
92
    """Test wind chill with scalars."""
93
    wc = windchill(-5 * units.degC, 35 * units('m/s'))
94
    assert_almost_equal(wc, -18.9357 * units.degC, 0)
95
96
97
def test_windchill_basic():
98
    """Test the basic wind chill calculation."""
99
    temp = np.array([40, -10, -45, 20]) * units.degF
100
    speed = np.array([5, 55, 25, 15]) * units.mph
101
102
    wc = windchill(temp, speed)
103
    values = np.array([36, -46, -84, 6]) * units.degF
104
    assert_array_almost_equal(wc, values, 0)
105
106
107
def test_windchill_kelvin():
108
    """Test wind chill when given Kelvin temperatures."""
109
    wc = windchill(268.15 * units.kelvin, 35 * units('m/s'))
110
    assert_almost_equal(wc, -18.9357 * units.degC, 0)
111
112
113
def test_windchill_invalid():
114
    """Test windchill for values that should be masked."""
115
    temp = np.array([10, 51, 49, 60, 80, 81]) * units.degF
116
    speed = np.array([4, 4, 3, 1, 10, 39]) * units.mph
117
118
    wc = windchill(temp, speed)
119
    # We don't care about the masked values
120
    truth = np.array([2.6230789, np.nan, np.nan, np.nan, np.nan, np.nan]) * units.degF
121
    mask = np.array([False, True, True, True, True, True])
122
    assert_array_almost_equal(truth, wc)
123
    assert_array_equal(wc.mask, mask)
124
125
126
def test_windchill_undefined_flag():
127
    """Test whether masking values for windchill can be disabled."""
128
    temp = units.Quantity(np.ma.array([49, 50, 49, 60, 80, 81]), units.degF)
129
    speed = units.Quantity(([4, 4, 3, 1, 10, 39]), units.mph)
130
131
    wc = windchill(temp, speed, mask_undefined=False)
132
    mask = np.array([False] * 6)
133
    assert_array_equal(wc.mask, mask)
134
135
136
def test_windchill_face_level():
137
    """Test windchill using the face_level flag."""
138
    temp = np.array([20, 0, -20, -40]) * units.degF
139
    speed = np.array([15, 30, 45, 60]) * units.mph
140
141
    wc = windchill(temp, speed, face_level_winds=True)
142
    values = np.array([3, -30, -64, -98]) * units.degF
143
    assert_array_almost_equal(wc, values, 0)
144
145
146
def test_heat_index_basic():
147
    """Test the basic heat index calculation."""
148
    temp = np.array([80, 88, 92, 110]) * units.degF
149
    rh = np.array([40, 100, 70, 40]) * units.percent
150
151
    hi = heat_index(temp, rh)
152
    values = np.array([80, 121, 112, 136]) * units.degF
153
    assert_array_almost_equal(hi, values, 0)
154
155
156
def test_heat_index_scalar():
157
    """Test heat index using scalars."""
158
    hi = heat_index(96 * units.degF, 65 * units.percent)
159
    assert_almost_equal(hi, 121 * units.degF, 0)
160
161
162
def test_heat_index_invalid():
163
    """Test heat index for values that should be masked."""
164
    temp = np.array([80, 88, 92, 79, 30, 81]) * units.degF
165
    rh = np.array([40, 39, 2, 70, 50, 39]) * units.percent
166
167
    hi = heat_index(temp, rh)
168
    mask = np.array([False, True, True, True, True, True])
169
    assert_array_equal(hi.mask, mask)
170
171
172
def test_heat_index_undefined_flag():
173
    """Test whether masking values can be disabled for heat index."""
174
    temp = units.Quantity(np.ma.array([80, 88, 92, 79, 30, 81]), units.degF)
175
    rh = np.ma.array([40, 39, 2, 70, 50, 39]) * units.percent
176
177
    hi = heat_index(temp, rh, mask_undefined=False)
178
    mask = np.array([False] * 6)
179
    assert_array_equal(hi.mask, mask)
180
181
182
def test_heat_index_units():
183
    """Test units coming out of heat index."""
184
    temp = units.Quantity([35., 20.], units.degC)
185
    rh = 70 * units.percent
186
    hi = heat_index(temp, rh)
187
    assert_almost_equal(hi.to('degC'), units.Quantity([50.3405, np.nan], units.degC), 4)
188
189
190
def test_heat_index_ratio():
191
    """Test giving humidity as number [0, 1] to heat index."""
192
    temp = units.Quantity([35., 20.], units.degC)
193
    rh = 0.7
194
    hi = heat_index(temp, rh)
195
    assert_almost_equal(hi.to('degC'), units.Quantity([50.3405, np.nan], units.degC), 4)
196
197
# class TestIrrad(object):
198
#    def test_basic(self):
199
#        'Test the basic solar irradiance calculation.'
200
#        from datetime import date
201
202
#        d = date(2008, 9, 28)
203
#        lat = 35.25
204
#        hours = np.linspace(6,18,10)
205
206
#        s = solar_irradiance(lat, d, hours)
207
#        values = np.array([0., 344.1, 682.6, 933.9, 1067.6, 1067.6, 933.9,
208
#            682.6, 344.1, 0.])
209
#        assert_array_almost_equal(s, values, 1)
210
211
#    def test_scalar(self):
212
#        from datetime import date
213
#        d = date(2008, 9, 28)
214
#        lat = 35.25
215
#        hour = 9.5
216
#        s = solar_irradiance(lat, d, hour)
217
#        assert_almost_equal(s, 852.1, 1)
218
219
#    def test_invalid(self):
220
#        'Test for values that should be masked.'
221
#        from datetime import date
222
#        d = date(2008, 9, 28)
223
#        lat = 35.25
224
#        hours = np.linspace(0,22,12)
225
#        s = solar_irradiance(lat, d, hours)
226
227
#        mask = np.array([ True,  True,  True,  True, False, False, False,
228
#            False, False, True,  True,  True])
229
#        assert_array_equal(s.mask, mask)
230
231
232
def test_pressure_to_heights_basic():
233
    """Test basic pressure to height calculation for standard atmosphere."""
234
    pressures = np.array([975.2, 987.5, 956., 943.]) * units.mbar
235
    heights = pressure_to_height_std(pressures)
236
    values = np.array([321.5, 216.5, 487.6, 601.7]) * units.meter
237
    assert_almost_equal(heights, values, 1)
238
239
240
def test_heights_to_pressure_basic():
241
    """Test basic height to pressure calculation for standard atmosphere."""
242
    heights = np.array([321.5, 216.5, 487.6, 601.7]) * units.meter
243
    pressures = height_to_pressure_std(heights)
244
    values = np.array([975.2, 987.5, 956., 943.]) * units.mbar
245
    assert_almost_equal(pressures, values, 1)
246
247
248
def test_pressure_to_heights_units():
249
    """Test that passing non-mbar units works."""
250
    assert_almost_equal(pressure_to_height_std(29 * units.inHg), 262.859 * units.meter, 3)
251
252
253
def test_coriolis_force():
254
    """Test basic coriolis force calculation."""
255
    lat = np.array([-90., -30., 0., 30., 90.]) * units.degrees
256
    cor = coriolis_parameter(lat)
257
    values = np.array([-1.4584232E-4, -.72921159E-4, 0, .72921159E-4,
258
                       1.4584232E-4]) * units('s^-1')
259
    assert_almost_equal(cor, values, 7)
260
261
262
def test_add_height_to_pressure():
263
    """Test the pressure at height above pressure calculation."""
264
    pressure = add_height_to_pressure(1000 * units.hPa, 877.17421094 * units.meter)
265
    assert_almost_equal(pressure, 900 * units.hPa, 5)
266
267
268
def test_add_pressure_to_height():
269
    """Test the height at pressure above height calculation."""
270
    height = add_pressure_to_height(110.8286757 * units.m, 100 * units.hPa)
271
    assert_almost_equal(height, 988.0028867 * units.meter, 5)
272
273
274
def test_sigma_to_pressure():
275
    """Test sigma_to_pressure."""
276
    surface_pressure = 1000. * units.hPa
277
    model_top_pressure = 0. * units.hPa
278
    sigma = np.arange(0., 1.1, 0.1)
279
    expected = np.arange(0., 1100., 100.) * units.hPa
280
    pressure = sigma_to_pressure(sigma, surface_pressure, model_top_pressure)
281
    assert_array_almost_equal(pressure, expected, 5)
282
283
284
def test_warning_dir():
285
    """Test that warning is raised wind direction > 2Pi."""
286
    with pytest.warns(UserWarning):
287
        get_wind_components(3. * units('m/s'), 270)
288
289
290
def test_coriolis_warning():
291
    """Test that warning is raise when latitude larger than pi radians."""
292
    with pytest.warns(UserWarning):
293
        coriolis_parameter(50)
294
    with pytest.warns(UserWarning):
295
        coriolis_parameter(-50)
296