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.
- pvlib/_deprecation.py +73 -0
- pvlib/atmosphere.py +79 -0
- pvlib/clearsky.py +35 -22
- pvlib/data/pvgis_tmy_test.csv +8761 -0
- pvlib/data/tmy_45.000_8.000_2005_2023.csv +8789 -0
- pvlib/data/tmy_45.000_8.000_2005_2023.epw +8768 -0
- pvlib/data/tmy_45.000_8.000_2005_2023.json +1 -0
- pvlib/data/tmy_45.000_8.000_2005_2023.txt +8761 -0
- pvlib/data/tmy_45.000_8.000_userhorizon.json +1 -1
- pvlib/iam.py +4 -4
- pvlib/iotools/midc.py +1 -1
- pvlib/iotools/pvgis.py +0 -10
- pvlib/irradiance.py +98 -55
- pvlib/ivtools/sdm.py +75 -52
- pvlib/pvsystem.py +132 -84
- pvlib/solarposition.py +46 -30
- pvlib/spa.py +4 -2
- pvlib/spectrum/irradiance.py +2 -1
- pvlib/spectrum/spectrl2.py +2 -1
- pvlib/temperature.py +49 -3
- pvlib/tests/iotools/test_pvgis.py +9 -9
- pvlib/tests/ivtools/test_sdm.py +23 -1
- pvlib/tests/test__deprecation.py +97 -0
- pvlib/tests/test_atmosphere.py +147 -0
- pvlib/tests/test_clearsky.py +7 -1
- pvlib/tests/test_conftest.py +0 -44
- pvlib/tests/test_irradiance.py +56 -10
- pvlib/tests/test_pvsystem.py +17 -1
- pvlib/tests/test_solarposition.py +33 -0
- pvlib/tests/test_spa.py +29 -0
- {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/METADATA +11 -10
- {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/RECORD +36 -37
- {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/WHEEL +1 -1
- pvlib/data/aod550_tcwv_20121101_test.nc +0 -0
- pvlib/data/pvgis_tmy_test.dat +0 -8761
- pvlib/data/tmy_45.000_8.000_2005_2020.csv +0 -8789
- pvlib/data/tmy_45.000_8.000_2005_2020.epw +0 -8768
- pvlib/data/tmy_45.000_8.000_2005_2020.json +0 -1
- pvlib/data/tmy_45.000_8.000_2005_2020.txt +0 -8761
- pvlib/data/variables_style_rules.csv +0 -56
- {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/LICENSE +0 -0
- {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/top_level.txt +0 -0
pvlib/_deprecation.py
CHANGED
|
@@ -316,3 +316,76 @@ def deprecated(since, message='', name='', alternative='', pending=False,
|
|
|
316
316
|
return finalize(wrapper, new_doc)
|
|
317
317
|
|
|
318
318
|
return deprecate
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def renamed_kwarg_warning(since, old_param_name, new_param_name, removal=""):
|
|
322
|
+
"""
|
|
323
|
+
Decorator to mark a possible keyword argument as deprecated and replaced
|
|
324
|
+
with other name.
|
|
325
|
+
|
|
326
|
+
Raises a warning when the deprecated argument is used, and replaces the
|
|
327
|
+
call with the new argument name. Does not modify the function signature.
|
|
328
|
+
|
|
329
|
+
.. warning::
|
|
330
|
+
Ensure ``removal`` date with a ``fail_on_pvlib_version`` decorator in
|
|
331
|
+
the test suite.
|
|
332
|
+
|
|
333
|
+
.. note::
|
|
334
|
+
Not compatible with positional-only arguments.
|
|
335
|
+
|
|
336
|
+
.. note::
|
|
337
|
+
Documentation for the function may updated to reflect the new parameter
|
|
338
|
+
name; it is suggested to add a |.. versionchanged::| directive.
|
|
339
|
+
|
|
340
|
+
Parameters
|
|
341
|
+
----------
|
|
342
|
+
since : str
|
|
343
|
+
The release at which this API became deprecated.
|
|
344
|
+
old_param_name : str
|
|
345
|
+
The name of the deprecated parameter.
|
|
346
|
+
new_param_name : str
|
|
347
|
+
The name of the new parameter.
|
|
348
|
+
removal : str, optional
|
|
349
|
+
The expected removal version, in order to compose the Warning message.
|
|
350
|
+
|
|
351
|
+
Examples
|
|
352
|
+
--------
|
|
353
|
+
>>> @renamed_kwarg_warning("1.4.0", "old_name", "new_name", "1.6.0")
|
|
354
|
+
>>> def some_function(new_name=None):
|
|
355
|
+
>>> pass
|
|
356
|
+
>>> some_function(old_name=1)
|
|
357
|
+
Parameter 'old_name' has been renamed since 1.4.0. and
|
|
358
|
+
will be removed in 1.6.0. Please use 'new_name' instead.
|
|
359
|
+
|
|
360
|
+
>>> @renamed_kwarg_warning("1.4.0", "old_name", "new_name")
|
|
361
|
+
>>> def some_function(new_name=None):
|
|
362
|
+
>>> pass
|
|
363
|
+
>>> some_function(old_name=1)
|
|
364
|
+
Parameter 'old_name' has been renamed since 1.4.0. and
|
|
365
|
+
will be removed soon. Please use 'new_name' instead.
|
|
366
|
+
"""
|
|
367
|
+
|
|
368
|
+
def deprecate(func, old=old_param_name, new=new_param_name, since=since):
|
|
369
|
+
def wrapper(*args, **kwargs):
|
|
370
|
+
if old in kwargs:
|
|
371
|
+
if new in kwargs:
|
|
372
|
+
raise ValueError(
|
|
373
|
+
f"{func.__name__} received both '{old}' and '{new}', "
|
|
374
|
+
"which are mutually exclusive since they refer to the "
|
|
375
|
+
f"same parameter. Please remove deprecated '{old}'."
|
|
376
|
+
)
|
|
377
|
+
warnings.warn(
|
|
378
|
+
f"Parameter '{old}' has been renamed since {since}. "
|
|
379
|
+
f"and will be removed "
|
|
380
|
+
+ (f"in {removal}" if removal else "soon")
|
|
381
|
+
+ f". Please use '{new}' instead.",
|
|
382
|
+
_projectWarning,
|
|
383
|
+
stacklevel=2,
|
|
384
|
+
)
|
|
385
|
+
kwargs[new] = kwargs.pop(old)
|
|
386
|
+
return func(*args, **kwargs)
|
|
387
|
+
|
|
388
|
+
wrapper = functools.wraps(func)(wrapper)
|
|
389
|
+
return wrapper
|
|
390
|
+
|
|
391
|
+
return deprecate
|
pvlib/atmosphere.py
CHANGED
|
@@ -337,6 +337,85 @@ def gueymard94_pw(temp_air, relative_humidity):
|
|
|
337
337
|
return pw
|
|
338
338
|
|
|
339
339
|
|
|
340
|
+
def rh_from_tdew(temp_air, temp_dew, coeff=(6.112, 17.62, 243.12)):
|
|
341
|
+
"""
|
|
342
|
+
Calculate relative humidity from dewpoint temperature using the Magnus
|
|
343
|
+
equation.
|
|
344
|
+
|
|
345
|
+
Parameters
|
|
346
|
+
----------
|
|
347
|
+
temp_air : numeric
|
|
348
|
+
Air temperature (dry-bulb temperature). [°C]
|
|
349
|
+
temp_dew : numeric
|
|
350
|
+
Dew-point temperature. [°C]
|
|
351
|
+
coeff : tuple, default (6.112, 17.62, 243.12)
|
|
352
|
+
Magnus equation coefficients (A, B, C). The default values are those
|
|
353
|
+
recommended by the WMO [1]_.
|
|
354
|
+
|
|
355
|
+
Returns
|
|
356
|
+
-------
|
|
357
|
+
numeric
|
|
358
|
+
Relative humidity (0.0-100.0). [%]
|
|
359
|
+
|
|
360
|
+
References
|
|
361
|
+
----------
|
|
362
|
+
.. [1] "Guide to Instruments and Methods of Observation",
|
|
363
|
+
World Meteorological Organization, WMO-No. 8, 2023.
|
|
364
|
+
https://library.wmo.int/idurl/4/68695
|
|
365
|
+
"""
|
|
366
|
+
|
|
367
|
+
# Calculate vapor pressure (e) and saturation vapor pressure (es)
|
|
368
|
+
e = coeff[0] * np.exp((coeff[1] * temp_air) / (coeff[2] + temp_air))
|
|
369
|
+
es = coeff[0] * np.exp((coeff[1] * temp_dew) / (coeff[2] + temp_dew))
|
|
370
|
+
|
|
371
|
+
# Calculate relative humidity as percentage
|
|
372
|
+
relative_humidity = 100 * (es / e)
|
|
373
|
+
|
|
374
|
+
return relative_humidity
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def tdew_from_rh(temp_air, relative_humidity, coeff=(6.112, 17.62, 243.12)):
|
|
378
|
+
"""
|
|
379
|
+
Calculate dewpoint temperature using the Magnus equation.
|
|
380
|
+
This is a reversal of the calculation in :py:func:`rh_from_tdew`.
|
|
381
|
+
|
|
382
|
+
Parameters
|
|
383
|
+
----------
|
|
384
|
+
temp_air : numeric
|
|
385
|
+
Air temperature (dry-bulb temperature). [°C]
|
|
386
|
+
relative_humidity : numeric
|
|
387
|
+
Relative humidity (0-100). [%]
|
|
388
|
+
coeff: tuple, default (6.112, 17.62, 243.12)
|
|
389
|
+
Magnus equation coefficients (A, B, C). The default values are those
|
|
390
|
+
recommended by the WMO [1]_.
|
|
391
|
+
|
|
392
|
+
Returns
|
|
393
|
+
-------
|
|
394
|
+
numeric
|
|
395
|
+
Dewpoint temperature. [°C]
|
|
396
|
+
|
|
397
|
+
References
|
|
398
|
+
----------
|
|
399
|
+
.. [1] "Guide to Instruments and Methods of Observation",
|
|
400
|
+
World Meteorological Organization, WMO-No. 8, 2023.
|
|
401
|
+
https://library.wmo.int/idurl/4/68695
|
|
402
|
+
"""
|
|
403
|
+
# Calculate the term inside the log
|
|
404
|
+
# From RH = 100 * (es/e), we get es = (RH/100) * e
|
|
405
|
+
# Substituting the Magnus equation and solving for dewpoint
|
|
406
|
+
|
|
407
|
+
# First calculate ln(es/A)
|
|
408
|
+
ln_term = (
|
|
409
|
+
(coeff[1] * temp_air) / (coeff[2] + temp_air)
|
|
410
|
+
+ np.log(relative_humidity/100)
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
# Then solve for dewpoint
|
|
414
|
+
dewpoint = coeff[2] * ln_term / (coeff[1] - ln_term)
|
|
415
|
+
|
|
416
|
+
return dewpoint
|
|
417
|
+
|
|
418
|
+
|
|
340
419
|
first_solar_spectral_correction = deprecated(
|
|
341
420
|
since='0.10.0',
|
|
342
421
|
alternative='pvlib.spectrum.spectral_factor_firstsolar'
|
pvlib/clearsky.py
CHANGED
|
@@ -327,13 +327,13 @@ def haurwitz(apparent_zenith):
|
|
|
327
327
|
'''
|
|
328
328
|
|
|
329
329
|
cos_zenith = tools.cosd(apparent_zenith.values)
|
|
330
|
-
|
|
330
|
+
ghi_clear = np.zeros_like(apparent_zenith.values)
|
|
331
331
|
cos_zen_gte_0 = cos_zenith > 0
|
|
332
|
-
|
|
333
|
-
|
|
332
|
+
ghi_clear[cos_zen_gte_0] = (1098.0 * cos_zenith[cos_zen_gte_0] *
|
|
333
|
+
np.exp(-0.059/cos_zenith[cos_zen_gte_0]))
|
|
334
334
|
|
|
335
335
|
df_out = pd.DataFrame(index=apparent_zenith.index,
|
|
336
|
-
data=
|
|
336
|
+
data=ghi_clear,
|
|
337
337
|
columns=['ghi'])
|
|
338
338
|
|
|
339
339
|
return df_out
|
|
@@ -683,22 +683,26 @@ def detect_clearsky(measured, clearsky, times=None, infer_limits=False,
|
|
|
683
683
|
var_diff=0.005, slope_dev=8, max_iterations=20,
|
|
684
684
|
return_components=False):
|
|
685
685
|
"""
|
|
686
|
-
Detects clear sky times
|
|
687
|
-
and Hansen
|
|
688
|
-
validated for analyzing GHI time series only. Users may attempt to
|
|
689
|
-
apply it to other types of time series data using different filter
|
|
690
|
-
settings, but should be skeptical of the results.
|
|
686
|
+
Detects clear sky times using the algorithm developed by Reno
|
|
687
|
+
and Hansen.
|
|
691
688
|
|
|
692
|
-
The algorithm
|
|
689
|
+
The algorithm [1]_ was designed and
|
|
690
|
+
validated for analyzing GHI time series. Jordan and Hansen [2]_ extended
|
|
691
|
+
the algorithm to plane-of-array (POA) irradiance measurements.
|
|
692
|
+
|
|
693
|
+
The algorithm [1]_ detects clear sky times by comparing statistics for a
|
|
693
694
|
measured time series and an expected clearsky time series.
|
|
694
695
|
Statistics are calculated using a sliding time window (e.g., 10
|
|
695
696
|
minutes). An iterative algorithm identifies clear periods, uses the
|
|
696
697
|
identified periods to estimate bias in the clearsky data, scales the
|
|
697
698
|
clearsky data and repeats.
|
|
698
699
|
|
|
699
|
-
Clear times are identified by meeting
|
|
700
|
+
Clear times are identified by meeting five criteria. Default values for
|
|
700
701
|
these thresholds are appropriate for 10 minute windows of 1 minute
|
|
701
|
-
GHI data.
|
|
702
|
+
GHI data. For data at longer intervals, it is recommended
|
|
703
|
+
to set ``infer_limits=True`` to use the thresholds from [2]_.
|
|
704
|
+
|
|
705
|
+
For POA data, ``clearsky`` must be on the same plane as ``measured``.
|
|
702
706
|
|
|
703
707
|
Parameters
|
|
704
708
|
----------
|
|
@@ -713,8 +717,8 @@ def detect_clearsky(measured, clearsky, times=None, infer_limits=False,
|
|
|
713
717
|
If True, does not use passed in kwargs (or defaults), but instead
|
|
714
718
|
interpolates these values from Table 1 in [2]_.
|
|
715
719
|
window_length : int, default 10
|
|
716
|
-
Length of sliding time window in minutes.
|
|
717
|
-
|
|
720
|
+
Length of sliding time window in minutes. Each window must contain at
|
|
721
|
+
least three data points.
|
|
718
722
|
mean_diff : float, default 75
|
|
719
723
|
Threshold value for agreement between mean values of measured
|
|
720
724
|
and clearsky in each interval, see Eq. 6 in [1]. [W/m2]
|
|
@@ -723,8 +727,6 @@ def detect_clearsky(measured, clearsky, times=None, infer_limits=False,
|
|
|
723
727
|
clearsky values in each interval, see Eq. 7 in [1]. [W/m2]
|
|
724
728
|
lower_line_length : float, default -5
|
|
725
729
|
Lower limit of line length criterion from Eq. 8 in [1].
|
|
726
|
-
Criterion satisfied when lower_line_length < line length difference
|
|
727
|
-
< upper_line_length.
|
|
728
730
|
upper_line_length : float, default 10
|
|
729
731
|
Upper limit of line length criterion from Eq. 8 in [1].
|
|
730
732
|
var_diff : float, default 0.005
|
|
@@ -736,7 +738,7 @@ def detect_clearsky(measured, clearsky, times=None, infer_limits=False,
|
|
|
736
738
|
change in successive values, see Eqs. 12 through 14 in [1].
|
|
737
739
|
max_iterations : int, default 20
|
|
738
740
|
Maximum number of times to apply a different scaling factor to
|
|
739
|
-
the clearsky and redetermine clear_samples
|
|
741
|
+
the clearsky and redetermine ``clear_samples``. Must be 1 or larger.
|
|
740
742
|
return_components : bool, default False
|
|
741
743
|
Controls if additional output should be returned. See below.
|
|
742
744
|
|
|
@@ -748,19 +750,23 @@ def detect_clearsky(measured, clearsky, times=None, infer_limits=False,
|
|
|
748
750
|
|
|
749
751
|
components : OrderedDict, optional
|
|
750
752
|
Dict of arrays of whether or not the given time window is clear
|
|
751
|
-
for each condition. Only provided if return_components is True.
|
|
753
|
+
for each condition. Only provided if ``return_components`` is True.
|
|
752
754
|
|
|
753
755
|
alpha : scalar, optional
|
|
754
|
-
Scaling factor applied to
|
|
755
|
-
detected clear_samples
|
|
756
|
+
Scaling factor applied to ``clearsky`` to obtain the
|
|
757
|
+
detected ``clear_samples``. Only provided if ``return_components`` is
|
|
756
758
|
True.
|
|
757
759
|
|
|
758
760
|
Raises
|
|
759
761
|
------
|
|
760
762
|
ValueError
|
|
761
|
-
If measured is not a Series and times is not provided
|
|
763
|
+
If ``measured`` is not a Series and times is not provided.
|
|
764
|
+
ValueError
|
|
765
|
+
If a window contains less than three data points.
|
|
766
|
+
ValueError
|
|
767
|
+
If the measured data is not sufficient to fill a window.
|
|
762
768
|
NotImplementedError
|
|
763
|
-
If timestamps are not equally spaced
|
|
769
|
+
If timestamps are not equally spaced.
|
|
764
770
|
|
|
765
771
|
References
|
|
766
772
|
----------
|
|
@@ -812,6 +818,13 @@ def detect_clearsky(measured, clearsky, times=None, infer_limits=False,
|
|
|
812
818
|
sample_interval, samples_per_window = \
|
|
813
819
|
tools._get_sample_intervals(times, window_length)
|
|
814
820
|
|
|
821
|
+
if samples_per_window < 3:
|
|
822
|
+
raise ValueError(f"Samples per window of {samples_per_window}"
|
|
823
|
+
" found. Each window must contain at least 3 data"
|
|
824
|
+
" points."
|
|
825
|
+
f" Window length of {window_length} found; increase"
|
|
826
|
+
f" window length to {3*sample_interval} or longer.")
|
|
827
|
+
|
|
815
828
|
# if infer_limits, find threshold values using the sample interval
|
|
816
829
|
if infer_limits:
|
|
817
830
|
window_length, mean_diff, max_diff, lower_line_length, \
|