Completed
Pull Request — master (#494)
by
unknown
01:17
created

test_most_unstable_cape_cin_surface()   A

Complexity

Conditions 1

Size

Total Lines 8

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 8
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 (cape_cin, density, dewpoint, dewpoint_rh, dry_lapse, el,
10
                        equivalent_potential_temperature,
11
                        isentropic_interpolation,
12
                        lcl, lfc, mixing_ratio,
13
                        mixing_ratio_from_specific_humidity, moist_lapse,
14
                        most_unstable_parcel, most_unstable_cape_cin,
15
                        parcel_profile, potential_temperature,
16
                        psychrometric_vapor_pressure_wet,
17
                        relative_humidity_from_mixing_ratio,
18
                        relative_humidity_from_specific_humidity,
19
                        relative_humidity_wet_psychrometric,
20
                        saturation_mixing_ratio,
21
                        saturation_vapor_pressure, vapor_pressure,
22
                        virtual_potential_temperature, virtual_temperature)
23
24
from metpy.calc.thermo import _find_append_zero_crossings
25
from metpy.testing import assert_almost_equal, assert_array_almost_equal, assert_nan
26
from metpy.units import units
27
28
29
def test_potential_temperature():
30
    """Test potential_temperature calculation."""
31
    temp = np.array([278., 283., 291., 298.]) * units.kelvin
32
    pres = np.array([900., 500., 300., 100.]) * units.mbar
33
    real_th = np.array([286.493, 344.961, 410.4335, 575.236]) * units.kelvin
34
    assert_array_almost_equal(potential_temperature(pres, temp), real_th, 3)
35
36
37
def test_scalar():
38
    """Test potential_temperature accepts scalar values."""
39
    assert_almost_equal(potential_temperature(1000. * units.mbar, 293. * units.kelvin),
40
                        293. * units.kelvin, 4)
41
    assert_almost_equal(potential_temperature(800. * units.mbar, 293. * units.kelvin),
42
                        312.2828 * units.kelvin, 4)
43
44
45
def test_fahrenheit():
46
    """Test that potential_temperature handles temperature values in Fahrenheit."""
47
    assert_almost_equal(potential_temperature(800. * units.mbar, 68. * units.degF),
48
                        (312.444 * units.kelvin).to(units.degF), 2)
49
50
51
def test_pot_temp_inhg():
52
    """Test that potential_temperature can handle pressure not in mb (issue #165)."""
53
    assert_almost_equal(potential_temperature(29.92 * units.inHg, 29 * units.degC),
54
                        301.019735 * units.kelvin, 4)
55
56
57
def test_dry_lapse():
58
    """Test dry_lapse calculation."""
59
    levels = np.array([1000, 900, 864.89]) * units.mbar
60
    temps = dry_lapse(levels, 303.15 * units.kelvin)
61
    assert_array_almost_equal(temps,
62
                              np.array([303.15, 294.16, 290.83]) * units.kelvin, 2)
63
64
65
def test_dry_lapse_2_levels():
66
    """Test dry_lapse calculation when given only two levels."""
67
    temps = dry_lapse(np.array([1000., 500.]) * units.mbar, 293. * units.kelvin)
68
    assert_array_almost_equal(temps, [293., 240.3723] * units.kelvin, 4)
69
70
71
def test_moist_lapse():
72
    """Test moist_lapse calculation."""
73
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
74
                       293. * units.kelvin)
75
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
76
    assert_array_almost_equal(temp, true_temp, 2)
77
78
79
def test_moist_lapse_degc():
80
    """Test moist_lapse with Celsius temperatures."""
81
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
82
                       19.85 * units.degC)
83
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
84
    assert_array_almost_equal(temp, true_temp, 2)
85
86
87
def test_parcel_profile():
88
    """Test parcel profile calculation."""
89
    levels = np.array([1000., 900., 800., 700., 600., 500., 400.]) * units.mbar
90
    true_prof = np.array([303.15, 294.16, 288.026, 283.073, 277.058, 269.402,
91
                          258.966]) * units.kelvin
92
93
    prof = parcel_profile(levels, 30. * units.degC, 20. * units.degC)
94
    assert_array_almost_equal(prof, true_prof, 2)
95
96
97
def test_parcel_profile_saturated():
98
    """Test parcel_profile works when LCL in levels (issue #232)."""
99
    levels = np.array([1000., 700., 500.]) * units.mbar
100
    true_prof = np.array([296.95, 284.381, 271.123]) * units.kelvin
101
102
    prof = parcel_profile(levels, 23.8 * units.degC, 23.8 * units.degC)
103
    assert_array_almost_equal(prof, true_prof, 2)
104
105
106
def test_sat_vapor_pressure():
107
    """Test saturation_vapor_pressure calculation."""
108
    temp = np.array([5., 10., 18., 25.]) * units.degC
109
    real_es = np.array([8.72, 12.27, 20.63, 31.67]) * units.mbar
110
    assert_array_almost_equal(saturation_vapor_pressure(temp), real_es, 2)
111
112
113
def test_sat_vapor_pressure_scalar():
114
    """Test saturation_vapor_pressure handles scalar values."""
115
    es = saturation_vapor_pressure(0 * units.degC)
116
    assert_almost_equal(es, 6.112 * units.mbar, 3)
117
118
119
def test_sat_vapor_pressure_fahrenheit():
120
    """Test saturation_vapor_pressure handles temperature in Fahrenheit."""
121
    temp = np.array([50., 68.]) * units.degF
122
    real_es = np.array([12.2717, 23.3695]) * units.mbar
123
    assert_array_almost_equal(saturation_vapor_pressure(temp), real_es, 4)
124
125
126
def test_basic_dewpoint_rh():
127
    """Test dewpoint_rh function."""
128
    temp = np.array([30., 25., 10., 20., 25.]) * units.degC
129
    rh = np.array([30., 45., 55., 80., 85.]) / 100.
130
131
    real_td = np.array([11, 12, 1, 16, 22]) * units.degC
132
    assert_array_almost_equal(real_td, dewpoint_rh(temp, rh), 0)
133
134
135
def test_scalar_dewpoint_rh():
136
    """Test dewpoint_rh with scalar values."""
137
    td = dewpoint_rh(10.6 * units.degC, 0.37)
138
    assert_almost_equal(td, 26. * units.degF, 0)
139
140
141
def test_percent_dewpoint_rh():
142
    """Test dewpoint_rh with rh in percent."""
143
    td = dewpoint_rh(10.6 * units.degC, 37 * units.percent)
144
    assert_almost_equal(td, 26. * units.degF, 0)
145
146
147
def test_warning_dewpoint_rh():
148
    """Test that warning is raised for >120% RH."""
149
    with pytest.warns(UserWarning):
150
        dewpoint_rh(10.6 * units.degC, 50)
151
152
153
def test_dewpoint():
154
    """Test dewpoint calculation."""
155
    assert_almost_equal(dewpoint(6.112 * units.mbar), 0. * units.degC, 2)
156
157
158
def test_dewpoint_weird_units():
159
    """Test dewpoint using non-standard units.
160
161
    Revealed from odd dimensionless units and ending up using numpy.ma math
162
    functions instead of numpy ones.
163
    """
164
    assert_almost_equal(dewpoint(15825.6 * units('g * mbar / kg')),
165
                        13.8564 * units.degC, 4)
166
167
168
def test_mixing_ratio():
169
    """Test mixing ratio calculation."""
170
    p = 998. * units.mbar
171
    e = 73.75 * units.mbar
172
    assert_almost_equal(mixing_ratio(e, p), 0.04963, 2)
173
174
175
def test_vapor_pressure():
176
    """Test vapor pressure calculation."""
177
    assert_almost_equal(vapor_pressure(998. * units.mbar, 0.04963),
178
                        73.74925 * units.mbar, 5)
179 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
180
181
def test_lcl():
182
    """Test LCL calculation."""
183
    lcl_pressure, lcl_temperature = lcl(1000. * units.mbar, 30. * units.degC, 20. * units.degC)
184
    assert_almost_equal(lcl_pressure, 864.761 * units.mbar, 2)
185
    assert_almost_equal(lcl_temperature, 17.676 * units.degC, 2)
186
187
188
def test_lcl_convergence():
189
    """Test LCL calculation convergence failure."""
190
    with pytest.raises(RuntimeError):
191
        lcl(1000. * units.mbar, 30. * units.degC, 20. * units.degC, max_iters=2)
