Skip to content

Commit

Permalink
Merge pull request #158 from ImperialCollegeLondon/patch-arbin-dateti…
Browse files Browse the repository at this point in the history
…me-bug

Patch arbin datetime bug
  • Loading branch information
tomjholland authored Oct 23, 2024
2 parents 08db6cc + 798df23 commit fb4f738
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 122 deletions.
2 changes: 1 addition & 1 deletion pyprobe/cyclers/arbin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ class Arbin(BaseCycler):
"Discharge Capacity (*)": "Discharge Capacity [*]",
"Aux_Temperature_1 (*)": "Temperature [*]",
}
datetime_format: str = "%d/%m/%Y %H:%M:%S%.f"
datetime_format: str = "%m/%d/%Y %H:%M:%S%.f"
6 changes: 4 additions & 2 deletions pyprobe/cyclers/basecycler.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,10 @@ def date(self) -> pl.Expr:
Returns:
pl.Expr: A polars expression for the date column.
"""
return pl.col("Date").str.to_datetime(
format=self.datetime_format, time_unit="us"
return (
pl.col("Date")
.str.strip_chars()
.str.to_datetime(format=self.datetime_format, time_unit="us")
)

@property
Expand Down
1 change: 1 addition & 0 deletions tests/cyclers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Module for tests of the cyclers module."""
44 changes: 25 additions & 19 deletions tests/cyclers/test_arbin.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
"""Tests for the Arbin cycler class."""

from datetime import datetime

import polars as pl

from pyprobe.cyclers.arbin import Arbin

from .test_basecycler import helper_read_and_process


def test_read_and_process_arbin(benchmark):
"""Test the full process of reading and processing a file."""
arbin_cycler = Arbin(
input_data_path="tests/sample_data/arbin/sample_data_arbin.csv"
)

def read_and_process():
return arbin_cycler.pyprobe_dataframe

pyprobe_dataframe = benchmark(read_and_process)
expected_columns = [
"Date",
"Time [s]",
"Step",
"Event",
"Current [A]",
"Voltage [V]",
"Capacity [Ah]",
"Temperature [C]",
]
assert set(pyprobe_dataframe.columns) == set(expected_columns)
assert set(
pyprobe_dataframe.select("Event").unique().collect().to_series().to_list()
) == set([0, 1, 2])
expected_df = pl.DataFrame(
{
"Date": [datetime(2024, 9, 20, 8, 37, 5, 772000)],
"Time [s]": [301.214],
"Step": [3],
"Event": [2],
"Current [A]": [2.650138],
"Voltage [V]": [3.599601],
"Capacity [Ah]": [0.0007812400999999999],
"Temperature [C]": [24.68785],
}
)
expected_events = set([0, 1, 2])
helper_read_and_process(
benchmark,
arbin_cycler,
expected_final_row=expected_df,
expected_events=expected_events,
)
37 changes: 37 additions & 0 deletions tests/cyclers/test_basecycler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import polars as pl
import polars.testing as pl_testing
import pytest
from polars.testing import assert_frame_equal

from pyprobe.cyclers.basecycler import BaseCycler

Expand Down Expand Up @@ -126,6 +127,42 @@ def sample_column_map():
}


def helper_read_and_process(
benchmark,
cycler_instance,
expected_final_row,
expected_events,
expected_columns=[
"Date",
"Time [s]",
"Step",
"Event",
"Current [A]",
"Voltage [V]",
"Capacity [Ah]",
"Temperature [C]",
],
):
"""A helper function for other cyclers to test processing raw data files."""

def read_and_process():
result = cycler_instance.pyprobe_dataframe
if isinstance(result, pl.LazyFrame):
return result.collect()
else:
return result

pyprobe_dataframe = benchmark(read_and_process)
print(pyprobe_dataframe.tail(1))
assert set(pyprobe_dataframe.columns) == set(expected_columns)
assert (
set(pyprobe_dataframe.select("Event").unique().to_series().to_list())
== expected_events
)
assert_frame_equal(expected_final_row, pyprobe_dataframe.tail(1))
return pyprobe_dataframe


def test_input_data_path_validator():
"""Test the input data path validator."""
# test with invalid path
Expand Down
26 changes: 10 additions & 16 deletions tests/cyclers/test_basytec.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
from datetime import datetime

import polars as pl
from polars.testing import assert_frame_equal

from pyprobe.cyclers.basytec import Basytec

from .test_basecycler import helper_read_and_process


def test_read_file_basytec():
"""Test reading a Basytec file."""
Expand All @@ -18,24 +19,12 @@ def test_read_file_basytec():
assert dataframe["Date"][2] == "2023-06-19 17:56:54.002823"


def test_read_and_process_basytec():
def test_read_and_process_basytec(benchmark):
"""Test the full process of reading and processing a file."""
basytec_cycler = Basytec(
input_data_path="tests/sample_data/basytec/sample_data_basytec.txt"
)
pyprobe_dataframe = basytec_cycler.pyprobe_dataframe
expected_columns = [
"Date",
"Time [s]",
"Step",
"Event",
"Current [A]",
"Voltage [V]",
"Capacity [Ah]",
"Temperature [C]",
]
assert set(pyprobe_dataframe.columns) == set(expected_columns)
last_row = pl.LazyFrame(
last_row = pl.DataFrame(
{
"Date": datetime(2023, 6, 19, 17, 58, 3, 235803),
"Time [s]": [70.235804],
Expand All @@ -47,4 +36,9 @@ def test_read_and_process_basytec():
"Temperature [C]": [25.47953],
}
)
assert_frame_equal(pyprobe_dataframe.tail(1), last_row)
helper_read_and_process(
benchmark,
basytec_cycler,
expected_final_row=last_row,
expected_events=set([0, 1]),
)
92 changes: 48 additions & 44 deletions tests/cyclers/test_biologic.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from pyprobe.cyclers.biologic import Biologic, BiologicMB

from .test_basecycler import helper_read_and_process


@pytest.fixture
def biologic_MB_cycler():
Expand Down Expand Up @@ -60,66 +62,68 @@ def test_sort_files():
]


