pvlib 0.11.1__py3-none-any.whl → 0.11.2__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 (43) hide show
  1. pvlib/_deprecation.py +73 -0
  2. pvlib/atmosphere.py +79 -0
  3. pvlib/clearsky.py +35 -22
  4. pvlib/data/pvgis_tmy_test.csv +8761 -0
  5. pvlib/data/tmy_45.000_8.000_2005_2023.csv +8789 -0
  6. pvlib/data/tmy_45.000_8.000_2005_2023.epw +8768 -0
  7. pvlib/data/tmy_45.000_8.000_2005_2023.json +1 -0
  8. pvlib/data/tmy_45.000_8.000_2005_2023.txt +8761 -0
  9. pvlib/data/tmy_45.000_8.000_userhorizon.json +1 -1
  10. pvlib/iam.py +4 -4
  11. pvlib/iotools/midc.py +1 -1
  12. pvlib/iotools/pvgis.py +0 -10
  13. pvlib/irradiance.py +98 -55
  14. pvlib/ivtools/sdm.py +75 -52
  15. pvlib/pvsystem.py +132 -84
  16. pvlib/solarposition.py +46 -30
  17. pvlib/spa.py +4 -2
  18. pvlib/spectrum/irradiance.py +2 -1
  19. pvlib/spectrum/spectrl2.py +2 -1
  20. pvlib/temperature.py +49 -3
  21. pvlib/tests/iotools/test_pvgis.py +9 -9
  22. pvlib/tests/ivtools/test_sdm.py +23 -1
  23. pvlib/tests/test__deprecation.py +97 -0
  24. pvlib/tests/test_atmosphere.py +147 -0
  25. pvlib/tests/test_clearsky.py +7 -1
  26. pvlib/tests/test_conftest.py +0 -44
  27. pvlib/tests/test_irradiance.py +56 -10
  28. pvlib/tests/test_pvsystem.py +17 -1
  29. pvlib/tests/test_solarposition.py +33 -0
  30. pvlib/tests/test_spa.py +29 -0
  31. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/METADATA +11 -10
  32. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/RECORD +36 -37
  33. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/WHEEL +1 -1
  34. pvlib/data/aod550_tcwv_20121101_test.nc +0 -0
  35. pvlib/data/pvgis_tmy_test.dat +0 -8761
  36. pvlib/data/tmy_45.000_8.000_2005_2020.csv +0 -8789
  37. pvlib/data/tmy_45.000_8.000_2005_2020.epw +0 -8768
  38. pvlib/data/tmy_45.000_8.000_2005_2020.json +0 -1
  39. pvlib/data/tmy_45.000_8.000_2005_2020.txt +0 -8761
  40. pvlib/data/variables_style_rules.csv +0 -56
  41. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/AUTHORS.md +0 -0
  42. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/LICENSE +0 -0
  43. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/top_level.txt +0 -0
pvlib/temperature.py CHANGED
@@ -118,13 +118,25 @@ def sapm_cell(poa_global, temp_air, wind_speed, a, b, deltaT,
118
118
  +===============+================+=======+=========+=====================+
119
119
  | glass/glass | open rack | -3.47 | -0.0594 | 3 |
120
120
  +---------------+----------------+-------+---------+---------------------+
121
- | glass/glass | close roof | -2.98 | -0.0471 | 1 |
121
+ | glass/glass | close mount | -2.98 | -0.0471 | 1 |
122
122
  +---------------+----------------+-------+---------+---------------------+
123
123
  | glass/polymer | open rack | -3.56 | -0.075 | 3 |
124
124
  +---------------+----------------+-------+---------+---------------------+
125
125
  | glass/polymer | insulated back | -2.81 | -0.0455 | 0 |
126
126
  +---------------+----------------+-------+---------+---------------------+
127
127
 
128
+ Mounting cases can be described in terms of air flow across and around the
129
+ rear-facing surface of the module:
130
+
131
+ * "open rack" refers to mounting that allows relatively free air flow.
132
+ This case is typical of ground-mounted systems on fixed racking or
133
+ single axis trackers.
134
+ * "close mount" refers to limited or restricted air flow. This case is
135
+ typical of roof-mounted systems with some gap behind the module.
136
+ * "insulated back" refers to systems with no air flow contacting the rear
137
+ surface of the module. This case is typical of building-integrated PV
138
+ systems, or systems laid flat on a ground surface.
139
+
128
140
  References
129
141
  ----------
130
142
  .. [1] King, D. et al, 2004, "Sandia Photovoltaic Array Performance
@@ -199,13 +211,25 @@ def sapm_module(poa_global, temp_air, wind_speed, a, b):
199
211
  +===============+================+=======+=========+=====================+
200
212
  | glass/glass | open rack | -3.47 | -0.0594 | 3 |
201
213
  +---------------+----------------+-------+---------+---------------------+
202
- | glass/glass | close roof | -2.98 | -0.0471 | 1 |
214
+ | glass/glass | close mount | -2.98 | -0.0471 | 1 |
203
215
  +---------------+----------------+-------+---------+---------------------+
204
216
  | glass/polymer | open rack | -3.56 | -0.075 | 3 |
205
217
  +---------------+----------------+-------+---------+---------------------+
206
218
  | glass/polymer | insulated back | -2.81 | -0.0455 | 0 |
207
219
  +---------------+----------------+-------+---------+---------------------+
208
220
 
221
+ Mounting cases can be described in terms of air flow across and around the
222
+ rear-facing surface of the module:
223
+
224
+ * "open rack" refers to mounting that allows relatively free air flow.
225
+ This case is typical of ground-mounted systems on fixed racking or
226
+ single axis trackers.
227
+ * "close mount" refers to limited or restricted air flow. This case is
228
+ typical of roof-mounted systems with some gap behind the module.
229
+ * "insulated back" refers to systems with no air flow contacting the rear
230
+ surface of the module. This case is typical of building-integrated PV
231
+ systems, or systems laid flat on a ground surface.
232
+
209
233
  References
210
234
  ----------
211
235
  .. [1] King, D. et al, 2004, "Sandia Photovoltaic Array Performance
@@ -269,13 +293,25 @@ def sapm_cell_from_module(module_temperature, poa_global, deltaT,
269
293
  +===============+================+=======+=========+=====================+
270
294
  | glass/glass | open rack | -3.47 | -0.0594 | 3 |
271
295
  +---------------+----------------+-------+---------+---------------------+
272
- | glass/glass | close roof | -2.98 | -0.0471 | 1 |
296
+ | glass/glass | close mount | -2.98 | -0.0471 | 1 |
273
297
  +---------------+----------------+-------+---------+---------------------+
274
298
  | glass/polymer | open rack | -3.56 | -0.075 | 3 |
275
299
  +---------------+----------------+-------+---------+---------------------+
276
300
  | glass/polymer | insulated back | -2.81 | -0.0455 | 0 |
277
301
  +---------------+----------------+-------+---------+---------------------+
278
302
 
303
+ Mounting cases can be described in terms of air flow across and around the
304
+ rear-facing surface of the module:
305
+
306
+ * "open rack" refers to mounting that allows relatively free air flow.
307
+ This case is typical of ground-mounted systems on fixed racking or
308
+ single axis trackers.
309
+ * "close mount" refers to limited or restricted air flow. This case is
310
+ typical of roof-mounted systems with some gap behind the module.
311
+ * "insulated back" refers to systems with no air flow contacting the rear
312
+ surface of the module. This case is typical of building-integrated PV
313
+ systems, or systems laid flat on a ground surface.
314
+
279
315
  References
280
316
  ----------
281
317
  .. [1] King, D. et al, 2004, "Sandia Photovoltaic Array Performance
@@ -360,6 +396,16 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0,
360
396
  | insulated | 15.0 | 0.0 |
361
397
  +--------------+---------------+---------------+
362
398
 
399
+ Mounting cases can be described in terms of air flow across and around the
400
+ rear-facing surface of the module:
401
+
402
+ * "freestanding" refers to mounting that allows relatively free air
403
+ circulation around the modules. This case is typical of ground-mounted
404
+ systems on tilted, fixed racking or single axis trackers.
405
+ * "insulated" refers to mounting with air flow across only the front
406
+ surface. This case is typical of roof-mounted systems with no gap
407
+ behind the module.
408
+
363
409
  References
364
410
  ----------
365
411
  .. [1] "PVsyst 7 Help", [Online]. Available:
@@ -304,7 +304,7 @@ def test_read_pvgis_hourly_empty_file():
304
304
  # PVGIS TMY tests
305
305
  @pytest.fixture
306
306
  def expected():
307
- return pd.read_csv(DATA_DIR / 'pvgis_tmy_test.dat', index_col='time(UTC)')
307
+ return pd.read_csv(DATA_DIR / 'pvgis_tmy_test.csv', index_col='time(UTC)')
308
308
 
309
309
 
310
310
  @pytest.fixture
@@ -315,7 +315,7 @@ def userhorizon_expected():
315
315
  @pytest.fixture
316
316
  def month_year_expected():
317
317
  return [
318
- 2014, 2011, 2008, 2011, 2009, 2011, 2020, 2006, 2006, 2013, 2007, 2018]
318
+ 2018, 2007, 2009, 2013, 2008, 2006, 2011, 2010, 2020, 2006, 2007, 2016]
319
319
 
320
320
 
321
321
  @pytest.fixture
@@ -323,10 +323,10 @@ def inputs_expected():
323
323
  return {
324
324
  'location': {'latitude': 45.0, 'longitude': 8.0, 'elevation': 250.0},
325
325
  'meteo_data': {
326
- 'radiation_db': 'PVGIS-SARAH2',
326
+ 'radiation_db': 'PVGIS-SARAH3',
327
327
  'meteo_db': 'ERA5',
328
328
  'year_min': 2005,
329
- 'year_max': 2020,
329
+ 'year_max': 2023,
330
330
  'use_horizon': True,
331
331
  'horizon_db': 'DEM-calculated'}}
332
332
 
@@ -564,14 +564,14 @@ def test_read_pvgis_horizon_invalid_coords():
564
564
 
565
565
 
566
566
  def test_read_pvgis_tmy_map_variables(pvgis_tmy_mapped_columns):
567
- fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.json'
567
+ fn = DATA_DIR / 'tmy_45.000_8.000_2005_2023.json'
568
568
  actual, _, _, _ = read_pvgis_tmy(fn, map_variables=True)
569
569
  assert all(c in pvgis_tmy_mapped_columns for c in actual.columns)
570
570
 
571
571
 
572
572
  def test_read_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
573
573
  meta_expected):
574
- fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.json'
574
+ fn = DATA_DIR / 'tmy_45.000_8.000_2005_2023.json'
575
575
  # infer outputformat from file extensions
576
576
  pvgis_data = read_pvgis_tmy(fn, map_variables=False)
577
577
  _compare_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
@@ -588,7 +588,7 @@ def test_read_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
588
588
 
589
589
 
590
590
  def test_read_pvgis_tmy_epw(expected, epw_meta):
591
- fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.epw'
591
+ fn = DATA_DIR / 'tmy_45.000_8.000_2005_2023.epw'
592
592
  # infer outputformat from file extensions
593
593
  pvgis_data = read_pvgis_tmy(fn, map_variables=False)
594
594
  _compare_pvgis_tmy_epw(expected, epw_meta, pvgis_data)
@@ -603,7 +603,7 @@ def test_read_pvgis_tmy_epw(expected, epw_meta):
603
603
 
604
604
  def test_read_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
605
605
  meta_expected, csv_meta):
606
- fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.csv'
606
+ fn = DATA_DIR / 'tmy_45.000_8.000_2005_2023.csv'
607
607
  # infer outputformat from file extensions
608
608
  pvgis_data = read_pvgis_tmy(fn, map_variables=False)
609
609
  _compare_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
@@ -620,7 +620,7 @@ def test_read_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
620
620
 
621
621
 
622
622
  def test_read_pvgis_tmy_basic(expected, meta_expected):
623
- fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.txt'
623
+ fn = DATA_DIR / 'tmy_45.000_8.000_2005_2023.txt'
624
624
  # XXX: can't infer outputformat from file extensions for basic
625
625
  with pytest.raises(ValueError, match="pvgis format 'txt' was unknown"):
626
626
  read_pvgis_tmy(fn, map_variables=False)
@@ -1,12 +1,12 @@
1
1
  import numpy as np
2
2
  import pandas as pd
3
+ from scipy import optimize
3
4
 
4
5
  import pytest
5
6
  from numpy.testing import assert_allclose
6
7
 
7
8
  from pvlib.ivtools import sdm
8
9
  from pvlib import pvsystem
9
- from pvlib._deprecation import pvlibDeprecationWarning
10
10
 
11
11
  from pvlib.tests.conftest import requires_pysam, requires_statsmodels
12
12
 
@@ -80,6 +80,25 @@ def test_fit_desoto():
80
80
  rtol=1e-4)
81
81
 
82
82
 
83
+ def test_fit_desoto_init_guess(mocker):
84
+ init_guess_array = np.array([9.4, 3.0e-10, 0.3, 125., 1.6])
85
+ init_guess = {k: v for k, v in zip(
86
+ ['IL_0', 'Io_0', 'Rs_0', 'Rsh_0', 'a_0'], init_guess_array)}
87
+ spy = mocker.spy(optimize, 'root')
88
+ result, _ = sdm.fit_desoto(v_mp=31.0, i_mp=8.71, v_oc=38.3, i_sc=9.43,
89
+ alpha_sc=0.005658, beta_voc=-0.13788,
90
+ cells_in_series=60, init_guess=init_guess)
91
+ np.testing.assert_array_equal(init_guess_array, spy.call_args[1]['x0'])
92
+
93
+
94
+ def test_fit_desoto_init_bad_key():
95
+ init_guess = {'IL_0': 6., 'bad_key': 0}
96
+ with pytest.raises(ValueError, match='is not a valid name;'):
97
+ result, _ = sdm.fit_desoto(v_mp=31.0, i_mp=8.71, v_oc=38.3, i_sc=9.43,
98
+ alpha_sc=0.005658, beta_voc=-0.13788,
99
+ cells_in_series=60, init_guess=init_guess)
100
+
101
+
83
102
  def test_fit_desoto_failure():
84
103
  with pytest.raises(RuntimeError) as exc:
85
104
  sdm.fit_desoto(v_mp=31.0, i_mp=8.71, v_oc=38.3, i_sc=9.43,
@@ -121,6 +140,9 @@ def test_fit_desoto_sandia(cec_params_cansol_cs5p_220p):
121
140
  expected = pd.Series(params)
122
141
  assert np.allclose(modeled[params.keys()].values,
123
142
  expected[params.keys()].values, rtol=5e-2)
143
+ assert_allclose(result['dEgdT'], -0.0002677)
144
+ assert_allclose(result['EgRef'], 1.3112547292120638)
145
+ assert_allclose(result['cells_in_series'], specs['cells_in_series'])
124
146
 
125
147
 
126
148
  def _read_iv_curves_for_test(datafile, npts):
@@ -0,0 +1,97 @@
1
+ """
2
+ Test the _deprecation module.
3
+ """
4
+
5
+ import pytest
6
+
7
+ from pvlib import _deprecation
8
+ from .conftest import fail_on_pvlib_version
9
+
10
+ import warnings
11
+
12
+
13
+ @pytest.mark.xfail(strict=True,
14
+ reason='fail_on_pvlib_version should cause test to fail')
15
+ @fail_on_pvlib_version('0.0')
16
+ def test_fail_on_pvlib_version():
17
+ pass # pragma: no cover
18
+
19
+
20
+ @fail_on_pvlib_version('100000.0')
21
+ def test_fail_on_pvlib_version_pass():
22
+ pass
23
+
24
+
25
+ @pytest.mark.xfail(strict=True, reason='ensure that the test is called')
26
+ @fail_on_pvlib_version('100000.0')
27
+ def test_fail_on_pvlib_version_fail_in_test():
28
+ raise Exception
29
+
30
+
31
+ # set up to test using fixtures with function decorated with
32
+ # conftest.fail_on_pvlib_version
33
+ @pytest.fixture
34
+ def some_data():
35
+ return "some data"
36
+
37
+
38
+ def alt_func(*args):
39
+ return args
40
+
41
+
42
+ @pytest.fixture
43
+ def deprec_func():
44
+ return _deprecation.deprecated(
45
+ "350.8", alternative="alt_func", name="deprec_func", removal="350.9"
46
+ )(alt_func)
47
+
48
+
49
+ @fail_on_pvlib_version('350.9')
50
+ def test_use_fixture_with_decorator(some_data, deprec_func):
51
+ # test that the correct data is returned by the some_data fixture
52
+ assert some_data == "some data"
53
+ with pytest.warns(_deprecation.pvlibDeprecationWarning):
54
+ # test for custom deprecation warning provided by pvlib
55
+ deprec_func(some_data)
56
+
57
+
58
+ @pytest.fixture
59
+ def renamed_kwarg_func():
60
+ """Returns a function decorated by renamed_kwarg_warning.
61
+ This function is called 'func' and has a docstring equal to 'docstring'.
62
+ """
63
+
64
+ @_deprecation.renamed_kwarg_warning(
65
+ "0.1.0", "old_kwarg", "new_kwarg", "0.2.0"
66
+ )
67
+ def func(new_kwarg):
68
+ """docstring"""
69
+ return new_kwarg
70
+
71
+ return func
72
+
73
+
74
+ def test_renamed_kwarg_warning(renamed_kwarg_func):
75
+ # assert decorated function name and docstring are unchanged
76
+ assert renamed_kwarg_func.__name__ == "func"
77
+ assert renamed_kwarg_func.__doc__ == "docstring"
78
+
79
+ # assert no warning is raised when using the new kwarg
80
+ with warnings.catch_warnings():
81
+ warnings.simplefilter("error")
82
+ assert renamed_kwarg_func(new_kwarg=1) == 1 # as keyword argument
83
+ assert renamed_kwarg_func(1) == 1 # as positional argument
84
+
85
+ # assert a warning is raised when using the old kwarg
86
+ with pytest.warns(Warning, match="Parameter 'old_kwarg' has been renamed"):
87
+ assert renamed_kwarg_func(old_kwarg=1) == 1
88
+
89
+ # assert an error is raised when using both the old and new kwarg
90
+ with pytest.raises(ValueError, match="they refer to the same parameter."):
91
+ renamed_kwarg_func(old_kwarg=1, new_kwarg=2)
92
+
93
+ # assert when not providing any of them
94
+ with pytest.raises(
95
+ TypeError, match="missing 1 required positional argument"
96
+ ):
97
+ renamed_kwarg_func()
@@ -88,6 +88,153 @@ def test_gueymard94_pw():
88
88
  assert_allclose(pws, expected, atol=0.01)
89
89
 
90
90
 
91
+ def test_tdew_to_rh_to_tdew():
92
+
93
+ # dewpoint temp calculated with wmo and aekr coefficients
94
+ dewpoint_original = pd.Series([
95
+ 15.0, 20.0, 25.0, 12.0, 8.0
96
+ ])
97
+
98
+ temperature_ambient = pd.Series([20.0, 25.0, 30.0, 15.0, 10.0])
99
+
100
+ # Calculate relative humidity using pandas series as input
101
+ relative_humidity = atmosphere.rh_from_tdew(
102
+ temp_air=temperature_ambient,
103
+ temp_dew=dewpoint_original
104
+ )
105
+
106
+ dewpoint_calculated = atmosphere.tdew_from_rh(
107
+ temp_air=temperature_ambient,
108
+ relative_humidity=relative_humidity
109
+ )
110
+
111
+ # test
112
+ pd.testing.assert_series_equal(
113
+ dewpoint_original,
114
+ dewpoint_calculated,
115
+ check_names=False
116
+ )
117
+
118
+
119
+ def test_rh_from_tdew():
120
+
121
+ dewpoint = pd.Series([
122
+ 15.0, 20.0, 25.0, 12.0, 8.0
123
+ ])
124
+
125
+ # relative humidity calculated with wmo and aekr coefficients
126
+ relative_humidity_wmo = pd.Series([
127
+ 72.95185312581116, 73.81500029087906, 74.6401272083123,
128
+ 82.27063889868842, 87.39018119185337
129
+ ])
130
+ relative_humidity_aekr = pd.Series([
131
+ 72.93876680928582, 73.8025121880607, 74.62820502423823,
132
+ 82.26135295757305, 87.38323744820416
133
+ ])
134
+
135
+ temperature_ambient = pd.Series([20.0, 25.0, 30.0, 15.0, 10.0])
136
+
137
+ # Calculate relative humidity using pandas series as input
138
+ rh_series = atmosphere.rh_from_tdew(
139
+ temp_air=temperature_ambient,
140
+ temp_dew=dewpoint
141
+ )
142
+
143
+ pd.testing.assert_series_equal(
144
+ rh_series,
145
+ relative_humidity_wmo,
146
+ check_names=False
147
+ )
148
+
149
+ # Calulate relative humidity using pandas series as input
150
+ # with AEKR coefficients
151
+ rh_series_aekr = atmosphere.rh_from_tdew(
152
+ temp_air=temperature_ambient,
153
+ temp_dew=dewpoint,
154
+ coeff=(6.1094, 17.625, 243.04)
155
+ )
156
+
157
+ pd.testing.assert_series_equal(
158
+ rh_series_aekr,
159
+ relative_humidity_aekr,
160
+ check_names=False
161
+ )
162
+
163
+ # Calculate relative humidity using array as input
164
+ rh_array = atmosphere.rh_from_tdew(
165
+ temp_air=temperature_ambient.to_numpy(),
166
+ temp_dew=dewpoint.to_numpy()
167
+ )
168
+
169
+ np.testing.assert_allclose(rh_array, relative_humidity_wmo.to_numpy())
170
+
171
+ # Calculate relative humidity using float as input
172
+ rh_float = atmosphere.rh_from_tdew(
173
+ temp_air=temperature_ambient.iloc[0],
174
+ temp_dew=dewpoint.iloc[0]
175
+ )
176
+
177
+ assert np.isclose(rh_float, relative_humidity_wmo.iloc[0])
178
+
179
+
180
+ # Unit tests
181
+ def test_tdew_from_rh():
182
+
183
+ dewpoint = pd.Series([
184
+ 15.0, 20.0, 25.0, 12.0, 8.0
185
+ ])
186
+
187
+ # relative humidity calculated with wmo and aekr coefficients
188
+ relative_humidity_wmo = pd.Series([
189
+ 72.95185312581116, 73.81500029087906, 74.6401272083123,
190
+ 82.27063889868842, 87.39018119185337
191
+ ])
192
+ relative_humidity_aekr = pd.Series([
193
+ 72.93876680928582, 73.8025121880607, 74.62820502423823,
194
+ 82.26135295757305, 87.38323744820416
195
+ ])
196
+
197
+ temperature_ambient = pd.Series([20.0, 25.0, 30.0, 15.0, 10.0])
198
+
199
+ # test as series
200
+ dewpoint_series = atmosphere.tdew_from_rh(
201
+ temp_air=temperature_ambient,
202
+ relative_humidity=relative_humidity_wmo
203
+ )
204
+
205
+ pd.testing.assert_series_equal(
206
+ dewpoint_series, dewpoint, check_names=False
207
+ )
208
+
209
+ # test as series with AEKR coefficients
210
+ dewpoint_series_aekr = atmosphere.tdew_from_rh(
211
+ temp_air=temperature_ambient,
212
+ relative_humidity=relative_humidity_aekr,
213
+ coeff=(6.1094, 17.625, 243.04)
214
+ )
215
+
216
+ pd.testing.assert_series_equal(
217
+ dewpoint_series_aekr, dewpoint,
218
+ check_names=False
219
+ )
220
+
221
+ # test as numpy array
222
+ dewpoint_array = atmosphere.tdew_from_rh(
223
+ temp_air=temperature_ambient.to_numpy(),
224
+ relative_humidity=relative_humidity_wmo.to_numpy()
225
+ )
226
+
227
+ np.testing.assert_allclose(dewpoint_array, dewpoint.to_numpy())
228
+
229
+ # test as float
230
+ dewpoint_float = atmosphere.tdew_from_rh(
231
+ temp_air=temperature_ambient.iloc[0],
232
+ relative_humidity=relative_humidity_wmo.iloc[0]
233
+ )
234
+
235
+ assert np.isclose(dewpoint_float, dewpoint.iloc[0])
236
+
237
+
91
238
  def test_first_solar_spectral_correction_deprecated():
92
239
  with pytest.warns(pvlibDeprecationWarning,
93
240
  match='Use pvlib.spectrum.spectral_factor_firstsolar'):
@@ -674,10 +674,16 @@ def test_detect_clearsky_missing_index(detect_clearsky_data):
674
674
 
675
675
  def test_detect_clearsky_not_enough_data(detect_clearsky_data):
676
676
  expected, cs = detect_clearsky_data
677
- with pytest.raises(ValueError, match='have at least'):
677
+ with pytest.raises(ValueError, match='times has only'):
678
678
  clearsky.detect_clearsky(expected['GHI'], cs['ghi'], window_length=60)
679
679
 
680
680
 
681
+ def test_detect_clearsky_window_too_short(detect_clearsky_data):
682
+ expected, cs = detect_clearsky_data
683
+ with pytest.raises(ValueError, match="Samples per window of "):
684
+ clearsky.detect_clearsky(expected['GHI'], cs['ghi'], window_length=2)
685
+
686
+
681
687
  @pytest.mark.parametrize("window_length", [5, 10, 15, 20, 25])
682
688
  def test_detect_clearsky_optimizer_not_failed(
683
689
  detect_clearsky_data, window_length
@@ -1,50 +1,6 @@
1
1
  import pytest
2
- import pandas
3
2
 
4
3
  from pvlib.tests import conftest
5
- from pvlib.tests.conftest import fail_on_pvlib_version
6
-
7
- from pvlib._deprecation import pvlibDeprecationWarning, deprecated
8
-
9
- @pytest.mark.xfail(strict=True,
10
- reason='fail_on_pvlib_version should cause test to fail')
11
- @fail_on_pvlib_version('0.0')
12
- def test_fail_on_pvlib_version():
13
- pass
14
-
15
-
16
- @fail_on_pvlib_version('100000.0')
17
- def test_fail_on_pvlib_version_pass():
18
- pass
19
-
20
-
21
- @pytest.mark.xfail(strict=True, reason='ensure that the test is called')
22
- @fail_on_pvlib_version('100000.0')
23
- def test_fail_on_pvlib_version_fail_in_test():
24
- raise Exception
25
-
26
-
27
- # set up to test using fixtures with function decorated with
28
- # conftest.fail_on_pvlib_version
29
- @pytest.fixture()
30
- def some_data():
31
- return "some data"
32
-
33
-
34
- def alt_func(*args):
35
- return args
36
-
37
-
38
- deprec_func = deprecated('350.8', alternative='alt_func',
39
- name='deprec_func', removal='350.9')(alt_func)
40
-
41
-
42
- @fail_on_pvlib_version('350.9')
43
- def test_use_fixture_with_decorator(some_data):
44
- # test that the correct data is returned by the some_data fixture
45
- assert some_data == "some data"
46
- with pytest.warns(pvlibDeprecationWarning): # test for deprecation warning
47
- deprec_func(some_data)
48
4
 
49
5
 
50
6
  @pytest.mark.parametrize('function_name', ['assert_index_equal',
@@ -15,7 +15,8 @@ from .conftest import (
15
15
  assert_frame_equal,
16
16
  assert_series_equal,
17
17
  requires_ephem,
18
- requires_numba
18
+ requires_numba,
19
+ fail_on_pvlib_version,
19
20
  )
20
21
 
21
22
  from pvlib._deprecation import pvlibDeprecationWarning
@@ -1063,7 +1064,7 @@ def test_dirindex(times):
1063
1064
  np.array([0., 79.73860422, 1042.48031487, 257.20751138]),
1064
1065
  index=times
1065
1066
  )
1066
- dni_clearsky = pd.Series(
1067
+ dni_clear = pd.Series(
1067
1068
  np.array([0., 316.1949056, 939.95469881, 646.22886049]),
1068
1069
  index=times
1069
1070
  )
@@ -1073,7 +1074,7 @@ def test_dirindex(times):
1073
1074
  )
1074
1075
  pressure = 93193.
1075
1076
  tdew = 10.
1076
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clearsky,
1077
+ out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear,
1077
1078
  zenith, times, pressure=pressure,
1078
1079
  temp_dew=tdew)
1079
1080
  dirint_close_values = irradiance.dirint(ghi, zenith, times,
@@ -1094,6 +1095,20 @@ def test_dirindex(times):
1094
1095
  equal_nan=True)
1095
1096
 
1096
1097
 
1098
+ @fail_on_pvlib_version("0.13")
1099
+ def test_dirindex_ghi_clearsky_deprecation():
1100
+ times = pd.DatetimeIndex(['2014-06-24T18-1200'])
1101
+ ghi = pd.Series([1038.62], index=times)
1102
+ ghi_clearsky = pd.Series([1042.48031487], index=times)
1103
+ dni_clearsky = pd.Series([939.95469881], index=times)
1104
+ zenith = pd.Series([10.56413562], index=times)
1105
+ pressure, tdew = 93193, 10
1106
+ with pytest.warns(pvlibDeprecationWarning, match='ghi_clear'):
1107
+ irradiance.dirindex(
1108
+ ghi=ghi, ghi_clearsky=ghi_clearsky, dni_clear=dni_clearsky,
1109
+ zenith=zenith, times=times, pressure=pressure, temp_dew=tdew)
1110
+
1111
+
1097
1112
  def test_dirindex_min_cos_zenith_max_zenith():
1098
1113
  # map out behavior under difficult conditions with various
1099
1114
  # limiting kwargs settings
@@ -1101,38 +1116,51 @@ def test_dirindex_min_cos_zenith_max_zenith():
1101
1116
  times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
1102
1117
  ghi = pd.Series([0, 1], index=times)
1103
1118
  ghi_clearsky = pd.Series([0, 1], index=times)
1104
- dni_clearsky = pd.Series([0, 5], index=times)
1119
+ dni_clear = pd.Series([0, 5], index=times)
1105
1120
  solar_zenith = pd.Series([90, 89.99], index=times)
1106
1121
 
1107
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clearsky, solar_zenith,
1122
+ out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1108
1123
  times)
1109
1124
  expected = pd.Series([nan, nan], index=times)
1110
1125
  assert_series_equal(out, expected)
1111
1126
 
1112
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clearsky, solar_zenith,
1127
+ out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1113
1128
  times, min_cos_zenith=0)
1114
1129
  expected = pd.Series([nan, nan], index=times)
1115
1130
  assert_series_equal(out, expected)
1116
1131
 
1117
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clearsky, solar_zenith,
1132
+ out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1118
1133
  times, max_zenith=90)
1119
1134
  expected = pd.Series([nan, nan], index=times)
1120
1135
  assert_series_equal(out, expected)
1121
1136
 
1122
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clearsky, solar_zenith,
1137
+ out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1123
1138
  times, min_cos_zenith=0, max_zenith=100)
1124
1139
  expected = pd.Series([nan, 5.], index=times)
1125
1140
  assert_series_equal(out, expected)
1126
1141
 
1127
1142
 
1143
+ @fail_on_pvlib_version("0.13")
1144
+ def test_dirindex_dni_clearsky_deprecation():
1145
+ times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
1146
+ ghi = pd.Series([0, 1], index=times)
1147
+ ghi_clearsky = pd.Series([0, 1], index=times)
1148
+ dni_clear = pd.Series([0, 5], index=times)
1149
+ solar_zenith = pd.Series([90, 89.99], index=times)
1150
+ with pytest.warns(pvlibDeprecationWarning, match='dni_clear'):
1151
+ irradiance.dirindex(ghi, ghi_clearsky, dni_clearsky=dni_clear,
1152
+ zenith=solar_zenith, times=times,
1153
+ min_cos_zenith=0)
1154
+
1155
+
1128
1156
  def test_dni():
