Skip to content

Instantly share code, notes, and snippets.

@schluppeck
Created March 20, 2025 21:38
Show Gist options
  • Select an option

  • Save schluppeck/87ff5cbac818fbdc9058bca3e1f467c6 to your computer and use it in GitHub Desktop.

Select an option

Save schluppeck/87ff5cbac818fbdc9058bca3e1f467c6 to your computer and use it in GitHub Desktop.
getting SPM coordinates from MM to VOXELS

Here are some hints

Denis Schluppeck, 2025-03-20, help for DAFNI students

... on how to get from coordinates reported in MM (often with negative numbers, because images are centered on 0,0,0) to VOXEL coordinates in SPM.

The matlab script test_coords.m included below shows you how you can go about this. It should work with minor modifications. See also comment on this gist for where in SPM you can find info about locations of voxels.

%% 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')
@schluppeck
Copy link
Author

SPM window of one of the contrast images... showing where VOXEL and other coordinate information is located:

48_20_23-object-response-location

@schluppeck
Copy link
Author

... and the time series plot using our returnTimeseries() function
timeseries-plot

... and even the slice of the contrast / statistical map applying returnSlice()
statistical-map

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment