From 4b3a7bbfb636b451ac074ec29e14a125c352a000 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 11 Mar 2016 19:41:11 -0700 Subject: [PATCH 1/3] fix whitespace --- pvlib/atmosphere.py | 54 +++++++++++++++++------------------ pvlib/test/test_atmosphere.py | 6 ++-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index d61315ba23..1bc77388b0 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -1,5 +1,5 @@ """ -The ``atmosphere`` module contains methods to calculate +The ``atmosphere`` module contains methods to calculate relative and absolute airmass and to determine pressure from altitude or vice versa. """ @@ -29,7 +29,7 @@ def pres2alt(pressure): Returns ------- altitude : scalar or Series - Altitude in meters above sea level + Altitude in meters above sea level Notes ------ @@ -66,7 +66,7 @@ def alt2pres(altitude): Parameters ---------- Altitude : scalar or Series - Altitude in meters above sea level + Altitude in meters above sea level Returns ------- @@ -103,7 +103,7 @@ def alt2pres(altitude): 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 @@ -111,18 +111,18 @@ def absoluteairmass(airmass_relative, pressure=101325.): 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 ------- @@ -131,7 +131,7 @@ def absoluteairmass(airmass_relative, pressure=101325.): References ---------- - [1] C. Gueymard, "Critical analysis and performance assessment of + [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. @@ -147,26 +147,26 @@ 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). + (in degrees). The ``model`` variable allows selection of different airmass models - (described below). If ``model`` is not + (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. + 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 + + 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 @@ -178,8 +178,8 @@ def relativeairmass(zenith, model='kastenyoung1989'): 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 @@ -190,31 +190,31 @@ def relativeairmass(zenith, model='kastenyoung1989'): Army Material Command, CRREL. [2] A. T. Young and W. M. Irvine, "Multicolor Photoelectric Photometry - of the Brighter Planets," The Astronomical Journal, vol. 72, + 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 - [4] C. Gueymard, "Critical analysis and performance assessment of + [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" 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))) ) @@ -242,10 +242,10 @@ def relativeairmass(zenith, model='kastenyoung1989'): model) AM = ( 1.0 / (np.cos(zenith_rad) + 0.50572*(((6.07995 + (90 - z)) ** - 1.6364))) ) - + try: AM[z > 90] = np.nan except TypeError: AM = np.nan if z > 90 else AM - + return AM diff --git a/pvlib/test/test_atmosphere.py b/pvlib/test/test_atmosphere.py index 2466c9a549..737fc0a853 100644 --- a/pvlib/test/test_atmosphere.py +++ b/pvlib/test/test_atmosphere.py @@ -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) @@ -30,7 +30,7 @@ def test_pres2alt(): atmosphere.pres2alt(100000) - + def test_alt2press(): atmosphere.pres2alt(1000) @@ -46,7 +46,7 @@ def test_airmasses(): def run_airmass(model, zenith): atmosphere.relativeairmass(zenith, model) - + def test_absoluteairmass(): relative_am = atmosphere.relativeairmass(ephem_data['zenith'], 'simple') atmosphere.absoluteairmass(relative_am) From ac6eadd3f4a791069b580cd0984f2698cc4eec0f Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 11 Mar 2016 19:44:20 -0700 Subject: [PATCH 2/3] raise valueerror --- pvlib/atmosphere.py | 8 +------- pvlib/test/test_atmosphere.py | 7 ++++++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index 1bc77388b0..762cd5f9e3 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -6,9 +6,6 @@ from __future__ import division -import logging -pvl_logger = logging.getLogger('pvlib') - import numpy as np APPARENT_ZENITH_MODELS = ('simple', 'kasten1966', 'kastenyoung1989', @@ -238,10 +235,7 @@ def relativeairmass(zenith, model='kastenyoung1989'): 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 diff --git a/pvlib/test/test_atmosphere.py b/pvlib/test/test_atmosphere.py index 737fc0a853..f570d75ebb 100644 --- a/pvlib/test/test_atmosphere.py +++ b/pvlib/test/test_atmosphere.py @@ -38,7 +38,7 @@ def test_alt2press(): # 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'] @@ -47,6 +47,11 @@ 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) From 4dce6e7998cecdff1eca5fd2420fb5d5e4dab3f2 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 11 Mar 2016 19:49:46 -0700 Subject: [PATCH 3/3] internal pep8 changes --- docs/sphinx/source/whatsnew/v0.3.0.txt | 3 + pvlib/atmosphere.py | 119 ++++++++++++------------- 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.3.0.txt b/docs/sphinx/source/whatsnew/v0.3.0.txt index 70139f18b0..d96046e135 100644 --- a/docs/sphinx/source/whatsnew/v0.3.0.txt +++ b/docs/sphinx/source/whatsnew/v0.3.0.txt @@ -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 diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index 762cd5f9e3..5f86036012 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -1,7 +1,6 @@ """ -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 @@ -48,14 +47,12 @@ 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. @@ -97,17 +94,16 @@ def alt2pres(altitude): return press - def absoluteairmass(airmass_relative, pressure=101325.): ''' 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 @@ -129,8 +125,8 @@ 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. + clear sky solar irradiance models using theoretical and measured + data," Solar Energy, vol. 51, pp. 121-138, 1993. ''' @@ -143,35 +139,38 @@ 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. + 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 ------- @@ -183,27 +182,27 @@ def relativeairmass(zenith, model='kastenyoung1989'): ---------- [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. + 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, 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). ''' @@ -213,33 +212,33 @@ def relativeairmass(zenith, model='kastenyoung1989'): 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: 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 + am = np.nan if z > 90 else am - return AM + return am