Skip to content

Commit

Permalink
Style, docs, misc minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias Noebauer committed Jul 19, 2018
1 parent 0a68165 commit 91c1efd
Show file tree
Hide file tree
Showing 8 changed files with 442 additions and 170 deletions.
82 changes: 46 additions & 36 deletions main_nnmf_SID.m
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,6 @@
SID_output.S = SID_output.S';
end

%% Crop sensor movie
sensor_movie = sensor_movie(SID_output.idx,:);

%% Plot NNMF results
close all;
timestr = datestr(now, 'YYmmddTHHMM');
Expand Down Expand Up @@ -347,7 +344,7 @@
colorbar;
print(fullfile(Input.outdir, [timestr '_nnmf_component_recon_' num2str(i, '%03d') '.png']), '-dpng', '-r600');
end
pause(10);
pause(2);
close all;

%% Save checkpoint
Expand All @@ -367,7 +364,7 @@

if Input.filter
disp('Filtering reconstructed spatial filters');
SID_output.segmm = filter_recon(SID_output.recon,opts);
SID_output.segmm = filter_recon(SID_output.recon, opts);
else
SID_output.segmm = SID_output.recon;
end
Expand All @@ -381,24 +378,29 @@
for ii=1:size(SID_output.segmm,u)
SID_output.neuron_centers_per_component{ii} = segment_component(SID_output.segmm{ii},Input.segmentation.threshold);
num(ii) = size(SID_output.neuron_centers_per_component{ii},1); %#ok<AGROW>
disp(num(ii));
disp(['Component ' num2str(ii) ': Found ' num2str(num(ii)) ' neuron candidates']);
end

ids = isoutlier(num, 'ThresholdFactor', 10);
ids = (num > mean(num)) .* ids;
outlier_ixs = find(ids);

for ii=find(ids)
for i = 1 : numel(outlier_ixs)
ii = outlier_ixs(i);
threshold = 0.1;
SID_output.neuron_centers_per_component{ii} = segment_component(SID_output.segmm{ii}, threshold);
num(ii) = size(SID_output.neuron_centers_per_component{ii},1);
disp(num(ii));
disp(['Re-segmenting component with overly many neurons with higher threshold: Component ' num2str(ii) ': Found ' num2str(num(ii)) ' neuron candidates']);
end

[SID_output.neuron_centers_ini,SID_output.neur_id]=iterate_cluster(SID_output.neuron_centers_per_component,Input.cluster_iter,Input.neur_rad,dim);
% Merge closely spaced neuron candidates from different NNMF components by finding clusters of candidates that have an extent smaller than Input.neuron_rad
[SID_output.neuron_centers_ini, SID_output.neur_id] = iterate_cluster(SID_output.neuron_centers_per_component, Input.cluster_iter, Input.neur_rad, dim);

figure;plot(hist(SID_output.neuron_centers_ini(:,3),size(SID_output.recon{1},3)));
figure; histogram(SID_output.neuron_centers_ini(:,3), -0.5 : 1 : size(SID_output.recon{1},3) + 0.5);
xlabel('Z plane index');
ylabel('Neuron frequency');
print(fullfile(Input.outdir, [timestr '_segmm_z-hist.png']), '-dpng', '-r300');

if ~isfield(Input.segmentation,'top_cutoff')
disp('Check the axial distribution and remove top/bottom artefacts');
Input.segmentation.top_cutoff = input('Input top cutoff \n');
Expand Down Expand Up @@ -439,6 +441,9 @@
%%
clearvars -except sensor_movie Input SID_output mean_signal psf_ballistic Hsize m sensor_movie_max sensor_movie_min dim;

%% Crop sensor movie
sensor_movie = sensor_movie(SID_output.idx,:);

%% Initiate forward_model
%TODO: check performance of generate_forward_model() with matfile
%psf_ballistic = matfile(Input.psffile);
Expand All @@ -455,13 +460,14 @@
opts.image_size = SID_output.movie_size(1:2);
opts.axial = Input.axial;
opts.neur_rad = Input.neur_rad;
SID_output.forward_model_ini=generate_LFM_library_GPU(SID_output.recon,SID_output.neuron_centers_ini,round(SID_output.neur_id),psf_ballistic,opts);
SID_output.forward_model_ini = generate_LFM_library_GPU(SID_output.recon, SID_output.neuron_centers_ini, ...
round(SID_output.neur_id), psf_ballistic, opts);
end

%% Generate template
SID_output.template=generate_template(SID_output.neuron_centers_ini,psf_ballistic.H,SID_output.std_image,Input.template_threshold);
SID_output.template = generate_template(SID_output.neuron_centers_ini, psf_ballistic.H, SID_output.std_image, Input.template_threshold);

%% Crop model
%% Remove neuron templates that don't have positive weights inside of to the overall crop region determined further up (based on crop_mask and/or crop_params)
neur = find(squeeze(max(SID_output.forward_model_ini(:, SID_output.idx), [], 2) > 0));
SID_output.forward_model_iterated = SID_output.forward_model_ini(neur, SID_output.idx);
SID_output.neuron_centers_iterated = SID_output.neuron_centers_ini(neur, :);
Expand Down Expand Up @@ -499,15 +505,15 @@
opts_temp.gpu_id = Input.gpu_ids(1);
end

if isfield(Input, 'bg_sub') && Input.bg_sub% && ~Input.use_std
if isfield(Input, 'bg_sub') && Input.bg_sub % && ~Input.use_std
SID_output.forward_model_iterated(end+1,:) = SID_output.bg_spatial(SID_output.idx);
SID_output.indices_in_orig=[SID_output.indices_in_orig' length(SID_output.indices_in_orig)+1];
SID_output.indices_in_orig = [SID_output.indices_in_orig' length(SID_output.indices_in_orig) + 1];
end

sensor_movie =double(sensor_movie);
sensor_movie = double(sensor_movie);
disp([datestr(now, 'YYYY-mm-dd HH:MM:SS') ': ' 'Starting temporal update']);
SID_output.forward_model_iterated=(1./(sqrt(sum(SID_output.forward_model_iterated.^2....
,2)))).*SID_output.forward_model_iterated;
SID_output.forward_model_iterated = (1 ./ sqrt(sum(SID_output.forward_model_iterated .^ 2, 2))) ...
.* SID_output.forward_model_iterated;
SID_output.timeseries_ini = LS_nnls(SID_output.forward_model_iterated(:,SID_output.microlenses(SID_output.idx)>0)', double(sensor_movie(SID_output.microlenses(SID_output.idx)>0,:)), opts_temp);
disp([datestr(now, 'YYYY-mm-dd HH:MM:SS') ': ' 'Temporal update completed']);

Expand Down Expand Up @@ -541,22 +547,23 @@
end
end

[SID_output.forward_model_iterated,SID_output.timeseries_iterated,template_...
,SID_output.indices_in_orig] = temporal_SID_update(...
sensor_movie,SID_output.forward_model_iterated,SID_output.timeseries_iterated...
,template_,SID_output.indices_in_orig,opts_temp);


[SID_output.forward_model_iterated,SID_output.timeseries_iterated,template_...
,SID_output.indices_in_orig] = merge_filters(...
SID_output.forward_model_iterated,SID_output.timeseries_iterated...
,template_,SID_output.indices_in_orig,opts_temp);
disp([datestr(now, 'YYYY-mm-dd HH:MM:SS') ': ' 'Iteration ' num2str(iter) ' of ' num2str(num_iter) ' completed']);
end
SID_output.neuron_centers_iterated=SID_output.neuron_centers_ini(SID_output.indices_in_orig(1:end-1),:);

SID_output.template_iterated=template_;
opts_temp.warm_start=[];
[SID_output.forward_model_iterated, ...
SID_output.timeseries_iterated, template_, ...
SID_output.indices_in_orig] = temporal_SID_update(sensor_movie, ...
SID_output.forward_model_iterated, ...
SID_output.timeseries_iterated, ...
template_, SID_output.indices_in_orig, opts_temp);

[SID_output.forward_model_iterated, ...
SID_output.timeseries_iterated, template_, ...
SID_output.indices_in_orig] = merge_filters(SID_output.forward_model_iterated, ...
SID_output.timeseries_iterated, ...
template_, SID_output.indices_in_orig, opts_temp);
disp([datestr(now, 'YYYY-mm-dd HH:MM:SS') ': ' 'Iteration ' num2str(iter) ' of ' num2str(Input.num_iter) ' completed']);
end
SID_output.neuron_centers_iterated = SID_output.neuron_centers_ini(SID_output.indices_in_orig(1:end-1), :);
SID_output.template_iterated = template_;
opts_temp.warm_start = [];
clear sensor_movie;
disp([datestr(now, 'YYYY-mm-dd HH:MM:SS') ': ' 'SID model optimization completed']);

Expand Down Expand Up @@ -614,6 +621,7 @@
hold on;
imagesc(squeeze(max(nmf_mip, [], 3)));
scatter(SID_output.neuron_centers_iterated(:,2), SID_output.neuron_centers_iterated(:,1), 'r.');
%scatter(SID_output.neuron_centers_ini(:,2), SID_output.neuron_centers_ini(:,1), 'r.');
hold off;
axis image;
axis ij;
Expand Down Expand Up @@ -720,7 +728,7 @@
axis image;
colorbar();
subplot(3,1,3);
plot((1:size(SID_output.timeseries_iterated,2))/15, SID_output.timeseries_iterated(ix,:));
plot((1:size(SID_output.timeseries_iterated,2)), SID_output.timeseries_iterated(ix,:));
title(['Neuron candidate ' num2str(ix)]);

%% Delete cached psf file
Expand All @@ -731,4 +739,6 @@

%%
disp([datestr(now, 'YYYY-mm-dd HH:MM:SS') ': ' 'main_nnmf_SID() returning'])
%end

%%
end
24 changes: 12 additions & 12 deletions src/generate_template.m
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
function template=generate_template(centers,H,std_image,thres,shape)
% GENERATE_TEMPLATE computes for each center of a putative neuron its
% template, a binary image fixing the area, where the LFM signature of the
%putative neuron is to be expected.
% template, a binary image that defines the area where the LFM signature of the
% putative neuron is to be expected.
%
% Input:
% centers... centroid of the putative neurons
% H... point spread function of the LFM
% std_image... standard deviation image of the LFM_movie
% thres... threshold for the estimation of the radius in which an
% LFM signature is to be expected. The smaller 'thres'
% the greater the radius.
% shape... boolean; if true the shape of the area, where the LFM
% signature of the putative neuron is to be expected, has
% the shape of a disk, otherwise the shape of a square.
% centers Centroids of the putative neurons
% H Point spread function of the LFM
% std_image Standard deviation image of the LFM_movie
% thres Threshold for the estimation of the radius in which an
% LFM signature is to be expected. The smaller 'thres'
% the greater the radius.
% shape boolean; if true the shape of the area, where the LFM
% signature of the putative neuron is to be expected, has
% the shape of a disk, otherwise the shape of a square.
%
% Output:
% template... Library of templates of the putative neurons
% template Library of templates of the putative neurons

if nargin<4
thres=0.03;
Expand Down
31 changes: 15 additions & 16 deletions src/iterate_cluster.m
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
function [centroid, ID, centers]=iterate_cluster(centers_cell,N,radius,dim)
% ITERATE_CLUSTER: Algorithm clusters the elements of the cell array
% centers_cell, such that the clusters have a maximal size of
% radius and each of their elements is from a different cell of
% centers_cell.
function [centroid, ID, centers] = iterate_cluster(centers_cell, N, radius, dim)
% ITERATE_CLUSTER clusters the elements of the cell array centers_cell,
% such that the clusters have a maximal radius according to input argument "radius"
% and each of their elements is from a different cell of centers_cell.
%
% Input:
% centers_cell... cell array of array of size [m,3]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% centers_cell cell array of array of size [m,3]
% N number of iterations to perform
% radius max radius of cluster
% dim vector of relative voxel edge lengths along the three dimensions

centroid =[];
for jj=1:size(centers_cell,2)
centroid=[centroid' centers_cell{jj}']';
end


for nn=1:N
centers=[];
centroid_=[];
centers_per_component_=centers_cell;
for ii=1:size(centroid,1)
centers{ii}=[];
centers{ii}=[]; %#ok<AGROW>
for jj=1:size(centers_per_component_,2)
if ~isempty(centers_per_component_{jj})
rnd_ind=randperm(size(centers_cell{jj},1));
[a,n]=min(sum((dim.*(centers_per_component_{jj}(rnd_ind,:)-[centroid(ii,:)])).^2,2));
[a, n] = min(sum((dim .* (centers_per_component_{jj}(rnd_ind,:) - centroid(ii,:))) .^2, 2));
if a<radius^2
centers{ii}=[centers{ii}' centers_per_component_{jj}(rnd_ind(n),:)']';
centers_per_component_{jj}(rnd_ind(n),:)=inf*[1 1 1];
Expand All @@ -33,8 +34,8 @@
end
idx=randperm(size(centroid_,1));
centroid=centroid_(idx,:);
size(centroid)
disp(nn);
%disp(size(centroid));
%disp(nn);
end

[~,n] = sort(sum(centroid,2));
Expand All @@ -44,7 +45,7 @@
for ii=1:size(centroid,1)
for jj=1:size(centers_per_component_,2)
if ~isempty(centers_per_component_{jj})
a=min(sum((dim.*(centers_cell{jj}-[centroid(ii,:)])).^2,2));
a = min(sum((dim .* (centers_cell{jj} - centroid(ii,:))) .^2, 2));
if a<radius^2
ID(ii,jj)=true;
end
Expand All @@ -54,7 +55,5 @@
ID=ID(n,:);
end


centroid = centroid(n,:);

end
end
37 changes: 17 additions & 20 deletions src/merge_filters.m
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
function [forward_model,timeseries,template,indices_in_orig]...
=merge_filters(forward_model,timeseries...
,template,indices_in_orig,opts)
% MERGE_FILTERS merges components of the SID-nnmf, that overlap over 30% in
% their templates and have a correlation of more than opts.limit (default:
% 0.9).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargin<5
opts=struct;
end

if ~isfield(opts,'limit')
opts.limit=0.90;
end

if ~isfield(opts,'bg_sub')
opts.bg_sub=true;
end

function [forward_model, timeseries, template, indices_in_orig] = ...
merge_filters(forward_model, timeseries, template, indices_in_orig, opts)
% MERGE_FILTERS merges components of the SID-nnmf, that overlap by more than 30% in
% their templates and have a correlation of more than opts.limit in their temporal signals (default: 0.9)

if nargin<5
opts=struct;
end

if ~isfield(opts,'limit')
opts.limit=0.90;
end

if ~isfield(opts,'bg_sub')
opts.bg_sub=true;
end

corr_m = corrcoef(timeseries')-eye(size(timeseries,1));
corr_m = corr_m(1:end-opts.bg_sub,1:end-opts.bg_sub);

Expand Down
30 changes: 15 additions & 15 deletions src/segment_component.m
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
function centers = segment_component(component, threshold)

component=component/max(component(:));
component(isnan(component))=0;
component=component-threshold;
component(component<0)=0;
centers=[];
B=reshape(component,[],1);
beads=bwconncomp((component));
for k=1:beads.NumObjects
qu=B(beads.PixelIdxList{1,k});
q=sum(B(beads.PixelIdxList{1,k}));
[a,b,c]=ind2sub(size(component),beads.PixelIdxList{1,k});
centers(k,:)=([a,b,c]'*qu/q)';
end
component=component/max(component(:));
component(isnan(component))=0;
component=component-threshold;
component(component<0)=0;
centers=[];

B=reshape(component,[],1);
beads=bwconncomp((component));
for k=1:beads.NumObjects
qu=B(beads.PixelIdxList{1,k});
q=sum(B(beads.PixelIdxList{1,k}));
[a,b,c]=ind2sub(size(component),beads.PixelIdxList{1,k});
centers(k,:)=([a,b,c]'*qu/q)'; %#ok<AGROW>
end

end
Loading

0 comments on commit 91c1efd

Please sign in to comment.