Skip to main content

BIDS-Aid

Latest Version Python Versions Source Code License Test Status codecov Code style: black Documentation Status

A toolkit for creating and managing BIDS-compliant fMRI datasets without original DICOMs. Intended for cases that require custom code and flexibility, such as when NIfTI source files lack consistent naming conventions, organized folder hierarchies, or sidecar metadata. Includes utilities for metadata reconstruction from NIfTI headers, file renaming, neurobehavioral log parsing (for E-Prime and Presentation), JSON sidecar generation, surface projection, and making surface clips/movies.

Installation

Standard Installation

pip install bidsaid[all]

Surface projection and movie writing are optional extras: bidsaid[surface] (neuromaps for the fsaverage surfaces), bidsaid[visual] (pyvista for rendering) and bidsaid[movie] (imageio with ffmpeg for writing movies). bidsaid[all] includes everything.

Development Version

git clone --depth 1 https://github.com/donishadsmith/bidsaid/
cd bidsaid
pip install -e .[all]

Features

  • File renaming: Convert arbitrary filenames to BIDS-compliant naming

  • File creation: Generate dataset_description.json and participants.tsv

  • Metadata utilities: Extract header metadata (e.g., TR, orientation, scanner info) and generate slice timing for singleband and multiband acquisitions

  • Log parsing: Load Presentation (e.g., .log) and E-Prime 3 (e.g, .edat3, .txt) files as DataFrames, or use extractor classes to generate BIDS events for block and event designs:

    Class Software Design Description
    PresentationBlockExtractor Presentation Block Extracts block-level timing with mean RT and accuracy
    PresentationEventExtractor Presentation Event Extracts trial-level timing with individual responses
    EPrimeBlockExtractor E-Prime 3 Block Extracts block-level timing with mean RT and accuracy
    EPrimeEventExtractor E-Prime 3 Event Extracts trial-level timing with individual responses
  • Auditing: Generate a table showing the presence or absence of certain files for each subject and session

  • QC: Creation and computation of certain quality control metrics (e.g., framewise displacement), censoring and temporal interpolation

  • Surface movies: Project denoised runs onto the fsaverage surfaces and write per-participant, per-task or group movies with SurfaceRenderer and MovieWriter

Quick Start

Creating BIDS-Compliant Filenames

from bidsaid.files import create_bids_file

create_bids_file(
    src_file="101_mprage.nii.gz",
    sub_id="101",
    ses_id="01",
    desc="T1w",
    dst_dir="/data/bids/sub-101/ses-01/anat",
)

Extracting Metadata from NIfTI Headers

from bidsaid.metadata import get_tr, create_slice_timing, get_image_orientation

tr = get_tr("sub-01_bold.nii.gz")
slice_timing = create_slice_timing(
    "sub-01_bold.nii.gz",
    slice_acquisition_method="interleaved",
    multiband_factor=4,
)
orientation_map, orientation = get_image_orientation("sub-01_bold.nii.gz")

Loading Raw Log Files

from bidsaid.parsers import (
    load_presentation_log,
    load_eprime_log,
    convert_edat3_to_text,
)

presentation_df = load_presentation_log("sub-01_task.log", convert_to_seconds=["Time"])

# E-Prime 3: convert .edat3 to text first, or load .txt directly
eprime_txt_path = convert_edat3_to_text("sub-01_task.edat3")
eprime_df = load_eprime_log(eprime_txt_path, convert_to_seconds=["Stimulus.OnsetTime"])

Creating BIDS Events from Presentation Logs

from bidsaid.events import PresentationBlockExtractor
import pandas as pd

extractor = PresentationBlockExtractor(
    "sub-01_task-faces.log",
    trial_types=("Face", "Place"),  # Can use regex ("Fa.*", "Pla.*")
    scanner_event_type="Pulse",
    scanner_trigger_code="99",
    convert_to_seconds=["Time"],
    rest_block_codes="crosshair",
    rest_code_pattern="fixed",
    split_cue_from_block=True,
)

events_df = pd.DataFrame(
    {
        "onset": extractor.extract_onsets(),
        "duration": extractor.extract_durations(),
        "trial_type": extractor.extract_trial_types(),
        "mean_rt": extractor.extract_mean_reaction_times(),
    }
)

Creating BIDS Events from E-Prime Logs

from bidsaid.events import EPrimeEventExtractor
import pandas as pd

extractor = EPrimeEventExtractor(
    "sub-01_task-gonogo.txt",
    trial_types="Go|NoGo",  # Can also use ("Go", "NoGo")
    onset_column_name="Stimulus.OnsetTime",
    procedure_column_name="Procedure",
    trigger_column_name="ScannerTrigger.RTTime",
    convert_to_seconds=[
        "Stimulus.OnsetTime",
        "Stimulus.OffsetTime",
        "ScannerTrigger.RTTime",
    ],
)

events_df = pd.DataFrame(
    {
        "onset": extractor.extract_onsets(),
        "duration": extractor.extract_durations(
            offset_column_name="Stimulus.OffsetTime"
        ),
        "trial_type": extractor.extract_trial_types(),
        "reaction_time": extractor.extract_reaction_times(
            reaction_time_column_name="Stimulus.RT"
        ),
    }
)

Audit BIDS Dataset

from bidsaid.audit import BIDSAuditor
from bidsaid.simulate import simulate_bids_dataset

bids_root = simulate_bids_dataset()

auditor = BIDSAuditor(bids_root)
auditor.check_raw_nifti_availability()
auditor.check_raw_sidecar_availability()
auditor.check_events_availability()
auditor.check_preprocessed_nifti_availability()

analysis_dir = bids_root / "first_level"
analysis_sub_dir = analysis_dir / "sub-1" / "ses-1"
analysis_sub_dir.mkdir(parents=True, exist_ok=True)

with open(analysis_sub_dir / "sub-1_task-rest_desc-betas.nii.gz", "w") as f:
    pass

auditor.check_first_level_availability(analysis_dir=analysis_dir, desc="betas")

Compute QC

from bidsaid.qc import create_censor_mask, compute_consecutive_censor_stats

censor_mask = create_censor_mask(
    "confounds.tsv",
    column_name="framewise_displacement",
    threshold=0.5,
    n_dummy_scans=4,
)

consecutive_censor_mean, consecutive_censor_std = compute_consecutive_censor_stats(
    censor_mask, n_dummy_scans=4
)

Surface Movies

from bidsaid.movie import MovieWriter, compute_vmax, create_surface_run, virtual_display
from bidsaid.surface import fetch_fsaverage_surfaces, get_cortex_masks
from bidsaid.visual import SurfaceRenderer

surfaces = fetch_fsaverage_surfaces("10k")
cortex_masks = get_cortex_masks(surfaces["medial"])

# One run per participant and task; the "sub" and "task" entities are read from the filename
surface_runs = [
    create_surface_run(
        denoised_file,
        surfaces["pial"],
        surfaces["white"],
        cortex_masks,
        n_interpolated_frames=1,  # smoother playback (display only)
        fwhm=4,
    )
    for denoised_file in [
        "sub-01_task-rest_desc-denoised_bold.nii.gz",
        "sub-01_task-music_desc-denoised_bold.nii.gz",
        "sub-02_task-rest_desc-denoised_bold.nii.gz",
        "sub-02_task-music_desc-denoised_bold.nii.gz",
    ]
]

threshold = 1.0
vmax = compute_vmax(surface_runs, threshold=threshold)

# virtual_display starts Xvfb for headless environments
with (
    virtual_display(),
    SurfaceRenderer(
        *surfaces["inflated"],
        sulcal_depths=surfaces["sulc"],
        color_range=(-vmax, vmax),
        threshold=threshold,
        top_spacing=80,  # space aboce brains for label
    ) as renderer,
):
    movie_files = MovieWriter(
        surface_runs,
        renderer,
        task_order=["rest", "music"],
        playback_speed=1,
        label_format="{subject_name} {task_name} t = {frame_time:.1f} s",
    ).write("movies", per_subject=True, per_task=True, shared=True)

Each participant is a row and each task a column. per_subject writes one movie per participant with their tasks side by side, per_task one movie per task with the participants stacked, and shared the full grid in a single movie.

See the API documentation for full parameter details and additional utilities.

Metadata

Release files for bidsaid 0.33.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bidsaid 0.33.0
File Size Uploaded Provenance
bidsaid-0.33.0.tar.gz 109.1 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for bidsaid 0.33.0
File
bidsaid-0.33.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
bidsaid-0.33.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
bidsaid-0.33.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
bidsaid-0.33.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 1.7 MB

Release files / bidsaid-0.33.0.tar.gz

Download URL bidsaid-0.33.0.tar.gz
Size 109.1 kB
Tags Source
SHA-256 checksum
How to use checksums
382264857d98467f2a4867bd59e5109e4e64cfd03d273df94c7ca9ed078e8646
BLAKE2b-256 checksum
How to use checksums
3c6874152e1f0a1ee8f494a7d2515382fbfa5cbf88d2a568db16578aa0bbf4e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / bidsaid-0.33.0-cp310-abi3-win_amd64.whl

Download URL bidsaid-0.33.0-cp310-abi3-win_amd64.whl
Size 301.6 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
ee4ac181689c67dbc6bb1474a35213f2798ff307e47953b2ba6faed8fbd89091
BLAKE2b-256 checksum
How to use checksums
e80d66dd48ea399467e5e7bd5248459e554aaf6a8b722450ff7f6666289299d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / bidsaid-0.33.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL bidsaid-0.33.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 458.0 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
63295f99ec9b7d7961eb9d0197e924002c08bb80b683fd78599532bf969501a4
BLAKE2b-256 checksum
How to use checksums
7f3c1d0a838c23cf0b3de22bbd32701fc5d9d56d2290a2163e789586ca3071a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / bidsaid-0.33.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL bidsaid-0.33.0-cp310-abi3-macosx_11_0_arm64.whl
Size 409.0 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c09bebfa6b7450571f088c3c42ecb464403ac8037721c5c93aa72dbe16f7b4ee
BLAKE2b-256 checksum
How to use checksums
9e6851a9f31e36aef9e23fb39e1908289ff33572ab466756430cc5463d876fb8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / bidsaid-0.33.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL bidsaid-0.33.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 410.6 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
bd07cd04e09cb5d78b235ba665720f1440464009047d5facb1a6aa395a19d503
BLAKE2b-256 checksum
How to use checksums
73502374dbd1b009baf73edbaf257472720695f1678ed2eef64e2aa8912ab6d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Security for bidsaid 0.33.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page