Skip to content

Commit

Permalink
update fLoCAnalysis and Params file to be transformed into a gear, ad…
Browse files Browse the repository at this point in the history
…ded parameters to logfile
  • Loading branch information
MNordt committed Sep 19, 2018
1 parent 9d9d405 commit 94e0c8e
Show file tree
Hide file tree
Showing 18 changed files with 542 additions and 113 deletions.
Empty file modified functions/do_screen.m
100644 → 100755
Empty file.
Empty file modified functions/draw_fixation.m
100644 → 100755
Empty file.
152 changes: 105 additions & 47 deletions functions/fLocAnalysis.m
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
function err = fLocAnalysis(session, init_params, glm_params, clip, stc)
function err = fLocAnalysis(session, init_params, glm_params, clip, QA)
% Automated analysis of fMRI data from fLoc funcional localizer experiment
% using vistasoft functions (https://github.com/vistalab/vistasoft).
%
% INPUTS
% INPUTS fLocAnalysis(session, init_params, glm_params, clip, QA)
% 1) session: name of session in ~/fLoc/data/ to analyze (string)
% 2) init_params: optional preprocessing parameters (struct)
% 3) glm_parms: optional GLM analysis parameters (struct)
% 4) clip: optional number of TRs to clip from beginnning of each run (int)
% 5) stc: optional flag controlling slice time correction (logical)
% 5) QA: optional flag controlling whether analysis exists if QA checks
% fail (logical)
%
% OUTPUT
% 1) err: 1 if analysis terminated with an error, 0 if analysis completed
Expand All @@ -21,6 +22,12 @@
%
% AS 8/2018

% Parfiles must be organized such that like conditions that you would like
% to be contrasted with all other conditions are grouped in twos. In other
% words, if the localizer uses both adult and child face conditions, they
% should be listed as, for instance, condition numbers 1 and 2, instead of
% 2 and 3 or 1 and 4.
% AR 09/2018

%% Check inputs and get analysis parameters

Expand All @@ -33,37 +40,49 @@
[~, session_id] = fileparts(session);
end

% check and set defaults for clip and stc arguements
% check and set defaults for clip arguement
if nargin < 4 || isempty(clip); clip = 0; end
if rem(clip, 1) ~= 0
fprintf('Error: clip arguement must be an integer. \n\n'); return;
end
if nargin < 5 || isempty(stc); stc = true; end
if stc == 1; stc = true; end
if stc == 0; stc = false; end
if ~islogical(stc)
fprintf('Error: stc arguement must be a logical. \n\n'); return;

if nargin < 6 || isempty(QA); QA = false; end

if QA == 1; QA = true; end
if QA == 0; QA = false; end

if ~islogical(QA)
fprintf('Error: QA argument must be a logical. \n\n'); return;
end

%Move to session's folder
cd(session)

% set preprocessing parameters if not provided
if nargin < 2 || isempty(init_params)
[~, init_params, dglm_params] = fLocAnalysisParams(session, clip, stc);
[~, init_params, dglm_params] = fLocAnalysisParams(session, clip);
end

% set GLM analysis parameters if not provided
if nargin < 3 || isempty(glm_params)
glm_params = dglm_params;
end

% save params
save fLocAnalysisParams.mat init_params glm_params

% apply canonical transformation to .nii.gz files
for rr = 1:length(init_params.functionals)
%init_params.glmParams{rr} = glm_params;
niftiWrite(niftiApplyCannonicalXform(niftiRead(init_params.functionals{rr})));
end

niftiWrite(niftiApplyCannonicalXform(niftiRead(init_params.inplane)));
nii = niftiRead(init_params.functionals{1}); nslices = size(nii.data, 3);

% open logfile to track progress of analysis
lid = fopen(fullfile(session, 'fLocAnalysis_log.txt'), 'w+');
logFileName = fullfile(session, 'fLocAnalysis_log.txt');
lid = fopen(logFileName, 'w+');
fprintf(lid, 'Starting analysis for session %s. \n\n', session_id);
fprintf('Starting analysis for session %s. \n\n', session_id);

Expand All @@ -75,28 +94,11 @@
fprintf('Initializing vistasoft session directory in: \n%s \n\n', session);
setpref('VISTA', 'verbose', false); % suppress wait bar
if exist(fullfile(session, 'Inplane'), 'dir') ~= 7
mrInit(init_params);
mrInit(init_params); %Saves mrSESSION.mat under session's folder
end

hi = initHiddenInplane('Original', 1);

% do slice timing correction assuming interleaved slice acquisition
if stc
fprintf(lid, 'Starting slice timing correction... \n');
fprintf('Starting slice timing correction... \n');
if ~(exist(fullfile(session, 'Inplane', 'Timed'), 'dir') == 7)
load(fullfile(session, 'mrSESSION'));
for rr = 1:length(init_params.functionals)
mrSESSION.functionals(rr).sliceOrder = [1:2:nslices 2:2:nslices];
end
setpref('VISTA', 'verbose', false); % suppress wait bar
saveSession; hi = initHiddenInplane('Original', 1);
hi = AdjustSliceTiming(hi, 0, 'Timed');
saveSession; close all;
end
fprintf(lid, 'Slice timing correction complete. \n\n');
fprintf('Slice timing correction complete. \n\n');
hi = initHiddenInplane('Timed', 1);
end

