Skip to content

Commit a6d78c3

Browse files
committed
Merge remote-tracking branch 'pvlib/master'
2 parents 960d8da + cbd7800 commit a6d78c3

File tree

12 files changed

+284
-2180
lines changed

12 files changed

+284
-2180
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ venv/
3131

3232
# spa_c_files builds
3333
pvlib/spa_c_files/build*
34+
pvlib/spa_c_files/spa_py.c
3435

3536
# spa_c_files source
3637
pvlib/spa_c_files/spa.c

MANIFEST.in

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
1-
#include *.txt
2-
include versioneer.py
3-
include pvlib/_version.py
4-
recursive-include pvlib/data *
1+
include MANIFEST.in
2+
include AUTHORS.md
3+
include LICENSE
54
include README.md
6-
include pvlib/spa_c_files/*.h
5+
include setup.py
6+
7+
# include most everything under pvlib by default
8+
# better to package too much than not enough
9+
graft pvlib
10+
11+
# we included pvlib files needed to compile NREL SPA code in graft above,
12+
# now we exclude the NREL code itself to comply with their license
13+
global-exclude */spa.c
14+
global-exclude */spa.h
15+
prune pvlib/spa_c_files/build
716

8-
#recursive-include docs *.txt
17+
graft docs
18+
prune docs/sphinx/build
19+
prune docs/sphinx/source/generated
20+
# all doc figures created by doc build
21+
prune docs/sphinx/source/savefig
22+
23+
global-exclude __pycache__
24+
global-exclude *.pyc
25+
global-exclude *.pyo
26+
global-exclude *.pyd
27+
global-exclude *.so
28+
global-exclude *~
29+
global-exclude .DS_Store
30+
global-exclude .git*
31+
global-exclude \#*
32+
global-exclude .ipynb_checkpoints
33+
34+
include versioneer.py
35+
include pvlib/_version.py

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ Bug fixes
160160
* Fixed bug in tracking.singleaxis that mistakenly assigned nan values when
161161
the Sun was still above the horizon. No effect on systems with axis_tilt=0.
162162
(:issue:`569`)
163+
* Source distribution did not contain LICENSE file. Added LICENSE, AUTHORS.md,
164+
and some docs to MANIFEST. (:issue:`579`)
165+
* Patch SPA C-files to fix timezone macro name clash with `pyconfig.h`. (:issue:`168`)
163166

164167

165168
Documentation

pvlib/solarposition.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,13 @@ def spa_c(time, latitude, longitude, pressure=101325, altitude=0,
159159
160160
References
161161
----------
162-
NREL SPA code: http://rredc.nrel.gov/solar/codesandalgorithms/spa/
162+
NREL SPA reference: http://rredc.nrel.gov/solar/codesandalgorithms/spa/
163+
NREL SPA C files: https://midcdmz.nrel.gov/spa/
164+
165+
Note: The ``timezone`` field in the SPA C files is replaced with
166+
``time_zone`` to avoid a nameclash with the function ``__timezone`` that is
167+
redefined by Python>=3.5. This issue is
168+
`Python bug 24643 <https://bugs.python.org/issue24643>`_.
163169
164170
USNO delta T:
165171
http://www.usno.navy.mil/USNO/earth-orientation/eo-products/long-term
@@ -194,7 +200,7 @@ def spa_c(time, latitude, longitude, pressure=101325, altitude=0,
194200
hour=date.hour,
195201
minute=date.minute,
196202
second=date.second,
197-
timezone=0, # date uses utc time
203+
time_zone=0, # date uses utc time
198204
latitude=latitude,
199205
longitude=longitude,
200206
elevation=altitude,
@@ -206,7 +212,9 @@ def spa_c(time, latitude, longitude, pressure=101325, altitude=0,
206212
spa_df = pd.DataFrame(spa_out, index=time)
207213

208214
if raw_spa_output:
209-
return spa_df
215+
# rename "time_zone" from raw output from spa_c_files.spa_py.spa_calc()
216+
# to "timezone" to match the API of pvlib.solarposition.spa_c()
217+
return spa_df.rename(columns={'time_zone': 'timezone'})
210218
else:
211219
dfout = pd.DataFrame({'azimuth': spa_df['azimuth'],
212220
'apparent_zenith': spa_df['zenith'],

pvlib/spa_c_files/README.md

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,81 @@
11
README
22
------
33

4-
NREL provides a C implementation of the solar position algorithm
5-
described in
6-
[Reda, I.; Andreas, A. (2003). Solar Position Algorithm for Solar Radiation Applications. 55 pp.; NREL Report No. TP-560-34302](
7-
http://www.nrel.gov/docs/fy08osti/34302.pdf).
4+
NREL provides a C implementation of the solar position algorithm described in
5+
[Reda, I.; Andreas, A. (2003). Solar Position Algorithm for Solar Radiation Applications. 55 pp.; NREL Report No. TP-560-34302](http://www.nrel.gov/docs/fy08osti/34302.pdf).
86

9-
This folder contains the files required to make NREL's C code accessible
10-
to the ``pvlib-python`` package. We use the Cython package to wrap NREL's SPA
7+
This folder contains the files required to make SPA C code accessible
8+
to the `pvlib-python` package. We use the Cython package to wrap the NREL SPA
119
implementation.
1210

13-
** Due to licensing issues, you must download the NREL C files from their
14-
[website](http://www.nrel.gov/midc/spa) **
11+
** Due to licensing issues, the SPA C files can _not_ be distributed with
12+
`pvlib-python`. You must download the SPA C files from the
13+
[NREL website](https://midcdmz.nrel.gov/spa/). **
1514

16-
Download the ``spa.c`` and ``spa.h`` files from NREL,
17-
and copy them into the ``pvlib/spa_c_files`` directory.
15+
Download the `spa.c` and `spa.h` files from NREL, and copy them into the
16+
`pvlib/spa_c_files` directory. When the extension is built, the ``timezone``
17+
field in the SPA C files is replaced with `time_zone` to avoid a nameclash
18+
with the function `__timezone` that is redefined by Python>=3.5. This issue
19+
is [Python bug 24643](https://bugs.python.org/issue24643).
1820

1921
There are a total of 5 files needed to compile the C code, described below:
2022

21-
* ``spa.c``: original C code from NREL
22-
* ``spa.h``: header file for spa.c
23-
* ``cspa_py.pxd``: a cython header file which essentially tells cython which parts of the main header file to pay attention to
24-
* ``spa_py.pyx``: the cython code used to define both functions in the python namespace. NOTE: It is possible to provide user access to other paramters of the SPA algorithm through modifying this file
25-
* ``setup.py``: a distutils file which performs the compiling of the cython code
23+
* `spa.c`: original C code from NREL
24+
* `spa.h`: header file for spa.c
25+
* `cspa_py.pxd`: a cython header file which essentially tells cython which
26+
parts of the main header file to pay attention to
27+
* `spa_py.pyx`: the cython code used to define both functions in the python
28+
namespace. NOTE: It is possible to provide user access to other paramters of
29+
the SPA algorithm through modifying this file
30+
* `setup.py`: a distutils file which performs the compiling of the cython code
2631

2732
The cython compilation process produces two files:
28-
* ``spa_py.c``: an intermediate cython c file
29-
* ``spa_py.so``: the python module which can be imported into a namespace
33+
* `spa_py.c`: an intermediate cython c file
34+
* `spa_py.so` or `spa_py.<cpyver-plat>.pyd`: the python module which
35+
can be imported into a namespace
3036

31-
To process the original 5 files,
32-
use the following shell command inside this folder
33-
34-
$ python setup.py build_ext --inplace
37+
To create the SPA Python extension, use the following shell command inside this
38+
folder:
39+
40+
$ python setup.py build_ext --inplace
41+
42+
There are four optional keyword arguments `delta_ut1=0`, `slope=30.0`,
43+
`azm_rotation=-10`, `atmos_refract` that effect four optional return values
44+
`incidence`, `suntransit`, `sunrise`, and `sunset`. If not given, the defaults
45+
shown are used.
46+
47+
There is an example in `spa_py_example.py` that contains a test function called
48+
`spa_calc_example` that users can use to check that the result is consistent
49+
with expected values:
50+
51+
>>> from spa_py_example import spa_calc_example
52+
>>> r = spa_calc_example()
53+
{
54+
'year': 2004,
55+
'month': 10,
56+
'day': 17,
57+
'hour': 12,
58+
'minute': 30,
59+
'second': 30.0,
60+
'delta_ut1': 0.0,
61+
'delta_t': 67.0,
62+
'time_zone': -7.0,
63+
'longitude': -105.1786,
64+
'latitude': 39.742476,
65+
'elevation': 1830.14,
66+
'pressure': 820.0,
67+
'temperature': 11.0,
68+
'slope': 30.0,
69+
'azm_rotation': -10.0,
70+
'atmos_refract': 0.5667,
71+
'function': 3,
72+
'e0': 39.59209464796398,
73+
'e': 39.60858878898177,
74+
'zenith': 50.39141121101823,
75+
'azimuth_astro': 14.311961805946808,
76+
'azimuth': 194.3119618059468,
77+
'incidence': 25.42168493680471,
78+
'suntransit': 11.765833793714224,
79+
'sunrise': 6.22578372122376,
80+
'sunset': 17.320379610556166
81+
}

pvlib/spa_c_files/SPA_NOTICE.md

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
1-
NOTICE
2-
Copyright © 2008-2011 Alliance for Sustainable Energy, LLC, All Rights Reserved
3-
The Solar Position Algorithm ("Software") is code in development prepared by employees of the Alliance for Sustainable Energy, LLC, (hereinafter the "Contractor"), under Contract No. DE-AC36-08GO28308 ("Contract") with the U.S. Department of Energy (the "DOE"). The United States Government has been granted for itself and others acting on its behalf a paid-up, non-exclusive, irrevocable, worldwide license in the Software to reproduce, prepare derivative works, and perform publicly and display publicly. Beginning five (5) years after the date permission to assert copyright is obtained from the DOE, and subject to any subsequent five (5) year renewals, the United States Government is granted for itself and others acting on its behalf a paid-up, non-exclusive, irrevocable, worldwide license in the Software to reproduce, prepare derivative works, distribute copies to the public, perform publicly and display publicly, and to permit others to do so. If the Contractor ceases to make this computer software available, it may be obtained from DOE's Office of Scientific and Technical Information's Energy Science and Technology Software Center (ESTSC) at P.O. Box 1020, Oak Ridge, TN 37831-1020. THIS SOFTWARE IS PROVIDED BY THE CONTRACTOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRACTOR OR THE U.S. GOVERNMENT BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER, INCLUDING BUT NOT LIMITED TO CLAIMS ASSOCIATED WITH THE LOSS OF DATA OR PROFITS, WHICH MAY RESULT FROM AN ACTION IN CONTRACT, NEGLIGENCE OR OTHER TORTIOUS CLAIM THAT ARISES OUT OF OR IN CONNECTION WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
4-
The Software is being provided for internal, noncommercial purposes only and shall not be re-distributed. Please contact Jennifer Ramsey in the NREL Commercialization and Technology Transfer Office for information concerning a commercial license to use the Software.
5-
As a condition of using the Software in an application, the developer of the application agrees to reference the use of the Software and make this Notice readily accessible to any end-user in a Help|About screen or equivalent manner.
1+
# NOTICE
2+
3+
Copyright (c) 2008-2011 Alliance for Sustainable Energy, LLC, All Rights Reserved
4+
5+
The Solar Position Algorithm ("Software") is code in development prepared by
6+
employees of the Alliance for Sustainable Energy, LLC, (hereinafter the
7+
"Contractor"), under Contract No. DE-AC36-08GO28308 ("Contract") with the
8+
U.S. Department of Energy (the "DOE"). The United States Government has been
9+
granted for itself and others acting on its behalf a paid-up, non-exclusive,
10+
irrevocable, worldwide license in the Software to reproduce, prepare
11+
derivative works, and perform publicly and display publicly. Beginning five
12+
(5) years after the date permission to assert copyright is obtained from the
13+
DOE, and subject to any subsequent five (5) year renewals, the United States
14+
Government is granted for itself and others acting on its behalf a paid-up,
15+
non-exclusive, irrevocable, worldwide license in the Software to reproduce,
16+
prepare derivative works, distribute copies to the public, perform publicly
17+
and display publicly, and to permit others to do so. If the Contractor ceases
18+
to make this computer software available, it may be obtained from DOE's
19+
Office of Scientific and Technical Information's Energy Science and
20+
Technology Software Center (ESTSC) at P.O. Box 1020, Oak Ridge, TN
21+
37831-1020. THIS SOFTWARE IS PROVIDED BY THE CONTRACTOR "AS IS" AND ANY
22+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE IMPLIED
23+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
DISCLAIMED. IN NO EVENT SHALL THE CONTRACTOR OR THE U.S. GOVERNMENT BE LIABLE
25+
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER,
26+
INCLUDING BUT NOT LIMITED TO CLAIMS ASSOCIATED WITH THE LOSS OF DATA OR
27+
PROFITS, WHICH MAY RESULT FROM AN ACTION IN CONTRACT, NEGLIGENCE OR OTHER
28+
TORTIOUS CLAIM THAT ARISES OUT OF OR IN CONNECTION WITH THE ACCESS, USE OR
29+
PERFORMANCE OF THIS SOFTWARE.
30+
31+
The Software is being provided for internal, noncommercial purposes only and
32+
shall not be re-distributed. Please contact [Jean
33+
Schulte](mailto:[email protected]) in the NREL Commercialization and
34+
Technology Transfer Office for information concerning a commercial license to
35+
use the Software.
36+
37+
As a condition of using the Software in an application, the developer of the
38+
application agrees to reference the use of the Software and make this Notice
39+
readily accessible to any end-user in a Help|About screen or equivalent manner.

pvlib/spa_c_files/cspa_py.pxd

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,43 @@
11
cdef extern from "spa.h":
2-
ctypedef struct spa_data:
3-
int year
4-
int month
5-
int day
6-
int hour
7-
int minute
8-
double second
9-
double delta_ut1
10-
double delta_t
11-
double timezone
12-
double longitude
13-
double latitude
2+
ctypedef enum:
3+
SPA_ZA, SPA_ZA_INC, SPA_ZA_RTS, SPA_ALL
144

15-
double elevation
5+
ctypedef struct spa_data:
6+
int year
7+
int month
8+
int day
9+
int hour
10+
int minute
11+
double second
12+
double delta_ut1
13+
double delta_t
14+
double time_zone
15+
double longitude
16+
double latitude
1617

17-
double pressure
18+
double elevation
1819

19-
double temperature
20+
double pressure
2021

21-
double slope
22+
double temperature
2223

23-
double azm_rotation
24+
double slope
2425

25-
double atmos_refract
26+
double azm_rotation
2627

27-
int function
28+
double atmos_refract
2829

29-
double e0
30-
double e
31-
double zenith
32-
double azimuth_astro
33-
double azimuth
34-
double incidence
30+
int function
3531

36-
double suntransit
37-
double sunrise
38-
double sunset
32+
double e0
33+
double e
34+
double zenith
35+
double azimuth_astro
36+
double azimuth
37+
double incidence
3938

40-
int spa_calculate(spa_data *spa)
39+
double suntransit
40+
double sunrise
41+
double sunset
42+
43+
int spa_calculate(spa_data *spa)

pvlib/spa_c_files/setup.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,34 @@
1-
#setup.py
1+
# setup.py
22

3+
import os
34
from distutils.core import setup
45
from distutils.extension import Extension
56
from Cython.Build import cythonize
67

8+
DIRNAME = os.path.dirname(__file__)
9+
10+
# patch spa.c
11+
with open(os.path.join(DIRNAME, 'spa.c'), 'rb') as f:
12+
SPA_C = f.read()
13+
# replace timezone with time_zone to avoid nameclash with the function
14+
# __timezone which is defined by a MACRO in pyconfig.h as timezone
15+
# see https://bugs.python.org/issue24643
16+
SPA_C = SPA_C.replace(b'timezone', b'time_zone')
17+
with open(os.path.join(DIRNAME, 'spa.c'), 'wb') as f:
18+
f.write(SPA_C)
19+
20+
# patch spa.h
21+
with open(os.path.join(DIRNAME, 'spa.h'), 'rb') as f:
22+
SPA_H = f.read()
23+
# replace timezone with time_zone to avoid nameclash with the function
24+
# __timezone which is defined by a MACRO in pyconfig.h as timezone
25+
# see https://bugs.python.org/issue24643
26+
SPA_H = SPA_H.replace(b'timezone', b'time_zone')
27+
with open(os.path.join(DIRNAME, 'spa.h'), 'wb') as f:
28+
f.write(SPA_H)
29+
30+
SPA_SOURCES = [os.path.join(DIRNAME, src) for src in ['spa_py.pyx', 'spa.c']]
31+
732
setup(
8-
ext_modules = cythonize([Extension("spa_py", ["spa_py.pyx",'spa.c'])])
33+
ext_modules=cythonize([Extension('spa_py', SPA_SOURCES)])
934
)

0 commit comments

Comments
 (0)