Skip to content

Commit ec329e2

Browse files
mikofskiwholmgren
authored andcommitted
DOC: Discuss Angstrom Kasten TL, set default alpha (#563)
* DOC: add example for Kasten pyrheliometric formula * closes #302 * add references to Kasten 96 and Molineaux * discuss using Kasten and calculating broadband AOD usinge Angstrom turbidity model Signed-off-by: Mark Mikofski <[email protected]> * DOC: update what's new, add refs to Bird & Hulstrom and Angstrom * DOC: split sentences, replace abbrev. AOD * use TMY in pvlib/data, lowercase MBARS, use non-specific variable names * split output from readtmy3 instead of using indexing for clarity * DOC: fix up ipython example * DOC: split sentences, revise, add angstrom example * ENH: set default alpha to 1.14, update what's new * DOC: use coerce year, use v0.6.0 get_property() for airmass * DOC: print calculated AOD, move TL calculation after turbidity section * DOC: wrap long lines, abbrev AOD, be explicit re: fictitious AOD
1 parent fec0679 commit ec329e2

File tree

3 files changed

+104
-11
lines changed

3 files changed

+104
-11
lines changed

docs/sphinx/source/clearsky.rst

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,12 @@ time series of clear sky data for a location. The :ref:`ineichen` and
2626
input data. The :ref:`detect_clearsky` subsection demonstrates the use
2727
of the clear sky detection algorithm.
2828

29-
The :py:func:`~pvlib.atmosphere.bird_hulstrom80_aod_bb`, and
30-
:py:func:`~pvlib.atmosphere.kasten96_lt` functions are useful for
31-
calculating inputs to the clear sky functions.
32-
3329
We'll need these imports for the examples below.
3430

3531
.. ipython::
3632

33+
In [1]: import os
34+
3735
In [1]: import itertools
3836

3937
In [1]: import matplotlib.pyplot as plt
@@ -42,7 +40,7 @@ We'll need these imports for the examples below.
4240

4341
In [1]: import pvlib
4442

45-
In [1]: from pvlib import clearsky, atmosphere
43+
In [1]: from pvlib import clearsky, atmosphere, tmy, solarposition
4644

4745
In [1]: from pvlib.location import Location
4846

@@ -118,6 +116,7 @@ The Ineichen and Perez clear sky model parameterizes irradiance in terms
118116
of the Linke turbidity [Ine02]_. pvlib-python implements this model in
119117
the :py:func:`pvlib.clearsky.ineichen` function.
120118

119+
121120
Turbidity data
122121
^^^^^^^^^^^^^^
123122

@@ -198,6 +197,62 @@ varies from 300 m to 1500 m.
198197
@savefig turbidity-yes-interp.png width=6in
199198
In [1]: plt.ylabel('Linke Turbidity');
200199

200+
The :py:func:`~pvlib.atmosphere.kasten96_lt` function can be used to calculate
201+
Linke turbidity [Kas96]_ as input to the clear sky Ineichen and Perez function.
202+
The Kasten formulation requires precipitable water and broadband aerosol
203+
optical depth (AOD). According to Molineaux, broadband AOD can be approximated
204+
by a single measurement at 700-nm [Mol98]_. An alternate broadband AOD
205+
approximation from Bird and Hulstrom combines AOD measured at two
206+
wavelengths [Bir80]_, and is implemented in
207+
:py:func:`~pvlib.atmosphere.bird_hulstrom80_aod_bb`.
208+
209+
.. ipython::
210+
211+
In [1]: pvlib_data = os.path.join(os.path.dirname(pvlib.__file__), 'data')
212+
213+
In [1]: mbars = 100 # conversion factor from mbars to Pa
214+
215+
In [1]: tmy_file = os.path.join(pvlib_data, '703165TY.csv') # TMY file
216+
217+
In [1]: tmy_data, tmy_header = tmy.readtmy3(tmy_file, coerce_year=1999) # read TMY data
218+
219+
In [1]: tl_historic = clearsky.lookup_linke_turbidity(time=tmy_data.index,
220+
...: latitude=tmy_header['latitude'], longitude=tmy_header['longitude'])
221+
222+
In [1]: solpos = solarposition.get_solarposition(time=tmy_data.index,
223+
...: latitude=tmy_header['latitude'], longitude=tmy_header['longitude'],
224+
...: altitude=tmy_header['altitude'], pressure=tmy_data['Pressure']*mbars,
225+
...: temperature=tmy_data['DryBulb'])
226+
227+
In [1]: am_rel = atmosphere.get_relative_airmass(solpos.apparent_zenith)
228+
229+
In [1]: am_abs = atmosphere.get_absolute_airmass(am_rel, tmy_data['Pressure']*mbars)
230+
231+
In [1]: airmass = pd.concat([am_rel, am_abs], axis=1).rename(
232+
...: columns={0: 'airmass_relative', 1: 'airmass_absolute'})
233+
234+
In [1]: tl_calculated = atmosphere.kasten96_lt(
235+
...: airmass.airmass_absolute, tmy_data['Pwat'], tmy_data['AOD'])
236+
237+
In [1]: tl = pd.concat([tl_historic, tl_calculated], axis=1).rename(
238+
...: columns={0:'Historic', 1:'Calculated'})
239+
240+
In [1]: tl.index = tmy_data.index.tz_convert(None) # remove timezone
241+
242+
In [1]: tl.resample('W').mean().plot();
243+
244+
In [1]: plt.grid()
245+
246+
In [1]: plt.title('Comparison of Historic Linke Turbidity Factors vs. \n'
247+
...: 'Kasten Pyrheliometric Formula at {name:s}, {state:s} ({usaf:d}TY)'.format(
248+
...: name=tmy_header['Name'], state=tmy_header['State'], usaf=tmy_header['USAF']));
249+
250+
In [1]: plt.ylabel('Linke Turbidity Factor, TL');
251+
252+
@savefig kasten-tl.png width=10in
253+
In [1]: plt.tight_layout()
254+
255+
201256
Examples
202257
^^^^^^^^
203258

@@ -326,11 +381,32 @@ contain one or both of aerosols and precipitable water. Consider data
326381
from the `ECMWF <https://software.ecmwf.int/wiki/display/WEBAPI/Access+ECMWF+Public+Datasets>`_
327382
and `SoDa <http://www.soda-pro.com/web-services/radiation/cams-mcclear>`_.
328383

329-
Aerosol optical depth is a function of wavelength, and the Simplified
330-
Solis model requires AOD at 700 nm. Models exist to convert AOD between
331-
different wavelengths, as well as convert Linke turbidity to AOD and PW
332-
[Ine08con]_, [Ine16]_.
384+
Aerosol optical depth (AOD) is a function of wavelength, and the Simplified
385+
Solis model requires AOD at 700 nm.
386+
:py:func:`~pvlib.atmosphere.angstrom_aod_at_lambda` is useful for converting
387+
AOD between different wavelengths using the Angstrom turbidity model. The
388+
Angstrom exponent, :math:`\alpha`, can be calculated from AOD at two
389+
wavelengths with :py:func:`~pvlib.atmosphere.angstrom_alpha`.
390+
[Ine08con]_, [Ine16]_, [Ang61]_.
391+
392+
.. ipython::
393+
394+
In [1]: aod1240nm = 1.2 # fictitious AOD measured at 1240-nm
395+
396+
In [1]: aod550nm = 3.1 # fictitious AOD measured at 550-nm
333397

398+
In [1]: alpha_exponent = atmosphere.angstrom_alpha(aod1240nm, 1240, aod550nm, 550)
399+
400+
In [1]: aod700nm = atmosphere.angstrom_aod_at_lambda(aod1240nm, 1240, alpha_exponent, 700)
401+
402+
In [1]: aod380nm = atmosphere.angstrom_aod_at_lambda(aod550nm, 550, alpha_exponent, 380)
403+
404+
In [1]: aod500nm = atmosphere.angstrom_aod_at_lambda(aod550nm, 550, alpha_exponent, 500)
405+
406+
In [1]: aod_bb = atmosphere.bird_hulstrom80_aod_bb(aod380nm, aod500nm)
407+
408+
In [1]: print('compare AOD at 700-nm = {:g}, to estimated broadband AOD = {:g}, '
409+
...: 'with alpha = {:g}'.format(aod700nm, aod_bb, alpha_exponent))
334410

335411
Examples
336412
^^^^^^^^
@@ -617,3 +693,17 @@ References
617693
.. [Ren16] Reno, M.J. and C.W. Hansen, "Identification of periods of clear
618694
sky irradiance in time series of GHI measurements" Renewable Energy,
619695
v90, p. 520-531, 2016.
696+
697+
.. [Mol98] B. Molineaux, P. Ineichen, and N. O’Neill, “Equivalence of
698+
pyrheliometric and monochromatic aerosol optical depths at a single key
699+
wavelength.,” Appl. Opt., vol. 37, no. 30, pp. 7008–18, Oct. 1998.
700+
701+
.. [Kas96] F. Kasten, “The linke turbidity factor based on improved values
702+
of the integral Rayleigh optical thickness,” Sol. Energy, vol. 56, no. 3,
703+
pp. 239–244, Mar. 1996.
704+
705+
.. [Bir80] R. E. Bird and R. L. Hulstrom, “Direct Insolation Models,”
706+
1980.
707+
708+
.. [Ang61] A. ÅNGSTRÖM, “Techniques of Determinig the Turbidity of the
709+
Atmosphere,” Tellus A, vol. 13, no. 2, pp. 214–223, 1961.

docs/sphinx/source/whatsnew/v0.6.0.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ Enhancements
107107
* Add irradiance.clearness_index_zenith_independent function. (:issue:`396`)
108108
* Add checking for consistency between module_parameters and dc_model. (:issue:`417`)
109109
* Add DC model methods desoto and pvsyst to ModelChain (:issue:`487`)
110+
* Set default alpha to 1.14 in :func:`~pvlib.atmosphere.angstrom_aod_at_lambda` (:issue:`563`)
110111

111112

112113
Bug fixes
@@ -152,6 +153,8 @@ Documentation
152153
top-level "Intro Examples" page.
153154
* Copy pvlib documentation's "Getting support" section to README.md.
154155
* Add PVSystem documentation page. (:issue:`514`, :issue:`319`)
156+
* Add example of Kasten Linke Turbidity calculation, discuss broadband AOD and
157+
Angstrom Turbidity Model. (:issue:`302`)
155158

156159

157160
Testing

pvlib/atmosphere.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ def kasten96_lt(airmass_absolute, precipitable_water, aod_bb):
621621
return lt
622622

623623

624-
def angstrom_aod_at_lambda(aod0, lambda0, alpha, lambda1=700.0):
624+
def angstrom_aod_at_lambda(aod0, lambda0, alpha=1.14, lambda1=700.0):
625625
r"""
626626
Get AOD at specified wavelength using Angstrom turbidity model.
627627
@@ -631,7 +631,7 @@ def angstrom_aod_at_lambda(aod0, lambda0, alpha, lambda1=700.0):
631631
aerosol optical depth (AOD) measured at known wavelength
632632
lambda0 : numeric
633633
wavelength in nanometers corresponding to ``aod0``
634-
alpha : numeric
634+
alpha : numeric, default 1.14
635635
Angstrom :math:`\alpha` exponent corresponding to ``aod0``
636636
lambda1 : numeric, default 700
637637
desired wavelength in nanometers

0 commit comments

Comments
 (0)