Skip to content

petab1to2: fix conversion of logNormal, logLaplace and parameterScaleUniform priors - #536

Merged
FFroehlich merged 5 commits into
mainfrom
claude/petab1to2-prior-mappings
Oct 9, 2026
Merged

FFroehlich merged 5 commits into
mainfrom
claude/petab1to2-prior-mappings

Conversation

@FFroehlich

@FFroehlich FFroehlich commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes three prior-conversion bugs in the PEtab v1 -> v2 converter (update_prior in v1v2_parameter_df). They turned up while verifying #535.

Mappings

v1 objectivePriorType parameterScale v1 parameters before now
logNormal / logLaplace any mu;sigma logNormal / logLaplace verbatim → pydantic ValidationError when building v2.Parameter log-normal / log-laplace, mu;sigma
parameterScaleUniform log a;b (ln-space) log-uniform with a;b → prior pdf is NaN log-uniform with exp(a);exp(b), clipped to the bounds
parameterScaleUniform log10 a;b (log10-space) NotImplementedError (log10-uniform) log-uniform with 10^a;10^b, clipped to the bounds

Why these are correct:

  1. logNormal / logLaplace. In v1 these are always based on the natural logarithm, whatever the parameterScale (Prior maps (LOG_NORMAL, _) to Normal(..., log=True)). That is the same convention as v2 log-normal / log-laplace, so only the name changes.
  2. and 3. parameterScaleUniform on log/log10. If ln(x) (or log10(x)) is uniform on [a, b], then x is log-uniform on [e^a, e^b] (or [10^a, 10^b]). v2 log-uniform takes the bounds of x itself as parameters. Parameter.prior_dist notes this ("Mind the different interpretation of distribution parameters for Uniform(..., log=True) and LogUniform"). So the parameters are transformed back to linear scale. Like v1's Prior, 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 objectivePriorParameters for parameterScaleUniform stay missing, so update_prior_pars still fills in lowerBound;upperBound. In v1 they default to the scaled bounds, which is the same distribution.

Not changed: a missing objectivePriorType (v1 default parameterScaleUniform) still converts to uniform with lowerBound;upperBound on 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 converted v2.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 now test_petab1to2_priors. It is parametrized over prior parameters and adds the cases above: log/log10 parameterScaleUniform within bounds, exceeding bounds (including -400;400 / -1000;1000, which overflow when unscaled), and with missing parameters, plus logNormal/logLaplace on lin and log10 scale. 11 of the new cases fail on the previous converter code, and all pass with this change. pytest tests/v2 passes (141 passed), including test_benchmark_collection with benchmark_models_petab installed. pre-commit (ruff, ruff-format) is clean.

🤖 Generated with Claude Code

FFroehlich and others added 2 commits October 8, 2026 13:37
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>
@FFroehlich
FFroehlich requested a review from a team as a code owner October 8, 2026 13:00
Copilot AI balanced review requested due to automatic review settings October 8, 2026 13:00
@codecov-commenter

codecov-commenter commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.77%. Comparing base (37b7025) to head (fc0d2dd).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Comment thread petab/v2/petab1to2.py Outdated
Comment on lines +514 to +517
prior_pars = v2.C.PARAMETER_SEPARATOR.join(
str(float(unscale(float(p), pscale)))
for p in str(prior_pars).split(v1.C.PARAMETER_SEPARATOR)
)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@dweindl

dweindl commented Oct 9, 2026

Copy link
Copy Markdown
Member

I think copilot raises a valid point. The rest looks good to me.

FFroehlich and others added 2 commits October 9, 2026 11:30
…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>
@FFroehlich
FFroehlich merged commit 402393d into main Oct 9, 2026
13 checks passed
@FFroehlich
FFroehlich deleted the claude/petab1to2-prior-mappings branch October 9, 2026 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants