In [ ]:
%load_ext autoreload
%autoreload 2
In [ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cellpy
from cellpy import log
from cellpy import cellreader
from cellpy import prms
from cellpy import prmreader
from cellpy.utils import batch
#import holoviews as hv
%matplotlib inline
#hv.extension('bokeh')
In [ ]:
log.setup_logging(default_level="DEBUG")
In [ ]:
## Uncomment this and run for checking your cellpy parameters.
# prmreader.info()
In [ ]:
filepath = r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\2019_types.res"
filepath = [
r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\20181126_cen41_02_cc_01.res",
r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\20181126_cen41_02_cc_02.res",
r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\20181126_cen41_02_cc_03.res",
r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\20181126_cen41_02_cc_04.res",
r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\20181126_cen41_02_cc_05.res",
r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\20181126_cen41_02_cc_06.res",
]
filepath2 = filepath[0]
m = 0.374433
outfilepath = r"C:\Scripting\MyFiles\development_cellpy\dev_data\arbin\2019_types.h5"
prms.Paths.rawdatadir = r"C:\ExperimentalData\BatteryTestData\Arbin\RAW"
In [ ]:
cell = cellreader.CellpyData()
cell.from_raw(filepath)
cell2 = cellreader.CellpyData()
cell2.from_raw(filepath2)
In [ ]:
cell.set_mass(m)
cell2.set_mass(m)
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
cell.make_step_table()
cell2.make_step_table()
In [ ]:
cell.make_summary()
cell2.make_summary()
In [ ]:
dataset = cell.dataset
dataset2 = cell2.dataset
In [ ]:
In [ ]:
In [ ]:
In [ ]:
dataset.summary
In [ ]:
dataset.steps
In [ ]:
dataset.raw
In [ ]:
dataset.raw.describe()
In [ ]:
dataset.raw.dtypes
In [ ]:
dataset2.raw.dtypes
In [ ]:
dataset.raw.Step_Index.unique()
In [ ]:
dataset2.raw.Step_Index.unique()
In [ ]:
In [ ]:
dataset.summary.dtypes
In [ ]:
dataset.steps.dtypes
In [ ]:
cell.save(outfilepath)
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
# Plot the charge capacity and the C.E. (and resistance) vs. cycle number (standard plot)
b.plot_summaries()
In [ ]:
# Show the journal pages
# b.experiment.journal.pages.head()
In [ ]:
# Show the most important part of the journal pages
b.view
In [ ]:
# b.experiment.status()
In [ ]:
# b.summaries.head()
In [ ]:
%%opts Curve (color=hv.Palette('Magma'))
voltage_curves = dict()
for label in b.experiment.cell_names:
d = b.experiment.data[label]
curves = d.get_cap(label_cycle_number=True, interpolated=True, number_of_points=100)
curve = hv.Curve(curves, kdims=["capacity", "cycle"], vdims="voltage").groupby("cycle").overlay().opts(show_legend=False)
voltage_curves[label] = curve
NdLayout = hv.NdLayout(voltage_curves, kdims='label').cols(3)
NdLayout
In [ ]:
%%opts Curve (color=hv.Palette('Magma'))
ocv_curves = dict()
for label in b.experiment.cell_names:
d = b.experiment.data[label]
ocv_data = d.get_ocv(direction="up", number_of_points=40)
ocv_curve = hv.Curve(ocv_data, kdims=["Step_Time", "Cycle_Index"], vdims="Voltage").groupby("Cycle_Index").overlay().opts(show_legend=False)
ocv_curves[label] = ocv_curve
NdLayout = hv.NdLayout(ocv_curves, kdims='label').cols(3)
NdLayout
In [ ]:
# This will show you all your cell names
cell_labels = b.experiment.cell_names
cell_labels
In [ ]:
# This is how to select the data (CellpyData-objects)
data1 = b.experiment.data["20160805_test001_45_cc"]
data2 = b.experiment.data["20160805_test001_47_cc"]
Let's see how the smoothing (interpolation) method works
In [ ]:
# get voltage curves
df_cycles1 = data1.get_cap(method="back-and-forth",categorical_column=True, label_cycle_number=True, interpolated=False)
In [ ]:
# get interpolated voltage curves
df_cycles2 = data1.get_cap(
method="back-and-forth", categorical_column=True, label_cycle_number=True, interpolated=True,
dx=0.1, number_of_points=100,
)
In [ ]:
%%opts Scatter [width=600] (color="red", alpha=0.9, size=12)
single_curve = hv.Curve(df_cycles1, kdims=["capacity", "cycle"], vdims="voltage", label="not-smoothed").groupby("cycle")
single_scatter = hv.Scatter(df_cycles2, kdims=["capacity", "cycle"], vdims="voltage", label="smoothed").groupby("cycle")
single_scatter * single_curve
You can for example use hvplot for looking more at your summary data
In [ ]:
import hvplot.pandas
In [ ]:
# hvplot does not like infinities
s = b.summaries.replace([np.inf, -np.inf], np.nan)
In [ ]:
layout = s["coulombic_efficiency"].hvplot() + s["discharge_capacity"].hvplot() * s["charge_capacity"].hvplot()
layout.cols(1)
In [ ]:
s["cumulated_coulombic_efficiency"].hvplot()
In [ ]:
from cellpy.utils.batch_tools.batch_analyzers import OCVRelaxationAnalyzer
print(" analyzing ocv relaxation data ".center(80, "-"))
analyzer = OCVRelaxationAnalyzer()
analyzer.assign(b.experiment)
analyzer.direction = "down"
analyzer.do()
dfs = analyzer.last
df_file_one, _df_file_two = dfs
# keeping only the columns with voltages
ycols = [col for col in df_file_one.columns if col.find("point")>=0]
# removing the first ocv rlx (relaxation before starting cycling)
df = df_file_one.iloc[1:, :]
# tidy format
df = df.melt(id_vars = "cycle", var_name="point", value_vars=ycols, value_name="voltage")
curve = hv.Curve(df, kdims=["cycle", "point"], vdims="voltage").groupby("point").overlay().opts(xlim=(1,10), width=800)
scatter = hv.Scatter(df, kdims=["cycle", "point"], vdims="voltage").groupby("point").overlay().opts(
xlim=(1,10), ylim=(0.7,1)
)
In [ ]:
layout = hv.Layout(curve * scatter)
layout.cols(1)
In [ ]:
b.summary_columns
In [ ]:
discharge_capacity = b.summaries.discharge_capacity
charge_capacity = b.summaries.charge_capacity
coulombic_efficiency = b.summaries.coulombic_efficiency
ir_charge = b.summaries.ir_charge
In [ ]:
fig, (ax1, ax2) = plt.subplots(2, 1)
ax1.plot(discharge_capacity)
ax1.set_ylabel("capacity ")
ax2.plot(ir_charge)
ax2.set_xlabel("cycle")
ax2.set_ylabel("resistance")
In [ ]:
# Lets check what cells we have
cell_labels = b.experiment.cell_names
cell_labels
In [ ]:
# OK, then I choose one of them
data = b.experiment.data["20160805_test001_45_cc"]
In [ ]:
cap = data.get_cap(categorical_column=True)
cap.head()
In [ ]:
fig, ax = plt.subplots()
ax.plot(cap.capacity, cap.voltage)
ax.set_xlabel("capacity")
ax.set_ylabel("voltage")
In [ ]:
cv = data.get_cap(method="forth")
fig, ax = plt.subplots()
ax.set_xlabel("capacity")
ax.set_ylabel("voltage")
ax.plot(cv.capacity, cv.voltage)
In [ ]:
c4 = data.get_cap(cycle=4, method="forth-and-forth")
c10 = data.get_cap(cycle=10, method="forth-and-forth")
fig, ax = plt.subplots()
ax.set_xlabel("capacity")
ax.set_ylabel("voltage")
ax.plot(c4.capacity,c4.voltage, "ro", label="cycle 4")
ax.plot(c10.capacity,c10.voltage, "bs", label="cycle 22")
ax.legend();
In [ ]:
from cellpy.utils import ica
v4, dqdv4 = ica.dqdv_cycle(
data.get_cap(
4,
categorical_column=True,
method = "forth-and-forth")
)
v10, dqdv10 = ica.dqdv_cycle(
data.get_cap(
10,
categorical_column=True,
method = "forth-and-forth")
)
plt.plot(v4,dqdv4, label="cycle 4")
plt.plot(v10, dqdv10, label="cycle 10")
plt.legend();
In [ ]:
fig, ax = plt.subplots()
for cycle in data.get_cycle_numbers():
d = data.get_cap(
cycle,
categorical_column=True,
method = "forth-and-forth"
)
if not d.empty:
v, dqdv = ica.dqdv_cycle(d)
ax.plot(v, dqdv)
else:
print(f"cycle {cycle} seems to be missing or corrupted")
In [ ]:
hv.extension('bokeh')
In [ ]:
tidy_ica = ica.dqdv_frames(data)
cycles = list(range(1,3)) + [10, 11, 12, 15]
tidy_ica = tidy_ica.loc[tidy_ica.cycle.isin(cycles), :]
In [ ]:
%%opts Curve [xlim=(0,1)] (color=hv.Palette('Magma'), alpha=0.9) NdOverlay [legend_position='right', width=800, height=500]
curve4 = (hv.Curve(tidy_ica, kdims=['voltage'], vdims=['dq', 'cycle'], label="Incremental capacity plot")
.groupby("cycle")
.overlay()
)
curve4
In [ ]: