@@ -196,8 +196,8 @@ def lookup_linke_turbidity(time, latitude, longitude, filepath=None,
196196 try :
197197 import scipy .io
198198 except ImportError :
199- raise ImportError ('The Linke turbidity lookup table requires scipy. ' +
200- 'You can still use clearsky.ineichen if you ' +
199+ raise ImportError ('The Linke turbidity lookup table requires scipy. '
200+ 'You can still use clearsky.ineichen if you '
201201 'supply your own turbidities.' )
202202
203203 if filepath is None :
@@ -214,54 +214,95 @@ def lookup_linke_turbidity(time, latitude, longitude, filepath=None,
214214 np .around (_linearly_scale (longitude , - 180 , 180 , 0 , 4320 ))
215215 .astype (np .int64 ))
216216
217- g = linke_turbidity_table [latitude_index ][longitude_index ]
217+ lts = linke_turbidity_table [latitude_index ][longitude_index ]
218218
219219 if interp_turbidity :
220- # Data covers 1 year. Assume that data corresponds to the value at the
221- # middle of each month. This means that we need to add previous Dec and
222- # next Jan to the array so that the interpolation will work for
223- # Jan 1 - Jan 15 and Dec 16 - Dec 31.
224- g2 = np .concatenate ([[g [- 1 ]], g , [g [0 ]]])
225- # Then we map the month value to the day of year value.
226- isleap = [calendar .isleap (t .year ) for t in time ]
227- if all (isleap ):
228- days = _calendar_month_middles (2016 ) # all years are leap
229- elif not any (isleap ):
230- days = _calendar_month_middles (2015 ) # none of the years are leap
231- else :
232- days = None # some of the years are leap years and some are not
233- if days is None :
234- # Loop over different years, might be slow for large timeserires
235- linke_turbidity = pd .Series ([
236- np .interp (t .dayofyear , _calendar_month_middles (t .year ), g2 )
237- for t in time
238- ], index = time )
239- else :
240- linke_turbidity = pd .Series (np .interp (time .dayofyear , days , g2 ),
241- index = time )
220+ linke_turbidity = _interpolate_turbidity (lts , time )
242221 else :
243- linke_turbidity = pd .DataFrame (time .month , index = time )
244- # apply monthly data
245- linke_turbidity = linke_turbidity .apply (lambda x : g [x [0 ]- 1 ], axis = 1 )
222+ months = time .month - 1
223+ linke_turbidity = pd .Series (lts [months ], index = time )
246224
247225 linke_turbidity /= 20.
248226
249227 return linke_turbidity
250228
251229
230+ def _is_leap_year (year ):
231+ """Determine if a year is leap year.
232+
233+ Parameters
234+ ----------
235+ year : numeric
236+
237+ Returns
238+ -------
239+ isleap : array of bools
240+ """
241+ isleap = ((np .mod (year , 4 ) == 0 ) &
242+ ((np .mod (year , 100 ) != 0 ) | (np .mod (year , 400 ) == 0 )))
243+ return isleap
244+
245+
246+ def _interpolate_turbidity (lts , time ):
247+ """
248+ Interpolated monthly Linke turbidity onto daily values.
249+
250+ Parameters
251+ ----------
252+ lts : np.array
253+ Monthly Linke turbidity values.
254+ time : pd.DatetimeIndex
255+ Times to be interpolated onto.
256+
257+ Returns
258+ -------
259+ linke_turbidity : pd.Series
260+ The interpolated turbidity.
261+ """
262+ # Data covers 1 year. Assume that data corresponds to the value at the
263+ # middle of each month. This means that we need to add previous Dec and
264+ # next Jan to the array so that the interpolation will work for
265+ # Jan 1 - Jan 15 and Dec 16 - Dec 31.
266+ lts_concat = np .concatenate ([[lts [- 1 ]], lts , [lts [0 ]]])
267+
268+ # handle leap years
269+ try :
270+ isleap = time .is_leap_year
271+ except AttributeError :
272+ year = time .year
273+ isleap = _is_leap_year (year )
274+
275+ dayofyear = time .dayofyear
276+ days_leap = _calendar_month_middles (2016 )
277+ days_no_leap = _calendar_month_middles (2015 )
278+
279+ # Then we map the month value to the day of year value.
280+ # Do it for both leap and non-leap years.
281+ lt_leap = np .interp (dayofyear , days_leap , lts_concat )
282+ lt_no_leap = np .interp (dayofyear , days_no_leap , lts_concat )
283+ linke_turbidity = np .where (isleap , lt_leap , lt_no_leap )
284+
285+ linke_turbidity = pd .Series (linke_turbidity , index = time )
286+
287+ return linke_turbidity
288+
289+
252290def _calendar_month_middles (year ):
253- """list of middle day of each month, used by Linke turbidity lookup"""
291+ """List of middle day of each month, used by Linke turbidity lookup"""
254292 # remove mdays[0] since January starts at mdays[1]
255- # make local copy of mdays since we need to change February for leap years
293+ # make local copy of mdays since we need to change
294+ # February for leap years
256295 mdays = np .array (calendar .mdays [1 :])
257296 ydays = 365
258297 # handle leap years
259298 if calendar .isleap (year ):
260299 mdays [1 ] = mdays [1 ] + 1
261300 ydays = 366
262- return np .concatenate ([[- calendar .mdays [- 1 ] / 2.0 ], # Dec last year
263- np .cumsum (mdays ) - np .array (mdays ) / 2. , # this year
264- [ydays + calendar .mdays [1 ] / 2.0 ]]) # Jan next year
301+ middles = np .concatenate (
302+ [[- calendar .mdays [- 1 ] / 2.0 ], # Dec last year
303+ np .cumsum (mdays ) - np .array (mdays ) / 2. , # this year
304+ [ydays + calendar .mdays [1 ] / 2.0 ]]) # Jan next year
305+ return middles
265306
266307
267308def _linearly_scale (inputmatrix , inputmin , inputmax , outputmin , outputmax ):
@@ -294,8 +335,8 @@ def haurwitz(apparent_zenith):
294335
295336 Implements the Haurwitz clear sky model for global horizontal
296337 irradiance (GHI) as presented in [1, 2]. A report on clear
297- sky models found the Haurwitz model to have the best performance
298- in terms of average monthly error among models which require only
338+ sky models found the Haurwitz model to have the best performance
339+ in terms of average monthly error among models which require only
299340 zenith angle [3].
300341
301342 Parameters
0 commit comments