Skip to content

NREL SPA license problems #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wholmgren opened this issue Feb 28, 2015 · 11 comments
Closed

NREL SPA license problems #9

wholmgren opened this issue Feb 28, 2015 · 11 comments
Labels
Milestone

Comments

@wholmgren
Copy link
Member

It appears to me that we may be in violation of NREL's SPA license

"The Software is being provided for internal, noncommercial purposes only and shall not be re-distributed."

A couple of potential problems:

  • We are redistributing their code rather than just making binaries with it.
  • We (or at least I) don't want to limit pvlib-python to non-commerical purposes. Everything else in pvlib-python is, to my knowledge, able to be used in commercial applications.

The license goes on to say that you must contact them about using it in commercial applications.

Am I reading this wrong? @Calama-Consulting did you have a different interpretation of this when you added the SPA code to pvlib?

@robwandrews
Copy link
Contributor

My inclusion of it was based on it's original inclusion in the MATLAB version of the code, which carries the following liscence:

Copyright (c) 2013, Sandia Labs
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

Neither the name of the {organization} nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Which doesn't seem to maintain the license for the spa code.
We have been given permission to modify this license for the pvlib-python version, so we are fine there.

I will follow up on this with the appropriate folks at NREL, in the meantime, we should add a logger message indicating these limitations until it is cleared out. Does that make sense?

Cheers

@wholmgren
Copy link
Member Author

Hm, sort of makes sense. Maybe I need more coffee. I don't see that the NREL C code is actually contained in PVLIB-Matlab, so I'm not sure how that license applies here.

Since I wasn't very clear, I am specifically concerned about us including NREL's spa.c and spa.h files in our distribution.

It seems as though the authors of the pvl_spa.m file read the NREL SPA paper, looked at the C code, and then made their own implementation of the algorithm. I think that it's ok for us to do the same thing, although at that point I would probably just drop the NREL SPA in favor of the (much) slower pyephem calculator. I think that the NREL license only applies to their C code implementation, and that it does not apply to the general algorithm.

Another option would be to distribute the cython wrappers but make people download their own copies of the NREL code. Certainly not an ideal situation, but it could work for people that really want the speed improvements and are willing to do some manual installation.

@robwandrews
Copy link
Contributor

I'm working on a change that will allow the user to install spa themselves with a version of the .c and .h files that they download from the NREL website. The best way I can think of is to have the pypi version have the function disabled by default. If they want to install spa, you would need to download the full tarball from github, and run

python setup_spa.py install

where setup_spa is the originial setup file, after they copy the spa.c and spa.h into the appropriate directory.

That is pretty messy, and there should be another way, I was thinking of something like this:

    def spa_compile():
        import sys
        import shutil
        import os
        '''
        Runs a set-up script to compile the cython version of the NREL SPA code 
        once a user has downloaded the package
        '''

        spac = input('Please enter the location of spa.c')
        spah = input('Please enter the location of spa.h')

        pvlib_loc=pvlib.__file__[:-12]

        shutil.copyfile(spac,pvlib_loc+'spa_c_files/spa.c')
        shutil.copyfile(spah,pvlib_loc+'spa_c_files/spa.h')

        os.system('python '+pvlib_loc+'/spa_c_files setup.py build_ext —inplace')

but setuptools doesn't copy all the required files into the spa_c_files in site-packages when it isn't explicitly asked to compile it on the first setup.

Thoughts?

@wholmgren
Copy link
Member Author

On the first proposal: my guess is that if NREL won't let us put their files in the PyPI package, then they won't let us put them on the github repo either. If I'm wrong about that, then this idea could work.

On the second proposal:

I think that it would be easier in the end to actually go further and just split the spa wrappers into a separate package. Here's my thinking...

Users would download a tarball or git clone the fairly simple spa repo, put their separately downloaded NREL files into that directory, and then run the spa repo's setup.py. pip install . would also work since the setup.py would be standard.

If the spa code is in a separate package, you only need to install once. No conflict with installing into an existing site-packages either.

Also, while a determined user will be able to follow any reasonable spa installation instructions, the user will not be happy following those instructions for every pvlib update -- especially bug fix updates. Users of virtual environments may find this even more annoying. (and by "user" I mean me, of course)

I think that this will also simply the unit tests, although I haven't really thought through that aspect.

@wholmgren
Copy link
Member Author

Sorry, I think I misread your first proposal. That would work. We could probably just use try/except in a single setup.py file.

@bmu
Copy link
Contributor

bmu commented Mar 4, 2015

My feelng is, that it would be the best to skip inclusion of SPA until we have a pure python version (in case it is allowed to use the algorythm, but not the C implementation). If there is a matlab version, we could try to "translate" it.

@robwandrews
Copy link
Contributor

I got part way through translating the matlab code, it is definitely possible though because of the differences in matrix handling between matlab and python, it is not an easy task. However, I stopped because it doesn't make a lot of sense to re-write good, functional and validated C code in slower python. That being said, if licensing is the bottleneck, that that might be what we have to do.

But, let me expand on the first proposal, with @wholmgren 's additions. Could we pull the spa code from the github repo, but maintain the compiling instructions in the setup.py, protected by a try/except clause. A user doing a pypi install will get the package with a non-functional spa module (and we will have to set up logging/debug appropriately). If they want to install spa, they will need to download the repo, insert their downloaded spa files, and re-run the setup.

Would that make sense?

@wholmgren
Copy link
Member Author

For the sake of expediency, this is ok with me for the 0.1 release.

pyephem is currently the default spa method (I think that this was a difference between UARENForecating and Sandia-Labs), and we should probably keep it that way if this is going to be the solution. We'd also want to add pyephem to the dependencies in setup.py.

Beyond 0.1, I do think that we'd want to put the spa wrappers in their own package so that people don't have to go through this procedure every time they upgrade or freshly install pvlib. The people that bothered to do it for 0.1 will probably be ok doing it once more if we promise that it's the last time they need to. I'm imagining that we could have pvlib bug fix releases every 1-3 months, and feature releases every 3-6 months. That would make for a lot of unnecessary installation grief if the spa wrappers remain a part of pvlib.

I agree that it doesn't make a lot of sense to rewrite the spa algorithm in python, licensing issues aside. However, if we do rewrite it, we could add an optional numba decorator to make it much faster.

@bmu bmu added this to the 0.1 milestone Mar 12, 2015
@bmu bmu added the license label Mar 12, 2015
@robwandrews
Copy link
Contributor

Not fully resolved, keeping this for context and shifting to the 0.2 milestone

@robwandrews robwandrews modified the milestones: 0.2, 0.1 Mar 13, 2015
@wholmgren
Copy link
Member Author

Just noticed this from PVLIB MATLAB's pvl_spa_help.m

Calculates the position of the sun given time, location, and optionally pressure and temperature Implements a vectorized version of NREL's Solar Position Algorithm by Reda and Andreas, 2008. This implementation is different and distinct from NREL's copyrighted spa.c (C code).

So they've apparently run into the same problem.

@bmu
Copy link
Contributor

bmu commented Apr 22, 2015

I think this is solved now, isn't it? So I would move it to the 0.1 milestone and close it.

@wholmgren wholmgren modified the milestones: 0.1, 0.2 Apr 22, 2015
@kandersolar kandersolar mentioned this issue Sep 13, 2022
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants