|
%% Some hints on getting timeseries information |
|
% with SPM data |
|
% |
|
% ds 2025-03-20 ... wrote it for DAFNI questions... |
|
|
|
|
|
%% the following shows code in principle. |
|
% you may have to adjust paths a bit to reflect |
|
% where your data files, spm.mat, etc are stored. |
|
|
|
%% Load the transformation matrix |
|
% info is stored in this MAT file |
|
load('spm.mat'); |
|
SPM |
|
|
|
%% load timeseries data... |
|
|
|
% load in the NIFTI file with the timeseries |
|
% you can check what is was for you here... |
|
SPM.xY.VY(1).fname |
|
|
|
% for me on my machine that file was up one level and |
|
% still had this long ugly filename... |
|
fname = '../swrMSC_COG_NEURO_03_WIP_visual_fmri_20250206110123_401.nii'; |
|
|
|
% read into matlab workspace |
|
yData = niftiread(fname); |
|
|
|
%% Get the transformation matrix |
|
% say the coordinates come from the spm maps... |
|
|
|
% e.g. the third contrast (faces > objects) is stored here.. |
|
|
|
% descrption |
|
SPM.xCon(3).Vspm.descrip |
|
|
|
|
|
% the spatial transform |
|
transform = SPM.xCon(3).Vspm.mat |
|
|
|
|
|
%% Define the coordinates / in MNI space ... |
|
% THIS IS where you'd put the info from your actual coordinates |
|
|
|
mni_coords = [-16.3; -74.9; -25.7]; % in units of MM |
|
% e.g. -16.3 -74.9 -25.7 (MNI) |
|
|
|
% should go to [48.2 19.5 23.1] in voxels... |
|
% read off the GUI in SPM window |
|
vox_coords = [48.2; 19.5; 23.1]; |
|
|
|
% BTW .. the statistical value for Faces > Objects |
|
% is - (MINUS!) 3.437... which means stronger response to |
|
% OBJECTS than faces...it's DARK on the gray scale image. |
|
|
|
|
|
% Apply the inverse transformation |
|
% this is a bit of linear algebra |
|
% to work out how we can find them... |
|
% they should be the same as reported by SPM! |
|
native_coords = inv(transform) * [mni_coords(:);1] |
|
|
|
|
|
%% now we can use our function to get timecourse |
|
|
|
% one gotcha is that we need to round the voxel coordinates |
|
% to the neearest integer: eg voxel coord x=23.6 is not cool! it needs to |
|
% be 27 |
|
|
|
rounded_vox_coords = round(native_coords(1:3)); |
|
|
|
% make clear what we need for returnTimecourse function |
|
x = rounded_vox_coords(1); |
|
y = rounded_vox_coords(2); |
|
z = rounded_vox_coords(3); |
|
|
|
timeseriesData = returnTimecourse(yData, x,y, z ) |
|
|
|
|
|
%% now plot - should look like faces > objects |
|
figure() |
|
plot(timeseriesData) |
|
|
|
%% we can also get the slice from the z slice? |
|
|
|
% it was the 3rd contrast on the list... so |
|
conImage = niftiread('con_0003.nii'); |
|
|
|
% get the z'th slice |
|
figure() |
|
theSlice = returnSlice(conImage, z); |
|
imagesc(theSlice) |
|
colormap(gray) |
|
caxis([-5 5]) |
|
|
|
% plot the point we got: |
|
hold on |
|
% gotcha - images use Y, X ordering, plots... use X, Y |
|
plot(y,x, 'ro', 'MarkerSize',12, 'MarkerFaceColor','red') |
|
title('location of the voxel in this slice') |
SPM window of one of the contrast images... showing where VOXEL and other coordinate information is located: