Completed
Push — master ( 5f4738...de82a3 )
by Ryan
01:49
created

test_rh_specific_humidity()   A

Complexity

Conditions 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 7
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 `thermo` module."""
5
6
import numpy as np
7
import pytest
8
9
from metpy.calc import (density, dewpoint, dewpoint_rh, dry_lapse, el,
10
                        equivalent_potential_temperature, lcl, lfc, mixing_ratio,
11
                        mixing_ratio_from_specific_humidity, moist_lapse,
12
                        parcel_profile, potential_temperature,
13
                        psychrometric_vapor_pressure_wet,
14
                        relative_humidity_from_mixing_ratio,
15
                        relative_humidity_from_specific_humidity,
16
                        relative_humidity_wet_psychrometric,
17
                        saturation_mixing_ratio,
18
                        saturation_vapor_pressure, vapor_pressure,
19
                        virtual_potential_temperature, virtual_temperature)
20
21
from metpy.testing import assert_almost_equal, assert_array_almost_equal, assert_nan
22
from metpy.units import units
23
24
25
def test_potential_temperature():
26
    """Test potential_temperature calculation."""
27
    temp = np.array([278., 283., 291., 298.]) * units.kelvin
28
    pres = np.array([900., 500., 300., 100.]) * units.mbar
29
    real_th = np.array([286.493, 344.961, 410.4335, 575.236]) * units.kelvin
30
    assert_array_almost_equal(potential_temperature(pres, temp), real_th, 3)
31
32
33
def test_scalar():
34
    """Test potential_temperature accepts scalar values."""
35
    assert_almost_equal(potential_temperature(1000. * units.mbar, 293. * units.kelvin),
36
                        293. * units.kelvin, 4)
37
    assert_almost_equal(potential_temperature(800. * units.mbar, 293. * units.kelvin),
38
                        312.2828 * units.kelvin, 4)
39
40
41
def test_fahrenheit():
42
    """Test that potential_temperature handles temperature values in Fahrenheit."""
43
    assert_almost_equal(potential_temperature(800. * units.mbar, 68. * units.degF),
44
                        (312.444 * units.kelvin).to(units.degF), 2)
45
46
47
def test_pot_temp_inhg():
48
    """Test that potential_temperature can handle pressure not in mb (issue #165)."""
49
    assert_almost_equal(potential_temperature(29.92 * units.inHg, 29 * units.degC),
50
                        301.019735 * units.kelvin, 4)
51
52
53
def test_dry_lapse():
54
    """Test dry_lapse calculation."""
55
    levels = np.array([1000, 900, 864.89]) * units.mbar
56
    temps = dry_lapse(levels, 303.15 * units.kelvin)
57
    assert_array_almost_equal(temps,
58
                              np.array([303.15, 294.16, 290.83]) * units.kelvin, 2)
59
60
61
def test_dry_lapse_2_levels():
62
    """Test dry_lapse calculation when given only two levels."""
63
    temps = dry_lapse(np.array([1000., 500.]) * units.mbar, 293. * units.kelvin)
64
    assert_array_almost_equal(temps, [293., 240.3723] * units.kelvin, 4)
65
66
67
def test_moist_lapse():
68
    """Test moist_lapse calculation."""
69
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
70
                       293. * units.kelvin)
71
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
72
    assert_array_almost_equal(temp, true_temp, 2)
73
74
75
def test_moist_lapse_degc():
76
    """Test moist_lapse with Celsius temperatures."""
77
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
78
                       19.85 * units.degC)
79
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
80
    assert_array_almost_equal(temp, true_temp, 2)
81
82
83
def test_parcel_profile():
84
    """Test parcel profile calculation."""
85
    levels = np.array([1000., 900., 800., 700., 600., 500., 400.]) * units.mbar
86
    true_prof = np.array([303.15, 294.16, 288.026, 283.073, 277.058, 269.402,
87
                          258.966]) * units.kelvin
88
89
    prof = parcel_profile(levels, 30. * units.degC, 20. * units.degC)
90
    assert_array_almost_equal(prof, true_prof, 2)
91
92
93
def test_parcel_profile_saturated():
94
    """Test parcel_profile works when LCL in levels (issue #232)."""
95
    levels = np.array([1000., 700., 500.]) * units.mbar
96
    true_prof = np.array([296.95, 284.381, 271.123]) * units.kelvin
97
98
    prof = parcel_profile(levels, 23.8 * units.degC, 23.8 * units.degC)
99
    assert_array_almost_equal(prof, true_prof, 2)
100
101
102
def test_sat_vapor_pressure():
103
    """Test saturation_vapor_pressure calculation."""
104
    temp = np.array([5., 10., 18., 25.]) * units.degC
105
    real_es = np.array([8.72, 12.27, 20.63, 31.67]) * units.mbar
106
    assert_array_almost_equal(saturation_vapor_pressure(temp), real_es, 2)
107
108
109
def test_sat_vapor_pressure_scalar():
110
    """Test saturation_vapor_pressure handles scalar values."""
111
    es = saturation_vapor_pressure(0 * units.degC)
112
    assert_almost_equal(es, 6.112 * units.mbar, 3)
113
114
115
def test_sat_vapor_pressure_fahrenheit():
116
    """Test saturation_vapor_pressure handles temperature in Fahrenheit."""
117
    temp = np.array([50., 68.]) * units.degF
118
    real_es = np.array([12.2717, 23.3695]) * units.mbar
119
    assert_array_almost_equal(saturation_vapor_pressure(temp), real_es, 4)
120
121
122
def test_basic_dewpoint_rh():
123
    """Test dewpoint_rh function."""
124
    temp = np.array([30., 25., 10., 20., 25.]) * units.degC
125
    rh = np.array([30., 45., 55., 80., 85.]) / 100.
126
127
    real_td = np.array([11, 12, 1, 16, 22]) * units.degC
128
    assert_array_almost_equal(real_td, dewpoint_rh(temp, rh), 0)
129
130
131
def test_scalar_dewpoint_rh():
132
    """Test dewpoint_rh with scalar values."""
133
    td = dewpoint_rh(10.6 * units.degC, 0.37)
134
    assert_almost_equal(td, 26. * units.degF, 0)
135
136
137
def test_dewpoint():
138
    """Test dewpoint calculation."""
139
    assert_almost_equal(dewpoint(6.112 * units.mbar), 0. * units.degC, 2)
140
141
142
def test_dewpoint_weird_units():
143
    """Test dewpoint using non-standard units.
144
145
    Revealed from odd dimensionless units and ending up using numpy.ma math
146
    functions instead of numpy ones.
147
    """
148
    assert_almost_equal(dewpoint(15825.6 * units('g * mbar / kg')),
149
                        13.8564 * units.degC, 4)
150
151
152
def test_mixing_ratio():
153
    """Test mixing ratio calculation."""
154
    p = 998. * units.mbar
155
    e = 73.75 * units.mbar
156
    assert_almost_equal(mixing_ratio(e, p), 0.04963, 2)
157
158
159
def test_vapor_pressure():
160
    """Test vapor pressure calculation."""
161
    assert_almost_equal(vapor_pressure(998. * units.mbar, 0.04963),
162
                        73.74925 * units.mbar, 5)
163
164
165
def test_lcl():
166
    """Test LCL calculation."""
167
    lcl_pressure, lcl_temperature = lcl(1000. * units.mbar, 30. * units.degC, 20. * units.degC)
168
    assert_almost_equal(lcl_pressure, 864.761 * units.mbar, 2)
169
    assert_almost_equal(lcl_temperature, 17.676 * units.degC, 2)
170
171
172
def test_lcl_convergence():
173
    """Test LCL calculation convergence failure."""
174
    with pytest.raises(RuntimeError):
175
        lcl(1000. * units.mbar, 30. * units.degC, 20. * units.degC, max_iters=2)
176
177
178 View Code Duplication
def test_lfc_basic():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
179
    """Test LFC calculation."""
180
    levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
181
    temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -49.]) * units.celsius
182
    dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
183
    l = lfc(levels, temperatures, dewpoints)
184
    assert_almost_equal(l[0], 727.468 * units.mbar, 2)
185
    assert_almost_equal(l[1], 9.705 * units.celsius, 2)
186
187
188
def test_no_lfc():
189
    """Test LFC calculation when there is no LFC in the data."""
190
    levels = np.array([959., 867.9, 779.2, 647.5, 472.5, 321.9, 251.]) * units.mbar
191
    temperatures = np.array([22.2, 17.4, 14.6, 1.4, -17.6, -39.4, -52.5]) * units.celsius
192
    dewpoints = np.array([9., 4.3, -21.2, -26.7, -31., -53.3, -66.7]) * units.celsius
193
    lfc_pressure, lfc_temperature = lfc(levels, temperatures, dewpoints)
194
    assert assert_nan(lfc_pressure, levels.units)
195
    assert assert_nan(lfc_temperature, temperatures.units)
196
197
198 View Code Duplication
def test_lfc_inversion():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
199
    """Test LFC when there is an inversion to be sure we don't pick that."""
200
    levels = np.array([963., 789., 782.3, 754.8, 728.1, 727., 700.,
201
                       571., 450., 300., 248.]) * units.mbar
202
    temperatures = np.array([25.4, 18.4, 17.8, 15.4, 12.9, 12.8,
203
                             10., -3.9, -16.3, -41.1, -51.5]) * units.celsius
204
    dewpoints = np.array([20.4, 0.4, -0.5, -4.3, -8., -8.2, -9.,
205
                          -23.9, -33.3, -54.1, -63.5]) * units.celsius
206
    l = lfc(levels, temperatures, dewpoints)
207
    assert_almost_equal(l[0], 706.0103 * units.mbar, 2)
208
    assert_almost_equal(l[1], 10.6232 * units.celsius, 2)
209
210
211
def test_saturation_mixing_ratio():
212
    """Test saturation mixing ratio calculation."""
213
    p = 999. * units.mbar
214
    t = 288. * units.kelvin
215
    assert_almost_equal(saturation_mixing_ratio(p, t), .01068, 3)
216
217
218
def test_equivalent_potential_temperature():
219
    """Test equivalent potential temperature calculation."""
220
    p = 999. * units.mbar
221
    t = 288. * units.kelvin
222
    ept = equivalent_potential_temperature(p, t)
223
    assert_almost_equal(ept, 315.9548 * units.kelvin, 3)
224
225
226
def test_virtual_temperature():
227
    """Test virtual temperature calculation."""
228
    t = 288. * units.kelvin
229
    qv = .0016  # kg/kg
230
    tv = virtual_temperature(t, qv)
231
    assert_almost_equal(tv, 288.2796 * units.kelvin, 3)
232
233
234
def test_virtual_potential_temperature():
235
    """Test virtual potential temperature calculation."""
236
    p = 999. * units.mbar
237
    t = 288. * units.kelvin
238
    qv = .0016  # kg/kg
239
    theta_v = virtual_potential_temperature(p, t, qv)
240
    assert_almost_equal(theta_v, 288.3620 * units.kelvin, 3)
241
242
243
def test_density():
244
    """Test density calculation."""
245
    p = 999. * units.mbar
246
    t = 288. * units.kelvin
247
    qv = .0016  # kg/kg
248
    rho = density(p, t, qv).to(units.kilogram / units.meter ** 3)
249
    assert_almost_equal(rho, 1.2072 * (units.kilogram / units.meter ** 3), 3)
250
251
252
def test_el():
253
    """Test equilibrium layer calculation."""
254
    levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
255
    temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.celsius
256
    dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
257
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
258
    assert_almost_equal(el_pressure, 520.8700 * units.mbar, 3)
259
    assert_almost_equal(el_temperature, -11.7027 * units.degC, 3)
260
261
262
def test_no_el():
263
    """Test equilibrium layer calculation when there is no EL in the data."""
264
    levels = np.array([959., 867.9, 779.2, 647.5, 472.5, 321.9, 251.]) * units.mbar
265
    temperatures = np.array([22.2, 17.4, 14.6, 1.4, -17.6, -39.4, -52.5]) * units.celsius
266
    dewpoints = np.array([19., 14.3, -11.2, -16.7, -21., -43.3, -56.7]) * units.celsius
267
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
268
    assert assert_nan(el_pressure, levels.units)
269
    assert assert_nan(el_temperature, temperatures.units)
270
271
272
def test_wet_psychrometric_vapor_pressure():
273
    """Test calculation of vapor pressure from wet and dry bulb temperatures."""
274
    p = 1013.25 * units.mbar
275
    dry_bulb_temperature = 20. * units.degC
276
    wet_bulb_temperature = 18. * units.degC
277
    psychrometric_vapor_pressure = psychrometric_vapor_pressure_wet(dry_bulb_temperature,
278
                                                                    wet_bulb_temperature, p)
279
    assert_almost_equal(psychrometric_vapor_pressure, 19.3673 * units.mbar, 3)
280
281
282
def test_wet_psychrometric_rh():
283
    """Test calculation of relative humidity from wet and dry bulb temperatures."""
284
    p = 1013.25 * units.mbar
285
    dry_bulb_temperature = 20. * units.degC
286
    wet_bulb_temperature = 18. * units.degC
287
    psychrometric_rh = relative_humidity_wet_psychrometric(dry_bulb_temperature,
288
                                                           wet_bulb_temperature, p)
289
    assert_almost_equal(psychrometric_rh, 82.8747 * units.percent, 3)
290
291
292
def test_wet_psychrometric_rh_kwargs():
293
    """Test calculation of relative humidity from wet and dry bulb temperatures."""
294
    p = 1013.25 * units.mbar
295
    dry_bulb_temperature = 20. * units.degC
296
    wet_bulb_temperature = 18. * units.degC
297
    coeff = 6.1e-4 / units.kelvin
298
    psychrometric_rh = relative_humidity_wet_psychrometric(dry_bulb_temperature,
299
                                                           wet_bulb_temperature, p,
300
                                                           psychrometer_coefficient=coeff)
301
    assert_almost_equal(psychrometric_rh, 82.9701 * units.percent, 3)
302
303
304
def test_rh_mixing_ratio():
305
    """Tests relative humidity from mixing ratio."""
306
    p = 1013.25 * units.mbar
307
    temperature = 20. * units.degC
308
    w = 0.012
309
    rh = relative_humidity_from_mixing_ratio(w, temperature, p)
310
    assert_almost_equal(rh, 81.7219 * units.percent, 3)
311
312
313
def test_mixing_ratio_from_specific_humidity():
314
    """Tests mixing ratio from specific humidity."""
315
    q = 0.012
316
    w = mixing_ratio_from_specific_humidity(q)
317
    assert_almost_equal(w, 0.01215, 3)
318
319
320
def test_rh_specific_humidity():
321
    """Tests relative humidity from specific humidity."""
322
    p = 1013.25 * units.mbar
323
    temperature = 20. * units.degC
324
    q = 0.012
325
    rh = relative_humidity_from_specific_humidity(q, temperature, p)
326
    assert_almost_equal(rh, 82.7145 * units.percent, 3)
327