Completed
Pull Request — master (#446)
by
unknown
06:54
created

test_mixing_ratio_from_specific_humidity()   A

Complexity

Conditions 1

Size

Total Lines 6

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