Skip to content

Commit c5667d8

Browse files
committed
upconversion
1 parent bcf1baa commit c5667d8

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

petab/v2/petab1to2.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,23 @@ def petab_files_1to2(yaml_config: Path | str, output_dir: Path | str):
104104
# sub-problems
105105
for problem_config in new_yaml_config.problems:
106106
# copy files that don't need conversion
107-
# (models, observables, visualizations)
107+
# (models, visualizations)
108108
for file in chain(
109-
problem_config.observable_files,
110109
(model.location for model in problem_config.model_files.values()),
111110
problem_config.visualization_files,
112111
):
113112
_copy_file(get_src_path(file), Path(get_dest_path(file)))
114113

114+
# Update observable table
115+
for observable_file in problem_config.observable_files:
116+
observable_df = v1.get_observable_df(get_src_path(observable_file))
117+
observable_df = v1v2_observable_df(
118+
observable_df,
119+
)
120+
v2.write_observable_df(
121+
observable_df, get_dest_path(observable_file)
122+
)
123+
115124
# Update condition table
116125
for condition_file in problem_config.condition_files:
117126
condition_df = v1.get_condition_df(get_src_path(condition_file))
@@ -339,3 +348,48 @@ def v1v2_condition_df(
339348
)
340349

341350
return condition_df
351+
352+
353+
def v1v2_observable_df(observable_df: pd.DataFrame) -> pd.DataFrame:
354+
"""Convert observable table from petab v1 to v2.
355+
356+
Perform all updates that can be done solely on the observable table:
357+
* drop observableTransformation, update noiseDistribution
358+
"""
359+
df = observable_df.copy().reset_index()
360+
361+
# drop observableTransformation, update noiseDistribution
362+
# if there is no observableTransformation, no need to update
363+
if v1.C.OBSERVABLE_TRANSFORMATION in df.columns:
364+
df[v1.C.OBSERVABLE_TRANSFORMATION] = df[
365+
v1.C.OBSERVABLE_TRANSFORMATION
366+
].fillna(v1.C.LIN)
367+
368+
if v1.C.NOISE_DISTRIBUTION in df:
369+
df[v1.C.NOISE_DISTRIBUTION] = df[v1.C.NOISE_DISTRIBUTION].fillna(
370+
v1.C.NORMAL
371+
)
372+
else:
373+
df[v1.C.NOISE_DISTRIBUTION] = v1.C.NORMAL
374+
375+
# merge observableTransformation into noiseDistribution
376+
def update_noise_dist(row):
377+
dist = row.get(v1.C.NOISE_DISTRIBUTION)
378+
trans = row.get(v1.C.OBSERVABLE_TRANSFORMATION)
379+
380+
if trans == v1.C.LIN:
381+
new_dist = dist
382+
else:
383+
new_dist = f"{trans}-{dist}"
384+
385+
if new_dist not in v2.C.NOISE_DISTRIBUTIONS:
386+
raise NotImplementedError(
387+
f"Noise distribution `{new_dist}' for "
388+
f"observable `{row[v1.C.OBSERVABLE_ID]}'"
389+
f" is not supported in PEtab v2."
390+
)
391+
392+
df[v2.C.NOISE_DISTRIBUTION] = df.apply(update_noise_dist, axis=1)
393+
df.drop(columns=[v1.C.OBSERVABLE_TRANSFORMATION], inplace=True)
394+
395+
return df

tests/v2/test_conversion.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ def test_benchmark_collection(problem_id):
4040
pytest.skip("Too slow. Re-enable once we are faster.")
4141

4242
yaml_path = benchmark_models_petab.get_problem_yaml_path(problem_id)
43-
problem = petab1to2(yaml_path)
43+
try:
44+
problem = petab1to2(yaml_path)
45+
except NotImplementedError as e:
46+
pytest.skip(str(e))
4447
assert isinstance(problem, Problem)
4548
assert len(problem.measurement_table.measurements)

0 commit comments

Comments
 (0)