Skip to content
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

Add replace() function to evtools #1203

Merged
merged 4 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions inst/base/mrgsolv.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2013 - 2023 Metrum Research Group
// Copyright (C) 2013 - 2024 Metrum Research Group
//
// This file is part of mrgsolve.
//
Expand Down Expand Up @@ -49,7 +49,7 @@ struct resim {
};

struct evdata {
evdata(double a_, int b_) : time(a_), evid(b_) {
evdata(double a_, int b_) : time(a_), evid(b_) {
cmt = 1;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Just a lint.

amt = 0.0;
rate = 0.0;
Expand Down
15 changes: 15 additions & 0 deletions inst/base/mrgsolve-evtools.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ void infuse(databox& self, const double amt, const int cmt, const double rate) {
return;
}

mrgsolve::evdata replace(const double amt, const int cmt) {
mrgsolve::evdata ev(0, 8);
Copy link
Collaborator Author

@kylebaron kylebaron Jun 22, 2024

Choose a reason for hiding this comment

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

The signature for the constructor is time and evid. We use 8 here because that signals to zero out the compartment and add the new amount. The time value (0) is arbitrary b/c we'll set the object to get implemented now later on.

ev.amt = amt;
ev.cmt = cmt;
ev.now = true;
ev.check_unique = false;
return ev;
}

void replace(databox& self, const double amt, const int cmt) {
mrgsolve::evdata ev = replace(amt, cmt);
self.mevector.push_back(ev);
return;
}

void retime(mrgsolve::evdata& ev, const double time) {
ev.time = time;
ev.now = false;
Expand Down
37 changes: 36 additions & 1 deletion inst/maintenance/unit-cpp/test-evtools.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ $SET end = 12, rtol = 1e-4, atol = 1e-4, delta = 0.25
$PLUGIN evtools
$PARAM
mode = 0, f1 = 1, dose = 100, irate = 50, newtime = 2
$CMT A B
reptime = 5
$CMT A B C
$PK
F_A = f1;
$DES
dxdt_A = -1 * A;
dxdt_B = 1 * A - 0.1 * B;
dxdt_C = 0;
$TABLE
bool givedose = TIME==0;
if(mode==1 && givedose) {
Expand Down Expand Up @@ -48,6 +50,14 @@ if(mode==6 && givedose) {
evt::now(ev);
evt::push(self, ev);
}
if(mode==7 && TIME==reptime) {
evt::replace(self, C/2.0, 3);
}
if(mode==8 && givedose) {
evt::ev rep = evt::replace(10, 3);
evt::retime(rep, reptime);
self.push(rep);
}
'

mod <- mcode("test-evtools-model-1", code)
Expand Down Expand Up @@ -103,3 +113,28 @@ test_that("evtools - give timed dose now", {
b <- mrgsim(mod, param = list(mode = 1))
expect_identical(as.data.frame(a), as.data.frame(b))
})

test_that("evtools - replace", {
mod <- init(mod, C = 100)
mod <- update(mod, delta = 0.1)
a <- mrgsim(mod, param = list(mode = 7))
before <- filter(a, time < 5)
expect_true(all(before$C==100))
after <- filter(a, time >= 5)
expect_true(all(after$C==50))

#' When the replacement is timed into the future, we see the
Copy link
Contributor

Choose a reason for hiding this comment

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

extreme nit-pick: I think it'd be better to use plain comments rather than roxygen-style ones. (I've been allergic to unnecessary roxygen-style comments ever since I spent time debugging this issue.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, @kyleam; I reverted the comments and will try to stick to plain R comments going forward (I think I do most of the time, but I'm sure there's tons of #' comments in the code too.)

#' replacement right at the indicated time
b <- mrgsim(mod, param = list(mode = 8, reptime = 8))
before <- filter(b, time <= 8) # note: <= 8
expect_true(all(before$C==100))
after <- filter(b, time > 8) # note: > 8
expect_true(all(after$C==10))

#' We can control this with `recsort`
c <- mrgsim(mod, param = list(mode = 8, reptime = 8), recsort = 3)
before <- filter(c, time < 8) # note: < 8
expect_true(all(before$C==100))
after <- filter(c, time >= 8) # note: >= 8
expect_true(all(after$C==10))
})
Loading