forked from lucadellasantina/ObjectFinder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcalcNearestNeighbor.m
More file actions
211 lines (185 loc) · 7.56 KB
/
calcNearestNeighbor.m
File metadata and controls
211 lines (185 loc) · 7.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
%% ObjectFinder - Recognize 3D structures in image stacks
% Copyright (C) 2016,2017,2018 Luca Della Santina
%
% This file is part of ObjectFinder
%
% ObjectFinder is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see <https://www.gnu.org/licenses/>.
%
% *ObjectFinder allows to analyze an image volume containing objects
% (i.e. labeling of synaptic structures) with the final goal of segmenting
% each individual object and computing its indivudual properties.*
%
% *This program calculates the Nearest Neighbor distance for a list of cells.
%
% Each row of the reference points' matrix is the [X,Y,Z] coordinates of
% each cell.
%
% The program performs the following main operations:
%
% # Ask user to choose the cell list
% # Calculate NN distance
% # Plot NN distance distributio
%
% *Input:*
%
% * Reference points: one matrix containing coordinates of cells
%
% *Output:*
%
% Plot NN distances as frequency histograms
% Plot Cumulative distribution of NN distances
%% Find nearest neighbor distance for each point in a group
% Each point is an entry in a n x 3 array containing xyz coordinates
[tmpName] = listdlg('PromptString','Select points',...
'SelectionMode','single', 'ListString',who);
tmpVars=who; %list available variables
tmpPts=evalin('base',char(tmpVars(tmpName))); %retrieve selected experiment data
clear tmpName tmpVars;
% TODO: make user define these parameters
%xyum = 0.103; % Olympus PLAPO 60x zoom1
%zum = 0.3; % Olympus PLAPO 60x zoom1
xyum = 0.31; % Olympus PLAPO 20x zoom1
zum = 1; % Olympus PLAPO 20x zoom1
dist3D = false; % Calculate 3d distance?
tmpPtsN = size(tmpPts,1);
for j = tmpPtsN:-1:1
if j == tmpPtsN % dont want to find self
searchBox = (1:tmpPtsN-1);
elseif j>1 && j<tmpPtsN
searchBox = ([1:(j-1) (j+1):tmpPtsN]);
else
searchBox = (2:tmpPtsN);
end
k = searchBox;
xyDistUm = hypot(tmpPts(j,1).*xyum-tmpPts(k,1).*xyum, tmpPts(j,2).*xyum-tmpPts(k,2).*xyum); %vYesSpotsXYZ from imaris is transposed over the xy axis so Dots and vYes.. have switched XY
xyzDistUm= hypot(xyDistUm, (tmpPts(j,3).*zum-tmpPts(k,3).*zum));
if dist3D
NNDist(j)= min(xyzDistUm);
else
NNDist(j)= min(xyDistUm);
end
end
clear xyum zum tmp* searchbox j k ans searchbox searchBox xyDistUm xyzDistUm dist3D;
%% Randomly generate the same amount of points as the given dataset
% generated points must be spaced at least tmpMinDist microns
[tmpName] = listdlg('PromptString','Select points',...
'SelectionMode','single', 'ListString',who);
tmpVars=who; %list available variables
tmpPts=evalin('base',char(tmpVars(tmpName))); %retrieve selected experiment data
clear tmpName tmpVars;
tmpPtsN = size(tmpPts,1);
tmpMax = max(tmpPts);
tmpMin = min(tmpPts);
% TODO: make user define these parameters
%xyum = 0.103; % Olympus PLAPO 60x zoom1
%zum = 0.3; % Olympus PLAPO 60x zoom1
xyum = 0.31; % Olympus PLAPO 20x zoom1
zum = 1; % Olympus PLAPO 20x zoom1
tmpMinDist = 1 / xyum;
dist3D = false; % Calculate 3d distance?
tmpPtsN = size(tmpPts,1);
tmpRndPts = [];
while size(tmpRndPts, 1) < tmpPtsN
% Generate new random point coordinates
tmpRndPt = [randi([tmpMin(1) tmpMax(1)],1,1),...
randi([tmpMin(2) tmpMax(2)],1,1),...
randi([tmpMin(3) tmpMax(3)],1,1)];
if isempty(tmpRndPts)
tmpRndPts = cat(1, tmpRndPts, tmpRndPt);
else
% Check that the new point is not closer than tmpMinDist to any of
% previously generated points.
xyDist = hypot(tmpRndPt(1)-tmpRndPts(:,1), tmpRndPt(2)-tmpRndPts(:,2));
xyzDist= hypot(xyDist, (tmpRndPt(3)-tmpRndPts(:,3)));
if dist3D
if min(xyzDist) > tmpMinDist, tmpRndPts = cat(1, tmpRndPts, tmpRndPt);end
else
if min(xyDist) > tmpMinDist, tmpRndPts = cat(1, tmpRndPts, tmpRndPt);end
end
end
end
randomPts = tmpRndPts;
clear tmp* xyum zum xyDist xyzDist dist3D;
%% Plot distribution properties of nearest neighbor distances
%
[tmpName] = listdlg('PromptString','Empirical NN distances',...
'SelectionMode','single', 'ListString',who);
tmpVars=who; %list available variables
tmpEmpNNDist=evalin('base',char(tmpVars(tmpName))); %retrieve selected experiment data
clear tmpName tmpVars;
[tmpName] = listdlg('PromptString','Random NN distances',...
'SelectionMode','single', 'ListString',who);
tmpVars=who; %list available variables
tmpRndNNDist=evalin('base',char(tmpVars(tmpName))); %retrieve selected experiment data
clear tmpName tmpVars;
%Relative frequency plot
subplot(2,1,1);
hold on;
[n, xout] = hist(tmpRndNNDist, numel(tmpEmpNNDist)/5);% Random data
%[tmpMu, tmpSigma] = normfit(xout); % Fit with normal distribution
bar(xout, n/sum(n)*100, 'FaceColor', [.8 .8 .8], 'EdgeColor', [.3 .3 .3]);
[n, xout] = hist(tmpEmpNNDist, numel(tmpEmpNNDist)/5); % Empirical data
tmpH = bar(xout, n/sum(n)*100, 'FaceColor', 'r', 'EdgeColor', 'r');
tmpH = get(tmpH, 'child');
set(tmpH, 'facea', 0.3);
title('Relative frequency');
ylabel('Relative frequency (%)');
legend('Random', 'Empirical', 'Location', 'NorthEast');
xlim([0 25]);
% Cumulative distribution plot
subplot(2,1,2)
hold on;
[tmpH, tmpStats] = cdfplot(tmpRndNNDist); % Random data
tmpYdata = get(tmpH, 'YData');
set(tmpH, 'YData', tmpYdata*100);
set(tmpH, 'color', [.3 .3 .3]);
[tmpH, tmpStats] = cdfplot(tmpEmpNNDist); % Empirical data
tmpYdata = get(tmpH, 'YData');
set(tmpH, 'YData', tmpYdata*100);
set(tmpH, 'color', 'r');
title('Cumulative distribution');
xlabel('Nearest neighbor distance');
ylabel('Fraction of total (%)');
legend('Random', 'Empirical', 'Location', 'SouthEast');
xlim([0 25]);
set(gcf, 'MenuBar', 'None');
clear tmp* n xout;
%% Plot selected points collapsed on a single xy plane
[tmpName] = listdlg('PromptString','Select points',...
'SelectionMode','single', 'ListString',who);
tmpVars=who; %list available variables
tmpPts=evalin('base',char(tmpVars(tmpName))); %retrieve selected experiment data
clear tmpName tmpVars;
% TODO: make user define these parameters
xySizePx = 2048;
%xyum = 0.103; % Olympus PLAPO 60x zoom1
xyum = 0.31; % Olympus PLAPO 20x zoom1
dotSizePx = 7 / xyum;
figure;
tmpH = scatter(tmpPts(:,1), tmpPts(:,2), dotSizePx);
xlim([1 xySizePx]);
ylim([1 xySizePx]);
axis off;
set(gcf, 'MenuBar', 'None');
clear tmp* n xout;
clear xySizePx dotSizePx xyum tmp*;
%% Changelog
%
% _*Version 1.0* created on 2017-10-03 by Luca Della Santina_
%
% + Calculates the NN distance of a set of empirical points
% + Calculates the NN distance of a randomly distributed set of points
% + Plot NN distance and cumulative distribution of NN distances
% + Calculations can be done either in 2D or 3D
% + Plots the position of points in 2D for visualization