{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Filtering data\n", "One of PyProBE's main strengths is to be able to filter data quickly and with natural language. This example shows the power of the filtering functions available." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Start by importing PyProBE and the dataset:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pyprobe\n", "import numpy as np\n", "info_dictionary = {'Name': 'Sample cell',\n", " 'Chemistry': 'NMC622',\n", " 'Nominal Capacity [Ah]': 0.04,\n", " 'Cycler number': 1,\n", " 'Channel number': 1,}\n", "data_directory = '../../../tests/sample_data/neware'\n", "\n", "# Create a cell object\n", "cell = pyprobe.Cell(info=info_dictionary)\n", "cell.add_procedure(procedure_name='Sample',\n", " folder_path = data_directory,\n", " filename = 'sample_data_neware.parquet')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the entire dataset:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "full_procedure = cell.procedure['Sample']\n", "fig = pyprobe.Plot()\n", "fig.add_line(full_procedure, 'Time [s]', 'Voltage [V]')\n", "fig.show_image()\n", "# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A `README.yaml` file is stored alongside this dataset, which appears like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "with open(data_directory+'/README.yaml', 'r') as file:\n", " readme = file.read()\n", " print(readme)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Constructing the README file in this way allows three separate experiments to be separated out from the data:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "initial_charge = full_procedure.experiment(\"Initial Charge\")\n", "break_in = full_procedure.experiment(\"Break-in Cycles\")\n", "pulses = full_procedure.experiment(\"Discharge Pulses\")\n", "\n", "fig = pyprobe.Plot()\n", "fig.add_line(initial_charge, 'Procedure Time [s]', 'Voltage [V]', color = 'red', label='Initial Charge')\n", "fig.add_line(break_in, 'Procedure Time [s]', 'Voltage [V]', color = 'blue', label='Break-in Cycles')\n", "fig.add_line(pulses, 'Procedure Time [s]', 'Voltage [V]', color='purple', label='Discharge Pulses')\n", "fig.show_image()\n", "# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Selecting the Break-in Cycles experiment, we can filter further:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cycle_3 = break_in.cycle(2) # python zero-indexing means we use index 2 to retrieve the third cycle\n", "\n", "fig = pyprobe.Plot()\n", "fig.add_line(break_in, 'Experiment Time [s]', 'Voltage [V]', color = 'blue', label='Break-in Cycles')\n", "fig.add_line(cycle_3, 'Experiment Time [s]', 'Voltage [V]', color='red', label='Cycle 3')\n", "fig.show_image()\n", "# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can break this down further into charge, discharge and rest sections:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "discharge = cycle_3.discharge()\n", "rest_0 = cycle_3.rest(0)\n", "charge = cycle_3.charge()\n", "rest_1 = cycle_3.rest(1)\n", "\n", "fig = pyprobe.Plot()\n", "fig.add_line(discharge, 'Experiment Time [s]', 'Voltage [V]', color = 'blue', label='Discharge')\n", "fig.add_line(rest_0, 'Experiment Time [s]', 'Voltage [V]', color='red', label='Rest 0')\n", "fig.add_line(charge, 'Experiment Time [s]', 'Voltage [V]', color='purple', label='Charge')\n", "fig.add_line(rest_1, 'Experiment Time [s]', 'Voltage [V]', color='green', label='Rest 1')\n", "fig.show_image()\n", "# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some cyclers will split constant voltage and constant current instructions into two separate steps. That is not the case for the cycler used for this dataset, but we can still extract them with PyProBE filtering:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "CC_discharge = discharge.constant_current(0)\n", "CC_charge = charge.constant_current(0)\n", "CV_hold = cycle_3.constant_voltage(0)\n", "\n", "fig = pyprobe.Plot()\n", "fig.add_line(cycle_3, 'Experiment Time [s]', 'Current [A]', color = 'blue', label='Rests')\n", "fig.add_line(CC_discharge, 'Experiment Time [s]', 'Current [A]', color='green', label='CC Discharge')\n", "fig.add_line(CC_charge, 'Experiment Time [s]', 'Current [A]', color='red', label='CC Charge')\n", "fig.add_line(CV_hold, 'Experiment Time [s]', 'Current [A]', color='purple', label='CV Hold')\n", "fig.show_image()\n", "# fig.show() # This will show the plot interactively, it is commented out for the sake of the documentation" ] } ], "metadata": { "kernelspec": { "display_name": "pyprobe-dev", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 2 }