pvlib 0.9.5__py3-none-any.whl → 0.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvlib/__init__.py +3 -2
- pvlib/atmosphere.py +6 -171
- pvlib/bifacial/infinite_sheds.py +30 -267
- pvlib/bifacial/utils.py +225 -5
- pvlib/data/test_psm3_2017.csv +17521 -17521
- pvlib/data/test_read_psm3.csv +17522 -17522
- pvlib/data/test_read_pvgis_horizon.csv +49 -0
- pvlib/data/variables_style_rules.csv +3 -0
- pvlib/iam.py +17 -4
- pvlib/inverter.py +6 -1
- pvlib/iotools/__init__.py +7 -2
- pvlib/iotools/acis.py +516 -0
- pvlib/iotools/midc.py +4 -4
- pvlib/iotools/psm3.py +32 -31
- pvlib/iotools/pvgis.py +84 -28
- pvlib/iotools/sodapro.py +8 -6
- pvlib/iotools/srml.py +121 -18
- pvlib/iotools/surfrad.py +2 -2
- pvlib/iotools/tmy.py +146 -102
- pvlib/irradiance.py +151 -0
- pvlib/ivtools/sde.py +11 -7
- pvlib/ivtools/sdm.py +16 -10
- pvlib/ivtools/utils.py +6 -6
- pvlib/location.py +3 -2
- pvlib/modelchain.py +67 -70
- pvlib/pvsystem.py +160 -532
- pvlib/shading.py +41 -0
- pvlib/singlediode.py +215 -65
- pvlib/soiling.py +3 -3
- pvlib/spa.py +327 -368
- pvlib/spectrum/__init__.py +8 -2
- pvlib/spectrum/mismatch.py +335 -0
- pvlib/temperature.py +1 -8
- pvlib/tests/bifacial/test_infinite_sheds.py +0 -111
- pvlib/tests/bifacial/test_utils.py +101 -4
- pvlib/tests/conftest.py +0 -31
- pvlib/tests/iotools/test_acis.py +213 -0
- pvlib/tests/iotools/test_midc.py +6 -6
- pvlib/tests/iotools/test_psm3.py +3 -3
- pvlib/tests/iotools/test_pvgis.py +21 -14
- pvlib/tests/iotools/test_sodapro.py +1 -1
- pvlib/tests/iotools/test_srml.py +71 -6
- pvlib/tests/iotools/test_tmy.py +43 -8
- pvlib/tests/ivtools/test_sde.py +19 -17
- pvlib/tests/ivtools/test_sdm.py +9 -4
- pvlib/tests/test_atmosphere.py +6 -62
- pvlib/tests/test_iam.py +12 -0
- pvlib/tests/test_irradiance.py +40 -2
- pvlib/tests/test_location.py +1 -1
- pvlib/tests/test_modelchain.py +33 -76
- pvlib/tests/test_pvsystem.py +366 -201
- pvlib/tests/test_shading.py +28 -0
- pvlib/tests/test_singlediode.py +166 -30
- pvlib/tests/test_soiling.py +8 -7
- pvlib/tests/test_spa.py +6 -7
- pvlib/tests/test_spectrum.py +145 -1
- pvlib/tests/test_temperature.py +0 -7
- pvlib/tests/test_tools.py +25 -0
- pvlib/tests/test_tracking.py +0 -149
- pvlib/tools.py +26 -1
- pvlib/tracking.py +1 -269
- {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/METADATA +1 -9
- {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/RECORD +67 -68
- pvlib/forecast.py +0 -1211
- pvlib/iotools/ecmwf_macc.py +0 -312
- pvlib/tests/iotools/test_ecmwf_macc.py +0 -162
- pvlib/tests/test_forecast.py +0 -228
- {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/LICENSE +0 -0
- {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/WHEEL +0 -0
- {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/top_level.txt +0 -0
pvlib/iotools/tmy.py
CHANGED
|
@@ -3,9 +3,29 @@
|
|
|
3
3
|
import datetime
|
|
4
4
|
import re
|
|
5
5
|
import pandas as pd
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import warnings
|
|
7
|
+
from pvlib._deprecation import pvlibDeprecationWarning
|
|
8
|
+
|
|
9
|
+
# Dictionary mapping TMY3 names to pvlib names
|
|
10
|
+
VARIABLE_MAP = {
|
|
11
|
+
'GHI (W/m^2)': 'ghi',
|
|
12
|
+
'ETR (W/m^2)': 'ghi_extra',
|
|
13
|
+
'DNI (W/m^2)': 'dni',
|
|
14
|
+
'ETRN (W/m^2)': 'dni_extra',
|
|
15
|
+
'DHI (W/m^2)': 'dhi',
|
|
16
|
+
'Pressure (mbar)': 'pressure',
|
|
17
|
+
'Wdir (degrees)': 'wind_direction',
|
|
18
|
+
'Wspd (m/s)': 'wind_speed',
|
|
19
|
+
'Dry-bulb (C)': 'temp_air',
|
|
20
|
+
'Dew-point (C)': 'temp_dew',
|
|
21
|
+
'RHum (%)': 'relative_humidity',
|
|
22
|
+
'Alb (unitless)': 'albedo',
|
|
23
|
+
'Pwat (cm)': 'precipitable_water'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def read_tmy3(filename, coerce_year=None, map_variables=None, recolumn=None,
|
|
28
|
+
encoding=None):
|
|
9
29
|
"""Read a TMY3 file into a pandas dataframe.
|
|
10
30
|
|
|
11
31
|
Note that values contained in the metadata dictionary are unchanged
|
|
@@ -24,9 +44,18 @@ def read_tmy3(filename, coerce_year=None, recolumn=True):
|
|
|
24
44
|
If supplied, the year of the index will be set to `coerce_year`, except
|
|
25
45
|
for the last index value which will be set to the *next* year so that
|
|
26
46
|
the index increases monotonically.
|
|
27
|
-
|
|
47
|
+
map_variables : bool, default None
|
|
48
|
+
When True, renames columns of the DataFrame to pvlib variable names
|
|
49
|
+
where applicable. See variable :const:`VARIABLE_MAP`.
|
|
50
|
+
recolumn : bool (deprecated, use map_variables instead)
|
|
28
51
|
If ``True``, apply standard names to TMY3 columns. Typically this
|
|
29
52
|
results in stripping the units from the column name.
|
|
53
|
+
Cannot be used in combination with ``map_variables``.
|
|
54
|
+
encoding : str, optional
|
|
55
|
+
Encoding of the file. For files that contain non-UTF8 characters it may
|
|
56
|
+
be necessary to specify an alternative encoding, e.g., for
|
|
57
|
+
SolarAnywhere TMY3 files the encoding should be 'iso-8859-1'. Users
|
|
58
|
+
may also consider using the 'utf-8-sig' encoding.
|
|
30
59
|
|
|
31
60
|
Returns
|
|
32
61
|
-------
|
|
@@ -35,7 +64,7 @@ def read_tmy3(filename, coerce_year=None, recolumn=True):
|
|
|
35
64
|
data : DataFrame
|
|
36
65
|
A pandas dataframe with the columns described in the table
|
|
37
66
|
below. For more detailed descriptions of each component, please
|
|
38
|
-
consult the TMY3 User's Manual
|
|
67
|
+
consult the TMY3 User's Manual [1]_, especially tables 1-1
|
|
39
68
|
through 1-6.
|
|
40
69
|
|
|
41
70
|
metadata : dict
|
|
@@ -57,80 +86,83 @@ def read_tmy3(filename, coerce_year=None, recolumn=True):
|
|
|
57
86
|
USAF Int USAF identifier
|
|
58
87
|
=============== ====== ===================
|
|
59
88
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
89
|
+
|
|
90
|
+
======================== ======================================================================================================================================================
|
|
91
|
+
field description
|
|
92
|
+
======================== ======================================================================================================================================================
|
|
93
|
+
**† denotes variables that are mapped when `map_variables` is True**
|
|
94
|
+
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
95
|
+
Index A pandas datetime index. NOTE, the index is timezone aware, and times are set to local standard time (daylight savings is not included)
|
|
96
|
+
ghi_extra† Extraterrestrial horizontal radiation recv'd during 60 minutes prior to timestamp, Wh/m^2
|
|
97
|
+
dni_extra† Extraterrestrial normal radiation recv'd during 60 minutes prior to timestamp, Wh/m^2
|
|
98
|
+
ghi† Direct and diffuse horizontal radiation recv'd during 60 minutes prior to timestamp, Wh/m^2
|
|
99
|
+
GHI source See [1]_, Table 1-4
|
|
100
|
+
GHI uncert (%) Uncertainty based on random and bias error estimates see [2]_
|
|
101
|
+
dni† Amount of direct normal radiation (modeled) recv'd during 60 mintues prior to timestamp, Wh/m^2
|
|
102
|
+
DNI source See [1]_, Table 1-4
|
|
103
|
+
DNI uncert (%) Uncertainty based on random and bias error estimates see [2]_
|
|
104
|
+
dhi† Amount of diffuse horizontal radiation recv'd during 60 minutes prior to timestamp, Wh/m^2
|
|
105
|
+
DHI source See [1]_, Table 1-4
|
|
106
|
+
DHI uncert (%) Uncertainty based on random and bias error estimates see [2]_
|
|
107
|
+
GH illum (lx) Avg. total horizontal illuminance recv'd during the 60 minutes prior to timestamp, lx
|
|
108
|
+
GH illum source See [1]_, Table 1-4
|
|
109
|
+
GH illum uncert (%) Uncertainty based on random and bias error estimates see [2]_
|
|
110
|
+
DN illum (lx) Avg. direct normal illuminance recv'd during the 60 minutes prior to timestamp, lx
|
|
111
|
+
DN illum source See [1]_, Table 1-4
|
|
112
|
+
DN illum uncert (%) Uncertainty based on random and bias error estimates see [2]_
|
|
113
|
+
DH illum (lx) Avg. horizontal diffuse illuminance recv'd during the 60 minutes prior to timestamp, lx
|
|
114
|
+
DH illum source See [1]_, Table 1-4
|
|
115
|
+
DH illum uncert (%) Uncertainty based on random and bias error estimates see [2]_
|
|
116
|
+
Zenith lum (cd/m^2) Avg. luminance at the sky's zenith during the 60 minutes prior to timestamp, cd/m^2
|
|
117
|
+
Zenith lum source See [1]_, Table 1-4
|
|
118
|
+
Zenith lum uncert (%) Uncertainty based on random and bias error estimates see [1]_ section 2.10
|
|
119
|
+
TotCld (tenths) Amount of sky dome covered by clouds or obscuring phenonema at time stamp, tenths of sky
|
|
120
|
+
TotCld source See [1]_, Table 1-5
|
|
121
|
+
TotCld uncert (code) See [1]_, Table 1-6
|
|
122
|
+
OpqCld (tenths) Amount of sky dome covered by clouds or obscuring phenonema that prevent observing the sky at time stamp, tenths of sky
|
|
123
|
+
OpqCld source See [1]_, Table 1-5
|
|
124
|
+
OpqCld uncert (code) See [1]_, Table 1-6
|
|
125
|
+
temp_air† Dry bulb temperature at the time indicated, deg C
|
|
126
|
+
Dry-bulb source See [1]_, Table 1-5
|
|
127
|
+
Dry-bulb uncert (code) See [1]_, Table 1-6
|
|
128
|
+
temp_dew† Dew-point temperature at the time indicated, deg C
|
|
129
|
+
Dew-point source See [1]_, Table 1-5
|
|
130
|
+
Dew-point uncert (code) See [1]_, Table 1-6
|
|
131
|
+
relative_humidity† Relatitudeive humidity at the time indicated, percent
|
|
132
|
+
RHum source See [1]_, Table 1-5
|
|
133
|
+
RHum uncert (code) See [1]_, Table 1-6
|
|
134
|
+
pressure† Station pressure at the time indicated, 1 mbar
|
|
135
|
+
Pressure source See [1]_, Table 1-5
|
|
136
|
+
Pressure uncert (code) See [1]_, Table 1-6
|
|
137
|
+
wind_direction† Wind direction at time indicated, degrees from north (360 = north; 0 = undefined,calm)
|
|
138
|
+
Wdir source See [1]_, Table 1-5
|
|
139
|
+
Wdir uncert (code) See [1]_, Table 1-6
|
|
140
|
+
wind_speed† Wind speed at the time indicated, meter/second
|
|
141
|
+
Wspd source See [1]_, Table 1-5
|
|
142
|
+
Wspd uncert (code) See [1]_, Table 1-6
|
|
143
|
+
Hvis (m) Distance to discernable remote objects at time indicated (7777=unlimited), meter
|
|
144
|
+
Hvis source See [1]_, Table 1-5
|
|
145
|
+
Hvis uncert (coe) See [1]_, Table 1-6
|
|
146
|
+
CeilHgt (m) Height of cloud base above local terrain (7777=unlimited), meter
|
|
147
|
+
CeilHgt source See [1]_, Table 1-5
|
|
148
|
+
CeilHgt uncert (code) See [1]_, Table 1-6
|
|
149
|
+
precipitable_water† Total precipitable water contained in a column of unit cross section from earth to top of atmosphere, cm
|
|
150
|
+
Pwat source See [1]_, Table 1-5
|
|
151
|
+
Pwat uncert (code) See [1]_, Table 1-6
|
|
152
|
+
AOD The broadband aerosol optical depth per unit of air mass due to extinction by aerosol component of atmosphere, unitless
|
|
153
|
+
AOD source See [1]_, Table 1-5
|
|
154
|
+
AOD uncert (code) See [1]_, Table 1-6
|
|
155
|
+
albedo† The ratio of reflected solar irradiance to global horizontal irradiance, unitless
|
|
156
|
+
Alb source See [1]_, Table 1-5
|
|
157
|
+
Alb uncert (code) See [1]_, Table 1-6
|
|
158
|
+
Lprecip depth (mm) The amount of liquid precipitation observed at indicated time for the period indicated in the liquid precipitation quantity field, millimeter
|
|
159
|
+
Lprecip quantity (hr) The period of accumulatitudeion for the liquid precipitation depth field, hour
|
|
160
|
+
Lprecip source See [1]_, Table 1-5
|
|
161
|
+
Lprecip uncert (code) See [1]_, Table 1-6
|
|
162
|
+
PresWth (METAR code) Present weather code, see [2]_.
|
|
163
|
+
PresWth source Present weather code source, see [2]_.
|
|
164
|
+
PresWth uncert (code) Present weather code uncertainty, see [2]_.
|
|
165
|
+
======================== ======================================================================================================================================================
|
|
134
166
|
|
|
135
167
|
.. admonition:: Midnight representation
|
|
136
168
|
|
|
@@ -152,21 +184,21 @@ def read_tmy3(filename, coerce_year=None, recolumn=True):
|
|
|
152
184
|
----------
|
|
153
185
|
.. [1] Wilcox, S and Marion, W. "Users Manual for TMY3 Data Sets".
|
|
154
186
|
NREL/TP-581-43156, Revised May 2008.
|
|
187
|
+
:doi:`10.2172/928611`
|
|
155
188
|
.. [2] Wilcox, S. (2007). National Solar Radiation Database 1991 2005
|
|
156
189
|
Update: Users Manual. 472 pp.; NREL Report No. TP-581-41364.
|
|
190
|
+
:doi:`10.2172/901864`
|
|
157
191
|
.. [3] `SolarAnywhere file formats
|
|
158
192
|
<https://www.solaranywhere.com/support/historical-data/file-formats/>`_
|
|
159
193
|
""" # noqa: E501
|
|
160
194
|
head = ['USAF', 'Name', 'State', 'TZ', 'latitude', 'longitude', 'altitude']
|
|
161
195
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
with open(str(filename), 'r', encoding='iso-8859-1') as fbuf:
|
|
169
|
-
firstline, data = _parse_tmy3(fbuf)
|
|
196
|
+
with open(str(filename), 'r', encoding=encoding) as fbuf:
|
|
197
|
+
# header information on the 1st line (0 indexing)
|
|
198
|
+
firstline = fbuf.readline()
|
|
199
|
+
# use pandas to read the csv file buffer
|
|
200
|
+
# header is actually the second line, but tell pandas to look for
|
|
201
|
+
data = pd.read_csv(fbuf, header=0)
|
|
170
202
|
|
|
171
203
|
meta = dict(zip(head, firstline.rstrip('\n').split(",")))
|
|
172
204
|
# convert metadata strings to numeric types
|
|
@@ -178,8 +210,10 @@ def read_tmy3(filename, coerce_year=None, recolumn=True):
|
|
|
178
210
|
|
|
179
211
|
# get the date column as a pd.Series of numpy datetime64
|
|
180
212
|
data_ymd = pd.to_datetime(data['Date (MM/DD/YYYY)'], format='%m/%d/%Y')
|
|
213
|
+
# extract minutes
|
|
214
|
+
minutes = data['Time (HH:MM)'].str.split(':').str[1].astype(int)
|
|
181
215
|
# shift the time column so that midnite is 00:00 instead of 24:00
|
|
182
|
-
shifted_hour = data['Time (HH:MM)'].str[
|
|
216
|
+
shifted_hour = data['Time (HH:MM)'].str.split(':').str[0].astype(int) % 24
|
|
183
217
|
# shift the dates at midnight (24:00) so they correspond to the next day.
|
|
184
218
|
# If midnight is specified as 00:00 do not shift date.
|
|
185
219
|
data_ymd[data['Time (HH:MM)'].str[:2] == '24'] += datetime.timedelta(days=1) # noqa: E501
|
|
@@ -197,25 +231,34 @@ def read_tmy3(filename, coerce_year=None, recolumn=True):
|
|
|
197
231
|
data_ymd.iloc[-1] = data_ymd.iloc[-1].replace(year=coerce_year+1)
|
|
198
232
|
# NOTE: as of pvlib-0.6.3, min req is pandas-0.18.1, so pd.to_timedelta
|
|
199
233
|
# unit must be in (D,h,m,s,ms,us,ns), but pandas>=0.24 allows unit='hour'
|
|
200
|
-
data.index = data_ymd + pd.to_timedelta(shifted_hour, unit='h')
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
234
|
+
data.index = data_ymd + pd.to_timedelta(shifted_hour, unit='h') \
|
|
235
|
+
+ pd.to_timedelta(minutes, unit='min')
|
|
236
|
+
# shouldnt' specify both recolumn and map_variables
|
|
237
|
+
if recolumn is not None and map_variables is not None:
|
|
238
|
+
msg = "`map_variables` and `recolumn` cannot both be specified"
|
|
239
|
+
raise ValueError(msg)
|
|
240
|
+
elif map_variables is None and recolumn is not None:
|
|
241
|
+
warnings.warn(
|
|
242
|
+
'The recolumn parameter is deprecated and will be removed in '
|
|
243
|
+
'pvlib 0.11.0. Use `map_variables` instead, although note that '
|
|
244
|
+
'its behavior is different from `recolumn`.',
|
|
245
|
+
pvlibDeprecationWarning)
|
|
246
|
+
elif map_variables is None and recolumn is None:
|
|
247
|
+
warnings.warn(
|
|
248
|
+
'TMY3 variable names will be renamed to pvlib conventions by '
|
|
249
|
+
'default starting in pvlib 0.11.0. Specify map_variables=True '
|
|
250
|
+
'to enable that behavior now, or specify map_variables=False '
|
|
251
|
+
'to hide this warning.', pvlibDeprecationWarning)
|
|
252
|
+
if map_variables:
|
|
253
|
+
data = data.rename(columns=VARIABLE_MAP)
|
|
254
|
+
elif recolumn or (recolumn is None and map_variables is None):
|
|
255
|
+
data = _recolumn(data)
|
|
204
256
|
|
|
205
257
|
data = data.tz_localize(int(meta['TZ'] * 3600))
|
|
206
258
|
|
|
207
259
|
return data, meta
|
|
208
260
|
|
|
209
261
|
|
|
210
|
-
def _parse_tmy3(fbuf):
|
|
211
|
-
# header information on the 1st line (0 indexing)
|
|
212
|
-
firstline = fbuf.readline()
|
|
213
|
-
# use pandas to read the csv file buffer
|
|
214
|
-
# header is actually the second line, but tell pandas to look for
|
|
215
|
-
data = pd.read_csv(fbuf, header=0)
|
|
216
|
-
return firstline, data
|
|
217
|
-
|
|
218
|
-
|
|
219
262
|
def _recolumn(tmy3_dataframe):
|
|
220
263
|
"""
|
|
221
264
|
Rename the columns of the TMY3 DataFrame.
|
|
@@ -283,7 +326,7 @@ def read_tmy2(filename):
|
|
|
283
326
|
data : DataFrame
|
|
284
327
|
A dataframe with the columns described in the table below. For a
|
|
285
328
|
more detailed descriptions of each component, please consult the
|
|
286
|
-
TMY2 User's Manual
|
|
329
|
+
TMY2 User's Manual [1]_, especially tables 3-1 through 3-6, and
|
|
287
330
|
Appendix B.
|
|
288
331
|
|
|
289
332
|
metadata : dict
|
|
@@ -385,6 +428,7 @@ def read_tmy2(filename):
|
|
|
385
428
|
----------
|
|
386
429
|
.. [1] Marion, W and Urban, K. "Wilcox, S and Marion, W. "User's Manual
|
|
387
430
|
for TMY2s". NREL 1995.
|
|
431
|
+
:doi:`10.2172/87130`
|
|
388
432
|
""" # noqa: E501
|
|
389
433
|
# paste in the column info as one long line
|
|
390
434
|
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' # noqa: E501
|
pvlib/irradiance.py
CHANGED
|
@@ -2227,6 +2227,8 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87):
|
|
|
2227
2227
|
--------
|
|
2228
2228
|
dirint
|
|
2229
2229
|
disc
|
|
2230
|
+
orgill_hollands
|
|
2231
|
+
boland
|
|
2230
2232
|
"""
|
|
2231
2233
|
|
|
2232
2234
|
dni_extra = get_extra_radiation(datetime_or_doy)
|
|
@@ -2265,6 +2267,93 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87):
|
|
|
2265
2267
|
return data
|
|
2266
2268
|
|
|
2267
2269
|
|
|
2270
|
+
def orgill_hollands(ghi, zenith, datetime_or_doy, dni_extra=None,
|
|
2271
|
+
min_cos_zenith=0.065, max_zenith=87):
|
|
2272
|
+
"""Estimate DNI and DHI from GHI using the Orgill and Hollands model.
|
|
2273
|
+
|
|
2274
|
+
The Orgill and Hollands model [1]_ estimates the diffuse fraction DF from
|
|
2275
|
+
global horizontal irradiance through an empirical relationship between
|
|
2276
|
+
hourly DF observations (in Toronto, Canada) and the ratio of GHI to
|
|
2277
|
+
extraterrestrial irradiance, Kt.
|
|
2278
|
+
|
|
2279
|
+
Parameters
|
|
2280
|
+
----------
|
|
2281
|
+
ghi: numeric
|
|
2282
|
+
Global horizontal irradiance in W/m^2.
|
|
2283
|
+
zenith: numeric
|
|
2284
|
+
True (not refraction-corrected) zenith angles in decimal degrees.
|
|
2285
|
+
datetime_or_doy : int, float, array, pd.DatetimeIndex
|
|
2286
|
+
Day of year or array of days of year e.g.
|
|
2287
|
+
pd.DatetimeIndex.dayofyear, or pd.DatetimeIndex.
|
|
2288
|
+
dni_extra : None or numeric, default None
|
|
2289
|
+
Extraterrestrial direct normal irradiance. [W/m2]
|
|
2290
|
+
min_cos_zenith : numeric, default 0.065
|
|
2291
|
+
Minimum value of cos(zenith) to allow when calculating global
|
|
2292
|
+
clearness index `kt`. Equivalent to zenith = 86.273 degrees.
|
|
2293
|
+
max_zenith : numeric, default 87
|
|
2294
|
+
Maximum value of zenith to allow in DNI calculation. DNI will be
|
|
2295
|
+
set to 0 for times with zenith values greater than `max_zenith`.
|
|
2296
|
+
|
|
2297
|
+
Returns
|
|
2298
|
+
-------
|
|
2299
|
+
data : OrderedDict or DataFrame
|
|
2300
|
+
Contains the following keys/columns:
|
|
2301
|
+
|
|
2302
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
2303
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
2304
|
+
W/m^2.
|
|
2305
|
+
* ``kt``: Ratio of global to extraterrestrial irradiance
|
|
2306
|
+
on a horizontal plane.
|
|
2307
|
+
|
|
2308
|
+
References
|
|
2309
|
+
----------
|
|
2310
|
+
.. [1] Orgill, J.F., Hollands, K.G.T., Correlation equation for hourly
|
|
2311
|
+
diffuse radiation on a horizontal surface, Solar Energy 19(4), pp 357–359,
|
|
2312
|
+
1977. Eqs. 3(a), 3(b) and 3(c)
|
|
2313
|
+
:doi:`10.1016/0038-092X(77)90006-8`
|
|
2314
|
+
|
|
2315
|
+
See Also
|
|
2316
|
+
--------
|
|
2317
|
+
dirint
|
|
2318
|
+
disc
|
|
2319
|
+
erbs
|
|
2320
|
+
boland
|
|
2321
|
+
"""
|
|
2322
|
+
if dni_extra is None:
|
|
2323
|
+
dni_extra = get_extra_radiation(datetime_or_doy)
|
|
2324
|
+
|
|
2325
|
+
kt = clearness_index(ghi, zenith, dni_extra, min_cos_zenith=min_cos_zenith,
|
|
2326
|
+
max_clearness_index=1)
|
|
2327
|
+
|
|
2328
|
+
# For Kt < 0.35, set the diffuse fraction
|
|
2329
|
+
df = 1 - 0.249*kt
|
|
2330
|
+
|
|
2331
|
+
# For Kt >= 0.35 and Kt <= 0.75, set the diffuse fraction
|
|
2332
|
+
df = np.where((kt >= 0.35) & (kt <= 0.75),
|
|
2333
|
+
1.557 - 1.84*kt, df)
|
|
2334
|
+
|
|
2335
|
+
# For Kt > 0.75, set the diffuse fraction
|
|
2336
|
+
df = np.where(kt > 0.75, 0.177, df)
|
|
2337
|
+
|
|
2338
|
+
dhi = df * ghi
|
|
2339
|
+
|
|
2340
|
+
dni = (ghi - dhi) / tools.cosd(zenith)
|
|
2341
|
+
bad_values = (zenith > max_zenith) | (ghi < 0) | (dni < 0)
|
|
2342
|
+
dni = np.where(bad_values, 0, dni)
|
|
2343
|
+
# ensure that closure relationship remains valid
|
|
2344
|
+
dhi = np.where(bad_values, ghi, dhi)
|
|
2345
|
+
|
|
2346
|
+
data = OrderedDict()
|
|
2347
|
+
data['dni'] = dni
|
|
2348
|
+
data['dhi'] = dhi
|
|
2349
|
+
data['kt'] = kt
|
|
2350
|
+
|
|
2351
|
+
if isinstance(datetime_or_doy, pd.DatetimeIndex):
|
|
2352
|
+
data = pd.DataFrame(data, index=datetime_or_doy)
|
|
2353
|
+
|
|
2354
|
+
return data
|
|
2355
|
+
|
|
2356
|
+
|
|
2268
2357
|
def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613,
|
|
2269
2358
|
min_cos_zenith=0.065, max_zenith=87):
|
|
2270
2359
|
r"""
|
|
@@ -2326,6 +2415,7 @@ def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613,
|
|
|
2326
2415
|
dirint
|
|
2327
2416
|
disc
|
|
2328
2417
|
erbs
|
|
2418
|
+
orgill_hollands
|
|
2329
2419
|
|
|
2330
2420
|
Notes
|
|
2331
2421
|
-----
|
|
@@ -3117,3 +3207,64 @@ def complete_irradiance(solar_zenith,
|
|
|
3117
3207
|
'dhi': dhi,
|
|
3118
3208
|
'dni': dni})
|
|
3119
3209
|
return component_sum_df
|
|
3210
|
+
|
|
3211
|
+
|
|
3212
|
+
def louche(ghi, solar_zenith, datetime_or_doy, max_zenith=90):
|
|
3213
|
+
"""
|
|
3214
|
+
Determine DNI and DHI from GHI using the Louche model.
|
|
3215
|
+
|
|
3216
|
+
Parameters
|
|
3217
|
+
----------
|
|
3218
|
+
ghi : numeric
|
|
3219
|
+
Global horizontal irradiance. [W/m^2]
|
|
3220
|
+
|
|
3221
|
+
solar_zenith : numeric
|
|
3222
|
+
True (not refraction-corrected) zenith angles in decimal
|
|
3223
|
+
degrees. Angles must be >=0 and <=90.
|
|
3224
|
+
|
|
3225
|
+
datetime_or_doy : numeric, pandas.DatetimeIndex
|
|
3226
|
+
Day of year or array of days of year e.g.
|
|
3227
|
+
pd.DatetimeIndex.dayofyear, or pd.DatetimeIndex.
|
|
3228
|
+
|
|
3229
|
+
Returns
|
|
3230
|
+
-------
|
|
3231
|
+
data: OrderedDict or DataFrame
|
|
3232
|
+
Contains the following keys/columns:
|
|
3233
|
+
|
|
3234
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
3235
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
3236
|
+
W/m^2.
|
|
3237
|
+
* ``kt``: Ratio of global to extraterrestrial irradiance
|
|
3238
|
+
on a horizontal plane.
|
|
3239
|
+
|
|
3240
|
+
References
|
|
3241
|
+
-------
|
|
3242
|
+
.. [1] Louche A, Notton G, Poggi P, Simonnot G. Correlations for direct
|
|
3243
|
+
normal and global horizontal irradiation on a French Mediterranean site.
|
|
3244
|
+
Solar Energy 1991;46:261-6. :doi:`10.1016/0038-092X(91)90072-5`
|
|
3245
|
+
|
|
3246
|
+
"""
|
|
3247
|
+
|
|
3248
|
+
I0 = get_extra_radiation(datetime_or_doy)
|
|
3249
|
+
|
|
3250
|
+
Kt = clearness_index(ghi, solar_zenith, I0)
|
|
3251
|
+
|
|
3252
|
+
kb = -10.627*Kt**5 + 15.307*Kt**4 - 5.205 * \
|
|
3253
|
+
Kt**3 + 0.994*Kt**2 - 0.059*Kt + 0.002
|
|
3254
|
+
dni = kb*I0
|
|
3255
|
+
dhi = ghi - dni*tools.cosd(solar_zenith)
|
|
3256
|
+
|
|
3257
|
+
bad_values = (solar_zenith > max_zenith) | (ghi < 0) | (dni < 0)
|
|
3258
|
+
dni = np.where(bad_values, 0, dni)
|
|
3259
|
+
# ensure that closure relationship remains valid
|
|
3260
|
+
dhi = np.where(bad_values, ghi, dhi)
|
|
3261
|
+
|
|
3262
|
+
data = OrderedDict()
|
|
3263
|
+
data['dni'] = dni
|
|
3264
|
+
data['dhi'] = dhi
|
|
3265
|
+
data['kt'] = Kt
|
|
3266
|
+
|
|
3267
|
+
if isinstance(datetime_or_doy, pd.DatetimeIndex):
|
|
3268
|
+
data = pd.DataFrame(data, index=datetime_or_doy)
|
|
3269
|
+
|
|
3270
|
+
return data
|
pvlib/ivtools/sde.py
CHANGED
|
@@ -64,7 +64,8 @@ def fit_sandia_simple(voltage, current, v_oc=None, i_sc=None, v_mp_i_mp=None,
|
|
|
64
64
|
|
|
65
65
|
Raises
|
|
66
66
|
------
|
|
67
|
-
RuntimeError
|
|
67
|
+
RuntimeError
|
|
68
|
+
if parameter extraction is not successful.
|
|
68
69
|
|
|
69
70
|
Notes
|
|
70
71
|
-----
|
|
@@ -106,7 +107,7 @@ def fit_sandia_simple(voltage, current, v_oc=None, i_sc=None, v_mp_i_mp=None,
|
|
|
106
107
|
.. math::
|
|
107
108
|
|
|
108
109
|
I &\approx \frac{I_{L}}{1 + G_{p} R_{s}}
|
|
109
|
-
- \frac{G_{p}}{1 + G_{p}R_{s}} V
|
|
110
|
+
- \frac{G_{p}}{1 + G_{p}R_{s}} V \\
|
|
110
111
|
&= \beta_{0} + \beta_{1} V
|
|
111
112
|
|
|
112
113
|
4. The exponential portion of the IV curve is defined by
|
|
@@ -124,8 +125,8 @@ def fit_sandia_simple(voltage, current, v_oc=None, i_sc=None, v_mp_i_mp=None,
|
|
|
124
125
|
.. math::
|
|
125
126
|
|
|
126
127
|
\log(\beta_{0} - \beta_{1} V - I)
|
|
127
|
-
&\approx \log(\frac{I_{0}}{1 + G_{p} R_{s}} + \frac{V}{nN_sV_{th}}
|
|
128
|
-
+ \frac{I R_{s}}{nN_sV_{th}}
|
|
128
|
+
&\approx \log(\frac{I_{0}}{1 + G_{p} R_{s}}) + \frac{V}{nN_sV_{th}}
|
|
129
|
+
+ \frac{I R_{s}}{nN_sV_{th}} \\
|
|
129
130
|
&= \beta_{2} + \beta_{3} V + \beta_{4} I
|
|
130
131
|
|
|
131
132
|
6. Calculate values for ``IL, I0, Rs, Rsh,`` and ``nNsVth`` from the
|
|
@@ -139,7 +140,8 @@ def fit_sandia_simple(voltage, current, v_oc=None, i_sc=None, v_mp_i_mp=None,
|
|
|
139
140
|
0 86758 909 4
|
|
140
141
|
.. [2] C. B. Jones, C. W. Hansen, "Single Diode Parameter Extraction from
|
|
141
142
|
In-Field Photovoltaic I-V Curves on a Single Board Computer", 46th IEEE
|
|
142
|
-
Photovoltaic Specialist Conference, Chicago, IL, 2019
|
|
143
|
+
Photovoltaic Specialist Conference, Chicago, IL, 2019.
|
|
144
|
+
:doi:`10.1109/PVSC40753.2019.8981330`
|
|
143
145
|
"""
|
|
144
146
|
|
|
145
147
|
# If not provided, extract v_oc, i_sc, v_mp and i_mp from the IV curve data
|
|
@@ -289,8 +291,10 @@ def _fit_sandia_cocontent(voltage, current, nsvth):
|
|
|
289
291
|
|
|
290
292
|
Raises
|
|
291
293
|
------
|
|
292
|
-
ValueError
|
|
293
|
-
|
|
294
|
+
ValueError
|
|
295
|
+
if ``voltage`` and ``current`` are different lengths.
|
|
296
|
+
ValueError
|
|
297
|
+
if ``len(voltage)`` < 6
|
|
294
298
|
|
|
295
299
|
Notes
|
|
296
300
|
-----
|
pvlib/ivtools/sdm.py
CHANGED
|
@@ -76,9 +76,10 @@ def fit_cec_sam(celltype, v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc,
|
|
|
76
76
|
|
|
77
77
|
Raises
|
|
78
78
|
------
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
ImportError
|
|
80
|
+
if NREL-PySAM is not installed.
|
|
81
|
+
RuntimeError
|
|
82
|
+
if parameter extraction is not successful.
|
|
82
83
|
|
|
83
84
|
Notes
|
|
84
85
|
-----
|
|
@@ -94,7 +95,7 @@ def fit_cec_sam(celltype, v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc,
|
|
|
94
95
|
----------
|
|
95
96
|
.. [1] A. Dobos, "An Improved Coefficient Calculator for the California
|
|
96
97
|
Energy Commission 6 Parameter Photovoltaic Module Model", Journal of
|
|
97
|
-
Solar Energy Engineering, vol 134, 2012.
|
|
98
|
+
Solar Energy Engineering, vol 134, 2012. :doi:`10.1115/1.4005759`
|
|
98
99
|
"""
|
|
99
100
|
|
|
100
101
|
try:
|
|
@@ -204,7 +205,7 @@ def fit_desoto(v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc, cells_in_series,
|
|
|
204
205
|
----------
|
|
205
206
|
.. [1] W. De Soto et al., "Improvement and validation of a model for
|
|
206
207
|
photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
|
|
207
|
-
2006.
|
|
208
|
+
2006. :doi:`10.1016/j.solener.2005.06.010`
|
|
208
209
|
"""
|
|
209
210
|
|
|
210
211
|
# Constants
|
|
@@ -405,6 +406,7 @@ def fit_pvsyst_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3):
|
|
|
405
406
|
.. [1] K. Sauer, T. Roessler, C. W. Hansen, Modeling the Irradiance and
|
|
406
407
|
Temperature Dependence of Photovoltaic Modules in PVsyst, IEEE Journal
|
|
407
408
|
of Photovoltaics v5(1), January 2015.
|
|
409
|
+
:doi:`10.1109/JPHOTOV.2014.2364133`
|
|
408
410
|
.. [2] A. Mermoud, PV Modules modeling, Presentation at the 2nd PV
|
|
409
411
|
Performance Modeling Workshop, Santa Clara, CA, May 2013
|
|
410
412
|
.. [3] A. Mermoud, T. Lejeuene, Performance Assessment of a Simulation
|
|
@@ -412,11 +414,13 @@ def fit_pvsyst_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3):
|
|
|
412
414
|
Photovoltaic Solar Energy Conference, Valencia, Spain, Sept. 2010
|
|
413
415
|
.. [4] C. Hansen, Estimating Parameters for the PVsyst Version 6
|
|
414
416
|
Photovoltaic Module Performance Model, Sandia National Laboratories
|
|
415
|
-
Report SAND2015-8598
|
|
417
|
+
Report SAND2015-8598. :doi:`10.2172/1223058`
|
|
416
418
|
.. [5] C. Hansen, Parameter Estimation for Single Diode Models of
|
|
417
|
-
Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065
|
|
419
|
+
Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065.
|
|
420
|
+
:doi:`10.2172/1177157`
|
|
418
421
|
.. [6] C. Hansen, Estimation of Parameters for Single Diode Models using
|
|
419
422
|
Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013.
|
|
423
|
+
:doi:`10.1109/PVSC.2013.6744135`
|
|
420
424
|
.. [7] PVLib MATLAB https://github.com/sandialabs/MATLAB_PV_LIB
|
|
421
425
|
"""
|
|
422
426
|
|
|
@@ -574,11 +578,13 @@ def fit_desoto_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3):
|
|
|
574
578
|
----------
|
|
575
579
|
.. [1] W. De Soto et al., "Improvement and validation of a model for
|
|
576
580
|
photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
|
|
577
|
-
2006.
|
|
581
|
+
2006. :doi:`10.1016/j.solener.2005.06.010`
|
|
578
582
|
.. [2] C. Hansen, Parameter Estimation for Single Diode Models of
|
|
579
|
-
Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065
|
|
583
|
+
Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065.
|
|
584
|
+
:doi:`10.2172/1177157`
|
|
580
585
|
.. [3] C. Hansen, Estimation of Parameters for Single Diode Models using
|
|
581
586
|
Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013.
|
|
587
|
+
:doi:`10.1109/PVSC.2013.6744135`
|
|
582
588
|
.. [4] PVLib MATLAB https://github.com/sandialabs/MATLAB_PV_LIB
|
|
583
589
|
"""
|
|
584
590
|
|
|
@@ -942,7 +948,7 @@ def _update_io(voc, iph, io, rs, rsh, nnsvth):
|
|
|
942
948
|
|
|
943
949
|
while maxerr > eps and k < niter:
|
|
944
950
|
# Predict Voc
|
|
945
|
-
pvoc = v_from_i(
|
|
951
|
+
pvoc = v_from_i(0., iph, tio, rs, rsh, nnsvth)
|
|
946
952
|
|
|
947
953
|
# Difference in Voc
|
|
948
954
|
dvoc = pvoc - voc
|