Movatterモバイル変換


[0]ホーム

URL:


openmpp

DOILifecycle: stableR-CMD-check

The goal ofopenmpp is to provide a programmaticinterface to the OpenM++ API directly from R to simplify creatingscenarios, running models, and gathering results for furtherprocessing.

Installation (R Package)

You can install the development version ofopenmpp fromGitHub with:

# install.packages("remotes")remotes::install_github("mattwarkentin/openmpp")

Installation (OpenM++)

If you do not have access to an existing OpenM++ server, you candownload and install OpenM++ locally and run a local server on yourworkstation. Theopenmpp package can then connect to thislocal server instance.

Download

For most users, the best way to install OpenM++ locally is todownload the pre-compiled binaries. To install OpenM++, download andunzip the “Source code and binaries” appropriate for your operatingsystem. The latest release of OpenM++ can be found here:https://github.com/openmpp/main/releases/latest.Pre-compiled binaries are available for Mac (Intel and Arm), Windows,and several common Linux distributions (Debian, Ubuntu, RedHat).

NOTE: Windows may allow you to view the contents of the zip directorywithout extracting, however, the files must be extracted for theinstallation to function properly.

Running OpenM++ on Windows

Enter the OpenM++ directory using the File Explorer. Right-clickanywhere inside the folder and select “Open in Terminal”.

In the Windows Terminal, enter the following command:

.\bin\oms.exe

This will start the process responsible for running the OpenM++ webservice (OMS). Note that the local host address will be printed in theconsole and is the address used by theopenmpp R package tocommunicate with the API. This local host address will be set as theOPENMPP_LOCAL_URL. See the Usage section for moredetails.

Running OpenM++ on MacOS

Open a new MacOS Terminal window (either by using Spotlight Search orby navigating to “Applications” and then “Utilities” in Finder).

After unzipping the downloaded directory in Finder, drag the folderinto the terminal and press Enter. This will change your activedirectory to the OpenM++ folder.

Enter the following command into the terminal:

bin/oms

Similar to the Windows installation, the web service (OMS) willinitiate and the local host address will be shared with the R packagefor API communication.

Usage

Theopenmpp package contains many functions that provideaccess to nearly every OpenM++ API endpoint. However, users of thispackage will typically only use a smaller set of functions for mostcommon tasks.

User Authentication

Each user is required to set their local or remote host address(i.e., URL) for the OpenM++ API in their global or project-specific.Renviron file in order for theopenmpppackage to authenticate and communicate with the API on behalf of theuser.

If you are working in an IDE (e.g., Positron, RStudio), you mayconsider using the following functionusethis::edit_r_environ() to open your.Renviron file for editing. Note that you will need torestart your R session after editing the file for the effect to takeplace.

For an API running locally, set the following environment variable inyour.Renviron file:

OPENMPP_LOCAL_URL=http://localhost:XXXX

WhereXXXX is the four digits corresponding to yourspecific local host address (typically 4040 is used). The local hostaddress is printed to the console when starting the OpenM++ web servicein the terminal.

This package also provides the ability to remotely connect to OpenM++using JWT tokens. For an API running remotely, set the followingenvironment variables in your.Renviron file:

OPENMPP_REMOTE_URL=...OPENMPP_REMOTE_USER=...OPENMPP_REMOTE_PWD=...

If you aren’t sure of your remote URL or your username/password, youmay contact your OpenM++ administrator to retrieve this information.Note that the URL, user name, and password should be kept confidentialand not committed into version control (e.g., git).

Once the environment variables are set, users may register a local orremote API connection in their R scripts.

library(openmpp)use_OpenMpp_local()

Or,

library(openmpp)use_OpenMpp_remote()

see?use_OpenMpp_local or?use_OpenMpp_remote for more information.

Main Functions

Models, Scenarios, Runs, andRunSets

There are 4 main classes you will work with when using theopenmpp package:OpenMppModel,OpenMppWorkset,OpenMppModelRun, andOpenMppModelRunSet. Each of these areR6classes.R6 is an encapsulated object-oriented programming(OOP) system for R. Use theload_*() set of functions toload a model, workset/scenario, model run, or set of model runs intomemory.

Instances of each of these 4 classes have methods (i.e., functions)and fields (i.e., data) associated with them. You can access thesefunctions and data using the standard$ subset operator(e.g.,obj$function() orobj$data).

Why use R6? We chose to use the R6 OOP as we believeit can simplify the ability for the R package to communicate withOpenM++ to ensure that all changes made to the microsimulation objectsin the R session are propagated and synchronized with the OpenM++database. Encapsulated OOP allows the internal state of the object(i.e., the connection to the actual object in the OpenM++ database) tobe accessed and modified through well-defined and high-level methods,rather than directly manipulating the data with low-level functioncalls. This approach enforces data integrity, improves code readability,and simplifies maintenance by abstracting away the implementationdetails of an object and preventing unintended modifications to itsstate. More information aboutR6 can be foundhere.

Developing New Models

Developing new microsimulation or agent-based models in OpenM++ isbeyond the scope of this package. In-depth information on modeldevelopment can be found here:https://github.com/openmpp/openmpp.github.io/wiki/Model-Development-Topics.

Example

Next, we will work through a very simple example of creating a newscenario, extracting parameters to change, changing parameters, runningthe model, and extracting results. This example will use theRiskPaths model that comes with the OpenM++ software.RiskPaths is a simple, competing risk, case-based continuous timemiscrosimulation model (MoreInformation).

To run this example, you must have installed OpenM++, initiated theOpenM++ web service (OMS) in the shell, and configured the R packageusing the instructions above.

library(openmpp)use_OpenMpp_local()

Let’s see what models are available:

get_models()#> # A tibble: 9 × 7#>   ModelId Name               Digest  Type Version CreateDateTime DefaultLangCode#>     <int> <chr>              <chr>  <int> <chr>   <chr>          <chr>#> 1     101 IDMM               bd573…     1 2.0.0.0 2025-06-01 17… EN#> 2     101 NewCaseBased       be317…     0 1.0.0.0 2025-06-01 17… EN#> 3     101 NewCaseBased_bili… 2a78a…     0 1.0.0.0 2025-06-01 17… EN#> 4     101 NewTimeBased       49cec…     1 1.0.1.0 2025-06-01 17… EN#> 5     101 OzProjGenX         1da1c…     0 0.22.0… 2025-06-01 17… EN#> 6     101 OzProjX            2e697…     0 0.22.0… 2025-06-01 17… EN#> 7     101 RiskPaths          d976a…     0 3.0.0.0 2025-06-01 17… EN#> 8     101 SM1                db37c…     0 1.0.0.0 2025-06-01 17… EN#> 9       1 modelOne           _2012…     0 1.0     2012-08-17 16… EN

We can now see what worksets and model runs exist for a givenmodel.

get_worksets('RiskPaths')#> # A tibble: 1 × 10#>   ModelName ModelDigest     ModelVersion ModelCreateDateTime Name  BaseRunDigest#>   <chr>     <chr>           <chr>        <chr>               <chr> <chr>#> 1 RiskPaths d976aa2fb999f0… 3.0.0.0      2025-06-01 17:27:0… Defa… ""#> # ℹ 4 more variables: IsReadonly <lgl>, UpdateDateTime <chr>,#> #   IsCleanBaseRun <lgl>, Txt <list>
get_runs('RiskPaths')#> # A tibble: 1 × 15#>   ModelName ModelDigest          ModelVersion ModelCreateDateTime Name  SubCount#>   <chr>     <chr>                <chr>        <chr>               <chr>    <int>#> 1 RiskPaths d976aa2fb999f097468… 3.0.0.0      2025-06-01 17:27:0… Risk…        1#> # ℹ 9 more variables: SubStarted <int>, SubCompleted <int>,#> #   CreateDateTime <chr>, Status <chr>, UpdateDateTime <chr>, RunId <int>,#> #   RunDigest <chr>, ValueDigest <chr>, RunStamp <chr>

Now we can load theRiskPaths model to inspect.

rp<-load_model('RiskPaths')rp#> ── OpenM++ Model ───────────────────────────────────────────────────────────────#> → ModelName: RiskPaths#> → ModelVersion: 3.0.0.0#> → ModelDigest: d976aa2fb999f097468bb2ea098c4daf

We will now load theDefault set of input parameters forthe RiskPaths model.

rp_default<-load_scenario('RiskPaths','Default')rp_default#> ── OpenM++ Workset (ReadOnly) ──────────────────────────────────────────────────#> → ModelName: RiskPaths#> → ModelVersion: 3.0.0.0#> → ModelDigest: d976aa2fb999f097468bb2ea098c4daf#> → WorksetName: Default#> → BaseRunDigest:

Finally, we will load the base run for the RiskPaths model.

baserun_digest<- rp$ModelRuns$RunDigest[[1]]rp_baserun<-load_run('RiskPaths', baserun_digest)rp_baserun#> ── OpenM++ ModelRun ────────────────────────────────────────────────────────────#> → ModelName: RiskPaths#> → ModelVersion: 3.0.0.0#> → ModelDigest: d976aa2fb999f097468bb2ea098c4daf#> → RunName: RiskPaths_Default#> → RunDigest: 40669534e0f7ecc1d5ed55652e2e07e3

We will create a new scenario based on the parameters from theRiskPaths_Default model run.

create_scenario('RiskPaths','MyNewScenario', baserun_digest)

We will load the new scenario, copy over theAgeBaselinePreg1 parameter from the base run.

my_scenario<-load_scenario('RiskPaths','MyNewScenario')

Let’s reduce the fertility rate by 10% across all age groups…

my_scenario$copy_params('AgeBaselinePreg1')
library(dplyr)current_rates<- my_scenario$Parameters$AgeBaselinePreg1reduced_rates<-  current_rates|>mutate(across(-sub_id, \(x) x*0.9))my_scenario$Parameters$AgeBaselinePreg1<- reduced_rates

