From d083c7277555da4578a683b57eeaec4c2858d18d Mon Sep 17 00:00:00 2001 From: Harvey Huang Date: Thu, 25 Apr 2024 10:05:37 -0500 Subject: [PATCH] Coded added to script02_writeMNI.m, plus other minor changes script02_writeMNI.m - added 2 blocks of code: writes MNI152 positions to a new electrodes.tsv (using SPM forward deformation fields), and writes MNI305 positions to a new electrodes.tsv using fsaverage gitignore - added ignores for *.asv and personalDataPath.m script01_preprocNSDMef - elecPath -> now elecsPath --- .gitignore | 1 + script01_preprocNSDMef.m | 10 +++---- script02_writeMNI.m | 58 +++++++++++++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 46184aa..337276f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ output/ personalDataPath.m .DS_Store */.DS_Store +*.asv \ No newline at end of file diff --git a/script01_preprocNSDMef.m b/script01_preprocNSDMef.m index f39f549..553b28e 100644 --- a/script01_preprocNSDMef.m +++ b/script01_preprocNSDMef.m @@ -10,7 +10,7 @@ addpath('functions'); % subject to preprocess -ss = 1; +ss = 17; sub_label = sprintf('%02d', ss); ses_label = 'ieeg01'; @@ -20,8 +20,8 @@ task_list = readtable(fullfile(localDataPath.input,['sub-' sub_label],['ses-' ses_label],['sub-' sub_label '_ses-' ses_label '_scans.tsv']), 'FileType', 'text', 'Delimiter', '\t', 'TreatAsEmpty', 'n/a'); % electrodes path (to exclude electrodes on the SOZ) -elecPath = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_electrodes.tsv']); -elecs = ieeg_readtableRmHyphens(elecPath); +elecsPath = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_electrodes.tsv']); +elecs = ieeg_readtableRmHyphens(elecsPath); % For all possible runs, set data_info data_info = []; @@ -253,8 +253,8 @@ %% render and plot noise ceiling SNR -elecPath = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_electrodes.tsv']); -elecs = ieeg_readtableRmHyphens(elecPath); +elecsPath = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_electrodes.tsv']); +elecs = ieeg_readtableRmHyphens(elecsPath); name = all_channels.name; all_channels_table = table(name); diff --git a/script02_writeMNI.m b/script02_writeMNI.m index 203345e..49240d2 100644 --- a/script02_writeMNI.m +++ b/script02_writeMNI.m @@ -1,24 +1,58 @@ +%% This script calculates MNI152 and MNI305 positions each subject and saves them -clear all localDataPath = setLocalDataPath(1); % runs local PersonalDataPath (gitignored) addpath('functions'); -subjects = {'01','02','03','04','05','06'}; +ss = 17; +sub_label = sprintf('%02d', ss); -ss = 4; -sub_label = subjects{ss}; ses_label = 'ieeg01'; - outdir = fullfile(localDataPath.output,'derivatives','preproc_car',['sub-' sub_label]); -% load(fullfile(outdir, ['sub-' sub_label '_desc-preprocCAR_ieeg.mat']), 'tt', 'srate', 'Mdata', 'eventsST', 'all_channels'); -load(fullfile(outdir, ['sub-' sub_label '_desc-preprocCARBB_ieeg.mat']), 'tt', 'srate', 'Mbb', 'eventsST', 'all_channels'); -readtable(fullfile(outdir, ['sub-' sub_label '_desc-preprocCAR_events.tsv']), 'FileType', 'text', 'Delimiter', '\t', 'TreatAsEmpty', 'n/a'); +% load electrodes +elecsPath = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_electrodes.tsv']); +elecs = ieeg_readtableRmHyphens(elecsPath); +elecmatrix = [elecs.x, elecs.y, elecs.z]; + +%% Get and save MNI152 positions to electrodesMni152.tsv (volumetric, SPM12) + +% locate forward deformation field from SPM. There are variabilities in session name, so we use dir to find a matching one +niiPath = dir(fullfile(localDataPath.input, 'sourcedata', 'spm_forward_deformation_fields', sprintf('sub-%s_ses-*_T1w_acpc.nii', sub_label))); +assert(length(niiPath) == 1, 'Error: did not find exactly one match in sourcedata T1w MRI'); % check for only one unique match +niiPath = fullfile(niiPath.folder, niiPath.name); + +% create a location in derivatives to save the transformed electrode images +rootdirMni = fullfile(localDataPath.input, 'derivatives', 'MNI152_electrode_transformations', sprintf('sub-%s', sub_label)); +mkdir(rootdirMni); + +% calculate MNI152 coordinates for electrodes +xyzMni152 = ieeg_getXyzMni(elecmatrix, niiPath, rootdirMni); + +% save as separate MNI 152 electrodes table +elecsMni152Path = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_space-' 'MNI152NLin2009' '_electrodes.tsv']); +elecsMni152 = elecs; +elecsMni152.x = xyzMni152(:, 1); elecsMni152.y = xyzMni152(:, 2); elecsMni152.z = xyzMni152(:, 3); +writetable(elecsMni152, elecsMni152Path, 'FileType', 'text', 'Delimiter', '\t'); + +fprintf('Saved to %s\n', elecsMni152Path); + +%% Get and save MNI305 positions (through fsaverage) + +% FS dir of current subject +FSdir = fullfile(localDataPath.input, 'sourcedata', 'freesurfer', sprintf('sub-%s', sub_label)); +FSsubjectsdir = fullfile(FSdir, '..'); -%% need to get MNI positions first +% calculate MNI305 coordinates for electrodes +[xyzMni305, vertIdxFsavg, minDists, surfUsed] = ieeg_mni305ThroughFsSphere(elecmatrix, elecs.hemisphere, FSdir, FSsubjectsdir, 'closest', 5); -% mni_coords = ieeg_mni305ThroughFsSphere(elecmatrix,hemi,FSdir,FSsubjectsdir) +% save as separate MNI 305 electrodes table +elecsMni305Path = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_space-' 'MNI305' '_electrodes.tsv']); +elecsMni305 = elecs; +elecsMni305.x = xyzMni305(:, 1); elecsMni305.y = xyzMni305(:, 2); elecsMni305.z = xyzMni305(:, 3); +elecsMni305.vertex_fsaverage = vertIdxFsavg; % also add a column to indicate vertex on fsavg, so we can easily get position for inflated brain +writetable(elecsMni305, elecsMni305Path, 'FileType', 'text', 'Delimiter', '\t'); +fprintf('Saved to %s\n', elecsMni305Path); %% Normalize bb power per run @@ -66,8 +100,8 @@ %% render and plot noise ceiling SNR -elecPath = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_electrodes.tsv']); -elecs = ieeg_readtableRmHyphens(elecPath); +elecsPath = fullfile(localDataPath.input, ['sub-' sub_label], ['ses-' ses_label], 'ieeg', ['sub-' sub_label '_ses-' ses_label '_electrodes.tsv']); +elecs = ieeg_readtableRmHyphens(elecsPath); name = all_channels.name; all_channels_table = table(name);