Repository navigation
Releases: VisionEval/VisionEval-4
Release list
VE-40-RC7: Multimodal Bug, PUMS helpers, Performance
VisionEval Release of September, 2026
The following updates are included in this release:
-
Updates to code and support scripts for localizing PUMS data used in the
VESimHouseholdspopulation
synthesis package. See the instructions insources/modules/VESimHouseholds/data-raw/Readme.md. -
Updated the builder code so the build customization file
ve-build-config.ymlcan be placed either
inVE_HOME(which is unnatural given the typical work flow) or inVE_RUNTIME.VE_RUNTIMEmakes more
sense since that's where the sample build configuration file is placed, and that's where the builder
will look first. -
Increased the valid range of tabular data used to evaluate congested lane miles in the
CalculateRoadPerformancemodule of theVETravelPerformancePackage. This solves a bug
which would lead to failed estimates of congested DVMT when available lane miles exceeded
a certain threshold. -
Incorporated fixes suggested by various contributors culminating in pull-request #15 that should
fully repair a longstanding problem in the optional VETravelDemandMM module. The problem was that the
household DVMT prediction split the modeling into urban and non-urban segments. The ordering by household
ID was disrupted by doing the prediction in two segments, which were then not in the same order as the
original household file, leading to mismatches when the results were reattached. A preliminary fix that
worked for the basic sample models was offered in the previous release (VE-40-RC6). Limitations to that
approach were identified in models with more complex zone naming schemes, and those are now fixed through
the hard work of @maxclements032 (see the pull request summary below). -
Added debugging information logging and forced garbage collection to the
AssignVehicleOwnershipmodule
ofVEHouseholdVehicles. That function was using excessive RAM (in excess of 22Gb) when running extremely
large models. The fix attempts to release memory more frequently than R does by default, and testing shows
that VisionEval can now run a VE-State model of the SCAG (LA/Southern California) MPO successfully on
systems with 32Gb RAM.
Pull Request Summary fixing alignment problem in optional package VETravelDemandMM
Summary
Issue #11 correctly identified that predictions generated within
segments sometimes need to be restored to the source household order.
Commit 8dbec0184b11dad36789a755aeb5810203ddddaf implemented that
restoration by extracting numeric substrings from HhId.
That approach does not generalize to multi-Azone or numeric-Azone
models. With numeric Azones, an ID such as 51001-1 produces two
numeric values instead of one; in the Virginia case that exposed the
problem, 13,842 household rows produced 27,684 ordering values. With
nonnumeric Azones, household-number suffixes repeat across Azones and
therefore are not unique ordering keys.
This change treats household IDs as complete identifiers and restores
prediction order by matching full IDs to the source dataset. It also
verifies that the mapping is complete and one-to-one before reordering
and fails explicitly when it is not.
Single-Azone RVMPO-style IDs retain their existing behavior, and merge_preds = FALSE is unchanged.
Testing
- Added focused regression coverage for numeric-Azone IDs, nonnumeric multi-Azone IDs with repeated suffixes, RVMPO-style IDs,
merge_preds = FALSE, and invalid ID mappings. - Passed the exact 13,842-row reproduction of the Virginia failure and the retained 15-case full-
HhIdregression suite. - Passed VisionEval-native package build/install and
R CMD checkwith no errors. - Previous RVMPO-MM regression testing found identical prediction ordering and zero prediction delta.
- External SayedMM, WPPDC, and PlanRVA runs completed successfully with the full-ID correction.
VE-40-RC6 Incremental Improvements
This release is principally for improving error handling, but there are a few noteworthy changes:
- Fixed a bug in VETravelDemandMM that led to some wrong estimates for Household DVMT (Issue #11)
- Created a sample model for VE-State that uses the VETravelDemandMM module
- Added an alternate algorithm for PredictWorkers that runs faster than the previous version, but yields slightly different results for the same model due to a different sequence of random numbers. You can enable that by adding "NewWorkerSample: 1" to a mddel stage or scenario. Note that the old version works acceptably fast provided the number of people and workers in each Azone is "reasonable".
- The Snapshot module in the VESnapshot package now successfully does everything it's supposed to (which is make a copy of a field like Household/DVMT to a Datastore variable with a different name, so you can later look at adjustments to that value made in successive module calls). See the documentation below.
- The documentation for updating PUMS and VEPowertrainsAndFuels on the documentation web pages is out of date and will be updated soon. Meanwhile, the code for retrieving PUMS data has been placed in a new data-raw folder in the VESimHouseholds source tree and you can play around with either the Census 2000 version or the ACS version for years after 2000.
You can install this release through the online installer. It should work fine to install the new release over your existing code, but as always, we recommend moving VE_RUNTIME to a different folder and ideally using a unique VE_HOME for this release.
Please post issues if you run into problems.
PUMS download helper instructions
You should typically select a few PUMAs to format for VisionEval, since it takes a long time to process the data into place if the PUMS file has more than a few tens of thousands of records. To use the functions, just source('PrepPUMS-ACS.R') and then run getACSPUMS(<state>, Year="2024", Get-Pumas=<PUMA-list>) where <state> is a two-digit state code, and Get-Pumas is a c() list of PUMA identifiers found in the state download for the year. Note that the Year needs to be a character variable, not an integer.
Snapshot Module
This module illustrates the basic structure of a VE module and implements a useful test facility that can copy an
arbitrary field (or more than one) present in the Datastore into a new field. Useful for grabbing a picture of a field
that is revised at different points in the model stream. Run 'installModel("VESnap")' to install a test module that
illustrates the application of the Snapshot module, including some spiffy features that allow you to take multiple
snapshots of the same field and keep them separate in the Datastore.
Model Parameter Estimation
This module has no parameters and nothing is estimated.
How the Module Works
The user specifies fields to copy in their visioneval.cnf script in the Snapshot: block. In the model's run
script, add a series of runModule("Shapshot",...) commands, including the Instance parameter to distinguish
which entry in visioneval.cnf will apply to that Snapshot.
See the VESnap test model that can be installed from this package. When the model runs and the
runModule("Snapshot",...) instruction is encountered, the specified fields are copied into new fields in the
Datastore where they can later be extraced, queried or otherwise used.
Configuring Snapshot
The snapshot configuration is placed in the main visioneval.cnf, or within SnapshotDir (system
parameter) which defaults to "snapshot" and which will be sought in the Model root directory, or
in the Parameer directory ('defs'). The Snapshot configuration will look like this in its fully
developed form:
Snapshot:
- Instance: "First"
Group: # The Datastore group (shortcut "Year" is acceptable)
Table: # The Datastore table within Group
Name: # The Datastore field with Table
SnapshotName: # The name of the field that will be created (in the same Group/Table as the input)
- Instance: "Second"
Group:
Table:
Name:
SnapshotName:
LoopIndex: 1
# If LoopIndex is missing, snapshot each time through the loop, overwriting to the same place.
# Otherwise only take the snapshot if the LoopIndex passed to runModule matches this number
The Instance is optional. If it is not specified, it will be ignored if it is passed from the
runModule instruction, and referred to as "NA" (literal character string, not an R NA value). A
minimal Snapshot will look like the following. Note the dash ahead of 'Group'. Snapshot must
define a list of objects (that leading dash), even if there is only one Snapshot
Snapshot:
- Group:
Table:
Name:
SnapshotName:
Any Group/Table/Name object must already have been specified in an earlier module call in the
ModelScript (i.e. before the runModule("Snapshot",...) step), and it will be looked up in the
AllSpecs_ls parameter for the properties required to construct a Get or Set specification.
Finally, you can use Instance and LoopIndex together with this configuration:
# In visioneval.cnf:
Snapshot:
- Instance: "FirstLoop"
Group: "Year"
Table: "Household"
Name: "DVMT"
SnapshotName: "HhDVMTFirstLoop"
LoopIndex: 1
- Instance: "SecondLoop"
Group: "Year"
Table: "Household"
Name: "DVMT"
SnapshotName: :HhDVMTSecondLoop
LoopIndex: 2
# In model run script (run_model.R):
... # Earlier script lines
for (i in 1:2) {
runModule("Snapshot", "VESnapshot", RunFor = "AllYear", RunYear = Year, Instance="FirstLoop", LoopIndex=i)
runModule("Snapshot", "VESnapshot", RunFor = "AllYear", RunYear = Year, Instance="SecondLoop", LoopIndex=i)
... # Remainder of loop
}
... # Remainder of run script
See the VESnap test model, variant snapshot, for a working example.
VE-40-RC5: Package Manifest and Initialize changes, ModuleUnits, PreviousYear
Release Notes for January 26, 2026
As always, if you have problems using (or understanding) any of the
new features in this release, please submit an issue.
We'll work promptly either to fix the problem or to provide a
workaround. Fixed problems will be available in new commits on the
development branch, and will be rolled into the next overall
release. We'll post comments in the Issues section when the issue is
resolved.
Here is a list of the major changes in this release. There were also a few message
adjustments, including error checking on some of the inputs to make it easier to
figure out why things are not working in a new model.
-
Numerous updates to the build system and the installer, notably:
-
Eliminated the packaged source option for building an installer – it’s
easier and less confusing to just useve.build()on a source code
snapshot or git clone. The installer now presents three options:-
Install from a binary release, which has two variants, one just
containing the VisionEval packages (and downloading the remaining
dependencies online as the installer runs), and the other containing
the VisionEval packages along with all the dependencies as a
pre-installed Windows library. The second type of installer is
overall a bit faster to install; the first will get the latest R
dependency packages as part of the installation. -
Install from a release snapshot, which gets you a copy of the GitHub
repository as of the release. The snapshot does not include any
later modifications to the development environment that have not yet
been packaged into a release. Because this installation also uses
theVE-Bootstrap.Rdevelopment environment, you will need RTools
and the build will take an hour or so depending on how fast your
machine is. -
Install from a local clone, which you would use if you have
separately cloned the GitHub repository. Using this option is
functionally identical to just setting the R working directory to
your repository root and loadingVE-Bootstrap.R. You’ll still need
to perform the build operation.
-
-
Added several functions to the build environment that will help navigate
the build process.-
ve.setup()to set interactively (via a TclTk dialog) the VE_BUILD
and VE_RUNTIME folders (it is recommended to keep these separate
from the GitHub root – the defaults will work fine if just doing
add-ons to your binary VisionEval installation -
ve.locations()to report the current environment settings
(defaults or values that override defaults, which can be set via
ve.setup(), or manually in .Renviron, or globally through User
Environment variables -
ve.instructions()to re-issue the list of build functions (which
varies depending on how much is already built)
-
-
The build environment is loaded in one of two ways:
-
From
VE-Bootstrap.Rif you are starting from the git repository
(either by cloning or using the snapshot option from the installer),
or -
From the
VEBuildpackage if you want to build an additional or
altered package into your existing VisionEval installation. You can
load the build environment by usinglibrary(VEBuild)once you have
a working VisionEval installation (even a binary one).
-
-
-
There is now a “Manifest” constructed when VisionEval packages are built
that describes when and how the package was built.-
The manifest adds fields to the package’s
DESCRIPTIONthat report
information about the build date, specific git commit, branch and
repository used for the package. If the package code did not come from a
Git repository, the manifest fields will say so and tell you the folder
that was used. -
You can access the Manifest information using the standard R
packageDescription()function, finding something like the following:- In the next release, the manifest information will be gathered for each
package used in the model run. It should be pretty straightforward to
write a short R script to interrogate each VisionEval package’s
DESCRIPTION to assemble the version information after doing a model run.
If you do write such a script, please create a GitHub issue and we’ll
use that code to develop the model run functionality.
- In the next release, the manifest information will be gathered for each
-
> packageDescription("VEStart")
Type: Package
Package: VEStart
Title: Bootstrap VisionEval with online load
...
VEBranch: development
VEBuildDate: Wed Jan 21 15:04:33 2026
VECommit: 2c8a3806d6ca659b3c243a8b3718fd62c1002b02
VELocalRepoPath: N:/Git-Repos/VisionEval-40/
VERemoteURL: git@github.com:visioneval/VisionEval-4.git
VEUpstreamBranch: visioneval/development
-
The walkthrough was comprehensively revisited and checked for currency.
-
You can activate the walkthrough using the
ve.walkthrough()function
once you are running VisionEval. “Running” means you either started from
an installed runtime or home directory, or used theve.run()function
from within the build environment once the build is complete -
The walkthrough creates a separate sub-directory to hold the walkthrough
results, so any models you install or run will be separate from your
“real” models. You should be careful not to install real models in the
walkthrough environment. -
You can leave the walkthrough environment and return to your regular
runtime by using theexit.walkthrough()function. -
Note that the walkthrough does not run functions for you. It just sets
up an environment that you can explore by opening one of the walkthrough
scripts (they’ll pop up in a File Explorer window) and trying out the
instructions listed there – there are explanations for the functions
inline in the walkthrough script files.
-
-
Exported units now work differently than before. The export should by
default produce much more intuitive results in exported output files. No
more speeds exported as “Miles/Day”!-
The way this works is that a new field called ModuleUnits is added to
the attributes of each column of data in the Datastore. -
The ModuleUnits are the the units used the module that first created the
Datastore column. -
By default when extracting or exporting data, the Datastore contents
will be converted to ModuleUnits. -
You can change that behavior by setting
convertUnits=FALSEwhen you
run the export function – you’ll then get the unmodified Datastore
units. -
As noted in the walkthrough, you can also force specific conversions by
creating a file calleddisplay_units.csvin yourdefsdirectory
(next togeo.csv). The display units override both the ModuleUnits and
the Datastore Units unless you choose not to convert units. You can also
put display_units.csv in the root of your VisionEval runtime and have it
apply to all your models, but with the new ModuleUnits you don’t need to
do any of that. -
To take advantage of ModuleUnits, you will need to re-run your models
since the older outputs did not include ModuleUnit information.
-
-
The “Initialize” module can now have a full name that includes its package,
rather than always being called “Initialize”, which has proved very
confusing when debugging models.-
A number of packages have included a special “Initialize” module that
manages things like optional input files, file consistency checking, and
even a bit of model estimation. -
The initialization process has been changed so the “Initialize” module
can now be called “Initialize<VEPackage>”. The standard packages that
include an Initialize function now have had those module names
comprehensively changed. -
If you have variants of standard packages that still have an
“Initialize” function, you can continue to build and run those without
renaming the function (i.e. the new architecture is fully backward
compatible).
-
-
The method for reading geo.csv has been changed so you can now use any
spatial file format with tabular attributes (in addition to .csv files,
which will still work.-
That means specifically that shapefiles will work fine
-
You can also set up geodatabases (e.g. with PostGis) or any other format
recognized by the Rsfpackage https://r-spatial.github.io/sf/. -
Any extra fields (but not the spatial geometry) will also be added as Bzone
tags (or AZone in VE-Stage) in the Datastore to any table that has entries
for Bzones (or Azone in VE-State) and you can use those to filter and
aggregate model results using the query mechanism. -
Several
visioneval.cnfsettings need to be changed to use an alternate
format.-
GeoFile: <filename>should mention the filename with its extension
(e.g.mygeo.shp). The file should be located in the `defs`
directory of your model. -
If you are using a geodatabase, look at the documentation for the
sfpackage to find the right format for the database driver and
the tab...
-
-
VE-40-RC4: Finalized Installer; Relaxed mean vehicle age restriction to 25 yrs
This minor release updates the installer (consistent with the website) to work smoothly in all variations. The website has the current installer scripts.
This release also updates the prohibition on "AutoMeanAge" and "LtTrkMeanAge" in VEHouseholdVehicles so mean age up to 25 years is allowed.
To use it, I'd suggest a fresh VE installation. It should work with any recent VE however. To get the update, you can install the win.library version of this release into a new "VE_HOME" folder, and then copy the VEHouseholdVehicles folder from the new VE_HOME ve-lib/X.Y (X.Y = your R version major.minor) to your "real" VE_HOME/ve-lib/X.Y, overwriting what was there.
VE-40-RC3: Updated Installer; Spatial geo.csv; Initial PreviousYear Group Implementation
This release of VisionEval 4.0 mostly focuses on getting the installer to work better, plus improving the documentation (see the README.md for installation and building instructions).
Installer
See the README.md file.
Spatial geo.csv
I've also added support for spatial geo.csv files, using the sf:st_read function to read .csv files (appears to work) as well as any spatial formation. If you want to access a spatial file, you'll need to add a GeoFile definition to your visioneval.cnf. If it's a file-based spatial format, just put the name of the main file (e.g. myModelGeo.shp) as the value of GeoFile, like this:
GeoFile: MyModelGeo.shp
It will look in the ParamDir (by default defs within your model folder). It will NOT use an absolute path - you would need to change ParamDir, but of course that will affect units.csv and deflators.csv as well. The default GeoFile will continue to be "geo.csv".
If you want to use a geodatabase in a format supported by the R sf package (e.g. PostGIS), add a GeoFile entry to your visioneval.cnf file structured like this:
GeoFile:
- <Spatial Database Reference> # see help("sf:st_read")
- <Spatial Layer>
Currently, you need fields in the GeoFile named explicitly "Marea", "Azone" and "Bzone" (and it might complain about "Czone"). I will be finishing an implementation in the next round allowing you to map one or more of those to fields with other names (e.g. mapping Bzone onto BlockGroup). The file needs to include geographies at the smallest level (either Azone or Bzone) and it will not automatically merge them if, for example, you spatial file is at the census Block level but you're hoping to use Block Group aggregates for the Bzones. I might relax that once we get the field mapping in place, though for transparency it will be better if you pre-merge the geographics in your GIS. The next implementation will also allow you to select which extra fields from your GeoFile to include in your Datastore results - currently, all the extra fields present in GeoFile will be added to the smallest geography Datastore outputs, including the "geography" spatial field (see the sf::st_read documentation for its format). Note that the GeoFile metadata is not currently saved in the Datastore anywhere, but the use case is just to join the Datastore results as tables back to GeoFile so that shouldn't be a problem.
PreviousYear Specification Group
The PreviousYear feature is a brand new beta feature that almost everyone can safely ignore. The PreviousYear group is used in a new module Get specification (like the existing "Year" or "BaseYear"). It will look in visioneval.cnf for a vector of years called (duh) PreviousYear, like this:
PreviousYear:
- 2010 # if this is the BaseYear
- 2020
- 2030
- 2040
That would be useful for 10 year increments heading (say) to 2050. You will need to define Model Stages for those previous years and make sure they run in an appropriate order. When you get to running (say) RunYear 2030, a specification in GROUP PreviousYear will find the value from the 2020 Group (previous year) in the Datastore.
If you don't define PreviousYear, the lookup will use the model "Years" parameter, but that will only work if all the years for your model are included in a single stage (which is a huge waste of runtime resources if you're also doing scenarios - though it would simplify testing for small models).
I expect to be working with the team that requested the PreviousYear feature (Brian G and Liming W.) to develop test models and samples showing how to configure the model runs. The feature will eventually be used to implement incremental land use forecasting in VisionEval across multiple years.
As always, please post an issue here if you're having trouble getting some or all of this to work.
VE-40-RC2: Installer bug fixes plus updated README.md
This release fixes a couple of small installer bugs and updates the README.md to have complete instructions for the VE 4 installer.
Please look at the README.md file for more information.
VE-40-RC1
This release provides the first publication of VisionEval 4, with a new installation scheme that should be a lot easier and more modular. The guts of VisionEval is the same as the most recent VisionEval 3 release in VisionEval-dev. All that has changed so far in Version 4 is the installation and build process. More documentation will be forthcoming in June 2025.
To install VisionEval, you can clone the repository, start R in the repository root (so it sources "VE-Bootstrap.R") and then run ve.build().
More simply, you can use the online installer (which also gives you a full build option from a snapshot rather than a git clone). To get started:
- Pick a supported version of R (any of the R 4.4.x or R 4.5.x releases will work)
- Make sure you have installed R Tools for Windows for your version of R
- Start your version of R either from R GUI or from RStudio
- Set its working directory to some empty directory (e.g. C:\Documents\VisionEval)
Then run the installer script either from this Github or the website.
Here's the link for this Github:
source(ve.url<-"https://github.com/VisionEval/VisionEval-4/blob/release/sources/framework/VEStart/inst/download/VE4-install.R")Here's the link from the website:
source(ve.url<-"https://visioneval.github.io/assets/install/VE4-install.R")