Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
778 commits
Select commit Hold shift + click to select a range
e79d0e6
fix a test
zneedell Oct 6, 2025
6add1e9
database fixes, including separating h5 tables from the main file
zneedell Oct 10, 2025
3425f0f
README update
zneedell Oct 10, 2025
14744f3
database fixes
zneedell Oct 14, 2025
ea5720e
update images
zneedell Oct 14, 2025
01cc7a1
provenance fixes for asim h5. Switch to more efficient method
zneedell Oct 15, 2025
27993e0
zarr store fixes
zneedell Oct 18, 2025
3eb486a
bugfix
zneedell Oct 20, 2025
0f1f29a
fix atlas init
zneedell Oct 20, 2025
0cb18c4
Fix urbansim and atlas postprocessor logic. make signatures consistent
zneedell Oct 20, 2025
774f8a5
more h5 improvements
zneedell Oct 20, 2025
5b26167
add source_file_paths to h5 record
zneedell Oct 20, 2025
0d9a04a
fix urbansim runner
zneedell Oct 20, 2025
b571d7e
fix urbansim skims
zneedell Oct 20, 2025
58efa2a
h5 bugfix
zneedell Oct 20, 2025
562932d
paths bugfix
zneedell Oct 20, 2025
4e2674f
try getting geoid_to_zone
zneedell Oct 20, 2025
de04d31
new tmp directory for beam
zneedell Oct 20, 2025
a0cb68b
specify numba cache loc
zneedell Oct 20, 2025
872a892
more numba cache fixes
zneedell Oct 20, 2025
c968a2d
bugfix
zneedell Oct 21, 2025
4867e99
bugfixes
zneedell Oct 21, 2025
1a10e72
Update restart logic
zneedell Oct 21, 2025
9015c33
clean up main run.py
zneedell Oct 21, 2025
9e1d45f
better comments in records.py
zneedell Oct 21, 2025
f58fa99
jvm improvements
zneedell Oct 22, 2025
cd2b0aa
jvm improvements, file loc fixes
zneedell Oct 22, 2025
3655d16
jvm fix
zneedell Oct 22, 2025
a9d975b
jvm fix!
zneedell Oct 22, 2025
f61edab
improve jvm options
zneedell Oct 22, 2025
8320574
improve jvm options
zneedell Oct 22, 2025
114ed6f
move dir fix
zneedell Oct 23, 2025
863da29
provenance fixes
zneedell Oct 23, 2025
961bd25
db fixes
zneedell Oct 23, 2025
3ee6636
correct folder name
zneedell Oct 24, 2025
3f5f6fd
GC tuning
zneedell Oct 24, 2025
61d1d06
Bookkeeping for inputs/outputs
zneedell Oct 24, 2025
2370701
better handling of omx files, add timestamp to gc log
zneedell Oct 24, 2025
cfa1ecd
bugfix
zneedell Oct 24, 2025
9b0f882
remove JVM option
zneedell Oct 25, 2025
47595b6
remove JVM option
zneedell Oct 25, 2025
afc3128
don't re-initialize on restart
zneedell Oct 25, 2025
ccf3122
tweak gc
zneedell Oct 25, 2025
e9dc333
hacky fix
zneedell Oct 25, 2025
aabcc55
hacky fix
zneedell Oct 25, 2025
9cabc60
assertion to warning
zneedell Oct 25, 2025
d23d2ee
more robust skims path
zneedell Oct 25, 2025
c56f26a
initialization fixes
zneedell Oct 29, 2025
44cbc36
bugfix
zneedell Oct 29, 2025
246ed98
revert change
zneedell Oct 29, 2025
8147551
path fix
zneedell Oct 29, 2025
d80dc8f
fix restart of atlas
zneedell Oct 29, 2025
a29103d
fix restart of other models
zneedell Oct 29, 2025
257f4f3
fix restart of urbansim
zneedell Oct 29, 2025
ec959fe
more atlas fixes
zneedell Oct 29, 2025
b116b38
bugfix
zneedell Oct 29, 2025
d83bda1
bugfix
zneedell Oct 29, 2025
0f0f8e8
bugfix
zneedell Oct 29, 2025
98269b0
tweak beam gc
zneedell Oct 29, 2025
44b5031
more atlas fixes
zneedell Oct 29, 2025
a53f9ab
more atlas fixes
zneedell Oct 29, 2025
5dcd5ac
more atlas fixes
zneedell Oct 29, 2025
297201e
more atlas fixes
zneedell Oct 29, 2025
2e93db4
more atlas fixes
zneedell Oct 30, 2025
c5bb5c8
fix atlas restart loop
zneedell Oct 30, 2025
fdf6a7b
fix atlas restart loop
zneedell Oct 30, 2025
38510ee
fix atlas restart loop
zneedell Oct 30, 2025
0cc3e73
restore breaking changes
zneedell Oct 30, 2025
8831637
another atlas bug
zneedell Oct 31, 2025
c140f0a
fixes for asim preprocessor after atlas run
zneedell Oct 31, 2025
b021175
more fixes for restart
zneedell Oct 31, 2025
f19d778
more fixes for restart
zneedell Oct 31, 2025
f496563
more fixes for restart
zneedell Oct 31, 2025
4a1ba9c
more fixes for restart
zneedell Oct 31, 2025
4165712
more fixes for restart
zneedell Oct 31, 2025
aecfe2e
database upload fixes
zneedell Oct 31, 2025
3d7b74e
database stuff
zneedell Oct 31, 2025
b82ad1a
atlas fix
zneedell Oct 31, 2025
31a9919
bugfix
zneedell Oct 31, 2025
307b2a1
bugfix
zneedell Oct 31, 2025
ed64545
bugfix
zneedell Oct 31, 2025
4b113c8
upload fix
zneedell Oct 31, 2025
994b744
upload fix
zneedell Oct 31, 2025
9d7356f
upload fix
zneedell Oct 31, 2025
16450f1
upload fix
zneedell Oct 31, 2025
b68c8e8
upload fix
zneedell Oct 31, 2025
583c63c
upload fix
zneedell Oct 31, 2025
ab7c927
upload fix
zneedell Oct 31, 2025
3826f4d
upload fix
zneedell Oct 31, 2025
fc3f62a
upload fix
zneedell Oct 31, 2025
be1fb8b
upload fix
zneedell Oct 31, 2025
094c07c
upload fix
zneedell Oct 31, 2025
95a9003
upload fix
zneedell Oct 31, 2025
e3f1a6a
upload fix
zneedell Oct 31, 2025
1f2270b
upload fix
zneedell Oct 31, 2025
7b5b59f
upload fix
zneedell Oct 31, 2025
af56def
upload fix
zneedell Oct 31, 2025
5f31b2e
schema fix
zneedell Oct 31, 2025
1d8f020
bugfix
zneedell Nov 2, 2025
f190ffe
schema updates
zneedell Nov 2, 2025
0b5414f
a bunch of db fixes
zneedell Nov 3, 2025
6932b46
add missing files
zneedell Nov 3, 2025
aabc1db
more config stuff
zneedell Nov 3, 2025
efad6f2
more config stuff
zneedell Nov 3, 2025
61ba6ce
more config stuff
zneedell Nov 4, 2025
91ea975
more config stuff
zneedell Nov 4, 2025
baeea03
more config stuff
zneedell Nov 4, 2025
d8a74c9
more config stuff
zneedell Nov 4, 2025
ce75f66
more config stuff
zneedell Nov 4, 2025
83cbbeb
more config stuff
zneedell Nov 4, 2025
58aac20
more config stuff
zneedell Nov 4, 2025
f01d197
more config stuff
zneedell Nov 4, 2025
f93abc5
more config stuff
zneedell Nov 4, 2025
0474f3d
more config stuff
zneedell Nov 4, 2025
efc99de
more config stuff
zneedell Nov 4, 2025
ac0fc55
more config stuff
zneedell Nov 4, 2025
320ff0a
more config stuff
zneedell Nov 4, 2025
c22e832
more config stuff
zneedell Nov 4, 2025
b71365c
more config stuff
zneedell Nov 4, 2025
96c53e8
more config stuff
zneedell Nov 4, 2025
697bf5c
Add legacy aliases for beam_geoms_fname, geoms_index_col, and beam_ro…
zneedell Nov 4, 2025
f2daea6
Add comprehensive ATLAS, BEAM, and shared settings mappings for backw…
zneedell Nov 4, 2025
a8a9933
more config stuff
zneedell Nov 4, 2025
821ff34
more config stuff
zneedell Nov 4, 2025
a1898d5
more config stuff
zneedell Nov 4, 2025
0fd044c
more config stuff
zneedell Nov 4, 2025
1bf1c0e
bugfix
zneedell Nov 4, 2025
589e7cd
always migrate urbansim config
zneedell Nov 4, 2025
0b51ebd
asim bugfix
zneedell Nov 4, 2025
b5e9907
better accounting for table prefix
zneedell Nov 5, 2025
396c6c7
pilates fips fix
zneedell Nov 5, 2025
9f49580
pilates fips fix
zneedell Nov 5, 2025
671bcba
attempt at GEOID fix
zneedell Nov 5, 2025
7b4841f
attempt at GEOID fix
zneedell Nov 5, 2025
d0c1434
debug
zneedell Nov 5, 2025
bb7331b
settings updates. Some tests still faailing on settings import
zneedell Nov 6, 2025
cd91cfa
fmt, remove old pydantic validation logic
zneedell Nov 6, 2025
3dbc96a
bugfix
zneedell Nov 6, 2025
4b76419
bugfix
zneedell Nov 6, 2025
005c7e9
fix type hints
zneedell Nov 6, 2025
1ec7918
bugfix
zneedell Nov 6, 2025
3ab8f2b
more logging
zneedell Nov 6, 2025
637fff2
bugfixes
zneedell Nov 6, 2025
d05beae
bugfixes
zneedell Nov 6, 2025
b9bee03
bugfixes
zneedell Nov 6, 2025
920b26c
fix setting with copy warning
zneedell Nov 6, 2025
6d53c7e
relative path issue
zneedell Nov 6, 2025
03bcfd3
relative path issue
zneedell Nov 6, 2025
f0bc347
bugfix
zneedell Nov 6, 2025
7968ccc
bugfix
zneedell Nov 6, 2025
787280a
bugfix
zneedell Nov 6, 2025
244261b
bugfix
zneedell Nov 6, 2025
7f8a0f5
create temp directories in scratch
zneedell Nov 7, 2025
41d1afd
expand vars
zneedell Nov 7, 2025
4b0676e
better location for singularity cache
zneedell Nov 7, 2025
d53b1b5
bug
zneedell Nov 7, 2025
0355c8b
add missing schema def!
zneedell Nov 7, 2025
8bba221
clean up
zneedell Nov 7, 2025
30ad4f9
fix singularity tmp location again
zneedell Nov 7, 2025
6704664
lots of test fixes
zneedell Nov 7, 2025
9dce3b9
relative path fixes
zneedell Nov 7, 2025
3bff7b8
make sure asim inputs and outputs are correctly tagged
zneedell Nov 10, 2025
3fdd619
fixes
zneedell Nov 11, 2025
842adac
sort shapefile
zneedell Nov 11, 2025
972fa31
add check to beam postprocessor too
zneedell Nov 11, 2025
26c2881
new tests
zneedell Nov 11, 2025
cd2449a
add zero-based-contiguous flag back to skims
zneedell Nov 11, 2025
db29a74
deal with zone consolidation
zneedell Nov 12, 2025
b33a6ef
fix schema upload
zneedell Nov 12, 2025
3172945
more permanent fix for zone ordering
zneedell Nov 13, 2025
c65bcfe
more permanent fix for zone ordering
zneedell Nov 13, 2025
2f2f22d
more permanent fix for zone ordering
zneedell Nov 13, 2025
08f19d2
try again with zone ordering
zneedell Nov 13, 2025
bd99ebd
try again with zone ordering
zneedell Nov 13, 2025
a1c64dd
try again with zone ordering
zneedell Nov 13, 2025
49b1318
try again with zone ordering
zneedell Nov 13, 2025
0a1608d
try again with zone ordering
zneedell Nov 13, 2025
801db38
Revert "try again with zone ordering"
zneedell Nov 13, 2025
c15f588
add debug
zneedell Nov 13, 2025
8267163
add debug
zneedell Nov 13, 2025
2a23925
fix?
zneedell Nov 13, 2025
fa527c8
more debug
zneedell Nov 13, 2025
381c318
more fixes
zneedell Nov 13, 2025
bb08d50
more fixes
zneedell Nov 13, 2025
af83a86
more fixes
zneedell Nov 13, 2025
aa474ed
more fixes
zneedell Nov 13, 2025
171bd1b
more fixes
zneedell Nov 14, 2025
2d50106
ugly fix
zneedell Nov 14, 2025
1e807d2
I think the zones are finally working
zneedell Nov 14, 2025
0e30ecf
configs
zneedell Nov 14, 2025
0206d51
retain geometry column in land use
zneedell Nov 14, 2025
c036129
fmt
zneedell Nov 14, 2025
52eb350
documentation, more careful handling of nans
zneedell Nov 14, 2025
ce529e0
force fill na
zneedell Nov 15, 2025
3d73eaf
fix quotestring in update beam config
zneedell Nov 15, 2025
a5023c8
fix quotestring in update beam config
zneedell Nov 15, 2025
2adffba
try geojson instead
zneedell Nov 15, 2025
c67a839
correct field name
zneedell Nov 16, 2025
4fcf358
correct field name
zneedell Nov 16, 2025
e5432ae
correct field name
zneedell Nov 16, 2025
24c6abe
more comprehensive fixes
zneedell Nov 16, 2025
403c571
more comprehensive fixes
zneedell Nov 16, 2025
6cf46ce
test fixes and documentation
zneedell Nov 17, 2025
6d179f4
another indexing bug
zneedell Nov 18, 2025
0039303
bugfix
zneedell Nov 18, 2025
d8e0bd5
another debug check
zneedell Nov 18, 2025
46179af
try standardizing switch to 0 based
zneedell Nov 18, 2025
8c682cf
more database improvements
zneedell Nov 18, 2025
e6ba5cc
big clean up for beam preprocessor
zneedell Nov 19, 2025
3c90c4e
more default columns
zneedell Nov 19, 2025
e480e54
bugfix
zneedell Nov 19, 2025
e5a1034
update asim version
zneedell Nov 19, 2025
5ce1c46
beam config update fix
zneedell Nov 19, 2025
52ab5dd
test fix
zneedell Nov 19, 2025
1d9e402
Correct schema for parquet enums
zneedell Nov 19, 2025
fc5299e
fmt
zneedell Nov 19, 2025
f31a4a7
lint
zneedell Nov 19, 2025
f4f3329
postprocessing fix, new asim image
zneedell Nov 19, 2025
1a66943
beam preprocessor fix
zneedell Nov 20, 2025
2b6d521
fix on-disk storage
zneedell Nov 21, 2025
fbe3817
update docs
zneedell Nov 21, 2025
ab86098
updated config
zneedell Nov 21, 2025
18d9be7
missing files!
zneedell Nov 21, 2025
1b92a56
better logging
zneedell Nov 24, 2025
eeaa19f
hack for updating run_info
zneedell Nov 24, 2025
0353dfd
views
zneedell Nov 24, 2025
c21b737
updates
zneedell Nov 24, 2025
75abca8
new test
zneedell Nov 24, 2025
43aa502
script
zneedell Nov 24, 2025
32a60e8
fixes
zneedell Nov 24, 2025
a3d2f07
add iteration and subiteration to records
zneedell Nov 24, 2025
db12ccb
asim post bugfix
zneedell Nov 24, 2025
a7efd1c
asim post bugfix
zneedell Nov 25, 2025
30a5cd8
robustness fix
zneedell Nov 25, 2025
6d4d4ed
robustness fix
zneedell Nov 25, 2025
9419a34
correct naming of asim outputs
zneedell Nov 25, 2025
ded9a35
complete migration to using decorator
zneedell Dec 2, 2025
2ebe7c3
bugfix for reporecords
zneedell Dec 2, 2025
c8b0415
bugfixes
zneedell Dec 2, 2025
8804037
new configs
zneedell Dec 3, 2025
1eb5d9d
fix configs
zneedell Dec 3, 2025
0263320
fix configs
zneedell Dec 3, 2025
fa82f21
fix configs
zneedell Dec 3, 2025
0c14e97
fix configs, more robust command construction
zneedell Dec 3, 2025
22b3f23
fix configs
zneedell Dec 3, 2025
ac3b71e
fix configs typo
zneedell Dec 3, 2025
237cb46
don't use stubs, dummy!
zneedell Dec 3, 2025
b342551
new database for sfbay
zneedell Dec 3, 2025
a92c14f
fix block to geoid mapping for usim input
zneedell Dec 3, 2025
274e311
bugfix in urbansim postprocessor
zneedell Dec 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,10 @@ tmp.py
pilates_conda_env_setup4hima.txt

*.DS_Store
.idea
.idea
.aider*

.apptainer/
.singularity/

pilates/database/schema/generated/
233 changes: 149 additions & 84 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,109 +1,174 @@
<p align="center"><img src="logo_multi.png" width="700"></p>
<p align="center"><img src="logo_multi.png" width="700" alt="PILATES Logo"></p>

**P**latform for \
**I**ntegrated \
**L**anduse \
**A**nd \
**T**ransportation \
**E**xperiments and \
**S**imulation
**PILATES** (**P**latform for **I**ntegrated **L**anduse **A**nd **T**ransportation **E**xperiments and **S**imulation) is a framework for orchestrating containerized microsimulation models to study the co-evolution of land use and transportation systems. Designed for long-term regional forecasting, PILATES enables researchers and planners to simulate complex urban dynamics over multi-decade periods by linking specialized models that operate at different time scales.

PILATES is designed to facilitate the integration of various containerized microsimulation applications that together fully model the co-evolution of land use and transportation systems over time for the purpose of long-term regional forecasting.
Rather than tightly coupling models within a single software process, PILATES orchestrates them in a containerized environment. This modular architecture allows it to leverage the behavioral sophistication of existing specialized models with minimal modification, while providing robust state management and reproducibility.

The PILATES Python library is comprised primarily of the following:
1. **run.py** -- An executable python script responisble for orchestrating the execution of all containerized applications and data-transformation steps.
2. **settings.yaml** -- A configuration file for managing and defining high-level system parameters (e.g. geographic region, local data paths, simulation time horizon, etc.)
3. **application-specific dirs** -- The subdirectories of `pilates/` contain application-specific I/O directories for mounting to their respective container images, as well as application-specific Python modules responsible for transforming and archiving I/O data generated/used by other component applications.
4. **utils/** -- A subdirectory of `pilates/` containing various Python modules that might be relevant to any or all of the component applications (e.g. common geographic data transformations or http requests to the US Census API.)
-----

## Integrated Simulation Models

## 1. Setting up your environment
1. Make sure docker is running on your machine and that you've either pre-downloaded the required container images (specified in `settings.yaml`) or that you've signed into a valid docker account with dockerhub access.
2. Change other relevant parameters in `settings.yaml` (probably only [L7-31](https://github.com/ual/PILATES/blob/v2/settings.yaml#L7-L30))
- UrbanSim settings of note:
- `region_to_region_id` must have an entry that corresponds to the name of the input HDF5 datastore (see below)
- ActivtySim settings of note:
- num_processors: adjust this number to take full advantage of multi-threaded data processing in Python. Number should be close to the total number of virtual CPUs available on your machine (threads X cores x processors per core or something like that).
- chunk_size: adjust this number to take full advantage of the available RAM on your machine. Trying making this number bigger until the activitysim container segfaults or is killed due to a memory error.
4. Make sure your Python environment has `docker-py`, and `pyyaml` installed.
PILATES integrates several leading microsimulation models to create a comprehensive forecasting platform:

## 2. I/O
PILATES only needs two local data files in order to run: 1) an archive of land use and population tables corresponding to base year data for the specified region; and 2) a table of base-year travel skims in the format of the specified travel model. Currently, these two files are organized as follows:
1. **pilates/urbansim/data/custom_mpo_\<xxxxxxxx\>_model_data.h5** - an UrbanSim-formatted HDF5 datastore where `<xxxxxxxx>` is an 8-digit region ID corresponding to one of the IDs in the settings [L40](https://github.com/ual/PILATES/blob/master/settings.yaml#L40).
2. **pilates/\<travel model\>/\<travel model data dir\>/\<skims filename\>** - the input skims file, where `<skims filename>` is the name of the skims file specified in settings [L30](https://github.com/ual/PILATES/blob/master/settings.yaml#L31). Currently `polaris` and `beam` are the only supported travel models/skim formats.
* **[UrbanSim](https://github.com/UDST/urbansim)**: Models long-term metropolitan evolution by simulating household and business location choices, real estate development, and land use changes over periods of years or decades.

With those two files in those two places, PILATES should handle the rest.
* **[ATLAS](https://doi.org/10.1080/03081060.2024.2353784)**: Simulates household vehicle fleet dynamics, including vehicle purchase, replacement, and technology adoption (e.g., electric vs. internal combustion vehicles).

NOTE: currently all input data is overwritten in place throughout the course of a multi-year PILATES run. To avoid data loss please store a local copy of the input data outside of PILATES.
* **[ActivitySim](https://github.com/ActivitySim/activitysim)**: Generates daily activity-based travel demand by simulating individual travel decisions including trip purpose, destination, time of day, and mode choice for a synthetic population.

## 3. Executing the full workflow
* **[BEAM](https://github.com/LBNL-UCB-STI/beam)**: The **B**ehavior, **E**nergy, **A**utonomy, and **M**obility framework simulates agent-based transportation on detailed road networks, modeling traffic congestion, transit operations, and emerging mobility services to produce network performance metrics.

-----

## Simulation Scenarios

PILATES supports various simulation configurations to match different research and planning needs:

1. **BEAM Only**: Detailed network performance analysis using fixed travel plans. Ideal for studying infrastructure impacts, operational strategies, or new mobility services.

2. **ActivitySim + BEAM**: Agent-based travel demand modeling with network feedback. ActivitySim generates daily travel demand, BEAM simulates it on the network, and the resulting travel times feed back until equilibrium is reached.

3. **UrbanSim + ActivitySim + BEAM**: Long-term land use and transportation co-evolution. UrbanSim simulates multi-year changes, which inform ActivitySim/BEAM travel demand modeling. Changes in accessibility from the transport model inform the next UrbanSim period.

4. **UrbanSim + ATLAS + ActivitySim + BEAM**: Comprehensive modeling of land use, transportation, and vehicle technology co-evolution, including how system changes influence household vehicle choices and their effects on energy consumption and emissions.

-----

## Key Features

* **Modular Architecture**: Containerized models (Docker/Singularity) can be mixed and matched to create custom simulation workflows
* **Flexible Temporal Coupling**: Configure execution frequency of different models to study various feedback loops and time horizons
* **State Management**: Automated tracking and persistence of simulation state across model runs and time steps
* **Reproducibility**: Complete provenance tracking of data transformations and model executions
* **High-Performance Computing**: Optimized for HPC environments with parallel processing support
* **Database Integration**: Optional analytical database backend for improved performance and data management

-----

## Getting Started

### Prerequisites

* Container runtime: **Docker** or **Singularity**
* **Anaconda** or **Miniconda** for Python environment management

### Installation

1. **Clone the repository:**

```bash
git clone https://github.com/LBNL-UCB-STI/PILATES.git
cd PILATES
```

2. **Create and activate the conda environment:**

```bash
conda env create -f environment.yml
conda activate pilates
```

3. **Download input data:**

Various raw input data files are required for the different models. See [lawrencium-setup.md](lawrencium-setup.md#download-data) for instructions.

### Configuration

1. Edit `settings.yaml` to configure your simulation:
- Set container preference: `container_manager: "docker"` or `"singularity"`
- Update region-specific parameters
- Adjust computational settings (`num_processors`, `chunk_size`, etc.)

### Running a Simulation

Execute the main script from the root directory. Use the `-p` flag to pull the latest container images before the first run:

```bash
python run.py -v -p
```
usage: ipython [-v] [-p] [-h HOUSEHOLD_SAMPLE_SIZE] [-s] [-w] [-d DISABLE_MODEL] [-c CONFIG]

optional arguments:
-v, --verbose print docker stdout
-p, --pull_latest pull latest docker images before running
-h HOUSEHOLD_SAMPLE_SIZE, --household_sample_size HOUSEHOLD_SAMPLE_SIZE
household sample size (only works if land use models are disables)
-s, --static_skims bypass traffic assignment altogether (i.e. use base year skims for every run)
-w, --warm_start_skims
generate full activity plans for the base year only. useful for generating warm start skims.
-d DISABLE_MODEL, --disable_model DISABLE_MODEL
"l" for land use, "a" for activity demand, "t" for traffic assignment. Can specify multiple (e.g. "at")
-c CONFIG, --config CONFIG
Specify different config .yaml (other than "settings.yaml")

## Advanced Features

### Database Integration

PILATES includes an optional database backend for improved performance and scalability. The database system supports:

- Direct database input to ActivitySim, eliminating expensive H5 preprocessing
- Dual storage architecture preserving both raw and processed data
- Parallel data uploads for large-scale simulations
- Complete data lineage tracking with OpenLineage metadata
- Automatic schema documentation and data quality validation

For detailed setup and usage instructions, see [docs/database-setup.md](docs/database-setup.md) and [docs/database_documentation_guide.md](docs/database_documentation_guide.md).

### HPC Execution

For high-performance computing environments, specialized scripts are available in the `hpc/` directory. For detailed instructions on setting up PILATES on the Lawrencium cluster, see [lawrencium-setup.md](lawrencium-setup.md).

```bash
cd hpc
./job_runner.sh [options]
```

## Miscellany
### Background Execution

### ActivitySim BEAM integration
In order to have BEAM to run correctly one needs to set the following settings:
To run PILATES as a background process:

1. **skims_fname**: `gemini/10.activitySimODSkims.UrbanSim.TAZ.Full.csv.gz` The full skim file that contains all Origin Destinations pairs with ActivitySim path types.
2. **beam_config**: `gemini/activitysim-base-from-60k-input.conf` Path to beam config. This path must be relative to `beam_local_input_folder` and `region`. The BEAM docker container is provided with this config as an input.
3. **beam_scenario_folder**: `gemini/activitysim-plans-base-2010-cut-60k` Folder with BEAM scenario where ActivitySim output goes. Files from this folder are a scenario input for BEAM.
4. **beam_local_input_folder**: `pilates/beam/production/` Path to BEAM input folder. This folder is going to be mapped to the BEAM container input folder.
5. **beam_local_output_folder**: `pilates/beam/beam_output/` The BEAM output is going to be saved here. In order to have a clean run this directory should be empty before start.
```bash
nohup python run.py -v &
```

#### BEAM Config: saves ASIM skims, enables BEAM to reuse the previous BEAM output plans, linkstats.
Output will be saved to `nohup.out`.

BEAM config should be set in the way so that BEAM saves ActivitySim skims, linkstats and loads people plans and linkstats from the previous runs.
-----

This is the BEAM config options that enables it.
## Architecture

```hocon
# most of the time we need a single iteration
beam.agentsim.firstIteration = 0
beam.agentsim.lastIteration = 0
PILATES uses a consistent preprocessor/runner/postprocessor pattern for model execution, providing a structured approach to data preparation, model execution, and output processing. This pattern enables:

beam.router.skim = {
# This allows to write skims on each iteration
writeSkimsInterval = 1
}
- Modular development and testing of individual components
- Reusability across different simulation models
- Clear separation of concerns for maintainability
- Integrated provenance tracking for reproducibility

beam.exchange{
output {
# this enables saving activitySim Skims
activitySimSkimsEnabled = true
# geo level different than TAZ (in beam taz-centers format)
geo.filePath = ${beam.inputDirectory}"/block_group-centers.csv.gz"
}
}
For implementation details and guidance on integrating new models, see [docs/architecture.md](docs/architecture.md).

# This loads linkStats from the last found BEAM runs
beam.warmStart.type = "linkStatsFromLastRun"
-----

# For subsequential beam runs (some data will be laoded from the latest found run in this directory)
beam.input.lastBaseOutputDir = ${beam.outputs.baseOutputDirectory}
# This prefix is used to find the last run output directory within beam.input.lastBaseOutputDir direcotry
beam.input.simulationPrefix = ${beam.agentsim.simulationName}
## Contributing

# fraction of input plans to be merged into the latest output plans (taken from the beam.input.lastBaseOutputDir)
beam.agentsim.agents.plans.merge.fraction = 0.2
```
We welcome contributions! Please use the [GitHub issue tracker](https://github.com/LBNL-UCB-STI/PILATES/issues) for bug reports, feature requests, and support questions.

### How to Contribute

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/my-feature`)
3. Commit your changes (`git commit -m 'Add new feature'`)
4. Push to the branch (`git push origin feature/my-feature`)
5. Open a Pull Request

Please see our (forthcoming) `CONTRIBUTING.md` for detailed guidelines.

-----

#### Executing the simulation
```shell
nohup python run.py -v
## Citation

If you use PILATES in your research, please cite:

```bibtex
@misc{pilates_2024,
author = {Needell, Zachary and Waddell, Paul and Caicedo, Juan and Laarabi, Haitam and Wang, Yuhan and Poliziani, Cristian and Lazarus, Jessica and Openkov, Dmitrii and Gardner, Max and Rezaei, Nazanin and others},
title = {Platform for Integrated Land use And Transportation Experiments and Simulation (PILATES) v1.0},
doi = {10.11578/dc.20240613.2},
url = {https://www.osti.gov/biblio/2373117},
place = {United States},
year = {2024},
month = {05}
}
```
nohup keeps the script working in case the user session is closed. The output is saved to nohup.out file by default.

-----

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
89 changes: 89 additions & 0 deletions add_missing_iterations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import json
import argparse
import shutil
import re
from pathlib import Path


def add_missing_iterations(run_info_path_str: str, no_backup: bool):
"""
Parses short_names in a run_info.json file to add missing 'iteration'
and 'sub_iteration' keys to file records.
"""
run_info_path = Path(run_info_path_str)

if not run_info_path.exists():
print(f"Error: File not found at {run_info_path}")
return

if not no_backup:
backup_path = run_info_path.with_suffix(run_info_path.suffix + ".bak")
print(f"Creating backup at {backup_path}")
shutil.copy(run_info_path, backup_path)

try:
with open(run_info_path, "r") as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"Error reading JSON file: {e}")
return

if "file_records" not in data:
print("Error: 'file_records' key not found in JSON data.")
return

updated_count = 0
# Regex to find an iteration number at the end of a short_name, e.g., "name_2018_1" -> "1"
iter_pattern = re.compile(r"_(\d+)$")

for record in data["file_records"].values():
# Check if iteration is missing or null
if record.get("iteration") is None:
short_name = record.get("short_name", "")
match = iter_pattern.search(short_name)

if match:
iteration_num = int(match.group(1))
record["iteration"] = iteration_num

# Also ensure sub_iteration exists
if record.get("sub_iteration") is None:
record["sub_iteration"] = 0

updated_count += 1
print(
f"Patched record '{short_name}': set iteration to {iteration_num}"
)

if updated_count > 0:
try:
with open(run_info_path, "w") as f:
json.dump(data, f, indent=2)
print(f"\nSuccessfully patched {updated_count} records in {run_info_path}")
except IOError as e:
print(f"Error writing to file: {e}")
else:
print("No records needed patching for missing iteration numbers.")


def main():
"""Main function to parse arguments and run the patcher."""
parser = argparse.ArgumentParser(
description="Adds missing 'iteration' fields to records in a run_info.json file by parsing the 'short_name'.",
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
"run_info_file", help="Path to the run_info.json file to patch."
)
parser.add_argument(
"--no-backup",
action="store_true",
help="If set, a backup of the original file will not be created.",
)

args = parser.parse_args()
add_missing_iterations(args.run_info_file, args.no_backup)


if __name__ == "__main__":
main()
Loading