Differentiating with the LEAN algorithm#
This example shows how to differentiate cycler data using the LEAN algorithm developed in: Feng X, Merla Y, Weng C, Ouyang M, He X, Liaw BY, et al. A reliable approach of differentiating discrete sampled-data for battery diagnosis. eTransportation. 2020;3: 100051. https://doi.org/10.1016/j.etran.2020.100051.
First import the package and dataset:
[1]:
import pyprobe
import numpy as np
info_dictionary = {'Name': 'Sample cell',
'Chemistry': 'NMC622',
'Nominal Capacity [Ah]': 0.04,
'Cycler number': 1,
'Channel number': 1,}
data_directory = '../../../tests/sample_data/neware'
# Create a cell object
cell = pyprobe.Cell(info=info_dictionary)
cell.add_procedure(procedure_name='Sample',
folder_path = data_directory,
filename = 'sample_data_neware.parquet')
The break-in cycles of this dataset are at C/10, so can be analysed as pseudo-OCV curves. We’re going to look at the last cycle:
[2]:
final_cycle= cell.procedure['Sample'].experiment('Break-in Cycles').cycle(-1)
fig = pyprobe.Plot()
fig.add_line(final_cycle, 'Time [hr]', 'Voltage [V]')
fig.show_image()
# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation
2024-12-23 16:54:14,456 - pyprobe.units - ERROR - Name Date does not match pattern.
2024-12-23 16:54:14,457 - pyprobe.units - ERROR - Name Step does not match pattern.
2024-12-23 16:54:14,458 - pyprobe.units - ERROR - Name Event does not match pattern.
2024-12-23 16:54:14,458 - pyprobe.units - ERROR - Name Cycle does not match pattern.
We can use the methods of the differentiation
module to calculate the gradients of the data.
[3]:
from pyprobe.analysis import differentiation
discharge_dQdV = differentiation.differentiate_LEAN(input_data = final_cycle.discharge(0),
x = 'Capacity [Ah]', y='Voltage [V]', k = 10, gradient = 'dxdy')
charge_dQdV = differentiation.differentiate_LEAN(input_data = final_cycle.charge(0).constant_current(),
x = 'Capacity [Ah]', y='Voltage [V]', k = 10, gradient = 'dxdy')
fig = pyprobe.Plot()
fig.add_line(discharge_dQdV, 'Capacity [Ah]', 'd(Capacity [Ah])/d(Voltage [V])', label='Discharge', color='blue')
fig.add_line(charge_dQdV, 'Capacity [Ah]', 'd(Capacity [Ah])/d(Voltage [V])', label='Charge', color='red')
fig.show_image()
# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation
On-the-fly unit conversion allows this to be computed in whichever unit you choose:
[4]:
discharge_dQdV = differentiation.differentiate_LEAN(input_data = final_cycle.discharge(0), x = 'Capacity [mAh]', y='Voltage [V]', k = 10, gradient = 'dxdy')
charge_dQdV = differentiation.differentiate_LEAN(input_data = final_cycle.charge(0).constant_current(), x = 'Capacity [mAh]', y='Voltage [V]', k = 10, gradient = 'dxdy')
fig = pyprobe.Plot()
fig.add_line(discharge_dQdV, 'Capacity [mAh]', 'd(Capacity [mAh])/d(Voltage [V])', label='Discharge', color='blue')
fig.add_line(charge_dQdV, 'Capacity [mAh]', 'd(Capacity [mAh])/d(Voltage [V])', label='Charge', color='red')
fig.show_image()
# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation
2024-12-23 16:54:16,640 - pyprobe.units - ERROR - Name Date does not match pattern.
2024-12-23 16:54:16,641 - pyprobe.units - ERROR - Name Step does not match pattern.
2024-12-23 16:54:16,641 - pyprobe.units - ERROR - Name Event does not match pattern.
2024-12-23 16:54:16,641 - pyprobe.units - ERROR - Name Cycle does not match pattern.
2024-12-23 16:54:16,682 - pyprobe.units - ERROR - Name Date does not match pattern.
2024-12-23 16:54:16,683 - pyprobe.units - ERROR - Name Step does not match pattern.
2024-12-23 16:54:16,683 - pyprobe.units - ERROR - Name Event does not match pattern.
2024-12-23 16:54:16,684 - pyprobe.units - ERROR - Name Cycle does not match pattern.
To align the curves, we can instead plot Cycle Capacity [Ah]
which is set to zero at the beginning of the filtered cycle.
[5]:
discharge_dQdV = differentiation.differentiate_LEAN(input_data = final_cycle.discharge(0), x = 'Cycle Capacity [Ah]', y='Voltage [V]', k = 10, gradient = 'dxdy')
charge_dQdV = differentiation.differentiate_LEAN(input_data = final_cycle.charge(0).constant_current(), x = 'Cycle Capacity [Ah]', y='Voltage [V]', k = 10, gradient = 'dxdy')
fig = pyprobe.Plot()
fig.add_line(discharge_dQdV, 'Cycle Capacity [Ah]', 'd(Cycle Capacity [Ah])/d(Voltage [V])', label='Discharge', color='blue')
fig.add_line(charge_dQdV, 'Cycle Capacity [Ah]', 'd(Cycle Capacity [Ah])/d(Voltage [V])', label='Charge', color='red')
fig.show_image()
# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation