Skip to content

Releases: VisionEval/VisionEval-4

VE-40-RC7: Multimodal Bug, PUMS helpers, Performance

Choose a tag to compare

@jrawbits jrawbits released this 08 Sep 15:33

VisionEval Release of September, 2026

The following updates are included in this release:

  1. Updates to code and support scripts for localizing PUMS data used in the VESimHouseholds population
    synthesis package. See the instructions in sources/modules/VESimHouseholds/data-raw/Readme.md.

  2. Updated the builder code so the build customization file ve-build-config.yml can be placed either
    in VE_HOME (which is unnatural given the typical work flow) or in VE_RUNTIME. VE_RUNTIME makes more
    sense since that's where the sample build configuration file is placed, and that's where the builder
    will look first.

  3. Increased the valid range of tabular data used to evaluate congested lane miles in the
    CalculateRoadPerformance module of the VETravelPerformance Package. This solves a bug
    which would lead to failed estimates of congested DVMT when available lane miles exceeded
    a certain threshold.

  4. 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).

  5. Added debugging information logging and forced garbage collection to the AssignVehicleOwnership module
    of VEHouseholdVehicles. 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-HhId regression suite.
  • Passed VisionEval-native package build/install and R CMD check with 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

Choose a tag to compare

@jrawbits jrawbits released this 24 Jul 15:07

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

Choose a tag to compare

@jrawbits jrawbits released this 24 Jan 19:35

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 use ve.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
        the VE-Bootstrap.R development 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 loading VE-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.R if you are starting from the git repository
        (either by cloning or using the snapshot option from the installer),
        or

      • From the VEBuild package if you want to build an additional or
        altered package into your existing VisionEval installation. You can
        load the build environment by using library(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 DESCRIPTION that 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.
> 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 the ve.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 the exit.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=FALSE when 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 called display_units.csv in your defs directory
      (next to geo.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 R sf package 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.cnf settings 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
        sf package to find the right format for the database driver and
        the tab...

Read more

VE-40-RC4: Finalized Installer; Relaxed mean vehicle age restriction to 25 yrs

Choose a tag to compare

@jrawbits jrawbits released this 13 Sep 19:20

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

Choose a tag to compare

@jrawbits jrawbits released this 08 Sep 16:14

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

Choose a tag to compare

@jrawbits jrawbits released this 17 May 15:15

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

VE-40-RC1 Pre-release
Pre-release

Choose a tag to compare

@jrawbits jrawbits released this 16 May 22:24

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:

  1. Pick a supported version of R (any of the R 4.4.x or R 4.5.x releases will work)
  2. Make sure you have installed R Tools for Windows for your version of R
  3. Start your version of R either from R GUI or from RStudio
  4. 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")