Skip to content

Commit

Permalink
Merge pull request #151 from ImperialCollegeLondon/add-more-cyclers
Browse files Browse the repository at this point in the history
Add additional cycler parsers
  • Loading branch information
tomjholland authored Oct 21, 2024
2 parents c057114 + 2f0320d commit df72274
Show file tree
Hide file tree
Showing 18 changed files with 1,094 additions and 110 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: "Build and test"
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- main
workflow_dispatch:
jobs:
qa:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
114 changes: 88 additions & 26 deletions docs/source/user_guide/input_data_guidance.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ PyProBE is able to import data from the following cyclers:
- .mpt
- .txt

* Arbin: :code:`'arbin'`

- .csv
- .xlsx

* Maccor: :code:`'maccor'`

- .csv

* Basytec: :code:`'basytec'`

- .txt


PyProBE data columns
--------------------
Expand All @@ -42,34 +55,83 @@ Once converted into the standard PyProBE format, the data columns stored in
current is passed and decreases when discharge current is passed.

The table below summarises the data columns in the PyProBE format and the corresponding
column names of of data from supported cyclers:
column names that are required in data from supported cyclers:

.. raw:: html

<style>
.scrollable-table-container {
position: relative;
overflow-x: auto;
white-space: nowrap;
}
.scrollable-table {
border-collapse: collapse;
width: 100%;
}
.scrollable-table th, .scrollable-table td {
padding: 8px;
text-align: left;
border: 1px solid #ddd;
}
.scrollable-table th {
background-color: #f2f2f2;
position: sticky;
top: 0;
z-index: 1;
}
.scrollable-table th:first-child, .scrollable-table td:first-child {
position: sticky;
left: 0;
z-index: 2;
background-color: #f2f2f2;
}
.scrollable-table th:nth-child(2), .scrollable-table td:nth-child(2) {
position: sticky;
left: 115px; /* Adjust this value based on the width of the first column */
z-index: 2;
background-color: #f2f2f2;
}
</style>

<div class="scrollable-table-container">

.. table::
:widths: 20 20 20 20

+----------------+-----------+------------------------+-----------------------------+
| PyProBE | Required? | Neware | BioLogic |
+================+===========+========================+=============================+
| Date | No | Date | "Acquisition started on" |
| | | | in header |
+----------------+-----------+------------------------+-----------------------------+
| Time [s] | Yes | *Auto from Date* | time/* |
+----------------+-----------+------------------------+-----------------------------+
| Step | Yes | Step Index | Ns |
+----------------+-----------+------------------------+-----------------------------+
| Cycle | Yes | *Auto from Step* | *Auto from Step* |
| | | | |
+----------------+-----------+------------------------+-----------------------------+
| Event | Yes | *Auto from Step* | *Auto from Step* |
| | | | |
+----------------+-----------+------------------------+-----------------------------+
| Current [A] | Yes | Current(*) | I/* |
+----------------+-----------+------------------------+-----------------------------+
| Voltage [V] | Yes | Voltage(*) | Ecell/* |
+----------------+-----------+------------------------+-----------------------------+
| Capacity [Ah] | Yes | Chg. Cap.(*), | Q charge/\*, |
| | | DChg. Cap.(*) | Q discharge/* |
+----------------+-----------+------------------------+-----------------------------+
:widths: 20 20 20 20 20 20 20
:class: scrollable-table

+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| PyProBE | Required? | Neware | BioLogic | Arbin | Maccor | Basytec |
+======================+===========+========================+=============================+=============================+=============================+=============================+
| ``Date`` | No | ``Date`` | ``Acquisition started on`` | ``Date Time`` | ``DPT Time`` | ``~Start of Test`` |
| | | | in header | | | in header |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Time [s]`` | Yes | *Auto from Date* | ``time/*`` | ``Test Time (*)`` | ``Test Time (sec)`` | ``~Time[*]`` |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Step`` | Yes | ``Step Index`` | ``Ns`` | ``Step Index`` | ``Step`` | ``Line`` |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Cycle`` | Yes | *Auto from Step* | *Auto from Step* | *Auto from Step* | *Auto from Step* | *Auto from Step* |
| | | | | | | |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Event`` | Yes | *Auto from Step* | *Auto from Step* | *Auto from Step* | *Auto from Step* | *Auto from Step* |
| | | | | | | |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Current [A]`` | Yes | ``Current(*)`` | ``I/*`` | ``Current (*)`` | ``Current`` | ``I[*]`` |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Voltage [V]`` | Yes | ``Voltage(*)`` | ``Ecell/*`` | ``Voltage (*)`` | ``Voltage`` | ``U[*]`` |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Capacity [Ah]`` | Yes | ``Chg. Cap.(*)``, | ``Q charge/*``, | ``Charge Capacity (*)``, | ``Capacity`` | ``Ah[*]`` |
| | | ``DChg. Cap.(*)`` | ``Q discharge/*`` | ``Discharge Capacity (*)`` | | |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| ``Temperature [C]`` | No | ``T1(*)`` | ``Temperature/*`` | ``Aux_Temperature_1 (*)`` | ``Temp 1`` | ``T1[*]`` |
+----------------------+-----------+------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+

.. raw:: html

</div>

Where no units are provided (as is the case with Maccor), the PyProBE default units are
assumed.

The columns marked with *Auto from ...* are automatically generated by the PyProBE
data import process. This process includes automatic unit conversion to the PyProBE
Expand Down
9 changes: 6 additions & 3 deletions pyprobe/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import polars as pl
from pydantic import BaseModel, Field, field_validator, validate_call

from pyprobe.cyclers import basecycler, biologic, neware
from pyprobe.cyclers import arbin, basecycler, basytec, biologic, maccor, neware
from pyprobe.filters import Procedure
from pyprobe.readme_processor import process_readme

Expand Down Expand Up @@ -98,11 +98,14 @@ def process_cycler_file(
"neware": neware.Neware,
"biologic": biologic.Biologic,
"biologic_MB": biologic.BiologicMB,
"arbin": arbin.Arbin,
"maccor": maccor.Maccor,
"basytec": basytec.Basytec,
}
t1 = time.time()
importer = cycler_dict[cycler](input_data_path=input_data_path)
self._write_parquet(importer, output_data_path)
print(f"\tparquet written in {time.time()-t1:.2f} seconds.")
print(f"\tparquet written in {time.time()-t1: .2f} seconds.")

@validate_call
def process_generic_file(
Expand Down Expand Up @@ -150,7 +153,7 @@ def process_generic_file(
column_dict=column_dict,
)
self._write_parquet(importer, output_data_path)
print(f"\tparquet written in {time.time()-t1:.2f} seconds.")
print(f"\tparquet written in {time.time()-t1: .2f} seconds.")

@validate_call
def add_procedure(
Expand Down
21 changes: 21 additions & 0 deletions pyprobe/cyclers/arbin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""A module to load and process Arbin battery cycler data."""


from pyprobe.cyclers.basecycler import BaseCycler


class Arbin(BaseCycler):
"""A class to load and process Neware battery cycler data."""

input_data_path: str
column_dict: dict[str, str] = {
"Date Time": "Date",
"Test Time (*)": "Time [*]",
"Step Index": "Step",
"Current (*)": "Current [*]",
"Voltage (*)": "Voltage [*]",
"Charge Capacity (*)": "Charge Capacity [*]",
"Discharge Capacity (*)": "Discharge Capacity [*]",
"Aux_Temperature_1 (*)": "Temperature [*]",
}
datetime_format: str = "%d/%m/%Y %H:%M:%S%.f"
Loading

0 comments on commit df72274

Please sign in to comment.