Skip to content

Commit 179dc82

Browse files
authored
Fix flatten_timepoint_specific_output_overrides (#239)
... again. Fixes an error when trying to apply re.sub to numeric values: ``` petab.flatten_timepoint_specific_output_overrides(problem) build/venv/lib/python3.9/site-packages/petab/core.py:290: in flatten_timepoint_specific_output_overrides observable[target] = re.sub( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pattern = 'observableParameter([0-9]+)_obs_a' repl = 'observableParameter\\1_obs_a__10__c0', string = 1, count = 0, flags = 0 def sub(pattern, repl, string, count=0, flags=0): """Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the Match object and must return a replacement string to be used.""" > return _compile(pattern, flags).sub(repl, string, count) E TypeError: cannot use a string pattern on a bytes-like object /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/re.py:210: TypeError ```
1 parent eb08318 commit 179dc82

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

petab/core.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import numpy as np
1919
import pandas as pd
20+
from pandas.api.types import is_string_dtype
2021

2122
from . import yaml
2223
from .C import * # noqa: F403
@@ -282,6 +283,10 @@ def flatten_timepoint_specific_output_overrides(
282283
if field not in measurements:
283284
continue
284285

286+
if not is_string_dtype(type(observable[target])):
287+
# if not a string, we don't have to substitute anything
288+
continue
289+
285290
hyperparameter_replacement_id = get_hyperparameter_replacement_id(
286291
hyperparameter_type=hyperparameter_type,
287292
observable_replacement_id=observable_replacement_id,

tests/test_petab.py

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,14 @@ def test_flatten_timepoint_specific_output_overrides():
349349
"""Test flatten_timepoint_specific_output_overrides"""
350350
observable_df = pd.DataFrame(
351351
data={
352-
OBSERVABLE_ID: ["obs1"],
352+
OBSERVABLE_ID: ["obs1", "obs2"],
353353
OBSERVABLE_FORMULA: [
354-
"observableParameter1_obs1 + observableParameter2_obs1"
354+
"observableParameter1_obs1 + observableParameter2_obs1",
355+
"x",
355356
],
356357
NOISE_FORMULA: [
357-
"(observableParameter1_obs1 + observableParameter2_obs1) * noiseParameter1_obs1"
358+
"(observableParameter1_obs1 + observableParameter2_obs1) * noiseParameter1_obs1",
359+
1,
358360
],
359361
}
360362
)
@@ -366,11 +368,17 @@ def test_flatten_timepoint_specific_output_overrides():
366368
obs1_2_2_1 = "obs1__obsParOverride2_1_0__noiseParOverride2__condition1"
367369
observable_df_expected = pd.DataFrame(
368370
data={
369-
OBSERVABLE_ID: [obs1_1_1_1, obs1_2_1_1, obs1_2_2_1],
371+
OBSERVABLE_ID: [
372+
obs1_1_1_1,
373+
obs1_2_1_1,
374+
obs1_2_2_1,
375+
"obs2__condition1",
376+
],
370377
OBSERVABLE_FORMULA: [
371378
f"observableParameter1_{obs1_1_1_1} + observableParameter2_{obs1_1_1_1}",
372379
f"observableParameter1_{obs1_2_1_1} + observableParameter2_{obs1_2_1_1}",
373380
f"observableParameter1_{obs1_2_2_1} + observableParameter2_{obs1_2_2_1}",
381+
"x",
374382
],
375383
NOISE_FORMULA: [
376384
f"(observableParameter1_{obs1_1_1_1} + observableParameter2_{obs1_1_1_1})"
@@ -379,6 +387,7 @@ def test_flatten_timepoint_specific_output_overrides():
379387
f" * noiseParameter1_{obs1_2_1_1}",
380388
f"(observableParameter1_{obs1_2_2_1} + observableParameter2_{obs1_2_2_1})"
381389
f" * noiseParameter1_{obs1_2_2_1}",
390+
1,
382391
],
383392
}
384393
)
@@ -387,54 +396,66 @@ def test_flatten_timepoint_specific_output_overrides():
387396
# Measurement table with timepoint-specific overrides
388397
measurement_df = pd.DataFrame(
389398
data={
390-
OBSERVABLE_ID: ["obs1", "obs1", "obs1", "obs1"],
399+
OBSERVABLE_ID: ["obs1", "obs1", "obs1", "obs1", "obs2"],
391400
SIMULATION_CONDITION_ID: [
392401
"condition1",
393402
"condition1",
394403
"condition1",
395404
"condition1",
405+
"condition1",
396406
],
397-
PREEQUILIBRATION_CONDITION_ID: ["", "", "", ""],
398-
TIME: [1.0, 1.0, 2.0, 2.0],
399-
MEASUREMENT: [0.1] * 4,
407+
PREEQUILIBRATION_CONDITION_ID: ["", "", "", "", ""],
408+
TIME: [1.0, 1.0, 2.0, 2.0, 3.0],
409+
MEASUREMENT: [0.1] * 5,
400410
OBSERVABLE_PARAMETERS: [
401411
"obsParOverride1;1.0",
402412
"obsParOverride2;1.0",
403413
"obsParOverride2;1.0",
404414
"obsParOverride2;1.0",
415+
"",
405416
],
406417
NOISE_PARAMETERS: [
407418
"noiseParOverride1",
408419
"noiseParOverride1",
409420
"noiseParOverride2",
410421
"noiseParOverride2",
422+
"",
411423
],
412424
}
413425
)
414426

415427
measurement_df_expected = pd.DataFrame(
416428
data={
417-
OBSERVABLE_ID: [obs1_1_1_1, obs1_2_1_1, obs1_2_2_1, obs1_2_2_1],
429+
OBSERVABLE_ID: [
430+
obs1_1_1_1,
431+
obs1_2_1_1,
432+
obs1_2_2_1,
433+
obs1_2_2_1,
434+
"obs2__condition1",
435+
],
418436
SIMULATION_CONDITION_ID: [
419437
"condition1",
420438
"condition1",
421439
"condition1",
422440
"condition1",
441+
"condition1",
423442
],
424-
PREEQUILIBRATION_CONDITION_ID: ["", "", "", ""],
425-
TIME: [1.0, 1.0, 2.0, 2.0],
426-
MEASUREMENT: [0.1] * 4,
443+
PREEQUILIBRATION_CONDITION_ID: ["", "", "", "", ""],
444+
TIME: [1.0, 1.0, 2.0, 2.0, 3.0],
445+
MEASUREMENT: [0.1] * 5,
427446
OBSERVABLE_PARAMETERS: [
428447
"obsParOverride1;1.0",
429448
"obsParOverride2;1.0",
430449
"obsParOverride2;1.0",
431450
"obsParOverride2;1.0",
451+
"",
432452
],
433453
NOISE_PARAMETERS: [
434454
"noiseParOverride1",
435455
"noiseParOverride1",
436456
"noiseParOverride2",
437457
"noiseParOverride2",
458+
"",
438459
],
439460
}
440461
)
@@ -483,7 +504,9 @@ def test_flatten_timepoint_specific_output_overrides():
483504
petab_problem=unflattened_problem,
484505
)
485506
# The unflattened simulation dataframe has the original observable IDs.
486-
assert (unflattened_simulation_df[OBSERVABLE_ID] == "obs1").all()
507+
assert (
508+
unflattened_simulation_df[OBSERVABLE_ID] == ["obs1"] * 4 + ["obs2"]
509+
).all()
487510

488511

489512
def test_flatten_timepoint_specific_output_overrides_special_cases():

0 commit comments

Comments
 (0)