Skip to content

Commit

Permalink
Merge remote-tracking branch 'pvlib/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
wholmgren committed Sep 17, 2018
2 parents 960d8da + cbd7800 commit a6d78c3
Show file tree
Hide file tree
Showing 12 changed files with 284 additions and 2,180 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ venv/

# spa_c_files builds
pvlib/spa_c_files/build*
pvlib/spa_c_files/spa_py.c

# spa_c_files source
pvlib/spa_c_files/spa.c
Expand Down
39 changes: 33 additions & 6 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,35 @@
#include *.txt
include versioneer.py
include pvlib/_version.py
recursive-include pvlib/data *
include MANIFEST.in
include AUTHORS.md
include LICENSE
include README.md
include pvlib/spa_c_files/*.h
include setup.py

# include most everything under pvlib by default
# better to package too much than not enough
graft pvlib

# we included pvlib files needed to compile NREL SPA code in graft above,
# now we exclude the NREL code itself to comply with their license
global-exclude */spa.c
global-exclude */spa.h
prune pvlib/spa_c_files/build

#recursive-include docs *.txt
graft docs
prune docs/sphinx/build
prune docs/sphinx/source/generated
# all doc figures created by doc build
prune docs/sphinx/source/savefig

global-exclude __pycache__
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.pyd
global-exclude *.so
global-exclude *~
global-exclude .DS_Store
global-exclude .git*
global-exclude \#*
global-exclude .ipynb_checkpoints

include versioneer.py
include pvlib/_version.py
3 changes: 3 additions & 0 deletions docs/sphinx/source/whatsnew/v0.6.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ Bug fixes
* Fixed bug in tracking.singleaxis that mistakenly assigned nan values when
the Sun was still above the horizon. No effect on systems with axis_tilt=0.
(:issue:`569`)
* Source distribution did not contain LICENSE file. Added LICENSE, AUTHORS.md,
and some docs to MANIFEST. (:issue:`579`)
* Patch SPA C-files to fix timezone macro name clash with `pyconfig.h`. (:issue:`168`)


