Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
7c312ad
add keyword 'label' to degradation_timeseries_plot, enabling 'left' a…
cdeline May 28, 2025
d6a898e
Update changelog, add pytests, update sphinx documentation
cdeline May 28, 2025
df2effc
fix flake8 grumbles
cdeline May 28, 2025
3099497
update pytests to include axes limits
cdeline Jun 18, 2025
1d140e6
fix flake8 grumbles
cdeline Jun 18, 2025
0548eab
add 'label' input option to `degradation_year_on_year`. Fixes #459
cdeline Jun 22, 2025
9af5635
add pytests and update changelog.
cdeline Jun 22, 2025
89ccbab
flake8 grumbles
cdeline Jun 22, 2025
b32211f
Minor updates to setup.py (constrain scipy<1.16) and refactor degrada…
cdeline Jun 23, 2025
8ad5dac
Custom fix for Pandas < 2.0.0 which can't average two columns of time…
cdeline Jun 23, 2025
cf5ff77
flake8 grumbles
cdeline Jun 23, 2025
d59b5c7
Merge branch 'master' into 459_YoY_label
mdeceglie Jun 24, 2025
4955fd8
Merge branch 'master' into 459_YoY_label
cdeline Jun 25, 2025
233da68
Merge branch '459_YoY_label' of https://github.com/cdeline/rdtools in…
cdeline Jun 25, 2025
125a5ff
Merge remote-tracking branch 'remotes/origin/master' into 455_degrada…
cdeline Jun 25, 2025
1ff743e
keep TZ-aware timestamps. Update pytests to specifically test _avg_t…
cdeline Jun 25, 2025
bc86af6
flake8 grumbles
cdeline Jun 25, 2025
ae080fd
try to UTC localize the pytest...
cdeline Jun 25, 2025
e448560
Add .asfreq() to get pytests to agree
cdeline Jun 25, 2025
fd62ea5
switch to calendar.timegm to hopefully remove TZ issues..
cdeline Jun 25, 2025
93f5a14
Merge branch '459_YoY_label' into integration_temp
cdeline Aug 4, 2025
dc83d52
regardless of uncertainty_method, return calc_info{'YoY_values')
cdeline Aug 4, 2025
c220fad
update _right dt labels to correct _left labels in degradation_year_o…
cdeline Aug 5, 2025
e8b6c9c
Merge branch '459_YoY_label' into 394_multi_YoY
cdeline Aug 5, 2025
0464c25
update _avg_timestamp_old_Pandas to allow for numeric index instead o…
cdeline Aug 6, 2025
644f4a8
add left label option to degradation_year_on_year
cdeline Aug 6, 2025
0957ade
update degradation_year_on_year, index set to either left, center or …
cdeline Aug 6, 2025
c624a8c
update return for default = none uncertainty option
cdeline Aug 6, 2025
3623edf
degradation_year_on_year - go back to single return when uncertainty_…
cdeline Aug 8, 2025
00b5ce8
Merge branch '459_YoY_label' into 394_multi_YoY
cdeline Aug 15, 2025
49aa300
add multi-year aggregation of slopes in degradation_year_on_year
cdeline Aug 15, 2025
8cc7562
add multi_yoy kwarg in degradation_year_on_year to toggle the multi-Y…
cdeline Aug 15, 2025
8a5c935
update plotting for detailed=True, allow usage_of_points > 2
cdeline Aug 18, 2025
378221a
Merge branch '459_YoY_label' into 394_multi_YoY
cdeline Aug 18, 2025
15babe2
flake8 grumbles
cdeline Aug 18, 2025
d6670b9
update plotting detailed=True for (even) and (odd) number of points …
cdeline Aug 18, 2025
0b31d1e
Merge branch '459_YoY_label' into 394_multi_YoY
cdeline Aug 18, 2025
13ac2c3
To allow multi_yoy=True in plotting.degradation_timeseries_plot, resa…
cdeline Aug 20, 2025
84c3127
Merge remote-tracking branch 'remotes/origin/master' into 459_YoY_label
cdeline Aug 26, 2025
4017424
Merge branch '459_YoY_label' into 394_multi_YoY
cdeline Aug 26, 2025
0f53385
Merge branch 'master' into 455_degradation_timeseries
cdeline Aug 26, 2025
d1df3e3
Merge branch '455_degradation_timeseries' into integration_temp
cdeline Aug 26, 2025
6708990
Merge branch '394_multi_YoY' into integration_temp
cdeline Aug 26, 2025
5d76c7e
flake8 grumbles
cdeline Aug 26, 2025
de2ceee
Add warning to degradation_timeseries_plot when multi_YoY=True
cdeline Sep 16, 2025
4566413
update to warning message in plotting.degradation_timeseries_plot
cdeline Sep 16, 2025
a317926
fix flake8 grumbles
cdeline Sep 16, 2025
1646f16
nbval fixes from qnguyen345-bare_except_error
cdeline Sep 16, 2025
963527b
Add pandas 3.0 futurewarning handling
cdeline Sep 18, 2025
7435734
Try again to solve pandas3.0 futurewarning
cdeline Sep 18, 2025
3810fd5
attempt 3 to fix nbval
cdeline Sep 18, 2025
fecbd2e
Add infer_objects to remove futurewarning
cdeline Sep 19, 2025
9b8b893
Merge branch '459_YoY_label' into 394_multi_YoY
cdeline Sep 19, 2025
4adc42e
minor inline comment update
cdeline Sep 19, 2025
8451499
update plotting tests to be relative value, update ordering of module…
cdeline Sep 19, 2025
67795f4
update inline comments and whatsnew docs
cdeline Sep 19, 2025
a0f4a1e
Clean up inline comments per Copilot review
cdeline Sep 19, 2025
4393644
added multi-YoY pytest - still need to catch warnings
cdeline Sep 19, 2025
728bb05
Add a warnings.catch_warnings to the plotting pytest
cdeline Sep 22, 2025
3898940
flake8 grumbles
cdeline Sep 22, 2025
e28b1cf
add multi-YoY=True pytest
cdeline Sep 22, 2025
49dd740
updated changelog
cdeline Sep 22, 2025
fd16332
Merge branch '459_YoY_label' into multi_YoY_integration
cdeline Dec 9, 2025
1bb9804
Merge branch '455_degradation_timeseries' into multi_YoY_integration
cdeline Dec 9, 2025
3817162
Merge remote-tracking branch 'origin/development' into multi_YoY_inte…
martin-springer Feb 11, 2026
99a8b02
Merge remote-tracking branch 'origin/development' into multi_YoY_inte…
martin-springer Feb 12, 2026
aec14b7
update changelog
martin-springer Feb 12, 2026
aa6a7ff
implement copilot suggestions
martin-springer Feb 12, 2026
cd591c5
linting
martin-springer Feb 12, 2026
6c5c624
use s instead of ns for pandas 3 compatibility
martin-springer Feb 12, 2026
26e5893
update pandas version comparison
martin-springer Feb 12, 2026
dc2d092
set matplotlib non-gui backend for tests
martin-springer Feb 12, 2026
640e03f
set dtype resolution based on pandas version
martin-springer Feb 12, 2026
27d578f
linting import order
martin-springer Feb 12, 2026
4e6a4b6
boost degradation.py test coverage
martin-springer Feb 12, 2026
09bc1fd
update changelog
martin-springer Feb 12, 2026
5280aaa
exclude coverage reports with suffixes
martin-springer Feb 12, 2026
77d045c
Update rdtools/degradation.py
martin-springer Feb 12, 2026
0fe8ebd
remove label=None handling, rely on default 'right' behavior
martin-springer Feb 12, 2026
c545a5c
refactor dt_center tz handling for old pandas
martin-springer Feb 12, 2026
b1953eb
Merge branch 'multi_YoY_integration' of https://github.com/NREL/rdtoo…
martin-springer Feb 12, 2026
81b9b56
simplify _avg_timestamp_old_Pandas
martin-springer Feb 12, 2026
0d73d2e
degradation_timeseries_plot: change rolling median min_periods to rol…
cdeline Feb 16, 2026
3bd8c8d
remove degradation_timeseries_plot(label=) and just default to center…
cdeline Feb 17, 2026
c55c207
update sensor_analysis() and clearsky_analysis() docstrings to discus…
cdeline Feb 17, 2026
fb0da2b
flake8 updates
cdeline Feb 17, 2026
e531678
Initial commit - multi-YoY notebook
cdeline Feb 17, 2026
098da41
pretty-print notebook dataframes with tabulate.
cdeline Feb 17, 2026
6880c05
update notebook requirements to silence pandas warnings
martin-springer Feb 19, 2026
4c14f79
add multi-yoy nb to tutorials
martin-springer Feb 19, 2026
27fccf6
fix nblink path
martin-springer Feb 19, 2026
f6575eb
Change the yoy_values index to be named 'dt'. Add new illustrations …
cdeline Feb 19, 2026
1ac4915
Merge branch 'multi_YoY_integration' of https://github.com/NREL/rdtoo…
cdeline Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/nbval.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ jobs:
pip install --timeout=300 -r requirements.txt -r docs/notebook_requirements.txt .[test]
- name: Run notebook and check output
run: |
# --sanitize-with: pre-process text to remove irrelevant differences (e.g. warning filepaths)
pytest --nbval docs/${{ matrix.notebook-file }} --sanitize-with docs/nbval_sanitization_rules.cfg
# --nbval-sanitize-with: pre-process text to remove irrelevant differences (e.g. warning filepaths)
pytest --nbval --nbval-sanitize-with docs/nbval_sanitization_rules.cfg docs/${{ matrix.notebook-file }}
- name: Run notebooks again, save files
run: |
pip install nbconvert[webpdf]
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
# ignore byte compiled files
*.py[co]