192
193
194
def test_lfc_basic():
195
    """Test LFC calculation."""
196
    levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
197
    temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -49.]) * units.celsius
198
    dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
199
    l = lfc(levels, temperatures, dewpoints)
200
    assert_almost_equal(l[0], 727.468 * units.mbar, 2)
201
    assert_almost_equal(l[1], 9.705 * units.celsius, 2)
202
203
204
def test_no_lfc():
205
    """Test LFC calculation when there is no LFC in the data."""
206
    levels = np.array([959., 867.9, 779.2, 647.5, 472.5, 321.9, 251.]) * units.mbar
207
    temperatures = np.array([22.2, 17.4, 14.6, 1.4, -17.6, -39.4, -52.5]) * units.celsius
208
    dewpoints = np.array([9., 4.3, -21.2, -26.7, -31., -53.3, -66.7]) * units.celsius
209
    lfc_pressure, lfc_temperature = lfc(levels, temperatures, dewpoints)
210
    assert assert_nan(lfc_pressure, levels.units)
211
    assert assert_nan(lfc_temperature, temperatures.units)
212
213
214
def test_lfc_inversion():
215
    """Test LFC when there is an inversion to be sure we don't pick that."""
216
    levels = np.array([963., 789., 782.3, 754.8, 728.1, 727., 700.,
217
                       571., 450., 300., 248.]) * units.mbar
218
    temperatures = np.array([25.4, 18.4, 17.8, 15.4, 12.9, 12.8,
219
                             10., -3.9, -16.3, -41.1, -51.5]) * units.celsius
220
    dewpoints = np.array([20.4, 0.4, -0.5, -4.3, -8., -8.2, -9.,
221
                          -23.9, -33.3, -54.1, -63.5]) * units.celsius
222
    l = lfc(levels, temperatures, dewpoints)
223
    assert_almost_equal(l[0], 706.0103 * units.mbar, 2)
224
    assert_almost_equal(l[1], 10.6232 * units.celsius, 2)
225
226
227
def test_lfc_equals_lcl():
228
    """Test LFC when there is no cap and the lfc is equal to the lcl."""
229
    levels = np.array([912., 905.3, 874.4, 850., 815.1, 786.6, 759.1,
230
                       748., 732.2, 700., 654.8]) * units.mbar
231
    temperatures = np.array([29.4, 28.7, 25.2, 22.4, 19.4, 16.8,
232
                             14.3, 13.2, 12.6, 11.4, 7.1]) * units.celsius
233
    dewpoints = np.array([18.4, 18.1, 16.6, 15.4, 13.2, 11.4, 9.6,
234
                          8.8, 0., -18.6, -22.9]) * units.celsius
235
    l = lfc(levels, temperatures, dewpoints)
236
    assert_almost_equal(l[0], 777.0333 * units.mbar, 2)
237
    assert_almost_equal(l[1], 15.8714 * units.celsius, 2)
238
239
240
def test_lfc_sfc_precision():
241
    """Test LFC when there are precision issues with the parcel path."""
242
    levels = np.array([839., 819.4, 816., 807., 790.7, 763., 736.2,
243
                       722., 710.1, 700.]) * units.mbar
244
    temperatures = np.array([20.6, 22.3, 22.6, 22.2, 20.9, 18.7, 16.4,
245
                             15.2, 13.9, 12.8]) * units.celsius
246
    dewpoints = np.array([10.6, 8., 7.6, 6.2, 5.7, 4.7, 3.7, 3.2, 3., 2.8]) * units.celsius
247
    l = lfc(levels, temperatures, dewpoints)
248
    assert assert_nan(l[0], levels.units)
249
    assert assert_nan(l[1], temperatures.units)
250
251
252
def test_saturation_mixing_ratio():
253
    """Test saturation mixing ratio calculation."""
254
    p = 999. * units.mbar
255
    t = 288. * units.kelvin
256
    assert_almost_equal(saturation_mixing_ratio(p, t), .01068, 3)
257
258
259
def test_equivalent_potential_temperature():
260
    """Test equivalent potential temperature calculation."""
261
    p = 1000 * units.mbar
262
    t = 293. * units.kelvin
263
    td = 280. * units.kelvin
264
    ept = equivalent_potential_temperature(p, t, td)
265
    assert_almost_equal(ept, 311.18586467284007 * units.kelvin, 3)
266
267
268
def test_virtual_temperature():
269
    """Test virtual temperature calculation."""
270
    t = 288. * units.kelvin
271
    qv = .0016  # kg/kg
272
    tv = virtual_temperature(t, qv)
273
    assert_almost_equal(tv, 288.2796 * units.kelvin, 3)
274
275
276
def test_virtual_potential_temperature():
277
    """Test virtual potential temperature calculation."""
278
    p = 999. * units.mbar
279
    t = 288. * units.kelvin
280
    qv = .0016  # kg/kg
281
    theta_v = virtual_potential_temperature(p, t, qv)
282
    assert_almost_equal(theta_v, 288.3620 * units.kelvin, 3)
283
284
285
def test_density():
286
    """Test density calculation."""
287
    p = 999. * units.mbar
288
    t = 288. * units.kelvin
289
    qv = .0016  # kg/kg
290
    rho = density(p, t, qv).to(units.kilogram / units.meter ** 3)
291
    assert_almost_equal(rho, 1.2072 * (units.kilogram / units.meter ** 3), 3)
292
293
294
def test_el():
295
    """Test equilibrium layer calculation."""
296
    levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
297
    temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.celsius
298
    dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
299
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
300
    assert_almost_equal(el_pressure, 520.8700 * units.mbar, 3)
301
    assert_almost_equal(el_temperature, -11.7027 * units.degC, 3)
302
303
304
def test_no_el():
305
    """Test equilibrium layer calculation when there is no EL in the data."""
306
    levels = np.array([959., 867.9, 779.2, 647.5, 472.5, 321.9, 251.]) * units.mbar
307
    temperatures = np.array([22.2, 17.4, 14.6, 1.4, -17.6, -39.4, -52.5]) * units.celsius
308
    dewpoints = np.array([19., 14.3, -11.2, -16.7, -21., -43.3, -56.7]) * units.celsius
309
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
310
    assert assert_nan(el_pressure, levels.units)
311
    assert assert_nan(el_temperature, temperatures.units)
312
313
314
def test_no_el_multi_crossing():
315
    """Test el calculation with no el and severel parcel path-profile crossings."""
316
    levels = np.array([918., 911., 880., 873.9, 850., 848., 843.5, 818., 813.8, 785.,
317
                       773., 763., 757.5, 730.5, 700., 679., 654.4, 645.,
318
                       643.9]) * units.mbar
319
    temperatures = np.array([24.2, 22.8, 19.6, 19.1, 17., 16.8, 16.5, 15., 14.9, 14.4, 16.4,
320
                             16.2, 15.7, 13.4, 10.6, 8.4, 5.7, 4.6, 4.5]) * units.celsius
321
    dewpoints = np.array([19.5, 17.8, 16.7, 16.5, 15.8, 15.7, 15.3, 13.1, 12.9, 11.9, 6.4,
322
                          3.2, 2.6, -0.6, -4.4, -6.6, -9.3, -10.4, -10.5]) * units.celsius
323
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
324
    assert assert_nan(el_pressure, levels.units)
325
    assert assert_nan(el_temperature, temperatures.units)
326
327
328
def test_el_lfc_equals_lcl():
329
    """Test equilibrium layer calculation when the lfc equals the lcl."""
330
    levels = np.array([912., 905.3, 874.4, 850., 815.1, 786.6, 759.1, 748.,
331
                       732.3, 700., 654.8, 606.8, 562.4, 501.8, 500., 482.,
332
                       400., 393.3, 317.1, 307., 300., 252.7, 250., 200.,
333
                       199.3, 197., 190., 172., 156.6, 150., 122.9, 112.,
334
                       106.2, 100.]) * units.mbar
335
    temperatures = np.array([29.4, 28.7, 25.2, 22.4, 19.4, 16.8, 14.3,
336
                             13.2, 12.6, 11.4, 7.1, 2.2, -2.7, -10.1,
337
                             -10.3, -12.4, -23.3, -24.4, -38., -40.1, -41.1,
338
                             -49.8, -50.3, -59.1, -59.1, -59.3, -59.7, -56.3,
339
                             -56.9, -57.1, -59.1, -60.1, -58.6, -56.9]) * units.celsius
340
    dewpoints = np.array([18.4, 18.1, 16.6, 15.4, 13.2, 11.4, 9.6, 8.8, 0.,
341
                          -18.6, -22.9, -27.8, -32.7, -40.1, -40.3, -42.4, -53.3,
342
                          -54.4, -68., -70.1, -70., -70., -70., -70., -70., -70.,
343
                          -70., -70., -70., -70., -70., -70., -70., -70.]) * units.celsius
344
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
345
    assert_almost_equal(el_pressure, 175.8684 * units.mbar, 3)
346
    assert_almost_equal(el_temperature, -57.0307 * units.degC, 3)
347
348
349
def test_wet_psychrometric_vapor_pressure():
350
    """Test calculation of vapor pressure from wet and dry bulb temperatures."""
351
    p = 1013.25 * units.mbar
352
    dry_bulb_temperature = 20. * units.degC
353
    wet_bulb_temperature = 18. * units.degC
354
    psychrometric_vapor_pressure = psychrometric_vapor_pressure_wet(dry_bulb_temperature,
355
                                                                    wet_bulb_temperature, p)
356
    assert_almost_equal(psychrometric_vapor_pressure, 19.3673 * units.mbar, 3)
357
358
359
def test_wet_psychrometric_rh():
360
    """Test calculation of relative humidity from wet and dry bulb temperatures."""
361
    p = 1013.25 * units.mbar
362
    dry_bulb_temperature = 20. * units.degC
363
    wet_bulb_temperature = 18. * units.degC
364 View Code Duplication
    psychrometric_rh = relative_humidity_wet_psychrometric(dry_bulb_temperature,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
365
                                                           wet_bulb_temperature, p)
366
    assert_almost_equal(psychrometric_rh, 82.8747 * units.percent, 3)
367
368
369
def test_wet_psychrometric_rh_kwargs():
370
    """Test calculation of relative humidity from wet and dry bulb temperatures."""
371
    p = 1013.25 * units.mbar
372
    dry_bulb_temperature = 20. * units.degC
373
    wet_bulb_temperature = 18. * units.degC
374
    coeff = 6.1e-4 / units.kelvin
375
    psychrometric_rh = relative_humidity_wet_psychrometric(dry_bulb_temperature,
376
                                                           wet_bulb_temperature, p,
377
                                                           psychrometer_coefficient=coeff)
378
    assert_almost_equal(psychrometric_rh, 82.9701 * units.percent, 3)
379
380
381
def test_rh_mixing_ratio():
382
    """Tests relative humidity from mixing ratio."""
383
    p = 1013.25 * units.mbar
384
    temperature = 20. * units.degC
385
    w = 0.012
386 View Code Duplication
    rh = relative_humidity_from_mixing_ratio(w, temperature, p)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
387
    assert_almost_equal(rh, 81.7219 * units.percent, 3)
388
389
390
def test_mixing_ratio_from_specific_humidity():
391
    """Tests mixing ratio from specific humidity."""
392
    q = 0.012
393
    w = mixing_ratio_from_specific_humidity(q)
394
    assert_almost_equal(w, 0.01215, 3)
395
396
397
def test_rh_specific_humidity():
398
    """Tests relative humidity from specific humidity."""
399
    p = 1013.25 * units.mbar
400
    temperature = 20. * units.degC
401
    q = 0.012
402
    rh = relative_humidity_from_specific_humidity(q, temperature, p)
403
    assert_almost_equal(rh, 82.7145 * units.percent, 3)
404
405
406
def test_cape_cin():
407
    """Tests the basic CAPE and CIN calculation."""
408
    p = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
409
    temperature = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.celsius
410 View Code Duplication
    dewpoint = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
411
    parcel_prof = parcel_profile(p, temperature[0], dewpoint[0])
412
    cape, cin = cape_cin(p, temperature, dewpoint, parcel_prof)
413
    assert_almost_equal(cape, 58.0368212 * units('joule / kilogram'), 6)
414
    assert_almost_equal(cin, -89.8073512 * units('joule / kilogram'), 6)
415
416
417
def test_cape_cin_no_el():
418
    """Tests that CAPE works with no EL."""
419
    p = np.array([959., 779.2, 751.3, 724.3]) * units.mbar
420
    temperature = np.array([22.2, 14.6, 12., 9.4]) * units.celsius
421
    dewpoint = np.array([19., -11.2, -10.8, -10.4]) * units.celsius
422
    parcel_prof = parcel_profile(p, temperature[0], dewpoint[0]).to('degC')
423
    cape, cin = cape_cin(p, temperature, dewpoint, parcel_prof)
424
    assert_almost_equal(cape, 0.08750805 * units('joule / kilogram'), 6)
425
    assert_almost_equal(cin, -89.8073512 * units('joule / kilogram'), 6)
426
427
428
def test_cape_cin_no_lfc():
429
    """Tests that CAPE is zero with no LFC."""
430
    p = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
431
    temperature = np.array([22.2, 24.6, 22., 20.4, 18., -10.]) * units.celsius
432
    dewpoint = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
433
    parcel_prof = parcel_profile(p, temperature[0], dewpoint[0]).to('degC')
434
    cape, cin = cape_cin(p, temperature, dewpoint, parcel_prof)
435
    assert_almost_equal(cape, 0.0 * units('joule / kilogram'), 6)
436
    assert_almost_equal(cin, 0.0 * units('joule / kilogram'), 6)
437 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
438
439
def test_find_append_zero_crossings():
440
    """Tests finding and appending zero crossings of an x, y series."""
441
    x = np.arange(11) * units.hPa
442
    y = np.array([3, 2, 1, -1, 2, 2, 0, 1, 0, -1, 2]) * units.degC
443
    x2, y2 = _find_append_zero_crossings(x, y)
444
445
    x_truth = np.array([0., 1., 2., 2.5, 3., 3.33333333, 4., 5.,
446
                        6., 7., 8., 9., 9.33333333, 10.]) * units.hPa
447
    y_truth = np.array([3, 2, 1, 0, -1, 0, 2, 2, 0, 1, 0, -1, 0, 2]) * units.degC
448
    assert_array_almost_equal(x2, x_truth, 6)
449
    assert_almost_equal(y2, y_truth, 6)
450
451
452
def test_most_unstable_parcel():
453 View Code Duplication
    """Tests calculating the most unstable parcel."""
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
454
    levels = np.array([1000., 959., 867.9]) * units.mbar
455
    temperatures = np.array([18.2, 22.2, 17.4]) * units.celsius
456
    dewpoints = np.array([19., 19., 14.3]) * units.celsius
457
    ret = most_unstable_parcel(levels, temperatures, dewpoints, depth=100 * units.hPa)
458
    assert_almost_equal(ret[0], 959.0 * units.hPa, 6)
459
    assert_almost_equal(ret[1], 22.2 * units.degC, 6)
460
    assert_almost_equal(ret[2], 19.0 * units.degC, 6)
461
462
463
def test_isentropic_pressure():
464
    """Test calculation of isentropic pressure function."""
465
    lev = [100000., 95000., 90000., 85000.] * units.Pa
466
    tmp = np.ones((4, 5, 5))
467
    tmp[0, :] = 296.
468 View Code Duplication
    tmp[1, :] = 292.
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
469
    tmp[2, :] = 290
470
    tmp[3, :] = 288.
471
    tmpk = tmp * units.kelvin
472
    isentlev = [296.] * units.kelvin
473
    isentprs = isentropic_interpolation(isentlev, lev, tmpk)
474
    trueprs = 1000. * units.hPa
475
    assert_almost_equal(isentprs[0].shape, (1, 5, 5), 3)
476
    assert_almost_equal(isentprs[0], trueprs, 3)
477
478
479
def test_isentropic_pressure_p_increase():
480
    """Test calculation of isentropic pressure function, p increasing order."""
481
    lev = [85000, 90000., 95000., 100000.] * units.Pa
482
    tmp = np.ones((4, 5, 5))
483
    tmp[0, :] = 288.
484
    tmp[1, :] = 290.
485
    tmp[2, :] = 292.
486
    tmp[3, :] = 296.
487
    tmpk = tmp * units.kelvin
488
    isentlev = [296.] * units.kelvin
489 View Code Duplication
    isentprs = isentropic_interpolation(isentlev, lev, tmpk)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
490
    trueprs = 1000. * units.hPa
491
    assert_almost_equal(isentprs[0], trueprs, 3)
492
493
494
def test_isentropic_pressure_adition_args():
495
    """Test calculation of isentropic pressure function, additional args."""
496
    lev = [100000., 95000., 90000., 85000.] * units.Pa
497
    tmp = np.ones((4, 5, 5))
498
    tmp[0, :] = 296.
499
    tmp[1, :] = 292.
500
    tmp[2, :] = 290.
501
    tmp[3, :] = 288.
502
    rh = np.ones((4, 5, 5))
503
    rh[0, :] = 100.
504 View Code Duplication
    rh[1, :] = 80.
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
505
    rh[2, :] = 40.
506
    rh[3, :] = 20.
507
    relh = rh * units.percent
508
    tmpk = tmp * units.kelvin
509
    isentlev = [296.] * units.kelvin
510
    isentprs = isentropic_interpolation(isentlev, lev, tmpk, relh)
511
    truerh = 100. * units.percent
512
    assert_almost_equal(isentprs[1], truerh, 3)
513
514
515
def test_isentropic_pressure_tmp_out():
516
    """Test calculation of isentropic pressure function, temperature output."""
517
    lev = [100000., 95000., 90000., 85000.] * units.Pa
518
    tmp = np.ones((4, 5, 5))
519
    tmp[0, :] = 296.
520
    tmp[1, :] = 292.
521
    tmp[2, :] = 290.
522
    tmp[3, :] = 288.
523
    tmpk = tmp * units.kelvin
524
    isentlev = [296.] * units.kelvin
525 View Code Duplication
    isentprs = isentropic_interpolation(isentlev, lev, tmpk, tmpk_out=True)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
526
    truetmp = 296. * units.kelvin
527
    assert_almost_equal(isentprs[1], truetmp, 3)
528
529
530
def test_isentropic_pressure_p_increase_rh_out():
531
    """Test calculation of isentropic pressure function, p increasing order."""
532
    lev = [85000., 90000., 95000., 100000.] * units.Pa
533
    tmp = np.ones((4, 5, 5))
534
    tmp[0, :] = 288.
535
    tmp[1, :] = 290.
536
    tmp[2, :] = 292.
537
    tmp[3, :] = 296.
538
    tmpk = tmp * units.kelvin
539
    rh = np.ones((4, 5, 5))
540 View Code Duplication
    rh[0, :] = 20.
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
541
    rh[1, :] = 40.
542
    rh[2, :] = 80.
543
    rh[3, :] = 100.
544
    relh = rh * units.percent
545
    isentlev = 296. * units.kelvin
546
    isentprs = isentropic_interpolation(isentlev, lev, tmpk, relh)
547
    truerh = 100. * units.percent
548
    assert_almost_equal(isentprs[1], truerh, 3)
549
550
551
def test_isentropic_pressure_interp():
552
    """Test calculation of isentropic pressure function."""
553
    lev = [100000., 95000., 90000., 85000.] * units.Pa
554
    tmp = np.ones((4, 5, 5))
555
    tmp[0, :] = 296.
556
    tmp[1, :] = 292.
557
    tmp[2, :] = 290
558
    tmp[3, :] = 288.
559
    tmpk = tmp * units.kelvin
560
    isentlev = [296., 297] * units.kelvin
561 View Code Duplication
    isentprs = isentropic_interpolation(isentlev, lev, tmpk)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
562
    trueprs = 936.18057 * units.hPa
563
    assert_almost_equal(isentprs[0][1], trueprs, 3)
564
565
566
def test_isentropic_pressure_adition_args_interp():
567
    """Test calculation of isentropic pressure function, additional args."""
568
    lev = [100000., 95000., 90000., 85000.] * units.Pa
569
    tmp = np.ones((4, 5, 5))
570
    tmp[0, :] = 296.
571
    tmp[1, :] = 292.
572
    tmp[2, :] = 290.
573
    tmp[3, :] = 288.
574
    rh = np.ones((4, 5, 5))
575
    rh[0, :] = 100.
576
    rh[1, :] = 80.
577
    rh[2, :] = 40.
578
    rh[3, :] = 20.
579
    relh = rh * units.percent
580
    tmpk = tmp * units.kelvin
581
    isentlev = [296., 297.] * units.kelvin
582
    isentprs = isentropic_interpolation(isentlev, lev, tmpk, relh)
583
    truerh = 69.171 * units.percent
584
    assert_almost_equal(isentprs[1][1], truerh, 3)
585
586
587
def test_isentropic_pressure_tmp_out_interp():
588
    """Test calculation of isentropic pressure function, temperature output."""
589
    lev = [100000., 95000., 90000., 85000.] * units.Pa
590
    tmp = np.ones((4, 5, 5))
591
    tmp[0, :] = 296.
592
    tmp[1, :] = 292.
593
    tmp[2, :] = 290.
594
    tmp[3, :] = 288.
595
    tmpk = tmp * units.kelvin
596
    isentlev = [296., 297.] * units.kelvin
597
    isentprs = isentropic_interpolation(isentlev, lev, tmpk, tmpk_out=True)
598
    truetmp = 291.4579 * units.kelvin
599
    assert_almost_equal(isentprs[1][1], truetmp, 3)
600
601
602
def test_isentropic_pressure_data_bounds_error():
603
    """Test calculation of isentropic pressure function, error for data out of bounds."""
604
    lev = [100000., 95000., 90000., 85000.] * units.Pa
605
    tmp = np.ones((4, 5, 5))
606
    tmp[0, :] = 296.
607
    tmp[1, :] = 292.
608
    tmp[2, :] = 290.
609
    tmp[3, :] = 288.
610
    tmpk = tmp * units.kelvin
611
    isentlev = [296., 350.] * units.kelvin
612
    with pytest.raises(ValueError):
613
        isentropic_interpolation(isentlev, lev, tmpk)
614
615
616
def test_isentropic_pressure_4d():
617
    """Test calculation of isentropic pressure function."""
618
    lev = [100000., 95000., 90000., 85000.] * units.Pa
619
    tmp = np.ones((3, 4, 5, 5))
620
    tmp[:, 0, :] = 296.
621
    tmp[:, 1, :] = 292.
622
    tmp[:, 2, :] = 290
623
    tmp[:, 3, :] = 288.
624
    tmpk = tmp * units.kelvin
625
    rh = np.ones((3, 4, 5, 5))
626
    rh[:, 0, :] = 100.
627
    rh[:, 1, :] = 80.
628
    rh[:, 2, :] = 40.
629
    rh[:, 3, :] = 20.
630
    relh = rh * units.percent
631
    isentlev = [296., 297., 300.] * units.kelvin
632
    isentprs = isentropic_interpolation(isentlev, lev, tmpk, relh, axis=1)
633
    trueprs = 1000. * units.hPa
634
    trueprs2 = 936.18057 * units.hPa
635
    trueprs3 = 879.446 * units.hPa
636
    truerh = 69.171 * units.percent
637
    assert_almost_equal(isentprs[0].shape, (3, 3, 5, 5), 3)
638
    assert_almost_equal(isentprs[0][:, 0, :], trueprs, 3)
639
    assert_almost_equal(isentprs[0][:, 1, :], trueprs2, 3)
640
    assert_almost_equal(isentprs[0][:, 2, :], trueprs3, 3)
641
    assert_almost_equal(isentprs[1][:, 1, ], truerh, 3)
642
643
644
def test_most_unstable_cape_cin_surface():
645
    """Tests the most unstable CAPE/CIN calculation when surface is most unstable."""
646
    pressure = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
647
    temperature = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.celsius
648
    dewpoint = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
649
    mucape, mucin = most_unstable_cape_cin(pressure, temperature, dewpoint)
650
    assert_almost_equal(mucape, 58.0368212 * units('joule / kilogram'), 6)
651
    assert_almost_equal(mucin, -89.8073512 * units('joule / kilogram'), 6)
652
653
654
def test_most_unstable_cape_cin():
655
    """Tests the most unstable CAPE/CIN calculation."""
656
    pressure = np.array([1000., 959., 867.9, 850., 825., 800.]) * units.mbar
657
    temperature = np.array([18.2, 22.2, 17.4, 10., 0., 15]) * units.celsius
658
    dewpoint = np.array([19., 19., 14.3, 0., -10., 0.]) * units.celsius
659
    mucape, mucin = most_unstable_cape_cin(pressure, temperature, dewpoint)
660
    assert_almost_equal(mucape, 157.07111 * units('joule / kilogram'), 4)
661
    assert_almost_equal(mucin, -15.74772 * units('joule / kilogram'), 4)
662