Skip to content
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2013-2018, Sandia National Laboratories and pvlib python Development Team
Copyright (c) 2013-2020, Sandia National Laboratories and pvlib python Development Team
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/plot_partial_module_shading_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,8 @@ def find_pmp(df):
plt.imshow(results_pivot, origin='lower', aspect='auto')
plt.xlabel('shaded fraction')
plt.ylabel('diffuse fraction')
xlabels = ["{:0.02f}".format(fs) for fs in results_pivot.columns[::5]]
ylabels = ["{:0.02f}".format(fd) for fd in results_pivot.index]
xlabels = [f"{fs:0.02f}" for fs in results_pivot.columns[::5]]
ylabels = [f"{fd:0.02f}" for fd in results_pivot.index]
plt.xticks(range(0, 5*len(xlabels), 5), xlabels)
plt.yticks(range(0, len(ylabels)), ylabels)
plt.title('Module P_mp across shading conditions')
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/plot_passias_diffuse_shading.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
for k in [1, 1.5, 2, 2.5, 3, 4, 5, 7, 10]:
gcr = 1/k
psi = shading.masking_angle_passias(surface_tilt, gcr)
plt.plot(surface_tilt, psi, label='k={}'.format(k))
plt.plot(surface_tilt, psi, label=f'k={k}')

plt.xlabel('Inclination angle [degrees]')
plt.ylabel('Average masking angle [degrees]')
Expand All @@ -71,7 +71,7 @@
shading_loss = shading.sky_diffuse_passias(psi)
transposition_ratio = irradiance.isotropic(surface_tilt, dhi=1.0)
relative_diffuse = transposition_ratio * (1-shading_loss) * 100 # %
plt.plot(surface_tilt, relative_diffuse, label='k={}'.format(k))
plt.plot(surface_tilt, relative_diffuse, label=f'k={k}')

plt.xlabel('Inclination angle [degrees]')
plt.ylabel('Relative diffuse irradiance [%]')
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/plot_single_axis_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

backtracking_position = backtracking_angles['tracker_theta'].fillna(0)
backtracking_position.plot(title='Backtracking Curve',
label='GCR:{:0.01f}'.format(gcr),
label=f'GCR:{gcr:0.01f}',
ax=ax)

plt.legend()
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/plot_transposition_gain.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def calculate_poa(tmy, solar_position, surface_tilt, surface_azimuth):
for tilt in range(0, 50, 10):
# we will hardcode azimuth=180 (south) for all fixed-tilt cases
poa_irradiance = calculate_poa(tmy, solar_position, tilt, 180)
column_name = "FT-{}".format(tilt)
column_name = f"FT-{tilt}"
# TMYs are hourly, so we can just sum up irradiance [W/m^2] to get
# insolation [Wh/m^2]:
df_monthly[column_name] = poa_irradiance.resample('m').sum()
Expand Down
40 changes: 15 additions & 25 deletions docs/sphinx/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# PVLIB_Python documentation build configuration file, created by
# sphinx-quickstart on Fri Nov 7 15:56:33 2014.
Expand All @@ -15,24 +14,12 @@
import sys
import os

# Mock modules so RTD works
from unittest.mock import MagicMock

# for warning suppression
import warnings

# for generating GH links with linenumbers
import inspect


class Mock(MagicMock):
@classmethod
def __getattr__(cls, name):
return Mock()

MOCK_MODULES = []
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)

import pandas as pd
pd.show_versions()

Expand Down Expand Up @@ -80,8 +67,9 @@ def __getattr__(cls, name):
master_doc = 'index'

# General information about the project.
project = u'pvlib-python'
copyright = u'2015, Sandia National Labs, Rob Andrews, University of Arizona, github contributors'
project = 'pvlib python'
copyright = \
'2013-2020, Sandia National Laboratories and pvlib python Development Team'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -224,7 +212,7 @@ def __getattr__(cls, name):
#html_file_suffix = None

# Output file base name for HTML help builder.
htmlhelp_basename = 'PVLIB_Pythondoc'
htmlhelp_basename = 'pvlib_pythondoc'


# custom CSS workarounds
Expand All @@ -251,8 +239,9 @@ def setup(app):
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'PVLIB_Python.tex', u'PVLIB\\_Python Documentation',
u'Sandia National Labs, Rob Andrews, University of Arizona, github contributors', 'manual'),
('index', 'pvlib_python.tex', 'pvlib\\_python Documentation',
'Sandia National Laboratoraties and pvlib python Development Team',
'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
Expand Down Expand Up @@ -289,8 +278,8 @@ def setup(app):
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'pvlib_python', u'PVLIB_Python Documentation',
[u'Sandia National Labs, Rob Andrews, University of Arizona, github contributors'], 1)
('index', 'pvlib_python', 'pvlib_python Documentation',
['Sandia National Laboratoraties and pvlib python Development Team'], 1)
]

# If true, show URL addresses after external links.
Expand All @@ -303,9 +292,10 @@ def setup(app):
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'PVLIB_Python', u'PVLIB_Python Documentation',
u'Sandia National Labs, Rob Andrews, University of Arizona, github contributors', 'PVLIB_Python', 'One line description of project.',
'Miscellaneous'),
('index', 'pvlib python', 'pvlib python Documentation',
'Sandia National Laboratoraties and pvlib python Development Team',
'pvlib python', 'One line description of project.',
'Miscellaneous'),
]

# Documents to append as an appendix to all manuals.
Expand All @@ -322,7 +312,7 @@ def setup(app):

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'python': ('https://docs.python.org/3.7/', None),
'python': ('https://docs.python.org/3.8/', None),
'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
}
Expand Down Expand Up @@ -432,7 +422,7 @@ def make_github_url(pagename):
# add line numbers if possible:
start, end = get_linenos(obj)
if start and end:
target_url += '#L{}-L{}'.format(start, end)
target_url += f'#L{start}-L{end}'

# Just a normal source RST page
else:
Expand Down
4 changes: 2 additions & 2 deletions pvlib/atmosphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ def get_relative_airmass(zenith, model='kastenyoung1989'):

if 'kastenyoung1989' == model:
am = (1.0 / (np.cos(zenith_rad) +
0.50572*(((6.07995 + (90 - z)) ** - 1.6364))))
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))
elif 'simple' == model:
Expand Down Expand Up @@ -434,7 +434,7 @@ def first_solar_spectral_correction(pw, airmass_absolute,
pw = pw.astype('float64')
if np.min(pw) < min_pw:
pw = np.maximum(pw, min_pw)
warn('Exceptionally low pw values replaced with {0} cm to prevent '
warn('Exceptionally low pw values replaced with {} cm to prevent '
'model divergence'.format(min_pw))

# Warn user about Pw data that is exceptionally high
Expand Down
36 changes: 18 additions & 18 deletions pvlib/forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
'module, or the module may be separated into its own package.')


class ForecastModel(object):
class ForecastModel:
"""
An object for querying and holding forecast model information for
use within the pvlib library.
Expand Down Expand Up @@ -143,7 +143,7 @@ def connect_to_catalog(self):
self.connected = True

def __repr__(self):
return '{}, {}'.format(self.model_name, self.set_type)
return f'{self.model_name}, {self.set_type}'

def set_dataset(self):
'''
Expand Down Expand Up @@ -710,9 +710,9 @@ def __init__(self, resolution='half', set_type='best'):

resolution = resolution.title()
if resolution not in self._resolutions:
raise ValueError('resolution must in {}'.format(self._resolutions))
raise ValueError(f'resolution must in {self._resolutions}')

model = 'GFS {} Degree Forecast'.format(resolution)
model = f'GFS {resolution} Degree Forecast'

# isobaric variables will require a vert_level to prevent
# excessive data downloads
Expand Down Expand Up @@ -746,7 +746,7 @@ def __init__(self, resolution='half', set_type='best'):
'mid_clouds',
'high_clouds']

super(GFS, self).__init__(model_type, model, set_type,
super().__init__(model_type, model, set_type,
vert_level=100000)

def process_data(self, data, cloud_cover='total_clouds', **kwargs):
Expand All @@ -766,7 +766,7 @@ def process_data(self, data, cloud_cover='total_clouds', **kwargs):
data: DataFrame
Processed forecast data.
"""
data = super(GFS, self).process_data(data, **kwargs)
data = super().process_data(data, **kwargs)
data['temp_air'] = self.kelvin_to_celsius(data['temp_air'])
data['wind_speed'] = self.uv_to_speed(data)
irrads = self.cloud_cover_to_irradiance(data[cloud_cover], **kwargs)
Expand Down Expand Up @@ -835,7 +835,7 @@ def __init__(self, set_type='best'):
'mid_clouds',
'high_clouds']

super(HRRR_ESRL, self).__init__(model_type, model, set_type)
super().__init__(model_type, model, set_type)

def process_data(self, data, cloud_cover='total_clouds', **kwargs):
"""
Expand All @@ -855,7 +855,7 @@ def process_data(self, data, cloud_cover='total_clouds', **kwargs):
Processed forecast data.
"""

data = super(HRRR_ESRL, self).process_data(data, **kwargs)
data = super().process_data(data, **kwargs)
data['temp_air'] = self.kelvin_to_celsius(data['temp_air'])
data['wind_speed'] = self.gust_to_speed(data)
# data['wind_speed'] = self.uv_to_speed(data) # GH 702
Expand Down Expand Up @@ -917,7 +917,7 @@ def __init__(self, set_type='best'):
'mid_clouds',
'high_clouds']

super(NAM, self).__init__(model_type, model, set_type)
super().__init__(model_type, model, set_type)

def process_data(self, data, cloud_cover='total_clouds', **kwargs):
"""
Expand All @@ -937,7 +937,7 @@ def process_data(self, data, cloud_cover='total_clouds', **kwargs):
Processed forecast data.
"""

data = super(NAM, self).process_data(data, **kwargs)
data = super().process_data(data, **kwargs)
data['temp_air'] = self.kelvin_to_celsius(data['temp_air'])
data['wind_speed'] = self.gust_to_speed(data)
irrads = self.cloud_cover_to_irradiance(data[cloud_cover], **kwargs)
Expand Down Expand Up @@ -1000,7 +1000,7 @@ def __init__(self, set_type='best'):
'mid_clouds',
'high_clouds', ]

super(HRRR, self).__init__(model_type, model, set_type)
super().__init__(model_type, model, set_type)

def process_data(self, data, cloud_cover='total_clouds', **kwargs):
"""
Expand All @@ -1019,7 +1019,7 @@ def process_data(self, data, cloud_cover='total_clouds', **kwargs):
data: DataFrame
Processed forecast data.
"""
data = super(HRRR, self).process_data(data, **kwargs)
data = super().process_data(data, **kwargs)
wind_mapping = {
'wind_speed_u': 'u-component_of_wind_height_above_ground_0',
'wind_speed_v': 'v-component_of_wind_height_above_ground_0',
Expand Down Expand Up @@ -1075,7 +1075,7 @@ def __init__(self, set_type='best'):
'dni',
'dhi',
'total_clouds', ]
super(NDFD, self).__init__(model_type, model, set_type)
super().__init__(model_type, model, set_type)

def process_data(self, data, **kwargs):
"""
Expand All @@ -1094,7 +1094,7 @@ def process_data(self, data, **kwargs):
"""

cloud_cover = 'total_clouds'
data = super(NDFD, self).process_data(data, **kwargs)
data = super().process_data(data, **kwargs)
data['temp_air'] = self.kelvin_to_celsius(data['temp_air'])
irrads = self.cloud_cover_to_irradiance(data[cloud_cover], **kwargs)
data = data.join(irrads, how='outer')
Expand Down Expand Up @@ -1137,10 +1137,10 @@ def __init__(self, resolution='20', set_type='best'):

resolution = str(resolution)
if resolution not in self._resolutions:
raise ValueError('resolution must in {}'.format(self._resolutions))
raise ValueError(f'resolution must in {self._resolutions}')

model_type = 'Forecast Model Data'
model = 'Rapid Refresh CONUS {}km'.format(resolution)
model = f'Rapid Refresh CONUS {resolution}km'
self.variables = {
'temp_air': 'Temperature_surface',
'wind_speed_gust': 'Wind_speed_gust_surface',
Expand All @@ -1158,7 +1158,7 @@ def __init__(self, resolution='20', set_type='best'):
'low_clouds',
'mid_clouds',
'high_clouds', ]
super(RAP, self).__init__(model_type, model, set_type)
super().__init__(model_type, model, set_type)

def process_data(self, data, cloud_cover='total_clouds', **kwargs):
"""
Expand All @@ -1178,7 +1178,7 @@ def process_data(self, data, cloud_cover='total_clouds', **kwargs):
Processed forecast data.
"""

data = super(RAP, self).process_data(data, **kwargs)
data = super().process_data(data, **kwargs)
data['temp_air'] = self.kelvin_to_celsius(data['temp_air'])
data['wind_speed'] = self.gust_to_speed(data)
irrads = self.cloud_cover_to_irradiance(data[cloud_cover], **kwargs)
Expand Down
16 changes: 8 additions & 8 deletions pvlib/iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
# a dict of required parameter names for each IAM model
# keys are the function names for the IAM models
_IAM_MODEL_PARAMS = {
'ashrae': set(['b']),
'physical': set(['n', 'K', 'L']),
'martin_ruiz': set(['a_r']),
'sapm': set(['B0', 'B1', 'B2', 'B3', 'B4', 'B5']),
'interp': set([])
'ashrae': {'b'},
'physical': {'n', 'K', 'L'},
'martin_ruiz': {'a_r'},
'sapm': {'B0', 'B1', 'B2', 'B3', 'B4', 'B5'},
'interp': set()
}


Expand Down Expand Up @@ -79,7 +79,7 @@ def ashrae(aoi, b=0.05):
pvlib.iam.interp
"""

iam = 1 - b * ((1 / np.cos(np.radians(aoi)) - 1))
iam = 1 - b * (1 / np.cos(np.radians(aoi)) - 1)
aoi_gte_90 = np.full_like(aoi, False, dtype='bool')
np.greater_equal(np.abs(aoi), 90, where=~np.isnan(aoi), out=aoi_gte_90)
iam = np.where(aoi_gte_90, 0, iam)
Expand Down Expand Up @@ -675,7 +675,7 @@ def marion_integrate(function, surface_tilt, region, num=None):
elif region == 'horizon':
num = 1800
else:
raise ValueError('Invalid region: {}'.format(region))
raise ValueError(f'Invalid region: {region}')

beta = np.radians(surface_tilt)
if isinstance(beta, pd.Series):
Expand All @@ -697,7 +697,7 @@ def marion_integrate(function, surface_tilt, region, num=None):
elif region == 'ground':
mask = (phi_range >= np.pi/2)
else:
raise ValueError('Invalid region: {}'.format(region))
raise ValueError(f'Invalid region: {region}')
phi_range = phi_range[mask]

# fast Cartesian product of phi and psi
Expand Down
1 change: 0 additions & 1 deletion pvlib/inverter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
This module contains functions for inverter modeling and for fitting inverter
models to data.
Expand Down
Loading