Skip to content

Commit 2279add

Browse files
authored
improvements to irradiance module, increase min requirements (#214)
* refactor disc * pep8, minimum, maximum functions * more de-pandafication * depandafy atmosphere * reorder zenith filter to avoid python 2.7 complex math * more disc refactoring * fix dirint. needs tests * update whatsnew * perez now works with scalars. array input still converted to series output * refactor perez to work with scalars and return scalars * bump pandas/numpy reqs * work around continuum min req conda packaging bug * switch to pip install for min req numpy=1.9.0 and pandas==0.13.1 * add pip to travis cache * try pandas 0.14.1 * numpy 1.9.3, pandas 0.14.1 * make pip install order explicit * add uninstalls * add no-cache-dir * 1.9.0, 0.14.0 * fix conda env test * update whatsnew * rebase on fs spectral changes
1 parent 58d77ea commit 2279add

File tree

13 files changed

+952
-931
lines changed

13 files changed

+952
-931
lines changed

.travis.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ addons:
2323
- ccache
2424

2525
cache:
26-
directories:
27-
- $HOME/.ccache
26+
# - pip
27+
- ccache
2828

2929
# setup miniconda for numpy, scipy, pandas
3030
before_install:
@@ -46,6 +46,14 @@ install:
4646
- echo "install"
4747
- conda env create --file ci/requirements-$CONDA_ENV.yml
4848
- source activate test_env # all envs are named test_env in the yml files
49+
# needed to make sure that pandas is compiled against the right
50+
# version of numpy
51+
- if [[ "$CONDA_ENV" == "py27-min" ]]; then
52+
pip uninstall numpy --yes;
53+
pip uninstall pandas --yes;
54+
pip install --no-cache-dir numpy==1.9.0;
55+
pip install --no-cache-dir pandas==0.14.0;
56+
fi
4957
- conda list
5058
- echo $PATH
5159
- ls -l /home/travis/miniconda/envs/test_env/lib

ci/requirements-py27-min.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
name: test_env
22
dependencies:
33
- python=2.7
4-
- numpy==1.8.2
5-
- pandas==0.13.1
64
- pytz
75
- pytest
86
- pytest-cov

docs/sphinx/source/whatsnew/v0.4.0.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ API Changes
1414
* Remove unneeded module argument from singlediode function. (:issue:`200`)
1515
* In ``pvlib.irradiance.perez``, renamed argument ``modelt`` to ``model``.
1616
(:issue:`196`)
17+
* Functions in the irradiance module now work with scalar inputs
18+
in addition to arrays and Series. Furthermore, these functions no
19+
longer promote scalar or array input to Series output.
20+
Also applies to atmosphere.relativeairmass. (:issue:`201`, :issue:`214`)
1721

1822

1923
Enhancements
@@ -22,6 +26,8 @@ Enhancements
2226
* Adds the First Solar spectral correction model. (:issue:`115`)
2327
* Adds the Gueymard 1994 integrated precipitable water model. (:issue:`115`)
2428
* Adds the PVWatts DC, AC, and system losses model. (:issue:`195`)
29+
* Improve PEP8 conformity in irradiance module. (:issue:`214`)
30+
* irradiance.disc is up to 10x faster. (:issue:`214`)
2531

2632

2733
Bug fixes
@@ -44,6 +50,17 @@ Other
4450
* Switch to the py.test testing framework. (:issue:`204`)
4551
* Reconfigure Appveyor CI builds and resolve an issue in which the command
4652
line length was too long. (:issue:`207`)
53+
* Manually build numpy and pandas for the min requirements test.
54+
This is needed to avoid Continuum's bad practice of bundling scipy
55+
with pandas. (:issue:`214`)
56+
57+
58+
Requirements
59+
~~~~~~~~~~~~
60+
61+
* pvlib now requires pandas >= 0.14.0 and numpy >= 1.9.0, both
62+
released in 2014. Most of pvlib will work with lesser versions.
63+
(:issue:`214`)
4764

4865

4966
Code Contributors

pvlib/atmosphere.py

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from __future__ import division
77

88
import numpy as np
9+
import pandas as pd
910
from warnings import warn
1011

1112
APPARENT_ZENITH_MODELS = ('simple', 'kasten1966', 'kastenyoung1989',
@@ -20,12 +21,12 @@ def pres2alt(pressure):
2021
2122
Parameters
2223
----------
23-
pressure : scalar or Series
24+
pressure : numeric
2425
Atmospheric pressure (Pascals)
2526
2627
Returns
2728
-------
28-
altitude : scalar or Series
29+
altitude : numeric
2930
Altitude in meters above sea level
3031
3132
Notes
@@ -45,12 +46,12 @@ def pres2alt(pressure):
4546
4647
References
4748
-----------
48-
49-
"A Quick Derivation relating altitude to air pressure" from Portland
50-
State Aerospace Society, Version 1.03, 12/22/2004.
49+
[1] "A Quick Derivation relating altitude to air pressure" from
50+
Portland State Aerospace Society, Version 1.03, 12/22/2004.
5151
'''
5252

5353
alt = 44331.5 - 4946.62 * pressure ** (0.190263)
54+
5455
return alt
5556

5657

@@ -60,12 +61,12 @@ def alt2pres(altitude):
6061
6162
Parameters
6263
----------
63-
Altitude : scalar or Series
64+
altitude : numeric
6465
Altitude in meters above sea level
6566
6667
Returns
6768
-------
68-
Pressure : scalar or Series
69+
pressure : numeric
6970
Atmospheric pressure (Pascals)
7071
7172
Notes
@@ -85,9 +86,8 @@ def alt2pres(altitude):
8586
8687
References
8788
-----------
88-
89-
"A Quick Derivation relating altitude to air pressure" from Portland
90-
State Aerospace Society, Version 1.03, 12/22/2004.
89+
[1] "A Quick Derivation relating altitude to air pressure" from
90+
Portland State Aerospace Society, Version 1.03, 12/22/2004.
9191
'''
9292

9393
press = 100 * ((44331.514 - altitude) / 11880.516) ** (1 / 0.1902632)
@@ -111,24 +111,22 @@ def absoluteairmass(airmass_relative, pressure=101325.):
111111
112112
Parameters
113113
----------
114-
115-
airmass_relative : scalar or Series
114+
airmass_relative : numeric
116115
The airmass at sea-level.
117116
118-
pressure : scalar or Series
117+
pressure : numeric
119118
The site pressure in Pascal.
120119
121120
Returns
122121
-------
123-
scalar or Series
122+
airmass_absolute : numeric
124123
Absolute (pressure corrected) airmass
125124
126125
References
127126
----------
128127
[1] C. Gueymard, "Critical analysis and performance assessment of
129128
clear sky solar irradiance models using theoretical and measured
130129
data," Solar Energy, vol. 51, pp. 121-138, 1993.
131-
132130
'''
133131

134132
airmass_absolute = airmass_relative * pressure / 101325.
@@ -147,15 +145,14 @@ def relativeairmass(zenith, model='kastenyoung1989'):
147145
148146
Parameters
149147
----------
150-
151-
zenith : float or Series
148+
zenith : numeric
152149
Zenith angle of the sun in degrees. Note that some models use
153150
the apparent (refraction corrected) zenith angle, and some
154151
models use the true (not refraction-corrected) zenith angle. See
155152
model descriptions to determine which type of zenith angle is
156153
required. Apparent zenith angles must be calculated at sea level.
157154
158-
model : String
155+
model : string
159156
Available models include the following:
160157
161158
* 'simple' - secant(apparent zenith angle) -
@@ -175,13 +172,12 @@ def relativeairmass(zenith, model='kastenyoung1989'):
175172
176173
Returns
177174
-------
178-
airmass_relative : float or Series
179-
Relative airmass at sea level. Will return NaN values for any
175+
airmass_relative : numeric
176+
Relative airmass at sea level. Will return NaN values for any
180177
zenith angle greater than 90 degrees.
181178
182179
References
183180
----------
184-
185181
[1] Fritz Kasten. "A New Table and Approximation Formula for the
186182
Relative Optical Air Mass". Technical Report 136, Hanover, N.H.:
187183
U.S. Army Material Command, CRREL.
@@ -207,7 +203,9 @@ def relativeairmass(zenith, model='kastenyoung1989'):
207203
Sandia Report, (2012).
208204
'''
209205

210-
z = zenith
206+
# need to filter first because python 2.7 does not support raising a
207+
# negative number to a negative power.
208+
z = np.where(zenith > 90, np.nan, zenith)
211209
zenith_rad = np.radians(z)
212210

213211
model = model.lower()
@@ -237,10 +235,8 @@ def relativeairmass(zenith, model='kastenyoung1989'):
237235
else:
238236
raise ValueError('%s is not a valid model for relativeairmass', model)
239237

240-
try:
241-
am[z > 90] = np.nan
242-
except TypeError:
243-
am = np.nan if z > 90 else am
238+
if isinstance(zenith, pd.Series):
239+
am = pd.Series(am, index=zenith.index)
244240

245241
return am
246242

@@ -282,14 +278,14 @@ def gueymard94_pw(temp_air, relative_humidity):
282278
283279
Parameters
284280
----------
285-
temp_air : array-like
281+
temp_air : numeric
286282
ambient air temperature at the surface (C)
287-
relative_humidity : array-like
283+
relative_humidity : numeric
288284
relative humidity at the surface (%)
289285
290286
Returns
291287
-------
292-
pw : array-like
288+
pw : numeric
293289
precipitable water (cm)
294290
295291
References
@@ -349,7 +345,7 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None,
349345
Pwat where:
350346
351347
* 0.5 cm <= Pwat <= 5 cm
352-
* 1.0 <= AMa <= 5.0
348+
* 1.0 <= AMa <= 5.0
353349
* Spectral range is limited to that of CMP11 (280 nm to 2800 nm)
354350
* spectrum simulated on a plane normal to the sun
355351
* All other parameters fixed at G173 standard
@@ -408,8 +404,8 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None,
408404
radiative transfer of sunshine: algorithms and performance
409405
assessment. Cocoa, FL: Florida Solar Energy Center, 1995.
410406
.. [2] Lee, Mitchell, and Panchula, Alex. "Spectral Correction for
411-
Photovoltaic Module Performance Based on Air Mass and Precipitable
412-
Water." IEEE Photovoltaic Specialists Conference, Portland, 2016
407+
Photovoltaic Module Performance Based on Air Mass and Precipitable
408+
Water." IEEE Photovoltaic Specialists Conference, Portland, 2016
413409
.. [3] Marion, William F., et al. User's Manual for Data for Validating
414410
Models for PV Module Performance. National Renewable Energy
415411
Laboratory, 2014. http://www.nrel.gov/docs/fy14osti/61610.pdf
@@ -423,30 +419,29 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None,
423419

424420
if np.min(pw) < 0.1:
425421
pw = np.maximum(pw, 0.1)
426-
warn('Exceptionally low Pwat values replaced with 0.1 cm to prevent'+
427-
' model divergence')
422+
warn('Exceptionally low Pwat values replaced with 0.1 cm to prevent' +
423+
' model divergence')
428424

429425

430426
# Warn user about Pwat data that is exceptionally high
431427
if np.max(pw) > 8:
432428
warn('Exceptionally high Pwat values. Check input data:' +
433-
' model may diverge in this range')
429+
' model may diverge in this range')
434430

435431

436432
# *** AMa ***
437433
# Replace Extremely High AM with AM 10 to prevent model divergence
438434
# AM > 10 will only occur very close to sunset
439-
if np.max(airmass_absolute) > 10:
440-
airmass_absolute = np.minimum(airmass_absolute,10)
441-
435+
if np.max(airmass_absolute) > 10:
436+
airmass_absolute = np.minimum(airmass_absolute, 10)
437+
442438
# Warn user about AMa data that is exceptionally low
443439
if np.min(airmass_absolute) < 0.58:
444440
warn('Exceptionally low air mass: ' +
445-
'model not intended for extra-terrestrial use')
446-
# pvl_absoluteairmass(1,pvl_alt2pres(4340)) = 0.58
447-
# Elevation of Mina Pirquita, Argentian = 4340 m. Highest elevation city
448-
# with population over 50,000.
449-
441+
'model not intended for extra-terrestrial use')
442+
# pvl_absoluteairmass(1,pvl_alt2pres(4340)) = 0.58 Elevation of
443+
# Mina Pirquita, Argentian = 4340 m. Highest elevation city with
444+
# population over 50,000.
450445

451446
_coefficients = {}
452447
_coefficients['cdte'] = (
@@ -468,9 +463,9 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None,
468463

469464
# Evaluate Spectral Shift
470465
coeff = coefficients
471-
AMa = airmass_absolute
466+
ama = airmass_absolute
472467
modifier = (
473-
coeff[0] + coeff[1]*AMa + coeff[2]*pw + coeff[3]*np.sqrt(AMa) +
474-
+ coeff[4]*np.sqrt(pw) + coeff[5]*AMa/np.sqrt(pw))
468+
coeff[0] + coeff[1]*ama + coeff[2]*pw + coeff[3]*np.sqrt(ama) +
469+
coeff[4]*np.sqrt(pw) + coeff[5]*ama/np.sqrt(pw))
475470

476471
return modifier

0 commit comments

Comments
 (0)