Skip to content

Raise ValueError in relativeairmass #129

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 3 commits into from
Mar 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 3 additions & 0 deletions docs/sphinx/source/whatsnew/v0.3.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ API changes
variable conventions.
* ``irradiance.total_irrad`` now follows the variable conventions.
(:issue:`105`)
* ``atmosphere.relativeairmass`` now raises a ValueError instead of
assuming ``'kastenyoung1989'`` if an invalid model is supplied.
(:issue:`119`)


Enhancements
Expand Down
171 changes: 82 additions & 89 deletions pvlib/atmosphere.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
"""
The ``atmosphere`` module contains methods to calculate
relative and absolute airmass and to determine
pressure from altitude or vice versa.
The ``atmosphere`` module contains methods to calculate relative and
absolute airmass and to determine pressure from altitude or vice versa.
"""

from __future__ import division

import logging
pvl_logger = logging.getLogger('pvlib')

import numpy as np

APPARENT_ZENITH_MODELS = ('simple', 'kasten1966', 'kastenyoung1989',
Expand All @@ -29,7 +25,7 @@ def pres2alt(pressure):
Returns
-------
altitude : scalar or Series
Altitude in meters above sea level
Altitude in meters above sea level

Notes
------
Expand All @@ -51,22 +47,20 @@ def pres2alt(pressure):

"A Quick Derivation relating altitude to air pressure" from Portland
State Aerospace Society, Version 1.03, 12/22/2004.

'''

alt = 44331.5 - 4946.62 * pressure ** (0.190263)
return alt



def alt2pres(altitude):
'''
Determine site pressure from altitude.

Parameters
----------
Altitude : scalar or Series
Altitude in meters above sea level
Altitude in meters above sea level

Returns
-------
Expand Down Expand Up @@ -100,29 +94,28 @@ def alt2pres(altitude):
return press



def absoluteairmass(airmass_relative, pressure=101325.):
'''
Determine absolute (pressure corrected) airmass from relative
Determine absolute (pressure corrected) airmass from relative
airmass and pressure

Gives the airmass for locations not at sea-level (i.e. not at standard
pressure). The input argument "AMrelative" is the relative airmass. The
input argument "pressure" is the pressure (in Pascals) at the location
of interest and must be greater than 0. The calculation for
absolute airmass is
Gives the airmass for locations not at sea-level (i.e. not at
standard pressure). The input argument "AMrelative" is the relative
airmass. The input argument "pressure" is the pressure (in Pascals)
at the location of interest and must be greater than 0. The
calculation for absolute airmass is

.. math::
absolute airmass = (relative airmass)*pressure/101325

Parameters
----------

airmass_relative : scalar or Series
The airmass at sea-level.
airmass_relative : scalar or Series
The airmass at sea-level.

pressure : scalar or Series
The site pressure in Pascal.
The site pressure in Pascal.

Returns
-------
Expand All @@ -131,9 +124,9 @@ def absoluteairmass(airmass_relative, pressure=101325.):

References
----------
[1] C. Gueymard, "Critical analysis and performance assessment of
clear sky solar irradiance models using theoretical and measured data,"
Solar Energy, vol. 51, pp. 121-138, 1993.
[1] C. Gueymard, "Critical analysis and performance assessment of
clear sky solar irradiance models using theoretical and measured
data," Solar Energy, vol. 51, pp. 121-138, 1993.

'''

Expand All @@ -146,106 +139,106 @@ def relativeairmass(zenith, model='kastenyoung1989'):
'''
Gives the relative (not pressure-corrected) airmass.

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'.
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
----------

zenith : float or Series
Zenith angle of the sun in degrees.
Note that some models use the apparent (refraction corrected)
zenith angle, and some models use the true
(not refraction-corrected) zenith angle.
See model descriptions to determine which type of zenith
angle is required.
Apparent zenith angles must be calculated at sea level.

model : String
zenith : float or Series
Zenith angle of the sun in degrees. Note that some models use
the apparent (refraction corrected) zenith angle, and some
models use the true (not refraction-corrected) zenith angle. See
model descriptions to determine which type of zenith angle is
required. Apparent zenith angles must be calculated at sea level.

model : String
Available models include the following:

* 'simple' - secant(apparent zenith angle) -
Note that this gives -inf at zenith=90
* 'kasten1966' - See reference [1] - requires apparent sun zenith
* 'youngirvine1967' - See reference [2] - requires true sun zenith
* 'kastenyoung1989' - See reference [3] - requires apparent sun zenith
* 'gueymard1993' - See reference [4] - requires apparent sun zenith
* 'young1994' - See reference [5] - requries true sun zenith
* 'pickering2002' - See reference [6] - requires apparent sun zenith
* 'kasten1966' - See reference [1] -
requires apparent sun zenith
* 'youngirvine1967' - See reference [2] -
requires true sun zenith
* 'kastenyoung1989' - See reference [3] -
requires apparent sun zenith
* 'gueymard1993' - See reference [4] -
requires apparent sun zenith
* 'young1994' - See reference [5] -
requries true sun zenith
* 'pickering2002' - See reference [6] -
requires apparent sun zenith

Returns
-------
airmass_relative : float or Series
Relative airmass at sea level. Will return NaN values for any
airmass_relative : float or Series
Relative airmass at sea level. Will return NaN values for any
zenith angle greater than 90 degrees.

References
----------

[1] Fritz Kasten. "A New Table and Approximation Formula for the
Relative Optical Air Mass". Technical Report 136, Hanover, N.H.: U.S.
Army Material Command, CRREL.
Relative Optical Air Mass". Technical Report 136, Hanover, N.H.:
U.S. Army Material Command, CRREL.

[2] A. T. Young and W. M. Irvine, "Multicolor Photoelectric Photometry
of the Brighter Planets," The Astronomical Journal, vol. 72,
pp. 945-950, 1967.
[2] A. T. Young and W. M. Irvine, "Multicolor Photoelectric
Photometry of the Brighter Planets," The Astronomical Journal, vol.
72, pp. 945-950, 1967.

[3] Fritz Kasten and Andrew Young. "Revised optical air mass tables and
approximation formula". Applied Optics 28:4735-4738
[3] Fritz Kasten and Andrew Young. "Revised optical air mass tables
and approximation formula". Applied Optics 28:4735-4738

[4] C. Gueymard, "Critical analysis and performance assessment of
clear sky solar irradiance models using theoretical and measured data,"
Solar Energy, vol. 51, pp. 121-138, 1993.
[4] C. Gueymard, "Critical analysis and performance assessment of
clear sky solar irradiance models using theoretical and measured
data," Solar Energy, vol. 51, pp. 121-138, 1993.

[5] A. T. Young, "AIR-MASS AND REFRACTION," Applied Optics, vol. 33,
[5] A. T. Young, "AIR-MASS AND REFRACTION," Applied Optics, vol. 33,
pp. 1108-1110, Feb 1994.

[6] Keith A. Pickering. "The Ancient Star Catalog". DIO 12:1, 20,
[7] Matthew J. Reno, Clifford W. Hansen and Joshua S. Stein,
"Global Horizontal Irradiance Clear Sky Models: Implementation and Analysis"

[7] Matthew J. Reno, Clifford W. Hansen and Joshua S. Stein, "Global
Horizontal Irradiance Clear Sky Models: Implementation and Analysis"
Sandia Report, (2012).
'''

z = zenith
zenith_rad = np.radians(z)

model = model.lower()

if 'kastenyoung1989' == model:
AM = ( 1.0 / (np.cos(zenith_rad) +
0.50572*(((6.07995 + (90 - z)) ** - 1.6364))) )
am = (1.0 / (np.cos(zenith_rad) +
0.50572*(((6.07995 + (90 - z)) ** - 1.6364))))
elif 'kasten1966' == model:
AM = 1.0 / (np.cos(zenith_rad) + 0.15*((93.885 - z) ** - 1.253))
am = 1.0 / (np.cos(zenith_rad) + 0.15*((93.885 - z) ** - 1.253))
elif 'simple' == model:
AM = 1.0 / np.cos(zenith_rad)
am = 1.0 / np.cos(zenith_rad)
elif 'pickering2002' == model:
AM = ( 1.0 / (np.sin(np.radians(90 - z +
244.0 / (165 + 47.0 * (90 - z) ** 1.1)))) )
am = (1.0 / (np.sin(np.radians(90 - z +
244.0 / (165 + 47.0 * (90 - z) ** 1.1)))))
elif 'youngirvine1967' == model:
AM = ( (1.0 / np.cos(zenith_rad)) *
(1 - 0.0012*( (1.0 / np.cos(zenith_rad)) ** 2) - 1) )
am = ((1.0 / np.cos(zenith_rad)) *
(1 - 0.0012*((1.0 / np.cos(zenith_rad)) ** 2) - 1))
elif 'young1994' == model:
AM = ( (1.002432*((np.cos(zenith_rad)) ** 2) +
0.148386*(np.cos(zenith_rad)) + 0.0096467) /
(np.cos(zenith_rad) ** 3 +
0.149864*(np.cos(zenith_rad) ** 2) +
0.0102963*(np.cos(zenith_rad)) + 0.000303978) )
am = ((1.002432*((np.cos(zenith_rad)) ** 2) +
0.148386*(np.cos(zenith_rad)) + 0.0096467) /
(np.cos(zenith_rad) ** 3 +
0.149864*(np.cos(zenith_rad) ** 2) +
0.0102963*(np.cos(zenith_rad)) + 0.000303978))
elif 'gueymard1993' == model:
AM = ( 1.0 / (np.cos(zenith_rad) +
0.00176759*(z)*((94.37515 - z) ** - 1.21563)) )
am = (1.0 / (np.cos(zenith_rad) +
0.00176759*(z)*((94.37515 - z) ** - 1.21563)))
else:
pvl_logger.warning("%s is not a valid model type for relative airmass. The 'kastenyoung1989' model was used.",
model)
AM = ( 1.0 / (np.cos(zenith_rad) +
0.50572*(((6.07995 + (90 - z)) ** - 1.6364))) )

raise ValueError('%s is not a valid model for relativeairmass', model)

try:
AM[z > 90] = np.nan
am[z > 90] = np.nan
except TypeError:
AM = np.nan if z > 90 else AM
return AM
am = np.nan if z > 90 else am

return am
13 changes: 9 additions & 4 deletions pvlib/test/test_atmosphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


# setup times and location to be tested.
times = pd.date_range(start=datetime.datetime(2014,6,24),
times = pd.date_range(start=datetime.datetime(2014,6,24),
end=datetime.datetime(2014,6,26), freq='1Min')

tus = Location(32.2, -111, 'US/Arizona', 700)
Expand All @@ -30,23 +30,28 @@

def test_pres2alt():
atmosphere.pres2alt(100000)

def test_alt2press():
atmosphere.pres2alt(1000)


# two functions combined will generate unique unit tests for each model
def test_airmasses():
models = ['simple', 'kasten1966', 'youngirvine1967', 'kastenyoung1989',
'gueymard1993', 'young1994', 'pickering2002', 'invalid']
'gueymard1993', 'young1994', 'pickering2002']
for model in models:
yield run_airmass, model, ephem_data['zenith']


def run_airmass(model, zenith):
atmosphere.relativeairmass(zenith, model)



@raises(ValueError)
def test_airmass_invalid():
atmosphere.relativeairmass(ephem_data['zenith'], 'invalid')


def test_absoluteairmass():
relative_am = atmosphere.relativeairmass(ephem_data['zenith'], 'simple')
atmosphere.absoluteairmass(relative_am)
Expand Down