From b9d2106c462d8631297889125a2555cbafdc2491 Mon Sep 17 00:00:00 2001 From: byeolstellakim Date: Fri, 25 Aug 2023 10:28:59 -0400 Subject: [PATCH 1/3] add interp options --- .../Data_processing_tools/downsample_scnlab.m | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/CanlabCore/Data_processing_tools/downsample_scnlab.m b/CanlabCore/Data_processing_tools/downsample_scnlab.m index 4a3fbef3..dbf67f29 100644 --- a/CanlabCore/Data_processing_tools/downsample_scnlab.m +++ b/CanlabCore/Data_processing_tools/downsample_scnlab.m @@ -15,6 +15,17 @@ % **new_samprate:** % desired sampling rate in Hz % +% **doplot:** +% visualize the plot. Default: off +% +% **method:** +% Interpolation method. Default: linear +% 'linear' (default) | 'nearest' | 'next' | 'previous' | 'pchip' | +% 'cubic' | 'v5cubic' | 'makima' | 'spline' +% +% **extrap:** +% Extrapolation strategy, specified as 'extrap' or a real scalar value. +% % .. % I prefer this to matlab's downsample.m because linear interpolation is % robust and does fewer weird things to the data. @@ -30,10 +41,30 @@ % % every 100 / TR = 100/.5 = 200 samples % % [yi, xi] = downsample_scnlab(y, 100, .5) +% [yi, xi] = downsample_scnlab(y, 100, .5, 'doplot', 'method', 'spline') % +% Programmers notes: +% 8/25/2023 - Byeol +% Add more method options for interp1 function. + doplot = 0; -if length(varargin) > 0, doplot = varargin{1}; end +method = 'linear'; +extrapolation = 'extrap'; + +for i = 1:length(varargin) + if ischar(varargin{i}) + switch varargin{i} + % functional commands + case {'doplot'} + doplot = 1; + case {'method'} + method = varargin{i+1}; + case {'extrap'} + extrapolation = varargin{i+1}; + end + end +end downsamplerate = orig_samprate ./ new_samprate; @@ -49,7 +80,7 @@ xi = linspace(0, nobs, nobs_out); -yi = interp1(x, y, xi, 'linear', 'extrap'); +yi = interp1(x, y, xi, method, extrapolation); if doplot From cfbb42b4748c5bb28377d46c0fa0216f4850272c Mon Sep 17 00:00:00 2001 From: Yoni Ashar Date: Fri, 25 Aug 2023 08:56:51 -0600 Subject: [PATCH 2/3] Adding another montage type 'full2' is a handy montage type -- less full, no color bar overlap issues --- .../canlab_results_fmridisplay.m | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/CanlabCore/Visualization_functions/canlab_results_fmridisplay.m b/CanlabCore/Visualization_functions/canlab_results_fmridisplay.m index 92ffdf7d..7dd57044 100644 --- a/CanlabCore/Visualization_functions/canlab_results_fmridisplay.m +++ b/CanlabCore/Visualization_functions/canlab_results_fmridisplay.m @@ -56,11 +56,8 @@ % 'compact2' A single row showing midline saggital and axial slices % 'multirow' A series of 'compact2' displays in one figure for comparing different images/maps side by side % 'regioncenters' A series of separate axes, each focused on one region -% -% 'full' for full montages of axial and sagg slices. -% -% 'full hcp' for full montage, but with surfaces and volumes from -% HCP data +% 'full2' for a slightly less full montage that avoids colorbar overlap issues +% 'full hcp' for full montage, but with surfaces and volumes from HCP data % % 'compact' [default] for single-figure parasagittal and axials slices. % @@ -161,7 +158,8 @@ if ischar(input_activation) if strcmp(input_activation, 'compact') || strcmp(input_activation, 'compact2') || strcmp(input_activation, 'full') ... - || strcmp(input_activation, 'multirow') || strcmp(input_activation, 'coronal') || strcmp(input_activation, 'sagittal') + || strcmp(input_activation, 'multirow') || strcmp(input_activation, 'coronal') || strcmp(input_activation, 'sagittal') ... + || strcmp(input_activation, 'full2') || strcmp(input_activation, 'full hcp') % Entered no data map; intention is not to plot blobs, just create underlay varargin{end + 1} = 'noblobs'; @@ -247,6 +245,9 @@ wh = strcmp(varargin, 'full hcp'); if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end +wh = strcmp(varargin, 'full2'); +if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end + wh = strcmp(varargin, 'compact'); if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end @@ -477,6 +478,36 @@ wh_montages = [1 2 3 4]; wh_surfaces = [1 2 3 4]; + case 'full2' + + % saggital + [o2, dat] = montage(o2, 'saggital', 'wh_slice', xyz, 'onerow', 'noverbose'); + shift_axes(-0.02, -0.04); + + % coronal + axh = axes('Position', [-0.02 0.37 .1 .17]); + o2 = montage(o2, 'volume_data', dat, 'coronal', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh); + + % axial + axh = axes('Position', [-0.02 0.19 .1 .17]); + o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh); + + allaxh = findobj(gcf, 'Type', 'axes'); + disp(length(allaxh)); + for i = 1:(length(allaxh)-36) + pos1 = get(allaxh(i), 'Position'); + pos1(1) = pos1(1) - 0.03; + set(allaxh(i), 'Position', pos1); + end + + % surface + o2 = surface(o2, 'axes', [0.1 0.74 .25 .25], 'direction', 'hires left', 'orientation', 'medial'); + o2 = surface(o2, 'axes', [0.3 0.74 .25 .25], 'direction', 'hires right', 'orientation', 'medial'); + o2 = surface(o2, 'axes', [0.5 0.74 .25 .25], 'direction', 'hires left', 'orientation', 'lateral'); + o2 = surface(o2, 'axes', [0.7 0.74 .25 .25], 'direction', 'hires right', 'orientation', 'lateral'); + + wh_montages = [1 2 3 4]; + wh_surfaces = [1 2 3 4]; case 'compact2' % creates a new figure %subplot(2, 1, 1); From 70886ffb727897e0649be70a40e8ff8d6990793e Mon Sep 17 00:00:00 2001 From: Michael Sun Date: Mon, 4 Sep 2023 18:15:14 -0400 Subject: [PATCH 3/3] 'exact' flag added to select_atlas_subset --- CanlabCore/@atlas/select_atlas_subset.m | 30 +++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/CanlabCore/@atlas/select_atlas_subset.m b/CanlabCore/@atlas/select_atlas_subset.m index ee0fee33..609e48c5 100644 --- a/CanlabCore/@atlas/select_atlas_subset.m +++ b/CanlabCore/@atlas/select_atlas_subset.m @@ -20,6 +20,9 @@ % 'labels_2' : If you enter any field name in the object, e.g., labels_2, % the function will search for keyword matches here instead of in obj.labels. % +% 'exact' : If you enter 'exact', function will not look for overlaps in +% names, and only look for exact string matches. +% % Examples: % % atlasfile = which('Morel_thalamus_atlas_object.mat'); @@ -59,6 +62,9 @@ % Edited by tor, 12/2019, to use any field to select labels; and update % auxiliary label fields too. % +% Edited by Michael Sun, 09/04/2023, added an 'exact' flag, so that users +% can select to match string labels exactly and not capture regions with +% overlapping labels e.g., Cblm_Vermis_VI and Cblm_Vermis_VII. % ------------------------------------------------------------------------- % DEFAULTS AND INPUTS @@ -67,6 +73,7 @@ strings_to_find = []; integers_to_find = []; doflatten = false; +doexact=false; % for entry of optional field to search for keywords myfields = fieldnames(obj); @@ -87,6 +94,7 @@ case 'flatten', doflatten = true; % case 'xxx', xxx = varargin{i+1}; varargin{i+1} = []; + case 'exact', doexact = true; otherwise @@ -117,14 +125,22 @@ for i = 1:length(strings_to_find) % Find which names match - wh = ~cellfun(@isempty, strfind(obj.(mylabelsfield), strings_to_find{i})); - if strmatch(mylabelsfield, 'label_descriptions') - wh=wh'; + if doexact == false + wh = ~cellfun(@isempty, strfind(obj.(mylabelsfield), strings_to_find{i})); + if strmatch(mylabelsfield, 'label_descriptions') + wh=wh'; + end + + to_extract = to_extract | wh; + % Addition by Michael Sun 09/04/2023: Match strings exactly + else + wh = strcmp(obj.(mylabelsfield), strings_to_find{i}); + if strmatch(mylabelsfield, 'label_descriptions') + wh=wh'; + end + + to_extract = to_extract | wh; end - - - to_extract = to_extract | wh; - end % -------------------------------------------------------------------------