Skip to content
21 changes: 21 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ API Reference
Quality
=======

Energy
-----------

Functions for checking if an energy data stream is cumulative
or not.

.. autosummary::
:toctree: generated/

quality.energy.cumulative_energy_simple_diff_check
quality.energy.cumulative_energy_avg_diff_check

If the energy data stream passes the checks, then
it is converted to non-cumulative energy data stream via simple or
average differencing

.. autosummary::
:toctree: generated/

quality.energy.convert_cumulative_energy

Data Shifts
-----------

Expand Down
4 changes: 4 additions & 0 deletions docs/examples/energy/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Energy
----------------

This includes examples for identifying and correcting cumulative energy time series.
72 changes: 72 additions & 0 deletions docs/examples/energy/cumulative-energy-simple-avg-check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
Cumulative Energy via Average Difference
=======================================

Check and correct energy series for cumulative energy via average differencing.
"""

# %%
# AC energy data streams are often cumulative, meaning they increase
# over time. These energy streams need to be corrected into a form
# that resembles regular, non-cumulative data. This process involves
# applying a percent threshold to the average difference in subsequent values
# to check if the data is always increasing. If it passes,
# that check, then the data stream is cumulative and it can be corrected
# via average differencing.

import pandas as pd
import matplotlib.pyplot as plt
from pvanalytics.quality import energy
import pathlib
import pvanalytics

# %%
# First, read in the ac energy data. This data set contains one week of
# 10-minute ac energy data.

pvanalytics_dir = pathlib.Path(pvanalytics.__file__).parent
energy_file = pvanalytics_dir / 'data' / 'system_10004_ac_energy.csv'
data = pd.read_csv(energy_file)
energy_series = data['ac_energy_inv_16425']

# %%
# Now check if the energy time series is cumulative via average differencing.
# This is done using the
# :py:func:`pvanalytics.quality.energy.cumulative_energy_avg_diff_check`
# function.

is_cumulative = energy.cumulative_energy_avg_diff_check(energy_series)

# %%
# If the energy series is cumulative,, then it can be converted to
# non-cumulative energy series via average differencing.
corrected_energy_series = 0.5 * \
(energy_series.diff().shift(-1) + energy_series.diff())

# %%
# Plot the original, cumulative energy series.

data.plot(x="local_measured_on", y='ac_energy_inv_16425')
plt.title("Cumulative Energy Series")
plt.xticks(rotation=45)
plt.xlabel("Datetime")
plt.ylabel("AC Energy (kWh)")
plt.tight_layout()
plt.show()

# %%
# Plot the corrected, non-cumulative energy series.

corrected_energy_df = pd.DataFrame({
"local_measured_on": data["local_measured_on"],
"corrected_ac_energy_inv_16425": corrected_energy_series})
corrected_energy_df = corrected_energy_df[
corrected_energy_df["corrected_ac_energy_inv_16425"] >= 0]
corrected_energy_df.plot(x="local_measured_on",
y="corrected_ac_energy_inv_16425")
plt.title("Corrected, Non-cumulative Energy Series")
plt.xticks(rotation=45)
plt.xlabel("Datetime")
plt.ylabel("AC Energy (kWh)")
plt.tight_layout()
plt.show()
72 changes: 72 additions & 0 deletions docs/examples/energy/cumulative-energy-simple-diff-check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
Cumulative Energy via Simple Difference
=======================================

Check and correct energy series for cumulative energy with simple differencing.
"""

# %%
# AC energy data streams are often cumulative, meaning they increase
# over time. These energy streams need to be corrected into a form
# that resembles regular, non-cumulative data. This process involves
# applying a percent threshold to the difference in subsequent values
# to check if the data is always increasing. If it passes,
# that check, then the data stream is cumulative and it can be corrected
# via simple differencing.

import pandas as pd
import matplotlib.pyplot as plt
from pvanalytics.quality import energy
import pathlib
import pvanalytics

# %%
# First, read in the ac energy data. This data set contains one week of
# 10-minute ac energy data.

pvanalytics_dir = pathlib.Path(pvanalytics.__file__).parent
energy_file = pvanalytics_dir / 'data' / 'system_10004_ac_energy.csv'
data = pd.read_csv(energy_file)
energy_series = data['ac_energy_inv_16425']

# %%
# Now check if the energy time series is cumulative via simple differencing.
# This is done using the
# :py:func:`pvanalytics.quality.energy.cumulative_energy_simple_diff_check`
# function.

is_cumulative = energy.cumulative_energy_simple_diff_check(energy_series)

# %%
# If the energy series is cumulative, then it can be converted
# to the non-cumulative energy series. This is done using the
# :py:func:`pvanalytics.quality.energy.convert_cumulative_energy` function.
corrected_energy_series = energy.convert_cumulative_energy(energy_series)

# %%
# Plot the original, cumulative energy series.

data.plot(x="local_measured_on", y='ac_energy_inv_16425')
plt.title("Cumulative Energy Series")
plt.xticks(rotation=45)
plt.xlabel("Datetime")
plt.ylabel("AC Energy (kWh)")
plt.tight_layout()
plt.show()

# %%
# Plot the corrected, non-cumulative energy series.

corrected_energy_df = pd.DataFrame({
"local_measured_on": data["local_measured_on"],
"corrected_ac_energy_inv_16425": corrected_energy_series})
corrected_energy_df = corrected_energy_df[
corrected_energy_df["corrected_ac_energy_inv_16425"] >= 0]
corrected_energy_df.plot(x="local_measured_on",
y="corrected_ac_energy_inv_16425")
plt.title("Corrected, Non-cumulative Energy Series")
plt.xticks(rotation=45)
plt.xlabel("Datetime")
plt.ylabel("AC Energy (kWh)")
plt.tight_layout()
plt.show()
16 changes: 14 additions & 2 deletions docs/whatsnew/0.2.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@
Enhancements
~~~~~~~~~~~~
* Compatibility with numpy 2.0. (:pull:`211`)
* Added function :py:func:`~pvanalytics.quality.energy.cumulative_energy_simple_diff_check` to
check if an energy time series is cumulative via simple differencing.
(:issue:`165`, :pull:`212`)
* Added function :py:func:`~pvanalytics.quality.energy.cumulative_energy_avg_diff_check` to
check if an energy time series is cumulative via average differencing.
(:issue:`165`, :pull:`212`)
* Added function :py:func:`~pvanalytics.quality.energy.convert_cumulative_energy` to correct
the cumulative energy to interval-based, non-cumulative energy series, if the energy series
passes the simple difference :py:func:`~pvanalytics.quality.energy.cumulative_energy_simple_diff_check`
or average difference :py:func:`~pvanalytics.quality.energy.cumulative_energy_avg_diff_check`
checks. (:issue:`165`, :pull:`212`)


Bug Fixes
Expand All @@ -20,12 +31,13 @@ Requirements

Documentation
~~~~~~~~~~~~~

* Added examples for checking cumulative energy time series. (:issue:`165`, :pull:`212`)

Testing
~~~~~~~

* Added testing for ``pvanalytics.quality.energy``. (:issue:`165`, :pull:`212`)


Contributors
~~~~~~~~~~~~
* Quyen Nguyen (:ghuser:`qnguyen345`)
Loading
Loading