forked from BIG-MAP/ModelMapper
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathextract_validation_data.py
More file actions
132 lines (102 loc) · 3.86 KB
/
extract_validation_data.py
File metadata and controls
132 lines (102 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""Utility script to extract validation data from a BPX JSON file.
The BPX format allows an optional "Validation" section containing experimental
discharge curves (e.g. C/20 discharge, 1C discharge). This script extracts
those curves and saves each experiment as a CSV file.
Usage::
python scripts/extract_validation_data.py assets/nmc_pouch_cell_BPX.json
This will create one CSV file per experiment found in the Validation section,
named after the experiment (spaces replaced by underscores), e.g.:
nmc_pouch_cell_BPX_C_20_discharge.csv
nmc_pouch_cell_BPX_1C_discharge.csv
Each CSV contains the columns present in the experiment data, e.g.:
Time [s], Current [A], Voltage [V], Temperature [K]
Options
-------
--output-dir Directory in which to write output CSV files (default: same
directory as the input file).
--list List available experiments without writing any files.
"""
import argparse
import csv
import json
import os
import sys
def load_bpx(path):
"""Load a BPX JSON file and return the parsed dict."""
with open(path) as f:
return json.load(f)
def list_experiments(data):
"""Return the names of all experiments in the Validation section."""
validation = data.get("Validation", {})
return list(validation.keys())
def extract_experiment(data, experiment_name):
"""Return the rows (list of dicts) for a single experiment.
Parameters
----------
data : dict
Parsed BPX data.
experiment_name : str
Key inside the ``Validation`` section.
Returns
-------
list[dict]
List of row dicts with column names as keys.
"""
experiment = data["Validation"][experiment_name]
columns = list(experiment.keys())
n_rows = len(experiment[columns[0]])
rows = []
for i in range(n_rows):
row = {col: experiment[col][i] for col in columns}
rows.append(row)
return rows, columns
def safe_filename(name):
"""Convert an experiment name to a safe filename fragment."""
return name.replace("/", "_").replace(" ", "_").replace("\\", "_")
def write_csv(rows, columns, path):
"""Write rows to a CSV file."""
with open(path, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=columns)
writer.writeheader()
writer.writerows(rows)
def main(argv=None):
parser = argparse.ArgumentParser(
description="Extract validation data from a BPX JSON file into CSV files."
)
parser.add_argument("bpx_file", help="Path to the BPX JSON file.")
parser.add_argument(
"--output-dir",
default=None,
help="Directory for output CSV files (default: same directory as input file).",
)
parser.add_argument(
"--list",
action="store_true",
help="List available experiments and exit without writing files.",
)
args = parser.parse_args(argv)
bpx_path = args.bpx_file
if not os.path.isfile(bpx_path):
print(f"Error: file not found: {bpx_path}", file=sys.stderr)
sys.exit(1)
data = load_bpx(bpx_path)
experiments = list_experiments(data)
if not experiments:
print("No Validation section found in the BPX file.", file=sys.stderr)
sys.exit(0)
if args.list:
print("Available experiments:")
for name in experiments:
print(f" {name}")
return
output_dir = args.output_dir or os.path.dirname(os.path.abspath(bpx_path))
os.makedirs(output_dir, exist_ok=True)
base = os.path.splitext(os.path.basename(bpx_path))[0]
for experiment_name in experiments:
rows, columns = extract_experiment(data, experiment_name)
out_name = f"{base}_{safe_filename(experiment_name)}.csv"
out_path = os.path.join(output_dir, out_name)
write_csv(rows, columns, out_path)
print(f"Wrote {len(rows)} rows to {out_path}")
if __name__ == "__main__":
main()