Skip to content

Commit 6c472c2

Browse files
committed
add tests. coerce pw to min 0.2
1 parent 2e38def commit 6c472c2

File tree

2 files changed

+126
-33
lines changed

2 files changed

+126
-33
lines changed

pvlib/clearsky.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ def simplified_solis(apparent_elevation, aod700=0.1, precipitable_water=1.,
351351
precipitable_water: numeric
352352
The precipitable water of the atmosphere (cm).
353353
Algorithm derived for values between 0.2 and 10 cm.
354+
Values less than 0.2 will be assumed to be equal to 0.2.
354355
355356
pressure: numeric
356357
The atmospheric pressure (Pascals).
@@ -382,25 +383,31 @@ def simplified_solis(apparent_elevation, aod700=0.1, precipitable_water=1.,
382383
"""
383384

384385
p = pressure
385-
p0 = 101325.
386386

387387
w = precipitable_water
388388

389+
# algorithm fails for pw < 0.2
390+
if np.isscalar(w):
391+
w = 0.2 if w < 0.2 else w
392+
else:
393+
w = w.copy()
394+
w[w < 0.2] = 0.2
395+
389396
# this algorithm is reasonably fast already, but it could be made
390397
# faster by precalculating the powers of aod700, the log(p/p0), and
391398
# the log(w) instead of repeating the calculations as needed in each
392399
# function
393400

394-
i0p = _calc_i0p(dni_extra, w, aod700, p, p0)
401+
i0p = _calc_i0p(dni_extra, w, aod700, p)
395402

396-
taub = _calc_taub(w, aod700, p, p0)
403+
taub = _calc_taub(w, aod700, p)
397404
b = _calc_b(w, aod700)
398405

399-
taug = _calc_taug(w, aod700, p, p0)
406+
taug = _calc_taug(w, aod700, p)
400407
g = _calc_g(w, aod700)
401408

402-
taud = _calc_taud(w, aod700, p, p0)
403-
d = _calc_d(w, aod700, p, p0)
409+
taud = _calc_taud(w, aod700, p)
410+
d = _calc_d(w, aod700, p)
404411

405412
sin_elev = np.sin(np.radians(apparent_elevation))
406413

@@ -430,8 +437,9 @@ def simplified_solis(apparent_elevation, aod700=0.1, precipitable_water=1.,
430437
return irrads
431438

432439

433-
def _calc_i0p(i0, w, aod700, p, p0):
440+
def _calc_i0p(i0, w, aod700, p):
434441
"""Calculate the "enhanced extraterrestrial irradiance"."""
442+
p0 = 101325.
435443
io0 = 1.08 * w**0.0051
436444
i01 = 0.97 * w**0.032
437445
i02 = 0.12 * w**0.56
@@ -440,9 +448,9 @@ def _calc_i0p(i0, w, aod700, p, p0):
440448
return i0p
441449

442450

443-
def _calc_taub(w, aod700, p, p0):
451+
def _calc_taub(w, aod700, p):
444452
"""Calculate the taub coefficient"""
445-
453+
p0 = 101325.
446454
tb1 = 1.82 + 0.056*np.log(w) + 0.0071*np.log(w)**2
447455
tb0 = 0.33 + 0.045*np.log(w) + 0.0096*np.log(w)**2
448456
tbp = 0.0089*w + 0.13
@@ -463,9 +471,9 @@ def _calc_b(w, aod700):
463471
return b
464472

465473

466-
def _calc_taug(w, aod700, p, p0):
474+
def _calc_taug(w, aod700, p):
467475
"""Calculate the taug coefficient"""
468-
476+
p0 = 101325.
469477
tg1 = 1.24 + 0.047*np.log(w) + 0.0061*np.log(w)**2
470478
tg0 = 0.27 + 0.043*np.log(w) + 0.0090*np.log(w)**2
471479
tgp = 0.0079*w + 0.1
@@ -482,17 +490,20 @@ def _calc_g(w, aod700):
482490
return g
483491

484492

485-
def _calc_taud(w, aod700, p, p0):
493+
def _calc_taud(w, aod700, p):
486494
"""Calculate the taud coefficient."""
487495

488496
# isscalar tests needed to ensure that the arrays will have the
489-
# right shape in the tds calculation
497+
# right shape in the tds calculation.
498+
# there's probably a better way to do this.
490499

491-
if np.isscalar(w):
500+
if np.isscalar(w) and np.isscalar(aod700):
492501
w = np.array([w])
493-
494-
if np.isscalar(aod700):
495502
aod700 = np.array([aod700])
503+
elif np.isscalar(w):
504+
w = np.full_like(aod700, w)
505+
elif np.isscalar(aod700):
506+
aod700 = np.full_like(w, aod700)
496507

497508
aod700_mask = aod700 < 0.05
498509
aod700_mask = np.array([aod700_mask, ~aod700_mask], dtype=np.int)
@@ -508,6 +519,7 @@ def _calc_taud(w, aod700, p, p0):
508519

509520
tds = (np.array([td0, td1, td2, td3, td4, tdp]) * aod700_mask).sum(axis=1)
510521

522+
p0 = 101325.
511523
taud = (tds[4]*aod700**4 + tds[3]*aod700**3 + tds[2]*aod700**2 +
512524
tds[1]*aod700 + tds[0] + tds[5]*np.log(p/p0))
513525

@@ -518,9 +530,10 @@ def _calc_taud(w, aod700, p, p0):
518530
return taud
519531

520532

521-
def _calc_d(w, aod700, p, p0):
533+
def _calc_d(w, aod700, p):
522534
"""Calculate the d coefficient."""
523535

536+
p0 = 101325.
524537
dp = 1/(18 + 152*aod700)
525538
d = -0.337*aod700**2 + 0.63*aod700 + 0.116 + dp*np.log(p/p0)
526539

pvlib/test/test_clearsky.py

Lines changed: 96 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -150,33 +150,113 @@ def test_haurwitz():
150150
assert_frame_equal(expected, out)
151151

152152

153-
def test_simplified_solis():
154-
clearsky.simplified_solis()
153+
def test_simplified_solis_series_elevation():
154+
expected = pd.DataFrame(
155+
np.array([[ 0. , 0. , 0. ],
156+
[ 0. , 0. , 0. ],
157+
[ 377.80060035, 79.91931339, 42.77453223],
158+
[ 869.47538184, 706.37903999, 110.05635962],
159+
[ 958.89448856, 1062.44821373, 129.02349236],
160+
[ 913.3209839 , 860.48978599, 118.94598678],
161+
[ 634.01066762, 256.00505836, 72.18396705],
162+
[ 0. , 0. , 0. ],
163+
[ 0. , 0. , 0. ]]),
164+
columns=['dni', 'ghi', 'dhi'],
165+
index=times_localized)
166+
167+
out = clearsky.simplified_solis(ephem_data['apparent_elevation'])
168+
assert_frame_equal(expected, out)
169+
170+
171+
def test_simplified_solis_scalar_elevation():
172+
expected = pd.DataFrame(np.array([[959.335463, 1064.653145, 129.125602]]),
173+
columns=['dni', 'ghi', 'dhi'])
174+
175+
out = clearsky.simplified_solis(80)
176+
assert_frame_equal(expected, out)
177+
178+
179+
def test_simplified_solis_array_elevation():
180+
expected = pd.DataFrame(np.array([[959.335463, 1064.653145, 129.125602]]),
181+
columns=['dni', 'ghi', 'dhi'])
182+
183+
out = clearsky.simplified_solis(np.array([80]))
184+
assert_frame_equal(expected, out)
185+
186+
187+
def test_simplified_solis_dni_extra():
188+
expected = pd.DataFrame(np.array([[963.555414, 1069.33637, 129.693603]]),
189+
columns=['dni', 'ghi', 'dhi'])
190+
191+
out = clearsky.simplified_solis(80, dni_extra=1370)
192+
assert_frame_equal(expected, out)
193+
155194

195+
def test_simplified_solis_pressure():
196+
expected = pd.DataFrame(np.
197+
array([[ 964.26930718, 1067.96543669, 127.22841797],
198+
[ 961.88811874, 1066.36847963, 128.1402539 ],
199+
[ 959.58112234, 1064.81837558, 129.0304193 ]]),
200+
columns=['dni', 'ghi', 'dhi'])
156201

157-
def test_calc_i0p():
158-
clearsky._calc_i0p(w, aod700, p, p0)
202+
out = clearsky.simplified_solis(
203+
80, pressure=np.array([95000, 98000, 101000]))
204+
assert_frame_equal(expected, out)
159205

160206

161-
def test_calc_taub():
162-
clearsky._calc_taub(w, aod700, p, p0)
207+
def test_simplified_solis_aod700():
208+
expected = pd.DataFrame(np.
209+
array([[ 1056.61710493, 1105.7229086 , 64.41747323],
210+
[ 1007.50558875, 1085.74139063, 102.96233698],
211+
[ 959.3354628 , 1064.65314509, 129.12560167],
212+
[ 342.45810926, 638.63409683, 77.71786575],
213+
[ 55.24140911, 7.5413313 , 0. ]]),
214+
columns=['dni', 'ghi', 'dhi'])
163215

216+
aod700 = np.array([0.0, 0.05, 0.1, 1, 10])
217+
out = clearsky.simplified_solis(80, aod700=aod700)
218+
assert_frame_equal(expected, out)
164219

165-
def test_calc_b():
166-
clearsky._calc_b(w, aod700, p, p0)
220+
221+
def test_simplified_solis_precipitable_water():
222+
expected = pd.DataFrame(np.
223+
array([[ 1001.15353307, 1107.84678941, 128.58887606],
224+
[ 1001.15353307, 1107.84678941, 128.58887606],
225+
[ 983.51027357, 1089.62306672, 129.08755996],
226+
[ 959.3354628 , 1064.65314509, 129.12560167],
227+
[ 872.02335029, 974.18046717, 125.63581346]]),
228+
columns=['dni', 'ghi', 'dhi'])
229+
230+
out = clearsky.simplified_solis(
231+
80, precipitable_water=pd.Series([0.0, 0.2, 0.5, 1.0, 5.0]))
232+
assert_frame_equal(expected, out)
233+
234+
235+
def test_simplified_solis_small_scalar_pw():
236+
expected = pd.DataFrame(np.
237+
array([[ 1001.15353307, 1107.84678941, 128.58887606]]),
238+
columns=['dni', 'ghi', 'dhi'])
239+
240+
out = clearsky.simplified_solis(80, precipitable_water=0.1)
241+
assert_frame_equal(expected, out)
167242

168243

169-
def test_calc_taug():
170-
clearsky._calc_taug(w, aod700, p, p0)
244+
def test_simplified_solis_return_raw():
245+
expected = np.array([[[ 1099.25706525, 656.24601381],
246+
[ 915.31689149, 530.31697378]],
171247

248+
[[ 1148.40081325, 913.42330823],
249+
[ 965.48550828, 760.04527609]],
172250

173-
def test_calc_g():
174-
clearsky._calc_g(w, aod700, p, p0)
251+
[[ 64.1063074 , 254.6186615 ],
252+
[ 62.75642216, 232.21931597]]])
175253

254+
aod700 = np.linspace(0, 0.5, 2)
255+
precipitable_water = np.linspace(0, 10, 2)
176256

177-
def test_calc_taud():
178-
clearsky._calc_taud(w, aod700, p, p0)
257+
aod700, precipitable_water = np.meshgrid(aod700, precipitable_water)
179258

259+
out = clearsky.simplified_solis(80, aod700, precipitable_water,
260+
return_raw=True)
180261

181-
def test_calc_d():
182-
clearsky._calc_d(w, aod700, p, p0)
262+
np.allclose(expected, out)

0 commit comments

Comments
 (0)