diff --git a/pyprobe/cell.py b/pyprobe/cell.py index 1273ad84..e984a0e8 100644 --- a/pyprobe/cell.py +++ b/pyprobe/cell.py @@ -120,7 +120,7 @@ def process_cycler_file( cycler_dict = {"neware": neware.Neware, "biologic": biologic.Biologic} t1 = time.time() importer = cycler_dict[cycler](input_data_path) - dataframe = importer.imported_dataframe + dataframe = importer.pyprobe_dataframe dataframe.write_parquet(output_data_path) print(f"\tparquet written in {time.time()-t1:.2f} seconds.") diff --git a/pyprobe/cyclers/basecycler.py b/pyprobe/cyclers/basecycler.py index f9db2b0b..82f736a6 100644 --- a/pyprobe/cyclers/basecycler.py +++ b/pyprobe/cyclers/basecycler.py @@ -1,47 +1,320 @@ """A module to load and process battery cycler data.""" +import glob +import os +import re +import warnings +from typing import Dict, List + import polars as pl +from pyprobe.unitconverter import UnitConverter + class BaseCycler: """A class to load and process battery cycler data.""" - imported_dataframe: pl.DataFrame + def __init__( + self, + input_data_path: str, + common_suffix: str, + column_name_pattern: str, + column_dict: Dict[str, str], + ) -> None: + """Create a cycler object. - required_columns = [ - "Date", - "Time [s]", - "Cycle", - "Step", - "Event", - "Current [A]", - "Voltage [V]", - "Capacity [Ah]", - ] + Args: + input_data_path (str): The path to the input data. + common_suffix (str): The part of the filename before an index number, + when a single procedure is split into multiple files. + column_name_pattern (str): The regular expression pattern to match the + column names. + column_dict (Dict[str, str]): A dictionary mapping the expected columns to + the actual column names in the data. + """ + self.input_data_path = input_data_path + self.common_suffix = common_suffix + self.column_name_pattern = column_name_pattern + self.column_dict = column_dict + self._dataframe_columns = self.imported_dataframe.columns - @staticmethod - def get_cycle_and_event(dataframe: pl.DataFrame) -> pl.DataFrame: - """Get the step and event columns from a DataFrame. + self.required_columns = { + "Date": self.date, + "Time [s]": self.time, + "Cycle": self.cycle, + "Step": self.step, + "Event": self.event, + "Current [A]": self.current, + "Voltage [V]": self.voltage, + "Capacity [Ah]": self.capacity, + } - Args: - dataframe: The DataFrame to process. + self.pyprobe_dataframe = pl.concat( + list(self.required_columns.values()), + how="horizontal", + ) + + @property + def date(self) -> pl.DataFrame: + """Identify and format the date column. + + Returns: + pl.DataFrame: A single column DataFrame containing the date. + """ + if ( + self.imported_dataframe.dtypes[ + self.imported_dataframe.columns.index("Date") + ] + != pl.Datetime + ): + date = pl.col("Date").str.to_datetime().alias("Date") + else: + date = pl.col("Date") + return self.imported_dataframe.select(date) + + @property + def time(self) -> pl.DataFrame: + """Identify and format the time column. + + Returns: + pl.DataFrame: A single column DataFrame containing the time in [s]. + """ + time = pl.col(self.column_dict["Time"]).alias("Time [s]") + return self.imported_dataframe.select(time) + + @property + def step(self) -> pl.DataFrame: + """Identify and format the step column.""" + step = pl.col(self.column_dict["Step"]).alias("Step") + return self.imported_dataframe.select(step) + + @property + def current(self) -> pl.DataFrame: + """Identify and format the current column. + + Returns: + pl.DataFrame: A single column DataFrame containing the current in [A]. + """ + current = UnitConverter.search_columns( + self._dataframe_columns, + self.column_dict["Current"], + self.column_name_pattern, + "Current", + ).to_default() + return self.imported_dataframe.select(current) + + @property + def voltage(self) -> pl.DataFrame: + """Identify and format the voltage column. + + Returns: + pl.DataFrame: A single column DataFrame containing the voltage in [V]. + """ + voltage = UnitConverter.search_columns( + self._dataframe_columns, + self.column_dict["Voltage"], + self.column_name_pattern, + "Voltage", + ).to_default() + return self.imported_dataframe.select(voltage) + + @property + def charge_capacity(self) -> pl.DataFrame: + """Identify and format the charge capacity column. + + Returns: + pl.DataFrame: A single column DataFrame containing the charge capacity in + [Ah]. + """ + charge_capacity = UnitConverter.search_columns( + self._dataframe_columns, + self.column_dict["Charge Capacity"], + self.column_name_pattern, + "Capacity", + ).to_default(keep_name=True) + return self.imported_dataframe.select(charge_capacity) + + @property + def discharge_capacity(self) -> pl.DataFrame: + """Identify and format the discharge capacity column. + + Returns: + pl.DataFrame: A single column DataFrame containing the discharge capacity in + [Ah]. + """ + discharge_capacity = UnitConverter.search_columns( + self._dataframe_columns, + self.column_dict["Discharge Capacity"], + self.column_name_pattern, + "Capacity", + ).to_default(keep_name=True) + return self.imported_dataframe.select(discharge_capacity) + + @property + def capacity_from_ch_dch(self) -> pl.DataFrame: + """Calculate the capacity from charge and discharge capacities. + + Returns: + pl.DataFrame: A DataFrame containing the calculated capacity column in [Ah]. + """ + charge_and_discharge_capacity = pl.concat( + [self.charge_capacity, self.discharge_capacity], how="horizontal" + ) + diff_charge_capacity = ( + pl.col(f"{self.column_dict['Charge Capacity']} [Ah]") + .diff() + .clip(lower_bound=0) + .fill_null(strategy="zero") + ) + diff_discharge_capacity = ( + pl.col(f"{self.column_dict['Discharge Capacity']} [Ah]") + .diff() + .clip(lower_bound=0) + .fill_null(strategy="zero") + ) + capacity = ( + (diff_charge_capacity - diff_discharge_capacity).cum_sum() + + pl.col(f"{self.column_dict['Charge Capacity']} [Ah]").max() + ).alias("Capacity [Ah]") + return charge_and_discharge_capacity.select(capacity) + + @property + def capacity(self) -> pl.DataFrame: + """Identify and format the capacity column. + + Returns: + pl.DataFrame: A single column DataFrame containing the capacity in [Ah]. + """ + if "Capacity" in self.column_dict: + capacity = UnitConverter.search_columns( + self._dataframe_columns, + self.column_dict["Capacity"], + self.column_name_pattern, + "Capacity", + ).to_default() + return self.imported_dataframe.select(capacity) + else: + return self.capacity_from_ch_dch + + @property + def cycle(self) -> pl.DataFrame: + """Identify the cycle number. + + Cycles are defined by repetition of steps. They are identified by a decrease + in the step number. Returns: - DataFrame: The DataFrame with the step and event columns. + pl.DataFrame: A single column DataFrame containing the cycle number. """ cycle = ( - (pl.col("Step") - pl.col("Step").shift() < 0) + ( + pl.col(self.column_dict["Step"]) + - pl.col(self.column_dict["Step"]).shift() + < 0 + ) .fill_null(strategy="zero") .cum_sum() .alias("Cycle") .cast(pl.Int64) ) + return self.imported_dataframe.select(cycle) + + @property + def event(self) -> pl.DataFrame: + """Identify the event number. + Events are defined by any change in the step number, increase or decrease. + + Returns: + pl.DataFrame: A single column DataFrame containing the event number. + """ event = ( - (pl.col("Step") - pl.col("Step").shift() != 0) + ( + pl.col(self.column_dict["Step"]) + - pl.col(self.column_dict["Step"]).shift() + != 0 + ) .fill_null(strategy="zero") .cum_sum() .alias("Event") .cast(pl.Int64) ) - return dataframe.with_columns(cycle, event) + return self.imported_dataframe.select(event) + + @staticmethod + def read_file(filepath: str) -> pl.DataFrame: + """Read a battery cycler file into a DataFrame. + + Args: + filepath (str): The path to the file. + + Returns: + pl.DataFrame: The DataFrame. + """ + raise NotImplementedError("Subclasses must implement this method") + + @property + def dataframe_list(self) -> list[pl.DataFrame]: + """Return a list of all the imported dataframes. + + Returns: + List[DataFrame]: A list of DataFrames. + """ + files = glob.glob(self.input_data_path) + files = self.sort_files(files) + list = [self.read_file(file) for file in files] + all_columns = set([col for df in list for col in df.columns]) + indices_to_remove = [] + for i in range(len(list)): + if len(list[i].columns) < len(all_columns): + indices_to_remove.append(i) + warnings.warn( + f"File {os.path.basename(files[i])} has missing columns, " + "it has not been read." + ) + continue + return [df for i, df in enumerate(list) if i not in indices_to_remove] + + @property + def imported_dataframe(self) -> pl.DataFrame: + """Return the dataframe containing the data from all imported files. + + Returns: + pl.DataFrame: The DataFrame. + """ + return pl.concat(self.dataframe_list, how="vertical", rechunk=True) + + def sort_files(self, file_list: List[str]) -> List[str]: + """Sort a list of files by the integer in the filename. + + Args: + file_list: The list of files. + + Returns: + list: The sorted list of files. + """ + # common first part of file names + self.common_prefix = os.path.commonprefix(file_list) + return sorted(file_list, key=self.sort_key) + + def sort_key(self, filepath: str) -> int: + """Sort key for the files. + + Args: + filepath (str): The path to the file. + + Returns: + int: The integer in the filename. + """ + # replace common prefix + stripped_filepath = filepath.replace(self.common_prefix, "") + + # find the index of the common suffix + suffix_index = stripped_filepath.find(self.common_suffix) + + # if the suffix is found, strip it and everything after it + if suffix_index != -1: + stripped_filepath = stripped_filepath[:suffix_index] + # extract the first number in the filename + match = re.search(r"\d+", stripped_filepath) + return int(match.group()) if match else 0 diff --git a/pyprobe/cyclers/biologic.py b/pyprobe/cyclers/biologic.py index 311c328a..7b4802ff 100644 --- a/pyprobe/cyclers/biologic.py +++ b/pyprobe/cyclers/biologic.py @@ -1,16 +1,11 @@ """A module to load and process Biologic battery cycler data.""" -import glob -import re -import warnings from datetime import datetime -from typing import List import polars as pl from pyprobe.cyclers.basecycler import BaseCycler -from pyprobe.unitconverter import UnitConverter class Biologic(BaseCycler): @@ -22,13 +17,20 @@ def __init__(self, input_data_path: str) -> None: Args: input_data_path: The path to the input data. """ - self.input_data_path = input_data_path - - @property - def imported_dataframe(self) -> pl.DataFrame: - """The imported DataFrame.""" - imported_dataframe = self.get_cycle_and_event(self.processed_dataframe) - return imported_dataframe.select(self.required_columns) + super().__init__( + input_data_path, + common_suffix="_MB", + column_name_pattern=r"(.+)/(.+)", + column_dict={ + "Date": "Date", + "Time": "time/s", + "Step": "Ns", + "Current": "I", + "Voltage": "Ecell", + "Charge Capacity": "Q charge", + "Discharge Capacity": "Q discharge", + }, + ) @staticmethod def read_file(filepath: str) -> pl.DataFrame: @@ -75,114 +77,21 @@ def read_file(filepath: str) -> pl.DataFrame: ) return dataframe - @classmethod - def sort_files(cls, file_list: List[str]) -> List[str]: - """Sort a list of files by the integer in the filename. - - Args: - file_list: The list of files. - - Returns: - list: The sorted list of files. - """ - return sorted(file_list, key=cls.sort_key) - - @staticmethod - def sort_key(filepath: str) -> int: - """Sort key for the files. - - Args: - filepath (str): The path to the file. - - Returns: - int: The integer in the filename. - """ - match = re.search(r"\d+_MB", filepath) - return int(match.group()[:-3]) if match else 0 - @property - def raw_dataframe(self) -> pl.DataFrame: + def imported_dataframe(self) -> pl.DataFrame: """Read a battery cycler file into a DataFrame. Args: filepath: The path to the file. """ - files = glob.glob(self.input_data_path) - files = self.sort_files(files) - dataframes = [self.read_file(file) for file in files] - all_columns = set([col for df in dataframes for col in df.columns]) - indices_to_remove = [] - for i in range(len(dataframes)): - if len(dataframes[i].columns) < len(all_columns): - indices_to_remove.append(i) - warnings.warn( - f"File {files[i]} has missing columns, it has not been read." - ) - continue - if i > 0: - dataframes[i] = dataframes[i].with_columns( - pl.col("Ns") + dataframes[i - 1]["Ns"].max() + 1 - ) - dataframes = [ - df for i, df in enumerate(dataframes) if i not in indices_to_remove - ] - return pl.concat(dataframes, how="vertical") + for i in range(len(self.dataframe_list)): + self.dataframe_list[i] = self.dataframe_list[i].with_columns( + pl.col("Ns") + self.dataframe_list[i - 1]["Ns"].max() + 1 + ) + return pl.concat(self.dataframe_list, how="vertical", rechunk=True) @property - def processed_dataframe(self) -> pl.DataFrame: - """Process a DataFrame from battery cycler data. - - Args: - dataframe: The DataFrame to process. - - Returns: - pl.DataFrame: The dataframe in PyProBE format. - """ - dataframe = self.raw_dataframe - columns = dataframe.columns - time = pl.col("time/s").alias("Time [s]") - - # Cycle and step - step = (pl.col("Ns") + 1).alias("Step") - - # Measured data - column_name_pattern = r"(.+)/(.+)" - current = UnitConverter.search_columns( - columns, "I", column_name_pattern, "Current" - ).to_default() - voltage = UnitConverter.search_columns( - columns, "Ecell", column_name_pattern, "Voltage" - ).to_default() - - make_charge_capacity = UnitConverter.search_columns( - columns, "Q charge", column_name_pattern, "Capacity" - ).to_default(keep_name=True) - make_discharge_capacity = UnitConverter.search_columns( - columns, "Q discharge", column_name_pattern, "Capacity" - ).to_default(keep_name=True) - - dataframe = dataframe.with_columns(time, step, current, voltage) - - dataframe = dataframe.with_columns( - make_charge_capacity, make_discharge_capacity - ) - - diff_charge_capacity = ( - pl.col("Q charge [Ah]") - .diff() - .clip(lower_bound=0) - .fill_null(strategy="zero") - ) - diff_discharge_capacity = ( - pl.col("Q discharge [Ah]") - .diff() - .clip(lower_bound=0) - .fill_null(strategy="zero") - ) - make_capacity = ( - (diff_charge_capacity - diff_discharge_capacity).cum_sum() - + pl.col("Q charge [Ah]").max() - ).alias("Capacity [Ah]") - - dataframe = dataframe.with_columns(make_capacity) - return dataframe + def step(self) -> pl.DataFrame: + """Identify and format the step column.""" + step = (pl.col(self.column_dict["Step"]) + 1).alias("Step") + return self.imported_dataframe.select(step) diff --git a/pyprobe/cyclers/neware.py b/pyprobe/cyclers/neware.py index e23c003a..f1e5bd9d 100644 --- a/pyprobe/cyclers/neware.py +++ b/pyprobe/cyclers/neware.py @@ -1,14 +1,11 @@ """A module to load and process Neware battery cycler data.""" -import glob + import os -import re -from typing import List, Tuple import polars as pl from pyprobe.cyclers.basecycler import BaseCycler -from pyprobe.unitconverter import UnitConverter class Neware(BaseCycler): @@ -20,13 +17,21 @@ def __init__(self, input_data_path: str) -> None: Args: input_data_path: The path to the input data. """ - self.input_data_path = input_data_path - - @property - def imported_dataframe(self) -> pl.DataFrame: - """The imported DataFrame.""" - imported_dataframe = self.get_cycle_and_event(self.processed_dataframe) - return imported_dataframe.select(self.required_columns) + file_ext = os.path.splitext(input_data_path)[1] + column_dict = { + "Date": "Date", + "Step": "Step Index", + "Current": "Current", + "Voltage": "Voltage", + "Charge Capacity": "Chg. Cap.", + "Discharge Capacity": "DChg. Cap.", + } + super().__init__( + input_data_path, + common_suffix=file_ext, + column_name_pattern=r"(.+)\((.+)\)", + column_dict=column_dict, + ) @staticmethod def read_file(filepath: str) -> pl.DataFrame: @@ -48,116 +53,18 @@ def read_file(filepath: str) -> pl.DataFrame: case _: raise ValueError(f"Unsupported file extension: {file_ext}") - @staticmethod - def sort_key(filepath_tuple: Tuple[str, str]) -> int: - """Sort key for the files. - - Args: - filepath_tupe (Tuple): A tuple containing the file suffix - and the full filepath. - - Returns: - int: The integer in the filename. - """ - filepath = filepath_tuple[0] - match = re.search(r"(\d+)(?=\.)", filepath) - return int(match.group()) if match else 0 - - @classmethod - def sort_files(cls, file_list: List[str]) -> List[str]: - """Sort a list of files by the integer in the filename. - - Args: - file_list (List[str]): The list of files. - - Returns: - List[str]: The sorted list of files. - """ - common_substring = os.path.commonprefix(file_list) - stripped_and_converted = [ - (file.replace(common_substring, ""), file) for file in file_list - ] - stripped_and_converted.sort(key=cls.sort_key) - - return [file for _, file in stripped_and_converted] - - @property - def raw_dataframe(self) -> pl.DataFrame: - """Read a battery cycler file into a DataFrame. - - Args: - filepath (str): The path to the file. - """ - files = glob.glob(self.input_data_path) - files = self.sort_files(files) - dataframes = [self.read_file(file) for file in files] - return pl.concat(dataframes, how="vertical", rechunk=True) - @property - def processed_dataframe(self) -> pl.DataFrame: - """Process a DataFrame from battery cycler data. - - Args: - dataframe: The DataFrame to process. - - Returns: - pl.DataFrame: The dataframe in PyProBE format. - """ - dataframe = self.raw_dataframe - columns = dataframe.columns - - if dataframe.dtypes[dataframe.columns.index("Date")] != pl.Datetime: - date = pl.col("Date").str.to_datetime().alias("Date") - dataframe = dataframe.with_columns(date) - - # Time + def time(self) -> pl.DataFrame: + """Make a time column.""" time = ( - (pl.col("Date").diff().dt.total_microseconds().cum_sum() / 1e6) + ( + pl.col(self.column_dict["Date"]) + .diff() + .dt.total_microseconds() + .cum_sum() + / 1e6 + ) .fill_null(strategy="zero") .alias("Time [s]") ) - - # Cycle and step - step = pl.col("Step Index").alias("Step") - - # Measured data - column_name_pattern = r"(.+)\((.+)\)" - current = UnitConverter.search_columns( - columns, "Current", column_name_pattern, "Current" - ).to_default() - voltage = UnitConverter.search_columns( - columns, "Voltage", column_name_pattern, "Voltage" - ).to_default() - - dataframe = dataframe.with_columns(time, step, current, voltage) - - make_charge_capacity = UnitConverter.search_columns( - columns, "Chg. Cap.", column_name_pattern, "Capacity" - ).to_default(keep_name=True) - make_discharge_capacity = UnitConverter.search_columns( - columns, "DChg. Cap.", column_name_pattern, "Capacity" - ).to_default(keep_name=True) - - dataframe = dataframe.with_columns( - make_charge_capacity, make_discharge_capacity - ) - - diff_charge_capacity = ( - pl.col("Chg. Cap. [Ah]") - .diff() - .clip(lower_bound=0) - .fill_null(strategy="zero") - ) - diff_discharge_capacity = ( - pl.col("DChg. Cap. [Ah]") - .diff() - .clip(lower_bound=0) - .fill_null(strategy="zero") - ) - make_capacity = ( - (diff_charge_capacity - diff_discharge_capacity).cum_sum() - + pl.col("Chg. Cap. [Ah]").max() - ).alias("Capacity [Ah]") - - dataframe = dataframe.with_columns(make_capacity) - return dataframe + return self.imported_dataframe.select(time) diff --git a/tests/cyclers/test_basecycler.py b/tests/cyclers/test_basecycler.py deleted file mode 100644 index 2a8a9956..00000000 --- a/tests/cyclers/test_basecycler.py +++ /dev/null @@ -1,24 +0,0 @@ -"""Tests for the BaseCycler class.""" - -import polars as pl -import polars.testing as pl_testing - -from pyprobe.cyclers.basecycler import BaseCycler - - -def test_get_cycle_and_event(): - """Test the get_cycle_and_event method.""" - dataframe = pl.DataFrame( - { - "Step": [1, 2, 3, 1, 2, 3, 5, 6, 7], - } - ) - new_dataframe = BaseCycler.get_cycle_and_event(dataframe) - expected_dataframe = pl.DataFrame( - { - "Step": [1, 2, 3, 1, 2, 3, 5, 6, 7], - "Cycle": [0, 0, 0, 1, 1, 1, 1, 1, 1], - "Event": [0, 1, 2, 3, 4, 5, 6, 7, 8], - } - ) - pl_testing.assert_frame_equal(new_dataframe, expected_dataframe) diff --git a/tests/cyclers/test_biologic.py b/tests/cyclers/test_biologic.py index a8402486..0647cead 100644 --- a/tests/cyclers/test_biologic.py +++ b/tests/cyclers/test_biologic.py @@ -1,4 +1,5 @@ """Tests for the neware module.""" +from datetime import datetime import polars as pl import polars.testing as pl_testing @@ -15,7 +16,7 @@ def biologic_cycler(): def test_read_file(biologic_cycler): """Test the read_file method.""" - unprocessed_dataframe = biologic_cycler.raw_dataframe + unprocessed_dataframe = biologic_cycler.imported_dataframe assert isinstance(unprocessed_dataframe, pl.DataFrame) assert unprocessed_dataframe.columns == [ "Ns changes", @@ -51,9 +52,9 @@ def test_read_and_process(benchmark, biologic_cycler): """Test the full process of reading and processing a file.""" def read_and_process(): - return biologic_cycler.processed_dataframe + return biologic_cycler.pyprobe_dataframe - processed_dataframe = benchmark(read_and_process) + pyprobe_dataframe = benchmark(read_and_process) expected_columns = [ "Date", "Time [s]", @@ -62,16 +63,16 @@ def read_and_process(): "Voltage [V]", "Capacity [Ah]", ] - assert isinstance(processed_dataframe, pl.DataFrame) - assert all(col in processed_dataframe.columns for col in expected_columns) - processed_dataframe = processed_dataframe.with_columns( + assert isinstance(pyprobe_dataframe, pl.DataFrame) + assert all(col in pyprobe_dataframe.columns for col in expected_columns) + 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"), ] ) - assert not any(processed_dataframe.select(pl.col("dt") < 0).to_numpy()) - assert not any(processed_dataframe.select(pl.col("dd") < 0).to_numpy()) + assert not any(pyprobe_dataframe.select(pl.col("dt") < 0).to_numpy()) + assert not any(pyprobe_dataframe.select(pl.col("dd") < 0).to_numpy()) def test_process_dataframe(monkeypatch): @@ -80,7 +81,12 @@ def test_process_dataframe(monkeypatch): def mock_dataframe(self): return pl.DataFrame( { - "Date": [0, 1, 2, 3], + "Date": [ + datetime(2022, 2, 2, 2, 2, 0), + datetime(2022, 2, 2, 2, 2, 1), + datetime(2022, 2, 2, 2, 2, 2), + datetime(2022, 2, 2, 2, 2, 3), + ], "time/s": [0.0, 1.0, 2.0, 3.0], "Ns": [0, 1, 2, 3], "I/mA": [1, 2, 3, 4], @@ -91,12 +97,12 @@ def mock_dataframe(self): ) monkeypatch.setattr( - "pyprobe.cyclers.biologic.Biologic.raw_dataframe", property(mock_dataframe) + "pyprobe.cyclers.biologic.Biologic.imported_dataframe", property(mock_dataframe) ) biologic_cycler = Biologic( "tests/sample_data/biologic/Sample_data_biologic_*_MB_CA1.txt" ) - processed_dataframe = biologic_cycler.processed_dataframe.select( + pyprobe_dataframe = biologic_cycler.pyprobe_dataframe.select( ["Time [s]", "Step", "Current [A]", "Voltage [V]", "Capacity [Ah]"] ) expected_dataframe = pl.DataFrame( @@ -109,4 +115,4 @@ def mock_dataframe(self): } ) - pl_testing.assert_frame_equal(processed_dataframe, expected_dataframe) + pl_testing.assert_frame_equal(pyprobe_dataframe, expected_dataframe) diff --git a/tests/cyclers/test_neware.py b/tests/cyclers/test_neware.py index 351fa8d1..16ab2be0 100644 --- a/tests/cyclers/test_neware.py +++ b/tests/cyclers/test_neware.py @@ -41,7 +41,7 @@ def test_sort_files(neware_cycler): def test_read_multiple_files(neware_cycler): """Test the read_file method with multiple files.""" - unprocessed_dataframe = neware_cycler.raw_dataframe + unprocessed_dataframe = neware_cycler.imported_dataframe assert isinstance(unprocessed_dataframe, pl.DataFrame) @@ -49,10 +49,10 @@ def test_read_and_process(benchmark, neware_cycler): """Test the full process of reading and processing a file.""" def read_and_process(): - return neware_cycler.processed_dataframe + return neware_cycler.pyprobe_dataframe - processed_dataframe = benchmark(read_and_process) - rows = processed_dataframe.shape[0] + pyprobe_dataframe = benchmark(read_and_process) + rows = pyprobe_dataframe.shape[0] expected_columns = [ "Date", "Time [s]", @@ -61,13 +61,13 @@ def read_and_process(): "Voltage [V]", "Capacity [Ah]", ] - assert isinstance(processed_dataframe, pl.DataFrame) - all(col in processed_dataframe.columns for col in expected_columns) + assert isinstance(pyprobe_dataframe, pl.DataFrame) + all(col in pyprobe_dataframe.columns for col in expected_columns) neware_cycler = Neware("tests/sample_data/neware/sample_data_neware*.xlsx") - processed_dataframe = neware_cycler.processed_dataframe - assert processed_dataframe.shape[0] == rows * 2 - all(col in processed_dataframe.columns for col in expected_columns) + pyprobe_dataframe = neware_cycler.pyprobe_dataframe + assert pyprobe_dataframe.shape[0] == rows * 2 + all(col in pyprobe_dataframe.columns for col in expected_columns) def test_process_dataframe(monkeypatch): @@ -100,11 +100,11 @@ def mock_dataframe(self): ) monkeypatch.setattr( - "pyprobe.cyclers.neware.Neware.raw_dataframe", property(mock_dataframe) + "pyprobe.cyclers.neware.Neware.imported_dataframe", property(mock_dataframe) ) neware_cycler = Neware("tests/sample_data/neware/sample_data_neware.xlsx") - processed_dataframe = neware_cycler.processed_dataframe - processed_dataframe = processed_dataframe.select( + pyprobe_dataframe = neware_cycler.pyprobe_dataframe + pyprobe_dataframe = pyprobe_dataframe.select( [ "Time [s]", "Step", @@ -122,6 +122,4 @@ def mock_dataframe(self): "Capacity [Ah]": [20, 40, 30, 20, 20, 20], } ) - print(processed_dataframe) - print(expected_dataframe) - pl_testing.assert_frame_equal(processed_dataframe, expected_dataframe) + pl_testing.assert_frame_equal(pyprobe_dataframe, expected_dataframe)