% do within-scan motion compensation and check for motion > 2 voxels
fprintf(lid, 'Starting within-scan motion compensation... \n');
Expand All @@ -109,16 +111,28 @@
end
fig = openfig(fullfile(session, 'Images', 'Within_Scan_Motion_Est.fig'), 'invisible');
L = get(get(fig, 'Children'), 'Children');
for rr = 1:length(init_params.functionals)
motion_est = L{rr + 1}.YData;
if max(motion_est(:)) > 2
fprintf(lid, 'Warning -- Within-scan motion exceeds 2 voxels. \nExited analysis.');
fprintf('Warning -- Within-scan motion exceeds 2 voxels. \nExited analysis.');
fclose(lid); return;
if QA
for rr = 1:length(init_params.functionals)
motion_est = L{rr + 1}.YData;
if max(motion_est(:)) > 2
fprintf(lid, 'Warning -- Within-scan motion exceeds 2 voxels. \n');
fprintf('Warning -- Within-scan motion exceeds 2 voxels. \n');
fprintf(lid,'Exited analysis');
fprintf('Exited analysis');
ffclose(lid);
return;
end
fprintf(lid,'QA checks passed for run %i. ',rr);
fprintf('QA checks passed for run %i. ',rr);
end
end
fprintf(lid, 'Within-scan motion compensation complete. QA checks passed. \n\n');
fprintf('Within-scan motion compensation complete. QA checks passed. \n\n');

% group motion compensation scans
hi = initHiddenInplane('MotionComp', init_params.scanGroups{1}(1));
hi = er_groupScans(hi, init_params.scanGroups{1});

fprintf(lid, 'Within-scan motion compensation complete. \n\n');
fprintf('Within-scan motion compensation complete. \n\n');

% do between-scan motion compensation and check for motion > 2 voxels
fprintf(lid, 'Starting between-scan motion compensation... \n');
Expand All @@ -132,6 +146,7 @@
hi = selectDataType(hi, 'MotionComp_RefScan1');
saveSession; close all;
end

fid = fopen(fullfile(session, 'Between_Scan_Motion.txt'), 'r');
motion_est = zeros(length(init_params.functionals) - 1, 3);
for rr = 1:length(init_params.functionals) - 1
Expand All @@ -141,14 +156,18 @@
motion_est(rr, 3) = str2double(ln{14});
end
fclose(fid);
if max(motion_est(:)) > 2
fprintf(lid, 'Warning -- Between-scan motion exceeds 2 voxels. \nExited analysis.');
fprintf('Warning -- Between-scan motion exceeds 2 voxels. \nExited analysis.');
fclose(lid); return;
if QA
if max(motion_est(:)) > 2
fprintf(lid, 'Warning -- Between-scan motion exceeds 2 voxels. \nExited analysis.');
fprintf('Warning -- Between-scan motion exceeds 2 voxels. \nExited analysis.');
fclose(lid); return;
else
fprintf(lid,'QA checks passed. \n\n');
fprintf('QA checks passed. \n\n');
end
end
fprintf(lid, 'Between-scan motion compensation complete. QA checks passed. \n\n');
fprintf('Between-scan motion compensation complete. QA checks passed. \n\n');

fprintf(lid, 'Between-scan motion compensation complete.\n\n');
fprintf('Between-scan motion compensation complete.\n\n');

%% Analyze fMRI data and generate model parameter maps

Expand Down Expand Up @@ -181,6 +200,7 @@
hi = er_assignParfilesToScans(hi, init_params.scanGroups{1}, init_params.parfile);
saveSession; close all;


% run GLM and compute default statistical contrasts
fprintf(lid, 'Performing GLM analysis for %s... \n\n', session);
fprintf('Performing GLM analysis for %s... \n\n', session);
Expand All @@ -206,8 +226,46 @@
fprintf(lid, 'GLM parameter maps saved in: \n%s/GLMs/... \n\n', session);
fprintf('GLM parameter maps saved in: \n%s/GLMs/... \n\n', session);

fprintf(lid, 'fLocAnalsis for %s is complete! \n', session_id);
fprintf('fLocAnalsis for %s is complete! \n', session_id); fclose(lid);
fprintf(lid, 'fLocAnalsis for %s is complete! \n\n', session_id);
fprintf('fLocAnalsis for %s is complete! \n', session_id);

% add MATLAB and Mr Vista Version to logfile
fprintf(lid,['---------------------------------------------------','\n\n']);

fprintf(lid,['MATLAB version ',version,'\n\n']);
load mrSESSION.mat
fprintf(lid,['mrVista Version ',mrSESSION.mrVistaVersion,'\n\n']);

% add all parameters used to logfile
fprintf(lid,['---------------------------------------------------','\n\n']);

load mrInit_params.mat
% initialization params
fprintf(lid,['Initialization parameters used\n\n',evalc('disp(params)')]);
fprintf(lid,['including: functionals\n\n',evalc('disp(params.functionals(:))')]);
fprintf(lid,['keepFrames\n\n',evalc('disp(params.keepFrames)')]);
fprintf(lid,['parfiles\n\n',evalc('disp(params.parfile(:))')]);

fprintf(lid,['---------------------------------------------------','\n\n']);

% scan params
for l = 1:length(dataTYPES(1).scanParams), fprintf(lid,['Original data type scan ',num2str(l),' params:\n\n',l,evalc( 'disp(dataTYPES(1).scanParams(l))' )]), end

fprintf(lid,['GLM data type scan params:\n\n',evalc('disp(dataTYPES(4).scanParams)')]);

fprintf(lid,['---------------------------------------------------','\n\n']);

% GLM params
fprintf(lid,['Event analysis parameters used\n\n',evalc('disp(dataTYPES(length(dataTYPES)).eventAnalysisParams)')]);

% close file
fclose(lid);
err = 0;

%Move cd back to fLoc from session
cd ..

%Clear workspace
clearvars -except err

end
28 changes: 21 additions & 7 deletions functions/fLocAnalysisParams.m
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
function [session, init_params, glm_params] = fLocAnalysisParams(session, clip, stc)
function [session, init_params, glm_params] = fLocAnalysisParams(session, clip)
% Generate data structures of vistasoft parameters for preprocessing and
% analyzing fLoc data with a GLM.
%
% INPUTS
% 1) session: name of session in ~/fLoc/data/ to analyze (string)
% 2) clip: number of TRs to clip from beginnning of each run (int)
% 3) stc: flag controlling slice time correction (logical)

%
% OUPUTS
% 1) session -- name of session in ~/fLoc/data/ to analyze (string)
Expand All @@ -26,6 +26,7 @@
% find paths to fMRI data and corresponding stimulus parfiles
[~, session_id] = fileparts(session);
niifiles = dir(fullfile(session, '*.nii.gz')); niifiles = {niifiles.name};
niifiles = niifiles(~contains(niifiles,'._')); % Alex made an edit: some file names had a random ._ at the beginning that need to be excluded
parfiles = dir(fullfile(session, '*.par')); parfiles = {parfiles.name};
niipaths = {}; parpaths = {}; num_runs = 0;
while sum(contains(lower(niifiles), ['run' num2str(num_runs + 1) '.nii.gz'])) >= 1
Expand All @@ -40,6 +41,12 @@
end
end

%Adding annotation for each run
annotations = {};
for i = 1:length(niipaths)
annotations{i} = ['localizer_run',num2str(i)];
end

% find path to anatomical inplane scan
inplane_idx = find(contains(lower(niifiles), 'inplane'), 1);
if isempty(inplane_idx)
Expand Down Expand Up @@ -81,7 +88,7 @@
init_params.motionCompRefScan = 1; % run number of reference scan for between-scans compensation

% necessary fields that cannot be modified (maybe these can be hidden)
init_params.sessionCode = session; % char array, session data directory
init_params.sessionCode = session_id; % char array, local session data directory
init_params.doAnalParams = 1; % logical, set GLM analysis parameters during intialization
init_params.doSkipFrames = 1; % logical, clip countdown frames during initialization
init_params.doPreprocessing = 1; % logcial, do some preprocessing during initialization
Expand All @@ -92,10 +99,15 @@
init_params.keepFrames = repmat([init_params.clip -1], num_runs, 1);

% unnecessary fields that can be filled in by user
init_params.subject = ''; % char array with participant ID
init_params.description = ''; % char array describing session
init_params.comments = ''; % char array of comments
init_params.annotations = {}; % cell array of descriptions for each run
init_params.subject = session_id(1:find(session_id == '_') - 1); % char array with participant ID
init_params.description = 'localizer'; % char array describing session
init_params.comments = 'Analyzed using fLoc'; % char array of comments
init_params.annotations = annotations; % cell array of descriptions for each run

%Alex noticed that the sessionDir needed to be changed so that the
%mrSESSION.mat file would be added to the session's folder, not to the fLoc
%folder
init_params.sessionDir = session;


%% Initialize and modify GLM analysis parameters
Expand All @@ -119,4 +131,6 @@
glm_params.peakPeriod = 6:8; % time window to estimate peak response
glm_params.bslPeriod = -4:0; % time window to estiamte baseline response

% annotation
glm_params.annotation = sprintf('LocalizerGLM_%iruns',length(init_params.functionals));
end
Loading

0 comments on commit 94e0c8e

Please sign in to comment.