diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index fb8775a190..46cbd2a110 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -317,8 +317,8 @@ def gueymard94_pw(temp_air, relative_humidity): 1294-1300. """ - T = temp_air + 273.15 # Convert to Kelvin - RH = relative_humidity + T = temp_air + 273.15 # Convert to Kelvin # noqa: N806 + RH = relative_humidity # noqa: N806 theta = T / 273.15 @@ -473,7 +473,7 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None, _coefficients['cigs'] = ( 0.85252, -0.022314, -0.0047216, 0.13666, 0.013342, -0.0008945) _coefficients['asi'] = ( - 1.12094, -0.047620, -0.0083627, -0.10443, 0.098382,-0.0033818) + 1.12094, -0.047620, -0.0083627, -0.10443, 0.098382, -0.0033818) if module_type is not None and coefficients is None: coefficients = _coefficients[module_type.lower()] diff --git a/pvlib/clearsky.py b/pvlib/clearsky.py index 72544f8dde..d6e92ec297 100644 --- a/pvlib/clearsky.py +++ b/pvlib/clearsky.py @@ -12,7 +12,7 @@ import numpy as np import pandas as pd -from pvlib import tools, atmosphere, solarposition, irradiance +from pvlib import atmosphere, tools def ineichen(apparent_zenith, airmass_absolute, linke_turbidity, @@ -204,7 +204,8 @@ def lookup_linke_turbidity(time, latitude, longitude, filepath=None, lt_h5_file = tables.open_file(filepath) try: - lts = lt_h5_file.root.LinkeTurbidity[latitude_index, longitude_index, :] + lts = lt_h5_file.root.LinkeTurbidity[latitude_index, + longitude_index, :] except IndexError: raise IndexError('Latitude should be between 90 and -90, ' 'longitude between -180 and 180.') @@ -364,8 +365,9 @@ def haurwitz(apparent_zenith): cos_zenith = tools.cosd(apparent_zenith.values) clearsky_ghi = np.zeros_like(apparent_zenith.values) - clearsky_ghi[cos_zenith>0] = 1098.0 * cos_zenith[cos_zenith>0] * \ - np.exp(-0.059/cos_zenith[cos_zenith>0]) + cos_zen_gte_0 = cos_zenith > 0 + clearsky_ghi[cos_zen_gte_0] = (1098.0 * cos_zenith[cos_zen_gte_0] * + np.exp(-0.059/cos_zenith[cos_zen_gte_0])) df_out = pd.DataFrame(index=apparent_zenith.index, data=clearsky_ghi, @@ -675,14 +677,14 @@ def detect_clearsky(measured, clearsky, times, window_length, if len(unique_deltas) == 1: sample_interval = unique_deltas[0] else: - raise NotImplementedError('algorithm does not yet support unequal ' \ + raise NotImplementedError('algorithm does not yet support unequal ' 'times. consider resampling your data.') samples_per_window = int(window_length / sample_interval) # generate matrix of integers for creating windows with indexing from scipy.linalg import hankel - H = hankel(np.arange(samples_per_window), + H = hankel(np.arange(samples_per_window), # noqa: N806 np.arange(samples_per_window-1, len(times))) # calculate measurement statistics @@ -729,14 +731,16 @@ def detect_clearsky(measured, clearsky, times, window_length, previous_alpha = alpha clear_meas = measured[clear_samples] clear_clear = clearsky[clear_samples] + def rmse(alpha): return np.sqrt(np.mean((clear_meas - alpha*clear_clear)**2)) + alpha = minimize_scalar(rmse).x if round(alpha*10000) == round(previous_alpha*10000): break else: import warnings - warnings.warn('failed to converge after %s iterations' \ + warnings.warn('failed to converge after %s iterations' % max_iterations, RuntimeWarning) # be polite about returning the same type as was input @@ -765,17 +769,18 @@ def bird(zenith, airmass_relative, aod380, aod500, precipitable_water, Based on NREL Excel implementation by Daryl R. Myers [1, 2]. - Bird and Hulstrom define the zenith as the "angle between a line to the sun - and the local zenith". There is no distinction in the paper between solar - zenith and apparent (or refracted) zenith, but the relative airmass is - defined using the Kasten 1966 expression, which requires apparent zenith. - Although the formulation for calculated zenith is never explicitly defined - in the report, since the purpose was to compare existing clear sky models - with "rigorous radiative transfer models" (RTM) it is possible that apparent - zenith was obtained as output from the RTM. However, the implentation - presented in PVLIB is tested against the NREL Excel implementation by Daryl - Myers which uses an analytical expression for solar zenith instead of - apparent zenith. + Bird and Hulstrom define the zenith as the "angle between a line to + the sun and the local zenith". There is no distinction in the paper + between solar zenith and apparent (or refracted) zenith, but the + relative airmass is defined using the Kasten 1966 expression, which + requires apparent zenith. Although the formulation for calculated + zenith is never explicitly defined in the report, since the purpose + was to compare existing clear sky models with "rigorous radiative + transfer models" (RTM) it is possible that apparent zenith was + obtained as output from the RTM. However, the implentation presented + in PVLIB is tested against the NREL Excel implementation by Daryl + Myers which uses an analytical expression for solar zenith instead + of apparent zenith. Parameters ---------- @@ -824,7 +829,8 @@ def bird(zenith, airmass_relative, aod380, aod500, precipitable_water, `SERI/TR-642-761 `_ - `Error Reports `_ + `Error Reports + `_ """ etr = dni_extra # extraradiation ze_rad = np.deg2rad(zenith) # zenith in radians diff --git a/pvlib/forecast.py b/pvlib/forecast.py index fcf3952dd9..1d70be3ed1 100644 --- a/pvlib/forecast.py +++ b/pvlib/forecast.py @@ -574,9 +574,9 @@ def isobaric_to_ambient_temperature(self, data): Temperature in K """ - P = data['pressure'] / 100.0 - Tiso = data['temperature_iso'] - Td = data['temperature_dew_iso'] - 273.15 + P = data['pressure'] / 100.0 # noqa: N806 + Tiso = data['temperature_iso'] # noqa: N806 + Td = data['temperature_dew_iso'] - 273.15 # noqa: N806 # saturation water vapor pressure e = 6.11 * 10**((7.5 * Td) / (Td + 273.3)) @@ -584,9 +584,9 @@ def isobaric_to_ambient_temperature(self, data): # saturation water vapor mixing ratio w = 0.622 * (e / (P - e)) - T = Tiso - ((2.501 * 10.**6) / 1005.7) * w + temperature = Tiso - ((2.501 * 10.**6) / 1005.7) * w - return T + return temperature def uv_to_speed(self, data): """ @@ -670,13 +670,19 @@ def __init__(self, resolution='half', set_type='best'): 'wind_speed_gust': 'Wind_speed_gust_surface', 'wind_speed_u': 'u-component_of_wind_isobaric', 'wind_speed_v': 'v-component_of_wind_isobaric', - 'total_clouds': 'Total_cloud_cover_entire_atmosphere_Mixed_intervals_Average', - 'low_clouds': 'Total_cloud_cover_low_cloud_Mixed_intervals_Average', - 'mid_clouds': 'Total_cloud_cover_middle_cloud_Mixed_intervals_Average', - 'high_clouds': 'Total_cloud_cover_high_cloud_Mixed_intervals_Average', - 'boundary_clouds': 'Total_cloud_cover_boundary_layer_cloud_Mixed_intervals_Average', + 'total_clouds': + 'Total_cloud_cover_entire_atmosphere_Mixed_intervals_Average', + 'low_clouds': + 'Total_cloud_cover_low_cloud_Mixed_intervals_Average', + 'mid_clouds': + 'Total_cloud_cover_middle_cloud_Mixed_intervals_Average', + 'high_clouds': + 'Total_cloud_cover_high_cloud_Mixed_intervals_Average', + 'boundary_clouds': ('Total_cloud_cover_boundary_layer_cloud_' + 'Mixed_intervals_Average'), 'convect_clouds': 'Total_cloud_cover_convective_cloud', - 'ghi_raw': 'Downward_Short-Wave_Radiation_Flux_surface_Mixed_intervals_Average', } + 'ghi_raw': ('Downward_Short-Wave_Radiation_Flux_' + 'surface_Mixed_intervals_Average')} self.output_variables = [ 'temp_air', @@ -716,7 +722,7 @@ def process_data(self, data, cloud_cover='total_clouds', **kwargs): return data[self.output_variables] -class HRRR_ESRL(ForecastModel): +class HRRR_ESRL(ForecastModel): # noqa: N801 """ Subclass of the ForecastModel class representing NOAA/GSD/ESRL's HRRR forecast model. @@ -925,7 +931,8 @@ def __init__(self, set_type='best'): 'low_clouds': 'Low_cloud_cover_low_cloud', 'mid_clouds': 'Medium_cloud_cover_middle_cloud', 'high_clouds': 'High_cloud_cover_high_cloud', - 'condensation_height': 'Geopotential_height_adiabatic_condensation_lifted'} + 'condensation_height': + 'Geopotential_height_adiabatic_condensation_lifted'} self.output_variables = [ 'temp_air', diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 261bd64e49..0880594e94 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -125,7 +125,7 @@ def _handle_extra_radiation_types(datetime_or_doy, epoch_year): # a better way to do it. if isinstance(datetime_or_doy, pd.DatetimeIndex): to_doy = tools._pandas_to_doy # won't be evaluated unless necessary - to_datetimeindex = lambda x: datetime_or_doy + def to_datetimeindex(x): return x # noqa: E306 to_output = partial(pd.Series, index=datetime_or_doy) elif isinstance(datetime_or_doy, pd.Timestamp): to_doy = tools._pandas_to_doy @@ -139,12 +139,12 @@ def _handle_extra_radiation_types(datetime_or_doy, epoch_year): tools._datetimelike_scalar_to_datetimeindex to_output = tools._scalar_out elif np.isscalar(datetime_or_doy): # ints and floats of various types - to_doy = lambda x: datetime_or_doy + def to_doy(x): return x # noqa: E306 to_datetimeindex = partial(tools._doy_to_datetimeindex, epoch_year=epoch_year) to_output = tools._scalar_out else: # assume that we have an array-like object of doy - to_doy = lambda x: datetime_or_doy + def to_doy(x): return x # noqa: E306 to_datetimeindex = partial(tools._doy_to_datetimeindex, epoch_year=epoch_year) to_output = tools._array_out @@ -1972,7 +1972,7 @@ def _gti_dirint_lt_90(poa_global, aoi, aoi_lt_90, solar_zenith, solar_azimuth, # we are here because we ran out of coeffs to loop over and # therefore we have exceeded max_iterations import warnings - failed_points = best_diff[aoi_lt_90][best_diff_lte_1_lt_90 == False] + failed_points = best_diff[aoi_lt_90][~best_diff_lte_1_lt_90] warnings.warn( ('%s points failed to converge after %s iterations. best_diff:\n%s' % (len(failed_points), max_iterations, failed_points)), diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index b76660ad85..eb381b0ce9 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -116,8 +116,6 @@ def basic_chain(times, latitude, longitude, raise ValueError('orientation_strategy or surface_tilt and ' 'surface_azimuth must be provided') - times = times - if altitude is None and pressure is None: altitude = 0. pressure = 101325. @@ -126,12 +124,9 @@ def basic_chain(times, latitude, longitude, elif pressure is None: pressure = atmosphere.alt2pres(altitude) - solar_position = solarposition.get_solarposition(times, latitude, - longitude, - altitude=altitude, - pressure=pressure, - method=solar_position_method, - **kwargs) + solar_position = solarposition.get_solarposition( + times, latitude, longitude, altitude=altitude, pressure=pressure, + method=solar_position_method, **kwargs) # possible error with using apparent zenith with some models airmass = atmosphere.get_relative_airmass( @@ -372,12 +367,11 @@ def dc_model(self, model): if model in DC_MODEL_PARAMS.keys(): # validate module parameters missing_params = DC_MODEL_PARAMS[model] - \ - set(self.system.module_parameters.keys()) - if missing_params: # some parameters are not in module.keys() + set(self.system.module_parameters.keys()) + if missing_params: # some parameters are not in module.keys() raise ValueError(model + ' selected for the DC model but ' - 'one or more required parameters ' - 'are missing : ' + - str(missing_params)) + 'one or more required parameters are ' + 'missing : ' + str(missing_params)) if model == 'sapm': self._dc_model = self.sapm elif model == 'desoto': diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 1de4bafbd8..7750347489 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -6,8 +6,8 @@ from __future__ import division from collections import OrderedDict -import os import io +import os try: from urllib2 import urlopen except ImportError: @@ -16,10 +16,9 @@ import numpy as np import pandas as pd -from pvlib import tools +from pvlib import atmosphere, irradiance, tools, singlediode as _singlediode from pvlib.tools import _build_kwargs from pvlib.location import Location -from pvlib import irradiance, atmosphere, singlediode as _singlediode # a dict of required parameter names for each DC power model @@ -333,7 +332,7 @@ def calcparams_desoto(self, effective_irradiance, temp_cell, **kwargs): kwargs = _build_kwargs(['a_ref', 'I_L_ref', 'I_o_ref', 'R_sh_ref', 'R_s', 'alpha_sc', 'EgRef', 'dEgdT', 'irrad_ref', 'temp_ref'], - self.module_parameters) + self.module_parameters) return calcparams_desoto(effective_irradiance, temp_cell, **kwargs) @@ -361,7 +360,7 @@ def calcparams_pvsyst(self, effective_irradiance, temp_cell): 'R_s', 'alpha_sc', 'EgRef', 'irrad_ref', 'temp_ref', 'cells_in_series'], - self.module_parameters) + self.module_parameters) return calcparams_pvsyst(effective_irradiance, temp_cell, **kwargs) @@ -511,7 +510,7 @@ def first_solar_spectral_loss(self, pw, airmass_absolute): """ if 'first_solar_spectral_coefficients' in \ - self.module_parameters.keys(): + self.module_parameters.keys(): coefficients = \ self.module_parameters['first_solar_spectral_coefficients'] module_type = None @@ -552,7 +551,6 @@ def _infer_cell_type(self): 'mc-Si': 'multisi', 'c-Si': 'multisi', 'Si-Film': 'asi', - 'CdTe': 'cdte', 'EFG mc-Si': 'multisi', 'GaAs': None, 'a-Si / mono-Si': 'monosi'} @@ -1133,7 +1131,7 @@ def calcparams_desoto(effective_irradiance, temp_cell, * EgRef = 1.121 * dEgdT = -0.0002677 - >>> M = np.polyval([-1.26E-4, 2.816E-3, -0.024459, 0.086257, 0.918093], + >>> M = np.polyval([-1.26E-4, 2.816E-3, -0.024459, 0.086257, 0.9181], ... AMa) # doctest: +SKIP Source: [1] @@ -1210,7 +1208,7 @@ def calcparams_desoto(effective_irradiance, temp_cell, # equivalent to the product of S (irradiance reaching a module's cells) * # M (spectral adjustment factor) as described in [1]. IL = effective_irradiance / irrad_ref * \ - (I_L_ref + alpha_sc * (Tcell_K - Tref_K)) + (I_L_ref + alpha_sc * (Tcell_K - Tref_K)) I0 = (I_o_ref * ((Tcell_K / Tref_K) ** 3) * (np.exp(EgRef / (k*(Tref_K)) - (E_g / (k*(Tcell_K)))))) # Note that the equation for Rsh differs from [1]. In [1] Rsh is given as @@ -1346,16 +1344,17 @@ def calcparams_pvsyst(effective_irradiance, temp_cell, nNsVth = gamma * k / q * cells_in_series * Tcell_K IL = effective_irradiance / irrad_ref * \ - (I_L_ref + alpha_sc * (Tcell_K - Tref_K)) + (I_L_ref + alpha_sc * (Tcell_K - Tref_K)) I0 = I_o_ref * ((Tcell_K / Tref_K) ** 3) * \ - (np.exp((q * EgRef) / (k * gamma) * (1 / Tref_K - 1 / Tcell_K))) + (np.exp((q * EgRef) / (k * gamma) * (1 / Tref_K - 1 / Tcell_K))) - Rsh_tmp = (R_sh_ref - R_sh_0 * np.exp(-R_sh_exp)) / (1.0 - np.exp(-R_sh_exp)) + Rsh_tmp = \ + (R_sh_ref - R_sh_0 * np.exp(-R_sh_exp)) / (1.0 - np.exp(-R_sh_exp)) Rsh_base = np.maximum(0.0, Rsh_tmp) Rsh = Rsh_base + (R_sh_0 - Rsh_base) * \ - np.exp(-R_sh_exp * effective_irradiance / irrad_ref) + np.exp(-R_sh_exp * effective_irradiance / irrad_ref) Rs = R_s @@ -1723,8 +1722,7 @@ def sapm_celltemp(poa_global, wind_speed, temp_air, if isinstance(model, str): model = temp_models[model.lower()] - elif isinstance(model, list): - model = model + elif isinstance(model, (dict, pd.Series)): model = [model['a'], model['b'], model['deltaT']] diff --git a/pvlib/singlediode.py b/pvlib/singlediode.py index d0ad27e995..bad1f81e5c 100644 --- a/pvlib/singlediode.py +++ b/pvlib/singlediode.py @@ -155,7 +155,7 @@ def bishop88(diode_voltage, photocurrent, saturation_current, grad_i_recomb = np.where(is_recomb, i_recomb / v_recomb, 0) grad_2i_recomb = np.where(is_recomb, 2 * grad_i_recomb / v_recomb, 0) g_diode = saturation_current * np.exp(v_star) / nNsVth # conductance - grad_i = -g_diode - g_sh - grad_i_recomb # di/dvd + grad_i = -g_diode - g_sh - grad_i_recomb # di/dvd grad_v = 1.0 - grad_i * resistance_series # dv/dvd # dp/dv = d(iv)/dv = v * di/dv + i grad = grad_i / grad_v # di/dv @@ -468,7 +468,7 @@ def _lambertw_v_from_i(resistance_shunt, resistance_series, nNsVth, current, # V = -I*(Rs + Rsh) + IL*Rsh - a*lambertwterm + I0*Rsh # Recast in terms of Gsh=1/Rsh for better numerical stability. V[idx_p] = (IL[idx_p] + I0[idx_p] - I[idx_p]) / Gsh[idx_p] - \ - I[idx_p] * Rs[idx_p] - a[idx_p] * lambertwterm + I[idx_p] * Rs[idx_p] - a[idx_p] * lambertwterm if output_is_scalar: return np.asscalar(V) @@ -500,7 +500,7 @@ def _lambertw_i_from_v(resistance_shunt, resistance_series, nNsVth, voltage, voltage, saturation_current, photocurrent) # Intitalize output I (V might not be float64) - I = np.full_like(V, np.nan, dtype=np.float64) + I = np.full_like(V, np.nan, dtype=np.float64) # noqa: E741, N806 # Determine indices where 0 < Rs requires implicit model solution idx_p = 0. < Rs @@ -540,7 +540,7 @@ def _lambertw_i_from_v(resistance_shunt, resistance_series, nNsVth, voltage, def _lambertw(photocurrent, saturation_current, resistance_series, - resistance_shunt, nNsVth, ivcurve_pnts=None): + resistance_shunt, nNsVth, ivcurve_pnts=None): # Compute short circuit current i_sc = _lambertw_i_from_v(resistance_shunt, resistance_series, nNsVth, 0., saturation_current, photocurrent) @@ -593,7 +593,7 @@ def _pwr_optfcn(df, loc): Function to find power from ``i_from_v``. ''' - I = _lambertw_i_from_v(df['r_sh'], df['r_s'], df['nNsVth'], df[loc], - df['i_0'], df['i_l']) + I = _lambertw_i_from_v(df['r_sh'], df['r_s'], # noqa: E741, N806 + df['nNsVth'], df[loc], df['i_0'], df['i_l']) return I * df[loc] diff --git a/pvlib/solarposition.py b/pvlib/solarposition.py index 6f18624884..aeed47486e 100644 --- a/pvlib/solarposition.py +++ b/pvlib/solarposition.py @@ -864,26 +864,27 @@ def _calculate_simple_day_angle(dayofyear): def equation_of_time_spencer71(dayofyear): """ - Equation of time from Duffie & Beckman and attributed to Spencer (1971) and - Iqbal (1983). + Equation of time from Duffie & Beckman and attributed to Spencer + (1971) and Iqbal (1983). - The coefficients correspond to the online copy of the `Fourier paper`_ [1]_ - in the Sundial Mailing list that was posted in 1998 by Mac Oglesby from his - correspondence with Macquarie University Prof. John Pickard who added the - following note. + The coefficients correspond to the online copy of the `Fourier + paper`_ [1]_ in the Sundial Mailing list that was posted in 1998 by + Mac Oglesby from his correspondence with Macquarie University Prof. + John Pickard who added the following note. In the early 1970s, I contacted Dr Spencer about this method because I was trying to use a hand calculator for calculating solar positions, etc. He was extremely helpful and gave me a reprint of this paper. He also pointed out an error in the original: in the series for E, the - constant was printed as 0.000075 rather than 0.0000075. I have corrected - the error in this version. + constant was printed as 0.000075 rather than 0.0000075. I have + corrected the error in this version. - There appears to be another error in formula as printed in both Duffie & - Beckman's [2]_ and Frank Vignola's [3]_ books in which the coefficient - 0.04089 is printed instead of 0.040849, corresponding to the value used in - the Bird Clear Sky model implemented by Daryl Myers [4]_ and printed in both - the Fourier paper from the Sundial Mailing List and R. Hulstrom's [5]_ book. + There appears to be another error in formula as printed in both + Duffie & Beckman's [2]_ and Frank Vignola's [3]_ books in which the + coefficient 0.04089 is printed instead of 0.040849, corresponding to + the value used in the Bird Clear Sky model implemented by Daryl + Myers [4]_ and printed in both the Fourier paper from the Sundial + Mailing List and R. Hulstrom's [5]_ book. .. _Fourier paper: http://www.mail-archive.com/sundial@uni-koeln.de/msg01050.html @@ -918,19 +919,23 @@ def equation_of_time_spencer71(dayofyear): """ day_angle = _calculate_simple_day_angle(dayofyear) # convert from radians to minutes per day = 24[h/day] * 60[min/h] / 2 / pi - return (1440.0 / 2 / np.pi) * (0.0000075 + + eot = (1440.0 / 2 / np.pi) * ( + 0.0000075 + 0.001868 * np.cos(day_angle) - 0.032077 * np.sin(day_angle) - 0.014615 * np.cos(2.0 * day_angle) - 0.040849 * np.sin(2.0 * day_angle) ) + return eot def equation_of_time_pvcdrom(dayofyear): """ Equation of time from PVCDROM. - `PVCDROM`_ is a website by Solar Power Lab at Arizona State University (ASU) + `PVCDROM`_ is a website by Solar Power Lab at Arizona State + University (ASU) - .. _PVCDROM: http://www.pveducation.org/pvcdrom/2-properties-sunlight/solar-time + .. _PVCDROM: + http://www.pveducation.org/pvcdrom/2-properties-sunlight/solar-time Parameters ---------- @@ -938,28 +943,29 @@ def equation_of_time_pvcdrom(dayofyear): Returns ------- - equation_of_time : numeric - Difference in time between solar time and mean solar time in minutes. + equation_of_time : numeric Difference in time between solar time and + mean solar time in minutes. References ---------- - [1] Soteris A. Kalogirou, "Solar Energy Engineering Processes and Systems, - 2nd Edition" Elselvier/Academic Press (2009). + [1] Soteris A. Kalogirou, "Solar Energy Engineering Processes and + Systems, 2nd Edition" Elselvier/Academic Press (2009). See Also -------- equation_of_time_Spencer71 """ # day angle relative to Vernal Equinox, typically March 22 (day number 81) - bday = _calculate_simple_day_angle(dayofyear) - (2.0 * np.pi / 365.0) * 80.0 + bday = \ + _calculate_simple_day_angle(dayofyear) - (2.0 * np.pi / 365.0) * 80.0 # same value but about 2x faster than Spencer (1971) return 9.87 * np.sin(2.0 * bday) - 7.53 * np.cos(bday) - 1.5 * np.sin(bday) def declination_spencer71(dayofyear): """ - Solar declination from Duffie & Beckman [1] and attributed to Spencer (1971) - and Iqbal (1983). + Solar declination from Duffie & Beckman [1] and attributed to + Spencer (1971) and Iqbal (1983). .. warning:: Return units are radians, not degrees. @@ -990,7 +996,8 @@ def declination_spencer71(dayofyear): declination_cooper69 """ day_angle = _calculate_simple_day_angle(dayofyear) - return (0.006918 - + return ( + 0.006918 - 0.399912 * np.cos(day_angle) + 0.070257 * np.sin(day_angle) - 0.006758 * np.cos(2. * day_angle) + 0.000907 * np.sin(2. * day_angle) - 0.002697 * np.cos(3. * day_angle) + 0.00148 * np.sin(3. * day_angle) @@ -1038,7 +1045,8 @@ def declination_cooper69(dayofyear): declination_spencer71 """ day_angle = _calculate_simple_day_angle(dayofyear) - return np.deg2rad(23.45 * np.sin(day_angle + (2.0 * np.pi / 365.0) * 285.0)) + dec = np.deg2rad(23.45 * np.sin(day_angle + (2.0 * np.pi / 365.0) * 285.0)) + return dec def solar_azimuth_analytical(latitude, hour_angle, declination, zenith): @@ -1073,8 +1081,8 @@ def solar_azimuth_analytical(latitude, hour_angle, declination, zenith): [3] `Wikipedia: Solar Azimuth Angle `_ - [4] `PVCDROM: Azimuth Angle `_ + [4] `PVCDROM: Azimuth Angle `_ See Also -------- @@ -1092,12 +1100,17 @@ def solar_azimuth_analytical(latitude, hour_angle, declination, zenith): with np.errstate(invalid='ignore', divide='ignore'): cos_azi = numer / denom - # when zero division occurs, use the limit value of the analytical expression - cos_azi = np.where(np.isclose(denom, 0.0, rtol=0.0, atol=1e-8), 1.0, cos_azi) + # when zero division occurs, use the limit value of the analytical + # expression + cos_azi = \ + np.where(np.isclose(denom, 0.0, rtol=0.0, atol=1e-8), 1.0, cos_azi) - # when too many round-ups in floating point math take cos_azi beyond 1.0, use 1.0 - cos_azi = np.where(np.isclose(cos_azi, 1.0, rtol=0.0, atol=1e-8), 1.0, cos_azi) - cos_azi = np.where(np.isclose(cos_azi, -1.0, rtol=0.0, atol=1e-8), -1.0, cos_azi) + # when too many round-ups in floating point math take cos_azi beyond + # 1.0, use 1.0 + cos_azi = \ + np.where(np.isclose(cos_azi, 1.0, rtol=0.0, atol=1e-8), 1.0, cos_azi) + cos_azi = \ + np.where(np.isclose(cos_azi, -1.0, rtol=0.0, atol=1e-8), -1.0, cos_azi) # when NaN values occur in input, ignore and pass to output with np.errstate(invalid='ignore'): @@ -1108,45 +1121,42 @@ def solar_azimuth_analytical(latitude, hour_angle, declination, zenith): def solar_zenith_analytical(latitude, hour_angle, declination): """ - Analytical expression of solar zenith angle based on spherical trigonometry. + Analytical expression of solar zenith angle based on spherical + trigonometry. - .. warning:: - The analytic form neglects the effect of atmospheric refraction. + .. warning:: The analytic form neglects the effect of atmospheric + refraction. Parameters ---------- - latitude : numeric - Latitude of location in radians. - hour_angle : numeric - Hour angle in the local solar time in radians. - declination : numeric - Declination of the sun in radians. + latitude : numeric Latitude of location in radians. hour_angle : + numeric Hour angle in the local solar time in radians. + declination : numeric Declination of the sun in radians. Returns ------- - zenith : numeric - Solar zenith angle in radians. + zenith : numeric Solar zenith angle in radians. References ---------- [1] J. A. Duffie and W. A. Beckman, "Solar Engineering of Thermal Processes, 3rd Edition" pp. 14, J. Wiley and Sons, New York (2006) - [2] J. H. Seinfeld and S. N. Pandis, "Atmospheric Chemistry and Physics" - p. 132, J. Wiley (1998) + [2] J. H. Seinfeld and S. N. Pandis, "Atmospheric Chemistry and + Physics" p. 132, J. Wiley (1998) - [3] Daryl R. Myers, "Solar Radiation: Practical Modeling for Renewable - Energy Applications", p. 5 CRC Press (2013) + [3] Daryl R. Myers, "Solar Radiation: Practical Modeling for + Renewable Energy Applications", p. 5 CRC Press (2013) - `Wikipedia: Solar Zenith Angle `_ + `Wikipedia: Solar Zenith Angle + `_ - `PVCDROM: Sun's Position `_ + `PVCDROM: Sun's Position + `_ See Also -------- - declination_spencer71 - declination_cooper69 - hour_angle + declination_spencer71 declination_cooper69 hour_angle """ return np.arccos( np.cos(declination) * np.cos(latitude) * np.cos(hour_angle) + diff --git a/pvlib/tmy.py b/pvlib/tmy.py index 371bd933f1..17cf316f28 100644 --- a/pvlib/tmy.py +++ b/pvlib/tmy.py @@ -157,10 +157,10 @@ def readtmy3(filename=None, coerce_year=None, recolumn=True): if filename is None: try: filename = _interactive_load() - except: - raise Exception('Interactive load failed. Tkinter not supported ' - 'on this system. Try installing X-Quartz and ' - 'reloading') + except ImportError: + raise ImportError('Interactive load failed. Tkinter not supported ' + 'on this system. Try installing X-Quartz and ' + 'reloading') head = ['USAF', 'Name', 'State', 'TZ', 'latitude', 'longitude', 'altitude'] @@ -402,16 +402,18 @@ def readtmy2(filename): if filename is None: try: filename = _interactive_load() - except: - raise Exception('Interactive load failed. Tkinter not supported on this system. Try installing X-Quartz and reloading') + except ImportError: + raise ImportError('Interactive load failed. Tkinter not supported ' + 'on this system. Try installing X-Quartz and ' + 'reloading') string = '%2d%2d%2d%2d%4d%4d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%2d%1s%1d%2d%1s%1d%4d%1s%1d%4d%1s%1d%3d%1s%1d%4d%1s%1d%3d%1s%1d%3d%1s%1d%4d%1s%1d%5d%1s%1d%10d%3d%1s%1d%3d%1s%1d%3d%1s%1d%2d%1s%1d' columns = 'year,month,day,hour,ETR,ETRN,GHI,GHISource,GHIUncertainty,DNI,DNISource,DNIUncertainty,DHI,DHISource,DHIUncertainty,GHillum,GHillumSource,GHillumUncertainty,DNillum,DNillumSource,DNillumUncertainty,DHillum,DHillumSource,DHillumUncertainty,Zenithlum,ZenithlumSource,ZenithlumUncertainty,TotCld,TotCldSource,TotCldUnertainty,OpqCld,OpqCldSource,OpqCldUncertainty,DryBulb,DryBulbSource,DryBulbUncertainty,DewPoint,DewPointSource,DewPointUncertainty,RHum,RHumSource,RHumUncertainty,Pressure,PressureSource,PressureUncertainty,Wdir,WdirSource,WdirUncertainty,Wspd,WspdSource,WspdUncertainty,Hvis,HvisSource,HvisUncertainty,CeilHgt,CeilHgtSource,CeilHgtUncertainty,PresentWeather,Pwat,PwatSource,PwatUncertainty,AOD,AODSource,AODUncertainty,SnowDepth,SnowDepthSource,SnowDepthUncertainty,LastSnowfall,LastSnowfallSource,LastSnowfallUncertaint' hdr_columns = 'WBAN,City,State,TZ,latitude,longitude,altitude' - TMY2, TMY2_meta = _read_tmy2(string, columns, hdr_columns, filename) + tmy2, tmy2_meta = _read_tmy2(string, columns, hdr_columns, filename) - return TMY2, TMY2_meta + return tmy2, tmy2_meta def _parsemeta_tmy2(columns, line): diff --git a/pvlib/tools.py b/pvlib/tools.py index 72835e8803..fa3d368369 100644 --- a/pvlib/tools.py +++ b/pvlib/tools.py @@ -100,9 +100,6 @@ def localize_to_utc(time, location): ------- pandas object localized to UTC. """ - import datetime as dt - import pytz - if isinstance(time, dt.datetime): if time.tzinfo is None: time = pytz.timezone(location.tz).localize(time) @@ -338,7 +335,8 @@ def _array_newton(func, x0, fprime, args, tol, maxiter, fprime2, rms = np.sqrt( sum((p1[zero_der_nz_dp] - p[zero_der_nz_dp]) ** 2) ) - warnings.warn('RMS of {:g} reached'.format(rms), RuntimeWarning) + warnings.warn('RMS of {:g} reached'.format(rms), + RuntimeWarning) # newton or halley warnings else: all_or_some = 'all' if zero_der.all() else 'some' @@ -399,7 +397,6 @@ def _golden_sect_DataFrame(params, VL, VH, func): df['VH'] = VH df['VL'] = VL - err = df['VH'] - df['VL'] errflag = True iterations = 0 diff --git a/pvlib/tracking.py b/pvlib/tracking.py index aeecedf615..c1d504b905 100644 --- a/pvlib/tracking.py +++ b/pvlib/tracking.py @@ -478,7 +478,6 @@ def singleaxis(apparent_zenith, apparent_azimuth, panel_norm_earth[:, 2]*0]).T # calculate vector magnitudes - panel_norm_earth_mag = np.sqrt(np.nansum(panel_norm_earth**2, axis=1)) projected_normal_mag = np.sqrt(np.nansum(projected_normal**2, axis=1)) # renormalize the projected vector diff --git a/setup.py b/setup.py index 0d943bb716..2119b9ef5c 100755 --- a/setup.py +++ b/setup.py @@ -1,12 +1,9 @@ #!/usr/bin/env python import os -import re -import shutil -import sys try: - from setuptools import setup, Command + from setuptools import setup from setuptools.extension import Extension except ImportError: raise RuntimeError('setuptools is required')