diff --git a/2017-18-scanning.md b/2017-18-scanning.md new file mode 100644 index 0000000..ac19d19 --- /dev/null +++ b/2017-18-scanning.md @@ -0,0 +1,13 @@ +## Scanner - actual numbers from the day (2017/18) + +2. **inplane anatomy** - T1w, 2D MPRAGE. 24 slices, inplane voxel size: 1.5 mm, slice thickness 3 mm (same prescription as fMRI data). Matrix size 128 x 128. +4. **fMRI data** (and all fMRI scans) 2D gradient-echo EPI, TR 1.5s, TE 40ms, FA: 72º, 160 dynamics. Voxel size 3mm isotropic. Matrix size 64 x 64. +6. **whole head anatomy** - T1w 3D MPRAGE. Matrix size 256 x 256, 160 slices. Reconstructed as sagittal images. voxel size 1 mm isotropic. TE 3.7 ms, TR 8.13 ms, FA 8°, TI 960 ms, and linear phase encoding order. + +## Stimulus set-up + +- stimuli were presented on a BOLDscreen (CRS Ltd, Rochester, UK) - https://www.crsltd.com/tools-for-functional-imaging/mr-safe-displays/boldscreen-32-lcd-for-fmri/ +- **2018/19 stimulus code:** inspect ``scene_localiser()`` in the ``stimulusCode`` directory. If you can't run the code and get errors, have a lootk at [this clip on youtube](https://www.youtube.com/watch?v=5kSvEO4-HVc) to get an impression. +- other details have remained the same since the 2017/18 version. + + diff --git a/2018-19-scanning.md b/2018-19-scanning.md new file mode 100644 index 0000000..da4fe1a --- /dev/null +++ b/2018-19-scanning.md @@ -0,0 +1,7 @@ +## Scanner - actual numbers from the day (2018/19). + +2. **inplane anatomy** - T1w, 2D MPRAGE. 24 slices, inplane voxel size: 1.5 mm, slice thickness 3 mm (same prescription as fMRI data). Matrix size 128 x 128. +4. **fMRI data** (and all fMRI scans) 2D gradient-echo EPI, TR 1.5s, TE 40ms, FA: 72º, *scene localiser scan*: 294 (288+4) dynamics, retinotopy scan: 160 dynamics. Voxel size 3mm isotropic (acquired). Matrix size 64 x 64. **Note: the scanner reconstruction may have changed the "reconstructed voxel size" to something else, for mathematical expediency.** (Check the dimensions in the actual data with ``fslinfo`` or ``fslhd``.) +6. **whole head anatomy** - T1w 3D MPRAGE. Matrix size 256 x 256, 160 slices. Reconstructed as sagittal images. voxel size 1 mm isotropic. TE 3.7 ms, TR 8.13 ms, FA 8°, TI 960 ms, and linear phase encoding order. +7. across the subjects we also acquired various other data sets (including **diffusion weighted**, a **T2 weighted** anatomy scan (using multiple echoes), ... but we didn't find time to analyze these in class. + diff --git a/2019-20-scanning.md b/2019-20-scanning.md new file mode 100644 index 0000000..e355dde --- /dev/null +++ b/2019-20-scanning.md @@ -0,0 +1,13 @@ +## Scanner - actual numbers from the day (2019/20). + +For each of three subjects (``subject-A``, ``subject-B`` and ``subject-C``) we collected 5 scans. The "series" numbers may be slightly different across individuals. but the scans (in order) were the same: + +1. **fMRI data** - 2D gradient-echo EPI, TR 2.0s, TE 30ms, multiband factor 2, FA: 80º, ``scene_localiser()`` scan: 192 dynamics. (Check the dimensions in the actual data with ``fslinfo`` or ``fslhd``.) + +2. **fMRI data** - acquisition details as in 1, but only 120 dynamics. Pseudorandomly ordered blocks on "normal", "inverted" and "caricatured" faces (at different levels). + +3. same as 2 (a repeat) + +4. **whole head anatomy** - T1w 3D MPRAGE. Matrix size 256 x 256, 160 slices. Reconstructed as sagittal images. voxel size 1 mm isotropic. TE 3.7 ms, TR 8.13 ms, FA 8°, TI 960 ms, and linear phase encoding order. + +5. **T2 weighted** anatomy scan. TE 89ms, TR 3.38s, FA, 90º (Check the dimensions in the actual data with ``fslinfo`` or ``fslhd``.) diff --git a/2022-23-scanning.md b/2022-23-scanning.md new file mode 100644 index 0000000..769e9cc --- /dev/null +++ b/2022-23-scanning.md @@ -0,0 +1,14 @@ +## Scanner - actual numbers from the day (2022/23). + +For each of four subjects (``sub-01`` .. ``sub-02``) we collected most of those scans. Look at the `Readme.md` file in each folder for any notes (eg `sub-02` has one scan with TR=2s, because of the sample protocol I had picked.) + +Data shared via `OneDrive` link on a moodle message to the participants on the module. + +### A note on the block-design parameters. + +- the visual scan (faces versus objects) used a `rest-A-rest-B-...` pattern. +- the finger tapping scan follwed the same timing. `rest-LEFT-rest-RIGHT...` + +Each `rest-stimulus` block took 24s (so 16 TRs at 1.5s... or 12 TRs for the one scan with a 2s TR). + +The code for these experiments is in the `stimulusCode` folder (`FFAlocaliser()` and `M1localiser()`). Ask DS for details on how this works, if you are interested in generating stimuli. diff --git a/gettingData.md b/gettingData.md index 9dc5969..f03c1a6 100644 --- a/gettingData.md +++ b/gettingData.md @@ -24,90 +24,116 @@ The protocol will be pretty standard for a cognitive neuroscience scanning sessi 2. A test EPI to make sure that the slice positioning for the fMRI experiment is ok. 3. fMRI experiment (block): gradient-echo EPI, TR 1.5s **(~4min)** 4. T1w-MPRAGE: to illustrate detailed (1mm isotropic) anatomy **(~5min)** -5. T2w-anatomy: higher resolution inplane, but thicker slices -6. fMRI experiment (block): gradient-echo EPI, TR 1.5s **(~4min)** (a finger-tapping experiment as opposed to a visual experiment) +5. T2w-FLAIR: (1mm isotropic) -## Scanner - actual numbers from the day (2023/24). +## Stimulus code -*details to be updated* ++ stimulus code: inspect ``FFAlocaliser`` for lots of details. ++ **timing: block design** 12s images (faces, objects), 12s rest: a 24s cycle. 10 repeats per scan - 240s or 160 dynamics (@ 1.5s). Stimuli were images from face and object image database (details below). +The code is written in ``matlab/mgl`` using the ``task`` library that comes with ``mgl``. Written by Alex Beckett and DS based on a version of a working code from Justin Gardner :smile: -## Scanner - actual numbers from the day (2022/23). +There are a couple of short youtube videos explaining a version of the FFA localiser and the fixation dimming task to control attention, which would be used in a real experiment. This should give you a sense of what the subject is doing inside the scanner. -For each of four subjects (``sub-01`` .. ``sub-02``) we collected most of those scans. Look at the `Readme.md` file in each folder for any notes (eg `sub-02` has one scan with TR=2s, because of the sample protocol I had picked.) +The experiment runs as a simple block design in the following order: -Data shared via `OneDrive` link on a moodle message to the participants on the module. +>[faces, rest] , [objects, rest] - ... -### A note on the block-design parameters. +The length of each ``[stimulus, rest]`` cycle is determined by the ``cycleLength`` (in TRs). -- the visual scan (faces versus objects) used a `rest-A-rest-B-...` pattern. -- the finger tapping scan follwed the same timing. `rest-LEFT-rest-RIGHT...` +To run, make sure the ``stimulusCode`` folder is on the path and then simply run the following command. the ``Escape`` key can be used to stop the experiment at any point: -Each `rest-stimulus` block took 24s (so 16 TRs at 1.5s... or 12 TRs for the one scan with a 2s TR). +```matlab +FFAlocaliser % quick test to see what's going on +``` -The code for these experiments is in the `stimulusCode` folder (`FFAlocaliser()` and `M1localiser()`). Ask DS for details on how this works, if you are interested in generating stimuli. +To run at the MR centre, we also want to specify TR, not to run in a small window, etc. So probably worth setting a few parameters in the call like this: -## Scanner - actual numbers from the day (2019/20). +```matlab +FFAlocaliser('TR=1.5', 'debug=0', 'numBlocks=10', 'cycleLength=12') +``` -For each of three subjects (``subject-A``, ``subject-B`` and ``subject-C``) we collected 5 scans. The "series" numbers may be slightly different across individuals. but the scans (in order) were the same: +## Scanner - actual numbers from the day (2023/24) -1. **fMRI data** - 2D gradient-echo EPI, TR 2.0s, TE 30ms, multiband factor 2, FA: 80º, ``scene_localiser()`` scan: 192 dynamics. (Check the dimensions in the actual data with ``fslinfo`` or ``fslhd``.) +2024-02-07, Denis Schluppeck -2. **fMRI data** - acquisition details as in 1, but only 120 dynamics. Pseudorandomly ordered blocks on "normal", "inverted" and "caricatured" faces (at different levels). +4 volunteers (``sub-01`` .. ``sub-04``), scanned on the 3T GE scanner at the SPMIC QMC site. Scanner operator: AC. Start time 1400h. -3. same as 2 (a repeat) +(Data available via `moodle` link to a zip file on OneDrive). -4. **whole head anatomy** - T1w 3D MPRAGE. Matrix size 256 x 256, 160 slices. Reconstructed as sagittal images. voxel size 1 mm isotropic. TE 3.7 ms, TR 8.13 ms, FA 8°, TI 960 ms, and linear phase encoding order. +For each person we obtained several scans. See `json` sidecar copied along for some details. -5. **T2 weighted** anatomy scan. TE 89ms, TR 3.38s, FA, 90º (Check the dimensions in the actual data with ``fslinfo`` or ``fslhd``.) +- T1w MPRAGE (1mm isotropic) +- T2w FLAIR (1mm isotropic) +- one or two repeats of an fMRI experiment (`FFAlocaliser.m`); 2.2mm isotropic, TR/TE 1500ms/35ms -## Scanner - actual numbers from the day (2018/19). +## fMRI experiment and timing -2. **inplane anatomy** - T1w, 2D MPRAGE. 24 slices, inplane voxel size: 1.5 mm, slice thickness 3 mm (same prescription as fMRI data). Matrix size 128 x 128. -4. **fMRI data** (and all fMRI scans) 2D gradient-echo EPI, TR 1.5s, TE 40ms, FA: 72º, *scene localiser scan*: 294 (288+4) dynamics, retinotopy scan: 160 dynamics. Voxel size 3mm isotropic (acquired). Matrix size 64 x 64. **Note: the scanner reconstruction may have changed the "reconstructed voxel size" to something else, for mathematical expediency.** (Check the dimensions in the actual data with ``fslinfo`` or ``fslhd``.) -6. **whole head anatomy** - T1w 3D MPRAGE. Matrix size 256 x 256, 160 slices. Reconstructed as sagittal images. voxel size 1 mm isotropic. TE 3.7 ms, TR 8.13 ms, FA 8°, TI 960 ms, and linear phase encoding order. -7. across the subjects we also acquired various other data sets (including **diffusion weighted**, a **T2 weighted** anatomy scan (using multiple echoes), ... but we didn't find time to analyze these in class. +- the original scan was 168 timepoints long, but the first 8TRs (12s) were cut to allow for steady state. +- after removing these initial dummies, the time series is 160 timepoints long +- timing of the experiment is (Faces-rest-Obj-rest)*5) -## Scanner - actual numbers from the day (2017/18) +``` +12s ON (faces) +12s OFF (gray) -2. **inplane anatomy** - T1w, 2D MPRAGE. 24 slices, inplane voxel size: 1.5 mm, slice thickness 3 mm (same prescription as fMRI data). Matrix size 128 x 128. -4. **fMRI data** (and all fMRI scans) 2D gradient-echo EPI, TR 1.5s, TE 40ms, FA: 72º, 160 dynamics. Voxel size 3mm isotropic. Matrix size 64 x 64. -6. **whole head anatomy** - T1w 3D MPRAGE. Matrix size 256 x 256, 160 slices. Reconstructed as sagittal images. voxel size 1 mm isotropic. TE 3.7 ms, TR 8.13 ms, FA 8°, TI 960 ms, and linear phase encoding order. +12s ON (objects) +12s OFF (gray) -## Stimulus set-up +... then each repeated for a total of 10 stimulus-rest blocks +``` -- stimuli were presented on a BOLDscreen (CRS Ltd, Rochester, UK) - https://www.crsltd.com/tools-for-functional-imaging/mr-safe-displays/boldscreen-32-lcd-for-fmri/ -- **2018/19 stimulus code:** inspect ``scene_localiser()`` in the ``stimulusCode`` directory. If you can't run the code and get errors, have a lootk at [this clip on youtube](https://www.youtube.com/watch?v=5kSvEO4-HVc) to get an impression. -- other details have remained the same since the 2017/18 version. +## File organisation + +The zip file contains data from the 4 participants in the following layout: + +```text +. +├── Readme.md +├── sub-01 +├── sub-02 +│   ├── sub-02-FLAIR.png +│   ├── sub-02-MPRAGE.png +│   ├── sub-02-flair.json +│   ├── sub-02-flair.nii.gz +│   ├── sub-02-fmri01.nii.gz +│   ├── sub-02-fmri02.nii.gz +│   ├── sub-02-mprage.json +│   └── sub-02-mprage.nii.gz +├── sub-03 +└── sub-04 +``` -## Stimulus code (2017/18) -+ stimulus code: inspect ``FFAlocaliser`` and ``jazLocaliser`` for lots of details. You should be able to run the code, too. -+ **timing: block design** 12s rest, 12s images (faces, objects), so 24s cycles. 10 repeats per scan - 240s or 160 dynamics (@ 1.5s). Stimuli were images from face and object image database (details below). -+ **timing: event-related design** 1.5s stimuli followed be a randomly chosen ITI between 9s and and 18s (in 1.5s increments). Stimuli were white, moving, random dots on a black background. 100% coherence, speed 4 deg/s. Scans lasted 240s or 160 dynamics (@ 1.5s). +## Notes -The code is written in ``matlab/mgl`` using the ``task`` library that comes with ``mgl``. Written by Alex Beckett and DS based on a version of a working code from Justin Gardner :smile: +For FSL design matrix rules, this means for EVs -There are a couple of short youtube videos explaining the FFA localiser and the fixation dimming task to control attention. This should give you a sense of what the subject is doing inside the scanner. +| setting | Faces | Objects | +| :---------- | :----- | :------ | +| Skip | 36 | 36 | +| Off | 36 | 36 | +| On | 12 | 12 | +| Phase | **36** | **12** | +| Stop After | -1 | -1 | +| Convolution | Gamma | Gamma | -The experiment runs as a simple block design in the following order: ->[faces, rest] , [objects, rest] - ... -The length of each ``[stimulus, rest]`` cycle is determined by the ``cycleLength`` (in TRs). -To run, make sure the ``stimulusCode`` folder is on the path and then simply run the following command. the ``Escape`` key can be used to stop the experiment at any point: -```Matlab -FFAlocaliser % quick test to see what's going on -``` +## Previous scanning sessions + +- [2022-23 cohort](./2022-23-scanning.md) + +- [2019-20 cohort](./2019-20-scanning.md) + +- [2018-19 cohort](./2018-19-scanning.md) + +- [2017-18 cohort](./2017-18-scanning.md) -To run at the MR centre, we also want to specify TR, not to run in a small window, etc. So probably worth setting a few parameters in the call like this: -```Matlab -FFAlocaliser('TR=1.5', 'debug=0', 'numBlocks=10', 'cycleLength=12') -``` ### Notes diff --git a/stimulusCode/FFAlocaliser.m b/stimulusCode/FFAlocaliser.m index e166ed9..5c4874a 100644 --- a/stimulusCode/FFAlocaliser.m +++ b/stimulusCode/FFAlocaliser.m @@ -6,8 +6,13 @@ % purpose: code for doing face and object area localiser. % images courtesy of Tim Andrews (York) and others. % +% +% +% +% % e.g.: % FFAlocaliser() +% FFAlocaliser('displayname=3T-GE-debug', 'TR=1.5') % % make sure to also look at jazLocaliser.m for event-related expt function myscreen = FFAlocaliser( varargin ) @@ -17,6 +22,8 @@ % setup default arguments if ieNotDefined('debug'), debug=0; end +if ieNotDefined('displayname'), displayname = ''; end + % scanning params if ieNotDefined('TR'), TR=1.5; end @@ -50,7 +57,7 @@ myscreen.datadir = './'; myscreen.allowpause = 0; myscreen.eatkeys = 1; -myscreen.displayname = ''; +myscreen.displayname = displayname; myscreen.background = 'gray'; myscreen.TR = TR; myscreen.cycleLength = cycleLength; % in TRs @@ -65,6 +72,7 @@ fixStimulus.diskSize = 0.0; % no disk (just superimpose on stim) fixStimulus.fixWidth = 1; +% by default the screen params should come from mglEditScreenParams setup!! if debug == 1 % gethostname and then display the stimulus on the corresponding screen % myscreen.screenParams{1} = {gethostname(),[],0,1024,768,80,[31 23],60,1,1,1.4,[],flipHV}; @@ -79,23 +87,25 @@ fixStimulus.fixWidth = 1; fixStimulus.diskSize = 0; -else - % running at 3T for experiment - defaultMonitorGamma = 1.8; - % myscreen.screenParams{1} = {gethostname(),'',2,1280,960,231,[83 3*83/4],60,1,1,defaultMonitorGamma,'',flipHV}; % 3T nottingham - myscreen.screenParams{1} = struct('computerName', gethostname(),... - 'displayName',[], 'screenNumber', 2, ... - 'screenWidth', 1280, 'screenHeight', 960, 'displayDistance', 231,... - 'displaySize',[83 3*83/4], 'framesPerSecond', 60, 'autoCloseScreen', 1, ... - 'saveData', 1, 'calibType', 1, 'monitorGamma', defaultMonitorGamma, 'calibFilename',[], ... - 'flipHV', flipHV, 'digin',[], 'hideCursor', 1, 'displayPos', [], 'backtickChar', '5'); +elseif debug == 2 + fprintf('should not need this code!!') + % don't run this code now... + % running at 3T for experiment + % defaultMonitorGamma = 1.8; + % % myscreen.screenParams{1} = {gethostname(),'',2,1280,960,231,[83 3*83/4],60,1,1,defaultMonitorGamma,'',flipHV}; % 3T nottingham + % myscreen.screenParams{1} = struct('computerName', gethostname(),... + % 'displayName',displayname, 'screenNumber', 2, ... + % 'screenWidth', 1280, 'screenHeight', 960, 'displayDistance', 231,... + % 'displaySize',[83 3*83/4], 'framesPerSecond', 60, 'autoCloseScreen', 1, ... + % 'saveData', 1, 'calibType', 1, 'monitorGamma', defaultMonitorGamma, 'calibFilename',[], ... + % 'flipHV', flipHV, 'digin',[], 'hideCursor', 1, 'displayPos', [], 'backtickChar', '5'); end % and init myscreen myscreen = initScreen(myscreen); % fix keys for our scanner setup. -myscreen.keyboard.backtick = mglCharToKeycode({'5'}); % that's the backtick +% myscreen.keyboard.backtick = mglCharToKeycode({'5'}); % that's the backtick myscreen.keyboard.nums = mglCharToKeycode({'1' '2' '3' '4' '6' '7' '8' '9' '0'}); % set the first task to be the fixation staircase task @@ -132,7 +142,7 @@ myscreen = initStimulus('stimulus',myscreen); % load in images and prep textures stimulus = initFaces(stimulus,myscreen); -stimulus.displayWidth = 10; % decide how WIDE the stimuli should be +stimulus.displayWidth = 18; % WAS 10!! decide how WIDE the stimuli should be %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % run the eye calibration @@ -249,12 +259,14 @@ MAX_IMAGES_TO_LOAD = 50; % stim directories are hard-coded. Could do better here. -imdir{1} = './stims/multiracial/frontal/'; -files{1} = dir([imdir{1} '*.jpg']); +% imdir{1} = './stims/multiracial/frontal/'; +imdir{1} = './scene_localiser/images/'; +files{1} = dir([imdir{1} 'face_*.png']); nFiles{1} = min(MAX_IMAGES_TO_LOAD, length(files{1})); -imdir{2} = './stims/objects/'; -files{2} = dir([imdir{2} '*.jpg']); +% imdir{2} = './stims/objects/'; +imdir{2} ='./scene_localiser/images/'; +files{2} = dir([imdir{2} 'object*.png']); nFiles{2} = min(MAX_IMAGES_TO_LOAD, length(files{2})); % imdir{3} = './stims/houses/'; @@ -274,7 +286,7 @@ im2 = reshape(im, imdims(1).*imdims(2), []); % x*y, RGBA im2(:,4) = 255.0; % add transparency layer and also makes it FLOAT!! - WHITE_CUTOFF = 200; + WHITE_CUTOFF = 254; GRAY_VAL = 127; % place on textured noise? diff --git a/stimulusCode/M1localiser.m b/stimulusCode/M1localiser.m index aa8f835..421f98c 100644 --- a/stimulusCode/M1localiser.m +++ b/stimulusCode/M1localiser.m @@ -15,6 +15,7 @@ % setup default arguments if ieNotDefined('debug'), debug=0; end +if ieNotDefined('displayname'), displayname = ''; end % scanning params if ieNotDefined('TR'), TR=1.5; end @@ -48,7 +49,7 @@ myscreen.datadir = './'; myscreen.allowpause = 0; myscreen.eatkeys = 1; -myscreen.displayname = ''; +myscreen.displayname = displayname; myscreen.background = 'gray'; myscreen.TR = TR; myscreen.cycleLength = cycleLength; % in TRs @@ -76,16 +77,17 @@ fixStimulus.fixWidth = 1; fixStimulus.diskSize = 0; -else +elseif debug == 2 + % not really needed anymore (as mglEditScreenParams takes over!) % running at 3T for experiment defaultMonitorGamma = 1.8; % myscreen.screenParams{1} = {gethostname(),'',2,1280,960,231,[83 3*83/4],60,1,1,defaultMonitorGamma,'',flipHV}; % 3T nottingham - myscreen.screenParams{1} = struct('computerName', gethostname(),... - 'displayName',[], 'screenNumber', 2, ... - 'screenWidth', 1280, 'screenHeight', 960, 'displayDistance', 231,... - 'displaySize',[83 3*83/4], 'framesPerSecond', 60, 'autoCloseScreen', 1, ... - 'saveData', 1, 'calibType', 1, 'monitorGamma', defaultMonitorGamma, 'calibFilename',[], ... - 'flipHV', flipHV, 'digin',[], 'hideCursor', 1, 'displayPos', [], 'backtickChar', '5'); + % myscreen.screenParams{1} = struct('computerName', gethostname(),... + % 'displayName',[], 'screenNumber', 2, ... + % 'screenWidth', 1280, 'screenHeight', 960, 'displayDistance', 231,... + % 'displaySize',[83 3*83/4], 'framesPerSecond', 60, 'autoCloseScreen', 1, ... + % 'saveData', 1, 'calibType', 1, 'monitorGamma', defaultMonitorGamma, 'calibFilename',[], ... + % 'flipHV', flipHV, 'digin',[], 'hideCursor', 1, 'displayPos', [], 'backtickChar', '5'); end % and init myscreen