Usage¶
The general usage of ffrprep is to preprocess frequency-following response (FFR) EEG data in BIDS format.
ffrprep is a BIDS-compatible preprocessing workflow designed specifically for FFR experiments, providing
automated preprocessing pipelines that include data loading, filtering, artifact removal, and report generation
for neurophysiological data analysis.
The exact command to run ffrprep depends on the Installation method and user. Regarding the latter, ffrprep
can either be used as a command line tool or directly within python. Please refer to the Tutorial for a more detailed walkthrough.
Here’s a very conceptual example of running ffrprep via CLI:
ffrprep
ffrprep optional_arguments
and here from within python:
from ffrprep import ffrprep_function
from ffrprep import ffrprep_function
result = ffrprep_function(input)
result = ffrprep_function(input, optional_arguments)
Below, we will focus on the CLI version. For programmatic use,
the Reference API documents every public function with its
signature and parameters.
ffrprep through the CLI¶
As ffrprep is a BIDS-App , it is primarily designed as a command-line tool that you can run directly from your terminal or command prompt.
Ideally, using the provided Docker or Singularity images as they encapsulate all dependencies and ensure a consistent environment across different systems, ensuring ease-of-use and
reproducibility.
Downloading the example dataset¶
The download subcommand of the container fetches the example
OSF dataset used in the
Tutorial. The
container’s entrypoint dispatches download … to the
ffrprep-download console script bundled inside the image.
# Just the EEG data (default)
docker run --rm \
-v /path/to/data:/out:rw \
ksitek/ffrprep:latest \
download example --out /out
# Also fetch the stimulus audio + augment events.tsv with the
# BIDS stim_file column (needed for the stim-vs-response
# correlation in the analysis report)
docker run --rm \
-v /path/to/data:/out:rw \
ksitek/ffrprep:latest \
download example --with-stimuli --out /out
--with-stimuli is BooleanOptionalAction (default False);
--no-with-stimuli is its inverse. The download lands the EEG
data under <out>/ffrprep_raw_data/ and the stimulus files
under <out>/ffrprep_raw_data/stimuli/ per the BIDS spec, then
augments every sub-*/eeg/*_events.tsv with the matching
stim_file column based on a trial_type → filename lookup.
Command-Line Arguments¶
ffrprep: A BIDS-App for standardized FFR preprocessing and analysis
usage: ffrprep [-h] [-v]
[--participant_label PARTICIPANT_LABEL [PARTICIPANT_LABEL ...]]
[--stage {preprocessing,analysis,both}]
[--ref_channels REF_CHANNELS [REF_CHANNELS ...]]
[--high_pass HIGH_PASS] [--low_pass LOW_PASS] [--l_freq L_FREQ]
[--h_freq H_FREQ] [--no-filter] [--baseline START END]
[--picks PICKS] [--on-missing {warn,raise,ignore}]
[--event-id EVENT_ID] [--events-file EVENTS_FILE] [--tmin TMIN]
[--tmax TMAX] [--reject-eeg REJECT_EEG] [--no-auto-reject]
[--concat-runs] [--save-each-node] [--run RUN [RUN ...]]
[--task TASK [TASK ...]]
[--split-by-trial-type | --no-split-by-trial-type]
[--trial-types TRIAL_TYPES [TRIAL_TYPES ...]]
[--difference-pairs DIFFERENCE_PAIRS [DIFFERENCE_PAIRS ...]]
[--skip_bids_validation] [--n_procs N_PROCS]
[--work_dir WORK_DIR]
bids_dir output_dir {participant,group}
Positional Arguments¶
- bids_dir
The directory with the input dataset formatted according to the BIDS standard.
- output_dir
The directory where the output files should be stored. If you are running group level analysis this folder should be prepopulated with the results of the participant level analysis.
- analysis_level
Possible choices: participant, group
Level of the analysis that will be performed. Multiple participant level analyses can be run independently (in parallel) using the same output_dir.
Named Arguments¶
- -v, --version
show program’s version number and exit
- --participant_label
The label(s) of the participant(s) that should be processed. The label corresponds to sub-<participant_label> from the BIDS spec (so it does not include “sub-“). Multiple participants can be specified with a space-separated list.
- --stage
Possible choices: preprocessing, analysis, both
Processing stage to run: preprocessing only, analysis only, or both stages sequentially.
- --skip_bids_validation
Assume the input dataset is BIDS compliant and skip the validation.
- --n_procs
Number of parallel (task, run) workers per subject. Each worker runs its own preprocessing or analysis workflow with the Linear plugin. Memory footprint scales linearly with this value. A failure in any worker aborts the run. Default: 1 (sequential). For multi-node / cluster scaling, run one ffrprep invocation per subject (e.g. via slurm array or GNU parallel) and use –n_procs to control intra-subject parallelism.
- --work_dir
Path where intermediate results should be stored.
Preprocessing options¶
- --ref_channels
Reference channel(s) for re-referencing. Provide space-separated channel names (e.g. –ref_channels M1 M2). Use ‘average’ for average reference. Comma-separated single-argument styles are also accepted for backward compatibility (e.g. ‘M1,M2’).
- --high_pass
High-pass filter cutoff frequency in Hz.
- --low_pass
Low-pass filter cutoff frequency in Hz.
- --l_freq
Lower-pass edge in Hz (MNE name: l_freq). If provided, overrides –high_pass. Use ‘None’ via –no-filter to disable.
- --h_freq
Upper-pass edge in Hz (MNE name: h_freq). If provided, overrides –low_pass. Use ‘None’ via –no-filter to disable.
- --no-filter
Disable filtering entirely (equivalent to l_freq=None and h_freq=None). When set, any provided l_freq/h_freq/high_pass/low_pass are ignored.
- --baseline
Baseline correction period. Provide two numbers: START END in seconds (e.g. –baseline -0.2 0 for -200ms to 0ms).
- --picks
Channels to include in epochs. Comma-separated list or single channel name (e.g. ‘Cz’ or ‘Cz,Fz’). If not provided, all channels are considered.
- --on-missing
Possible choices: warn, raise, ignore
Behavior when events referenced by event_id are missing: warn, raise, or ignore. Matches MNE’s on_missing option.
- --event-id
Event id mapping. Provide a JSON string like ‘{“A”:1,”B”:2}’ or comma-separated pairs like ‘A:1,B:2’. If not provided, event ids will be inferred from events file or annotations.
- --events-file
Optional path to an events.tsv file to use for epoching. If not provided, events will be inferred from annotations.
- --tmin
Start time of epochs relative to event onset (s).
- --tmax
End time of epochs relative to event onset (s).
- --reject-eeg
Peak-to-peak rejection threshold for EEG channels in Volts. Set to 0 to disable automatic rejection.
- --no-auto-reject
Disable automatic amplitude-based epoch rejection.
- --concat-runs
Concatenate multiple runs for a subject and process them as a single recording. By default runs are processed separately.
- --save-each-node
Write intermediate outputs to disk after each preprocessing step (disk-backed mode). This reduces peak memory at the expense of increased I/O and runtime.
- --run
Run label(s) to process for the participant (without the ‘run-’ prefix). If not provided, all runs found for the subject will be processed. Multiple runs can be provided as space-separated values, or as a single comma-separated string (e.g. ‘1 2’ or ‘1,2’).
- --task
Task label(s) to process for the participant (without the ‘task-’ prefix). If not provided, all tasks found for the subject will be processed. Multiple tasks can be provided as space-separated values, or as a single comma-separated string (e.g. ‘active passive’).
Analysis options¶
- --split-by-trial-type, --no-split-by-trial-type
Emit per-trial-type epoched and evoked outputs. Pass –no-split-by-trial-type to fall back to a single combined output per (subject, task, run).
- --trial-types
Restrict per-trial-type outputs to this subset of trial types (matched against the events.tsv
trial_typecolumn). If omitted, all trial types are emitted.- --difference-pairs
Difference evokeds to compute, given as
A:Btokens (e.g. Pos:Neg). For exactly two trial types the diff is auto-computed; this flag is required to opt in to diffs when there are three or more trial types.
Example Call(s)¶
The examples below all use Docker — the recommended path. They
build up from the simplest call (preprocessing only, one subject)
to per-trial-type analysis outputs with explicit difference pairs.
Singularity users can swap the docker run … invocation for
singularity run --cleanenv -B <host>:<container> <image.sif>
keeping every flag below the image name identical.
All examples assume your BIDS dataset is at
/local/bids_dataset on the host and the derivatives should
land in /local/bids_dataset/derivatives.
Example 1 - Basic preprocessing¶
docker run --rm \
-v /local/bids_dataset:/data:rw \
ksitek/ffrprep:latest \
/data \
/data/derivatives \
participant \
--participant_label 01 02 \
--stage preprocessing
What’s in this call:
docker run --rmruns the container and removes it after completion.-v /local/bids_dataset:/data:rwmounts the local BIDS dataset read-write so derivatives can be written back to disk.ksitek/ffrprep:latestis the published image (see Installation for tag pinning)./data(1st positional) is the BIDS dataset inside the container;/data/derivatives(2nd) is the output directory;participant(3rd) is the BIDS-App analysis level.--participant_label 01 02processes onlysub-01andsub-02.--stage preprocessingruns only the preprocessing stage.
Example 2 - Full analysis with custom parameters¶
docker run --rm \
-v /local/bids_dataset:/data:rw \
ksitek/ffrprep:latest \
/data \
/data/derivatives \
participant \
--stage both \
--high_pass 0.5 \
--low_pass 50.0 \
--ref_channels average \
--baseline "-0.1,0" \
--n_procs 4
What’s in this call:
--stage bothruns both preprocessing and analysis stages.--high_pass 0.5/--low_pass 50.0set the band-pass filter in Hz.--ref_channels averageuses an average reference.--baseline "-0.1,0"sets the baseline window to −100 ms → 0 ms.--n_procs 4runs 4 per-(task, run) iterations in parallel per subject (see Parallelization below).
By default the analysis stage emits one evoked response per
trial_type value in events.tsv
(_desc-evoked{Cond}.fif), a combined evoked across all events
(_desc-evoked.fif), and — for 2-trial-type datasets — an
auto-paired difference evoked (_desc-evokedDiff{A}Vs{B}.fif).
This per-trial-type split is governed by --split-by-trial-type
(default on); pass --no-split-by-trial-type to emit only the
combined evoked. Examples 3 and 4 below show how to pick explicit
difference pairs or restrict the output set.
Example 3 - Per-trial-type analysis with explicit difference pairs¶
For datasets with more than two trial_type values, the
automatic difference is ambiguous; use
--difference-pairs A:B [C:D …] to specify which pairs to
subtract. Each pair becomes one
_desc-evokedDiff{A}Vs{B}.fif file. The per-trial-type
_desc-evoked{Cond}.fif and combined _desc-evoked.fif
files are always emitted.
docker run --rm \
-v /local/bids_dataset:/data:rw \
ksitek/ffrprep:latest \
/data \
/data/derivatives \
participant \
--stage both \
--difference-pairs positive:negative tone1:tone2 \
--n_procs 4
What’s in this call:
--difference-pairs positive:negative tone1:tone2emits two difference evokeds:_desc-evokedDiffPositiveVsNegative.fif(positive − negative) and_desc-evokedDiffTone1VsTone2.fif(tone1 − tone2).All per-trial-type and combined evokeds for this (task, run) group are also written —
--split-by-trial-typeis on by default, and--difference-pairsrequires it (the pairs are subtracted from the per-trial-type evokeds, so combining it with--no-split-by-trial-typewould leave nothing to subtract).
Example 4 - Restrict outputs to a subset, no split¶
The trial-type split is controlled by a single boolean flag, exposed
in both forms via argparse.BooleanOptionalAction:
--split-by-trial-type(the default) emits the combined evoked plus one_desc-evoked{Cond}.fifper trial type plus the auto-paired / explicit difference evokeds. Passing this flag explicitly is equivalent to omitting it.--no-split-by-trial-typestrips back to the combined evoked only — no per-trial-type files, no differences.
To keep the split on but restrict it to a subset of trial types
(while still emitting the combined evoked), pass
--trial-types A B.
# Combined evoked only — strips per-trial-type files and
# any (auto-paired or explicit) difference evokeds
docker run --rm \
-v /local/bids_dataset:/data:rw \
ksitek/ffrprep:latest \
/data \
/data/derivatives \
participant \
--stage both \
--no-split-by-trial-type \
--n_procs 4
# Only emit per-trial-type files for "positive" + the combined
# evoked; drop the "negative" output even though events.tsv
# contains both
docker run --rm \
-v /local/bids_dataset:/data:rw \
ksitek/ffrprep:latest \
/data \
/data/derivatives \
participant \
--stage both \
--trial-types positive \
--n_procs 4
Parallelization and cluster usage¶
ffrprep follows the standard BIDS-App parallelism model:
Inside one invocation —
--n_procs Nruns N per-(task, run) iterations concurrently for the subject(s) being processed. Each worker runs its own preprocessing or analysis workflow with the NipypeLinearplugin. Default:--n_procs 1(sequential). Memory footprint scales linearly with N — each worker loads its own raw + epochs into memory, so dial it down on small machines.Across invocations — for multi-node / cluster scaling, run one
ffrprepinvocation per subject under your scheduler (slurm job array, GNU parallel, HTCondor, etc.). Both layers compose: 8 parallel slurm tasks each with--n_procs 4gives 32-way effective parallelism.
Single workstation¶
ffrprep \
/data/bids_dataset \
/data/bids_dataset/derivatives \
participant \
--participant_label 01 02 03 \
--n_procs 4
The 4 workers chew through each subject’s (task, run) iterations in parallel, then move to the next subject.
Cluster (slurm job array)¶
Run one invocation per subject via the scheduler; each job uses
--n_procs for intra-subject parallelism. Example wrapper script:
# ffrprep_one_subject.sh
#!/bin/bash
#SBATCH --array=0-99
#SBATCH --cpus-per-task=4
#SBATCH --mem=16G
SUBJECTS=(sub-01 sub-02 sub-03 ...)
SUB=${SUBJECTS[$SLURM_ARRAY_TASK_ID]}
ffrprep /data /data/derivatives participant \
--participant_label ${SUB#sub-} \
--n_procs $SLURM_CPUS_PER_TASK
Cluster (GNU parallel on a single beefy box)¶
parallel -j 8 \
"ffrprep /data /data/derivatives participant \
--participant_label {} --n_procs 4" \
::: 01 02 03 04 05 06 07 08
Failure handling¶
A failure in any (task, run) iteration aborts the run (fail-fast). The
exception propagates up from the worker to the CLI entry point, so the
underlying error is visible in the terminal output. Per-iteration logs
land in <work_dir>/<task>-<run>.log so you can drill into the
failing iteration without scanning the whole subject log.
Support and communication¶
The documentation of this project is found here: https://sitek.github.io/ffrprep.
All bugs, concerns and enhancement requests for this software can be submitted here: https://github.com/sitek/ffrprep/issues.
If you have a problem or would like to ask a question about how to use ffrprep,
please submit a question to NeuroStars.org with an ffrprep tag.
NeuroStars.org is a platform similar to StackOverflow but dedicated to neuroinformatics.
All previous ffrprep questions are available here:
http://neurostars.org/tags/ffrprep/
Not running on a local machine? - Data transfer¶
Please contact you local system administrator regarding possible and favourable transfer options (e.g., rsync or FileZilla).
A very comprehensive approach would be Datalad, which will handle data transfers with the appropriate settings and commands. Datalad also performs version control over your data.