pvlib 0.9.4a1__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.
Files changed (86) hide show
  1. pvlib/__init__.py +3 -2
  2. pvlib/atmosphere.py +23 -173
  3. pvlib/bifacial/infinite_sheds.py +88 -277
  4. pvlib/bifacial/utils.py +270 -28
  5. pvlib/data/adr-library-cec-inverters-2019-03-05.csv +5009 -0
  6. pvlib/data/precise_iv_curves1.json +10251 -0
  7. pvlib/data/precise_iv_curves2.json +10251 -0
  8. pvlib/data/precise_iv_curves_parameter_sets1.csv +33 -0
  9. pvlib/data/precise_iv_curves_parameter_sets2.csv +33 -0
  10. pvlib/data/test_psm3_2017.csv +17521 -17521
  11. pvlib/data/test_psm3_2019_5min.csv +288 -288
  12. pvlib/data/test_read_psm3.csv +17522 -17522
  13. pvlib/data/test_read_pvgis_horizon.csv +49 -0
  14. pvlib/data/variables_style_rules.csv +3 -0
  15. pvlib/iam.py +207 -51
  16. pvlib/inverter.py +6 -1
  17. pvlib/iotools/__init__.py +7 -2
  18. pvlib/iotools/acis.py +516 -0
  19. pvlib/iotools/midc.py +4 -4
  20. pvlib/iotools/psm3.py +59 -42
  21. pvlib/iotools/pvgis.py +84 -28
  22. pvlib/iotools/sodapro.py +8 -6
  23. pvlib/iotools/srml.py +121 -18
  24. pvlib/iotools/surfrad.py +2 -2
  25. pvlib/iotools/tmy.py +146 -102
  26. pvlib/irradiance.py +270 -15
  27. pvlib/ivtools/sde.py +14 -20
  28. pvlib/ivtools/sdm.py +31 -20
  29. pvlib/ivtools/utils.py +127 -6
  30. pvlib/location.py +3 -2
  31. pvlib/modelchain.py +67 -70
  32. pvlib/pvarray.py +225 -0
  33. pvlib/pvsystem.py +169 -539
  34. pvlib/shading.py +43 -2
  35. pvlib/singlediode.py +216 -66
  36. pvlib/snow.py +36 -15
  37. pvlib/soiling.py +3 -3
  38. pvlib/spa.py +327 -368
  39. pvlib/spectrum/__init__.py +8 -2
  40. pvlib/spectrum/mismatch.py +335 -0
  41. pvlib/temperature.py +124 -13
  42. pvlib/tests/bifacial/test_infinite_sheds.py +44 -106
  43. pvlib/tests/bifacial/test_utils.py +102 -5
  44. pvlib/tests/conftest.py +0 -31
  45. pvlib/tests/iotools/test_acis.py +213 -0
  46. pvlib/tests/iotools/test_midc.py +6 -6
  47. pvlib/tests/iotools/test_psm3.py +7 -5
  48. pvlib/tests/iotools/test_pvgis.py +21 -14
  49. pvlib/tests/iotools/test_sodapro.py +1 -1
  50. pvlib/tests/iotools/test_srml.py +71 -6
  51. pvlib/tests/iotools/test_tmy.py +43 -8
  52. pvlib/tests/ivtools/test_sde.py +19 -17
  53. pvlib/tests/ivtools/test_sdm.py +9 -4
  54. pvlib/tests/ivtools/test_utils.py +96 -1
  55. pvlib/tests/test_atmosphere.py +8 -64
  56. pvlib/tests/test_clearsky.py +0 -1
  57. pvlib/tests/test_iam.py +74 -1
  58. pvlib/tests/test_irradiance.py +56 -2
  59. pvlib/tests/test_location.py +1 -1
  60. pvlib/tests/test_modelchain.py +33 -76
  61. pvlib/tests/test_pvarray.py +46 -0
  62. pvlib/tests/test_pvsystem.py +366 -201
  63. pvlib/tests/test_shading.py +35 -0
  64. pvlib/tests/test_singlediode.py +306 -29
  65. pvlib/tests/test_snow.py +84 -1
  66. pvlib/tests/test_soiling.py +8 -7
  67. pvlib/tests/test_solarposition.py +7 -7
  68. pvlib/tests/test_spa.py +6 -7
  69. pvlib/tests/test_spectrum.py +145 -1
  70. pvlib/tests/test_temperature.py +29 -11
  71. pvlib/tests/test_tools.py +41 -0
  72. pvlib/tests/test_tracking.py +0 -149
  73. pvlib/tools.py +49 -25
  74. pvlib/tracking.py +1 -269
  75. pvlib-0.10.0.dist-info/AUTHORS.md +35 -0
  76. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/LICENSE +5 -2
  77. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/METADATA +3 -13
  78. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/RECORD +80 -75
  79. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/WHEEL +1 -1
  80. pvlib/data/adr-library-2013-10-01.csv +0 -1762
  81. pvlib/forecast.py +0 -1211
  82. pvlib/iotools/ecmwf_macc.py +0 -312
  83. pvlib/tests/iotools/test_ecmwf_macc.py +0 -162
  84. pvlib/tests/test_forecast.py +0 -228
  85. pvlib-0.9.4a1.dist-info/AUTHORS.md +0 -32
  86. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/top_level.txt +0 -0
pvlib/iotools/acis.py ADDED
@@ -0,0 +1,516 @@
1
+ import requests
2
+ import pandas as pd
3
+ import numpy as np
4
+
5
+
6
+ VARIABLE_MAP = {
7
+ # time series names
8
+ 'pcpn': 'precipitation',
9
+ 'maxt': 'temp_air_max',
10
+ 'avgt': 'temp_air_average',
11
+ 'obst': 'temp_air_observation',
12
+ 'mint': 'temp_air_min',
13
+ 'cdd': 'cooling_degree_days',
14
+ 'hdd': 'heating_degree_days',
15
+ 'gdd': 'growing_degree_days',
16
+ 'snow': 'snowfall',
17
+ 'snwd': 'snowdepth',
18
+
19
+ # metadata names
20
+ 'lat': 'latitude',
21
+ 'lon': 'longitude',
22
+ 'elev': 'altitude',
23
+ }
24
+
25
+
26
+ def _get_acis(start, end, params, map_variables, url, **kwargs):
27
+ """
28
+ generic helper for the public get_acis_X functions
29
+ """
30
+ params = {
31
+ # use pd.to_datetime so that strings (e.g. '2021-01-01') are accepted
32
+ 'sdate': pd.to_datetime(start).strftime('%Y-%m-%d'),
33
+ 'edate': pd.to_datetime(end).strftime('%Y-%m-%d'),
34
+ 'output': 'json',
35
+ **params, # endpoint-specific parameters
36
+ }
37
+ response = requests.post(url,
38
+ json=params,
39
+ headers={"Content-Type": "application/json"},
40
+ **kwargs)
41
+ response.raise_for_status()
42
+ payload = response.json()
43
+
44
+ # somewhat inconveniently, the ACIS API tends to return errors as "valid"
45
+ # responses instead of using proper HTTP error codes:
46
+ if "error" in payload:
47
+ raise requests.HTTPError(payload['error'], response=response)
48
+
49
+ columns = ['date'] + [e['name'] for e in params['elems']]
50
+ df = pd.DataFrame(payload['data'], columns=columns)
51
+ df = df.set_index('date')
52
+ df.index = pd.to_datetime(df.index)
53
+ df.index.name = None
54
+
55
+ metadata = payload['meta']
56
+
57
+ try:
58
+ # for StnData endpoint, unpack combination "ll" into lat, lon
59
+ metadata['lon'], metadata['lat'] = metadata.pop('ll')
60
+ except KeyError:
61
+ pass
62
+
63
+ try:
64
+ metadata['elev'] = metadata['elev'] * 0.3048 # feet to meters
65
+ except KeyError:
66
+ # some queries don't return elevation
67
+ pass
68
+
69
+ if map_variables:
70
+ df = df.rename(columns=VARIABLE_MAP)
71
+
72
+ for key in list(metadata.keys()):
73
+ if key in VARIABLE_MAP:
74
+ metadata[VARIABLE_MAP[key]] = metadata.pop(key)
75
+
76
+ return df, metadata
77
+
78
+
79
+ def get_acis_prism(latitude, longitude, start, end, map_variables=True,
80
+ url="https://data.rcc-acis.org/GridData", **kwargs):
81
+ """
82
+ Retrieve estimated daily precipitation and temperature data from PRISM
83
+ via the Applied Climate Information System (ACIS).
84
+
85
+ ACIS [2]_, [3]_ aggregates and provides access to climate data
86
+ from many underlying sources. This function retrieves daily data from
87
+ the Parameter-elevation Regressions on Independent Slopes Model
88
+ (PRISM) [1]_, a gridded precipitation and temperature model
89
+ from Oregon State University.
90
+
91
+ Geographical coverage: US, Central America, and part of South America.
92
+ Approximately 0° to 50° in latitude and -130° to -65° in longitude.
93
+
94
+ Parameters
95
+ ----------
96
+ latitude : float
97
+ in decimal degrees, between -90 and 90, north is positive
98
+ longitude : float
99
+ in decimal degrees, between -180 and 180, east is positive
100
+ start : datetime-like
101
+ First day of the requested period
102
+ end : datetime-like
103
+ Last day of the requested period
104
+ map_variables : bool, default True
105
+ When True, rename data columns and metadata keys to pvlib variable
106
+ names where applicable. See variable :const:`VARIABLE_MAP`.
107
+ url : str, default: 'https://data.rcc-acis.org/GridData'
108
+ API endpoint URL
109
+ kwargs:
110
+ Optional parameters passed to ``requests.post``.
111
+
112
+ Returns
113
+ -------
114
+ data : pandas.DataFrame
115
+ Daily precipitation [mm], temperature [Celsius], and degree day
116
+ [Celsius-days] data
117
+ metadata : dict
118
+ Metadata of the selected grid cell
119
+
120
+ Raises
121
+ ------
122
+ requests.HTTPError
123
+ A message from the ACIS server if the request is rejected
124
+
125
+ Notes
126
+ -----
127
+ PRISM data is aggregated from 12:00 to 12:00 UTC, meaning data labeled
128
+ May 26 reflects to the 24 hours ending at 7:00am Eastern Standard Time
129
+ on May 26.
130
+
131
+ References
132
+ ----------
133
+ .. [1] `PRISM <https://prism.oregonstate.edu/>`_
134
+ .. [2] `ACIS Gridded Data <http://www.rcc-acis.org/docs_gridded.html>`_
135
+ .. [3] `ACIS Web Services <http://www.rcc-acis.org/docs_webservices.html>`_
136
+
137
+ Examples
138
+ --------
139
+ >>> from pvlib.iotools import get_acis_prism
140
+ >>> df, meta = get_acis_prism(40, 80, '2020-01-01', '2020-12-31')
141
+ """
142
+ elems = [
143
+ {"name": "pcpn", "interval": "dly", "units": "mm"},
144
+ {"name": "maxt", "interval": "dly", "units": "degreeC"},
145
+ {"name": "mint", "interval": "dly", "units": "degreeC"},
146
+ {"name": "avgt", "interval": "dly", "units": "degreeC"},
147
+ {"name": "cdd", "interval": "dly", "units": "degreeC"},
148
+ {"name": "hdd", "interval": "dly", "units": "degreeC"},
149
+ {"name": "gdd", "interval": "dly", "units": "degreeC"},
150
+ ]
151
+ params = {
152
+ 'loc': f"{longitude},{latitude}",
153
+ 'grid': "21",
154
+ 'elems': elems,
155
+ 'meta': ["ll", "elev"],
156
+ }
157
+ df, meta = _get_acis(start, end, params, map_variables, url, **kwargs)
158
+ df = df.replace(-999, np.nan)
159
+ return df, meta
160
+
161
+
162
+ def get_acis_nrcc(latitude, longitude, start, end, grid, map_variables=True,
163
+ url="https://data.rcc-acis.org/GridData", **kwargs):
164
+ """
165
+ Retrieve estimated daily precipitation and temperature data from the
166
+ Northeast Regional Climate Center via the Applied Climate
167
+ Information System (ACIS).
168
+
169
+ ACIS [2]_, [3]_ aggregates and provides access to climate data
170
+ from many underlying sources. This function retrieves daily data from
171
+ Cornell's Northeast Regional Climate Center (NRCC) [1]_.
172
+
173
+ Geographical coverage: US, Central America, and part of South America.
174
+ Approximately 0° to 50° in latitude and -130° to -65° in longitude.
175
+
176
+ Parameters
177
+ ----------
178
+ latitude : float
179
+ in decimal degrees, between -90 and 90, north is positive
180
+ longitude : float
181
+ in decimal degrees, between -180 and 180, east is positive
182
+ start : datetime-like
183
+ First day of the requested period
184
+ end : datetime-like
185
+ Last day of the requested period
186
+ grid : int
187
+ Options are either 1 (for "NRCC Interpolated") or 3
188
+ (for "NRCC Hi-Resolution"). See [2]_ for details.
189
+ map_variables : bool, default True
190
+ When True, rename data columns and metadata keys to pvlib variable
191
+ names where applicable. See variable :const:`VARIABLE_MAP`.
192
+ url : str, default: 'https://data.rcc-acis.org/GridData'
193
+ API endpoint URL
194
+ kwargs:
195
+ Optional parameters passed to ``requests.post``.
196
+
197
+ Returns
198
+ -------
199
+ data : pandas.DataFrame
200
+ Daily precipitation [mm], temperature [Celsius], and degree day
201
+ [Celsius-days] data
202
+ metadata : dict
203
+ Metadata of the selected grid cell
204
+
205
+ Raises
206
+ ------
207
+ requests.HTTPError
208
+ A message from the ACIS server if the request is rejected
209
+
210
+ Notes
211
+ -----
212
+ The returned values are 24-hour aggregates, but
213
+ the aggregation period may not be midnight to midnight in local time.
214
+ Check the ACIS and NRCC documentation for details.
215
+
216
+ References
217
+ ----------
218
+ .. [1] `NRCC <http://www.nrcc.cornell.edu/>`_
219
+ .. [2] `ACIS Gridded Data <http://www.rcc-acis.org/docs_gridded.html>`_
220
+ .. [3] `ACIS Web Services <http://www.rcc-acis.org/docs_webservices.html>`_
221
+
222
+ Examples
223
+ --------
224
+ >>> from pvlib.iotools import get_acis_nrcc
225
+ >>> df, meta = get_acis_nrcc(40, -80, '2020-01-01', '2020-12-31', grid=1)
226
+ """
227
+ elems = [
228
+ {"name": "pcpn", "interval": "dly", "units": "mm"},
229
+ {"name": "maxt", "interval": "dly", "units": "degreeC"},
230
+ {"name": "mint", "interval": "dly", "units": "degreeC"},
231
+ {"name": "avgt", "interval": "dly", "units": "degreeC"},
232
+ {"name": "cdd", "interval": "dly", "units": "degreeC"},
233
+ {"name": "hdd", "interval": "dly", "units": "degreeC"},
234
+ {"name": "gdd", "interval": "dly", "units": "degreeC"},
235
+ ]
236
+ params = {
237
+ 'loc': f"{longitude},{latitude}",
238
+ 'grid': grid,
239
+ 'elems': elems,
240
+ 'meta': ["ll", "elev"],
241
+ }
242
+ df, meta = _get_acis(start, end, params, map_variables, url, **kwargs)
243
+ df = df.replace(-999, np.nan)
244
+ return df, meta
245
+
246
+
247
+
248
+ def get_acis_mpe(latitude, longitude, start, end, map_variables=True,
249
+ url="https://data.rcc-acis.org/GridData", **kwargs):
250
+ """
251
+ Retrieve estimated daily Multi-sensor Precipitation Estimates
252
+ via the Applied Climate Information System (ACIS).
253
+
254
+ ACIS [2]_, [3]_ aggregates and provides access to climate data
255
+ from many underlying sources. This function retrieves daily data from
256
+ the National Weather Service's Multi-sensor Precipitation Estimates
257
+ (MPE) [1]_, a gridded precipitation model.
258
+
259
+ This dataset covers the contiguous United States, Mexico, and parts of
260
+ Central America.
261
+
262
+ Parameters
263
+ ----------
264
+ latitude : float
265
+ in decimal degrees, between -90 and 90, north is positive
266
+ longitude : float
267
+ in decimal degrees, between -180 and 180, east is positive
268
+ start : datetime-like
269
+ First day of the requested period
270
+ end : datetime-like
271
+ Last day of the requested period
272
+ map_variables : bool, default True
273
+ When True, rename data columns and metadata keys to pvlib variable
274
+ names where applicable. See variable :const:`VARIABLE_MAP`.
275
+ url : str, default: 'https://data.rcc-acis.org/GridData'
276
+ API endpoint URL
277
+ kwargs:
278
+ Optional parameters passed to ``requests.post``.
279
+
280
+ Returns
281
+ -------
282
+ data : pandas.DataFrame
283
+ Daily precipitation [mm] data
284
+ metadata : dict
285
+ Coordinates of the selected grid cell
286
+
287
+ Raises
288
+ ------
289
+ requests.HTTPError
290
+ A message from the ACIS server if the request is rejected
291
+
292
+ Notes
293
+ -----
294
+ The returned values are 24-hour aggregates, but
295
+ the aggregation period may not be midnight to midnight in local time.
296
+ Check the ACIS and MPE documentation for details.
297
+
298
+ References
299
+ ----------
300
+ .. [1] `Multisensor Precipitation Estimates
301
+ <https://www.weather.gov/marfc/Multisensor_Precipitation>`_
302
+ .. [2] `ACIS Gridded Data <http://www.rcc-acis.org/docs_gridded.html>`_
303
+ .. [3] `ACIS Web Services <http://www.rcc-acis.org/docs_webservices.html>`_
304
+
305
+ Examples
306
+ --------
307
+ >>> from pvlib.iotools import get_acis_mpe
308
+ >>> df, meta = get_acis_mpe(40, -80, '2020-01-01', '2020-12-31')
309
+ """
310
+ elems = [
311
+ # only precipitation is supported in this dataset
312
+ {"name": "pcpn", "interval": "dly", "units": "mm"},
313
+ ]
314
+ params = {
315
+ 'loc': f"{longitude},{latitude}",
316
+ 'grid': "2",
317
+ 'elems': elems,
318
+ 'meta': ["ll"], # "elev" is not supported for this dataset
319
+ }
320
+ df, meta = _get_acis(start, end, params, map_variables, url, **kwargs)
321
+ df = df.replace(-999, np.nan)
322
+ return df, meta
323
+
324
+
325
+ def get_acis_station_data(station, start, end, trace_val=0.001,
326
+ map_variables=True,
327
+ url="https://data.rcc-acis.org/StnData", **kwargs):
328
+ """
329
+ Retrieve weather station climate records via the Applied Climate
330
+ Information System (ACIS).
331
+
332
+ ACIS [1]_, [2]_ aggregates and provides access to climate data
333
+ from many underlying sources. This function retrieves measurements
334
+ from ground stations belonging to various global networks.
335
+
336
+ This function can query data from stations all over the world.
337
+ The stations available in a given area can be listed using
338
+ :py:func:`get_acis_available_stations`.
339
+
340
+ Parameters
341
+ ----------
342
+ station : str
343
+ Identifier code for the station to query. Identifiers from many
344
+ station networks are accepted, including WBAN, COOP, FAA, WMO, GHCN,
345
+ and others. See [1]_ and [2]_ for details.
346
+ start : datetime-like
347
+ First day of the requested period
348
+ end : datetime-like
349
+ Last day of the requested period
350
+ map_variables : bool, default True
351
+ When True, rename data columns and metadata keys to pvlib variable
352
+ names where applicable. See variable :const:`VARIABLE_MAP`.
353
+ trace_val : float, default 0.001
354
+ Value to replace "trace" values in the precipitation data
355
+ url : str, default: 'https://data.rcc-acis.org/GridData'
356
+ API endpoint URL
357
+ kwargs:
358
+ Optional parameters passed to ``requests.post``.
359
+
360
+ Returns
361
+ -------
362
+ data : pandas.DataFrame
363
+ Daily precipitation [mm], temperature [Celsius], snow [mm], and
364
+ degree day [Celsius-days] data
365
+ metadata : dict
366
+ station metadata
367
+
368
+ Raises
369
+ ------
370
+ requests.HTTPError
371
+ A message from the ACIS server if the request is rejected
372
+
373
+ See Also
374
+ --------
375
+ get_acis_available_stations
376
+
377
+ References
378
+ ----------
379
+ .. [1] `ACIS Web Services <http://www.rcc-acis.org/docs_webservices.html>`_
380
+ .. [2] `ACIS Metadata <http://www.rcc-acis.org/docs_metadata.html>`_
381
+
382
+ Examples
383
+ --------
384
+ >>> # Using an FAA code (Chicago O'Hare airport)
385
+ >>> from pvlib.iotools import get_acis_station_data
386
+ >>> df, meta = get_acis_station_data('ORD', '2020-01-01', '2020-12-31')
387
+ >>>
388
+ >>> # Look up available stations in a lat/lon rectangle, with data
389
+ >>> # available in the specified date range:
390
+ >>> from pvlib.iotools import get_acis_available_stations
391
+ >>> stations = get_acis_available_stations([39.5, 40.5], [-80.5, -79.5],
392
+ ... '2020-01-01', '2020-01-03')
393
+ >>> stations['sids'][0]
394
+ ['369367 2', 'USC00369367 6', 'WYNP1 7']
395
+ >>> df, meta = get_acis_station_data('369367', '2020-01-01', '2020-01-03')
396
+ """
397
+ elems = [
398
+ {"name": "maxt", "interval": "dly", "units": "degreeC"},
399
+ {"name": "mint", "interval": "dly", "units": "degreeC"},
400
+ {"name": "avgt", "interval": "dly", "units": "degreeC"},
401
+ {"name": "obst", "interval": "dly", "units": "degreeC"},
402
+ {"name": "pcpn", "interval": "dly", "units": "mm"},
403
+ {"name": "snow", "interval": "dly", "units": "cm"},
404
+ {"name": "snwd", "interval": "dly", "units": "cm"},
405
+ {"name": "cdd", "interval": "dly", "units": "degreeC"},
406
+ {"name": "hdd", "interval": "dly", "units": "degreeC"},
407
+ {"name": "gdd", "interval": "dly", "units": "degreeC"},
408
+ ]
409
+ params = {
410
+ 'sid': str(station),
411
+ 'elems': elems,
412
+ 'meta': ('name,state,sids,sid_dates,ll,elev,uid,county,'
413
+ 'climdiv,valid_daterange,tzo,network')
414
+ }
415
+ df, metadata = _get_acis(start, end, params, map_variables, url, **kwargs)
416
+ df = df.replace("M", np.nan)
417
+ df = df.replace("T", trace_val)
418
+ df = df.astype(float)
419
+ return df, metadata
420
+
421
+
422
+ def get_acis_available_stations(latitude_range, longitude_range,
423
+ start=None, end=None,
424
+ url="https://data.rcc-acis.org/StnMeta",
425
+ **kwargs):
426
+ """
427
+ List weather stations in a given area available from the
428
+ Applied Climate Information System (ACIS).
429
+
430
+ The ``sids`` returned by this function can be used with
431
+ :py:func:`get_acis_station_data` to retrieve weather measurements
432
+ from the station.
433
+
434
+ Parameters
435
+ ----------
436
+ latitude_range : list
437
+ A 2-element list of [southern bound, northern bound]
438
+ in decimal degrees, between -90 and 90, north is positive
439
+ longitude_range : list
440
+ A 2-element list of [western bound, eastern bound]
441
+ in decimal degrees, between -180 and 180, east is positive
442
+ start : datetime-like, optional
443
+ If specified, return only stations that have data between ``start`` and
444
+ ``end``. If not specified, all stations in the region are returned.
445
+ end : datetime-like, optional
446
+ See ``start``
447
+ url : str, default: 'https://data.rcc-acis.org/StnMeta'
448
+ API endpoint URL
449
+ kwargs:
450
+ Optional parameters passed to ``requests.post``.
451
+
452
+ Returns
453
+ -------
454
+ stations : pandas.DataFrame
455
+ A dataframe of station metadata, one row per station.
456
+ The ``sids`` column contains IDs that can be used with
457
+ :py:func:`get_acis_station_data`.
458
+
459
+ Raises
460
+ ------
461
+ requests.HTTPError
462
+ A message from the ACIS server if the request is rejected
463
+
464
+ See Also
465
+ --------
466
+ get_acis_station_data
467
+
468
+ References
469
+ ----------
470
+ .. [1] `ACIS Web Services <http://www.rcc-acis.org/docs_webservices.html>`_
471
+ .. [2] `ACIS Metadata <http://www.rcc-acis.org/docs_metadata.html>`_
472
+
473
+ Examples
474
+ --------
475
+ >>> # Look up available stations in a lat/lon rectangle, with data
476
+ >>> # available in the specified date range:
477
+ >>> from pvlib.iotools import get_acis_available_stations
478
+ >>> stations = get_acis_available_stations([39.5, 40.5], [-80.5, -79.5],
479
+ ... '2020-01-01', '2020-01-03')
480
+ >>> stations['sids'][0]
481
+ ['369367 2', 'USC00369367 6', 'WYNP1 7']
482
+ """
483
+ bbox = "{},{},{},{}".format(
484
+ longitude_range[0],
485
+ latitude_range[0],
486
+ longitude_range[1],
487
+ latitude_range[1],
488
+ )
489
+ params = {
490
+ "bbox": bbox,
491
+ "meta": ("name,state,sids,sid_dates,ll,elev,"
492
+ "uid,county,climdiv,tzo,network"),
493
+ }
494
+ if start is not None and end is not None:
495
+ params['elems'] = ['maxt', 'mint', 'avgt', 'obst',
496
+ 'pcpn', 'snow', 'snwd']
497
+ params['sdate'] = pd.to_datetime(start).strftime('%Y-%m-%d')
498
+ params['edate'] = pd.to_datetime(end).strftime('%Y-%m-%d')
499
+
500
+ response = requests.post(url,
501
+ json=params,
502
+ headers={"Content-Type": "application/json"},
503
+ **kwargs)
504
+ response.raise_for_status()
505
+ payload = response.json()
506
+ if "error" in payload:
507
+ raise requests.HTTPError(payload['error'], response=response)
508
+
509
+ metadata = payload['meta']
510
+ for station_record in metadata:
511
+ station_record['altitude'] = station_record.pop('elev')
512
+ station_record['longitude'], station_record['latitude'] = \
513
+ station_record.pop('ll')
514
+
515
+ df = pd.DataFrame(metadata)
516
+ return df
pvlib/iotools/midc.py CHANGED
@@ -102,7 +102,7 @@ TZ_MAP = {
102
102
  }
103
103
 
104
104
 
105
- def format_index(data):
105
+ def _format_index(data):
106
106
  """Create DatetimeIndex for the Dataframe localized to the timezone provided
107
107
  as the label of the second (time) column.
108
108
 
@@ -126,7 +126,7 @@ def format_index(data):
126
126
  return data
127
127
 
128
128
 
129
- def format_index_raw(data):
129
+ def _format_index_raw(data):
130
130
  """Create DatetimeIndex for the Dataframe localized to the timezone provided
131
131
  as the label of the third column.
132
132
 
@@ -200,9 +200,9 @@ def read_midc(filename, variable_map={}, raw_data=False, **kwargs):
200
200
  """
201
201
  data = pd.read_csv(filename, **kwargs)
202
202
  if raw_data:
203
- data = format_index_raw(data)
203
+ data = _format_index_raw(data)
204
204
  else:
205
- data = format_index(data)
205
+ data = _format_index(data)
206
206
  data = data.rename(columns=variable_map)
207
207
  return data
208
208