BIDS Output¶
The pipeline writes a Motion-BIDS dataset. This page catalogs every file it produces and the conventions behind them.
Two BIDS terms used throughout this page
- Entity — a
key-valuesegment in a BIDS filename, e.g.sub-01,ses-01,task-VRtracking,tracksys-Head. Entities encode what a file is, so the name alone identifies its subject, session, task, and tracking system. - Sidecar — a
.jsonfile sitting next to a data file with the same name, holding that file's metadata (units, sampling rate, descriptions). Everymotion.tsv/channels.tsvhas a matching.jsonsidecar.
Directory structure¶
A run produces three tiers under bids_root: the raw dataset at the root, a verbatim sourcedata/ copy of the inputs, and a preprocessed derivatives/resxr/ tier.
bids_root/
├── dataset_description.json
├── participants.tsv
├── participants.json
├── README
├── .bidsignore
├── sub-01/
│ └── ses-01/
│ ├── sub-01_ses-01_scans.tsv
│ ├── sub-01_ses-01_task-VRtracking_events.tsv
│ ├── sub-01_ses-01_task-VRtracking_events.json
│ ├── <session_id>_report.html
│ └── motion/
│ ├── sub-01_ses-01_task-VRtracking_tracksys-Head_motion.tsv
│ ├── sub-01_ses-01_task-VRtracking_tracksys-Head_motion.json
│ ├── sub-01_ses-01_task-VRtracking_tracksys-Head_channels.tsv
│ ├── sub-01_ses-01_task-VRtracking_tracksys-Head_channels.json
│ └── ... (Hands, Eyes, Face, …)
├── sourcedata/
│ └── sub-01/ses-01/ # exact copy of the input session folder
└── derivatives/
└── resxr/
├── dataset_description.json # DatasetType: derivative
├── README
└── sub-01/ses-01/
├── sub-01_ses-01_scans.tsv
└── motion/ ... # same motion/channels files (no events)
One tracksys- set (motion.tsv + motion.json + channels.tsv + channels.json) is written per enabled tracking system. The derivative tier mirrors the motion files but omits the events files.
Filenames¶
Motion and channels files follow the BIDS entity convention:
For example, with task_name: VRtracking:
sub-01_ses-01_task-VRtracking_tracksys-Head_motion.tsv
sub-01_ses-01_task-VRtracking_tracksys-Hands_channels.tsv
<System> is one of Head, Hands, Eyes, Face, Body, Controllers. The scans.tsv and events.tsv files use only sub-/ses- (and task- for events), without tracksys-.
motion.tsv¶
The numeric time series for one tracking system — one row per sample, no header row (the columns are described in the sibling channels.tsv). The column order matches channels.tsv exactly.
Each motion.tsv is produced from a prepared DataFrame: its leading columns are latency (and latency_global when a per-system clock is used), and the internal timestamp/timeSinceStartup columns have been removed. Missing values are written using the configured token (default n/a); files use LF line endings and full float precision.
channels.tsv¶
One row per column in the matching motion.tsv, describing each channel. Columns:
| Column | Description |
|---|---|
name |
Channel/column name (e.g. Node_Head_px, latency). |
component |
Spatial component (x/y/z, quat_x…quat_w, or n/a). |
type |
BIDS channel type. In practice the pipeline emits POS, ORNT, LATENCY, and MISC; other BIDS types (VEL, ACCEL, GYRO, …) are recognized by the schema but are not produced from current Quest/Unity columns. |
tracked_point |
The tracked point the channel belongs to (or n/a for latency). |
units |
Physical units (m, s, boolean, normalized, n/a, …). |
sampling_frequency |
The system's nominal (expected) rate. |
reference_frame |
global for spatial channels (POS/ORNT), else n/a. |
Channel type, component, and units are inferred from each column's name suffix (e.g. _px/_py/_pz → POS in metres; _qx…_qw → ORNT quaternion; latency/latency_global → LATENCY in seconds; face blendshapes → MISC, normalized).
JSON sidecars¶
motion.json¶
Per tracking system. Contains: TaskName, TaskDescription (from system_descriptions or device.task_description), Manufacturer, ManufacturersModelName, SoftwareVersions, TrackingSystemName, SamplingFrequency (expected), SamplingFrequencyEffective (measured), MissingValues, MotionChannelCount, TrackedPointsCount, the per-type channel counts (POSChannelCount, ORNTChannelCount, LATENCYChannelCount, MISCChannelCount, …), and DeviceSerialNumber when present.
SoftwareVersions is assembled engine-agnostically from the captured metadata, e.g.:
channels.json¶
Describes the coordinate system, from bids.reference_frame:
{
"reference_frame": {
"Description": "Global VR playspace coordinate system...",
"Levels": {
"global": {
"Description": "...",
"RotationRule": "left-hand",
"RotationOrder": "ZXY",
"SpatialAxes": "RSA"
}
}
}
}
dataset_description.json¶
- Raw (root):
Name,BIDSVersion,DatasetType(raw),License, andAuthors(if any). - Derivative:
Namesuffixed(preprocessed),DatasetType: derivative,GeneratedBy: [{"Name": "ResXR"}].
Events¶
When the input has an events file and/or custom tables, the pipeline writes a single merged events.tsv at the session root (raw tier only):
It starts with the BIDS-required onset, duration, then name, followed by the union of all custom-table columns. Native event rows carry n/a in custom columns and vice versa. The sibling events.json documents onset, duration, name (with Levels listing observed event names), and every custom column for which a schema description exists (Description, Format, and optional Units/Levels/Minimum/Maximum).
scans.tsv¶
One per session (both tiers). Lists each motion file with its acquisition time:
| Column | Value |
|---|---|
filename |
motion/<motion filename> |
acq_time |
The recording's UTC start (YYYY-MM-DDThh:mm:ss.000), or n/a if unknown. |
participants.tsv / participants.json¶
Dataset-level. participants.tsv has one row per subject — participant_id, age, sex, handedness — drawn from the session mappings (n/a where unset). participants.json documents those columns, including the sex levels (M/F) and handedness levels (R/L/A).
.bidsignore¶
Created at the dataset root (only if absent — never overwritten) to keep non-standard artifacts from tripping BIDS validators. It ignores all .html, .png, and .jpg files and the .git/ directory dataset-wide (not only the generated reports).
Conventions worth knowing¶
- LF line endings are forced on all generated TSV/JSON files, so output is byte-reproducible across operating systems.
- Full float precision is preserved in
motion.tsv(no rounding). sourcedata/is a verbatim copy of the input session folder (including theCustomTables/subfolder), so the original recording always travels with the dataset. It is not re-copied if already present unlessoutput.overwriteis set.