You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Updates Pmetrics to the PMcore in LAPKB/PMcore#333 (chore/pharmsol-main). That branch currently depends on pharmsol branch claude/sweet-davinci-o6m0ej (7233a77); the exact revisions are pinned in Cargo.lock. A copy, src/rust/Cargo.lock, ships in the source package (.Rbuildignore drops the root one), so install_github and R CMD build builds are pinned too; keep the two identical. Draft: this uses git dependencies and can't be released until PMcore and pharmsol cut releases.
Prediction::outeq() now returns an OutputLabel. Simulation rows map it back to the output's position in the model, so PM_model$sim() output is unchanged.
Error models are added under the model's declared output label instead of a dense slot. With the new pharmsol this means gamma/lambda is actually optimised (cycles.csv gets a gamlam.<label> column).
Labels: no more input_n / outeq_n
pharmsol now matches labels exactly and no longer accepts outeq_1 for 1, so the old prefixes are dropped:
Generated DSL uses bare labels: out(1), bolus(1), infusion(1), lag(1).
Data INPUT/OUTEQ values are used as labels as-is (trimmed; 01 → 1). This also covers the planned alphanumeric labels, e.g. INPUT = tacrolimus or OUTEQ = plasma.
Back-compat:label_data_csv() and the DSL error-model matching resolve against the labels the model actually declares. A numeric identifier n also matches input_n / outeq_n, so user DSL models (and saved DSL) written with the prefixes keep working.
Models saved with the current release
Saved PM_model objects keep their own $fit/$sim bodies and a cached DSL with input_1/outeq_1. These now keep working:
label_data_csv() called without labels (as the old methods do) takes them from the calling model's DSL.
A numeric error-model label that isn't declared binds to the output at that position.
Result parsers read a legacy outeq_N label as output N.
Checked with the shipped objects: modEx$fit() runs with op and cycle populated, and modEx$sim() and NPex$model$sim() run.
Output parsing
pred.csv now holds the output label in outeq (previously a 0-based index), and cycles.csv has gamlam.<label>.
settings.json now records the model's output labels.
New engine_outeq_index() converts labels to Pmetrics output numbers: numeric labels are used as-is, named labels are numbered by their position in the model's outputs, and legacy 0-based files are still shifted. It is used in PM_op, PM_pop, PM_post and PM_cycle.
gamlam columns are split on the gamlam. prefix only, so labels containing dots don't break. The cycle number comes from cycles.csv, so a declared output without observations no longer drops PM_cycle.
PM_model$from_dsl() requires a numeric output label to equal its position (outputs = 1, 2, not 2, 1 or 1, 3), so numeric and named outputs number consistently. It also rejects error-model names that resolve to the same output (e.g. 1 and outeq_1).
New DSL functions in R-defined models
pharmsol's new built-ins were only usable in DSL text (PM_model$from_dsl()). The R-to-DSL translator now accepts them as well:
effect50(min = 0, max = 1, e50 = 0.5, h = 1, x): the sigmoid Emax (Hill) model.
sigmoid(x, k = 1) and logit(p).
tanh(x).
Arguments can be given by position, by name, or both; names are kept in the generated DSL. Each call is checked against its signature, so a mistake is reported against the user's R expression. All of these are documented in ?PM_model. R's own ifelse was already translated (to an if) and is unchanged.
Testing
Smoke fit (one-comp IV, NPAG, 3 cycles): op/pop/post have outeq = 1 and finite weighted residuals; cycle$gamlam is populated and gamma moves (4.55 → 3.79); sim is unchanged.
New tests check the translated calls, compare the computed values with the formulas evaluated in R, and cover the error messages (DSL language tests: 218 passed).
testthat: 752 passed, 1 skipped (existing), 1 failed: test-data-currency.R. The shipped example objects (NPex, modEx) embed the old PM_model$fit/$sim bodies. They need regenerating with Rscript data-raw/data-raw.R (a full NPAG fit), which I'd do once the PMcore version is final.
Known gaps / follow-ups
Downstream plotting/summary code still treats outeq as a number; full alphanumeric support will need the label carried through to those.
Points pm_rs at the PMcore `chore/pharmsol-main` branch, which moves to a
pharmsol where output labels are matched exactly and error models are keyed
by label.
- Rust: `simulate` replaces `estimate_predictions_dense`; simulation rows map
the prediction's output label back to its position; error models are added
under the model's declared output label.
- Labels: drop the `input_n` / `outeq_n` prefixes. Data identifiers are used as
labels verbatim, so `INPUT = 1` matches route `1` and `OUTEQ = plasma`
matches output `plasma`. Numeric identifiers still resolve to `input_n` /
`outeq_n` in models that declare them that way.
- Parsers: pred.csv and cycles.csv now carry output labels instead of 0-based
indices. settings.json records the output labels, and the parsers convert
labels to output numbers (numeric labels as-is, named labels by position).
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Output mapping collisions, cycle reconstruction failures, and stale serialized model methods can break results, while route resolution and dependency pinning also remain unresolved.
Updates Pmetrics for the PMcore/pharmsol migration in LAPKB/PMcore#333, adapting its Rust backend and R interfaces to label-based inputs and outputs. The dependency switch remains a draft pending upstream releases.
Changes:
Adopts the new simulation API and label-keyed error models.
Emits bare numeric labels while resolving legacy prefixed model labels.
Records output labels and updates result parsing, documentation, and regression tests.
The new pharmsol DSL functions were only usable in DSL text. The R-to-DSL
translator now accepts them, keeps argument names so calls can use the DSL's
named and default arguments, and checks each call against its signature so
mistakes are reported against the R expression. Documented in PM_model.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Output-label collisions can merge predictions or apply incorrect error coefficients, while previously serialized models can fail under the new label matching.
Exclude gamlam columns from cycle-data statistics pivot
R/PM_cycle.R:264
Output labels ending in mean, median, or sd are still picked up by the earlier cycle_data pivot, before this prefix handling runs. For example, gamlam.mean becomes a spurious parameter statistic, while gamlam.effect.mean makes separate_wider_delim() fail on three components. At line 201, restrict the pivot to ends_with(c("mean", "median", "sd")) & !starts_with("gamlam.").
Preserve dotted output labels during missing-marker checks
R/model_dsl.R:1267
Dotted output labels such as plasma.free cannot reach this relabeling step through the normal fit path: the malformed-NA check in R/PM_data.R:1155 flags them, and PM_data$save() refuses to write the backend CSV. Restrict missing-marker detection and correction for INPUT/OUTEQ to whole-cell markers so dots inside labels are preserved.
❌ Patch coverage is 95.62500% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.82%. Comparing base (ef474a1) to head (1d28572).
- Parse cycles.csv gamlam when a declared output has no observations
- Require numeric DSL output labels to equal their position
- Reject error-model names that resolve to the same output
- Keep models saved by earlier releases working: take data labels from the
caller's DSL, bind numeric error-model labels by position, and read legacy
outeq_N labels in result files
- Ship src/rust/Cargo.lock so source-package builds are pinned
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Sparse-output error models are decoded incorrectly, compatibility regressions break existing models and data, and stale example objects cause R CMD check to fail.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updates Pmetrics to the PMcore in LAPKB/PMcore#333 (
chore/pharmsol-main). That branch currently depends on pharmsol branchclaude/sweet-davinci-o6m0ej(7233a77); the exact revisions are pinned inCargo.lock. A copy,src/rust/Cargo.lock, ships in the source package (.Rbuildignoredrops the root one), soinstall_githubandR CMD buildbuilds are pinned too; keep the two identical. Draft: this uses git dependencies and can't be released until PMcore and pharmsol cut releases.Rust (
src/rust)estimate_predictions_dense→simulate(subject, params, None).Prediction::outeq()now returns anOutputLabel. Simulation rows map it back to the output's position in the model, soPM_model$sim()output is unchanged.cycles.csvgets agamlam.<label>column).Labels: no more
input_n/outeq_npharmsol now matches labels exactly and no longer accepts
outeq_1for1, so the old prefixes are dropped:out(1),bolus(1),infusion(1),lag(1).INPUT/OUTEQvalues are used as labels as-is (trimmed;01→1). This also covers the planned alphanumeric labels, e.g.INPUT = tacrolimusorOUTEQ = plasma.label_data_csv()and the DSL error-model matching resolve against the labels the model actually declares. A numeric identifiernalso matchesinput_n/outeq_n, so user DSL models (and saved DSL) written with the prefixes keep working.Models saved with the current release
Saved
PM_modelobjects keep their own$fit/$simbodies and a cached DSL withinput_1/outeq_1. These now keep working:label_data_csv()called without labels (as the old methods do) takes them from the calling model's DSL.outeq_Nlabel as outputN.Checked with the shipped objects:
modEx$fit()runs withopandcyclepopulated, andmodEx$sim()andNPex$model$sim()run.Output parsing
pred.csvnow holds the output label inouteq(previously a 0-based index), andcycles.csvhasgamlam.<label>.settings.jsonnow records the model's output labels.engine_outeq_index()converts labels to Pmetrics output numbers: numeric labels are used as-is, named labels are numbered by their position in the model's outputs, and legacy 0-based files are still shifted. It is used inPM_op,PM_pop,PM_postandPM_cycle.gamlamcolumns are split on thegamlam.prefix only, so labels containing dots don't break. The cycle number comes fromcycles.csv, so a declared output without observations no longer dropsPM_cycle.PM_model$from_dsl()requires a numeric output label to equal its position (outputs = 1, 2, not2, 1or1, 3), so numeric and named outputs number consistently. It also rejects error-model names that resolve to the same output (e.g.1andouteq_1).New DSL functions in R-defined models
pharmsol's new built-ins were only usable in DSL text (
PM_model$from_dsl()). The R-to-DSL translator now accepts them as well:effect50(min = 0, max = 1, e50 = 0.5, h = 1, x): the sigmoid Emax (Hill) model.sigmoid(x, k = 1)andlogit(p).tanh(x).Arguments can be given by position, by name, or both; names are kept in the generated DSL. Each call is checked against its signature, so a mistake is reported against the user's R expression. All of these are documented in
?PM_model. R's ownifelsewas already translated (to anif) and is unchanged.Testing
op/pop/posthaveouteq = 1and finite weighted residuals;cycle$gamlamis populated and gamma moves (4.55 → 3.79);simis unchanged.testthat: 752 passed, 1 skipped (existing), 1 failed:test-data-currency.R. The shipped example objects (NPex,modEx) embed the oldPM_model$fit/$simbodies. They need regenerating withRscript data-raw/data-raw.R(a full NPAG fit), which I'd do once the PMcore version is final.Known gaps / follow-ups
outeqas a number; full alphanumeric support will need the label carried through to those.