Documentation
Expand Down
14 changes: 11 additions & 3 deletions pvlib/solarposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,13 @@ def spa_c(time, latitude, longitude, pressure=101325, altitude=0,
References
----------
NREL SPA code: http://rredc.nrel.gov/solar/codesandalgorithms/spa/
NREL SPA reference: http://rredc.nrel.gov/solar/codesandalgorithms/spa/
NREL SPA C files: https://midcdmz.nrel.gov/spa/
Note: The ``timezone`` field in the SPA C files is replaced with
``time_zone`` to avoid a nameclash with the function ``__timezone`` that is
redefined by Python>=3.5. This issue is
`Python bug 24643 <https://bugs.python.org/issue24643>`_.
USNO delta T:
http://www.usno.navy.mil/USNO/earth-orientation/eo-products/long-term
Expand Down Expand Up @@ -194,7 +200,7 @@ def spa_c(time, latitude, longitude, pressure=101325, altitude=0,
hour=date.hour,
minute=date.minute,
second=date.second,
timezone=0, # date uses utc time
time_zone=0, # date uses utc time
latitude=latitude,
longitude=longitude,
elevation=altitude,
Expand All @@ -206,7 +212,9 @@ def spa_c(time, latitude, longitude, pressure=101325, altitude=0,
spa_df = pd.DataFrame(spa_out, index=time)

if raw_spa_output:
return spa_df
# rename "time_zone" from raw output from spa_c_files.spa_py.spa_calc()
# to "timezone" to match the API of pvlib.solarposition.spa_c()
return spa_df.rename(columns={'time_zone': 'timezone'})
else:
dfout = pd.DataFrame({'azimuth': spa_df['azimuth'],
'apparent_zenith': spa_df['zenith'],
Expand Down
89 changes: 68 additions & 21 deletions pvlib/spa_c_files/README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,81 @@
README
------

NREL provides a C implementation of the solar position algorithm
described in
[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).
NREL provides a C implementation of the solar position algorithm described in
[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).

This folder contains the files required to make NREL's C code accessible
to the ``pvlib-python`` package. We use the Cython package to wrap NREL's SPA
This folder contains the files required to make SPA C code accessible
to the `pvlib-python` package. We use the Cython package to wrap the NREL SPA
implementation.

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

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

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

* ``spa.c``: original C code from NREL
* ``spa.h``: header file for spa.c
* ``cspa_py.pxd``: a cython header file which essentially tells cython which parts of the main header file to pay attention to
* ``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
* ``setup.py``: a distutils file which performs the compiling of the cython code
* `spa.c`: original C code from NREL
* `spa.h`: header file for spa.c
* `cspa_py.pxd`: a cython header file which essentially tells cython which
parts of the main header file to pay attention to
* `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
* `setup.py`: a distutils file which performs the compiling of the cython code

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

To process the original 5 files,
use the following shell command inside this folder

$ python setup.py build_ext --inplace
To create the SPA Python extension, use the following shell command inside this
folder:

$ python setup.py build_ext --inplace

There are four optional keyword arguments `delta_ut1=0`, `slope=30.0`,
`azm_rotation=-10`, `atmos_refract` that effect four optional return values
`incidence`, `suntransit`, `sunrise`, and `sunset`. If not given, the defaults
shown are used.

There is an example in `spa_py_example.py` that contains a test function called
`spa_calc_example` that users can use to check that the result is consistent
with expected values:

>>> from spa_py_example import spa_calc_example
>>> r = spa_calc_example()
{
'year': 2004,
'month': 10,
'day': 17,
'hour': 12,
'minute': 30,
'second': 30.0,
'delta_ut1': 0.0,
'delta_t': 67.0,
'time_zone': -7.0,
'longitude': -105.1786,
'latitude': 39.742476,
'elevation': 1830.14,
'pressure': 820.0,
'temperature': 11.0,
'slope': 30.0,
'azm_rotation': -10.0,
'atmos_refract': 0.5667,
'function': 3,
'e0': 39.59209464796398,
'e': 39.60858878898177,
'zenith': 50.39141121101823,
'azimuth_astro': 14.311961805946808,
'azimuth': 194.3119618059468,
'incidence': 25.42168493680471,
'suntransit': 11.765833793714224,
'sunrise': 6.22578372122376,
'sunset': 17.320379610556166
}
44 changes: 39 additions & 5 deletions pvlib/spa_c_files/SPA_NOTICE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
NOTICE
Copyright © 2008-2011 Alliance for Sustainable Energy, LLC, All Rights Reserved
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.
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.
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.
# NOTICE

Copyright (c) 2008-2011 Alliance for Sustainable Energy, LLC, All Rights Reserved

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.

The Software is being provided for internal, noncommercial purposes only and
shall not be re-distributed. Please contact [Jean
Schulte](mailto:Jean.Schulte@nrel.gov) in the NREL Commercialization and
Technology Transfer Office for information concerning a commercial license to
use the Software.

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.
61 changes: 32 additions & 29 deletions pvlib/spa_c_files/cspa_py.pxd
Original file line number Diff line number Diff line change
@@ -1,40 +1,43 @@
cdef extern from "spa.h":
ctypedef struct spa_data:
int year
int month
int day
int hour
int minute
double second
double delta_ut1
double delta_t
double timezone
double longitude
double latitude
ctypedef enum:
SPA_ZA, SPA_ZA_INC, SPA_ZA_RTS, SPA_ALL

double elevation
ctypedef struct spa_data:
int year
int month
int day
int hour
int minute
double second
double delta_ut1
double delta_t
double time_zone
double longitude
double latitude

double pressure
double elevation

double temperature
double pressure

double slope
double temperature

double azm_rotation
double slope

double atmos_refract
double azm_rotation

int function
double atmos_refract

double e0
double e
double zenith
double azimuth_astro
double azimuth
double incidence
int function

double suntransit
double sunrise
double sunset
double e0
double e
double zenith
double azimuth_astro
double azimuth
double incidence

int spa_calculate(spa_data *spa)
double suntransit
double sunrise
double sunset

int spa_calculate(spa_data *spa)
29 changes: 27 additions & 2 deletions pvlib/spa_c_files/setup.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
#setup.py
# setup.py

import os
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

DIRNAME = os.path.dirname(__file__)

# patch spa.c
with open(os.path.join(DIRNAME, 'spa.c'), 'rb') as f:
SPA_C = f.read()
# replace timezone with time_zone to avoid nameclash with the function
# __timezone which is defined by a MACRO in pyconfig.h as timezone
# see https://bugs.python.org/issue24643
SPA_C = SPA_C.replace(b'timezone', b'time_zone')
with open(os.path.join(DIRNAME, 'spa.c'), 'wb') as f:
f.write(SPA_C)

# patch spa.h
with open(os.path.join(DIRNAME, 'spa.h'), 'rb') as f:
SPA_H = f.read()
# replace timezone with time_zone to avoid nameclash with the function
# __timezone which is defined by a MACRO in pyconfig.h as timezone
# see https://bugs.python.org/issue24643
SPA_H = SPA_H.replace(b'timezone', b'time_zone')
with open(os.path.join(DIRNAME, 'spa.h'), 'wb') as f:
f.write(SPA_H)

SPA_SOURCES = [os.path.join(DIRNAME, src) for src in ['spa_py.pyx', 'spa.c']]

setup(
ext_modules = cythonize([Extension("spa_py", ["spa_py.pyx",'spa.c'])])
ext_modules=cythonize([Extension('spa_py', SPA_SOURCES)])
)

0 comments on commit a6d78c3

Please sign in to comment.