VisionEval / VisionEval-Dev

Development version of VisionEval framework
https://visioneval.github.io/
Apache License 2.0
6 stars 32 forks source link

VisionEval

VisionEval is a model system and supporting software framework for building collaborative disaggregate strategic planning models.

NOTE ON WEBSITE: The VisionEval website can be found at https://VisionEval.github.io The previous domain name (visioneval.org) will continue to redirect to the new Github loacation but users and developers are encouraged to update their bookmarks.

The development branch is the basis for development of new features and fixes to VisionEval. All new development should be based on the development branch.

Thanks for your cooperation. If you have questions or complaints, please contact jeremy.raw at dot.gov.

Documentation

Documentation for VisionEval is online at https://visioneval.github.io/docs

Release

You can retrieve the current binary release of VisionEval from https://visioneval.github.io/category/download.html

Detailed release notes are found in the "release-notes" directory of repository.

VisionEval Repositories

There are five repositories in the VisionEval organization to serve different purposes:

Issues

Please submit issues, bugs, or feature requests about VisionEval on the VisionEval-Dev issues page.

Please submit issues or content change requests about the VisionEval.org website on the VisionEval.org issues page.

For Developers: Building

To modify and rebuild the released VisionEval system, you can clone a suitable branch (either "main" or "development") from the "development" repository: VisionEval-Dev repository.

Here are the build steps:

  1. Clone the Github
  2. Start VisionEval-dev.Rproj in the root directory, or you can use launch.bat to start the standard R GUI. You do NOT need RStudio to build or run VisionEVal, just a compatible version of R. If you use launch.bat, you will need to set the R_HOME environment variable or edit the script itself to point at your version of R. Supported R versions are listed in build/R-versions.yml.
  3. Run ve.build() to construct the packages
  4. Run ve.run() to launch the runtime (note that the built "runtime" is only used indirectly)
    1. VisionEval runs in the new "runtime.test" directory
    2. You can set a directory of your choice selected either by passing it as a parameter (ve.run('myRuntimeDirectory")) or by setting the VE_RUNTIME environment variable either as a system or user environment variable, or by defining it in the .Renviron file that is created in the repository root when you run ve.build(). A complete working runtime will be created in VE_RUNTIME if it does not already exist
  5. Once running, do walkthrough() or run ve.test() (with no parameters) to get a list of sample scripts illustrating basic functions (all to run in an additional temporary runtime to avoid confusing them with real work).
    1. walkthrough() is also available for ordinary users in the distributed runtime
    2. Run ve.test("VEModel") to load more detailed API test functions (a comprehensive exercise of what works and how).
    3. The walkthrough function creates a temporary runtime directory (to avoid trampling any real models you may have). Run exit.walkthrough() (or quit and restart the R session) to return to regular VE_RUNTIME

For Developers: Submitting changes or bug requests

If you intend to submit changes back to the VisionEval project, please clone the VisionEval-Dev repository, development branch. Pull requests against this branch are welcome (but make sure you have rebased the pull request on the current HEAD of development).

Pre-built binary installers of recently released versions (the "main" branch) are available at https://visioneval.org and as "releases" in the development branch of VisionEval-dev.

You can install the directly from a copy (.zip) or clone of this VisionEval repository branch, using the instructions in the build/Building.md file in the repository, or in the detailed installation instructions at https://visioneval.github.io/docs

You do NOT need to fork the repository unless you are planning to submit changes (pull requests) back to the VisionEval project.

Release Notes

If we remember, the latest release notes follow. If you suspect a failure to update here, please look at the release-notes folder, which is more likely to be up to date, and which also includes the notes for earlier releases.

Version 3.1.1 Release

This release (VE-3.1.1) includes VisionEval 3.0, the "Next Generation" framework, referred to here as VE-3. It includes updates from the previous releases (documented below)

Please post any issues you encounter on the VisionEval/VisionEval-dev Github repository.

Emerging documentation for this release is located at https://visioneval.github.io/docs. You can build the documentation "book" using ve.build('book') from the Github development environment (start VisionEval-dev.Rproj from the VisionEval git root). You will firstt need to check out the VisionEval-docs repository (as VisionEval-docs) adjacent to the location of your VisionEval(-dev) installation.

Interactive quick start documentation is available by running the "walkthrough()" function and stepping through the various scripts provided there. The walkthrough provides a rudimentary view of VE-3 operations.

Release 3.1.1 is the first major public release in a long time, and will appear on the main branch of the VisionEval/VisionEval repository as well as VisionEval/VisionEval-dev. There are no new functionality changes compared to VE-3.0.4 below, but a variety of bug fixes and operational improvements have been included and the overall system should be stable and buildable with current recent versions of R 4.x (2024-01-22: R 4.1.3, R 4.2.3, and R 4.3.2).

Version 3.0.4 Release

Updates in VE-3.0.4

This release introduces a simplified export process that is also more configurable. Output is available to CSV files, SQLite, and any data format supported by the R DBI database interface (including MySQL/MariaDB, PostgreSQL, SQL Service, or Microsoft Access). It is also straightforward to write results to Excel spreadsheets. The walkthrough and test functions have been updated and provide working examples of the core functionality.

Additional documentation on VE 3 will be forthcoming as the next major development effort. Also note that while VisionEval 3 supports earlier models in that it can run them, the greatest benefit will accrue to models that have been restructured into VE 3 model stages and scenarios (with different input sets and scripts appearing as alternatives within a single model).

This release is still somewhat "experimental". Please try it out (and reach out to me - jeremy.raw@dot.gov - if you need help converting your models to the new structure).

Updates from "VE-3.0.0 Release 1" to "VE-3.0.3" (prior releases)

A new "BaseScenario" parameter was added for the scenarios sub-folder "visioneval.cnf". This parameter is preferred over "StartFrom" since it only looks at the base stage setup, not the Datastore that results from it

Additional small changes were also made in Release 2:

Version 3.0.2 Release

This release (VE-3.0.2) includes VisionEval 3.0, the "Next Generation" framework, referred to here as VE-3. It includes updates from the previous release.

Installers for R 4.1.3, R 4.2.3 and R 4.3.0 are available below for the end user version in the "assets" section of this release. Alternatively, to get the latest and greatest, you may clone the Github "development" branch and build VE-3 using the standard VisionEval build tools.

Please post any issues you encounter on the VisionEval/VisionEval-dev Github repository. Numerous previous issues have been resolved in this release.

Emerging documentation for this release is located at docs.visioneval.org. You can build the documentation "book" using ve.build('book') from the Github development environment (start VisionEval-dev.Rproj from the VisionEval git root).

Interactive quick start documentation is available by running the "walkthrough()" function and stepping through the various scripts provided there. The walkthrough provides a rudimentary view of VE-3 operations.

Updates from "VE-3.0.0 Release 1" to "VE-3.0.2" (this release)

A new "BaseScenario" parameter was added for the scenarios sub-folder "visioneval.cnf". This parameter is preferred over "StartFrom" since it only looks at the base stage setup, not the Datastore that results from it

Additional small changes were also made in Release 2:

VisionEval 3.0.0 Release (VE-3)

Setting up a runtime environment

The VE-3 runtime environment has three parts:

  1. The "load directory" containing the startup scripts
    • By default, the installation location of VisionEval
    • VisionEval should be started from this folder (but it need not run models there; see "runtime directory" below)
  2. The directory containing the VisionEval R package library (ve-lib)
    • Usually located within the load directory (end user installation)
    • May instead be located adjacent to the load directory (as in the built artifacts of the Github)
  3. The "runtime directory" which contains models to be run and their results
    • You can change the runtime directory at startup by setting the VE_RUNTIME operating system environment variable
    • This scheme allows you to install new VisionEval runtimes and not overwrite (or have to copy) your previous models. You may still want to copy those models within the VE-3 environment before running them again (or just use the run("save") function the first time you run them).
    • In the development environment, what is called the "runtime" directory is used as the "load directory" and if you use "ve.run()" to launch a VisionEval run, the development environment will create a separate "runtime.test" directory where it does its work. That is to avoid accidentally overwriting models you may be developing within the Github tree.

Sample / Prototype Models

The VisionEval sample models are stored within the VisionEval packages and copies of those standard models, with a small sample dataset, can be installed using the VE-3 "installModel" function. You can access help for that function by loading the VEModel package and running ?help("installModel"). A default name is provided for the model when it is installed, and you can use that name later to re-open the model (e.g. in a new VisionEval session). The default name is constructed from the model (VERSPM, VE-State, others) and the model "variant", which describes a specific set of sample files that illustrate model structures and operations that you can adapt for your own models.

Installed models are set up in subdirectories of the "models" subdirectory of the VisionEval runtime directory. The name of the model subdirectory is the model name used by VE-3. So if your "models" directory contains a subdirectory called "myRSPM", you can use the mod <- openModel('myRSPM') function to open the model. See the R help for openModel.

Both installModel and openModel functions return model objects that contain the functions and data needed to configure, run and report results from the model. See below and the walkthrough for more information.

Setting Up and Running Models

A typical VE-3 model development process would be to install a prototype model that does what you want, and then adjust the model structure by creating your own model geography (zones), setting the model base year and run years (and adjusting the deflators.csv file), creating all the module inputs for base and future years in your baseline scenario, and once that is all running, creating scenarios (subsets of the main model that make changes to the inputs for the scenario). See docs.visioneval.org for more information.

Running existing VisionEval models... If you already have a VisionEval model, you can still run it the old way, using source("run_model.R") from the directory containing the inputs, defs, and run_model.R script. However that approach does not put full information into the model results so some of the advanced VE-3 functions for examining the model will not be available.

A better way to get your old models into VE-3 is to create a subdirectory of "models" in the runtime directory with the name of your model (say myOldModel), then use mod <- openModel('myOldModel') to open the model, and mod$run() to run it. It should (fingers crossed, file an issue if it doesn't) "just work". You don't have to change a thing, and you can still "extract" or "query" the results as usual (see below).

Re-running models VE-3 notices if you've already run your model and if you run it again, it will do nothing and report the model status (print(mod) will show you the status at any time). If the run failed for some reason, it will try to run again. To force it to throw away the previous run, do mod$run('reset'). If you want to save the previous run, do mod$run('save') and the previous results will be moved to a new timestamped directory prior to starting the whole model over again.

Parallel Processing VE-3 has a basic implementation of parallel processing. You enable it by calling the R function mod$plan(workers=3) before you do mod$run(). VE-3 will group the model stages (see below) into sets that have the same starting point (see below, StartFrom) and distributed them across the number of "workers" (CPU's) available on your computer. Note that a large VisionEval model will consume up to 7 or 8 gigabytes of memory per running stage, so the limiting factor on parallel processing is more likely to be how much RAM you have and not how many processors. The parallel processing is implemented through R's "future" package (and support from "parallely") and any type of connection you can set up that way (including clusters of machines) shoudl work "in principle" and if you'd like to figure out how to set that up, get in touch with us. The stock parallell processing implementation uses the "callr" package to set up multiple R sessions.

VE-3 Model Configuration

To enable the new VE-3 features, particularly model stage and scenario management as well as efficient extraction of results, VE-3 uses a new configuration scheme. Parameters that used to be kept separately in "defs/run_parameters.json" and in the arguments to the initializeModel function in the run_model.R script are now maintained in one or more YAML files called "visioneval.cnf" (which, if you're seriously into nostalgia, could still be a JSON file called "run_parameters.json"; it should still work). Plus there are a lot more parameters to control other features of VE-3.

You can have a global "visioneval.cnf" (where you might set your preferred DatastoreType or a common random Seed), each model must have a "visioneval.cnf" in its root directory (i.e. inside "models\myModel") that describes the base model, and if the model has stages or scenarios defined in subdirectories of the the model (see below), those can also have a "visioneval.cnf" describing how they differ from the base scenario. However, you can also configure scenarios directly in the main model "visioneval.cnf", but that gets inconvenient if you have lots of them, or if they change frequently; see below on setting up scenarios.

Model Stages

The most radical change in VE-3 (which is fully backward compatible with old models) is that models are reconceived as a series of "model stages" - units that can be run to generate output in a Datastore. A model stage can be part of a model (e.g. population synthesis, or just the base year run of the model, or whatever). A stage can have its own run_model.R script (which can have some informative name if you prefer), its own inputs, and its own outputs. All the stages share the basic model structural information: everything that is in the "defs" directory, notably "geo.csv", "units.csv" and "deflators.csv".

Stages can be connected to each other, using the "StartFrom" parameter in the stage's "visioneval.cnf" file. When the stage is run, any information that is not present in that stage will be sought in the "StartFrom" stage (and if that stage also has a StartFrom, the run will keep looking up the "ladder" of StartFrom stages until it has found everything it needs). A stage without a StartFrom needs to have all the inputs and scripts it needs in its own directories. If you have multiple stages that share the same StartFrom (e.g. future year scenarios that StartFrom the default future scenario), those can easily be run in parallel (see above); the default is to run them sequentially, which is better the first time through, since it is a bit harder to find the murder weapon if one or more of the stages comes to an untimely demise.

It is possible to start a model from another model (in effect, turning the other model into a "stage") but that is intended mostly for use in debugging a large model that has crashed many minutes (or hours) into a run, and the key difference is that it copies the previous model's Datastore, rather than just accessing it in place. To use that, you can set up another model to load the partially-formed carcass with a script that starts just before the old model crashed and then play around with the inputs and not have to wait hours to find out if it worked or not. Use the LoadModel configuration parameter in the subsequent model's "visioneval.cnf" to copy over the datastore (and the LoadStage if you need to load a stage other than the very last one in the previous model).

VE-3 puts its results in a subdirectory of the model called "results". Each stage, if any are defined, will go in a subdirectory of "results" named after the stage.

One downside of the stages is that each stage has its own separate Datastore which VE-3 links internally to the StartFrom stage Datastores (without copying them). So to get at the results from your full model run, you'll either need to use the VE-3 extraction and query mechanims (see below). If you have R scripts already that run on one big Datastore, you can merge the stage datastores into a single datastore through a process called "flattening" the Datastore. You can just copy the results from your stage and add the Flatten parameter, like this:

rs <- mod$results("stageToFlatten")   # stageToFlatten is the name of the final stage you would like all the data from
rs$copy("OtherDirectory",Flatten=TRUE)  # Generates a Datastore with all data available to the stage from its StartFrom stages

Note that you can open that "OtherDirectory" using the openResults function (see its R help) that you can then extract or query using the machinery described below.

Building scenarios

Scenarios are just model stages that have the special property of being "Reportable" (that is, they will automatically be included in extracts or in queries). You can manually mark a stage as "Reportable" in its visioneval.cnf, but VE-3 marks any stage Reportable that does not have another stage starting from it (i.e. a terminal stage).

So to make a scenario, you define a model stage. If the changes do not involve different inputs (e.g. separating base and future years into different stages), you can just define the model stage in the model's visioneval.cnf.

For scenario-type stages, you might want to define different inputs, or perhaps even a different run_model.R script (though be careful with that - if the same data doesn't emerge from each Reportable stage, the query process may leave you with "NA's" in some of your metrics). That's most easily done by creating a sub-directory and putting a visioneval.cnf with the stage particulars into that directory. It's probably better to put run-model.R scripts under different names in the single "scripts" directory for the overall model than to bury them in the scenario stage. The stage (scenario) sub-directory should just contain input files that are different from what is available to its StartFrom stages.

So to set up scenarios efficiently, you'll create your default future year (with complete inputs), then just create a few altered input files in the scenario subdirectory of the model (the subdirectory is named after the "stage" according to its - or the model's - visioneval.cnf). When the stage runs, it looks for input files locally, and anything it doesn't find it searches for in its StartFrom stage (and on up the ladder, as described earlier). Building scenarios as stages in that way makes it very easy to keep track of what's different in each scenario. Plus, when you run the model, you just run the model - each scenario (stage) gets run in its turn automatically. And when you extract or query the results, you get the results for all the (Reportable) scenarios. - though you can also get at the results for stages that are not reportable; you just have to ask for them explicitly by name or index.

Instead of defining individual subdirectories for your stages, you can push them all down into a single subdirectory of your model called "scenarios". Inside that scenarios, you can construct a set of manual scenarios (and they will all be reportable by default, even if some of the scenarios you define start from others - that's the key behavioral difference). Or you can construct variant inputs and have VE-3 combine them into all possible permutations and combinations. That reproduces in essence the behavior of the old VEScenario package that no longer exists. If you do combination scenarios, you can visualize them easily with the (now long-in-the-tooth) R HTML visualizer. More modern approaches to dumping VisionEval outputs into Access, Excel, SQL generally or using various Tableau or Power BI templates are under development and will go into another minor update release shortly.

Extracting model results

Extracting results is pretty simple. You run the model, you get a "VEResults" object by calling rs <- mod$results(), and then you do rs$export(). Be default, that creates .CSV files. You can use rs$export("sql") to generate a SQLite database. The 3.1 export mechanism is configurable to use any RDBI interface.

Querying model results

A spiffy mechanism for generating summary queries was built a few years back by Brian Gregor (the original author of VIsionEval). That mechanism was reworked into VE-3 to query model results and generate tables of outputs for multiple scenarios within a model (all the "Reportable" ones). The idea is to generate summary metrics from simple one-line computations (e.g. household DVMT per capita) and build a table of all the metrics for each scenario. It's more easily shown in examples than explained briefly in text, so check out the "walkthrough" and also the "queries" subdirectory in many of the sample models (see "installModel" above).

The metrics can be split out by grouping variables (e.g. Income or some adjacent characteristic, such as Households in urbanized areas). In VE-3, Bzones can be tagged with new properties (e.g. identifying EJ zones) and those can also be used to subdivide the query metrics - just add your tags as columns in the model's geo.csv file before you run the model.

Queries can generate two types of output format: "wide format" which produces one column for each year of each scenario and one row for each metric, and "long format" which produces one row for each scenario for each year for each metric (so there is only one column of metric values in the resulting output). See the walkthrough for examples of how to generate those outputs.

Interior changes

As noted above, model stages can have different run_model.R scripts. That will support using (for example) different versions of the PowertrainsAndFuels module in different scenarios.

The framework now supports modules with "dynamic" specifications (generated by a function call at runtime, rather than being built as static data into an R package). See the VESnapshot package and help for its functions "Dynamic" and "Snapshot" for more details.

Earlier pre-release versions

The following notes were written at the time of earlier pre-releases and contain additional information about VE-3.

In beta-release-0.8: Updated 01-getting-started.md in VisionEval-docs (and configuration to build it into the installer) - currently a pull request. Fixed a variety of problems with queries and indexing model contents. Fixed runtime and development startup (including functional access to the walkthrough's in their own independent runtime folder). See the getting started document for some instructions.

Updated tests and walkthrough, and in the process fixed a bunch of bugs (beta-release-0.7).

In beta-release-0.7: Updated with a new test architecture (see the changelog, test-architecfture.md, for description) (beta-release-0.6). Also fixed some bugs in the VEModel results extraction code where earlier stages in a staged model were not being included in the results.

Updated to improve walkthrough and test access and clean up runtime build process (beta-release-0.4). This release (which skips beta-release-0.3) includes the patched MultiModal module, restructuring of the tutorials and vignettes, some fixes to the build process, the locate employment bug patch, and (most exciting) the fully functional dynamic visualizer that uses the VEModel scenario and query features to let you configure exactly what scenario categories and metrics you want to display.

Updated to beta-release-0.5 which makes a variety of minor fixes (including updates the scenario functionality to work better, added new scheme for managing pull requests and the changelog.

The internal VEModel test.R script, which I've used to develop the framework, is also included in (and will run from) the installed runtime. Just source("tools/tests/VEModel/test.R") once you have launched the runtime. I will be updating walkthrough.R to demonstrate the test features in a more tutorial fashion.

The revised walkthrough will be part of beta-release-0.5, which will also include updating the scenarios and visualizer so you can visualize an arbitrary set of manually constructed scenarios, rather than just the category-permutation scenarios that track the old VEScenario functionality. That will make the visualizer a fully-supported element of VisionEval.

The installers included as assets below have been updated to tag beta-release-0.4.

Key changes include the following:

Though it is still feasible to run a "classic" VisionEval model by doing source("run_model.R"), the full power of the new framework requires a few simple modifications to the model structures. We should probably have a vignette on converting an old model. The basic strategy is simple: move the model into a subdirectory of the "models" directory in the runtime (callint it, say, "myModel"), and create a visioneval.cnf file that reproduces key elements from defs/run_parameters.json and the InitializeModel function in run_model.R. You can remove intializeModel from the run_model.R script (though you can also leave it - it will be ignored if you use the VEModel run function). Then just use mod <- openModel("myModel") and then mod$run(). You'll also eventually want to restructure the various scenarios you created by varying inputs to that model, and there will soon be a tutorial on how to do that.

Aside from the above, here are the key user-visible changes in this VisionEval version (there are probably many more, but they'll be intuitive or optional for basic model setup and runs).