We will now run the model and give it the name'ExampleRun'. We use thewait = TRUE flag tomake sure we want for the model run to finish before returning to our Rsession. We useprogress = FALSE to avoid printing progressbars in this document. Note that model runs may take a long time whenthe number of simulation cases is large.

my_scenario$ReadOnly<-TRUEmy_scenario$run('ExampleRun',wait =TRUE,progress =FALSE)

Note that we can use theopts argument and theopts_run() function to configure our run. By default,models are run with 5,000 simulation cases and 12 SubValues. This allowsfor quick model runs and faster iteration, but users will want toincrease the number of simulation cases when performing a full modelrun.

Now that our model run is complete, let’s load it into memory.

example_run<-load_run('RiskPaths','ExampleRun')example_run#> ── OpenM++ ModelRun ────────────────────────────────────────────────────────────#> → ModelName: RiskPaths#> → ModelVersion: 3.0.0.0#> → ModelDigest: d976aa2fb999f097468bb2ea098c4daf#> → RunName: ExampleRun#> → RunDigest: e2c64228dbbaeef02e074013aaeebf38

We can now extract an output table from theTables fieldin the model run object (example_run$Tables).

example_run$Tables$T06_BirthsByUnion#> # A tibble: 7 × 3#>   expr_name Dim0                   expr_value#>   <chr>     <chr>                       <dbl>#> 1 Expr0     US_NEVER_IN_UNION         1205.#> 2 Expr0     US_FIRST_UNION_PERIOD1    2944.#> 3 Expr0     US_FIRST_UNION_PERIOD2     333.#> 4 Expr0     US_AFTER_FIRST_UNION        10.0#> 5 Expr0     US_SECOND_UNION             72.0#> 6 Expr0     US_AFTER_SECOND_UNION        1.00#> 7 Expr0     all                       4565.

Great, we have created a new scenario, modified some parameters, ranthe model, and extracted output tables. In this last step, we will loadmultiple model runs into memory to compare them.

rp_runs<-load_runs('RiskPaths', rp$ModelRuns$RunDigest)rp_runs#> ── OpenM++ ModelRunSet ─────────────────────────────────────────────────────────#> → ModelName: RiskPaths#> → ModelVersion: 3.0.0.0#> → ModelDigest: d976aa2fb999f097468bb2ea098c4daf#> → RunNames: [RiskPaths_Default, ExampleRun]#> → RunDigests: [40669534e0f7ecc1d5ed55652e2e07e3, e2c64228dbbaeef02e074013aaeebf38]

We will extract a new table from both models. Note that an extracolumn,RunName is added to indicate which model run theoutput table data corresponds to.

births<- rp_runs$Tables$T06_BirthsByUnionbirths#> # A tibble: 14 × 4#>    RunName           expr_name Dim0                   expr_value#>    <chr>             <chr>     <chr>                       <dbl>#>  1 RiskPaths_Default Expr0     US_NEVER_IN_UNION         1285#>  2 RiskPaths_Default Expr0     US_FIRST_UNION_PERIOD1    2986#>  3 RiskPaths_Default Expr0     US_FIRST_UNION_PERIOD2     293#>  4 RiskPaths_Default Expr0     US_AFTER_FIRST_UNION        11#>  5 RiskPaths_Default Expr0     US_SECOND_UNION             57#>  6 RiskPaths_Default Expr0     US_AFTER_SECOND_UNION        1#>  7 RiskPaths_Default Expr0     all                       4633#>  8 ExampleRun        Expr0     US_NEVER_IN_UNION         1205.#>  9 ExampleRun        Expr0     US_FIRST_UNION_PERIOD1    2944.#> 10 ExampleRun        Expr0     US_FIRST_UNION_PERIOD2     333.#> 11 ExampleRun        Expr0     US_AFTER_FIRST_UNION        10.0#> 12 ExampleRun        Expr0     US_SECOND_UNION             72.0#> 13 ExampleRun        Expr0     US_AFTER_SECOND_UNION        1.00#> 14 ExampleRun        Expr0     all                       4565.

We can even plot this usingggplot2! Note that thenumber of simulation cases forExampleRun islow so the results are not to be trusted! This is onlyfor demonstration purposes.

library(ggplot2)births|>ggplot(aes(Dim0, expr_value,fill = RunName))+geom_col(position =position_dodge())+labs(x =NULL,y ='Number of births by union')+coord_flip()+theme_minimal()+theme(legend.position ='bottom')

When we are sure we no longer need a scenario or model run, we canusedelete_scenario() ordelete_run() to cleanthings up!

Contributor Guidelines

Contributions to this package are welcome. The preferred method ofcontribution is through a GitHub pull request. Before contributing,please file an issue to discuss the idea with the project team. Moredetails on contributing can be found in theCONTRIBUTINGdocument.

Code of Conduct

Please note that theopenmpp project is released with aContributorCode of Conduct. By contributing to this project, you agree to abideby its terms.


[8]ページ先頭

©2009-2025 Movatter.jp