8000 Location demotion and PVSystem/LocalizedPVSystem/ModelChain addition by wholmgren · Pull Request #93 · pvlib/pvlib-python · GitHub
[go: up one dir, main page]

Skip to content

Location demotion and PVSystem/LocalizedPVSystem/ModelChain addition #93

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

Merged
merged 105 commits into from
Mar 9, 2016
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
c33d65d
change location default tz to utc
wholmgren Oct 28, 2015
d965f26
a mess of pvsystem and location stuff thats not working
wholmgren Oct 28, 2015
e1ad189
add SingleAxisTracker. more brainstorming
wholmgren Oct 28, 2015
b4cc4b7
fix import error
wholmgren Nov 10, 2015
e92acdd
add get_solarposition and get_clearsky
wholmgren Nov 10, 2015
27fd18e
add get_irradiance, simple doc strings, and a few kwargs
wholmgren Nov 10, 2015
82f28ba
make solarposition.spa_python work without Location
wholmgren Nov 10, 2015
cb22f24
add doc links and n_modules kwargs
wholmgren Nov 10, 2015
ca0c6ba
add altitude
wholmgren Nov 10, 2015
2524995
get_clearsky works
wholmgren Nov 10, 2015
c5d55d3
add v0.3.0 description
wholmgren Nov 10, 2015
697e8d2
remove Location inheritance from PVSystem
wholmgren Nov 13, 2015
ff0fb3b
remove Location inheritance from SAT
wholmgren Nov 13, 2015
e2a22cf
remove Location inheritance from SAT
wholmgren Nov 13, 2015
b9d41c8
fix klucher spelling
wholmgren Nov 11, 2015
b01dc5a
add klucher to total_irrad test list
wholmgren Nov 11, 2015
0c5cf68
fix bad paper link
wholmgren Nov 13, 2015
58bb3f5
add release date
wholmgren Nov 13, 2015
2465ae1
more slow progress
wholmgren Nov 15, 2015
ddc8816
addes classes. rename modules
wholmgren Nov 15, 2015
7e108ec
add LocalizedPVSystem. improve docs a little
wholmgren Nov 15, 2015
37a36da
add stub modelchain
wholmgren Nov 16, 2015
cddf91d
make package overview doc
wholmgren Nov 16, 2015
a381049
doc improvements
wholmgren Nov 16, 2015
ed6dc81
more doc stuff
wholmgren Nov 16, 2015
1a677d6
make aoi loss models have a consistent signature
wholmgren Nov 16, 2015
515d97a
flesh out modelchain a little
wholmgren Nov 16, 2015
3b7cd9a
remove location from solarposition module. enforce localized or utc t…
wholmgren Dec 21, 2015
b2d33ff
move iam args into PVSystems self.module_parameters
wholmgren Dec 21, 2015
dc75691
get test_pvsystem working with new ineichen sig. add dummy class tests
wholmgren Dec 21, 2015
10775e2
make test_clearsky work with new sig. fails due to changes in ephem m…
wholmgren Dec 21, 2015
66b3603
make altitude a kwarg
wholmgren Dec 21, 2015
ad7c990
make test_irradiance work with new ineichen sig
wholmgren Dec 21, 2015
358accd
make test_atmosphere work with new solpos sig
wholmgren Dec 21, 2015
34b925d
merge ci/appveyor/rtdconda into pvsystem
wholmgren Jan 18, 2016
6036106
fix cs test numbers due to new solpos
wholmgren Jan 18, 2016
2d14082
add has_ephem, modify tests for min pandas compatibility
wholmgren Jan 19, 2016
125cae2
further fixes to min req and transition to all nrel_numpy defaults
wholmgren Jan 19, 2016
04f477f
pull in some @MoonRaker changes to docs conf.py
wholmgren Jan 19, 2016
aa52f5f
fix pvlib/pvlib-python#105, add poa_diffuse
wholmgren Jan 19, 2016
7120082
standardize sapm_celltemp arg names. add dict/Series input
wholmgren Jan 19, 2016
a366714
get the procedural code example working in the docs
wholmgren Jan 19, 2016
c3073f0
change rtd python to 3.5 to use dict unpacking
wholmgren Jan 19, 2016
560bf84
add recommonmark
wholmgren Jan 19, 2016
96449ba
remove recommonmark. problem was in rtd admin config
wholmgren Jan 19, 2016
eae606c
back to 2.7...
wholmgren Jan 20, 2016
3ca9fdd
fix python 2.7 issues in doc example. make plotting work
wholmgren Jan 20, 2016
e5d77d5
minor markup correction
Jan 21, 2016
7d49393
add get_absoluteairmass
wholmgren Jan 30, 2016
c541abd
add get_aoi, dni/am calcs
wholmgren Jan 30, 2016
f46ef23
run_model finally works
wholmgren Jan 30, 2016
0d5bf83
update mc part of overview
wholmgren Jan 30, 2016
7a863fc
more doc improvements
wholmgren Jan 30, 2016
2bbc618
more doc improvements
wholmgren Jan 30, 2016
0f36234
create PVSystem.localize, allow LocalizedPVSystem pvsystem and locati…
wholmgren Jan 30, 2016
67744b0
update docs with LocalizedPVSystem improvements
wholmgren Jan 30, 2016
64a8fec
fix small typos
wholmgren Jan 30, 2016
176495c
fix small typos
wholmgren Jan 30, 2016
d030bb2
try short sphinx class refs
wholmgren Jan 30, 2016
d8b9968
trying to track down model differences
wholmgren Jan 30, 2016
55fa894
fix azimuth prob in docs
wholmgren Jan 30, 2016
9901538
maybe fixed discrepancies...
wholmgren Jan 30, 2016
a2fc762
add irradiance and weather kwargs to run_model
wholmgren Jan 30, 2016
eb8a803
merge pvlib/master into pvsystem
wholmgren Jan 31, 2016
fe5d021
clean up merge cruft
wholmgren Jan 31, 2016
3f96b89
convert get_airmassabsolute to get_airmass. add a bunch of failing st…
wholmgren Jan 31, 2016
63da5e6
fix silly syntax error
wholmgren Jan 31, 2016
9d8c374
fix pd import, default am model, ValueError text
wholmgren Jan 31, 2016
8aa8d53
editing docs
wholmgren Jan 31, 2016
862e0f0
editing docs
wholmgren Jan 31, 2016
aeb02e8
fix tmy2 metadata label problem
wholmgren Jan 31, 2016
28ed812
break AIRMASS_MODELS into *_ZENITH_MODELS
wholmgren Jan 31, 2016
cf1c1f3
small clean ups
wholmgren Jan 31, 2016
3391abf
add pressure, temperature to get_solarposition. make from_tmy work
wholmgren Jan 31, 2016
c547c3c
make location tests work
wholmgren Jan 31, 2016
bcb41ae
update whatsnew. might still be missing a few things
wholmgren Jan 31, 2016
ac6f710
remove sphinx markup from see also numpy doc section
wholmgren Jan 31, 2016
49c670d
implement modelchain tests
wholmgren Feb 1, 2016
df389aa
implement PVSystem tests
wholmgren Feb 1, 2016
4bfff5a
Merge remote-tracking branch 'wholmgren/pvsystem' into origin/pvsystem
Feb 1, 2016
5fc704e
Minor changes to the documentation
Feb 1, 2016
cd0da5b
highly experimental LocalizedSingleAxisTracker
wholmgren Feb 1, 2016
911ceff
typo
dacoex Feb 1, 2016
d41053c
contributors
dacoex Feb 1, 2016
01b5ff5
added python 3
dacoex Feb 3, 2016
50da307
Merge pull request #2 from dacoex/pvsystem
wholmgren Feb 7, 2016
96a6884
add api changes to whatsnew
wholmgren Feb 7, 2016
9e5ca7c
fix small doc issues
wholmgren Feb 8, 2016
feef0b5
add tests, fix attribute error
wholmgren Feb 10, 2016
9025cfc
pin to ipython 4.0.1
wholmgren Feb 10, 2016
96e7eb3
more tests for location
wholmgren Feb 10, 2016
4c3ad9b
lots of pvsystem tests
wholmgren Feb 11, 2016
ab6063f
solarposition.get_solarposition is smart about alt pressure kwargs
wholmgren Feb 20, 2016
ee32772
add basic_chain to modelchain
wholmgren Feb 20, 2016
99aea92
merge masters pep8 changes into this branch
wholmgren Feb 20, 2016
1494117
more pep8 and doc line length
wholmgren Feb 20, 2016
0002bd0
clean up modelchain documentation
wholmgren Mar 7, 2016
23d3727
remove unused mc stuff
wholmgren Mar 7, 2016
6448172
remove removed specificchain from classes doc
wholmgren Mar 7, 2016
67d45f8
add basic_chain to package_overview
wholmgren Mar 7, 2016
31e323d
add altitude and pressure kwargs to basic_chain
wholmgren Mar 7, 2016
a17379f
pin appveyors scipy to 0.16 to avoid yet another continuum package issue
wholmgren Mar 7, 2016
5280cb9
add test for orientation prop, altitude/pressure kwargs
wholmgren Mar 7, 2016
8c9c89d
correction, appveyor scipy=0.16.0. ugh
wholmgren Mar 7, 2016
ab69f9a
run_model now returns self
wholmgren Mar 7, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/sphinx/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ Contents

self
package_overview
whatsnew
modules
classes
comparison_pvlib_matlab
whatsnew
variables_style_rules


Indices and tables
Expand Down
133 changes: 87 additions & 46 deletions docs/sphinx/source/package_overview.rst
F438
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ is well-tested procedural code that implements PV system models.
pvlib-python also provides a collection of classes for users
that prefer object-oriented programming.
These classes can help users keep track of data in a more organized way,
and can help to simplify the modeling process.
The classes do not add any functionality beyond the procedural code.
Most of the object methods are simple wrappers around the
corresponding procedural code.
provide some "smart" functions with more flexible inputs,
and simplify the modeling process for common situations.
The classes do not add any algorithms beyond what's available
in the procedural code, and most of the object methods
are simple wrappers around the corresponding procedural code.

Let's use each of these pvlib modeling paradigms
to calculate the yearly energy yield for a given hardware
Expand All @@ -33,23 +34,31 @@ configuration at a handful of sites listed below.

import pandas as pd
import matplotlib.pyplot as plt

# seaborn makes the plots look nicer
import seaborn as sns
sns.set_color_codes()

times = pd.DatetimeIndex(start='2015', end='2016', freq='1h')

# very approximate
coordinates = [(30, -110, 'Tucson'),
(35, -105, 'Albuquerque'),
(40, -120, 'San Francisco'),
(50, 10, 'Berlin')]
# latitude, longitude, name, altitude
coordinates = [(30, -110, 'Tucson', 700),
(35, -105, 'Albuquerque', 1500),
(40, -120, 'San Francisco', 10),
(50, 10, 'Berlin', 34)]