def test_read_and_process(benchmark, biologic_cycler, biologic_MB_cycler):
def test_read_and_process_biologic(benchmark, biologic_cycler):
"""Test the full process of reading and processing a file."""

def read_and_process():
return biologic_cycler.pyprobe_dataframe

pyprobe_dataframe = benchmark(read_and_process)

expected_columns = [
"Date",
"Time [s]",
"Step",
"Event",
"Current [A]",
"Voltage [V]",
"Capacity [Ah]",
"Temperature [C]",
]
assert set(pyprobe_dataframe.columns) == set(expected_columns)
last_row = pl.DataFrame(
{
"Date": [datetime(2024, 5, 13, 11, 19, 51, 602139)],
"Time [s]": [139.524007],
"Step": [1],
"Event": [1],
"Current [A]": [-0.899826],
"Voltage [V]": [3.4854481],
"Capacity [Ah]": [-0.03237135133365209],
"Temperature [C]": [23.029291],
}
)
pyprobe_dataframe = helper_read_and_process(
benchmark,
biologic_cycler,
expected_final_row=last_row,
expected_events=set([0, 1]),
)
pyprobe_dataframe = pyprobe_dataframe.with_columns(
[
pl.col("Time [s]").diff().fill_null(strategy="zero").alias("dt"),
pl.col("Date").diff().fill_null(strategy="zero").alias("dd"),
pl.col("Step").diff().fill_null(strategy="zero").alias("ds"),
]
)
assert not any(pyprobe_dataframe.select(pl.col("dt") < 0).collect().to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("dd") < 0).collect().to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("ds") < 0).collect().to_numpy())
steps = list(
pyprobe_dataframe.select(pl.col("Step")).collect().unique().to_numpy().flatten()
)
assert set(steps) == set([0, 1])
assert not any(pyprobe_dataframe.select(pl.col("dt") < 0).to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("dd") < 0).to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("ds") < 0).to_numpy())

pyprobe_dataframe = biologic_MB_cycler.pyprobe_dataframe
expected_columns = [
"Date",
"Time [s]",
"Step",
"Event",
"Current [A]",
"Voltage [V]",
"Capacity [Ah]",
"Temperature [C]",
]
assert set(pyprobe_dataframe.columns) == set(expected_columns)

def test_read_and_process_biologic_MB(benchmark, biologic_MB_cycler):
"""Test the full process of reading and processing modulo bat files."""
last_row = pl.DataFrame(
{
"Date": [datetime(2024, 5, 13, 11, 19, 51, 858016)],
"Time [s]": [256016.11344],
"Step": [5],
"Event": [5],
"Current [A]": [0.450135],
"Voltage [V]": [3.062546],
"Capacity [Ah]": [0.307727],
"Temperature [C]": [22.989878],
}
)
pyprobe_dataframe = helper_read_and_process(
benchmark,
biologic_MB_cycler,
expected_final_row=last_row,
expected_events=set([0, 1, 2, 3, 4, 5]),
)
pyprobe_dataframe = pyprobe_dataframe.with_columns(
[
pl.col("Time [s]").diff().fill_null(strategy="zero").alias("dt"),
pl.col("Date").diff().fill_null(strategy="zero").alias("dd"),
pl.col("Step").diff().fill_null(strategy="zero").alias("ds"),
]
)
assert not any(pyprobe_dataframe.select(pl.col("dt") < 0).collect().to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("dd") < 0).collect().to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("ds") < 0).collect().to_numpy())
steps = list(
pyprobe_dataframe.select(pl.col("Step")).collect().unique().to_numpy().flatten()
)
assert set(steps) == set([0, 1, 2, 3, 4, 5])
assert not any(pyprobe_dataframe.select(pl.col("dt") < 0).to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("dd") < 0).to_numpy())
assert not any(pyprobe_dataframe.select(pl.col("ds") < 0).to_numpy())


def test_process_dataframe(monkeypatch):
Expand Down
25 changes: 10 additions & 15 deletions tests/cyclers/test_maccor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,15 @@

from pyprobe.cyclers.maccor import Maccor

from .test_basecycler import helper_read_and_process

def test_read_and_process_maccor():

def test_read_and_process_maccor(benchmark):
"""Test reading and processing a sample Maccor file."""
maccor_cycler = Maccor(
input_data_path="tests/sample_data/maccor/sample_data_maccor.csv"
)
pyprobe_dataframe = maccor_cycler.pyprobe_dataframe
expected_columns = [
"Date",
"Time [s]",
"Step",
"Event",
"Current [A]",
"Voltage [V]",
"Capacity [Ah]",
"Temperature [C]",
]
assert set(pyprobe_dataframe.columns) == set(expected_columns)
last_row = pl.LazyFrame(
last_row = pl.DataFrame(
{
"Date": datetime(2023, 11, 23, 15, 56, 24, 60000),
"Time [s]": [13.06],
Expand All @@ -37,7 +27,12 @@ def test_read_and_process_maccor():
"Temperature [C]": [22.2591],
}
)
assert_frame_equal(pyprobe_dataframe.tail(1), last_row)
helper_read_and_process(
benchmark,
maccor_cycler,
expected_final_row=last_row,
expected_events=set([0, 1]),
)


@pytest.fixture
Expand Down
Loading

0 comments on commit fb4f738

Please sign in to comment.