pvlib 0.12.1a1__py3-none-any.whl → 0.13.0a1__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.
@@ -9,21 +9,23 @@ from pvlib.bifacial import utils
9
9
  from pvlib.irradiance import beam_component, aoi, haydavies
10
10
 
11
11
 
12
- def _poa_ground_shadows(poa_ground, f_gnd_beam, df, vf_gnd_sky):
12
+ def _poa_ground_shadows(ghi, dhi, albedo, f_gnd_beam, vf_gnd_sky):
13
13
  """
14
14
  Reduce ground-reflected irradiance to the tilted plane (poa_ground) to
15
15
  account for shadows on the ground.
16
16
 
17
17
  Parameters
18
18
  ----------
19
- poa_ground : numeric
20
- Ground reflected irradiance on the tilted surface, assuming full GHI
21
- illumination on all of the ground. [W/m^2]
19
+ ghi : numeric
20
+ Global horizontal irradiance, with no adjustments. [W/m^2]
21
+ dhi : numeric
22
+ Diffuse horizontal irradiance, with no adjustments. [W/m^2]
23
+ albedo : numeric
24
+ Ground albedo, the ratio of reflected to incident irradiance of the
25
+ ground surface. [W/m^2]
22
26
  f_gnd_beam : numeric
23
27
  Fraction of the distance between rows that is illuminated (unshaded).
24
28
  [unitless]
25
- df : numeric
26
- Diffuse fraction, the ratio of DHI to GHI. [unitless]
27
29
  vf_gnd_sky : numeric
28
30
  View factor from the ground to the sky, integrated along the distance
29
31
  between rows. [unitless]
@@ -35,7 +37,7 @@ def _poa_ground_shadows(poa_ground, f_gnd_beam, df, vf_gnd_sky):
35
37
  ground. [W/m^2]
36
38
 
37
39
  """
38
- return poa_ground * (f_gnd_beam*(1 - df) + df*vf_gnd_sky)
40
+ return albedo * (f_gnd_beam * (ghi - dhi) + vf_gnd_sky * dhi)
39
41
 
40
42
 
41
43
  def _poa_sky_diffuse_pv(dhi, gcr, surface_tilt):
