Skip to content

Commit

Permalink
Merge pull request #84 from thomas-vincent/surface_glm
Browse files Browse the repository at this point in the history
Surface glm
  • Loading branch information
thomas-vincent committed Feb 15, 2019
2 parents 52ecaad + f67e362 commit cdcfec2
Show file tree
Hide file tree
Showing 15 changed files with 784 additions and 187 deletions.
2 changes: 2 additions & 0 deletions bst_plugin/MANIFEST
@@ -1,3 +1,5 @@
process_nst_prefix_matrix.m
nst_save_table_in_bst.m
nst_parse_bst_item_name.m
nst_format_pval.m
nst_get_formats.m
Expand Down
96 changes: 80 additions & 16 deletions bst_plugin/nst_ppl_surface_template_V1.m
Expand Up @@ -162,6 +162,7 @@
create_dir(options.fig_dir);
create_dir(options.moco.export_dir);
create_dir(options.tag_bad_channels.export_dir);
create_dir(options.GLM_group.rois_summary.csv_export_output_dir);

% Get head model precomputed for all optode pairs
% (precompute it by cloning given data if needed)
Expand All @@ -173,7 +174,11 @@
[sFile_raw_fhm, fm_subject, fhm_redone] = get_sFile_for_full_head_model(file_raw1, options, force_redo);

%% Within-subject analyses
for igroup=1:length(groups)
nb_groups = length(groups);
all_sFile_table_zscores = cell(1, nb_groups);
group_condition_names = cell(1, nb_groups);
any_rois_summary_redone = 0;
for igroup=1:nb_groups
redo_group = options.GLM_group.redo;
subject_names = groups(igroup).subject_names;
group_label = groups(igroup).label;
Expand Down Expand Up @@ -239,6 +244,7 @@
group_condition_name = '';
end
group_condition_name = [group_condition_name 'GLM' get_ppl_tag()];
group_condition_names{igroup} = group_condition_name;
for ihb=1:size(all_sFiles_con, 1)
for icon=1:size(all_sFiles_con, 2)
% TODO: use pipeline tag to name condition folder
Expand Down Expand Up @@ -299,41 +305,98 @@
all_sFiles_con(ihb, icon, :), sFile_gp_mask);
all_sFiles_subj_zmat{ihb, icon} = sFile_subj_zmat;
end

if redone
% Set contrast name as prefix for each ROI column
bst_process('CallProcess', 'process_nst_prefix_matrix', ...
sFile_subj_zmat, [], 'col_prefixes', [contrasts(icon).label '_']);
end

end
if options.GLM_group.rois_summary.do
% Concatenate across contrasts
[sFile_concat, redone] = nst_run_bst_proc(['Group analysis/' group_condition_name '/' hb_types{ihb} ' masked z-scores'], ...
redone | options.GLM_group.rois_summary.redo, ...
'process_nst_concat_matrices', ...
all_sFiles_subj_zmat(ihb, :), [], ...
'stacking_type', stacking_types.column);
all_sFiles_subj_zmat_con_concat{ihb} = sFile_concat;

if redone
% Set Hb type as prefix for all columns. Add user-defined col prefix
if ~isempty(options.GLM_group.rois_summary.matrix_col_prefix)
col_prefix = [options.GLM_group.rois_summary.matrix_col_prefix '_'];
else
col_prefix = '';
end
bst_process('CallProcess', 'process_nst_prefix_matrix', ...
sFile_concat, [], 'col_prefixes', [col_prefix hb_types{ihb} '_']);
end
end
end

if options.GLM_group.rois_summary.do
hb_prefixes = strjoin(cellfun(@(c) [options.GLM_group.rois_summary.matrix_col_prefix '_' c '_'], ...
hb_types, 'UniformOutput', 0), ',');

[sFile_table_zscores, redone] = nst_run_bst_proc(['Group analysis/' group_condition_name '/all masked zscores'], ...
redone | options.GLM_group.rois_summary.redo, ...
'process_nst_concat_matrices', ...
all_sFiles_subj_zmat_con_concat, [], ...
'prefixes', hb_prefixes, ...
'stacking_type', stacking_types.column);
if isempty(group_label)
group_prefix = '';
else
group_prefix = [group_label '_'];

all_sFile_table_zscores{igroup} = sFile_table_zscores;
any_rois_summary_redone = any_rois_summary_redone | redone;



if redone && isempty(options.GLM_group.rois_summary.stack_groups)
% Group results will not be stacked so save each group data separately
if isempty(group_label)
group_prefix = '';
else
group_prefix = [group_label '_'];
end
csv_fn = fullfile(options.GLM_group.rois_summary.csv_export_output_dir, ...
[group_prefix 'z-scores.csv']);
bst_process('CallProcess', 'process_nst_save_matrix_csv', ...
sFile_table_zscores, [], ...
'ignore_rows_all_zeros', 0, 'ignore_cols_all_zeros', 0, ...
'csv_file', {csv_fn, 'ASCII-CSV'});
end
csv_fn = fullfile(options.GLM_group.rois_summary.csv_export_output_dir, ...
[group_prefix 'z-scores.csv']);
nst_run_bst_proc({}, redone | options.GLM_group.rois_summary.redo, ...
'process_nst_save_matrix_csv', ...
sFile_table_zscores, [], ...
'csv_file', {csv_fn, 'ASCII-CSV'});
end
end
end
end

if options.GLM_group.do && options.GLM_group.rois_summary.do && ...
~isempty(options.GLM_group.rois_summary.stack_groups)

% Concatenate all group results and save as CSV

% TODO: move checks to global option checks
assert(size(options.GLM_group.rois_summary.stack_groups, 1) == 1);
assert(length(unique(options.GLM_group.rois_summary.stack_groups)) == length(options.GLM_group.rois_summary.stack_groups));
assert(isempty(setdiff(options.GLM_group.rois_summary.stack_groups, 1:nb_groups)));

[varying, common_pref, common_suf] = str_remove_common(group_condition_names);
stacked_group_cond_name = [common_pref strjoin(varying, '_') common_suf];
[sFile_table_zscores, redone] = nst_run_bst_proc(['Group analysis/' stacked_group_cond_name '/all groups masked zscores'], ...
any_rois_summary_redone | options.GLM_group.rois_summary.redo, ...
'process_nst_concat_matrices', ...
all_sFile_table_zscores(options.GLM_group.rois_summary.stack_groups), [], ...
'stacking_type', stacking_types.row);

[varying_label, common_prefix, common_suffix] = str_remove_common({groups(options.GLM_group.rois_summary.stack_groups).label}, 1);
varying_label(cellfun(@isempty, varying_label)) = {''};

csv_fn = fullfile(options.GLM_group.rois_summary.csv_export_output_dir, ...
[common_prefix strjoin(varying_label, '_') common_suffix '_z-scores.csv']);
nst_run_bst_proc({}, redone | options.GLM_group.rois_summary.redo, ...
'process_nst_save_matrix_csv', ...
sFile_table_zscores, [], ...
'ignore_rows_all_zeros', 0, 'ignore_cols_all_zeros', 1, ...
'csv_file', {csv_fn, 'ASCII-CSV'});
end


%% Finalize
if prev_iCortex ~= iCortex
% Set default cortical surface to original one
Expand Down Expand Up @@ -657,6 +720,7 @@
options.GLM_group.rois_summary.atlas = 'MarsAtlas';
options.GLM_group.rois_summary.matrix_col_prefix = '';
options.GLM_group.rois_summary.csv_export_output_dir = 'results';
options.GLM_group.rois_summary.stack_groups = [];

options.make_figs = 1;
options.save_fig_method = 'saveas'; % 'saveas', 'export_fig'
Expand Down Expand Up @@ -767,7 +831,7 @@
warning('Data folder should not be part of nirstorm source folders (%s)', folder);
end

if ~exist(folder, 'dir')
if ~isempty(folder) && ~exist(folder, 'dir')
mkdir(folder);
end

Expand Down
67 changes: 67 additions & 0 deletions bst_plugin/nst_save_table_in_bst.m
@@ -0,0 +1,67 @@
function sFile = nst_save_table_in_bst(t, subject_name, condition, comment, extra, displayUnits)
% Save a table as a matrix brainstorm item:
% Field Std is not used
% Fields Time and Description are not used because their interpretation by
% brainstorm is not straightfoward.
% Description sometimes refer to row names and sometimes to column names
% depending on the matrix dimension and if Time is available.
% Here new fields RowNames and ColNames are added to store them.
%
%

if nargin < 5
extra = struct();
end

if nargin < 6
displayUnits = '';
end

MatNew = db_template('matrix');
MatNew.Value = table2array(t);
nrows = size(MatNew.Value, 1);
MatNew.Std = [];
MatNew.Time = [];
MatNew.Description = {};
MatNew.DisplayUnits = displayUnits;
MatNew.Comment = comment;

if ~isempty(t.Row)
MatNew.RowNames = t.Row;
else
MatNew.RowNames = arrayfun(@(n) sprintf('row_%d', n), 1:nrows, 'UniformOutput', 0);
end
MatNew.RowNames = line_vector(MatNew.RowNames);
MatNew.Time = 1:length(MatNew.RowNames);
MatNew.ColNames = line_vector(t.Properties.VariableNames);
MatNew.Description = MatNew.ColNames;

sSubject = bst_get('Subject', subject_name, 1);
if isempty(sSubject)
db_add_subject(subject_name, []);
end
[sStudy, iStudy] = bst_get('StudyWithCondition', [subject_name '/' condition]);
if isempty(sStudy)
iStudy = db_add_condition(subject_name, condition);
sStudy = bst_get('Study', iStudy);
end

% Add extra fields
extra_fields = fieldnames(extra);
for ifield = 1:length(extra_fields)
% assert(~isfield(MatNew, extra_fields{ifield}));
MatNew.(extra_fields{ifield}) = extra.(extra_fields{ifield});
end

sFile = bst_process('GetNewFilename', bst_fileparts(sStudy.FileName), 'matrix_table');
% Save file
bst_save(sFile, MatNew, 'v6');
% Register in database
db_add_data(iStudy, sFile, MatNew);
end

function v = line_vector(v)
if size(v, 2) == 1 && size(v, 1) > 1
v = v';
end
end

0 comments on commit cdcfec2

Please sign in to comment.