Skip to content

Commit 1fb6b39

Browse files
committed
Handle observableTransformation in petab.v1.simulate.sample_noise
Previously, `petab.v1.simulate.sample_noise` silently ignored `observableTransformation`. For example, in case of observableTransformation=log and noiseDistribution=normal, it incorrectly sampled from a normal instead of a log-normal distribution. Fixes #382.
1 parent 84fbdba commit 1fb6b39

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

petab/v1/simulate.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,20 +241,38 @@ def sample_noise(
241241
simulated_value,
242242
)
243243

244-
# default noise distribution is petab.C.NORMAL
245-
noise_distribution = petab_problem.observable_df.loc[
244+
observable_row = petab_problem.observable_df.loc[
246245
measurement_row[petab.C.OBSERVABLE_ID]
247-
].get(petab.C.NOISE_DISTRIBUTION, petab.C.NORMAL)
246+
]
247+
# default noise distribution is petab.C.NORMAL
248+
noise_distribution = observable_row.get(
249+
petab.C.NOISE_DISTRIBUTION, petab.C.NORMAL
250+
)
248251
# an empty noise distribution column in an observables table can result in
249252
# `noise_distribution == float('nan')`
250253
if pd.isna(noise_distribution):
251254
noise_distribution = petab.C.NORMAL
252255

256+
observable_transformation = observable_row.get(
257+
petab.C.OBSERVABLE_TRANSFORMATION, petab.C.LIN
258+
)
259+
# observableTransformation=log -> the log of the simulated value is
260+
# distributed according to `noise_distribution`
261+
if observable_transformation == petab.C.LOG:
262+
simulated_value = np.log(simulated_value)
263+
elif observable_transformation == petab.C.LOG10:
264+
simulated_value = np.log10(simulated_value)
265+
253266
# below is e.g.: `np.random.normal(loc=simulation, scale=noise_value)`
254267
simulated_value_with_noise = getattr(rng, noise_distribution)(
255268
loc=simulated_value, scale=noise_value * noise_scaling_factor
256269
)
257270

271+
if observable_transformation == petab.C.LOG:
272+
simulated_value_with_noise = np.exp(simulated_value_with_noise)
273+
elif observable_transformation == petab.C.LOG10:
274+
simulated_value_with_noise = np.power(10, simulated_value_with_noise)
275+
258276
if zero_bounded and np.sign(simulated_value) != np.sign(
259277
simulated_value_with_noise
260278
):

0 commit comments

Comments
 (0)