-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathspecification.qmd
More file actions
2564 lines (1812 loc) · 70.9 KB
/
Copy pathspecification.qmd
File metadata and controls
2564 lines (1812 loc) · 70.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
```{r,echo=FALSE,message=FALSE}
source("setup.R")
```
# Model specification {#sec-model-specification}
This chapter details the mrgsolve model specification format.
## How / where to write a model
There are two ways to write your model:
1. Code in a __separate file__ and source into your R script
2. Code __inline__ as a character string already in your R script
We recommend method `1` (separate file) for any non-trivial modeling work.
Method `2` is handy for quickly coding a model and you'll also see us using
that approach frequently when demonstrating how to use mrgsolve.
### Separate file {#sec-spec-separate-file}
For most applications, you will want to put your model code in a standalone
file. This file can have any extension, but there is some special behavior
when you use the `.cpp` extension. We'll show you both here.
#### Using `.cpp` file extension
Open a text editor and type the model code into a file with name that has the
format `<model-name>.cpp`. This filename format identifies a "name" for your
model (`<model-name>`, the "stem" of the file name). Note: this whole file will
be read and parsed, so everything in it must be valid mrgsolve model
specification elements.
Use the `mread()` function to read and parse this file. For the model
called `mymodel` saved in `mymodel.cpp` (in the current working directory),
issue the command:
```{r,eval=FALSE}
mod <- mread("mymodel")
```
`mread()` returns a model object from which you can simulate.
#### Using any file extension
You can use any file extension to save your mrgsolve model. Rather
than using `.cpp`, you might use `.mod`. When you are using an extension
other than `.cpp`, pass in the entire file name, both stem and
extension. If you have the model code saved in `mymodel.mod` then
you'd call
```{r, eval = FALSE}
mod <- mread("mymodel.mod")
```
to load that model.
#### The model project directory
The second argument to `mread()` is `project`. This is the directory where
mrgsolve will look for your model file (passed as the first argument to
`mread()`).
If your `myproject.mod` file is located in the `models` directory, then
you could load that file with
```{r, eval = FALSE}
mod <- mread("mymodel.mod", project = "models")
```
Alternatively, you can just past the entire path to the model file
```{r, eval = FALSE}
mod <- mread("models/mymodel.mod")
```
### Inline / `code` \ {#sec-spec-inline}
Often it is more convenient to write a model right in your `R` script. The
model might look something like this:
```{r}
code <- '
$PARAM CL = 1, VC = 20
$PKMODEL ncmt=1
'
```
Here, we created a character vector of length 1 and saved it to the `R` object
called `code`. The name of this object is irrelevant. But `code` will be
passed into mrgsolve as the model definition. When mrgsolve gets a model
like this along with a "name" for the model, mrgsolve will write the code to a
file called `<model-name>.cpp` and read it right back in as if you had typed
the code into this file (@sec-spec-separate-file).
To parse and load this model, use the `mcode()` command:
```{r,eval=FALSE}
mod <- mcode("mymodel", code)
```
`mcode()` is a convenience wrapper for `mread()`. `mcode` writes the code to
`mymodel.cpp` in `tempdir()`, reads it back in, compiles and loads.
The `mcode` call is equivalent to:
```{r, eval=FALSE}
mod <- mread("mymodel", tempdir(), code)
```
For help, see `?mread` , `?mcode` in the `R` help system after loading
mrgsolve.
### Comments
You can comment out code in the model specification file with two
front slashes `//`
```{c, eval = FALSE}
$MAIN
double a = 1.234;
// double b = 5.678;
```
This comment sequence is what is used in `C++` code, but you can use it
_anywhere_ in the mrgsolve model specification file.
## Code blocks {#sec-code-blocks}
### About code blocks
__Block identifier__
Different types of code are organized in the model specification file and
separated by block identifiers. There are two ways to formulate block
identifiers that can be used in mrgsolve. In the first type, a dollar-sign is
placed at the start of the block name
```{c,eval=FALSE}
$BLOCKNAME
<block-code>
```
For example, a block of parameters would be
```{c, eval=FALSE}
$PARAM
CL = 1
```
The second way to write this is with brackets
```{c, eval=FALSE}
[ BLOCKNAME ]
<block-code>
```
There is no functional difference between the dollar-sign notation and the
brackets. When model specification code is saved into a file with a `.cpp`
extension, the code editor may make certain assumptions about formatting or
styling the code. Using brackets will most-likely work better with the
editor in that case.
Block identifiers are case-insensitive so all of these also work
```{c, eval = FALSE}
$param
CL = 1
```
```{c, eval = FALSE}
[ param ]
CL = 1
```
Users are free to include block code on the same line as the block identifier,
but must include a space after the identifier. For example, the parser will
recognize `$PARAM CL = 1` but not `$PARAMCL=1` as parameters.
__Block syntax__
Different blocks may require different syntax. For example, code written in
`$PARAM` will be parsed by the `R` parser and will generally need to adhere to
`R` syntax requirements. On the other hand, code in `$MAIN`, `$ODE`, and
`$TABLE` will be used to make functions in `C++` and therefore will need to be
valid `C++` code, including terminal `;` on each line.
__Block options__
Options may be specified on some code blocks that signal how the code is
to be parsed or used in the simulation.
Block options can be boolean in which case you indicate the option name
with nothing following. For example, to indicate `block = TRUE` for an
OMEGA matrix, write
```{c, eval = FALSE}
$OMEGA @block
1 2 3
```
Here `@block` indicates `block = TRUE`. Starting with mrgsolve 1.0.0, block
options can be negated by writing `!` between `@` and the option name. To
request a non-block (diagonal) OMEGA matrix
```{c, eval = FALSE}
$OMEGA @!block
1 2 3
```
But note well that diagonal is the default configuration for OMEGA, so it is
never necessary to write this.
Other non-boolean block options state the name and then a value to be assigned
to that name. For example, if we wanted to assign labels to the ETAs from
an OMEGA block, we'd write
```{c, eval = FALSE}
$OMEGA @labels ECL EVC
1 2
```
This essentially sets labels equal to the vector `c("ECL", "EVC")`.
We note two specific boolean options (`@object` and `@as_object`) that have
similar function across multiple blocks.
### Programmatic or bulk initialization
The following describes syntax for initializing blocks as R objects using
R code. This can be helpful, say, when you need to initialize a 50x50
OMEGA matrix or a series of systematically named parameters. We will describe
the `@object` and `@as_object` options that are available on select blocks.
The `@object` option lets you name an object defined in `$ENV` to use to
instantiate the block data. For example, to specify a series of parameters
using the `@object` option, you'd write
```{c, eval = FALSE}
$ENV
params <- list(CL = 1, V = 20, KA = 1.2)
$PARAM @object params
```
This tells mrgsolve that there is an object called `params` that it is in
the `$ENV` environment and mrgsolve will use that to define the names and
values. This is a trivial example to show how a simple series of parameters
could be defined. However, the intended use for this functionality is to allow
efficient creation of a large, systematically-named series of parameters in
a large model.
The `@as_object` option is a boolean option that tells mrgsolve that the
block code will actually return the object (rather than asking mrgsolve to
look in `$ENV` for the object). The equivalent specification for the block
above would be:
```{c, eval = FALSE}
$PARAM @as_object
list(CL = 1, V = 20, KA = 1.2)
```
The following blocks contain both the `@object` and `@as_object` options:
- `$PARAM`
- `$INPUT`
- `$THETA`
- `$CMT`
- `$INT`
- `$OMEGA`
- `$SIGMA`
Please see the specific block documentation for more details on the specific
type of object that should be returned when this syntax is invoked.
### `$PROB` \ {#sec-block-prob}
__Syntax__: text
__Multiple allowed__: yes
__Options__: `@annotated`, `@covariates`
Use this block to make notes about the model. There are no restrictions on the
text that gets entered here. mrgsolve does not routinely process the text
in any way, except when rendering the model as a document. Frequently, we
write the text here in markdown format so that it will render nicely in the
model document. But this is completely optional.
See the annotated model in @sec-topic-annotated for an example.
### `$PARAM` \ {#sec-block-param}
__Syntax__: R
__Multiple allowed__: yes
__Options__: `@annotated`, `@covariates`, `@tag`, `@input`, `@object`, `@as_object`
Define the parameter list in the current model. Parameters are names associated
with values that can be used throughout the model. A value must be given
for every parameter name. Names (and numbers) of parameters must be set at the
time the model is compiled, but parameter values may be updated without
re-compiling the model.
The `@covariates` option allows you to tag a collection of parameters as
"covariates". It does not change the functionality of the model or simulation
workflow in any way, but allows you to get that list of covariate names out
of the model object.
The `@input` option adds a tag to the parameters in the block so that input
data sets will be checked for these parameters when `check_data_names()` is
called. Use the `@tag` option and supply a user-defined tag that can also be
used for checking data sets and parameters.
Example:
```{c, eval=FALSE}
[ PARAM ] CL = 1, VC = 20, KA = 1.2
KM = 25, VMAX = 400, FLAG = 1, WT = 80
SEX = 0, N = sqrt(25)
```
Note that the "values" in the parameter list will get evaluated by the R
interpreter and the evaluation will happen inside the environment which is
defined by the `$ENV` block. For example
```{c, eval = FALSE}
$ENV MWT = 1.2
$PARAM
WT = 80 * 2.2
MASS = 600 * MWT
```
Annotated example:
```{c, eval=FALSE}
[ PARAM ] @annotated
CL : 1 : Clearance (L/hr)
VC : 20 : Volume of distribution (L)
KA: 1.2 : Absorption rate constant (1/hr)
```
See the `popex` model for an example of using `@covariates`
```{r, include = FALSE, message = FALSE}
obj <- as.list(mod <- modlib("popex", compile = FALSE))
```
```{r, echo = FALSE}
blocks(mod, PARAM)
```
then
```{r, eval = FALSE}
mod <- modlib("popex")
```
```{r}
as.list(mod)$covariates
```
Notes:
* Multiple blocks are allowed
* Values are evaluated by the `R` interpreter
The `@object` and `@as_object` options should name or return a named list of
parameters.
See also: @sec-block-input, @sec-block-theta and @sec-block-fixed.
See `?param` in the `R` help system after loading mrgsolve.
### `$INPUT` \ {#sec-block-input}
__Syntax__: R
__Multiple allowed__: yes
__Options__: `@annotated`, `@covariates`, `@tag`, `@object`, `@as_object`
This block operates just like $PARAM (@sec-block-param), in that it is a way
to introduce parameters in to the model. Additionally, the `@input` tag is
added to the model parameters and input data sets will be checked for these
parameters when `check_data_names()` is called.
See also: @sec-block-param, @sec-block-theta, @sec-block-fixed.
### `$FIXED` \ {#sec-block-fixed}
__Syntax__: R
__Multiple allowed__: yes
__Options__: `@annotated`, `@object`, `@as_object`
Like `$PARAM`, `$FIXED` is used to specify `name=value` pairs. Unlike
`$PARAM`, however, the values associated with names in `$FIXED` are not able
to be updated.
By default, names in `$FIXED` are associated with their value through a
`C++` preprocessor `#define` statement.
Usually, `$FIXED` is only used when there are a very large number of
parameters ($>$ 100 or 200). When some of these parameters never need
to be updated, you can move them to a `$FIXED` block to get a modest gain
in efficiency of the simulation.
Items in `$FIXED` will not be shown when parameters are queried.
Example:
```{c,eval=FALSE}
[ PARAM ] CL = 2, VC = 20
[ FIXED ]
g = 9.8
```
Annotated example:
```{c, eval=FALSE}
$FIXED @annotated
g : 9.8 : Acceleration due to gravity (m/s^2)
```
See also: @sec-block-param and @sec-block-theta.
Notes:
* Multiple blocks are allowed
* Values are evaluated by the `R` interpreter
### `$CMT` and `$INIT`
__Syntax__: text
__Multiple allowed__: yes
__Options__: `@annotated`, `@object`, `@as_object`
Declare the names of all compartments in the model.
* For `$CMT` give the names of compartments; initial values are assumed to be 0
* For `$INIT` give the name and initial value for all compartments
Note that both `$CMT` and `$INIT` declare compartments, so any compartment name
should get declared in either `$CMT` or `$INIT`, but never both.
Examples:
```{c,eval=FALSE}
[ CMT ] GUT CENT RESPONSE
```
```{c,eval=FALSE}
[ INIT ] GUT = 0, CENT = 0, RESPONSE = 25
```
Annotated examples:
```{c, eval=FALSE}
[ CMT ] @annotated
GUT : Dosing compartment (mg)
CENT : Central PK compartment (mg)
RESPONSE : Response
```
```{c, eval=FALSE}
$INIT @annotated
GUT : 0 : Dosing compartment (mg)
CENT : 0 : Central PK compartment (mg)
RESPONSE : 25 : Response
```
The `@object` and `@as_object` options should name or return a named list of
compartments and initial values when used in `$INIT` and a character vector
of compartment names when used in `$CMT`.
See `?init` in the `R` help system after loading mrgsolve.
### `$MAIN` \ {#sec-block-main}
__Syntax__: C++
__Multiple allowed__: no
__Options__: `@check_modeled_infusions`
This code block has two main purposes:
* Derive new algebraic relationships between parameters, random, effects and
other derived variables
* Set the initial conditions for model compartments
For users who are familiar with NONMEM, `$MAIN` is similar to `$PK`.
`$MAIN` is wrapped into a `C++` function and compiled / loaded by mrgsolve.
The `MAIN` function gets called just prior to advancing the system from the
current time to the next time for each record in the data set. `$MAIN` also
gets called several times before starting the problem (`NEWIND == 0`) and
just prior to simulating each individual (`NEWIND == 1`). Finally, `$MAIN`
gets called every time the model initial conditions are queried with `init()`.
New variables may be declared in `$MAIN`. See @sec-new-variables for details.
Examples:
```{c,eval=FALSE}
[ CMT ] CENT RESP
[ PARAM ] KIN = 100, KOUT = 2, CL = 1, VC = 20
[ MAIN ]
RESP_0 = KIN/KOUT;
double ke = CL/VC;
```
Note that `@check_modeled_infusions` block option defaults to true. To turn off
warnings from mrgsolve when checking modeled infusions against the data set
`RATE`, use the negation: `@!check_modeled_infusions`. mrgsolve will always
error when an infusion resolves to a negative rate or duration.
### `$PK` \ {#sec-block-pk}
This is an alias for `$MAIN`.
### `$ODE` \ {#sec-block-ode}
__Syntax__: C++
__Multiple allowed__: yes
__Options__: `@param`
Use `$ODE` to define model differential equations. For all compartments assign
the value of the differential equation to `dxdt_CMT` where `CMT` is the name
of the compartment. The `dxdt_` equation may be a function of model
parameters (via `$PARAM`), the current value of any compartment (`CMT`)
or any user-derived variable.
For example:
```{c,eval=FALSE}
[ CMT ] GUT CENT
[ ODE ]
dxdt_GUT = -KA*GUT;
dxdt_CENT = KA*GUT - KE*CENT;
```
It is important to make sure that there is a `dxdt_` expression defined for
every compartment listed in `$CMT` or `$INIT`, even if it is `dxdt_CMT = 0;`
The `$ODE` function is called repeatedly during a simulation run. So it is
wise to do as many calculations as possible outside of `$ODE`, usually in
`$MAIN`. But remember that any calculation that depends on an amount in a
compartment and helps determine the `dxdt_` expression in a model must be
written in `$ODE`.
New variables may be declared in `$ODE`. See @sec-new-variables
for details.
For example:
```{c,eval=FALSE}
$CMT CENT RESP
$PARAM VC = 100, KE = 0.2, KOUT = 2, KIN = 100
$ODE
double CP = CENT/VC;
double INH = CP/(IMAX+CP)
dxdt_CENT = -KE*CENT;
dxdt_RESP = KIN*(1 - INH) - RESP*KOUT;
```
If the model needs to refer to the current time, use the `SOLVERTIME` variable.
Notes:
* `$ODE` is written in `C++` syntax; every line must end in `;`
* There may be only one `$ODE` block in a model
### `$DES` \ {#sec-block-des}
This is an alias for `$ODE`.
### `$TABLE` \ {#sec-block-table}
__Syntax__: C++
__Multiple allowed__: yes
Use `$TABLE` to interact with parameters, compartment values, and other
user-defined variables __after__ the system advances to the next time.
For example:
```{c,eval=FALSE}
[ TABLE ]
double CP = CENT/VC;
```
__NOTE__
mrgsolve formerly had a `table()` macro for inserting derived values into
simulated output. This macro has been deprecated. The only way to insert
derived values into the simulated output is via `$CAPTURE`.
__NOTE__
When variables are marked for capture (see @sec-block-capture), the values of
those variables are saved at the __end__ of the `$TABLE` function. This process
is carried out automatically by mrgsolve and therefore requires no user
intervention.
### `$ERROR` \ {#sec-block-error}
This is an alias for `$TABLE`.
### `$EVENT` \ {#sec-block-event}
__Syntax__: C++
__Multiple allowed__: no
__mrgsolve version__: >= 1.5.2
Use the `$EVENT` block to write code to implement doses or other modeled events
inside your model file. `$EVENT` functions just like `$ERROR` (or `$TABLE`),
but it gets called just prior to `$ERROR`. This lets you set up modeled doses
or events for execution "now" and also seem them in the simulated output on
that same record. For example
```{r}
#| eval: false
$EVENT
if(NEWIND > 1) return;
evt::ev dose = evt::bolus(250, 2);
evt::ii(dose, 12);
evt::ss(dose, 1);
evt::addl(dose, 9)
self.push(dose);
```
**A subtle difference between `$ERROR` and `$EVENT`**
Coding modeled events in `$EVENT` rather than `$TABLE` will give a very limited
and subtle difference in output that you will most likely see when you
administer a bolus dose to a compartment you are watching (e.g. a bolus to the
central compartment). Using `$EVENT` will let you see the result of the dose
immediately - on the record where the dose code is executed; when `$TABLE` is
used, you will only see the result of that dose on subsequent output records.
You'd see a difference between `$TABLE` and `$EVENT` behavior when you bolus
into a depot compartment too, but you probably aren't noticing because you are
likely monitoring the central compartment, not the depot. Regardless, the
`$TABLE` / `$EVENT` difference is just bookkeeping for the current record; you
might see that bookkeeping difference on the current record, but the difference
will not factor into how the system advances beyond that record.
**The key point for using `$EVENT`**
For the time being, the important thing to remember when you want to dose
"now" (not some time in the future) is those interventions should be coded into
`$EVENT` (or `$ERROR`) and they will happen right after the system advances
in time on the current record, not prior to advancing in time for the next
record. I recommend you always use `$EVENT` or `$TABLE` to execute doses or
other events from inside your model. This distinction only applies to doses
happening "now"; there is no difference in behavior when the dose is scheduled
to happen at a future time.
### `$PREAMBLE` \ {#sec-block-preamble}
__Syntax__: C++
__Multiple allowed__: no
This is the fourth C++ code block. It is called once in two different settings
(@sec-section-sequence):
1. Immediately prior to starting the simulation run
1. Immediately prior to calling `$MAIN` when calculating initial conditions
`$PREAMBLE` is a function that allows you to set up your C++ environment. It is
only called one time during the simulation run (right at the start). The code
in this block is typically used to configure or initialize C++ variables or data
structures that were declared in `$GLOBAL`.
For example:
```{c,eval=FALSE}
[ PLUGIN ] Rcpp
[ GLOBAL ]
namespace{
Rcpp::NumericVector x;
}
[ PREAMBLE ]
x.push_back(1);
x.push_back(2);
x.push_back(3);
[ MAIN ]
<some code that uses x vector>
```
In this example, we want to use a numeric vector `x` and declare it in `$GLOBAL`
so that we can use it anywhere else in the code (the declaration is also made in
an unnamed namespace to ensure that the variable is local to the model file).
Then, in `$PREAMBLE`, we put 3 numbers into the vector and we use `x` in
`$MAIN`. Since `$MAIN`, `$TABLE` and (especially) `$ODE` are called repeatedly
as the simulation run progresses, we put the initialization of `x` in `$PREAMBLE`
to make sure the initialization of `x` only happens once.
Notes:
* `$PREAMBLE` is written in `C++` syntax; every line must end in `;`
* There may be only one `$PREAMBLE` block in a model
* Like `$MAIN`, `$ODE` and `$TABLE`, `double`, `int` and `bool` variables
initialized in `$PREAMBLE` are actually initialized for global (within the
model file)
See also: @sec-section-sequence and @sec-block-plugin.
### `$PRED` \ {#sec-block-pred}
__Syntax__: C++
__Multiple allowed__: no
Use `$PRED` to write a model without differential equations. In this block,
write all algebraic expressions for derived parameters, the response, and
any other derived output quantities.
For example:
```{c, eval=FALSE}
[ PARAM ] TVE0 = 100, AUC50 = 100, IMAX = 40, AUC = 0
[ PRED ]
double E0 = EVE0*exp(ETA(1));
double RESP = E0 - IMAX*AUC/(AUC50+AUC);
```
In this example, the entire model is written in the `$PRED` block. It is an
error to include the following blocks when `$PRED` is being used: `$MAIN`,
`$TABLE`, `$PKMODEL`, `$ODE`, `$CMT`, `$INIT`.
See @sec-pred-data for additional information regarding data sets
in use with `$PRED` block.
### `$CAPTURE` \ {#sec-block-capture}
__Syntax__: text
__Multiple allowed__: yes
__Options__: `@annotated`, `@etas`
This is a block to identify variables that should be captured in the simulated
output. The `@etas` option is new with version 1.0.8.
For example:
```{c,eval=FALSE}
[ PARAM ] A = 1, B = 2
[ MAIN ]
double C = 3;
bool yes = true;
[ CAPTURE ] A B C yes
```
This construct will result in four additional columns in the simulated output
with names `A`, `B`, `C`, and `yes`.
Users can also rename captured variables by providing a
`newname = oldname` specification.
```{c, eval = FALSE}
$PARAM WT = 70, THETA1 = 2.2
$MAIN
double CL = THETA1*pow(WT/70,0.75)*exp(ETA(1));
$OMEGA 1
$CAPTURE WEIGHT = WT TVCL = THETA2 CL ETA(1)
```
In this example, the names of the captured data items will be
`WEIGHT,TVCL,CL,ETA_1`.
Users can use the `capture` type to declare variables in `$MAIN` and `$TABLE`.
`capture` types are really `double`s, but using that type will signal mrgsolve
to automatically capture that value. For example:
```{c,eval=FALSE}
$PARAM VC = 300
$CMT CENT
$TABLE
capture DV = (CENT/VC);
```
Since we used type `capture` for `DV`, `DV` will show up as a column in the
simulated data.
Annotated example:
```{c,eval=FALSE}
$MAIN
double CLi = TVCL*exp(ECL);
$TABLE
double DV = (CENT/VC)*exp(PROP);
$CAPTURE @annotated
CLi : Individual clearance (L/hr)
DV : Plasma concentration (mcg/ml)
```
Use the `@etas` option to specify an expression that evaluates to integers
which identify the `ETA` number(s) to capture. For example
```{c, eval = FALSE}
$OMEGA 0.1 0.2 0.3
$CAPTURE @etas 1:LAST
CL DV
```
Will capture all three `ETA`s into the simulation outputs. NONMEM-style
names will be used (e.g. `ETA1`). This is in contrast to the names that are
generated when `ETA(1)` is captured; in this case, the parens are removed and
replaced with `_` so the output name is `ETA_1`. mrgsolve will provide `LAST`
(and `last`) which will evaluate to the maximum number of `ETAs` in the problem
(in this case, 3). You can write any valid expression in `@etas`. When the
expression is evaluated, it will be evaluated in the model environment created
through the `$ENV` block (@sec-block-env).
::: {.callout-tip}
In addition to listing model variables for output in the `$CAPTURE` block,
users can "dynamically" capture model variables through the `capture`
argument to [`mread()`](https://mrgsolve.org/docs/reference/mread.html). These
may be model parameters (listed in `$PARAM`) or user-defined model variables.
To get a listing of available user-defined variables, you can use
```{r}
#| eval: false
mod <- house()
as.list(mod)$cpp_variables
```
:::
### `$OMEGA` \ {#sec-block-omega}
__Syntax__: text
__Multiple allowed__: yes
__Options__: `@annotated`, `@block`, `@correlation`, `@labels`, `@name`, `@object`, `@as_object`
See `?modMATRIX` for more details about options for this block.
Use this block to enter variance/covariance matrices for subject-level random
effects drawn from multivariate normal distribution. All random effects are
assumed to have mean of 0. Off diagonal elements for block matrices are assumed
to be correlation coefficients if the `@correlation` option is used (see below).
By default, a __diagonal__ matrix is assumed. So:
```{c, eval=FALSE}
$OMEGA
1 2 3
```
will generate a 3x3 omega matrix.
A __block__ matrix may be entered by using `block = TRUE`. So:
```{c, eval = FALSE}
$OMEGA @block
0.1 0.02 0.3
```
will generate a 2x2 matrix with covariance 0.02.
A 2x2 matrix where the off-diagonal element is a correlation, not a covariance
can be specified like this:
```{c,eval=FALSE}
$OMEGA @correlation
0.1 0.67 0.3
```
Here, the correlation is 0.67. mrgsolve will calculate the covariances and
substitute these values. The matrix will be stored and used with these
covariances, not the correlation.
A name can be assigned to each matrix:
```{c, eval=FALSE}
$OMEGA @name PK @block
0.2 0.02 0.3
$OMEGA @name PD
0.1 0.2 0.3 0.5
```
to distinguish between multiple `$OMEGA` blocks and to facilitate updating
later. The model in the preceding example will have two `$OMEGA` matrices:
2x2 and 4x4.
Labels can be assigned which function as aliases for the different `ETAs`
```{c, eval = FALSE}
$OMEGA @block @labels ETA_CL ETA_V
0.1 0.05 0.2
```
The number of labels should match the number of rows (or columns) in the
matrix.
Annotated example (diagonal matrix):
```{c, eval=FALSE}
$OMEGA @annotated
ECL: 0.09 : ETA on clearance
EVC: 0.19 : ETA on volume
EKA: 0.45 : ETA on absorption rate constant
```
Annotated example (block matrix):
```{c, eval=FALSE}
$OMEGA @annotated @block
ECL: 0.09 : ETA on clearance
EVC: 0.001 0.19 : ETA on volume
EKA: 0.001 0.001 0.45 : ETA on absorption rate constant
```
The `@object` and `@as_object` options should name or return a square numeric
matrix. If `rownames` are included in the matrix, then they will be used to
form labels for the realized ETAs. For example, we can initialize a very
large `$OMEGA` matrix with
```{c, eval = FALSE}
$OMEGA @as_object
n <- 20
lbl <- paste0("ETA_", LETTERS[1:n])
matrix(0, 20, 20, dimnames = list(lbl, lbl))
```
Note: this only initializes the matrix; you will (likely) need to update it
with meaningful values after the model is loaded (@sec-matrix-chapter).
### `$SIGMA` \ {#sec-block-sigma}
__Syntax__: text
__Multiple allowed__: yes
__Options__: `@annotated`, `@block`, `@correlation`, `@labels`, `@name`, `@object`, `@as_object`
See `?modMATRIX` for more details about options for this block.
Use this block to enter variance/covariance matrices for within-subject random
effects drawn from multivariate normal distribution. All random effects are
assumed to have mean of 0. Off diagonal elements for block matrices are assumed
to be correlation coefficients if the `@correlation` option is used (see below).
The `@object` and `@as_object` options should name or return a square numeric
matrix. If `rownames` are included in the matrix, then they will be used to
form labels for the realized EPS values.
The `$SIGMA` block functions like the `$OMEGA` block. See `$OMEGA` for details.
### `$SET` {#sec-block-set}
__Syntax__: R
__Multiple allowed__: no
Use this code block to set different options for the simulation. Use a
`name = value` format, where `value` is evaluated by the `R` interpreter.
Most of the options that can be entered in `$SET` are passed to `update`.
For example:
```{c,eval=FALSE}
[ SET ] end = 240, delta = 0.5, req = "RESP"
```
Here, we set the simulation `end` time to 240, set the time difference between
two adjacent time points to 0.25 time units, and request only the `RESP`
compartment in the simulated output.
### `$GLOBAL`
__Syntax__: C++
__Multiple allowed__: no