@@ -339,18 +341,11 @@ def get_irradiance_poa(surface_tilt, surface_azimuth, solar_zenith,
339
341
  # and restricted views
340
342
  # this is a deviation from [1], because the row to ground view factor
341
343
  # is accounted for in a different manner
342
- ground_diffuse = ghi * albedo
343
-
344
- # diffuse fraction
345
- diffuse_fraction = np.clip(dhi / ghi, 0., 1.)
346
- # make diffuse fraction 0 when ghi is small
347
- diffuse_fraction = np.where(ghi < 0.0001, 0., diffuse_fraction)
348
-
349
344
  # Reduce ground-reflected irradiance because other rows in the array
350
345
  # block irradiance from reaching the ground.
351
346
  # [2], Eq. 9
352
- ground_diffuse = _poa_ground_shadows(
353
- ground_diffuse, f_gnd_beam, diffuse_fraction, vf_gnd_sky)
347
+ ground_diffuse = _poa_ground_shadows(ghi, dhi, albedo, f_gnd_beam,
348
+ vf_gnd_sky)
354
349
 
355
350
  # Ground-reflected irradiance on the row surface accounting for
356
351
  # the view to the ground. This deviates from [1], Eq. 10, 11 and
pvlib/iotools/__init__.py CHANGED
@@ -16,7 +16,6 @@ from pvlib.iotools.psm4 import get_nsrdb_psm4_tmy # noqa: F401
16
16
  from pvlib.iotools.psm4 import get_nsrdb_psm4_conus # noqa: F401
17
17
  from pvlib.iotools.psm4 import get_nsrdb_psm4_full_disc # noqa: F401
18
18
  from pvlib.iotools.psm4 import read_nsrdb_psm4 # noqa: F401
19
- from pvlib.iotools.psm4 import parse_nsrdb_psm4 # noqa: F401
20
19
  from pvlib.iotools.pvgis import get_pvgis_tmy, read_pvgis_tmy # noqa: F401
21
20
  from pvlib.iotools.pvgis import read_pvgis_hourly # noqa: F401
22
21
  from pvlib.iotools.pvgis import get_pvgis_hourly # noqa: F401
pvlib/iotools/bsrn.py CHANGED
@@ -9,6 +9,9 @@ import warnings
9
9
  import io
10
10
  import os
11
11
 
12
+ from pvlib.tools import _file_context_manager
13
+ from pvlib._deprecation import deprecated
14
+
12
15
  BSRN_FTP_URL = "ftp.bsrn.awi.de"
13
16
 
14
17
  BSRN_LR0100_COL_SPECS = [(0, 3), (4, 9), (10, 16), (16, 22), (22, 27),
@@ -109,7 +112,7 @@ def get_bsrn(station, start, end, username, password,
109
112
  UserWarning
110
113
  If one or more requested files are missing a UserWarning is returned
111
114
  with a list of the filenames missing. If no files match the specified
112
- station and timeframe a seperate UserWarning is given.
115
+ station and timeframe a separate UserWarning is given.
113
116
 
114
117
  Notes
115
118
  -----
@@ -136,7 +139,7 @@ def get_bsrn(station, start, end, username, password,
136
139
 
137
140
  See Also
138
141
  --------
139
- pvlib.iotools.read_bsrn, pvlib.iotools.parse_bsrn
142
+ pvlib.iotools.read_bsrn
140
143
 
141
144
  References
142
145
  ----------
@@ -159,8 +162,7 @@ def get_bsrn(station, start, end, username, password,
159
162
  end = pd.to_datetime(end)
160
163
 
161
164
  # Generate list files to download based on start/end (SSSMMYY.dat.gz)
162
- filenames = pd.date_range(
163
- start, end.replace(day=1) + pd.DateOffset(months=1), freq='1M')\
165
+ filenames = pd.date_range(start.date().replace(day=1), end, freq='1MS')\
164
166
  .strftime(f"{station}%m%y.dat.gz").tolist()
165
167
 
166
168
  # Create FTP connection
@@ -191,7 +193,7 @@ def get_bsrn(station, start, end, username, password,
191
193
  bio.seek(0) # reset buffer to start of file
192
194
  gzip_file = io.TextIOWrapper(gzip.GzipFile(fileobj=bio),
193
195
  encoding='latin1')
194
- dfi, metadata = parse_bsrn(gzip_file, logical_records)
196
+ dfi, metadata = _parse_bsrn(gzip_file, logical_records)
195
197
  dfs.append(dfi)
196
198
  # FTP client raises an error if the file does not exist on server
197
199
  except ftplib.error_perm as e:
@@ -217,7 +219,7 @@ def get_bsrn(station, start, end, username, password,
217
219
  return data, metadata
218
220
 
219
221
 
220
- def parse_bsrn(fbuf, logical_records=('0100',)):
222
+ def _parse_bsrn(fbuf, logical_records=('0100',)):
221
223
  """
222
224
  Parse a file-like buffer of a BSRN station-to-archive file.
223
225
 
@@ -382,7 +384,7 @@ def read_bsrn(filename, logical_records=('0100',)):
382
384
  Parameters
383
385
  ----------
384
386
  filename: str or path-like
385
- Name or path of a BSRN station-to-archive data file
387
+ Name, path, or in-memory buffer of a BSRN station-to-archive data file
386
388
  logical_records: list or tuple, default: ('0100',)
387
389
  List of the logical records (LR) to parse. Options include: '0100',
388
390
  '0300', and '0500'.
@@ -439,7 +441,7 @@ def read_bsrn(filename, logical_records=('0100',)):
439
441
 
440
442
  See Also
441
443
  --------
442
- pvlib.iotools.parse_bsrn, pvlib.iotools.get_bsrn
444
+ pvlib.iotools.get_bsrn
443
445
 
444
446
  References
445
447
  ----------
@@ -457,7 +459,11 @@ def read_bsrn(filename, logical_records=('0100',)):
457
459
  if str(filename).endswith('.gz'): # check if file is a gzipped (.gz) file
458
460
  open_func, mode = gzip.open, 'rt'
459
461
  else:
460
- open_func, mode = open, 'r'
462
+ open_func, mode = _file_context_manager, 'r'
461
463
  with open_func(filename, mode) as f:
462
- content = parse_bsrn(f, logical_records)
464
+ content = _parse_bsrn(f, logical_records)
463
465
  return content
466
+
467
+
468
+ parse_bsrn = deprecated(since="0.13.0", name="parse_bsrn",
469
+ alternative="read_bsrn")(read_bsrn)
pvlib/iotools/epw.py CHANGED
@@ -6,6 +6,9 @@ import io
6
6
  from urllib.request import urlopen, Request
7
7
  import pandas as pd
8
8
 
9
+ from pvlib.tools import _file_context_manager
10
+ from pvlib._deprecation import deprecated
11
+
9
12
 
10
13
  def read_epw(filename, coerce_year=None):
11
14
  r'''
@@ -23,7 +26,8 @@ def read_epw(filename, coerce_year=None):
23
26
  Parameters
24
27
  ----------
25
28
  filename : String
26
- Can be a relative file path, absolute file path, or url.
29
+ Can be a relative file path, absolute file path, url, or in-memory
30
+ file buffer.
27
31
 
28
32
  coerce_year : int, optional
29
33
  If supplied, the year of the data will be set to this value. This can
@@ -43,10 +47,6 @@ def read_epw(filename, coerce_year=None):
43
47
  metadata : dict
44
48
  The site metadata available in the file.
45
49
 
46
- See Also
47
- --------
48
- pvlib.iotools.parse_epw
49
-
50
50
  Notes
51
51
  -----
52
52
 
@@ -226,18 +226,17 @@ def read_epw(filename, coerce_year=None):
226
226
  'Safari/537.36')})
227
227
  response = urlopen(request)
228
228
  with io.StringIO(response.read().decode(errors='ignore')) as csvdata:
229
- data, meta = parse_epw(csvdata, coerce_year)
229
+ data, meta = _parse_epw(csvdata, coerce_year)
230
230
 
231
231
  else:
232
- # Assume it's accessible via the file system
233
- with open(str(filename), 'r') as csvdata:
234
- data, meta = parse_epw(csvdata, coerce_year)
235
-
232
+ # Assume it's a buffer or accessible via the file system
233
+ with _file_context_manager(filename, 'r') as csvdata:
234
+ data, meta = _parse_epw(csvdata, coerce_year)
236
235
 
237
236
  return data, meta
238
237
 
239
238
 
240
- def parse_epw(csvdata, coerce_year=None):
239
+ def _parse_epw(csvdata, coerce_year=None):
241
240
  """
242
241
  Given a file-like buffer with data in Energy Plus Weather (EPW) format,
243
242
  parse the data into a dataframe.
@@ -310,3 +309,7 @@ def parse_epw(csvdata, coerce_year=None):
310
309
  data.index = idx
311
310
 
312
311
  return data, meta
312
+
313
+
314
+ parse_epw = deprecated(since="0.13.0", name="parse_epw",
315
+ alternative="read_epw")(read_epw)
pvlib/iotools/psm3.py CHANGED
@@ -7,8 +7,8 @@ import io
7
7
  import requests
8
8
  import pandas as pd
9
9
  from json import JSONDecodeError
10
- import warnings
11
- from pvlib._deprecation import pvlibDeprecationWarning
10
+ from pvlib._deprecation import deprecated
11
+ from pvlib import tools
12
12
 
13
13
  NSRDB_API_BASE = "https://developer.nrel.gov"
14
14
  PSM_URL = NSRDB_API_BASE + "/api/nsrdb/v2/solar/psm3-2-2-download.csv"
@@ -127,7 +127,7 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
127
127
  timeseries data from NREL PSM3
128
128
  metadata : dict
129
129
  metadata from NREL PSM3 about the record, see
130
- :func:`pvlib.iotools.parse_psm3` for fields
130
+ :func:`pvlib.iotools.read_psm3` for fields
131
131
 
132
132
  Raises
133
133
  ------
@@ -152,7 +152,7 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
152
152
 
153
153
  See Also
154
154
  --------
155
- pvlib.iotools.read_psm3, pvlib.iotools.parse_psm3
155
+ pvlib.iotools.read_psm3
156
156
 
157
157
  References
158
158
  ----------
@@ -216,12 +216,12 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
216
216
  # the CSV is in the response content as a UTF-8 bytestring
217
217
  # to use pandas we need to create a file buffer from the response
218
218
  fbuf = io.StringIO(response.content.decode('utf-8'))
219
- return parse_psm3(fbuf, map_variables)
219
+ return read_psm3(fbuf, map_variables)
220
220
 
221
221
 
222
- def parse_psm3(fbuf, map_variables=True):
222
+ def read_psm3(filename, map_variables=True):
223
223
  """
224
- Parse an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
224
+ Read an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
225
225
  is described in [1]_ and the SAM CSV format is described in [2]_.
226
226
 
227
227
  .. versionchanged:: 0.9.0
@@ -231,8 +231,8 @@ def parse_psm3(fbuf, map_variables=True):
231
231
 
232
232
  Parameters
233
233
  ----------
234
- fbuf: file-like object
235
- File-like object containing data to read.
234
+ filename: str, path-like, or buffer
235
+ Filename or in-memory buffer of a file containing data to read.
236
236
  map_variables: bool, default True
237
237
  When true, renames columns of the Dataframe to pvlib variable names
238
238
  where applicable. See variable :const:`VARIABLE_MAP`.
@@ -302,12 +302,15 @@ def parse_psm3(fbuf, map_variables=True):
302
302
  Examples
303
303
  --------
304
304
  >>> # Read a local PSM3 file:
305
+ >>> df, metadata = iotools.read_psm3("data.csv") # doctest: +SKIP
306
+
307
+ >>> # Read a file object or an in-memory buffer:
305
308
  >>> with open(filename, 'r') as f: # doctest: +SKIP
306
- ... df, metadata = iotools.parse_psm3(f) # doctest: +SKIP
309
+ ... df, metadata = iotools.read_psm3(f) # doctest: +SKIP
307
310
 
308
311
  See Also
309
312
  --------
310
- pvlib.iotools.read_psm3, pvlib.iotools.get_psm3
313
+ pvlib.iotools.get_psm3
311
314
 
312
315
  References
313
316
  ----------
@@ -316,11 +319,25 @@ def parse_psm3(fbuf, map_variables=True):
316
319
  .. [2] `Standard Time Series Data File Format
317
320
  <https://web.archive.org/web/20170207203107/https://sam.nrel.gov/sites/default/files/content/documents/pdf/wfcsv.pdf>`_
318
321
  """
319
- # The first 2 lines of the response are headers with metadata
320
- metadata_fields = fbuf.readline().split(',')
321
- metadata_fields[-1] = metadata_fields[-1].strip() # strip trailing newline
322
- metadata_values = fbuf.readline().split(',')
323
- metadata_values[-1] = metadata_values[-1].strip() # strip trailing newline
322
+ with tools._file_context_manager(filename) as fbuf:
323
+ # The first 2 lines of the response are headers with metadata
324
+ metadata_fields = fbuf.readline().split(',')
325
+ metadata_values = fbuf.readline().split(',')
326
+ # get the column names so we can set the dtypes
327
+ columns = fbuf.readline().split(',')
328
+ columns[-1] = columns[-1].strip() # strip trailing newline
329
+ # Since the header has so many columns, excel saves blank cols in the
330
+ # data below the header lines.
331
+ columns = [col for col in columns if col != '']
332
+ dtypes = dict.fromkeys(columns, float) # all floats except datevec
333
+ dtypes.update({'Year': int, 'Month': int, 'Day': int, 'Hour': int,
334
+ 'Minute': int, 'Cloud Type': int, 'Fill Flag': int})
335
+ data = pd.read_csv(
336
+ fbuf, header=None, names=columns, usecols=columns, dtype=dtypes,
337
+ delimiter=',', lineterminator='\n') # skip carriage returns \r
338
+
339
+ metadata_fields[-1] = metadata_fields[-1].strip() # trailing newline
340
+ metadata_values[-1] = metadata_values[-1].strip() # trailing newline
324
341
  metadata = dict(zip(metadata_fields, metadata_values))
325
342
  # the response is all strings, so set some metadata types to numbers
326
343
  metadata['Local Time Zone'] = int(metadata['Local Time Zone'])
@@ -328,22 +345,9 @@ def parse_psm3(fbuf, map_variables=True):
328
345
  metadata['Latitude'] = float(metadata['Latitude'])
329
346
  metadata['Longitude'] = float(metadata['Longitude'])
330
347
  metadata['Elevation'] = int(metadata['Elevation'])
331
- # get the column names so we can set the dtypes
332
- columns = fbuf.readline().split(',')
333
- columns[-1] = columns[-1].strip() # strip trailing newline
334
- # Since the header has so many columns, excel saves blank cols in the
335
- # data below the header lines.
336
- columns = [col for col in columns if col != '']
337
- dtypes = dict.fromkeys(columns, float) # all floats except datevec
338
- dtypes.update(Year=int, Month=int, Day=int, Hour=int, Minute=int)
339
- dtypes['Cloud Type'] = int
340
- dtypes['Fill Flag'] = int
341
- data = pd.read_csv(
342
- fbuf, header=None, names=columns, usecols=columns, dtype=dtypes,
343
- delimiter=',', lineterminator='\n') # skip carriage returns \r
348
+
344
349
  # the response 1st 5 columns are a date vector, convert to datetime
345
- dtidx = pd.to_datetime(
346
- data[['Year', 'Month', 'Day', 'Hour', 'Minute']])
350
+ dtidx = pd.to_datetime(data[['Year', 'Month', 'Day', 'Hour', 'Minute']])
347
351
  # in USA all timezones are integers
348
352
  tz = 'Etc/GMT%+d' % -metadata['Time Zone']
349
353
  data.index = pd.DatetimeIndex(dtidx).tz_localize(tz)
@@ -357,43 +361,5 @@ def parse_psm3(fbuf, map_variables=True):
357
361
  return data, metadata
358
362
 
359
363
 
360
- def read_psm3(filename, map_variables=True):
361
- """
362
- Read an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
363
- is described in [1]_ and the SAM CSV format is described in [2]_.
364
-
365
- .. versionchanged:: 0.9.0
366
- The function now returns a tuple where the first element is a dataframe
367
- and the second element is a dictionary containing metadata. Previous
368
- versions of this function had the return values switched.
369
-
370
- Parameters
371
- ----------
372
- filename: str
373
- Filename of a file containing data to read.
374
- map_variables: bool, default True
375
- When true, renames columns of the Dataframe to pvlib variable names
376
- where applicable. See variable :const:`VARIABLE_MAP`.
377
-
378
- Returns
379
- -------
380
- data : pandas.DataFrame
381
- timeseries data from NREL PSM3
382
- metadata : dict
383
- metadata from NREL PSM3 about the record, see
384
- :func:`pvlib.iotools.parse_psm3` for fields
385
-
386
- See Also
387
- --------
388
- pvlib.iotools.parse_psm3, pvlib.iotools.get_psm3
389
-
390
- References
391
- ----------
392
- .. [1] `NREL National Solar Radiation Database (NSRDB)
393
- <https://nsrdb.nrel.gov/>`_
394
- .. [2] `Standard Time Series Data File Format
395
- <https://web.archive.org/web/20170207203107/https://sam.nrel.gov/sites/default/files/content/documents/pdf/wfcsv.pdf>`_
396
- """
397
- with open(str(filename), 'r') as fbuf:
398
- content = parse_psm3(fbuf, map_variables)
399
- return content
364
+ parse_psm3 = deprecated(since="0.12.1", name="parse_psm3",
365
+ alternative="read_psm3")(read_psm3)