A toolkit for post-hoc BIDS conversion starting from NIfTI files. Includes utilities for metadata extraction, file renaming, neurobehavioral log parsing (for E-Prime and Presentation), and JSON sidecar generation. Designed primarily for datasets where the original DICOMs are unavailable.
pip install nifti2bids[all]git clone --depth 1 https://github.com/donishadsmith/nifti2bids/
cd nifti2bids
pip install -e .[all]-
File renaming: Convert arbitrary filenames to BIDS-compliant naming
-
File creation: Generate
dataset_description.jsonandparticipants.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 PresentationBlockExtractorPresentation Block Extracts block-level timing with mean RT and accuracy PresentationEventExtractorPresentation Event Extracts trial-level timing with individual responses EPrimeBlockExtractorE-Prime 3 Block Extracts block-level timing with mean RT and accuracy EPrimeEventExtractorE-Prime 3 Event Extracts trial-level timing with individual responses -
Auditing: Generate a table of showing the presence or abscence of certain files for each subject and session
from nifti2bids.bids import create_bids_file
create_bids_file(
src_file="101_mprage.nii.gz",
subj_id="101",
ses_id="01",
desc="T1w",
dst_dir="/data/bids/sub-101/ses-01/anat",
)from nifti2bids.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")from nifti2bids.parsers import (
load_presentation_log,
load_eprime_log,
convert_edat3_to_txt,
)
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_txt("sub-01_task.edat3")
eprime_df = load_eprime_log(eprime_txt_path, convert_to_seconds=["Stimulus.OnsetTime"])from nifti2bids.bids import PresentationBlockExtractor
import pandas as pd
extractor = PresentationBlockExtractor(
"sub-01_task-faces.log",
block_cue_names=("Face", "Place"),
scanner_event_type="Pulse",
scanner_trigger_code="99",
convert_to_seconds=["Time"],
rest_block_code="crosshair",
rest_code_frequency="fixed",
split_cue_as_instruction=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(),
}
)from nifti2bids.bids import EPrimeEventExtractor
import pandas as pd
extractor = EPrimeEventExtractor(
"sub-01_task-gonogo.txt",
trial_types=("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"
),
}
)from nifti2bids.audit import BIDSAuditor
from nifti2bids.simulate import simulate_bids_dataset
bids_root = simulate_bids_dataset()
auditor = BIDSAuditor(bids_root)
auditor.check_raw_nifti_availability()
auditor.check_preprocessed_nifti_availability()See the API documentation for full parameter details and additional utilities.