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/tests/test_iam.py CHANGED
@@ -42,7 +42,7 @@ def test_physical():
42
42
  expected = np.array([0, 0.8893998, 0.98797788, 0.99926198, 1, 0.99926198,
43
43
  0.98797788, 0.8893998, 0, np.nan])
44
44
  iam = _iam.physical(aoi, 1.526, 0.002, 4)
45
- assert_allclose(iam, expected, equal_nan=True)
45
+ assert_allclose(iam, expected, atol=1e-7, equal_nan=True)
46
46
 
47
47
  # GitHub issue 397
48
48
  aoi = pd.Series(aoi)
@@ -51,6 +51,34 @@ 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
+
66
+ def test_physical_ar():
67
+ aoi = np.array([0, 22.5, 45, 67.5, 90, 100, np.nan])
68
+ expected = np.array([1, 0.99944171, 0.9917463, 0.91506158, 0, 0, np.nan])
69
+ iam = _iam.physical(aoi, n_ar=1.29)
70
+ assert_allclose(iam, expected, atol=1e-7, equal_nan=True)
71
+
72
+
73
+ def test_physical_noar():
74
+ aoi = np.array([0, 22.5, 45, 67.5, 90, 100, np.nan])
75
+ expected = _iam.physical(aoi)
76
+ iam0 = _iam.physical(aoi, n_ar=1)
77
+ iam1 = _iam.physical(aoi, n_ar=1.526)
78
+ assert_allclose(iam0, expected, equal_nan=True)
79
+ assert_allclose(iam1, expected, equal_nan=True)
80
+
81
+
54
82
  def test_physical_scalar():
55
83
  aoi = -45.
56
84
  iam = _iam.physical(aoi, 1.526, 0.002, 4)
@@ -322,3 +350,48 @@ def test_marion_integrate_invalid():
322
350
 
323
351
  with pytest.raises(ValueError):
324
352
  _iam.marion_integrate(_iam.ashrae, 0, 'bad', 180)
353
+
354
+
355
+ def test_schlick():
356
+ idx = pd.date_range('2019-01-01', freq='h', periods=9)
357
+ aoi = pd.Series([-180, -135, -90, -45, 0, 45, 90, 135, 180], idx)
358
+ expected = pd.Series([0, 0, 0, 0.99784451, 1.0, 0.99784451, 0, 0, 0], idx)
359
+
360
+ # scalars
361
+ for aoi_scalar, expected_scalar in zip(aoi, expected):
362
+ actual = _iam.schlick(aoi_scalar)
363
+ assert_allclose(expected_scalar, actual)
364
+
365
+ # numpy arrays
366
+ actual = _iam.schlick(aoi.values)
367
+ assert_allclose(expected.values, actual)
368
+
369
+ # pandas Series
370
+ actual = _iam.schlick(aoi)
371
+ assert_series_equal(expected, actual)
372
+
373
+
374
+ def test_schlick_diffuse():
375
+ surface_tilt = np.array([0, 20, 70, 90])
376
+ # expected values calculated with marion_integrate and schlick
377
+ expected_sky = np.array([0.95238092, 0.96249934, 0.96228167, 0.95238094])
378
+ expected_ground = np.array([0, 0.62693858, 0.93218737, 0.95238094])
379
+
380
+ # numpy arrays
381
+ actual_sky, actual_ground = _iam.schlick_diffuse(surface_tilt)
382
+ assert_allclose(expected_sky, actual_sky)
383
+ assert_allclose(expected_ground, actual_ground, rtol=1e-6)
384
+
385
+ # scalars
386
+ for i in range(len(surface_tilt)):
387
+ actual_sky, actual_ground = _iam.schlick_diffuse(surface_tilt[i])
388
+ assert_allclose(expected_sky[i], actual_sky)
389
+ assert_allclose(expected_ground[i], actual_ground, rtol=1e-6)
390
+
391
+ # pandas Series
392
+ idx = pd.date_range('2019-01-01', freq='h', periods=len(surface_tilt))
393
+ actual_sky, actual_ground = _iam.schlick_diffuse(pd.Series(surface_tilt,
394
+ idx))
395
+ assert_series_equal(pd.Series(expected_sky, idx), actual_sky)
396
+ assert_series_equal(pd.Series(expected_ground, idx), actual_ground,
397
+ rtol=1e-6)
@@ -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'],
@@ -804,6 +805,38 @@ def test_erbs():
804
805
  assert_frame_equal(np.round(out, 0), np.round(expected, 0))
805
806
 
806
807
 
808
+ def test_boland():
809
+ index = pd.DatetimeIndex(['20190101']*3 + ['20190620'])
810
+ ghi = pd.Series([0, 50, 1000, 1000], index=index)
811
+ zenith = pd.Series([120, 85, 10, 10], index=index)
812
+ expected = pd.DataFrame(np.array(
813
+ [[0.0, 0.0, 0.0],
814
+ [81.9448546, 42.8580353, 0.405723511],
815
+ [723.764990, 287.230626, 0.718132729],
816
+ [805.020419, 207.209650, 0.768214312]]),
817
+ columns=['dni', 'dhi', 'kt'], index=index)
818
+
819
+ out = irradiance.boland(ghi, zenith, index)
820
+
821
+ assert np.allclose(out, expected)
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
+
807
840
  def test_erbs_min_cos_zenith_max_zenith():
808
841
  # map out behavior under difficult conditions with various
809
842
  # limiting kwargs settings
@@ -887,8 +920,12 @@ def test_dirindex(times):
887
920
  assert np.allclose(out, expected_out, rtol=tolerance, atol=0,
888
921
  equal_nan=True)
889
922
  tol_dirint = 0.2
890
- assert np.allclose(out.values, dirint_close_values, rtol=tol_dirint, atol=0,
891
- 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)
892
929
 
893
930
 
894
931
  def test_dirindex_min_cos_zenith_max_zenith():
@@ -1187,3 +1224,20 @@ def test_complete_irradiance():
1187
1224
  dhi=None,
1188
1225
  dni=i.dni,
1189
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
+
@@ -0,0 +1,46 @@
1
+ import numpy as np
2
+ from numpy.testing import assert_allclose
3
+
4
+ from pvlib import pvarray
5
+
6
+
7
+ def test_pvefficiency_adr():
8
+ g = [1000, 200, 1000, 200, 1000, 200, 0.0, np.nan]
9
+ t = [25, 25, 50, 50, 75, 75, 25, 25]
10
+ params = [1.0, -6.651460, 0.018736, 0.070679, 0.054170]
11
+
12
+ # the expected values were calculated using the new function itself
13
+ # hence this test is primarily a regression test
14
+ eta = [1.0, 0.949125, 0.928148, 0.876472, 0.855759, 0.803281, 0.0, np.nan]
15
+
16
+ result = pvarray.pvefficiency_adr(g, t, *params)
17
+ assert_allclose(result, eta, atol=1e-6)
18
+
19
+
20
+ def test_fit_pvefficiency_adr():
21
+ g = [1000, 200, 1000, 200, 1000, 200]
22
+ t = [25, 25, 50, 50, 75, 75]
23
+ eta = [1.0, 0.949125, 0.928148, 0.876472, 0.855759, 0.803281]
24
+
25
+ # the expected values were calculated using the new function itself
26
+ # hence this test is primarily a regression test
27
+ params = [1.0, -6.651460, 0.018736, 0.070679, 0.054170]
28
+
29
+ result = pvarray.fit_pvefficiency_adr(g, t, eta, dict_output=False)
30
+ # the fitted parameters vary somewhat by platform during the testing
31
+ # so the tolerance is higher on the parameters than on the efficiencies
32
+ # in the other tests
33
+ assert_allclose(result, params, rtol=1e-3)
34
+
35
+ result = pvarray.fit_pvefficiency_adr(g, t, eta, dict_output=True)
36
+ assert 'k_a' in result
37
+
38
+
39
+ def test_pvefficiency_adr_round_trip():
40
+ g = [1000, 200, 1000, 200, 1000, 200]
41
+ t = [25, 25, 50, 50, 75, 75]
42
+ eta = [1.0, 0.949125, 0.928148, 0.876472, 0.855759, 0.803281]
43
+
44
+ params = pvarray.fit_pvefficiency_adr(g, t, eta, dict_output=False)
45
+ result = pvarray.pvefficiency_adr(g, t, *params)
46
+ assert_allclose(result, eta, atol=1e-6)