You're right about the problem being because of the sparseness of the map.
We had the same problem for utilizing the MNE morph maps. To solve this I
implemented a nearest neighbor interpolation onto the hires freesurfer mesh,
then passed the morphing through that operator onto the low resolution mesh
for another subject.
I've appended the code I use to do this mapping below. This code is a
custom function that assumes a bunch of things about where data lives so you
won't be able to run it. It also depends on a function from the Stanford
VISTASOFT tools. The function is nearpoints, a mex implementation of a
nearest neighbor mapping. Nearpoints is extremely fast so it works well for
this largish datasets, so it is a generically useful function. Hopefully
this code gives you the idea of what is going on.
The total transformation is a combination of mappings. I take the From
subject and map it onto the hi-res FS surface. I then apply the hi res
morphing of the FROM subject to the TO subject. And finally I take the hi
res to lo res mapping on the to subject:
The key line is this one:
totalTrans{iHemi} = toHi2Lo*(hi2hi{iHemi}*fromLo2Hi);
Justin Ales
function [mapMtx totalTrans] = makeDefaultCortexMorphMap(fromSub,toSub)
%function [mapMtx] = makeDefaultCortexMorphMap(fromSub,toSub)
%
% This function makes a morphing matrix that maps values from 1 subject to
another
% Freesurfer based MNE morphing matrices must have been computed already
% with command:
% mne_make_morph_maps --to skeri0055_fs4 --from skeri0001_fs4
%
%example usage:
%[mapMtx] = makeDefaultCortexMorphMap('skeri0001','skeri0055');
% $Log: makeDefaultCortexMorphMap.m,v $
% Revision 1.4 2009/06/26 21:12:30 ales
% mrSimScript does arbitrary waveforms
% skeriDefaultSimParameters has updated help
% makeDefaultCortexMorphMap returns an identity matrix for mapping an
individual on to itself
% makeForwardMatrixFromMne has some added help
%
% Revision 1.3 2009/05/29 16:58:14 ales
% Changed something. I don't remember what now. sorry.
%
% Revision 1.2 2009/05/21 17:04:23 ales
% Added auto log message comments
%
% Read stuff in
toSub = [toSub '_fs4'];
fromSub = [fromSub '_fs4'];
freesurfDir = getpref('freesurfer','SUBJECTS_DIR');
toSubSrcSpaceFile = fullfile(freesurfDir,toSub,'bem',[ toSub
'-ico-5p-src.fif']);
fromSubSrcSpaceFile = fullfile(freesurfDir,fromSub,'bem',[ fromSub
'-ico-5p-src.fif']);
if strcmp(fromSub,toSub)
toSubSrc = mne_read_source_spaces(toSubSrcSpaceFile);
mapMtx = speye(sum([toSubSrc.nuse])); %<- tricky use of [] to make a
matrix from structure
totalTrans = [];
return;
end
toSubSrc = mne_read_source_spaces(toSubSrcSpaceFile);
fromSubSrc = mne_read_source_spaces(fromSubSrcSpaceFile);
[hi2hi{1},hi2hi{2}] = mne_read_morph_map(fromSub,toSub,freesurfDir);
%% Make lowrez transfer matrix
for iHemi = 1:2,
fromDecIdx = double(fromSubSrc(iHemi).vertno); %Decimation index for fromSub
toDecIdx = double(toSubSrc(iHemi).vertno); %Decimation index for toSub
nHiFrom = double(fromSubSrc(iHemi).np); %Num vertices hires in from subject
nHiTo = double(toSubSrc(iHemi).np); %Num vertices hires in "to" subject
nLoTo = double(toSubSrc(iHemi).nuse);
nLoFrom = double(fromSubSrc(iHemi).nuse);
idxFrom =
nearpoints(fromSubSrc(iHemi).rr',fromSubSrc(iHemi).rr(fromDecIdx,:)');
idxTo = nearpoints(toSubSrc(iHemi).rr',toSubSrc(iHemi).rr(toDecIdx,:)');
%Sparse mapping matrix from low res to hi res surface using nearest
%neighbour interpolation.
fromLo2Hi = sparse(1:nHiFrom,idxFrom,ones(size(idxFrom)),nHiFrom,nLoFrom);
toLo2Hi = sparse(1:nHiTo,idxTo,ones(size(idxTo)),nHiTo,nLoTo);
%Indexing matrix from Hi res "to" subject to low res "to" subject
toHi2Lo = sparse(1:nLoTo,toDecIdx,ones(nLoTo,1),nLoTo,nHiTo);
%Fix if missing some end columns because of a zero mapping
[i j s] = find(hi2hi{iHemi});
hi2hi{iHemi} = sparse(i,j,s,nHiTo,nHiFrom);
totalTrans{iHemi} = toHi2Lo*(hi2hi{iHemi}*fromLo2Hi);
end
%Make the hemi parts into 1 big matrix suitable for our default cortex.
mapMtx = [totalTrans{1}
sparse(size(totalTrans{1},1),size(totalTrans{2},2)); ...
sparse(size(totalTrans{2},1),size(totalTrans{1},2)) totalTrans{2}];