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.
Files changed (71) hide show
  1. pvlib/__init__.py +3 -2
  2. pvlib/atmosphere.py +6 -171
  3. pvlib/bifacial/infinite_sheds.py +30 -267
  4. pvlib/bifacial/utils.py +225 -5
  5. pvlib/data/test_psm3_2017.csv +17521 -17521
  6. pvlib/data/test_read_psm3.csv +17522 -17522
  7. pvlib/data/test_read_pvgis_horizon.csv +49 -0
  8. pvlib/data/variables_style_rules.csv +3 -0
  9. pvlib/iam.py +17 -4
  10. pvlib/inverter.py +6 -1
  11. pvlib/iotools/__init__.py +7 -2
  12. pvlib/iotools/acis.py +516 -0
  13. pvlib/iotools/midc.py +4 -4
  14. pvlib/iotools/psm3.py +32 -31
  15. pvlib/iotools/pvgis.py +84 -28
  16. pvlib/iotools/sodapro.py +8 -6
  17. pvlib/iotools/srml.py +121 -18
  18. pvlib/iotools/surfrad.py +2 -2
  19. pvlib/iotools/tmy.py +146 -102
  20. pvlib/irradiance.py +151 -0
  21. pvlib/ivtools/sde.py +11 -7
  22. pvlib/ivtools/sdm.py +16 -10
  23. pvlib/ivtools/utils.py +6 -6
  24. pvlib/location.py +3 -2
  25. pvlib/modelchain.py +67 -70
  26. pvlib/pvsystem.py +160 -532
  27. pvlib/shading.py +41 -0
  28. pvlib/singlediode.py +215 -65
  29. pvlib/soiling.py +3 -3
  30. pvlib/spa.py +327 -368
  31. pvlib/spectrum/__init__.py +8 -2
  32. pvlib/spectrum/mismatch.py +335 -0
  33. pvlib/temperature.py +1 -8
  34. pvlib/tests/bifacial/test_infinite_sheds.py +0 -111
  35. pvlib/tests/bifacial/test_utils.py +101 -4
  36. pvlib/tests/conftest.py +0 -31
  37. pvlib/tests/iotools/test_acis.py +213 -0
  38. pvlib/tests/iotools/test_midc.py +6 -6
  39. pvlib/tests/iotools/test_psm3.py +3 -3
  40. pvlib/tests/iotools/test_pvgis.py +21 -14
  41. pvlib/tests/iotools/test_sodapro.py +1 -1
  42. pvlib/tests/iotools/test_srml.py +71 -6
  43. pvlib/tests/iotools/test_tmy.py +43 -8
  44. pvlib/tests/ivtools/test_sde.py +19 -17
  45. pvlib/tests/ivtools/test_sdm.py +9 -4
  46. pvlib/tests/test_atmosphere.py +6 -62
  47. pvlib/tests/test_iam.py +12 -0
  48. pvlib/tests/test_irradiance.py +40 -2
  49. pvlib/tests/test_location.py +1 -1
  50. pvlib/tests/test_modelchain.py +33 -76
  51. pvlib/tests/test_pvsystem.py +366 -201
  52. pvlib/tests/test_shading.py +28 -0
  53. pvlib/tests/test_singlediode.py +166 -30
  54. pvlib/tests/test_soiling.py +8 -7
  55. pvlib/tests/test_spa.py +6 -7
  56. pvlib/tests/test_spectrum.py +145 -1
  57. pvlib/tests/test_temperature.py +0 -7
  58. pvlib/tests/test_tools.py +25 -0
  59. pvlib/tests/test_tracking.py +0 -149
  60. pvlib/tools.py +26 -1
  61. pvlib/tracking.py +1 -269
  62. {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/METADATA +1 -9
  63. {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/RECORD +67 -68
  64. pvlib/forecast.py +0 -1211
  65. pvlib/iotools/ecmwf_macc.py +0 -312
  66. pvlib/tests/iotools/test_ecmwf_macc.py +0 -162
  67. pvlib/tests/test_forecast.py +0 -228
  68. {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/AUTHORS.md +0 -0
  69. {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/LICENSE +0 -0
  70. {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/WHEEL +0 -0
  71. {pvlib-0.9.5.dist-info → pvlib-0.10.0.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,8 @@ import pytest
9
9
 
10
10
  from pvlib import atmosphere
11
11
 
12
+ from pvlib._deprecation import pvlibDeprecationWarning
13
+
12
14
 
13
15
  def test_pres2alt():
14
16
  out = atmosphere.pres2alt(np.array([10000, 90000, 101325]))
@@ -86,68 +88,10 @@ def test_gueymard94_pw():
86
88
  assert_allclose(pws, expected, atol=0.01)
87
89
 
88
90
 
89
- @pytest.mark.parametrize("module_type,expect", [
90
- ('cdte', np.array(
91
- [[ 0.9905102 , 0.9764032 , 0.93975028],
92
- [ 1.02928735, 1.01881074, 0.98578821],
93
- [ 1.04750335, 1.03814456, 1.00623986]])),
94
- ('monosi', np.array(
95
- [[ 0.9776977 , 1.02043409, 1.03574032],
96
- [ 0.98630905, 1.03055092, 1.04736262],
97
- [ 0.98828494, 1.03299036, 1.05026561]])),
98
- ('polysi', np.array(
99
- [[ 0.9770408 , 1.01705849, 1.02613202],
100
- [ 0.98992828, 1.03173953, 1.04260662],
101
- [ 0.99352435, 1.03588785, 1.04730718]])),
102
- ('cigs', np.array(
103
- [[ 0.9745919 , 1.02821696, 1.05067895],
104
- [ 0.97529378, 1.02967497, 1.05289307],
105
- [ 0.97269159, 1.02730558, 1.05075651]])),
106
- ('asi', np.array(
107
- [[ 1.0555275 , 0.87707583, 0.72243772],
108
- [ 1.11225204, 0.93665901, 0.78487953],
109
- [ 1.14555295, 0.97084011, 0.81994083]]))
110
- ])
111
- def test_first_solar_spectral_correction(module_type, expect):
112
- ams = np.array([1, 3, 5])
113
- pws = np.array([1, 3, 5])
114
- ams, pws = np.meshgrid(ams, pws)
115
- out = atmosphere.first_solar_spectral_correction(pws, ams, module_type)
116
- assert_allclose(out, expect, atol=0.001)
117
-
118
-
119
- def test_first_solar_spectral_correction_supplied():
120
- # use the cdte coeffs
121
- coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187)
122
- out = atmosphere.first_solar_spectral_correction(1, 1, coefficients=coeffs)
123
- expected = 0.99134828
124
- assert_allclose(out, expected, atol=1e-3)
125
-
126
-
127
- def test_first_solar_spectral_correction_ambiguous():
128
- with pytest.raises(TypeError):
129
- atmosphere.first_solar_spectral_correction(1, 1)
130
-
131
-
132
- def test_first_solar_spectral_correction_range():
133
- with pytest.warns(UserWarning, match='Exceptionally high pw values'):
134
- out = atmosphere.first_solar_spectral_correction(np.array([.1, 3, 10]),
135
- np.array([1, 3, 5]),
136
- module_type='monosi')
137
- expected = np.array([0.96080878, 1.03055092, nan])
138
- assert_allclose(out, expected, atol=1e-3)
139
- with pytest.warns(UserWarning, match='Exceptionally high pw values'):
140
- out = atmosphere.first_solar_spectral_correction(6, 1.5, max_pw=5,
141
- module_type='monosi')
142
- with pytest.warns(UserWarning, match='Exceptionally low pw values'):
143
- out = atmosphere.first_solar_spectral_correction(np.array([0, 3, 8]),
144
- np.array([1, 3, 5]),
145
- module_type='monosi')
146
- expected = np.array([0.96080878, 1.03055092, 1.04932727])
147
- assert_allclose(out, expected, atol=1e-3)
148
- with pytest.warns(UserWarning, match='Exceptionally low pw values'):
149
- out = atmosphere.first_solar_spectral_correction(0.2, 1.5, min_pw=1,
150
- module_type='monosi')
91
+ def test_first_solar_spectral_correction_deprecated():
92
+ with pytest.warns(pvlibDeprecationWarning,
93
+ match='Use pvlib.spectrum.spectral_factor_firstsolar'):
94
+ atmosphere.first_solar_spectral_correction(1, 1, 'cdte')
151
95
 
152
96
 
153
97
  def test_kasten96_lt():
pvlib/tests/test_iam.py CHANGED
@@ -51,6 +51,18 @@ def test_physical():
51
51
  assert_series_equal(iam, expected)
52
52
 
53
53
 
54
+ def test_physical_n1_L0():
55
+ aoi = np.array([0, 22.5, 45, 67.5, 90, 100, np.nan])
56
+ expected = np.array([1, 1, 1, 1, 0, 0, np.nan])
57
+ iam = _iam.physical(aoi, n=1, L=0)
58
+ assert_allclose(iam, expected, equal_nan=True)
59
+
60
+ aoi = pd.Series(aoi)
61
+ expected = pd.Series(expected)
62
+ iam = _iam.physical(aoi, n=1, L=0)
63
+ assert_series_equal(iam, expected)
64
+
65
+
54
66
  def test_physical_ar():
55
67
  aoi = np.array([0, 22.5, 45, 67.5, 90, 100, np.nan])
56
68
  expected = np.array([1, 0.99944171, 0.9917463, 0.91506158, 0, 0, np.nan])
@@ -246,6 +246,7 @@ def test_haydavies_components(irrad_data, ephem_data, dni_et):
246
246
  assert_allclose(result['horizon'], expected['horizon'][-1], atol=1e-4)
247
247
  assert isinstance(result, dict)
248
248
 
249
+
249
250
  def test_reindl(irrad_data, ephem_data, dni_et):
250
251
  result = irradiance.reindl(
251
252
  40, 180, irrad_data['dhi'], irrad_data['dni'], irrad_data['ghi'],
@@ -820,6 +821,22 @@ def test_boland():
820
821
  assert np.allclose(out, expected)
821
822
 
822
823
 
824
+ def test_orgill_hollands():
825
+ index = pd.DatetimeIndex(['20190101']*3 + ['20190620'])
826
+ ghi = pd.Series([0, 50, 1000, 1000], index=index)
827
+ zenith = pd.Series([120, 85, 10, 10], index=index)
828
+ expected = pd.DataFrame(np.array(
829
+ [[0.0, 0.0, 0.0],
830
+ [108.731366, 40.5234370, 0.405723511],
831
+ [776.155771, 235.635779, 0.718132729],
832
+ [835.696102, 177.000000, 0.768214312]]),
833
+ columns=['dni', 'dhi', 'kt'], index=index)
834
+
835
+ out = irradiance.orgill_hollands(ghi, zenith, index)
836
+
837
+ assert np.allclose(out, expected)
838
+
839
+
823
840
  def test_erbs_min_cos_zenith_max_zenith():
824
841
  # map out behavior under difficult conditions with various
825
842
  # limiting kwargs settings
@@ -903,8 +920,12 @@ def test_dirindex(times):
903
920
  assert np.allclose(out, expected_out, rtol=tolerance, atol=0,
904
921
  equal_nan=True)
905
922
  tol_dirint = 0.2
906
- assert np.allclose(out.values, dirint_close_values, rtol=tol_dirint, atol=0,
907
- equal_nan=True)
923
+ assert np.allclose(
924
+ out.values,
925
+ dirint_close_values,
926
+ rtol=tol_dirint,
927
+ atol=0,
928
+ equal_nan=True)
908
929
 
909
930
 
910
931
  def test_dirindex_min_cos_zenith_max_zenith():
@@ -1203,3 +1224,20 @@ def test_complete_irradiance():
1203
1224
  dhi=None,
1204
1225
  dni=i.dni,
1205
1226
  dni_clear=clearsky.dni)
1227
+
1228
+
1229
+ def test_louche():
1230
+
1231
+ index = pd.DatetimeIndex(['20190101']*3 + ['20190620']*1)
1232
+ ghi = pd.Series([0, 50, 1000, 1000], index=index)
1233
+ zenith = pd.Series([91, 85, 10, 10], index=index)
1234
+ expected = pd.DataFrame(np.array(
1235
+ [[0, 0, 0],
1236
+ [130.089669, 38.661938, 0.405724],
1237
+ [828.498650, 184.088106, 0.718133],
1238
+ [887.407348, 126.074364, 0.768214]]),
1239
+ columns=['dni', 'dhi', 'kt'], index=index)
1240
+
1241
+ out = irradiance.louche(ghi, zenith, index)
1242
+
1243
+ assert_frame_equal(out, expected)
@@ -212,7 +212,7 @@ def test_get_clearsky_valueerror(times):
212
212
  def test_from_tmy_3():
213
213
  from pvlib.tests.iotools.test_tmy import TMY3_TESTFILE
214
214
  from pvlib.iotools import read_tmy3
215
- data, meta = read_tmy3(TMY3_TESTFILE)
215
+ data, meta = read_tmy3(TMY3_TESTFILE, map_variables=True)
216
216
  loc = Location.from_tmy(meta, data)
217
217
  assert loc.name is not None
218
218
  assert loc.altitude != 0
@@ -6,7 +6,6 @@ import pandas as pd
6
6
  from pvlib import iam, modelchain, pvsystem, temperature, inverter
7
7
  from pvlib.modelchain import ModelChain
8
8
  from pvlib.pvsystem import PVSystem
9
- from pvlib.tracking import SingleAxisTracker
10
9
  from pvlib.location import Location
11
10
  from pvlib._deprecation import pvlibDeprecationWarning
12
11
 
@@ -753,50 +752,6 @@ def test_run_model_with_weather_noct_sam_temp(sapm_dc_snl_ac_system, location,
753
752
  'model': 'noct_sam'}
754
753
 
755
754
 
756
- def test_run_model_tracker(sapm_dc_snl_ac_system, location, weather, mocker):
757
- with pytest.warns(pvlibDeprecationWarning):
758
- system = SingleAxisTracker(
759
- module_parameters=sapm_dc_snl_ac_system.arrays[0].module_parameters, # noqa: E501
760
- temperature_model_parameters=(
761
- sapm_dc_snl_ac_system.arrays[0].temperature_model_parameters
762
- ),
763
- inverter_parameters=sapm_dc_snl_ac_system.inverter_parameters)
764
- mocker.spy(system, 'singleaxis')
765
- mc = ModelChain(system, location)
766
- mc.run_model(weather)
767
- assert system.singleaxis.call_count == 1
768
- assert (mc.results.tracking.columns == ['tracker_theta',
769
- 'aoi',
770
- 'surface_azimuth',
771
- 'surface_tilt']).all()
772
- assert mc.results.ac[0] > 0
773
- assert np.isnan(mc.results.ac[1])
774
- assert isinstance(mc.results.dc, pd.DataFrame)
775
-
776
-
777
- def test_run_model_tracker_list(
778
- sapm_dc_snl_ac_system, location, weather, mocker):
779
- with pytest.warns(pvlibDeprecationWarning):
780
- system = SingleAxisTracker(
781
- module_parameters=sapm_dc_snl_ac_system.arrays[0].module_parameters, # noqa: E501
782
- temperature_model_parameters=(
783
- sapm_dc_snl_ac_system.arrays[0].temperature_model_parameters
784
- ),
785
- inverter_parameters=sapm_dc_snl_ac_system.inverter_parameters)
786
- mocker.spy(system, 'singleaxis')
787
- mc = ModelChain(system, location)
788
- mc.run_model([weather])
789
- assert system.singleaxis.call_count == 1
790
- assert (mc.results.tracking.columns == ['tracker_theta',
791
- 'aoi',
792
- 'surface_azimuth',
793
- 'surface_tilt']).all()
794
- assert mc.results.ac[0] > 0
795
- assert np.isnan(mc.results.ac[1])
796
- assert isinstance(mc.results.dc, tuple)
797
- assert len(mc.results.dc) == 1
798
-
799
-
800
755
  def test__assign_total_irrad(sapm_dc_snl_ac_system, location, weather,
801
756
  total_irrad):
802
757
  data = pd.concat([weather, total_irrad], axis=1)
@@ -1047,27 +1002,6 @@ def test_run_model_from_poa_arrays_solar_position_weather(
1047
1002
  assert_series_equal(m.call_args[1]['pressure'], data['pressure'])
1048
1003
 
1049
1004
 
1050
- def test_run_model_from_poa_tracking(sapm_dc_snl_ac_system, location,
1051
- total_irrad):
1052
- with pytest.warns(pvlibDeprecationWarning):
1053
- system = SingleAxisTracker(
1054
- module_parameters=sapm_dc_snl_ac_system.arrays[0].module_parameters, # noqa: E501
1055
- temperature_model_parameters=(
1056
- sapm_dc_snl_ac_system.arrays[0].temperature_model_parameters
1057
- ),
1058
- inverter_parameters=sapm_dc_snl_ac_system.inverter_parameters)
1059
- mc = ModelChain(system, location, aoi_model='no_loss',
1060
- spectral_model='no_loss')
1061
- ac = mc.run_model_from_poa(total_irrad).results.ac
1062
- assert (mc.results.tracking.columns == ['tracker_theta',
1063
- 'aoi',
1064
- 'surface_azimuth',
1065
- 'surface_tilt']).all()
1066
- expected = pd.Series(np.array([149.280238, 96.678385]),
1067
- index=total_irrad.index)
1068
- assert_series_equal(ac, expected)
1069
-
1070
-
1071
1005
  @pytest.mark.parametrize("input_type", [lambda x: x[0], tuple, list])
1072
1006
  def test_run_model_from_effective_irradiance(sapm_dc_snl_ac_system, location,
1073
1007
  weather, total_irrad, input_type):
@@ -1798,16 +1732,6 @@ def test_ModelChain_no_extra_kwargs(sapm_dc_snl_ac_system, location):
1798
1732
  ModelChain(sapm_dc_snl_ac_system, location, arbitrary_kwarg='value')
1799
1733
 
1800
1734
 
1801
- @fail_on_pvlib_version('0.10')
1802
- def test_ModelChain_attributes_deprecated_10(sapm_dc_snl_ac_system, location):
1803
- match = 'Use ModelChain.results'
1804
- mc = ModelChain(sapm_dc_snl_ac_system, location)
1805
- with pytest.warns(pvlibDeprecationWarning, match=match):
1806
- mc.aoi
1807
- with pytest.warns(pvlibDeprecationWarning, match=match):
1808
- mc.aoi = 5
1809
-
1810
-
1811
1735
  def test_basic_chain_alt_az(sam_data, cec_inverter_parameters,
1812
1736
  sapm_temperature_cs5p_220m):
1813
1737
  times = pd.date_range(start='20160101 1200-0700',
@@ -2063,3 +1987,36 @@ def test__irrad_for_celltemp():
2063
1987
  assert len(poa) == 2
2064
1988
  assert_series_equal(poa[0], effect_irrad)
2065
1989
  assert_series_equal(poa[1], effect_irrad)
1990
+
1991
+
1992
+ def test_ModelChain___repr__(sapm_dc_snl_ac_system, location):
1993
+
1994
+ mc = ModelChain(sapm_dc_snl_ac_system, location,
1995
+ name='my mc')
1996
+
1997
+ expected = '\n'.join([
1998
+ 'ModelChain: ',
1999
+ ' name: my mc',
2000
+ ' clearsky_model: ineichen',
2001
+ ' transposition_model: haydavies',
2002
+ ' solar_position_method: nrel_numpy',
2003
+ ' airmass_model: kastenyoung1989',
2004
+ ' dc_model: sapm',
2005
+ ' ac_model: sandia_inverter',
2006
+ ' aoi_model: sapm_aoi_loss',
2007
+ ' spectral_model: sapm_spectral_loss',
2008
+ ' temperature_model: sapm_temp',
2009
+ ' losses_model: no_extra_losses'
2010
+ ])
2011
+
2012
+ assert mc.__repr__() == expected
2013
+
2014
+
2015
+ def test_ModelChainResult___repr__(sapm_dc_snl_ac_system, location, weather):
2016
+ mc = ModelChain(sapm_dc_snl_ac_system, location)
2017
+ mc.run_model(weather)
2018
+ mcres = mc.results.__repr__()
2019
+ mc_attrs = dir(mc.results)
2020
+ mc_attrs = [a for a in mc_attrs if not a.startswith('_')]
2021
+ assert all([a in mcres for a in mc_attrs])
2022
+