Skip to content

Commit

Permalink
Speed improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
bogpetre committed Jan 24, 2024
1 parent 5cd624c commit d723ccc
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
53 changes: 47 additions & 6 deletions CanlabCore/@atlas/downsample_parcellation.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
% Output ::
% atlas_obj - a new atlas object, reindexed according to labelfield

if isvector(varargin{1})
fprintf('Downsampling %s parcels\n', obj.atlas_name);

if isempty(varargin)
labelfield = 'labels_2';
elseif isvector(varargin{1})
if length(varargin{1}) ~= num_regions(obj)
error('New labels has length %d which does not match input atlas parcel count (%d)',length(varargin{1}), num_regions(obj));
end
labelfield='labels';
obj.lbaels = varargin{1};
elseif isempty(varargin)
labelfield = 'labels_2';
else
labelfield = varargin{1};
end
Expand Down Expand Up @@ -64,16 +66,55 @@

rm_lbl_ind = find(~ismember(1:length(valid_lbls), 1:length(kept_lbl_ind)));

% merge high resolution regions
[new_lbl_parcels, lbl_exp] = unique(obj.(new_lbl),'stable');
new_parcels = cell(1,length(new_lbl_parcels));
parfor i = 1:length(new_lbl_parcels)

% init progress watcher
n_reg = length(new_lbl_parcels);
last_msg = sprintf('Creating new region 1/%d',n_reg);
fprintf('%s',last_msg);

% working with sparse matrices is much faster for atlases with many
% parcels, while atlases with few parcels are likely to run quickly
% regardless
obj.probability_maps = sparse(obj.probability_maps);
for i = 1:length(new_lbl_parcels)
% this can be parallelized but it's very memory intensive for some
% atlases (e.g. canlab2023) and parallelization makes the problem worse
% by several factors.

% update progress watcher
delete_last_chars = length(last_msg);
fprintf('%s',char(8*ones(1,delete_last_chars)))
new_msg = sprintf('Assembling region %d/%d',i,n_reg);
fprintf('%s',new_msg);
last_msg = new_msg;

new_parcel{i} = obj.select_atlas_subset(new_lbl_parcels(i), new_lbl, 'exact', 'flatten');
end
fprintf('\n');

% init progress watcher
n_reg = length(new_parcel);
last_msg = sprintf('Merging new region 1/%d',n_reg);
fprintf('%s',last_msg);

% Combine parcels
new_atlas_obj = new_parcel{1};
for i = 2:length(new_parcel)
new_atlas_obj = new_atlas_obj.merge_atlases(new_parcel{i});
% update progress watcher
delete_last_chars = length(last_msg);
fprintf('%s',char(8*ones(1,delete_last_chars)))
new_msg = sprintf('Adding region %d/%d',i,n_reg);
fprintf('%s',new_msg);
last_msg = new_msg;

new_atlas_obj = new_atlas_obj.merge_atlases(new_parcel{i},'noverbose','nocomparespace');
end
fprintf('\n');
new_atlas_obj.probability_maps = sparse(new_atlas_obj.probability_maps);

for i = 1:length(kept_lbl_ind)
% increment by 1
old_lbls = obj.(valid_lbls{kept_lbl_ind(i)});
Expand All @@ -86,4 +127,4 @@
new_atlas_obj.(valid_lbls{ind}) = {};
end

end
end
11 changes: 8 additions & 3 deletions CanlabCore/@atlas/merge_atlases.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

case 'always_replace', always_replace = true; varargin{i} = [];
case 'noreplace', doreplacevoxels = false; varargin{i} = [];
case 'noverbose', doverbose = false; varargin{i} = [];

otherwise , warning(['Unknown input string option:' varargin{i}]);
end
Expand All @@ -50,11 +51,12 @@
% Subset
% -------------------------------------------------------------------------

if ~isempty(varargin) && any(cellfun(@isvector, varargin) || cellfun(@iscell, varargin))
if ~isempty(varargin) && any(cellfun(@isvector, varargin) | cellfun(@iscell, varargin))

if doverbose, disp('Getting atlas subset with select_atlas_subset'); end

atlas_obj_to_add = select_atlas_subset(atlas_obj_to_add, varargin{:});
args = varargin(cellfun(@isvector, varargin) | cellfun(@iscell, varargin));
atlas_obj_to_add = select_atlas_subset(atlas_obj_to_add, args{:});

end

Expand Down Expand Up @@ -135,7 +137,10 @@
atlas_obj_to_add.probability_maps(wh, :) = 0;
end

atlas_obj.probability_maps = [full(atlas_obj.probability_maps) full(atlas_obj_to_add.probability_maps)];
% concatenating sparse matrices first is much faster than converting to full and the
% concatenating full matrices
%atlas_obj.probability_maps = [full(atlas_obj.probability_maps) full(atlas_obj_to_add.probability_maps)];
atlas_obj.probability_maps = full([atlas_obj.probability_maps atlas_obj_to_add.probability_maps]);

atlas_obj = probability_maps_to_region_index(atlas_obj);

Expand Down

0 comments on commit d723ccc

Please sign in to comment.