rdtools 2.2.0b1__tar.gz → 2.2.0b2__tar.gz
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.
- {rdtools-2.2.0b1/rdtools.egg-info → rdtools-2.2.0b2}/PKG-INFO +1 -1
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/_version.py +3 -3
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/clearsky_temperature.py +3 -1
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/degradation.py +8 -18
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/filtering.py +4 -4
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/normalization.py +2 -3
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/soiling.py +7 -6
- {rdtools-2.2.0b1 → rdtools-2.2.0b2/rdtools.egg-info}/PKG-INFO +1 -1
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools.egg-info/requires.txt +6 -6
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/setup.py +8 -6
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/LICENSE +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/MANIFEST.in +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/README.md +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/__init__.py +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/_deprecation.py +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/aggregation.py +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/analysis_chains.py +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/availability.py +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/bootstrap.py +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/data/temperature.hdf5 +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/models/xgboost_clipping_model.json +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools/plotting.py +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools.egg-info/SOURCES.txt +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools.egg-info/dependency_links.txt +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools.egg-info/not-zip-safe +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/rdtools.egg-info/top_level.txt +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/setup.cfg +0 -0
- {rdtools-2.2.0b1 → rdtools-2.2.0b2}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "
|
|
11
|
+
"date": "2023-12-01T15:24:38-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.2.0-beta.
|
|
14
|
+
"full-revisionid": "250e412bda8199491d8dc45673752374913b9c65",
|
|
15
|
+
"version": "2.2.0-beta.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -57,7 +57,9 @@ def get_clearsky_tamb(times, latitude, longitude, window_size=40,
|
|
|
57
57
|
freq_actual = times.freq
|
|
58
58
|
|
|
59
59
|
dt_daily = pd.date_range(times.date[0] - buffer, times.date[-1] + buffer,
|
|
60
|
-
freq='D'
|
|
60
|
+
freq='D')
|
|
61
|
+
dt_daily = dt_daily.tz_localize(times.tz, ambiguous='infer',
|
|
62
|
+
nonexistent='shift_forward')
|
|
61
63
|
|
|
62
64
|
f = h5py.File(filepath, "r")
|
|
63
65
|
|
|
@@ -38,7 +38,7 @@ def degradation_ols(energy_normalized, confidence_level=68.2):
|
|
|
38
38
|
|
|
39
39
|
# calculate a years column as x value for regression, ignoring leap years
|
|
40
40
|
day_diffs = (df.index - df.index[0])
|
|
41
|
-
df['days'] = day_diffs.
|
|
41
|
+
df['days'] = day_diffs / pd.Timedelta('1d')
|
|
42
42
|
df['years'] = df.days / 365.0
|
|
43
43
|
|
|
44
44
|
# add intercept-constant to the exogeneous variable
|
|
@@ -123,22 +123,14 @@ def degradation_classical_decomposition(energy_normalized,
|
|
|
123
123
|
|
|
124
124
|
# calculate a years column as x value for regression, ignoring leap years
|
|
125
125
|
day_diffs = (df.index - df.index[0])
|
|
126
|
-
df['days'] = day_diffs.
|
|
126
|
+
df['days'] = day_diffs / pd.Timedelta('1d')
|
|
127
127
|
df['years'] = df.days / 365.0
|
|
128
128
|
|
|
129
129
|
# Compute yearly rolling mean to isolate trend component using
|
|
130
130
|
# moving average
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if row.years - 0.5 >= min(df.years) and \
|
|
135
|
-
row.years + 0.5 <= max(df.years):
|
|
136
|
-
roll = df[(df.years <= row.years + 0.5) &
|
|
137
|
-
(df.years >= row.years - 0.5)]
|
|
138
|
-
energy_ma.append(roll.energy_normalized.mean())
|
|
139
|
-
else:
|
|
140
|
-
energy_ma.append(np.nan)
|
|
141
|
-
|
|
131
|
+
energy_ma = df['energy_normalized'].rolling('365d', center=True).mean()
|
|
132
|
+
has_full_year = (df['years'] >= df['years'][0] + 0.5) & (df['years'] <= df['years'][-1] - 0.5)
|
|
133
|
+
energy_ma[~has_full_year] = np.nan
|
|
142
134
|
df['energy_ma'] = energy_ma
|
|
143
135
|
|
|
144
136
|
# add intercept-constant to the exogeneous variable
|
|
@@ -290,7 +282,7 @@ def degradation_year_on_year(energy_normalized, recenter=True,
|
|
|
290
282
|
tolerance=pd.Timedelta('8D')
|
|
291
283
|
)
|
|
292
284
|
|
|
293
|
-
df['time_diff_years'] = (df.dt - df.dt_right).
|
|
285
|
+
df['time_diff_years'] = (df.dt - df.dt_right) / pd.Timedelta('365d')
|
|
294
286
|
df['yoy'] = 100.0 * (df.energy - df.energy_right) / (df.time_diff_years)
|
|
295
287
|
df.index = df.dt
|
|
296
288
|
|
|
@@ -395,10 +387,8 @@ def _mk_test(x, alpha=0.05):
|
|
|
395
387
|
n = len(x)
|
|
396
388
|
|
|
397
389
|
# calculate S
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
for j in range(k + 1, n):
|
|
401
|
-
s += np.sign(x[j] - x[k])
|
|
390
|
+
x = np.array(x)
|
|
391
|
+
s = np.sum(np.triu(np.sign(-np.subtract.outer(x, x)), 1))
|
|
402
392
|
|
|
403
393
|
# calculate the unique data
|
|
404
394
|
unique_x = np.unique(x)
|
|
@@ -424,8 +424,9 @@ def logic_clip_filter(power_ac,
|
|
|
424
424
|
# series sampling frequency is less than 95% consistent.
|
|
425
425
|
_check_data_sampling_frequency(power_ac)
|
|
426
426
|
# Get the sampling frequency of the time series
|
|
427
|
-
time_series_sampling_frequency =
|
|
428
|
-
.
|
|
427
|
+
time_series_sampling_frequency = (
|
|
428
|
+
power_ac.index.to_series().diff() / pd.Timedelta('60s')
|
|
429
|
+
).mode()[0]
|
|
429
430
|
# Make copies of the original inputs for the cases that the data is
|
|
430
431
|
# changes for clipping evaluation
|
|
431
432
|
original_time_series_sampling_frequency = time_series_sampling_frequency
|
|
@@ -651,8 +652,7 @@ def xgboost_clip_filter(power_ac,
|
|
|
651
652
|
# series sampling frequency is less than 95% consistent.
|
|
652
653
|
_check_data_sampling_frequency(power_ac)
|
|
653
654
|
# Get the most common sampling frequency
|
|
654
|
-
sampling_frequency = int(power_ac.index.to_series().diff()
|
|
655
|
-
.astype('timedelta64[m]').mode()[0])
|
|
655
|
+
sampling_frequency = int((power_ac.index.to_series().diff() / pd.Timedelta('60s')).mode()[0])
|
|
656
656
|
freq_string = str(sampling_frequency) + "T"
|
|
657
657
|
# Min-max normalize
|
|
658
658
|
# Resample the series based on the most common sampling frequency
|
|
@@ -380,7 +380,7 @@ def irradiance_rescale(irrad, irrad_sim, max_iterations=100,
|
|
|
380
380
|
'''
|
|
381
381
|
|
|
382
382
|
if method == 'iterative':
|
|
383
|
-
def _rmse(fact):
|
|
383
|
+
def _rmse(fact, filt):
|
|
384
384
|
"""
|
|
385
385
|
Calculates RMSE with a given rescale fact(or) according to global
|
|
386
386
|
filt(er)
|
|
@@ -392,10 +392,9 @@ def irradiance_rescale(irrad, irrad_sim, max_iterations=100,
|
|
|
392
392
|
|
|
393
393
|
def _single_rescale(irrad, irrad_sim, guess):
|
|
394
394
|
"Optimizes rescale factor once"
|
|
395
|
-
global filt
|
|
396
395
|
csi = irrad / (guess * irrad_sim) # clear sky index
|
|
397
396
|
filt = (csi >= 0.8) & (csi <= 1.2) & (irrad > 200)
|
|
398
|
-
min_result = minimize(_rmse, guess, method='Nelder-Mead')
|
|
397
|
+
min_result = minimize(_rmse, guess, (filt), method='Nelder-Mead')
|
|
399
398
|
|
|
400
399
|
factor = min_result['x'][0]
|
|
401
400
|
return factor
|
|
@@ -1762,11 +1762,11 @@ class CODSAnalysis():
|
|
|
1762
1762
|
self.soiling_loss = [0, 0, (1 - result_df.soiling_ratio).mean()]
|
|
1763
1763
|
self.small_soiling_signal = True
|
|
1764
1764
|
self.errors = (
|
|
1765
|
-
'Soiling signal is small relative to the noise.'
|
|
1766
|
-
'Iterative decomposition not possible
|
|
1767
|
-
'Degradation found by RdTools YoY')
|
|
1768
|
-
|
|
1769
|
-
return
|
|
1765
|
+
'Soiling signal is small relative to the noise. '
|
|
1766
|
+
'Iterative decomposition not possible. '
|
|
1767
|
+
'Degradation found by RdTools YoY.')
|
|
1768
|
+
warnings.warn(self.errors)
|
|
1769
|
+
return self.result_df, self.degradation, self.soiling_loss
|
|
1770
1770
|
self.small_soiling_signal = False
|
|
1771
1771
|
|
|
1772
1772
|
# Aggregate all bootstrap samples
|
|
@@ -2507,7 +2507,8 @@ def _make_seasonal_samples(list_of_SCs, sample_nr=10, min_multiplier=0.5,
|
|
|
2507
2507
|
''' Generate seasonal samples by perturbing the amplitude and the phase of
|
|
2508
2508
|
a seasonal components found with the fitted CODS model '''
|
|
2509
2509
|
samples = pd.DataFrame(index=list_of_SCs[0].index,
|
|
2510
|
-
columns=range(int(sample_nr*len(list_of_SCs)))
|
|
2510
|
+
columns=range(int(sample_nr*len(list_of_SCs))),
|
|
2511
|
+
dtype=float)
|
|
2511
2512
|
# From each fitted signal, we will generate new seaonal components
|
|
2512
2513
|
for i, signal in enumerate(list_of_SCs):
|
|
2513
2514
|
# Remove beginning and end of signal
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
matplotlib>=3.0.0
|
|
2
|
-
numpy>=1.
|
|
3
|
-
pandas
|
|
2
|
+
numpy>=1.17.3
|
|
3
|
+
pandas<2.1,>=1.3.0
|
|
4
4
|
statsmodels>=0.11.1
|
|
5
|
-
scipy>=1.
|
|
5
|
+
scipy>=1.2.0
|
|
6
6
|
h5py>=2.8.0
|
|
7
7
|
plotly>=4.0.0
|
|
8
8
|
xgboost>=1.3.3
|
|
9
|
-
pvlib<0.
|
|
9
|
+
pvlib<0.11.0,>=0.7.0
|
|
10
10
|
scikit-learn>=0.22.0
|
|
11
11
|
arch>=4.11
|
|
12
12
|
filterpy>=1.4.2
|
|
@@ -17,7 +17,7 @@ flake8
|
|
|
17
17
|
ipython
|
|
18
18
|
nbsphinx-link==1.3.0
|
|
19
19
|
nbsphinx==0.8.8
|
|
20
|
-
nbval
|
|
20
|
+
nbval==0.9.6
|
|
21
21
|
pytest>=3.6.3
|
|
22
22
|
pytest-mock
|
|
23
23
|
sphinx-gallery==0.8.1
|
|
@@ -36,5 +36,5 @@ sphinx-gallery==0.8.1
|
|
|
36
36
|
pytest>=3.6.3
|
|
37
37
|
coverage
|
|
38
38
|
flake8
|
|
39
|
-
nbval
|
|
39
|
+
nbval==0.9.6
|
|
40
40
|
pytest-mock
|
|
@@ -35,21 +35,23 @@ TESTS_REQUIRE = [
|
|
|
35
35
|
'pytest >= 3.6.3',
|
|
36
36
|
'coverage',
|
|
37
37
|
'flake8',
|
|
38
|
-
'nbval',
|
|
38
|
+
'nbval==0.9.6', # https://github.com/computationalmodelling/nbval/issues/194
|
|
39
39
|
'pytest-mock',
|
|
40
40
|
]
|
|
41
41
|
|
|
42
42
|
INSTALL_REQUIRES = [
|
|
43
43
|
'matplotlib >= 3.0.0',
|
|
44
|
-
'numpy >= 1.
|
|
45
|
-
#
|
|
46
|
-
|
|
44
|
+
'numpy >= 1.17.3',
|
|
45
|
+
# pandas restricted to <2.1 until
|
|
46
|
+
# https://github.com/pandas-dev/pandas/issues/55794
|
|
47
|
+
# is resolved
|
|
48
|
+
'pandas >= 1.3.0, <2.1',
|
|
47
49
|
'statsmodels >= 0.11.1',
|
|
48
|
-
'scipy >= 1.
|
|
50
|
+
'scipy >= 1.2.0',
|
|
49
51
|
'h5py >= 2.8.0',
|
|
50
52
|
'plotly>=4.0.0',
|
|
51
53
|
'xgboost >= 1.3.3',
|
|
52
|
-
'pvlib >= 0.7.0, <0.
|
|
54
|
+
'pvlib >= 0.7.0, <0.11.0',
|
|
53
55
|
'scikit-learn >= 0.22.0',
|
|
54
56
|
'arch >= 4.11',
|
|
55
57
|
'filterpy >= 1.4.2'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|