PyDPEET 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. pydpeet/__init__.py +56 -0
  2. pydpeet/citations/__init__.py +7 -0
  3. pydpeet/citations/citeme.py +397 -0
  4. pydpeet/citations/html_writer.py +137 -0
  5. pydpeet/dev_utils/__init__.py +7 -0
  6. pydpeet/dev_utils/generate_inits/__init__.py +7 -0
  7. pydpeet/dev_utils/generate_inits/generate_inits.py +327 -0
  8. pydpeet/io/__init__.py +7 -0
  9. pydpeet/io/configs/__init__.py +7 -0
  10. pydpeet/io/configs/config.py +227 -0
  11. pydpeet/io/configs/const.py +1 -0
  12. pydpeet/io/convert.py +594 -0
  13. pydpeet/io/device/__init__.py +7 -0
  14. pydpeet/io/device/arbin_4_23_PV090331/__init__.py +7 -0
  15. pydpeet/io/device/arbin_4_23_PV090331/formatter.py +22 -0
  16. pydpeet/io/device/arbin_4_23_PV090331/mapper.py +18 -0
  17. pydpeet/io/device/arbin_4_23_PV090331/reader.py +68 -0
  18. pydpeet/io/device/arbin_8_00_PV221201/__init__.py +7 -0
  19. pydpeet/io/device/arbin_8_00_PV221201/formatter.py +26 -0
  20. pydpeet/io/device/arbin_8_00_PV221201/mapper.py +18 -0
  21. pydpeet/io/device/arbin_8_00_PV221201/reader.py +66 -0
  22. pydpeet/io/device/basytec_6_3_1_0/__init__.py +7 -0
  23. pydpeet/io/device/basytec_6_3_1_0/formatter.py +18 -0
  24. pydpeet/io/device/basytec_6_3_1_0/mapper.py +18 -0
  25. pydpeet/io/device/basytec_6_3_1_0/reader.py +54 -0
  26. pydpeet/io/device/digatron_4_20_6_236/__init__.py +7 -0
  27. pydpeet/io/device/digatron_4_20_6_236/formatter.py +27 -0
  28. pydpeet/io/device/digatron_4_20_6_236/mapper.py +18 -0
  29. pydpeet/io/device/digatron_4_20_6_236/reader.py +45 -0
  30. pydpeet/io/device/digatron_eis_4_20_6_236/__init__.py +7 -0
  31. pydpeet/io/device/digatron_eis_4_20_6_236/formatter.py +39 -0
  32. pydpeet/io/device/digatron_eis_4_20_6_236/mapper.py +18 -0
  33. pydpeet/io/device/digatron_eis_4_20_6_236/reader.py +42 -0
  34. pydpeet/io/device/neware_8_0_0_516/__init__.py +7 -0
  35. pydpeet/io/device/neware_8_0_0_516/formatter.py +31 -0
  36. pydpeet/io/device/neware_8_0_0_516/mapper.py +18 -0
  37. pydpeet/io/device/neware_8_0_0_516/reader.py +397 -0
  38. pydpeet/io/device/parstat_2_63_3/__init__.py +7 -0
  39. pydpeet/io/device/parstat_2_63_3/formatter.py +34 -0
  40. pydpeet/io/device/parstat_2_63_3/mapper.py +18 -0
  41. pydpeet/io/device/parstat_2_63_3/reader.py +34 -0
  42. pydpeet/io/device/safion_1_9/__init__.py +7 -0
  43. pydpeet/io/device/safion_1_9/formatter.py +25 -0
  44. pydpeet/io/device/safion_1_9/mapper.py +18 -0
  45. pydpeet/io/device/safion_1_9/reader.py +89 -0
  46. pydpeet/io/device/zahner/__init__.py +7 -0
  47. pydpeet/io/device/zahner/formatter.py +73 -0
  48. pydpeet/io/device/zahner/mapper.py +34 -0
  49. pydpeet/io/device/zahner/reader.py +46 -0
  50. pydpeet/io/device/zahner_new/__init__.py +7 -0
  51. pydpeet/io/device/zahner_new/formatter.py +72 -0
  52. pydpeet/io/device/zahner_new/mapper.py +50 -0
  53. pydpeet/io/device/zahner_new/reader.py +46 -0
  54. pydpeet/io/map.py +69 -0
  55. pydpeet/io/read.py +50 -0
  56. pydpeet/io/utils/__init__.py +7 -0
  57. pydpeet/io/utils/ext_path.py +34 -0
  58. pydpeet/io/utils/formatter_utils.py +429 -0
  59. pydpeet/io/utils/load_custom_module.py +33 -0
  60. pydpeet/io/utils/timing.py +36 -0
  61. pydpeet/io/write.py +99 -0
  62. pydpeet/process/__init__.py +7 -0
  63. pydpeet/process/analyze/__init__.py +7 -0
  64. pydpeet/process/analyze/average.py +297 -0
  65. pydpeet/process/analyze/capacity.py +208 -0
  66. pydpeet/process/analyze/configs/__init__.py +7 -0
  67. pydpeet/process/analyze/configs/battery_config.py +38 -0
  68. pydpeet/process/analyze/configs/ocv_config.py +177 -0
  69. pydpeet/process/analyze/configs/step_analyzer_config.py +178 -0
  70. pydpeet/process/analyze/cycle.py +63 -0
  71. pydpeet/process/analyze/efficiency.py +182 -0
  72. pydpeet/process/analyze/energy.py +51 -0
  73. pydpeet/process/analyze/extract/__init__.py +7 -0
  74. pydpeet/process/analyze/extract/dva_ica.py +224 -0
  75. pydpeet/process/analyze/extract/ocv.py +196 -0
  76. pydpeet/process/analyze/power.py +32 -0
  77. pydpeet/process/analyze/resistance.py +87 -0
  78. pydpeet/process/analyze/soc.py +418 -0
  79. pydpeet/process/analyze/soh.py +72 -0
  80. pydpeet/process/analyze/utils.py +122 -0
  81. pydpeet/process/merge/__init__.py +7 -0
  82. pydpeet/process/merge/series.py +274 -0
  83. pydpeet/process/sequence/__init__.py +7 -0
  84. pydpeet/process/sequence/configs/__init__.py +7 -0
  85. pydpeet/process/sequence/configs/config.py +17 -0
  86. pydpeet/process/sequence/step_analyzer.py +440 -0
  87. pydpeet/process/sequence/utils/__init__.py +7 -0
  88. pydpeet/process/sequence/utils/annotate/__init__.py +7 -0
  89. pydpeet/process/sequence/utils/annotate/annotate_primitives.py +419 -0
  90. pydpeet/process/sequence/utils/configs/CONFIG_Fallback.py +231 -0
  91. pydpeet/process/sequence/utils/configs/CONFIG_preprocessing.py +243 -0
  92. pydpeet/process/sequence/utils/configs/__init__.py +7 -0
  93. pydpeet/process/sequence/utils/console_prints/__init__.py +7 -0
  94. pydpeet/process/sequence/utils/console_prints/log_time.py +30 -0
  95. pydpeet/process/sequence/utils/postprocessing/__init__.py +7 -0
  96. pydpeet/process/sequence/utils/postprocessing/df_primitives_correction.py +166 -0
  97. pydpeet/process/sequence/utils/postprocessing/filter_df.py +168 -0
  98. pydpeet/process/sequence/utils/postprocessing/generate_instructions.py +297 -0
  99. pydpeet/process/sequence/utils/preprocessing/__init__.py +7 -0
  100. pydpeet/process/sequence/utils/preprocessing/calculate_thresholds.py +27 -0
  101. pydpeet/process/sequence/utils/processing/__init__.py +7 -0
  102. pydpeet/process/sequence/utils/processing/analyze_segments.py +368 -0
  103. pydpeet/process/sequence/utils/processing/attempt_to_merge_neighboring_segments.py +122 -0
  104. pydpeet/process/sequence/utils/processing/check_CV_results.py +226 -0
  105. pydpeet/process/sequence/utils/processing/check_power_zero_watt_segments.py +85 -0
  106. pydpeet/process/sequence/utils/processing/check_zero_length.py +117 -0
  107. pydpeet/process/sequence/utils/processing/split_in_segments.py +97 -0
  108. pydpeet/process/sequence/utils/processing/supress_smaller_segments.py +99 -0
  109. pydpeet/process/sequence/utils/processing/widen_constant_segments.py +185 -0
  110. pydpeet/process/sequence/utils/visualize/__init__.py +7 -0
  111. pydpeet/process/sequence/utils/visualize/visualize_data.py +288 -0
  112. pydpeet/res/__init__.py +7 -0
  113. pydpeet/settings.py +0 -0
  114. pydpeet/utils/__init__.py +7 -0
  115. pydpeet/utils/logging_style.py +28 -0
  116. pydpeet/version.py +0 -0
  117. pydpeet-0.2.0.dist-info/METADATA +85 -0
  118. pydpeet-0.2.0.dist-info/RECORD +122 -0
  119. pydpeet-0.2.0.dist-info/WHEEL +5 -0
  120. pydpeet-0.2.0.dist-info/licenses/AUTHORS.md +0 -0
  121. pydpeet-0.2.0.dist-info/licenses/LICENCE.md +27 -0
  122. pydpeet-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,68 @@
1
+ import pandas as pd
2
+
3
+ from pydpeet.io.configs.const import PANDAS_EXCEL_ENGINE
4
+
5
+
6
+ def to_dataframe(input_path: str) -> tuple[pd.DataFrame, str]:
7
+ """
8
+ Parses the input file from the Arbin Old Cycler into a pandas DataFrame.
9
+
10
+ Parameters:
11
+ input_path (str): Path to the input file.
12
+
13
+ Returns:
14
+ (pandas.DataFrame, str): A tuple containing the DataFrame with data and metadata as a string.
15
+ """
16
+ # load Excel data
17
+ excel_data = pd.ExcelFile(input_path, engine=PANDAS_EXCEL_ENGINE)
18
+
19
+ return read_sheets(excel_data)
20
+
21
+
22
+ def read_sheets(excel_file: pd.ExcelFile) -> tuple[pd.DataFrame, str]:
23
+ # variables for the dataframe and String
24
+ """
25
+ Reads data from all sheets in an Excel file and returns them as a tuple of a DataFrame and a string.
26
+
27
+ The first sheet that starts with "Channel" is used as the main data sheet. If there are more sheets with this name,
28
+ they are appended to the first sheet.
29
+
30
+ All sheets named "Info" are concatenated into a single string as metadata.
31
+
32
+ Parameters:
33
+ excel_file (pd.ExcelFile): The Excel file to read from.
34
+
35
+ Returns:
36
+ (pd.DataFrame, str): A tuple containing the DataFrame with data and metadata as a string.
37
+ """
38
+ arbin_df = None
39
+ metadata_str = []
40
+ iterator = 0
41
+
42
+ # iterate all sheets
43
+ for sheet_name in excel_file.sheet_names:
44
+ # find sheet that starts with "Channel"
45
+ if sheet_name.startswith("Channel"):
46
+ # if it´s the first sheet, that starts with the channel, it gets added to df
47
+ if iterator == 0:
48
+ arbin_df = excel_file.parse(sheet_name, header=0)
49
+ # if it´s the second or higher Sheet, it will be appended without the header and the first row,
50
+ # because first row of 2nd sheet and last row of first sheet are the same
51
+ else:
52
+ # get Data from further Sheet(s)
53
+ # remove the first two rows (header and multiple row)
54
+ further_sheet_data = excel_file.parse(sheet_name, header=0).iloc[1:]
55
+ # concat both sheets into one
56
+ arbin_df = pd.concat([arbin_df, further_sheet_data], ignore_index=True)
57
+ iterator += 1
58
+ # combine all other sheets into a string as metadata
59
+ elif sheet_name.startswith("Info"):
60
+ # only metadata sheet in arbin Old is called "Info"
61
+ sheet_data = excel_file.parse(sheet_name, header=None) # no header
62
+ sheet_str = f"Sheet: {sheet_name}\n{sheet_data.to_string(index=False, header=False)}"
63
+ metadata_str.append(sheet_str)
64
+
65
+ # combine all metadata sheets into one string
66
+ metadata_str_combined = "\n\n".join(metadata_str)
67
+
68
+ return arbin_df, metadata_str_combined
@@ -0,0 +1,7 @@
1
+ """
2
+ Auto-generated __init__ file.
3
+ Created: 2026-03-06 15:11:49
4
+ """
5
+
6
+ # Restrictive package init: start with no public API
7
+ __all__ = []
@@ -0,0 +1,26 @@
1
+ import pandas as pd
2
+
3
+ from pydpeet.io.utils.formatter_utils import (
4
+ absolute_time_timedate_typecast,
5
+ testtime_hours_to_seconds_with_string_interpretation,
6
+ )
7
+
8
+
9
+ def get_data_into_format(df: pd.DataFrame) -> pd.DataFrame:
10
+ """
11
+ Format the given DataFrame into a standard format.
12
+
13
+ Parameters
14
+ ----------
15
+ data_frame : pandas.DataFrame
16
+ The DataFrame to be formatted
17
+
18
+ Returns
19
+ -------
20
+ pandas.DataFrame
21
+ The formatted DataFrame
22
+ """
23
+ df = testtime_hours_to_seconds_with_string_interpretation(df, True)
24
+ df = absolute_time_timedate_typecast(df)
25
+
26
+ return df
@@ -0,0 +1,18 @@
1
+ # Map raw-data column names (left) to standardized column names (right)
2
+ COLUMN_MAP = {
3
+ "Record number": "Step_Count",
4
+ "Voltage(V)": "Voltage[V]",
5
+ "Current(A)": "Current[A]",
6
+ "Relative Time(h:min:s.ms)": "Test_Time[s]",
7
+ "Real Time(h:min:s.ms)": "Date_Time",
8
+ }
9
+
10
+ # Default columns of the standardized format
11
+ # which are not present in the raw data files.
12
+ MISSING_REQUIRED_COLUMNS = [
13
+ "Temperature[°C]",
14
+ "EIS_f[Hz]",
15
+ "EIS_Z_Real[Ohm]",
16
+ "EIS_Z_Imag[Ohm]",
17
+ "EIS_DC[A]",
18
+ ]
@@ -0,0 +1,66 @@
1
+ import pandas as pd
2
+
3
+ from pydpeet.io.configs.const import PANDAS_EXCEL_ENGINE
4
+
5
+
6
+ def to_dataframe(input_path: str) -> tuple[pd.DataFrame, str]:
7
+ """
8
+ Parses the input file from the Arbin Cycler into a pandas DataFrame.
9
+
10
+ Parameters:
11
+ input_path (str): Path to the input file.
12
+
13
+ Returns:
14
+ (pandas.DataFrame, str): A tuple containing the DataFrame with data and metadata as a string.
15
+ """
16
+ # load Excel data
17
+ excel_data = pd.ExcelFile(input_path, engine=PANDAS_EXCEL_ENGINE)
18
+
19
+ return read_sheets(excel_data)
20
+
21
+
22
+ def read_sheets(excel_file: pd.ExcelFile) -> tuple[pd.DataFrame, str]:
23
+ """
24
+ Reads data from all sheets in an Excel file and returns them as a tuple of a DataFrame and a string.
25
+
26
+ The first sheet that starts with "Detail" is used as the main data sheet. If there are more sheets with this name,
27
+ they are appended to the first sheet.
28
+
29
+ All other sheets are concatenated into a single string as metadata.
30
+
31
+ Parameters:
32
+ excel_file (pd.ExcelFile): The Excel file to read from.
33
+
34
+ Returns:
35
+ (pd.DataFrame, str): A tuple containing the DataFrame with data and metadata as a string.
36
+ """
37
+ # variables for the dataframe and String
38
+ arbin_df = None
39
+ metadata_str = []
40
+ iterator = 0
41
+
42
+ # iterate all sheets
43
+ for sheet_name in excel_file.sheet_names:
44
+ # find sheet that starts with "Detail"
45
+ if sheet_name.startswith("Detail"):
46
+ # if it´s the first sheet, that starts with the channel, it gets added to df
47
+ if iterator == 0:
48
+ arbin_df = excel_file.parse(sheet_name, header=0)
49
+ # if it´s the second or higher Sheet, it will be appended without the header and the first row,
50
+ # because first row of 2nd sheet and last row of first sheet are the same
51
+ else:
52
+ # get Data from further Sheet(s)
53
+ # remove the first two rows (header and multiple row)
54
+ further_sheet_data = excel_file.parse(sheet_name, header=0).iloc[1:]
55
+ # concat bot sheets into one
56
+ arbin_df = pd.concat([arbin_df, further_sheet_data])
57
+ iterator += 1
58
+ else: # combine all other sheets into a string as metadata
59
+ sheet_data = excel_file.parse(sheet_name, header=None) # no header
60
+ sheet_str = f"Sheet: {sheet_name}\n{sheet_data.to_string(index=False, header=False)}"
61
+ metadata_str.append(sheet_str)
62
+
63
+ # combine all metadata sheets into one string
64
+ metadata_str_combined = "\n\n".join(metadata_str)
65
+
66
+ return arbin_df, metadata_str_combined
@@ -0,0 +1,7 @@
1
+ """
2
+ Auto-generated __init__ file.
3
+ Created: 2026-03-06 15:11:49
4
+ """
5
+
6
+ # Restrictive package init: start with no public API
7
+ __all__ = []
@@ -0,0 +1,18 @@
1
+ import pandas as pd
2
+
3
+ from pydpeet.io.utils.formatter_utils import round_testtime, testtime_hours_to_seconds_direct
4
+
5
+
6
+ def get_data_into_format(df: pd.DataFrame) -> pd.DataFrame:
7
+ """
8
+ Takes a pandas DataFrame and applies two functions to it:
9
+
10
+ 1. `testtime_hours_to_seconds_direct`: converts the "Test_Time[s]" column from hours to seconds with string interpretation.
11
+ 2. `round_testtime`: rounds the "Test_Time[s]" column down to the nearest second.
12
+
13
+ Returns the modified DataFrame.
14
+ """
15
+ df = testtime_hours_to_seconds_direct(df)
16
+ df = round_testtime(df)
17
+
18
+ return df
@@ -0,0 +1,18 @@
1
+ # Map raw-data column names (left) to standardized column names (right)
2
+ COLUMN_MAP = {
3
+ "Time[h]": "Test_Time[s]",
4
+ "U[V]": "Voltage[V]",
5
+ "I[A]": "Current[A]",
6
+ "T1[°C]": "Temperature[°C]",
7
+ "Line": "Step_Count",
8
+ }
9
+
10
+ # Default columns of the standardized format
11
+ # which are not present in the raw data files.
12
+ MISSING_REQUIRED_COLUMNS = [
13
+ "Date_Time",
14
+ "EIS_f[Hz]",
15
+ "EIS_Z_Real[Ohm]",
16
+ "EIS_Z_Imag[Ohm]",
17
+ "EIS_DC[A]",
18
+ ]
@@ -0,0 +1,54 @@
1
+ import logging
2
+ from io import StringIO
3
+
4
+ import pandas as pd
5
+
6
+
7
+ def to_dataframe(input_path: str) -> tuple[pd.DataFrame, str]:
8
+ """
9
+ Parses the input file from the basytec cycler into a pandas DataFrame.
10
+ It first converts the data portion to CSV format in memory.
11
+
12
+ Parameters:
13
+ input_path (str): Path to the input file.
14
+
15
+ Returns:
16
+ (pd.DataFrame, str): A tuple containing the DataFrame with the data and metadata as a string.
17
+ """
18
+ with open(input_path, encoding="iso-8859-1") as file:
19
+ lines = file.readlines()
20
+
21
+ # Collect all metadata lines (those starting with '~')
22
+ metadata_lines = []
23
+ data_start_idx = 0
24
+ for idx, line in enumerate(lines):
25
+ if line.startswith("~"):
26
+ metadata_lines.append(line.strip())
27
+ else:
28
+ data_start_idx = idx
29
+ break
30
+
31
+ if not metadata_lines:
32
+ logging.warning("The file does not contain expected metadata lines starting with '~'.")
33
+
34
+ # The last metadata line is used as the header; remove it from metadata_lines.
35
+ header_line = metadata_lines.pop().lstrip("~").strip()
36
+ headers = header_line.split()
37
+
38
+ # Join the remaining metadata lines into a single string.
39
+ metadata_str = "\n".join(metadata_lines)
40
+
41
+ # Convert the remaining data lines into CSV format.
42
+ csv_lines = [",".join(headers)] # CSV header
43
+ for line in lines[data_start_idx:]:
44
+ line = line.strip()
45
+ if line: # Skip empty lines.
46
+ # Split on whitespace then join with commas.
47
+ csv_lines.append(",".join(line.split()))
48
+
49
+ csv_content = "\n".join(csv_lines)
50
+
51
+ # Use StringIO to read the CSV content into a DataFrame.
52
+ df = pd.read_csv(StringIO(csv_content))
53
+
54
+ return df, metadata_str
@@ -0,0 +1,7 @@
1
+ """
2
+ Auto-generated __init__ file.
3
+ Created: 2026-03-06 15:11:49
4
+ """
5
+
6
+ # Restrictive package init: start with no public API
7
+ __all__ = []
@@ -0,0 +1,27 @@
1
+ import pandas as pd
2
+
3
+ from pydpeet.io.utils.formatter_utils import absolute_time_timedate_typecast, fix_time_format
4
+
5
+
6
+ def get_data_into_format(df: pd.DataFrame) -> pd.DataFrame:
7
+ """
8
+ Applies a series of transformations to the input DataFrame to
9
+ ensure that the "Date_Time" column is in the correct
10
+ datetime format. The time format is initially fixed using the specified
11
+ input format, and then typecast to pandas datetime objects.
12
+
13
+ Parameters
14
+ ----------
15
+ data_frame : pd.DataFrame
16
+ The DataFrame to be formatted.
17
+
18
+ Returns
19
+ -------
20
+ pd.DataFrame
21
+ The formatted DataFrame with the "Date_Time"
22
+ column converted to datetime objects.
23
+ """
24
+ fix_time_format(df, input_format="%d.%m.%Y %H:%M:%S")
25
+ absolute_time_timedate_typecast(df)
26
+
27
+ return df
@@ -0,0 +1,18 @@
1
+ # Map raw-data column names (left) to standardized column names (right)
2
+ COLUMN_MAP = {
3
+ "Schritt Zeit": "Test_Time[s]",
4
+ "Spannung": "Voltage[V]",
5
+ "Strom": "Current[A]",
6
+ "Schritt Nr.": "Step_Count",
7
+ "Zeitstempel": "Date_Time",
8
+ "T_Batt": "Temperature[°C]",
9
+ }
10
+
11
+ # Default columns of the standardized format
12
+ # which are not present in the raw data files.
13
+ MISSING_REQUIRED_COLUMNS = [
14
+ "EIS_f[Hz]",
15
+ "EIS_Z_Real[Ohm]",
16
+ "EIS_Z_Imag[Ohm]",
17
+ "EIS_DC[A]",
18
+ ]
@@ -0,0 +1,45 @@
1
+ import pandas as pd
2
+
3
+
4
+ def to_dataframe(input_path: str) -> tuple[pd.DataFrame, str]:
5
+ """
6
+ Parses the input file from the Digatron Cycler into a pandas DataFrame.
7
+
8
+ Parameters:
9
+ input_path (str): Path to the input file.
10
+
11
+ Returns:
12
+ (pandas.DataFrame, str): A tuple containing the DataFrame with data and metadata as a string.
13
+ """
14
+ metadata = []
15
+
16
+ # Open the file and process lines
17
+ with open(input_path, encoding="us-ascii") as file:
18
+ # Read metadata until the header line is found
19
+ line = file.readline()
20
+ while not line.startswith("Zeitstempel"):
21
+ metadata.append(line.strip())
22
+ line = file.readline()
23
+
24
+ # Extract headers and remaining data
25
+ headers = line.strip().split(";")
26
+ data_lines = [row.strip().split(";") for row in file if row.strip()]
27
+
28
+ # appending first string from datalines
29
+ metadata.append(";".join(data_lines.pop(0)))
30
+
31
+ # Join metadata into a single string
32
+ metadata_str = "\n".join(metadata)
33
+
34
+ # Create DataFrame
35
+ df = pd.DataFrame(data_lines, columns=headers)
36
+
37
+ # Convert numeric columns to appropriate types
38
+ for col in headers:
39
+ try:
40
+ df[col] = pd.to_numeric(df[col])
41
+ except ValueError:
42
+ # Leave non-numeric columns as is
43
+ pass
44
+
45
+ return df, metadata_str
@@ -0,0 +1,7 @@
1
+ """
2
+ Auto-generated __init__ file.
3
+ Created: 2026-03-06 15:11:49
4
+ """
5
+
6
+ # Restrictive package init: start with no public API
7
+ __all__ = []
@@ -0,0 +1,39 @@
1
+ import pandas as pd
2
+
3
+ from pydpeet.io.utils.formatter_utils import (
4
+ absolute_time_timedate_typecast,
5
+ apply_convert_to_float_if_possible,
6
+ move_strings_from_column_to_metadata,
7
+ nan_to_none_in_column,
8
+ replace_empty_with_none_in_standard_columns,
9
+ round_testtime,
10
+ typecast,
11
+ )
12
+
13
+
14
+ def get_data_into_format(df: pd.DataFrame) -> pd.DataFrame:
15
+ """
16
+ Format the given DataFrame into a standard format.
17
+
18
+ Parameters
19
+ ----------
20
+ data_frame : pandas.DataFrame
21
+ The DataFrame to be formatted
22
+
23
+ Returns
24
+ -------
25
+ pandas.DataFrame
26
+ The formatted DataFrame
27
+ """
28
+ df = replace_empty_with_none_in_standard_columns(df)
29
+ typecast(df, "Step_Count", int)
30
+ df = apply_convert_to_float_if_possible(df, "Voltage[V]")
31
+ df = apply_convert_to_float_if_possible(df, "Current[A]")
32
+ df = round_testtime(df)
33
+ df = absolute_time_timedate_typecast(df)
34
+ typecast(df, "EIS_Z_Real[Ohm]", float)
35
+ typecast(df, "EIS_Z_Imag[Ohm]", float)
36
+ df = nan_to_none_in_column(df, "Current[A]")
37
+ df = move_strings_from_column_to_metadata(df, "Voltage[V]")
38
+
39
+ return df
@@ -0,0 +1,18 @@
1
+ # Map raw-data column names (left) to standardized column names (right)
2
+ COLUMN_MAP = {
3
+ "Zreal1": "EIS_Z_Real[Ohm]",
4
+ "Zimg1": "EIS_Z_Imag[Ohm]",
5
+ "Zeitstempel": "Date_Time",
6
+ "Schritt Nr.": "Step_Count",
7
+ "Spannung": "Voltage[V]",
8
+ "Strom": "Current[A]",
9
+ "Progr. Zeit": "Test_Time[s]",
10
+ }
11
+
12
+ # Default columns of the standardized format
13
+ # which are not present in the raw data files.
14
+ MISSING_REQUIRED_COLUMNS = [
15
+ "Temperature[°C]",
16
+ "EIS_f[Hz]",
17
+ "EIS_DC[A]",
18
+ ]
@@ -0,0 +1,42 @@
1
+ import pandas as pd
2
+
3
+
4
+ def to_dataframe(input_path: str) -> tuple[pd.DataFrame, str]:
5
+ """
6
+ Parses the input file from the Digatron Cycler into a pandas DataFrame.
7
+
8
+ Parameters:
9
+ input_path (str): Path to the input file.
10
+
11
+ Returns:
12
+ (pandas.DataFrame, str): A tuple containing the DataFrame with data and metadata as a string.
13
+ """
14
+ metadata = []
15
+
16
+ # Open the file and process lines
17
+ with open(input_path, encoding="iso-8859-1") as file:
18
+ # Read metadata until the header line is found
19
+ line = file.readline()
20
+ while not line.startswith("Zeitstempel"):
21
+ metadata.append(line.strip())
22
+ line = file.readline()
23
+
24
+ # Extract headers and remaining data
25
+ headers = line.strip().split(",")
26
+ # TODO: Why is this still here?
27
+ # for i in range(4):
28
+ # line = file.readline()
29
+ # metadata.append(line.strip())
30
+
31
+ data_lines = [row.strip().split(",") for row in file if row.strip()]
32
+
33
+ # appending first string from datalines
34
+ metadata.append(";".join(data_lines.pop(0)))
35
+
36
+ # Join metadata into a single string
37
+ metadata_str = "\n".join(metadata)
38
+
39
+ # Create DataFrame
40
+ df = pd.DataFrame(data_lines, columns=headers)
41
+
42
+ return df, metadata_str
@@ -0,0 +1,7 @@
1
+ """
2
+ Auto-generated __init__ file.
3
+ Created: 2026-03-06 15:11:49
4
+ """
5
+
6
+ # Restrictive package init: start with no public API
7
+ __all__ = []
@@ -0,0 +1,31 @@
1
+ import pandas as pd
2
+
3
+ from pydpeet.io.utils.formatter_utils import (
4
+ absolute_time_timedate_typecast,
5
+ testtime_hours_to_seconds_with_string_interpretation,
6
+ typecast,
7
+ )
8
+
9
+
10
+ def get_data_into_format(df: pd.DataFrame) -> pd.DataFrame:
11
+ """
12
+ Format a DataFrame from a Neware cycler into a standard format.
13
+
14
+ The DataFrame is modified in-place.
15
+
16
+ Parameters
17
+ ----------
18
+ data_frame : pd.DataFrame
19
+ DataFrame to be formatted
20
+
21
+ Returns
22
+ -------
23
+ pd.DataFrame
24
+ Formatted DataFrame
25
+ """
26
+ testtime_hours_to_seconds_with_string_interpretation(df, True)
27
+ df = absolute_time_timedate_typecast(df)
28
+ typecast(df, "Step_Count", int)
29
+ typecast(df, "Temperature[°C]", float)
30
+
31
+ return df
@@ -0,0 +1,18 @@
1
+ # Map raw-data column names (left) to standardized column names (right)
2
+ COLUMN_MAP = {
3
+ "step_id": "Step_Count",
4
+ "Voltage(V)": "Voltage[V]",
5
+ "Current[A] - record": "Current[A]",
6
+ "T1": "Temperature[°C]",
7
+ "Total Time": "Test_Time[s]",
8
+ "Date": "Date_Time",
9
+ }
10
+
11
+ # Default columns of the standardized format
12
+ # which are not present in the raw data files.
13
+ MISSING_REQUIRED_COLUMNS = [
14
+ "EIS_f[Hz]",
15
+ "EIS_Z_Real[Ohm]",
16
+ "EIS_Z_Imag[Ohm]",
17
+ "EIS_DC[A]",
18
+ ]