# ignore coveralls yaml, coverge dir
# ignore coveralls yaml, coverage dir
.coveralls.yml
.coverage
.coverage.*
htmlcov/

# ignore test cache
Expand Down
479 changes: 479 additions & 0 deletions docs/Multi-year_on_year_example.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/TrendAnalysis_example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -62377,7 +62377,7 @@
"# Visualize the results\n",
"ta_new_filter.plot_degradation_summary('sensor', summary_title='Sensor-based degradation results',\n",
" scatter_ymin=0.5, scatter_ymax=1.1,\n",
" hist_xmin=-30, hist_xmax=45);\n",
" hist_xmin=-30, hist_xmax=45)\n",
"plt.show()"
]
},
Expand Down Expand Up @@ -62492,7 +62492,7 @@
"# Visualize the results\n",
"ta_stuck_filter.plot_degradation_summary('sensor', summary_title='Sensor-based degradation results',\n",
" scatter_ymin=0.5, scatter_ymax=1.1,\n",
" hist_xmin=-30, hist_xmax=45);\n",
" hist_xmin=-30, hist_xmax=45)\n",
"plt.show()"
]
},
Expand Down
2 changes: 1 addition & 1 deletion docs/TrendAnalysis_example_NSRDB.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
"ax.plot(df.index, df.soiling, 'o', alpha=0.01)\n",
"#ax.set_ylim(0,1500)\n",
"fig.autofmt_xdate()\n",
"ax.set_ylabel('soiling signal');\n",
"ax.set_ylabel('soiling signal')\n",
"df['power'] = df['power_ac'] * df['soiling']\n",
"\n",
"plt.show()"
Expand Down
4 changes: 3 additions & 1 deletion docs/notebook_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ nbconvert==7.17.0
nbformat==5.10.4
nest-asyncio==1.6.0
notebook==7.2.2
numexpr==2.10.1
numexpr==2.10.2
pandocfilters==1.5.1
parso==0.8.4
pexpect==4.9.0
Expand All @@ -45,6 +45,7 @@ qtconsole==5.5.2
Send2Trash==1.8.3
simplegeneric==0.8.1
soupsieve==2.6
tabulate==0.9.0
terminado==0.18.1
testpath==0.6.0
tinycss2==1.2.1
Expand All @@ -53,3 +54,4 @@ traitlets==5.14.3
wcwidth==0.2.13
webencodings==0.5.1
widgetsnbextension==4.0.11

1 change: 1 addition & 0 deletions docs/sphinx/source/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
RdTools Change Log
==================
.. include:: changelog/pending.rst
.. include:: changelog/v3.1.0.rst
.. include:: changelog/v3.0.1.rst
.. include:: changelog/v3.0.0.rst
Expand Down
61 changes: 61 additions & 0 deletions docs/sphinx/source/changelog/pending.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
*************************
v3.2.0 (X, X, 2026)
*************************

Enhancements
------------
* :py:func:`~rdtools.degradation.degradation_year_on_year` has new parameter ``label=``
to return the calc_info['YoY_values'] as either right labeled (default), left or
center labeled. (:issue:`459`)
* :py:func:`~rdtools.plotting.degradation_timeseries_plot` now defaults to rolling
median, centered on the timestamp (pd.rolling(center=True)).
(:issue:`455`)
* :py:func:`~rdtools.degradation.degradation_year_on_year` has new parameter ``multi_yoy``
(default False) to trigger multiple YoY degradation calculations similar to Hugo Quest et
al 2023. In this mode, instead of a series of 1-year duration slopes, 2-year, 3-year etc
slopes are also included. calc_info['YoY_values'] returns a non-monotonic index
in this mode due to multiple overlapping annual slopes. (:issue:`394`)
* :py:func:`~rdtools.plotting.degradation_timeseries_plot` now supports ``multi_yoy=True``
data by resampling overlapping YoY values to their mean. A warning is issued when this
resampling occurs. (:issue:`394`)
* :py:func:`~rdtools.plotting.degradation_summary_plots` ``detailed=True`` mode now
properly handles points used odd vs even number of times (not just 0, 1, 2).
(:issue:`394`)
* :py:func:`~rdtools.degradation.degradation_year_on_year` now returns
``calc_info['YoY_times']`` DataFrame with ``dt_right``, ``dt_center``, and ``dt_left``
columns for each YoY slope. (:issue:`459`)
* Added new example notebook ``docs/Multi-year_on_year_example.ipynb`` demonstrating the
``label='center'`` and ``multi_yoy=True`` features of
:py:func:`~rdtools.degradation.degradation_year_on_year`. (:issue:`394`)

Bug Fixes
---------
* Fixed ``usage_of_points`` calculation in :py:func:`~rdtools.degradation.degradation_year_on_year`
to properly handle ``multi_yoy=True`` mode with overlapping slopes. (:issue:`394`)


Maintenance
-----------
* Added ``_avg_timestamp_old_Pandas`` helper function for pandas <2.0 compatibility
when calculating center labels.
* Fixed nbval workflow command syntax (``--sanitize-with`` to ``--nbval-sanitize-with``).
* Improved pandas 3.0 compatibility with datetime resolution handling.
* Updated ``docs/notebook_requirements.txt`` to require ``numexpr>=2.10.2`` and
``tabulate>=0.9.0`` to satisfy pandas' optional dependency minimum versions and
avoid related warnings/errors.

Testing
-------
* Added tests for error handling paths in :py:mod:`~rdtools.degradation`:
``classical_decomposition`` missing/irregular data, ``year_on_year`` circular block
validation, no valid pairs error, and ``_mk_test`` edge cases (no trend, ties,
decreasing).
* Added test for ``multi_yoy=True`` parameter in ``degradation_year_on_year``.
* Set matplotlib backend to ``Agg`` in test ``conftest.py`` to avoid tkinter issues.


Contributors
------------
* Chris Deline (:ghuser:`cdeline`)
* Martin Springer (:ghuser:`martin-springer`)

1 change: 1 addition & 0 deletions docs/sphinx/source/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ This page shows example usage of the RdTools analysis functions.
examples/TrendAnalysis_example
examples/TrendAnalysis_example_NSRDB
examples/system_availability_example
examples/Multi-year_on_year_example
3 changes: 3 additions & 0 deletions docs/sphinx/source/examples/Multi-year_on_year_example.nblink
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"path": "../../../Multi-year_on_year_example.ipynb"
}
8 changes: 5 additions & 3 deletions rdtools/analysis_chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ def _clearsky_preprocess(self):
)

def sensor_analysis(
self, analyses=["yoy_degradation"], yoy_kwargs={}, srr_kwargs={}
self, analyses=["yoy_degradation"], yoy_kwargs={"label": "right"}, srr_kwargs={}
):
"""
Perform entire sensor-based analysis workflow.
Expand All @@ -1014,6 +1014,7 @@ def sensor_analysis(
and 'srr_soiling'
yoy_kwargs : dict
kwargs to pass to :py:func:`rdtools.degradation.degradation_year_on_year`
default is {"label": "right"}, which will right-label the YoY slope values.
srr_kwargs : dict
kwargs to pass to :py:func:`rdtools.soiling.soiling_srr`

Expand Down Expand Up @@ -1041,7 +1042,7 @@ def sensor_analysis(
self.results["sensor"] = sensor_results

def clearsky_analysis(
self, analyses=["yoy_degradation"], yoy_kwargs={}, srr_kwargs={}
self, analyses=["yoy_degradation"], yoy_kwargs={"label": "right"}, srr_kwargs={}
):
"""
Perform entire clear-sky-based analysis workflow. Results are stored
Expand All @@ -1053,7 +1054,8 @@ def clearsky_analysis(
Analyses to perform as a list of strings. Valid entries are 'yoy_degradation'
and 'srr_soiling'
yoy_kwargs : dict
kwargs to pass to :py:func:`rdtools.degradation.degradation_year_on_year`
kwargs to pass to :py:func:`rdtools.degradation.degradation_year_on_year`.
default is {"label": "right"}, which will right-label the YoY slope values.
srr_kwargs : dict
kwargs to pass to :py:func:`rdtools.soiling.soiling_srr`

Expand Down
Loading