Repository navigation
petab1to2: fix conversion of logNormal, logLaplace and parameterScaleUniform priors - #536
Conversation
PEtab v2 has no log10-based noise distributions or priors. Since ln(y) = ln(10) * log10(y), a normal (Laplace) distribution of log10(y) with standard deviation (scale) sigma is a normal (Laplace) distribution of ln(y) with ln(10) * sigma. * log10-normal and log10-laplace noise now become log-normal and log-laplace with the noise formula `log(10) * (<formula>)`. Previously, log10-normal became log-normal with an unchanged noise formula (changing the likelihood), and log10-laplace raised NotImplementedError. * parameterScaleNormal and parameterScaleLaplace priors on log10-scaled parameters now become log-normal and log-laplace with both prior parameters multiplied by ln(10). Previously, log10-normal priors kept their parameters, and log10-laplace priors raised NotImplementedError. Closes #529 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Uniform priors * v1 `logNormal` / `logLaplace` were passed through verbatim, but v2 only knows `log-normal` / `log-laplace`. Both are based on the natural logarithm, so the parameters are kept. * `parameterScaleUniform` on `log` scale became `log-uniform` with the ln-space parameters, but v2 `log-uniform` takes the bounds of the parameter itself, so the prior density was NaN. Use exp(a); exp(b). * `parameterScaleUniform` on `log10` scale raised NotImplementedError. Convert to `log-uniform` with 10^a; 10^b. Missing parameterScaleUniform parameters still default to the parameter bounds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #536 +/- ##
==========================================
+ Coverage 76.69% 76.77% +0.08%
==========================================
Files 67 67
Lines 7538 7547 +9
Branches 1344 1346 +2
==========================================
+ Hits 5781 5794 +13
+ Misses 1262 1259 -3
+ Partials 495 494 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🟡 Changes recommended
Valid wide log10-uniform prior intervals still overflow during conversion before truncation.
1 open finding
What changed in this PR
Corrects prior conversion from PEtab v1 to v2, alongside the prerequisite log10 noise and prior rescaling changes.
Changes:
- Maps log-normal/log-laplace prior names and converts scaled uniform bounds.
- Rescales log10 noise and normal/Laplace prior parameters.
- Adds regression tests comparing densities and likelihoods.
| File | Description |
|---|---|
| tests/v2/test_conversion.py | Adds conversion equivalence tests. |
| petab/v2/petab1to2.py | Corrects prior mappings, bounds, and log10 rescaling. |
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.
| prior_pars = v2.C.PARAMETER_SEPARATOR.join( | ||
| str(float(unscale(float(p), pscale))) | ||
| for p in str(prior_pars).split(v1.C.PARAMETER_SEPARATOR) | ||
| ) |
There was a problem hiding this comment.
Fixed in fc0d2dd: like v1's Prior, the scaled interval is now clipped to the scaled parameter bounds before unscaling, and the linear lowerBound / upperBound are used for clipped endpoints. Added regression cases for log10 -400;400 and log -1000;1000 to test_petab1to2_priors; both failed before (OverflowError / overflow in exp) and now match the v1 prior density.
…r-mappings # Conflicts: # petab/v2/petab1to2.py # tests/v2/test_conversion.py
|
I think copilot raises a valid point. The rest looks good to me. |
…r-mappings # Conflicts: # petab/v2/petab1to2.py # tests/v2/test_conversion.py
…ling Like v1 `Prior`, clip the scaled interval [a, b] to the scaled parameter bounds, using the linear bounds for clipped endpoints. Before, valid but wide intervals overflowed when unscaled (e.g., log10 `-400;400` raised OverflowError; log `-1000;1000` gave an infinite upper bound). Addresses review comment on #536. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Fixes three prior-conversion bugs in the PEtab v1 -> v2 converter (
update_priorinv1v2_parameter_df). They turned up while verifying #535.Mappings
objectivePriorTypeparameterScalelogNormal/logLaplacemu;sigmalogNormal/logLaplaceverbatim → pydanticValidationErrorwhen buildingv2.Parameterlog-normal/log-laplace,mu;sigmaparameterScaleUniformloga;b(ln-space)log-uniformwitha;b→ prior pdf is NaNlog-uniformwithexp(a);exp(b), clipped to the boundsparameterScaleUniformlog10a;b(log10-space)NotImplementedError(log10-uniform)log-uniformwith10^a;10^b, clipped to the boundsWhy these are correct:
parameterScale(Priormaps(LOG_NORMAL, _)toNormal(..., log=True)). That is the same convention as v2log-normal/log-laplace, so only the name changes.log-uniformtakes the bounds of x itself as parameters.Parameter.prior_distnotes this ("Mind the different interpretation of distribution parameters forUniform(..., log=True)andLogUniform"). So the parameters are transformed back to linear scale. Like v1'sPrior, the scaled interval [a, b] is first clipped to the scaled parameter bounds, and the linear bounds are used for clipped endpoints. Within the bounds this gives the same truncated density, and it avoids overflow for valid but wide intervals such as log10-400;400.Missing
objectivePriorParametersforparameterScaleUniformstay missing, soupdate_prior_parsstill fills inlowerBound;upperBound. In v1 they default to the scaled bounds, which is the same distribution.Not changed: a missing
objectivePriorType(v1 defaultparameterScaleUniform) still converts touniformwithlowerBound;upperBoundon any scale. On log-scaled parameters the density differs from v1's log-uniform default. But this matches the v2 spec's default for parameters without a prior, and it keeps the optimum of v1 problems that have no priors.Verification
For each case I compared
petab.v1.priors.Prior.from_par_dict(row, type_="objective").pdf(x)with the convertedv2.Parameter.prior_dist.pdf(x)on a grid spanning the bounds [1e-3, 1e2]. This included prior ranges inside the bounds, wider than the bounds (truncation) and partly outside them. All agree to rel. 1e-12.Tests:
test_petab1to2_parameter_scale_priors(from #535) is nowtest_petab1to2_priors. It is parametrized over prior parameters and adds the cases above: log/log10parameterScaleUniformwithin bounds, exceeding bounds (including-400;400/-1000;1000, which overflow when unscaled), and with missing parameters, pluslogNormal/logLaplaceonlinandlog10scale. 11 of the new cases fail on the previous converter code, and all pass with this change.pytest tests/v2passes (141 passed), includingtest_benchmark_collectionwithbenchmark_models_petabinstalled.pre-commit(ruff, ruff-format) is clean.🤖 Generated with Claude Code