export_pipeline¶
Multi-session export pipeline, and the vr-foraging-packaging command that drives it.
Runs in two phases:
- Phase 1 —
process_sessions: iterate raw session directories → per-session parquets (optionally also NWB-Zarr). - Phase 2 —
aggregate: read per-session parquets → flat cross-session parquets.
The vr-foraging-packaging CLI exposes each phase as a subcommand.
batch
¶
Multi-session export: run the session pipeline over many sessions, then aggregate.
Phase 1 — :func:process_sessions: iterate raw session directories → per-session parquets.
Phase 2 — :func:aggregate: read per-session parquets → experiment-level parquets.
The two phases are independent: Phase 2 reads only what Phase 1 left on disk, so
a slow Phase 1 does not have to be repeated to re-cut the aggregates. The
vr-foraging-packaging CLI in :mod:.cli exposes each as its own subcommand.
AGGREGATED_TABLES = (SESSION_TABLE, 'sites')
module-attribute
¶
process_sessions(dataset_paths, output_dir, *, include_processors=(), exclude_processors=(), strict_parsing=False, schema_migration_mode=SchemaMigrationMode.DISABLED, max_workers=1, clean=True, write_parquet=True, write_nwb=False)
¶
Run :func:~.pipeline.session.process_session over many session directories.
Phase 1 of the export. This layer is deliberately thin: everything about a
single session — loading the dataset, building and filtering the processor
list, writing parquet and NWB — belongs to process_session. What is
genuinely multi-session, and therefore lives here, is clean, max_workers,
and the sessions/{session_id}/ layout.
Everything propagates. Anything escaping a processor is unexpected by
definition, so neither a failing session nor a failing batch is caught here
(see docs/knowledge/conventions/error-policy.md).
Parameters¶
dataset_paths:
Iterable of paths, each pointing to the root directory of one raw session.
output_dir:
Root of the experiment export. Per-session files go to
output_dir/sessions/{session_id}/.
include_processors, exclude_processors, strict_parsing, schema_migration_mode, write_parquet, write_nwb:
Per-session options, forwarded unchanged to
:func:~.pipeline.session.process_session (as include / exclude /
strict_parsing / write_parquet / write_nwb). This layer adds no
behaviour of its own to any of them, so their semantics are documented
once, there.
Note that ``write_parquet=False`` leaves Phase 2 nothing to aggregate:
:func:`aggregate` reads the per-session parquets back off disk.
max_workers:
Number of parallel threads. 1 (default) runs sessions sequentially.
Values > 1 process up to max_workers sessions concurrently via
:class:~concurrent.futures.ThreadPoolExecutor.
clean:
When True (default), delete the outputs a previous run of this
function left in output_dir — the sessions/ tree and the
aggregated {table}.parquet files — so a re-run never mixes results
from two invocations. Set to False to resume a partial run.
It deliberately does **not** wipe *output_dir* itself. Anything else
living there is not ours to delete: a log file being written to
``output_dir/run.log`` is the obvious case, and on Windows removing an
open file fails outright.
Returns¶
list[Path]
Paths to the written session directories (output_dir/sessions/{session_id}).
Source code in src/aind_behavior_vr_foraging_packaging/pipeline/batch.py
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | |
aggregate(sessions_dir, output_dir, *, schema_migration_mode=SchemaMigrationMode.DISABLED)
¶
Concatenate per-session parquets into experiment-level files.
Writes one flat output_dir/{table}.parquet for each name in
:data:AGGREGATED_TABLES, with a session_id column for joins.
Each file is sorted by session_id (stably, so rows keep their order
within a session) and written in row groups of
:data:AGGREGATED_ROW_GROUP_SIZES rows, with statistics and a page index.
Readers filtering on session_id therefore fetch only the row groups that
hold the sessions they asked for.
What gets aggregated is fixed, not configurable: the set is a property of the schema — which tables are small enough to scan experiment-wide — rather than something a caller should decide per run.
Per-session files are never deleted. Copying rows into an aggregate is not a
reason to destroy the source: the per-session files are what
--skip-processing re-aggregation reads back, and the only copies carrying
provenance in their parquet schema.
Parameters¶
sessions_dir:
Directory produced by :func:process_sessions
(i.e. output_dir/sessions/).
output_dir:
Root output directory where aggregated files are written.
schema_migration_mode:
DISABLED leaves the table unchanged, FILL_MISSING appends or
fills migrated values while preserving existing ones, and FORCE
recomputes every migrated value. Raw columns are never replaced.