Skip to content

Commit a1c737d

Browse files
authored
Merge pull request #55 from Remi-Gau/remi-results
create BIDS_results
2 parents 0dace15 + 85a1644 commit a1c737d

13 files changed

+349
-48
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@
55
*.nii
66

77
opt.mat
8+
9+
# files in the demo folder related to running the demo analysis
10+
demo/*.zip
11+
demo/output/*

README.md

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,30 @@
55

66
<!-- TOC -->
77

8-
- [Instructions for SPM12 Preprocessing Pipeline](#instructions-for-spm12-preprocessing-pipeline)
8+
- [Instructions for SPM12 Preprocessing Pipeline](#instructions-for-spm12-preprocessing-pipeline)
99
- [Dependencies](#dependencies)
1010
- [General description](#general-description)
1111
- [Assumption](#assumption)
1212
- [Setting up](#setting-up)
13+
- [getOptions](#getoptions)
14+
- [model JSON files](#model-json-files)
1315
- [Order of the analysis](#order-of-the-analysis)
1416
- [Docker](#docker)
1517
- [build docker image](#build-docker-image)
1618
- [run docker image](#run-docker-image)
19+
- [MRIQC](#mriqc)
1720
- [Details about some steps](#details-about-some-steps)
1821
- [Slice timing correction](#slice-timing-correction)
1922
- [Boiler plate methods section](#boiler-plate-methods-section)
2023
- [Preprocessing](#preprocessing)
2124
- [fMRI data analysis](#fmri-data-analysis)
2225
- [References](#references)
23-
- [Testing](#testing)
26+
- [Unit testing](#unit-testing)
27+
- [Contributors ✨](#contributors-)
2428

2529
<!-- /TOC -->
2630

31+
2732
## Dependencies
2833

2934
Make sure that the following toolboxes are installed and added to the matlab path.
@@ -38,6 +43,7 @@ For instructions see the following links:
3843

3944
For simplicity the NIfTI tools toolbox has been added to this repo in the `subfun` folder.
4045

46+
4147
## General description
4248

4349
This set of function will read and unzip the data from a [BIDS data set](https://bids.neuroimaging.io/). It will then perform:
@@ -53,19 +59,21 @@ It can also prepare the data to run an MVPA analysis by running a GLM for each s
5359

5460
The core functions are in the sub-function folder `subfun`
5561

62+
5663
## Assumption
5764

5865
At the moment this pipeline makes some assumptions:
5966
- it assumes that the dummy scans have been removed from the BIDS data set and it can jump straight into pre-processing,
6067
- it assumes the metadata for a given task are the same as those the first run of the first subject this pipeline is being run on,
6168
- it assumes that group are defined in the subject field (eg `sub-ctrl01`, `sub-blind01`, ...) and not in the `participants.tsv` file.
6269

70+
6371
## Setting up
6472

6573
### getOptions
6674

6775

68-
All the details specific to your analysis should be set in the `getOptions.m`.
76+
All the details specific to your analysis should be set in the `getOptions.m`. There is a getOption_template file that shows you would set up the getOption file if one wanted to analyse the [ds001 data set from OpenNeuro](https://openneuro.org/datasets/ds000001/versions/57fecb0ccce88d000ac17538).
6977

7078
Set the group of subjects to analyze.
7179
```
@@ -102,6 +110,7 @@ The directory where your files are located on your computer: make sure you have
102110

103111
Some more SPM options can be set in the `spm_my_defaults.m`.
104112

113+
105114
### model JSON files
106115
This files allow you to specify which contrasts to run and follow the BIDS statistical model extension and as implement by [fitlins](https://fitlins.readthedocs.io/en/latest/model.html)
107116

@@ -153,47 +162,51 @@ In brief this means:
153162
- at the subject level automatically compute the t contrast against baseline for the condition `motion`and `static` and compute the t-contrats for motion VS static with these given weights.
154163
- at the level of the data set (so RFX) do the t contrast of the `motion`, `static`, `motion VS static`.
155164

165+
We are currently using this to run different subject level GLM models for our univariate and multivariate analysis where in the first one we compute a con image that averages the beta image of all the runs where as in the latter case we get one con image for each run.
166+
156167

157168
## Order of the analysis
158169

159170
1. __Remove Dummy Scans__:
160-
Unzip bold files and removes dummy scans by running the script (to be run even if `opt.numDummies` set to `0`):
161-
`BIDS_rmDummies.m`
171+
Unzip bold files and removes dummy scans by running the script (to be run even if `opt.numDummies` set to `0`): `BIDS_rmDummies.m`
172+
173+
2. __Slice Time Correction__: Performs Slice Time Correction (STC) of the functional volumes by running the script: `BIDS_STC.m`
162174

163-
2. __Slice Time Correction__: Performs Slice Time Correction (STC) of the functional volumes by running the script:
164-
`BIDS_STC.m`
165175
STC will be performed using the information provided in the BIDS data set. It will use the mid-volume acquisition time point as as reference.
176+
166177
The `getOption.m` fields related to STC can still be used to do some slice timing correction even no information is can be found in the BIDS data set.
178+
167179
In general slice order and reference slice is entered in time unit (ms) (this is the BIDS way of doing things) instead of the slice index of the reference slice (the "SPM" way of doing things).
180+
168181
More info available on this page of the [SPM wikibook](https://en.wikibooks.org/wiki/SPM/Slice_Timing).
169182

170183
3. __Spatial Preprocessing__:
171-
Performs spatial preprocessing by running the script:
172-
`BIDS_SpatialPrepro.m`
184+
Performs spatial preprocessing by running the script: `BIDS_SpatialPrepro.m`
173185

174186
4. __SMOOTHING__:
175-
Performs smoothing of the functional data by running the script:
176-
`BIDS_Smoothing.m`
187+
Performs smoothing of the functional data by running the script: `BIDS_Smoothing.m`
177188

178189
5. __FIXED EFFECTS ANALYSIS (FIRST-LEVEL ANALYSIS)__:
179-
Performs the fixed effects analysis by running the ffx script:
180-
`BIDS_FFX.m`
190+
Performs the fixed effects analysis by running the ffx script: `BIDS_FFX.m`
181191

182192
This will run twice, once for model specification and another time for model estimation. See the function for more details.
183193

184194
This will take each condition present in the `events.tsv` file of each run and convolve it with a canonical HRF. It will also add the 6 realignment parameters of every run as confound regressors.
185195

186196
6. __RANDOM EFFECTS ANALYSIS (SECOND-LEVEL ANALYSIS)__:
187-
Performs the random effects analysis by running the RFX script:
188-
`BIDS_RFX.m`
197+
Performs the random effects analysis by running the RFX script: `BIDS_RFX.m`
198+
199+
7. __GET THE RESULTS FROM A SPECIFIC CONTRAST__: `BIDS_Results.m`
189200

190201
- See __"batch.m"__ for examples and for the order of the scripts.
191202
- See __"batch_dowload_run.m"__ for an example of how to download a data set and analyze it all in one go.
192203

204+
193205
## Docker
194206

195207
The recipe to build the docker image is in the `Dockerfile`
196208

209+
197210
### build docker image
198211

199212
To build the image with with octave and SPM the `Dockerfile` just type :
@@ -202,6 +215,7 @@ To build the image with with octave and SPM the `Dockerfile` just type :
202215

203216
This will create an image with the tag name `cpp_spm_octave:0.0.1`
204217

218+
205219
### run docker image
206220

207221
The following code would start the docker image and would map 2 folders one for `output` and one for `code` you want to run.
@@ -231,6 +245,7 @@ docker run -it --rm -v $data_dir/raw:/data:ro -v $data_dir:/out poldracklab/mriq
231245

232246
## Details about some steps
233247

248+
234249
### Slice timing correction
235250

236251
BELOW: some comments from [here](http://mindhive.mit.edu/node/109) on STC, when it should be applied
@@ -243,8 +258,10 @@ _If you do slice timing correction before realignment, you might look down your
243258

244259
_There's no way to avoid all the error (short of doing a four-dimensional realignment process combining spatial and temporal correction - Remi's note: fMRIprep does it), but I believe the current thinking is that doing slice timing first minimizes your possible error. The set of voxels subject to such an interpolation error is small, and the interpolation into another TR will also be small and will only affect a few TRs in the time course. By contrast, if one realigns first, many voxels in a slice could be affected at once, and their whole time courses will be affected. I think that's why it makes sense to do slice timing first. That said, here's some articles from the SPM e-mail list that comment helpfully on this subject both ways, and there are even more if you do a search for "slice timing AND before" in the archives of the list._
245260

261+
246262
## Boiler plate methods section
247263

264+
248265
### Preprocessing
249266

250267
The fMRI data were pre-processed and analyzed using statistical parametric mapping (SPM12 – v7487; Wellcome Center for Neuroimaging, London, UK; www.fil.ion.ucl.ac.uk/spm) running on {octave 4.{??} / matlab 20{XX} (Mathworks)}.
@@ -263,6 +280,7 @@ The anatomical T1 image was bias field corrected, segmented and normalized to MN
263280

264281
Functional MNI normalized images were then spatially smoothed using a 3D gaussian kernel (FWHM = {XX} mm).
265282

283+
266284
### fMRI data analysis
267285

268286
At the subject level, we performed a mass univariate analysis with a linear regression at each voxel of the brain, using generalized least squares with a global FAST model to account for temporal auto-correlation (Corbin et al, 2018) and a drift fit with discrete cosine transform basis (128 seconds cut-off). Image intensity scaling was done run-wide before statistical modeling such that the mean image will have mean intracerebral intensity of 100.
@@ -279,17 +297,19 @@ Table of constrast with weight: WIP
279297

280298
Group level: WIP
281299

300+
282301
### References
283302

284303
Friston KJ, Ashburner J, Frith CD, Poline J-B, Heather JD & Frackowiak RSJ (1995) Spatial registration and normalization of images Hum. Brain Map. 2:165-189
285304

286305
Corbin, N., Todd, N., Friston, K. J. & Callaghan, M. F. Accurate modeling of temporal correlations in rapidly sampled fMRI time series. Hum. Brain Mapp. 39, 3884–3897 (2018).
287306

288307

289-
## Testing
308+
## Unit testing
290309

291310
All tests are in the test folder. There is also an empty dummy BIDS dataset that is partly created using the bash script `createDummyDataSet.sh`.
292311

312+
293313
## Contributors ✨
294314

295315
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

batch.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
BIDS_RFX(1, 6, 6)
3434
BIDS_RFX(2, 6, 6)
3535

36+
BIDS_Results(6, 6, opt, 0)
37+
3638
% subject level multivariate
3739
isMVPA=1;
3840
BIDS_FFX(1, 6, opt, isMVPA);

demo/batch_download_run.m

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,29 @@
4646
opt.model.univariate.file = fullfile(WD, 'model-MoAE_smdl.json');
4747

4848

49+
% specify the result to compute
50+
opt.result.Steps(1) = struct(...
51+
'Level', 'subject', ...
52+
'Contrasts', struct(...
53+
'Name', 'listening', ... % has to match
54+
'Mask', false, ... % this might need improving if a mask is required
55+
'MC', 'FWE', ... FWE, none, FDR
56+
'p', 0.05, ...
57+
'k', 0, ...
58+
'NIDM', true) );
59+
60+
opt.result.Steps(1).Contrasts(2) = struct(...
61+
'Name', 'listening_inf_baseline', ...
62+
'Mask', false, ...
63+
'MC', 'none', ... FWE, none, FDR
64+
'p', 0.01, ...
65+
'k', 0, ...
66+
'NIDM', true);
67+
68+
69+
70+
71+
4972
%% Get data
5073
fprintf('%-40s:', 'Downloading dataset...');
5174
urlwrite(URL, 'MoAEpilot.zip');
@@ -72,5 +95,6 @@
7295
BIDS_Smoothing(FWHM, opt);
7396
BIDS_FFX(1, FWHM, opt, 0);
7497
BIDS_FFX(2, FWHM, opt, 0);
98+
BIDS_Results(FWHM, opt, 0)
7599

76100

demo/model-MoAE_smdl.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
"task": "auditory"
66
},
77
"Steps": [
8+
{
9+
"Level": "dataset",
10+
"AutoContrasts": []
11+
},
812
{
913
"Level": "subject",
1014
"AutoContrasts": ["trial_type.listening"],

getOption.m

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,18 @@
77
end
88

99
% group of subjects to analyze
10-
opt.groups = {''}; % {'blnd', 'ctrl'};
10+
opt.groups = {''};
1111
% suject to run in each group
12-
% opt.subjects = {[4:6]}; % {[1:2], [1:2]};
13-
opt.subjects = {[]}; % {[1:2], [1:2]};
12+
opt.subjects = {[1:2]};
1413

1514

1615
% task to analyze
1716
opt.taskName = 'MotionDecoding';
1817

19-
% opt.taskName = 'visMotion';
20-
21-
% opt.taskName = 'balloonanalogrisktask';
22-
23-
2418

2519
% The directory where the data are located
26-
27-
% opt.dataDir = '/Users/mohamed/Desktop/MotionWorkshop/raw';
28-
% opt.dataDir = '/Users/mohamed/Desktop/Data/raw';
29-
30-
% opt.dataDir = '/home/remi/BIDS/visMotion/raw';
31-
opt.dataDir = '/home/remi/BIDS/MotionDecoding/raw';
32-
33-
% opt.dataDir = '/home/remi/BIDS/ds001/rawdata';
20+
opt.dataDir = '/Users/mohamed/Desktop/MotionWorkshop/raw';
21+
opt.dataDir = '/Users/mohamed/Desktop/Data/raw';
3422

3523

3624
% Options for slice time correction
@@ -51,22 +39,27 @@
5139
% Suffix output directory for the saved jobs
5240
opt.JOBS_dir = fullfile(opt.dataDir, '..', 'derivatives', 'SPM12_CPPL', 'JOBS', opt.taskName);
5341

54-
% specify the model file that contains the contrasts to compute
55-
56-
% opt.model.univariate.file = '/Users/mohamed/Documents/GitHub/BIDS_fMRI_scripts/model-motionDecodingUnivariate_smdl.json';
57-
% opt.model.multivariate.file = '/Users/mohamed/Documents/GitHub/BIDS_fMRI_scripts/model-motionDecodingMultivariate_smdl.json';
5842

59-
% opt.model.univariate.file = '/home/remi/github/CPP_BIDS_SPM_pipeline/model-visMotionLoc_smdl.json';
43+
% specify the model file that contains the contrasts to compute
44+
opt.model.univariate.file = '/Users/mohamed/Documents/GitHub/BIDS_fMRI_scripts/model-motionDecodingUnivariate_smdl.json';
45+
opt.model.multivariate.file = '/Users/mohamed/Documents/GitHub/BIDS_fMRI_scripts/model-motionDecodingMultivariate_smdl.json';
6046

61-
opt.model.univariate.file = '/home/remi/github/CPP_BIDS_SPM_pipeline/model-motionDecodingUnivariate_smdl.json';
62-
opt.model.multivariate.file = '/home/remi/github/CPP_BIDS_SPM_pipeline/model-motionDecodingMultivariate_smdl.json';
6347

64-
% opt.model.univariate.file = '/home/remi/github/CPP_BIDS_SPM_pipeline/model-balloonanalogriskUnivariate_smdl.json';
65-
% opt.model.multivariate.file = '/home/remi/github/CPP_BIDS_SPM_pipeline/model-balloonanalogriskMultivariate_smdl.json';
48+
% specify the result to compute
49+
opt.result.Steps(1) = struct(...
50+
'Level', 'dataset', ...
51+
'Contrasts', struct(...
52+
'Name', 'Vis_U', ... % has to match one of the contrast defined in the model json file
53+
'Mask', false, ... % this might need improving if a mask is required
54+
'MC', 'none', ... FWE, none, FDR
55+
'p', 0.05, ...
56+
'k', 0, ...
57+
'NIDM', true) );
6658

6759

6860
% Save the opt variable as a mat file to load directly in the preprocessing
6961
% scripts
7062
save('opt.mat','opt')
7163

64+
7265
end

getOption_template

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@ if nargin<1
77
end
88

99
% group of subjects to analyze
10-
opt.groups = {''}; % {'blnd', 'ctrl'};
10+
opt.groups = {''};
1111
% suject to run in each group
12-
opt.subjects = {[]}; % {[1:2], [1:2]};
12+
opt.subjects = {[]};
1313

1414

1515
% task to analyze
16-
opt.taskName = 'visMotion';
16+
opt.taskName = 'balloonanalogrisktask';
1717

1818

19-
% The directory where the derivatives are located
20-
opt.dataDir = '/home/remi/BIDS/visMotion/raw';
19+
20+
% The directory where the data are located
21+
opt.dataDir = '/home/remi/BIDS/ds001/rawdata';
2122

2223

2324
% Options for slice time correction
@@ -39,7 +40,20 @@ opt.funcVoxelDims = [];
3940
opt.JOBS_dir = fullfile(opt.dataDir, '..', 'derivatives', 'SPM12_CPPL', 'JOBS', opt.taskName);
4041

4142
% specify the model file that contains the contrasts to compute
42-
opt.model.univariate.file = '/home/remi/github/CPP_BIDS_SPM_pipeline/model-visMotionLoc_smdl.json';
43+
opt.model.univariate.file = fullfile(fileparts(mfilename('fullpath')), 'model', model-balloonanalogriskUnivariate_smdl.json');
44+
opt.model.multivariate.file = fullfile(fileparts(mfilename('fullpath')), 'model', model-balloonanalogriskMultivariate_smdl.json');
45+
46+
47+
% specify the result to compute
48+
opt.result.Steps(1) = struct(...
49+
'Level', 'dataset', ...
50+
'Contrasts', struct(...
51+
'Name', 'pumps_demean', ... % has to match
52+
'Mask', false, ... % this might need improving if a mask is required
53+
'MC', 'none', ... FWE, none, FDR
54+
'p', 0.05, ...
55+
'k', 0, ...
56+
'NIDM', true) );
4357

4458

4559
% Save the opt variable as a mat file to load directly in the preprocessing
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"Name": "balloonanalogrisk",
3+
"Description": "contrasts for the balloonanalogrisk dataset",
4+
"Input": {
5+
"task": "balloonanalogrisktask"
6+
},
7+
"Steps": [
8+
{
9+
"Level": "subject",
10+
"AutoContrasts": [],
11+
"Contrasts": []
12+
},
13+
{
14+
"Level": "run",
15+
"AutoContrasts": ["trial_type.pumps_demean"]
16+
},
17+
{
18+
"Level": "dataset",
19+
"AutoContrasts": []
20+
}
21+
]
22+
}

0 commit comments

Comments
 (0)