Skip to content

Commit e3faaad

Browse files
authored
fix bug in get_relative_airmass(model=youngirvine1967). improve test_atmosphere (#546)
* ignore vscode * improve atmo tests. fix youngirvine1967 * change pandas testing import
1 parent 23b97c2 commit e3faaad

File tree

3 files changed

+53
-43
lines changed

3 files changed

+53
-43
lines changed

docs/sphinx/source/whatsnew/v0.6.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ Bug fixes
125125
by lonlat bounding box (:issue:`521`)
126126
* Fix issue with unbounded clearness index calculation in disc. (:issue:`540`)
127127
* Limit pvwatts_ac results to be greater than or equal to 0. (:issue:`541`)
128+
* Fix bug in get_relative_airmass(model='youngirvine1967'). (:issue:`545`)
128129

129130

130131
Documentation
@@ -155,6 +156,7 @@ Testing
155156
* Use pytest-mock to ensure that ModelChain DC model is set up correctly.
156157
* Add Python 3.7 to build matrix
157158
* Make test_forecast.py more robust. (:issue:`293`)
159+
* Improve test_atmosphere.py. (:issue:`158`)
158160

159161

160162
Contributors

pvlib/atmosphere.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ def get_relative_airmass(zenith, model='kastenyoung1989'):
229229
am = (1.0 / (np.sin(np.radians(90 - z +
230230
244.0 / (165 + 47.0 * (90 - z) ** 1.1)))))
231231
elif 'youngirvine1967' == model:
232-
am = ((1.0 / np.cos(zenith_rad)) *
233-
(1 - 0.0012*((1.0 / np.cos(zenith_rad)) ** 2) - 1))
232+
sec_zen = 1.0 / np.cos(zenith_rad)
233+
am = sec_zen * (1 - 0.0012 * (sec_zen * sec_zen - 1))
234234
elif 'young1994' == model:
235235
am = ((1.002432*((np.cos(zenith_rad)) ** 2) +
236236
0.148386*(np.cos(zenith_rad)) + 0.0096467) /

pvlib/test/test_atmosphere.py

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,77 @@
11
import itertools
22

33
import numpy as np
4+
from numpy import nan
45
from numpy.testing import assert_allclose
56
import pandas as pd
7+
from pandas.util.testing import assert_series_equal
68
import pytest
79

810
from pvlib import atmosphere
9-
from pvlib import solarposition
1011
from pvlib._deprecation import pvlibDeprecationWarning
1112

1213
from conftest import fail_on_pvlib_version
1314

14-
latitude, longitude, tz, altitude = 32.2, -111, 'US/Arizona', 700
15-
16-
times = pd.date_range(start='20140626', end='20140626', freq='6h', tz=tz)
17-
18-
ephem_data = solarposition.get_solarposition(times, latitude, longitude)
19-
20-
21-
# need to add physical tests instead of just functional tests
2215

2316
def test_pres2alt():
24-
atmosphere.pres2alt(100000)
25-
26-
27-
def test_alt2press():
28-
atmosphere.pres2alt(1000)
29-
30-
31-
@pytest.mark.parametrize("model",
32-
['simple', 'kasten1966', 'youngirvine1967', 'kastenyoung1989',
33-
'gueymard1993', 'young1994', 'pickering2002'])
34-
def test_airmass(model):
35-
out = atmosphere.get_relative_airmass(ephem_data['zenith'], model)
36-
assert isinstance(out, pd.Series)
37-
out = atmosphere.get_relative_airmass(ephem_data['zenith'].values, model)
38-
assert isinstance(out, np.ndarray)
17+
out = atmosphere.pres2alt(np.array([10000, 90000, 101325]))
18+
expected = np.array([15797.638, 988.637, 0.124])
19+
assert_allclose(out, expected, atol=0.001)
20+
21+
22+
def test_alt2pres():
23+
out = atmosphere.alt2pres(np.array([-100, 0, 1000, 8000]))
24+
expected = np.array([102532.073, 101324.999, 89874.750, 35600.496])
25+
assert_allclose(out, expected, atol=0.001)
26+
27+
28+
@pytest.fixture
29+
def zeniths():
30+
return np.array([100, 89.9, 80, 0])
31+
32+
33+
@pytest.mark.parametrize("model,expected",
34+
[['simple', [nan, 572.958, 5.759, 1.000]],
35+
['kasten1966', [nan, 35.365, 5.580, 0.999]],
36+
['youngirvine1967', [
37+
nan, -2.251358367165932e+05, 5.5365, 1.0000]],
38+
['kastenyoung1989', [nan, 36.467, 5.586, 1.000]],
39+
['gueymard1993', [nan, 36.431, 5.581, 1.000]],
40+
['young1994', [nan, 30.733, 5.541, 1.000]],
41+
['pickering2002', [nan, 37.064, 5.581, 1.000]]])
42+
def test_airmass(model, expected, zeniths):
43+
out = atmosphere.get_relative_airmass(zeniths, model)
44+
expected = np.array(expected)
45+
assert_allclose(out, expected, equal_nan=True, atol=0.001)
46+
# test series in/out. index does not matter
47+
# hits the isinstance() block in get_relative_airmass
48+
times = pd.DatetimeIndex(start='20180101', periods=len(zeniths), freq='1s')
49+
zeniths = pd.Series(zeniths, index=times)
50+
expected = pd.Series(expected, index=times)
51+
out = atmosphere.get_relative_airmass(zeniths, model)
52+
assert_series_equal(out, expected, check_less_precise=True)
3953

4054

4155
def test_airmass_scalar():
4256
assert not np.isnan(atmosphere.get_relative_airmass(10))
4357

4458

45-
def test_airmass_scalar_nan():
46-
assert np.isnan(atmosphere.get_relative_airmass(100))
47-
48-
4959
def test_airmass_invalid():
5060
with pytest.raises(ValueError):
51-
atmosphere.get_relative_airmass(ephem_data['zenith'], 'invalid')
61+
atmosphere.get_relative_airmass(0, 'invalid')
5262

5363

5464
def test_get_absolute_airmass():
55-
relative_am = atmosphere.get_relative_airmass(ephem_data['zenith'],
56-
'simple')
57-
atmosphere.get_absolute_airmass(relative_am)
58-
atmosphere.get_absolute_airmass(relative_am, pressure=100000)
59-
60-
61-
def test_get_absolute_airmass_numeric():
62-
atmosphere.get_absolute_airmass(2)
63-
64-
65-
def test_get_absolute_airmass_nan():
66-
np.testing.assert_equal(np.nan, atmosphere.get_absolute_airmass(np.nan))
65+
# input am
66+
relative_am = np.array([nan, 40, 2, .999])
67+
# call without pressure kwarg
68+
out = atmosphere.get_absolute_airmass(relative_am)
69+
expected = np.array([nan, 40., 2., 0.999])
70+
assert_allclose(out, expected, equal_nan=True, atol=0.001)
71+
# call with pressure kwarg
72+
out = atmosphere.get_absolute_airmass(relative_am, pressure=90000)
73+
expected = np.array([nan, 35.529, 1.776, 0.887])
74+
assert_allclose(out, expected, equal_nan=True, atol=0.001)
6775

6876

6977
@fail_on_pvlib_version('0.7')

0 commit comments

Comments
 (0)