-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Non-compartmental analysis #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Siel
wants to merge
24
commits into
main
Choose a base branch
from
feat/new-nca
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
da044a9
feat: add NormalizedRow API and ResidualErrorModel
Siel 0c4c36b
feat: Non-compartmental analysis (NCA) (#189)
Siel 4d3109c
Merge branch 'main' into feat/normalized-row-api
Siel 1e0c4ed
chore: cleanup
Siel f24d525
chore: fmt
Siel 0229425
feat: more validation scenarios
Siel 932150b
feat: Json
Siel eb99b43
chore: wire up the tests, and update them to the newer API
Siel 49e5fc6
chore: fmt
Siel 8f4b155
Update src/optimize/effect.rs
Siel 07ef9fe
feat: all datasets are now 0 index, Pmetrics is supported but vectors…
Siel f267be1
suggestions: Suggestions for renamed items (#196)
mhovd feedeec
Merge branch 'feat/zero-index' into feat/normalized-row-api
mhovd 7abf761
Don't use deprecated method
mhovd 86b82e6
Merge branch 'feat/normalized-row-api' into feat/json
Siel f364d76
making sure both 0-index and 1-index data are supported
Siel 26246a8
fix: vector size missmatch
Siel 2415f1c
wip: adding missing functionality and re-defining base structs
Siel 4528d8d
total rewrite of the NCA module
Siel 7dcf028
Merge branch 'main' into feat/new-nca
Siel 7ff63ce
chore: fmt
Siel e7376b2
Remove JSON from this PR
mhovd c36e797
Delete json_exa.rs
mhovd 7832f67
Move tests (#210)
mhovd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,3 +52,7 @@ harness = false | |
| [[bench]] | ||
| name = "analytical_vs_ode" | ||
| harness = false | ||
|
|
||
| [[bench]] | ||
| name = "nca" | ||
| harness = false | ||
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; | ||
| use pharmsol::nca::{lambda_z_candidates, NCAOptions, NCA}; | ||
| use pharmsol::prelude::*; | ||
| use std::hint::black_box; | ||
|
|
||
| /// Build a typical PK subject with 12 time points (oral dose) | ||
| fn typical_oral_subject(id: &str) -> Subject { | ||
| Subject::builder(id) | ||
| .bolus(0.0, 100.0, 0) | ||
| .observation(0.0, 0.0, 0) | ||
| .observation(0.25, 2.5, 0) | ||
| .observation(0.5, 5.0, 0) | ||
| .observation(1.0, 8.0, 0) | ||
| .observation(2.0, 10.0, 0) | ||
| .observation(4.0, 7.5, 0) | ||
| .observation(6.0, 5.0, 0) | ||
| .observation(8.0, 3.5, 0) | ||
| .observation(12.0, 1.5, 0) | ||
| .observation(16.0, 0.8, 0) | ||
| .observation(24.0, 0.2, 0) | ||
| .observation(36.0, 0.05, 0) | ||
| .build() | ||
| } | ||
|
|
||
| /// Build a population of n subjects with slight variation | ||
| fn build_population(n: usize) -> Data { | ||
| let subjects: Vec<Subject> = (0..n) | ||
| .map(|i| { | ||
| let scale = 1.0 + (i as f64 % 7.0) * 0.05; // slight variation | ||
| Subject::builder(&format!("subj_{}", i)) | ||
| .bolus(0.0, 100.0, 0) | ||
| .observation(0.0, 0.0, 0) | ||
| .observation(0.25, 2.5 * scale, 0) | ||
| .observation(0.5, 5.0 * scale, 0) | ||
| .observation(1.0, 8.0 * scale, 0) | ||
| .observation(2.0, 10.0 * scale, 0) | ||
| .observation(4.0, 7.5 * scale, 0) | ||
| .observation(6.0, 5.0 * scale, 0) | ||
| .observation(8.0, 3.5 * scale, 0) | ||
| .observation(12.0, 1.5 * scale, 0) | ||
| .observation(16.0, 0.8 * scale, 0) | ||
| .observation(24.0, 0.2 * scale, 0) | ||
| .observation(36.0, 0.05 * scale, 0) | ||
| .build() | ||
| }) | ||
| .collect(); | ||
| Data::new(subjects) | ||
| } | ||
|
|
||
| fn bench_single_subject_nca(c: &mut Criterion) { | ||
| let subject = typical_oral_subject("bench_subj"); | ||
| let opts = NCAOptions::default(); | ||
|
|
||
| c.bench_function("nca_single_subject", |b| { | ||
| b.iter(|| { | ||
| let result = black_box(&subject).nca(black_box(&opts)); | ||
| let _ = black_box(result); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| fn bench_population_nca(c: &mut Criterion) { | ||
| let mut group = c.benchmark_group("nca_population"); | ||
|
|
||
| for size in [10, 100, 500] { | ||
| let data = build_population(size); | ||
| let opts = NCAOptions::default(); | ||
|
|
||
| group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, _| { | ||
| b.iter(|| { | ||
| let results = black_box(&data).nca_all(black_box(&opts)); | ||
| black_box(results); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| group.finish(); | ||
| } | ||
|
|
||
| fn bench_lambda_z_candidates(c: &mut Criterion) { | ||
| use pharmsol::data::event::{AUCMethod, BLQRule}; | ||
| use pharmsol::data::observation::ObservationProfile; | ||
| use pharmsol::nca::LambdaZOptions; | ||
|
|
||
| let subject = typical_oral_subject("bench_subj"); | ||
| let occ = &subject.occasions()[0]; | ||
| let profile = ObservationProfile::from_occasion(occ, 0, &BLQRule::Exclude).unwrap(); | ||
| let lz_opts = LambdaZOptions::default(); | ||
|
|
||
| // Get AUClast for the candidate scoring | ||
| let auc_results = subject.auc(0, &AUCMethod::Linear, &BLQRule::Exclude); | ||
| let auc_last = auc_results[0].as_ref().copied().unwrap_or(50.0); | ||
|
|
||
| c.bench_function("nca_lambda_z_candidates", |b| { | ||
| b.iter(|| { | ||
| let candidates = lambda_z_candidates( | ||
| black_box(&profile), | ||
| black_box(&lz_opts), | ||
| black_box(auc_last), | ||
| ); | ||
| black_box(candidates); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| fn bench_observation_metrics(c: &mut Criterion) { | ||
| use pharmsol::data::event::{AUCMethod, BLQRule}; | ||
|
|
||
| let subject = typical_oral_subject("bench_subj"); | ||
|
|
||
| c.bench_function("nca_auc_cmax_metrics", |b| { | ||
| b.iter(|| { | ||
| let auc = black_box(&subject).auc(0, &AUCMethod::Linear, &BLQRule::Exclude); | ||
| let cmax = black_box(&subject).cmax(0, &BLQRule::Exclude); | ||
| black_box((auc, cmax)); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| criterion_group!( | ||
| benches, | ||
| bench_single_subject_nca, | ||
| bench_population_nca, | ||
| bench_lambda_z_candidates, | ||
| bench_observation_metrics, | ||
| ); | ||
| criterion_main!(benches); |
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example shows calling
.nca()with two arguments, but according to the trait definition insrc/nca/traits.rs, the method signature is.nca(&self, options: &NCAOptions) -> Result<NCAResult, NCAError>which only takes one argument. This example code will not compile.