Skip to content

Commit

Permalink
PEtab import: Fix potentially incorrect sensitivities with state-depe…
Browse files Browse the repository at this point in the history
…ndent sigmas (#2562)

Due to PEtab not allowing and observables in noiseFormula and
AMICI not allowing state variables in sigma expressions, we are trying
to replace any state variables by matching observables during PEtab import.

However, if there were multiple observables with the same observableFormula,
or one observableFormula was contained in another one, the substition
of observableFormula for observableId could - depending on the ordering -
result in noiseFormulas depending on other observables, which could lead to
incorrect sensitivities due to #2561.

This change ensures that we are only using the observableId from the same
row of the observable table as the noiseFormula.

---------

Co-authored-by: Dilan Pathirana <[email protected]>
  • Loading branch information
dweindl and dilpath authored Oct 24, 2024
1 parent a20447a commit 9c603e1
Showing 1 changed file with 12 additions and 14 deletions.
26 changes: 12 additions & 14 deletions python/sdist/amici/petab/import_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,27 @@ def get_observation_model(

observables = {}
sigmas = {}

nan_pat = r"^[nN]a[nN]$"

for _, observable in observable_df.iterrows():
oid = str(observable.name)
# need to sanitize due to https://github.com/PEtab-dev/PEtab/issues/447
name = re.sub(nan_pat, "", str(observable.get(OBSERVABLE_NAME, "")))
formula_obs = re.sub(nan_pat, "", str(observable[OBSERVABLE_FORMULA]))
formula_noise = re.sub(nan_pat, "", str(observable[NOISE_FORMULA]))
observables[oid] = {"name": name, "formula": formula_obs}
sigmas[oid] = formula_noise

# PEtab does currently not allow observables in noiseFormula and AMICI
# cannot handle states in sigma expressions. Therefore, where possible,
# replace species occurring in error model definition by observableIds.
replacements = {
sp.sympify(observable["formula"], locals=_clash): sp.Symbol(
observable_id
formula_noise_sym = sp.sympify(formula_noise, locals=_clash)
formula_obs_sym = sp.sympify(formula_obs, locals=_clash)
# PEtab does currently not allow observables in noiseFormula, and
# AMICI cannot handle state variables in sigma expressions.
# Therefore, where possible, replace state variables occurring in
# the error model definition by equivalent observableIds.
# Do not use observableIds from other rows
# (https://github.com/AMICI-dev/AMICI/issues/2561).
formula_noise_sym = formula_noise_sym.subs(
formula_obs_sym, sp.Symbol(oid)
)
for observable_id, observable in observables.items()
}
for observable_id, formula in sigmas.items():
repl = sp.sympify(formula, locals=_clash).subs(replacements)
sigmas[observable_id] = str(repl)
sigmas[oid] = str(formula_noise_sym)

noise_distrs = petab_noise_distributions_to_amici(observable_df)

Expand Down

0 comments on commit 9c603e1

Please sign in to comment.