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
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
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