import pvlib

# get the module and inverter specifications from SAM
sandia_modules = pvlib.pvsystem.retrieve_sam('SandiaMod')
sapm_inverters = pvlib.pvsystem.retrieve_sam('sandiainverter')
module = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
inverter = sapm_inverters['ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_']

# specify constant ambient air temp and wind for simplicity
temp_air = 20
wind_speed = 0


Procedural
Expand All @@ -67,13 +76,15 @@ to accomplish our system modeling goal:
'surface_azimuth': 180}

energies = {}
for latitude, longitude, name in coordinates:
for latitude, longitude, name, altitude in coordinates:
system['surface_tilt'] = latitude
cs = pvlib.clearsky.ineichen(times, latitude, longitude)
cs = pvlib.clearsky.ineichen(times, latitude, longitude, altitude=altitude)
solpos = pvlib.solarposition.get_solarposition(times, latitude, longitude)
dni_extra = pvlib.irradiance.extraradiation(times)
dni_extra = pd.Series(dni_extra, index=times)
airmass = pvlib.atmosphere.relativeairmass(solpos['apparent_zenith'])
pressure = pvlib.atmosphere.alt2pres(altitude)
am_abs = pvlib.atmosphere.absoluteairmass(airmass, pressure)
aoi = pvlib.irradiance.aoi(system['surface_tilt'], system['surface_azimuth'],
solpos['apparent_zenith'], solpos['azimuth'])
total_irrad = pvlib.irradiance.total_irrad(system['surface_tilt'],
Expand All @@ -83,10 +94,11 @@ to accomplish our system modeling goal:
cs['dni'], cs['ghi'], cs['dhi'],
dni_extra=dni_extra,
model='haydavies')
temps = pvlib.pvsystem.sapm_celltemp(total_irrad['poa_global'], 0, 20)
temps = pvlib.pvsystem.sapm_celltemp(total_irrad['poa_global'],
wind_speed, temp_air)
dc = pvlib.pvsystem.sapm(module, total_irrad['poa_direct'],
total_irrad['poa_diffuse'], temps['temp_cell'],
airmass, aoi)
am_abs, aoi)
ac = pvlib.pvsystem.snlinverter(inverter, dc['v_mp'], dc['p_mp'])
annual_energy = ac.sum()
energies[name] = annual_energy
Expand All @@ -105,11 +117,11 @@ Object oriented (Location, PVSystem, ModelChain)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The first object oriented paradigm uses a model where
a :class:`PVSystem <pvlib.pvsystem.PVSystem>` object represents an
a :py:class:`~pvlib.pvsystem.PVSystem` object represents an
assembled collection of modules, inverters, etc.,
a :class:`Location <pvlib.location.Location>` object represents a
a :py:class:`~pvlib.location.Location` object represents a
particular place on the planet,
and a :class:`ModelChain <pvlib.modelchain.ModelChain>` object describes
and a :py:class:`~pvlib.modelchain.ModelChain` object describes
the modeling chain used to calculate PV output at that Location.
This can be a useful paradigm if you prefer to think about
the PV system and its location as separate concepts or if
Expand All @@ -118,9 +130,9 @@ It can also be helpful if you make extensive use of Location-specific
methods for other calculations.

The following code demonstrates how to use
:class:`Location <pvlib.location.Location>`,
:class:`PVSystem <pvlib.pvsystem.PVSystem>`, and
:class:`ModelChain <pvlib.modelchain.ModelChain>`
:py:class:`~pvlib.location.Location`,
:py:class:`~pvlib.pvsystem.PVSystem`, and
:py:class:`~pvlib.modelchain.ModelChain`
objects to accomplish our system modeling goal:

.. ipython:: python
Expand All @@ -129,57 +141,86 @@ objects to accomplish our system modeling goal:
from pvlib.location import Location
from pvlib.modelchain import ModelChain

system = PVSystem(module, inverter, **other_params)
system = PVSystem(module_parameters=module,
inverter_parameters=inverter)

energies = {}
for latitude, longitude, name in coordinates:
location = Location(latitude, longitude)
# not yet clear what, exactly, goes into ModelChain(s)
mc = ModelChain(system, location, times,
'south_at_latitude', **other_modelchain_params)
output = mc.run_model()
annual_energy = output['power'].sum()
for latitude, longitude, name, altitude in coordinates:
location = Location(latitude, longitude, name=name, altitude=altitude)
# very experimental
mc = ModelChain(system, location,
orientation_strategy='south_at_latitude_tilt')
# optional parameters for irradiance and weather data
dc, ac = mc.run_model(times)
annual_energy = ac.sum()
energies[name] = annual_energy

#energies = pd.DataFrame(energies)
#energies.plot()
energies = pd.Series(energies)

# based on the parameters specified above, these are in W*hrs
print(energies.round(0))

energies.plot(kind='bar', rot=0)
@savefig modelchain-energies.png width=6in
plt.ylabel('Yearly energy yield (W hr)')


Object oriented (LocalizedPVSystem)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The second object oriented paradigm uses a model where a
:class:`LocalizedPVSystem <pvlib.pvsystem.LocalizedPVSystem>` represents a
:py:class:`~pvlib.pvsystem.LocalizedPVSystem` represents a
PV system at a particular place on the planet.
This can be a useful paradigm if you're thinking about
a power plant that already exists.

The following code demonstrates how to use a
:class:`LocalizedPVSystem <pvlib.pvsystem.LocalizedPVSystem>`
:py:class:`~pvlib.pvsystem.LocalizedPVSystem`
object to accomplish our modeling goal:

.. ipython:: python

from pvlib.pvsystem import PVSystem, LocalizedPVSystem

module =
inverter =
other_system_params = {} # sometime helpful to break apart
base_system = PVSystem(module, inverter, **other_system_params)
from pvlib.pvsystem import LocalizedPVSystem

energies = {}
for latitude, longitude, name in coordinates:
localized_system = base_system.localize(latitude, longitude, name=name)
localized_system.surface_tilt = latitude
cs = localized_system.get_clearsky(times)
solpos = localized_system.get_solarposition(times)
total_irrad = localized_system.get_irradiance(times, **solpos, **cs)
power = localized_system.get_power(stuff)
annual_energy = power.sum()
for latitude, longitude, name, altitude in coordinates:
localized_system = LocalizedPVSystem(module_parameters=module,
inverter_parameters=inverter,
surface_tilt=latitude,
surface_azimuth=180,
latitude=latitude,
longitude=longitude,
name=name,
altitude=altitude)
clearsky = localized_system.get_clearsky(times)
solar_position = localized_system.get_solarposition(times)
total_irrad = localized_system.get_irradiance(solar_position['apparent_zenith'],
solar_position['azimuth'],
clearsky['dni'],
clearsky['ghi'],
clearsky['dhi'])
temps = localized_system.sapm_celltemp(total_irrad['poa_global'],
wind_speed, temp_air)
aoi = localized_system.get_aoi(solar_position['apparent_zenith'],
solar_position['azimuth'])
airmass = localized_system.get_airmass(solar_position=solar_position)
dc = localized_system.sapm(total_irrad['poa_direct'],
total_irrad['poa_diffuse'],
temps['temp_cell'],
airmass['airmass_absolute'],
aoi)
ac = localized_system.snlinverter(dc['v_mp'], dc['p_mp'])
annual_energy = ac.sum()
energies[name] = annual_energy

#energies = pd.DataFrame(energies)
#energies.plot()
energies = pd.Series(energies)

# based on the parameters specified above, these are in W*hrs
print(energies.round(0))

energies.plot(kind='bar', rot=0)
@savefig localized-pvsystem-energies.png width=6in
plt.ylabel('Yearly energy yield (W hr)')


User extensions
Expand Down
34 changes: 32 additions & 2 deletions docs/sphinx/source/whatsnew/v0.3.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,49 @@ This is a major release from 0.2.2.
We recommend that all users upgrade to this version after testing
10000 their code for compatibility and updating as necessary.


Enhancements
~~~~~~~~~~~~

* Adds ``PVSystem`` and ``SingleAxisTracker`` classes. (:issue:`17`)
* Adds ``PVSystem``, ``LocalizedPVSystem``, ``ModelChain``,
and ``SingleAxisTracker`` classes. (:issue:`17`)
* Replaces ``location`` arguments with ``latitude``, ``longitude``,
``altitude``, and ``tz`` as appropriate.
This separates the object-oriented API from the procedural API.
(:issue:`17`)

* ``Location`` classes can be created from TMY2/TMY3 metadata
using the ``from_tmy`` constructor.
* ``Location`` classes gain the ``get_solarposition``, ``get_clearsky``,
and ``get_airmass`` functions.
* Add Package Overview and Classes pages to documentation.
* Adds support for Appveyor, a Windows continuous integration service.
(:issue:`111`)
* The readthedocs documentation build now uses conda packages
instead of mock packages. This enables code to be run
and figures to be generated during the documentation builds.
(:issue:`104`)
* Reconfigures TravisCI builds and adds e.g. ``has_numba`` decorators
to the test suite. The result is that the TravisCI test suite runs
almost 10x faster and users do not have to install all optional
dependencies to run the test suite. (:issue:`109`)
* Adds more unit tests that test that the return values are
actually correct.
* Add ``atmosphere.APPARENT_ZENITH_MODELS`` and
``atmosphere.TRUE_ZENITH_MODELS`` to enable code that can
automatically determine which type of zenith data to use
e.g. ``Location.get_airmass``.
* Change default ``Location`` timezone to ``'UTC'``.

Bug fixes
~~~~~~~~~

* ``pvsystem.sapm_celltemp`` argument names now follow the
variable conventions.
* ``irradiance.total_irrad`` now follows the variable conventions.
(:issue:`105`)
* Fixed the metadata key specification in documentation of the
readtmy2 function.


Contributors
~~~~~~~~~~~~
Expand Down
19 changes: 10 additions & 9 deletions pvlib/atmosphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

import numpy as np

AIRMASS_MODELS = ['kastenyoung1989', 'kasten1966', 'simple',
'pickering2002', 'youngirvine1967', 'young1994',
'gueymard1993']

APPARENT_ZENITH_MODELS = ('simple', 'kasten1966', 'kastenyoung1989',
'gueymard1993', 'pickering2002')
TRUE_ZENITH_MODELS = ('youngirvine1967', 'young1994')
AIRMASS_MODELS = APPARENT_ZENITH_MODELS + TRUE_ZENITH_MODELS


def pres2alt(pressure):
'''
Expand Down Expand Up @@ -143,12 +144,12 @@ def absoluteairmass(airmass_relative, pressure=101325.):

def relativeairmass(zenith, model='kastenyoung1989'):
'''
Gives the relative (not pressure-corrected) airmass
Gives the relative (not pressure-corrected) airmass.

Gives the airmass at sea-level when given a sun zenith angle, z (in
degrees).
The "model" variable allows selection of different airmass models
(described below). "model" must be a valid string. If "model" is not
Gives the airmass at sea-level when given a sun zenith angle
(in degrees).
The ``model`` variable allows selection of different airmass models
(described below). If ``model`` is not
included or is not valid, the default model is 'kastenyoung1989'.

Parameters
Expand Down
Loading
0