Skip to content

Commit ab6bffe

Browse files
committed
support templated fielddata filenames SimID_SIMULATIONKEY_JOBINDEX_
1 parent 941783d commit ab6bffe

File tree

2 files changed

+137
-20
lines changed

2 files changed

+137
-20
lines changed

pyvcell/_internal/simdata/fielddata.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
from pathlib import Path
22

3-
from pyvcell._internal.simdata.simdata_models import DataFileHeader, DataFileMetadata, DataBlockHeader, VariableInfo, VariableType
3+
from pyvcell._internal.simdata.simdata_models import (
4+
DataBlockHeader,
5+
DataFileHeader,
6+
DataFileMetadata,
7+
VariableInfo,
8+
VariableType,
9+
)
10+
11+
JOBINDEX = "JOBINDEX"
12+
SIMULATIONKEY = "SIMULATIONKEY"
413

514

615
class FieldDataFileMetadata:
@@ -32,8 +41,10 @@ def file_header(self) -> DataFileHeader:
3241
return self.data_file_metadata.file_header
3342

3443

35-
def parse_fielddata_filename(file_name: str, fielddata_name: str) -> tuple[int, int, str, str, VariableType, float]:
36-
# parse filename like "SimID_286243594_0_DEMO_fieldData_Channel0_5_23_Volume.fda" into (286243594, 0, DEMO_fieldData, 5.23, 'Volume')
44+
def parse_fielddata_canonical_filename(
45+
file_name: str, fielddata_name: str
46+
) -> tuple[int, int, str, str, VariableType, float]:
47+
# parse filename like "SimID_286243594_0_DEMO_fieldData_Channel0_5_23_Volume.fdat" into (286243594, 0, DEMO_fieldData, 5.23, 'Volume')
3748
parts = file_name.split("_")
3849
sim_id = int(parts[1])
3950
job_id = int(parts[2])
@@ -46,14 +57,47 @@ def parse_fielddata_filename(file_name: str, fielddata_name: str) -> tuple[int,
4657
var_name = var_name.replace(f"SimID_{sim_id}_{job_id}_", "")
4758
var_name = var_name.replace(f"_{whole_number}_{fraction}_{var_type_name}.fdat", "")
4859
var_name = var_name.replace(f"{fielddata_name}_", "")
49-
expected_fname = f"SimID_{sim_id}_{job_id}_{fielddata_name}_{var_name}_{whole_number}_{fraction}_{var_type_name}.fdat"
60+
expected_fname = (
61+
f"SimID_{sim_id}_{job_id}_{fielddata_name}_{var_name}_{whole_number}_{fraction}_{var_type_name}.fdat"
62+
)
5063
if file_name != expected_fname:
5164
raise ValueError(f"filename {file_name} with fielddata_name {fielddata_name} does not match expected format")
5265
var_type = VariableType.from_field_data_var_type(var_type_name)
5366
return sim_id, job_id, fielddata_name, var_name, var_type, time
5467

5568

56-
def create_fielddata_filename(sim_id: int, job_id: int, fd_name: str, var_name: str, var_type: VariableType, time:float) -> str:
69+
def parse_fielddata_template_filename(file_name: str, fielddata_name: str) -> tuple[str, str, VariableType, float]:
70+
# parse filename like "SimID_SIMULATIONKEY_JOBINDEX_DEMO_fieldData_Channel0_5_23_Volume.fdat" into (286243594, 0, DEMO_fieldData, 5.23, 'Volume')
71+
parts = file_name.split("_")
72+
simkey_template = parts[1] # expecting SIMULATIONKEY
73+
jobindex_template = parts[2] # expecting JOBINDEX
74+
if simkey_template != SIMULATIONKEY or jobindex_template != JOBINDEX:
75+
raise ValueError(f"filename {file_name} does not match expected template format")
76+
var_type_name = parts[-1].split(".")[0]
77+
78+
whole_number = parts[-3]
79+
fraction = parts[-2]
80+
time = float(f"{whole_number}.{fraction}")
81+
var_name = file_name
82+
var_name = var_name.replace(f"SimID_{simkey_template}_{jobindex_template}_", "")
83+
var_name = var_name.replace(f"_{whole_number}_{fraction}_{var_type_name}.fdat", "")
84+
var_name = var_name.replace(f"{fielddata_name}_", "")
85+
expected_fname = (
86+
f"SimID_{simkey_template}_{jobindex_template}_{fielddata_name}_{var_name}_{whole_number}_{fraction}_{var_type_name}.fdat"
87+
)
88+
if file_name != expected_fname:
89+
raise ValueError(f"filename {file_name} with fielddata_name {fielddata_name} does not match expected format")
90+
var_type = VariableType.from_field_data_var_type(var_type_name)
91+
return fielddata_name, var_name, var_type, time
92+
93+
94+
def create_fielddata_canonical_filename(
95+
sim_id: int, job_id: int, fd_name: str, var_name: str, var_type: VariableType, time: float
96+
) -> str:
5797
time_str = str(time).replace(".", "_")
5898
return f"SimID_{sim_id}_{job_id}_{fd_name}_{var_name}_{time_str}_{var_type.field_data_var_type}.fdat"
5999

100+
101+
def create_fielddata_template_filename(fd_name: str, var_name: str, var_type: VariableType, time: float) -> str:
102+
time_str = str(time).replace(".", "_")
103+
return f"SimID_{SIMULATIONKEY}_{JOBINDEX}_{fd_name}_{var_name}_{time_str}_{var_type.field_data_var_type}.fdat"

tests/_internal/simdata/fielddata_test.py

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,135 @@
22

33
import pytest
44

5-
from pyvcell._internal.simdata.fielddata import FieldDataFileMetadata, create_fielddata_filename, parse_fielddata_filename
5+
from pyvcell._internal.simdata.fielddata import (
6+
FieldDataFileMetadata,
7+
create_fielddata_canonical_filename,
8+
parse_fielddata_canonical_filename,
9+
create_fielddata_template_filename,
10+
parse_fielddata_template_filename,
11+
)
612
from pyvcell._internal.simdata.simdata_models import VariableType
713

814

9-
def test_parse_fielddata_filename_good() -> None:
15+
def test_parse_fielddata_canonical_filename_good() -> None:
1016
file_name = "SimID_286243594_0_DEMO_fieldData_Channel0_5_23_Volume.fdat"
1117

1218
# "DEMO_fieldData_Channel0" is ambiguous, assume "DEMO_fieldData" is the fielddata_name
1319
fd_name = "DEMO_fieldData"
1420
expected_var_name = "Channel0"
15-
ret = parse_fielddata_filename(file_name=file_name, fielddata_name=fd_name)
21+
ret = parse_fielddata_canonical_filename(file_name=file_name, fielddata_name=fd_name)
1622
assert ret == (286243594, 0, fd_name, expected_var_name, VariableType.VOLUME, 5.23)
1723
# round trip - create filename from parsed values and compare
18-
assert file_name == create_fielddata_filename(sim_id=ret[0], job_id=ret[1], fd_name=ret[2], var_name=ret[3], var_type=ret[4], time=ret[5])
24+
assert file_name == create_fielddata_canonical_filename(
25+
sim_id=ret[0], job_id=ret[1], fd_name=ret[2], var_name=ret[3], var_type=ret[4], time=ret[5]
26+
)
1927

2028
# "DEMO_fieldData_Channel0" is ambiguous, assume "DEMO" is the fielddata_name
2129
fd_name = "DEMO"
2230
expected_var_name = "fieldData_Channel0"
23-
ret = parse_fielddata_filename(file_name=file_name, fielddata_name=fd_name)
31+
ret = parse_fielddata_canonical_filename(file_name=file_name, fielddata_name=fd_name)
2432
assert ret == (286243594, 0, fd_name, expected_var_name, VariableType.VOLUME, 5.23)
2533
# round trip - create filename from parsed values and compare
26-
assert file_name == create_fielddata_filename(sim_id=ret[0], job_id=ret[1], fd_name=ret[2], var_name=ret[3], var_type=ret[4], time=ret[5])
34+
assert file_name == create_fielddata_canonical_filename(
35+
sim_id=ret[0], job_id=ret[1], fd_name=ret[2], var_name=ret[3], var_type=ret[4], time=ret[5]
36+
)
2737

2838
# make sure integer time is parsed correctly
2939
file_name = "SimID_286243594_0_DEMO_fieldData_Channel0_5_0_Volume.fdat"
3040
# DEMO_fieldData_Channel0 is f'{fielddata_name}_{var_name}'
3141
fd_name = "DEMO_fieldData"
3242
expected_var_name = "Channel0"
33-
ret = parse_fielddata_filename(file_name=file_name, fielddata_name=fd_name)
43+
ret = parse_fielddata_canonical_filename(file_name=file_name, fielddata_name=fd_name)
3444
assert ret == (286243594, 0, fd_name, expected_var_name, VariableType.VOLUME, 5.0)
3545
# round trip - create filename from parsed values and compare
36-
assert file_name == create_fielddata_filename(sim_id=ret[0], job_id=ret[1], fd_name=ret[2], var_name=ret[3], var_type=ret[4], time=ret[5])
46+
assert file_name == create_fielddata_canonical_filename(
47+
sim_id=ret[0], job_id=ret[1], fd_name=ret[2], var_name=ret[3], var_type=ret[4], time=ret[5]
48+
)
3749

3850

39-
def test_parse_fielddata_filename_bad() -> None:
51+
def test_parse_fielddata_canonical_filename_bad() -> None:
4052
file_name = "SimID_286243594_0_DEMO_fieldData_Channel0_5_23_Volume.fdat"
4153

4254
# bad fielddata_name
4355
fd_name = "DEMO_fieldData2"
4456
with pytest.raises(ValueError) as exc:
45-
parse_fielddata_filename(file_name=file_name, fielddata_name=fd_name)
46-
assert exc.value.args[0] == f'filename {file_name} with fielddata_name {fd_name} does not match expected format'
57+
parse_fielddata_canonical_filename(file_name=file_name, fielddata_name=fd_name)
58+
assert exc.value.args[0] == f"filename {file_name} with fielddata_name {fd_name} does not match expected format"
4759

4860
# bad prefix
4961
file_name = "Sim_286243594_0_DEMO_fieldData_Channel0_5_23_Volume.fdat"
5062
fd_name = "DEMO_fieldData"
5163
with pytest.raises(ValueError) as exc:
52-
parse_fielddata_filename(file_name=file_name, fielddata_name=fd_name)
53-
assert exc.value.args[0] == f'filename {file_name} with fielddata_name {fd_name} does not match expected format'
64+
parse_fielddata_canonical_filename(file_name=file_name, fielddata_name=fd_name)
65+
assert exc.value.args[0] == f"filename {file_name} with fielddata_name {fd_name} does not match expected format"
5466

5567
# bad suffix
5668
file_name = "SimID_286243594_0_DEMO_fieldData_Channel0_5_23_Volume.fda"
5769
fd_name = "DEMO_fieldData"
5870
with pytest.raises(ValueError) as exc:
59-
parse_fielddata_filename(file_name=file_name, fielddata_name=fd_name)
60-
assert exc.value.args[0] == f'filename {file_name} with fielddata_name {fd_name} does not match expected format'
71+
parse_fielddata_canonical_filename(file_name=file_name, fielddata_name=fd_name)
72+
assert exc.value.args[0] == f"filename {file_name} with fielddata_name {fd_name} does not match expected format"
73+
74+
75+
def test_parse_fielddata_template_filename_good() -> None:
76+
file_name = "SimID_SIMULATIONKEY_JOBINDEX_DEMO_fieldData_Channel0_5_23_Volume.fdat"
77+
78+
# "DEMO_fieldData_Channel0" is ambiguous, assume "DEMO_fieldData" is the fielddata_name
79+
fd_name = "DEMO_fieldData"
80+
expected_var_name = "Channel0"
81+
ret = parse_fielddata_template_filename(file_name=file_name, fielddata_name=fd_name)
82+
assert ret == (fd_name, expected_var_name, VariableType.VOLUME, 5.23)
83+
# round trip - create filename from parsed values and compare
84+
assert file_name == create_fielddata_template_filename(
85+
fd_name=ret[0], var_name=ret[1], var_type=ret[2], time=ret[3]
86+
)
87+
88+
# "DEMO_fieldData_Channel0" is ambiguous, assume "DEMO" is the fielddata_name
89+
fd_name = "DEMO"
90+
expected_var_name = "fieldData_Channel0"
91+
ret = parse_fielddata_template_filename(file_name=file_name, fielddata_name=fd_name)
92+
assert ret == (fd_name, expected_var_name, VariableType.VOLUME, 5.23)
93+
# round trip - create filename from parsed values and compare
94+
assert file_name == create_fielddata_template_filename(
95+
fd_name=ret[0], var_name=ret[1], var_type=ret[2], time=ret[3]
96+
)
97+
98+
# make sure integer time is parsed correctly
99+
file_name = "SimID_SIMULATIONKEY_JOBINDEX_DEMO_fieldData_Channel0_5_0_Volume.fdat"
100+
# DEMO_fieldData_Channel0 is f'{fielddata_name}_{var_name}'
101+
fd_name = "DEMO_fieldData"
102+
expected_var_name = "Channel0"
103+
ret = parse_fielddata_template_filename(file_name=file_name, fielddata_name=fd_name)
104+
assert ret == (fd_name, expected_var_name, VariableType.VOLUME, 5.0)
105+
# round trip - create filename from parsed values and compare
106+
assert file_name == create_fielddata_template_filename(
107+
fd_name=ret[0], var_name=ret[1], var_type=ret[2], time=ret[3]
108+
)
109+
110+
111+
def test_parse_fielddata_template_filename_bad() -> None:
112+
file_name = "SimID_SIMULATIONKEY_JOBINDEX_DEMO_fieldData_Channel0_5_23_Volume.fdat"
113+
114+
# bad fielddata_name
115+
fd_name = "DEMO_fieldData2"
116+
with pytest.raises(ValueError) as exc:
117+
parse_fielddata_template_filename(file_name=file_name, fielddata_name=fd_name)
118+
assert exc.value.args[0] == f"filename {file_name} with fielddata_name {fd_name} does not match expected format"
119+
120+
# bad prefix
121+
file_name = "Sim_SIMULATIONKEY_JOBINDEX_DEMO_fieldData_Channel0_5_23_Volume.fdat"
122+
fd_name = "DEMO_fieldData"
123+
with pytest.raises(ValueError) as exc:
124+
parse_fielddata_template_filename(file_name=file_name, fielddata_name=fd_name)
125+
assert exc.value.args[0] == f"filename {file_name} with fielddata_name {fd_name} does not match expected format"
126+
127+
# bad suffix
128+
file_name = "SimID_SIMULATIONKEY_JOBINDEX_DEMO_fieldData_Channel0_5_23_Volume.fda"
129+
fd_name = "DEMO_fieldData"
130+
with pytest.raises(ValueError) as exc:
131+
parse_fielddata_template_filename(file_name=file_name, fielddata_name=fd_name)
132+
assert exc.value.args[0] == f"filename {file_name} with fielddata_name {fd_name} does not match expected format"
133+
61134

62135
def test_read_fielddata_file_metadata(fielddata_file_path: Path) -> None:
63136
fd_metadata = FieldDataFileMetadata(field_data_file=fielddata_file_path)

0 commit comments

Comments
 (0)