From 722bfc04ab3f6ebed79140b4db6ae3125d708b69 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Mon, 27 Jun 2022 13:56:54 +0200 Subject: [PATCH 1/2] update doc basic calls bids app and bids filter file --- docs/source/FAQ.md | 57 ++++++++++++++++++++++++++++++++-- src/messages/cppSpmHelp.m | 64 ++++++++++++++++++++++++++++----------- 2 files changed, 101 insertions(+), 20 deletions(-) diff --git a/docs/source/FAQ.md b/docs/source/FAQ.md index c38f9ac89..52d9f3174 100644 --- a/docs/source/FAQ.md +++ b/docs/source/FAQ.md @@ -201,7 +201,60 @@ You can use bids matlab to help you create bids valid filenames. ### How can run my script only only certain files, like just the session `02` for example? -So in general you can select a subset of your data by using the `opt.query`. +Currently there are 2 ways of doing this. +- using a `bids_filter_file.json` file or its counterpart field `opt.bidsFilterFile` +- using the `opt.query` option field. +On the long run the plan is to use only the `bids_filter_file.json`, +but for now both possibilities should work. + +#### `bids filter file` + +This is similar to the way you can "select" only certain files to preprocess +with [fmriprep](https://fmriprep.org/en/stable/faq.html#how-do-i-select-only-certain-files-to-be-input-to-fmriprep). + +You can use a `opt.bidsFilterFile` field in your options +to define a typical images "bold", "T1w" in terms of their bids entities. +The default value is: + +```matlab +struct('fmap', struct('modality', 'fmap'), ... + 'bold', struct('modality', 'func', 'suffix', 'bold'), ... + 't2w', struct('modality', 'anat', 'suffix', 'T2w'), ... + 't1w', struct('modality', 'anat', 'space', '', 'suffix', 'T1w'), ... + 'roi', struct('modality', 'roi', 'suffix', 'mask')); +``` + +Similarly when using the BIDS app cpp_spm you can use the argument `bids_filter_file` +to point to a JSON file that would also define typical images "bold", "T1w"... + +The default content in this case would be: + +```json +{ + "fmap": {"datatype": "fmap"}, + "bold": {"datatype": "func", "suffix": "bold"}, + "t2w": {"datatype": "anat", "suffix": "T2w"}, + "t1w": {"datatype": "anat", "space": "", "suffix": "T1w"}, + "roi": {"datatype": "roi", "suffix": "mask"}, +} +``` + +So if you wanted to run your analysis on say run `02` and `05` of session `02`, +you would define this file like this: + +```json +{ + "fmap": {"datatype": "fmap"}, + "bold": {"datatype": "func", "suffix": "bold", "ses": "02", "run": ["02", "05"]}, + "t2w": {"datatype": "anat", "suffix": "T2w"}, + "t1w": {"datatype": "anat", "space": "", "suffix": "T1w"}, + "roi": {"datatype": "roi", "suffix": "mask"}, +} +``` + +#### `opt.query` + +You can select a subset of your data by using the `opt.query`. This will create a "filter" that bids matlab will use to only "query" and retrieve the subset of files that match the requirement of that filter @@ -221,8 +274,6 @@ you would define your filter like this: opt.query.run = {'02', '05'} ``` - - (preprocessing resampling)= ## Preprocessing diff --git a/src/messages/cppSpmHelp.m b/src/messages/cppSpmHelp.m index 2dc8ed496..b00f300f9 100644 --- a/src/messages/cppSpmHelp.m +++ b/src/messages/cppSpmHelp.m @@ -5,8 +5,8 @@ function cppSpmHelp() % % Note: % - % - all parameters use snake_case - % - most invalid calls simply initialize CPP SPM + % - all parameters use ``snake_case`` + % - most "invalid" calls simply initialize CPP SPM % % % @@ -17,8 +17,13 @@ function cppSpmHelp() % .. code-block:: matlab % % cpp_spm(bids_dir, output_dir, analysis_level, ... - % 'action', 'some_action') - % + % 'action', 'some_action', ... + % 'participant_label', {}, ... + % 'dry_run', false, ... + % 'bids_filter_file', struct([]), ... + % 'verbosity', 2, ... + % 'space', {'individual', 'IXI549Space'}, ... + % 'options', struct([])) % % % *Obligatory parameters* @@ -32,7 +37,6 @@ function cppSpmHelp() % :param analysis_level: can either be ``'subject'`` or ``'dataset'`` % :type analysis_level: string % - % % :param action: defines the pipeline to run; can be any of: % % - ``'preprocess'`` @@ -41,11 +45,11 @@ function cppSpmHelp() % - ``'results'`` % :type action: string % - % Note that: + % .. note:: % - % - ``'stats'`` runs model speification / estimation, contrast computation, display results - % - ``'contrasts'`` runs contrast computation, display results - % - ``'results'`` displays results + % - ``'stats'`` runs model speification / estimation, contrast computation, display results + % - ``'contrasts'`` runs contrast computation, display results + % - ``'results'`` displays results % % *Optional parameters common to all actions* % @@ -60,15 +64,20 @@ function cppSpmHelp() % :param bids_filter_file: % :type bids_filter_file: path to JSON file or structure % - % :param options: - % :type options: path to JSON file or structure - % % :param verbosity: can be ``0``, ``1`` or ``2``. Defaults to ``2`` % :type verbosity: positive scalar % % :param space: Defaults to ``{'individual', 'IXI549Space'}`` % :type space: cell string % + % :param options: See the ``checkOptions`` help to see the available options. + % :type options: path to JSON file or structure + % + % .. note:: + % + % Arguments passed to cpp_spm have priorities over the options defined in ``opt``. + % For example passing the argument ``'dry_run', true`` + % will override the option ``opt.dryRun = false``. % % **PREPROCESSING:** % @@ -76,11 +85,23 @@ function cppSpmHelp() % % cpp_spm(bids_dir, output_dir, 'subject', ... % 'action', 'preprocess', ... - % 'task', {...}) + % 'participant_label', {}, ... + % 'dry_run', false, ... + % 'bids_filter_file', struct([]), ... + % 'verbosity', 2, ... + % 'space', {'individual', 'IXI549Space'}, ... + % 'options', struct([]), ... + % 'task', {}, ... + % 'dummy_scans', 0, ... % specific to preprocessing + % 'anat_only', false, ... % specific to preprocessing + % 'ignore', {}, ... % specific to preprocessing + % 'fwhm', 6) % % % *Obligatory parameters* % + % .. TODO check if REALLY obligatory + % % :param task: only one task % :type task: cell string % @@ -106,17 +127,26 @@ function cppSpmHelp() % % cpp_spm(bids_dir, output_dir, 'subject', ... % 'action', 'stats', ... - % 'preproc_dir', preproc_dir, ... - % 'model_file', model_file) + % 'preproc_dir', preproc_dir, ... % specific to stats + % 'model_file', model_file, ... % specific to stats + % 'participant_label', {}, ... + % 'dry_run', false, ... + % 'bids_filter_file', struct([]), ... + % 'verbosity', 2, ... + % 'space', {'individual', 'IXI549Space'}, ... + % 'options', struct([]), ..., + % 'roi_based', false, ... + % 'task', {}, ... + % 'fwhm', 6) % % % *Obligatory parameters* % % :param preproc_dir: path to preprocessed data - % :type preproc_dir: path + % :type preproc_dir: path % % :param model_file: - % :type model_file: path to JSON file or structure + % :type model_file: path to JSON file or structure % % % *Optional parameters* From e9bf708856452acc0cd2ddb8effee89f051ccc07 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Mon, 27 Jun 2022 15:06:06 +0200 Subject: [PATCH 2/2] update FAQ to help structure data to run stats on fmriprep --- docs/source/FAQ.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/docs/source/FAQ.md b/docs/source/FAQ.md index 52d9f3174..02b401b2a 100644 --- a/docs/source/FAQ.md +++ b/docs/source/FAQ.md @@ -333,6 +333,90 @@ See those for some pointers on how to make choices for the resolution to choose for your analysis. +## Statistics + +### How should I structure my data to run my statistical analysis? + +The main thing to remember is that CPP SPM will read the events.tsv files from +your raw BIDS data set and will read the bold images from a `cpp_spm-preproc` +folder. + +If your data was preprocessed with fmriprep, cpp_spm will first need to copy, +unzip and smooth the data into a `cpp_spm-preproc` folder + +Here is an example of how the data is organized for the MoAE fmriprep demo and +what the `cpp_spm` bids call would look like. + +```bash +├── inputs +│ ├── fmriprep # fmriprep preprocessed BIDS dataset +│ | ├── dataset_description.json +│ │ └── sub-01 +│ │ ├── anat +│ │ ├── figures +│ │ └── func +│ │ ├── sub-01_task-auditory_desc-confounds_timeseries.json +│ │ ├── sub-01_task-auditory_desc-confounds_timeseries.tsv +│ │ ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-brain_mask.json +│ │ ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-brain_mask.nii.gz +│ │ ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-preproc_bold.json +│ │ └── sub-01_task-auditory_space-MNI152NLin6Asym_desc-preproc_bold.nii.gz +│ └── raw # raw BIDS dataset +│ ├── dataset_description.json +│ ├── README +│ ├── sub-01 +│ │ ├── anat +│ │ │ └── sub-01_T1w.nii +│ │ └── func +│ │ ├── sub-01_task-auditory_bold.nii +│ │ └── sub-01_task-auditory_events.tsv +│ └── task-auditory_bold.json +├── models # models used to run the GLM +│ ├── model-MoAEfmriprep_smdl.json +│ ├── model-MoAEindividual_smdl.json +│ └── model-MoAE_smdl.json +├── options +└── outputs + └── derivatives + └── cpp_spm-preproc # contains either data taken from fmriprep and smoothed + ├── dataset_description.json + ├── README + ├── jobs + │ └── auditory + │ └── sub-01 + └── sub-01 + ├── anat + └── func + ├── sub-01_task-auditory_desc-confounds_timeseries.json + ├── sub-01_task-auditory_desc-confounds_timeseries.tsv + ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-brain_mask.json + ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-brain_mask.nii + ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-preproc_bold.json + ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-preproc_bold.nii + ├── sub-01_task-auditory_space-MNI152NLin6Asym_desc-smth8_bold.json + └── sub-01_task-auditory_space-MNI152NLin6Asym_desc-smth8_bold.nii +``` + +```matlab +WD = fileparts(mfilename('fullpath')); + +subject_label = '01'; + +bids_dir = fullfile(WD, 'inputs', 'raw'); +output_dir = fullfile(WD, 'outputs', 'derivatives'); +preproc_dir = fullfile(output_dir, 'cpp_spm-preproc'); + +model_file = fullfile(pwd, 'models', 'model-MoAEfmriprep_smdl.json'); + +cpp_spm(bids_dir, output_dir, 'subject', ... + 'participant_label', {subject_label}, ... + 'action', 'stats', ... + 'preproc_dir', preproc_dir, ... + 'model_file', model_file, ... + 'fwhm', 8, ... + 'options', opt); +``` + ## Results ### How can I change which slices are shown in a montage?