1129
1157
  ghi = pd.Series([90, 100, 100, 100, 100])
1130
1158
  dhi = pd.Series([100, 90, 50, 50, 50])
1131
1159
  zenith = pd.Series([80, 100, 85, 70, 85])
1132
- clearsky_dni = pd.Series([50, 50, 200, 50, 300])
1160
+ dni_clear = pd.Series([50, 50, 200, 50, 300])
1133
1161
 
1134
1162
  dni = irradiance.dni(ghi, dhi, zenith,
1135
- clearsky_dni=clearsky_dni, clearsky_tolerance=2)
1163
+ dni_clear=dni_clear, clearsky_tolerance=2)
1136
1164
  assert_series_equal(dni,
1137
1165
  pd.Series([float('nan'), float('nan'), 400,
1138
1166
  146.190220008, 573.685662283]))
@@ -1143,6 +1171,17 @@ def test_dni():
1143
1171
  146.190220008, 573.685662283]))
1144
1172
 
1145
1173
 
1174
+ @fail_on_pvlib_version("0.13")
1175
+ def test_dni_dni_clearsky_deprecation():
1176
+ ghi = pd.Series([90, 100, 100, 100, 100])
1177
+ dhi = pd.Series([100, 90, 50, 50, 50])
1178
+ zenith = pd.Series([80, 100, 85, 70, 85])
1179
+ dni_clear = pd.Series([50, 50, 200, 50, 300])
1180
+ with pytest.warns(pvlibDeprecationWarning, match='dni_clear'):
1181
+ irradiance.dni(ghi, dhi, zenith,
1182
+ clearsky_dni=dni_clear, clearsky_tolerance=2)
1183
+
1184
+
1146
1185
  @pytest.mark.parametrize(
1147
1186
  'surface_tilt,surface_azimuth,solar_zenith,' +
1148
1187
  'solar_azimuth,aoi_expected,aoi_proj_expected',
@@ -1235,6 +1274,13 @@ def test_clearsky_index():
1235
1274
  assert_series_equal(out, expected)
1236
1275
 
1237
1276
 
1277
+ @fail_on_pvlib_version("0.13")
1278
+ def test_clearsky_index_clearsky_ghi_deprecation():
1279
+ with pytest.warns(pvlibDeprecationWarning, match='ghi_clear'):
1280
+ ghi, clearsky_ghi = 200, 300
1281
+ irradiance.clearsky_index(ghi, clearsky_ghi=clearsky_ghi)
1282
+
1283
+
1238
1284
  def test_clearness_index():
1239
1285
  ghi = np.array([-1, 0, 1, 1000])
1240
1286
  solar_zenith = np.array([180, 90, 89.999, 0])