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 prms
from cellpy import prmreader
from cellpy import cellreader
from cellpy.utils import ocv_rlx, plotutils, helpers
import holoviews as hv

%matplotlib inline
hv.extension('bokeh')

In [ ]:
######################################################################
##                                                                  ##
##                       development                                ##
##                                                                  ##
######################################################################

from pathlib import Path
from pprint import pprint

# Use these when working on my work PC:
raw_data_path = r"C:\Scripting\MyFiles\development_cellpy\testdata"
out_data_path = r"C:\Scripting\Processing\Test\out"

# Use these when working on my MacBook:
raw_data_path = "/Users/jepe/scripting/cellpy/dev_data/gitt"
out_data_path = "/Users/jepe/scripting/cellpy/dev_data/out"

raw_data_path = Path(raw_data_path)
out_data_path = Path(out_data_path)

print(" SETTING SOME PRMS ".center(80, "="))
prms.Paths["db_filename"] = "cellpy_db.xlsx"
prms.Paths["cellpydatadir"] = out_data_path
prms.Paths["outdatadir"] = out_data_path
prms.Paths["rawdatadir"] = raw_data_path
prms.Paths["db_path"] = out_data_path
prms.Paths["filelogdir"] = out_data_path
pprint(prms.Paths)

In [ ]:
fn = "20181026_cen31_03_cc_05"
resn = fn + ".res"
cellpyn = fn + ".h5"
filename = prms.Paths["rawdatadir"] / resn
cellpyname = prms.Paths["cellpydatadir"] / cellpyn

Load a cell

Only need a part of it, so using only the first 29 cycles (splitting on cycle 30)


In [ ]:
dd = cellreader.get(filename, logging_mode="INFO")

In [ ]:
d, _ = helpers.split_experiment(dd, 90)

OCV rlx curves


In [ ]:
ocv_cycles = d.get_ocv(interpolated=True, number_of_points=40, direction="down").reset_index(drop=True)

In [ ]:
ocv_cycles.head()

In [ ]:
%%opts Curve [width=600] (alpha=0.9, color=hv.Palette('Magma'))
single_curves = hv.Curve(ocv_cycles, kdims=["Step_Time", "Cycle_Index"], vdims=["Voltage"]).groupby("Cycle_Index").overlay()
single_curves.opts(tools=["hover"])

Extract OCV points

Using the select_ocv_points function from cellpy.utils.ocv_rlx.

def select_ocv_points(
    cellpydata,
    cycles=None,
    selection_method="martin",
    number_of_points=5,
    interval=10,
    relative_voltage=False,
    report_times=False,
    direction=None,
):

    """Select points from the ocvrlx steps.

        Args:
            cellpydata: CellpyData-object
            cycles: list of cycle numbers to process (optional)
            selection_method: criteria for selecting points
                martin: select first and last, and then last/2, last/2/2 etc.
                    until you have reached the wanted number of points.
                fixed_times: select first, and then
            number_of_points: number of points you want.
            interval: interval between each point (in use only for methods
                where interval makes sense). If it is a list, then
                number_of_points will be calculated as len(interval) + 1 (and
                override the set number_of_points).
            relative_voltage: set to True if you would like the voltage to be
                relative to the voltage before starting the ocv rlx step.
                Defaults to False. Remark that for the initial rxl step (when
                you just have put your cell on the tester) does not have any
                prior voltage. The relative voltage will then be versus the
                first measurement point.
            report_times: also report the ocv rlx total time if True (defaults
                to False)
            direction ("up", "down" or "both"): select "up" if you would like
                to process only the ocv rlx steps where the voltage is relaxing
                upwards and vize versa. Defaults to "both".

        Returns:
            pandas.DataFrame

    """

In [ ]:
p_fixed_time, i1 = ocv_rlx.select_ocv_points(d, selection_method="fixed_times", direction="both", return_times=True)

In [ ]:
p_martin, i2 = ocv_rlx.select_ocv_points(d, direction="both", return_times=True)

In [ ]:
i1.head()

In [ ]:
i2.head()

In [ ]:
p_martin.head()

In [ ]:
p_fx_down = p_fixed_time.loc[p_fixed_time.type == "ocvrlx_down"]
p_m_down = p_martin.loc[p_martin.type == "ocvrlx_down"]

In [ ]:
p_fx_down_fast = p_fx_down.loc[p_fx_down.step == 15]
p_m_down_fast = p_m_down.loc[p_m_down.step == 15]
p_fx_down_slow = p_fx_down.loc[p_fx_down.step == 8]
p_m_down_slow = p_m_down.loc[p_m_down.step == 8]

In [ ]:
p_m_down.plot(x="cycle", y=p_m_down.columns.drop("cycle").drop("step"))

In [ ]:
p_fx_down.plot(x="cycle", y=[c for c in p_fx_down.columns if c.startswith("point_")])

In [ ]:
p_fx_down_fast.plot(x="cycle", y=[c for c in p_fx_down.columns if c.startswith("point_")])

In [ ]:
p_m_down_fast.plot(x="cycle", y=[c for c in p_fx_down.columns if c.startswith("point_")])

In [ ]:
p_m_down_slow.plot(x="cycle", y=[c for c in p_m_down_slow.columns if c.startswith("point_")])

In [ ]:
ax1 = p_fx_down_slow.plot(x="cycle", y=[c for c in p_fx_down_slow.columns if c.startswith("point_")])

In [ ]:
ycols = [c for c in p_fx_down_slow.columns if c.startswith("point_")]
xcol = "cycle"
fig, (ax1, ax2) = plt.subplots(1,2)
fig.suptitle("Fixed dt")
ax1.set_ylabel("voltage (vs. Li/Li+)")
p_fx_down_slow.plot(x=xcol, y=ycols, ax=ax1, title="slow cycles")
p_fx_down_fast.plot(x=xcol, y=ycols, ax=ax2, title="fast cycles", legend=False)
plt.tight_layout()

In [ ]:
ycols = [c for c in p_m_down_slow.columns if c.startswith("point_")]
xcol = "cycle"
fig, (ax1, ax2) = plt.subplots(1,2)
fig.suptitle("Martin")
ax1.set_ylabel("voltage (vs. Li/Li+)")
p_m_down_slow.plot(x=xcol, y=ycols, ax=ax1, title="slow cycles")
p_m_down_fast.plot(x=xcol, y=ycols, ax=ax2, title="fast cycles", legend=False)
plt.tight_layout()

Delta V


In [ ]:
p_m_down_slow["delta"] = p_m_down_slow["point_04"] - p_m_down_slow["point_00"]
p_m_down_fast["delta"] = p_m_down_fast["point_04"] - p_m_down_fast["point_00"]

In [ ]:
ycols = "delta"
xcol = "cycle"
fig, ax = plt.subplots()
fig.suptitle("Martin")
ax.set_ylabel("delta V (point_04 - point_00)")
p_m_down_slow.plot(x=xcol, y=ycols, ax=ax, label="slow cycles")
p_m_down_fast.plot(x=xcol, y=ycols, ax=ax, label="fast cycles");
#plt.tight_layout()

In [ ]:
p_fx_down_slow["delta"] = p_fx_down_slow["point_04"] - p_fx_down_slow["point_00"]
p_fx_down_fast["delta"] = p_fx_down_fast["point_04"] - p_fx_down_fast["point_00"]

In [ ]:
ycols = "delta"
xcol = "cycle"
fig, ax = plt.subplots()
fig.suptitle("fixed")
ax.set_ylabel("delta V (point_04 - point_00)")
p_fx_down_slow.plot(x=xcol, y=ycols, ax=ax, label="slow cycles")
p_fx_down_fast.plot(x=xcol, y=ycols, ax=ax, label="fast cycles");
#plt.tight_layout()

raw


In [ ]:
plotutils.cycle_info_plot(d)

In [ ]: