-
Notifications
You must be signed in to change notification settings - Fork 0
/
organoidCorrelation.m
417 lines (327 loc) · 12.1 KB
/
organoidCorrelation.m
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
%% Organoid Project - Correlational Analysis
% author: Tim Sit
% Last Update: 20180508
% For The Organoid Project; data recorded by Dr. Susanna Mierau and Stefano
% assume data loaded and spikes extraced using the main script
% organoidProject.m
%% Calculation of correlation
% choice of time bin will be critical here!
spikes = a;
method = 'correlation';
downSample = 0;
lag = 1;
adjM = getAdjM(spikes, method, downSample, lag);
%% Spike tiling coefficient method to find correlation
% find spike times (in seconds)
electrode_1 = spikeMatrix(:, 19);
electrode_2 = spikeMatrix(:, 20);
N1v = sum(electrode_1);
N2v = sum(electrode_2);
Time = [1 / fs, length(spikeMatrix) / fs];
spike_times_1 = find(electrode_1 == 1) / fs;
spike_times_2 = find(electrode_2 == 1) / fs;
% test out for a pair of spike trains
dtv = 0.01; % in seconds, the delay time to look for conincidental spikes
tileCoef = sttc(N1v, N2v, dtv, Time, spike_times_1, spike_times_2);
%% tiling coefficient over all electrode pairs
% this will take a while...
method = 'tileCoef';
downSample = 0;
lag = 0.04;
adjM = getAdjM(spikeMatrix, method, downSample, lag);
%% Plot Adacenecy matrix
figure
h = imagesc(adjM);
% x and y axis labels
xlabel('Electrode')
ylabel('Electrode')
% make NaN values white
% set(h, 'AlphaData', ~isnan(adjM))
yticks([1, 10:10:60])
xticks([1, 10:10:60])
aesthetics
set(gca,'TickDir','out');
cb = colorbar;
ylabel(cb, 'Correlation')
cb.TickDirection = 'out';
caxis([0 1])
cb.Ticks = 0:0.1:1;
set(gca,'TickDir','out');
cb.Location = 'Southoutside';
cb.Box = 'off';
set(gca, 'FontSize', 14)
yLength = 800;
xLength = yLength * 0.90;
set(gcf, 'Position', [100 100 xLength yLength])
%% Network plot!
% need to emphasise on making this asetheticly pleasing
figure
goodElectrodes = 1:60;
% TODO: make sure electrode 31 has no correlation,
% TODO: make sure locations are correct
plotAdj(adjM, goodElectrodes')
yLength = 800;
xLength = yLength * 1.1;
set(gcf, 'Position', [100 100 xLength yLength])
% remember to export it ussing export rather than save as
% or else the aspect ratio will not be correct
%% Relationship between correlation coefficient and distance
% set up distance matrix
gridLength = 8;
electrodePairs = npermutek(1:gridLength, 2);
% remove the 4 corners
corners = [1; 8; 57; 64];
electrodePairs(corners, :) = [ ];
% distanceMatrix = pdist(electrodePairs, 'euclidean'); % nope
distanceMatrix = distmat(electrodePairs);
% remove self connections
distanceMatrix(logical(eye(size(distanceMatrix)))) = NaN;
corrMatrix = adjM;
corrMatrix(logical(eye(size(corrMatrix)))) = NaN;
% plot relationship between distance and corr coef
figure
dotSize = 60;
elecSpacingCoef = 200;
scatter(distanceMatrix(:) * elecSpacingCoef, corrMatrix(:), dotSize, 'filled', 'MarkerFaceAlpha',.5,'MarkerEdgeAlpha',0);
xlabel('Distance (\mum)')
% ylabel('Tiling coeffecient')
ylabel('Correlation')
set(gca, 'FontSize', 14)
set(gca,'TickDir','out');
aesthetics
ylim([0 1])
set(gcf, 'Position', [100, 100, 500 * 16/9, 500])
% plot individual electrodes with different colours
figure
dotSize = 60;
elecSpacingCoef = 200; % they are 200 micro-meters apart (\mu m)
for elec = 1:length(channels)
scatter(distanceMatrix(:, elec) * elecSpacingCoef, corrMatrix(:, elec), dotSize, 'filled', 'MarkerFaceAlpha',.5,'MarkerEdgeAlpha',0);
hold on
end
xlabel('Distance (\mum)')
ylabel('Tiling coefficient')
set(gca, 'FontSize', 14)
set(gca,'TickDir','out');
%% Network spike participation
networkSpikeDur = 10 * 10^-3; % 10 ms
minChannel = 5;
fs = 25000;
[networkSpikeMatrix, networkSpikeTimes] = detectNetworkSpike(spikeMatrix, fs, networkSpikeDur, minChannel);
% visualise participation
figure
imagesc(networkSpikeMatrix')
colormap(flipud(gray)) % black and white, with 1 being black
aesthetics
ylim([1 size(spikeMatrix, 2)])
ax = gca;
ax.YTick = [1 5:5:60];
ylabel('Electrode number')
xlabel('Network spike number')
set(gca, 'FontSize', 14)
set(gca,'TickDir','out')
%% Network spike participation correlation
% requres the networkSpikeMatrix
networkSpikeDur = 5 * 10^-3; % 10 ms
minChannel = 5;
fs = 25000;
[networkSpikeMatrix, networkSpikeTimes] = detectNetworkSpike(spikeMatrix, fs, networkSpikeDur, minChannel);
numChannel = size(spikeMatrix, 2);
combChannel = nchoosek(1:numChannel, 2);
adjM = NaN(numChannel, numChannel);
for channelPairNum = 1:size(combChannel, 1)
electrode_1 = networkSpikeMatrix(:, combChannel(channelPairNum, 1))';
electrode_2 = networkSpikeMatrix(:, combChannel(channelPairNum, 2))';
coefVal = spikePartCoef([electrode_1; electrode_2]);
adjM(combChannel(channelPairNum, 1), combChannel(channelPairNum, 2)) = coefVal;
adjM(combChannel(channelPairNum, 2), combChannel(channelPairNum, 1)) = coefVal;
end
% assign diagonal values to 1, but only if the participated in at least one
% network spike
% adjM(logical(eye(size(adjM)))) = 1;
activeElectrode = find(sum(networkSpikeMatrix >= 1));
% activeElectrode = find(sum(spikeMatrix >= 1));
for atvE = 1:length(activeElectrode)
adjM(activeElectrode(atvE), activeElectrode(atvE)) = 1;
end
%% Visualise network spike participation for each electrode
figure
imagesc(networkSpikeMatrix')
colormap(flipud(gray)) % black and white, with 1 being black
aesthetics
ylim([1 size(spikeMatrix, 2)])
ax = gca;
ax.YTick = [1 5:5:60];
ylabel('Electrode number')
xlabel('Network spike number')
set(gca, 'FontSize', 14)
set(gca,'TickDir','out')
%% Visualise participation correlation
% adjacency matrix
figure
h = imagesc(adjM);
% make NaN values white
set(h, 'AlphaData', ~isnan(adjM))
aesthetics
set(gca,'TickDir','out');
cb = colorbar;
ylabel(cb, 'Correlation')
cb.TickDirection = 'out';
% cb.Ticks = 0:0.1:1;
set(gca,'TickDir','out');
cb.Location = 'Southoutside';
cb.Box = 'off';
set(gca, 'FontSize', 14)
% network plot
figure
goodElectrodes = 1:60;
% TODO: make sure electrode 31 has no correlation,
% TODO: make sure locations are correct
plotAdj(adjM, goodElectrodes')
%% Paper figure: distance distribution plot
% aim of this is to show that we get highly correlated nodes across the
% grid (near and far)
% one way to do this it to plot a histogram of the distances for
% connections with "high correlation", eg. 0.8
% I will utilise the corr matrix and distance matrix
% put them together
% then index only the ones where corr >= 0.8
% then make a histogram of that based on distance
elecSpacingCoef = 200;
distAndCorr = [distanceMatrix(:) * elecSpacingCoef, corrMatrix(:)];
% find distances where correlation > 0.8
distAndHighCorr = distAndCorr(distAndCorr(:, 2) >= 0.8, 1);
figure
histogram(distAndHighCorr, 'EdgeColor', 'white')
aesthetics
ylabel('Number of connections')
xlabel('Distance (\mum)')
xlim([200 1700])
set(gca,'TickDir','out');
set(gcf, 'Position', [100, 100, 500 * 16/9, 500])
set(gca, 'FontSize', 14)
%% Paper figure: distance distribution plot multiple histograms
% same set up, but with medium and low correlation as well
elecSpacingCoef = 200;
distAndCorr = [distanceMatrix(:) * elecSpacingCoef, corrMatrix(:)];
% find high correlation distacne: > 0.8
distAndHighCorr = distAndCorr(distAndCorr(:, 2) >= 0.8, 1);
% find medium correlation distances: 0.3 - 0.8
distAndMedCorr = distAndCorr(distAndCorr(:, 2) >= 0.3 & distAndCorr(:, 2) < 0.8, 1);
% find low correlation distances: < 0.3
distAndLowCorr = distAndCorr(distAndCorr(:, 2) < 0.3, 1);
% one way is to use bar
% https://uk.mathworks.com/matlabcentral/answers/288261-how-to-get-multiple-groups-plotted-with-histogram
edges = 200:200:1800;
h1 = histcounts(distAndHighCorr, edges) / size(distAndCorr, 1) * 100; % make it a proportion value
h2 = histcounts(distAndMedCorr, edges) / size(distAndCorr, 1) * 100;
h3 = histcounts(distAndLowCorr, edges) / size(distAndCorr, 1) * 100;
figure
bar(edges(1:end-1),[h1; h2; h3]', 'EdgeColor','white')
aesthetics
ylabel('Proportion of connections (%)')
xlabel('Distance (\mum)')
% xlim([200 1700])
legend('High correlation (> 0.8)', 'Medium correlation (0.3 - 0.8)', 'Low correlation (< 0.3)')
legend boxoff
set(gca,'TickDir','out');
set(gcf, 'Position', [100, 100, 500 * 16/9, 500])
set(gca, 'FontSize', 14)
colormap(viridis)
print(gcf, '-opengl','-depsc', '-r600', '/media/timothysit/Seagate Expansion Drive1/The_Organoid_Project/testHist.eps')
% another way is to make transparent histograms
% http://desk.stinkpot.org:8080/tricks/index.php/2006/07/how-to-make-a-transparent-histogram-in-matlab/
figure
histogram(distAndHighCorr, 'EdgeColor', 'white')
h = findobj(gca,'Type','patch');
set(h,'FaceColor','r','EdgeColor','w','facealpha',0.75);
hold on
histogram(distAndMedCorr, 'EdgeColor', 'white')
h = findobj(gca,'Type','patch');
set(h,'facealpha',0.75);
aesthetics
legend('High', 'Medium')
legend boxoff
%% Paper figure: distance distribution plot with trendline
% the end product to aim for here is to have just three lines with the
% histfit, and also the data points to show the fit
% set up distance matrix
gridLength = 8;
electrodePairs = npermutek(1:gridLength, 2);
% remove the 4 corners
corners = [1; 8; 57; 64];
electrodePairs(corners, :) = [ ];
% distanceMatrix = pdist(electrodePairs, 'euclidean'); % nope
distanceMatrix = distmat(electrodePairs);
% remove self connections
distanceMatrix(logical(eye(size(distanceMatrix)))) = NaN;
corrMatrix = adjM;
corrMatrix(logical(eye(size(corrMatrix)))) = NaN;
% same set up, but with medium and low correlation as well
elecSpacingCoef = 200;
distAndCorr = [distanceMatrix(:) * elecSpacingCoef, corrMatrix(:)];
% find high correlation distacne: > 0.8
distAndHighCorr = distAndCorr(distAndCorr(:, 2) >= 0.8, 1);
% find medium correlation distances: 0.3 - 0.8
distAndMedCorr = distAndCorr(distAndCorr(:, 2) >= 0.3 & distAndCorr(:, 2) < 0.8, 1);
% find low correlation distances: < 0.3
distAndLowCorr = distAndCorr(distAndCorr(:, 2) < 0.3, 1);
edges = 200:200:1800;
distAndHighCorrCount = histcounts(distAndHighCorr, edges);
distAndMedCorrCount = histcounts(distAndMedCorr, edges);
distAndLowCorrCount = histcounts(distAndLowCorr, edges);
distAndHighCorrProp = histcounts(distAndHighCorr, edges) / size(distAndCorr, 1) * 100; % make it a proportion value
distAndMedCorrProp = histcounts(distAndMedCorr, edges) / size(distAndCorr, 1) * 100;
distAndLowCorrProp = histcounts(distAndLowCorr, edges) / size(distAndCorr, 1) * 100;
% the actual figure
figure
numbins = 8;
fitmethod = 'gamma';
% Low Correlation
h3 = histfit(distAndLowCorr, numbins, fitmethod);
h3Color = [166, 206, 227] / 255;
set(h3(2), 'color', h3Color);
delete(h3(1))
hold on
% Medium Correlation
h2 = histfit(distAndMedCorr, numbins, fitmethod);
h2Color = [178, 223,138] / 255;
set(h2(2),'color', h2Color);
delete(h2(1))
hold on
% High Correlation
h1 = histfit(distAndHighCorr, numbins, fitmethod);
h1Color = [31, 120, 180] / 255;
set(h1(2),'color',h1Color);
% remove the bars
delete(h1(1))
hold on
% labels and legends
ylabel('Number of connections')
xlabel('Distance (\mum)')
aesthetics
% legend({'High correlation (> 0.8)', 'Medium correlation (0.3 - 0.8)', 'Low correlation (< 0.3)'})
% legend boxoff
% overlay scatter
dotSize = 50;
scatter(edges(1:8), distAndHighCorrCount, dotSize, h1Color, 'filled')
scatter(edges(1:8), distAndMedCorrCount, dotSize, h2Color, 'filled')
scatter(edges(1:8), distAndLowCorrCount, dotSize, h3Color, 'filled')
xlim([100 1700])
edges = 200:200:1800;
xticks(edges)
% convert from raw count to proportion
% yt = get(gca, 'YTick');
% set(gca, 'YTick', yt, 'YTickLabel', round(yt/size(distAndCorr, 1) * 100 ) )
% ylabel('Proportion of connections (%)')
% only label lines and not the dots
h = findobj(gca,'Type','line');
legend(h, {'High correlation (> 0.8)', 'Medium correlation (0.3 - 0.8)', 'Low correlation (< 0.3)'})
% legend(h, {'Low correlation (< 0.3)', 'Medium correlation (0.3 - 0.8)', 'High correlation (> 0.8)'})
legend boxoff
lineThickness(3);
set(gca,'TickDir','out');
set(gcf, 'Position', [100, 100, 500 * 16/9, 500])
set(gca, 'FontSize', 14)
%% save directly
print(gcf, '-opengl','-depsc', '-r600', '/media/timothysit/Seagate Expansion Drive1/The_Organoid_Project/figures/paper_figures_first_draft/figure_4/correlation_0503_slice_1_record_2/new_distribution_fits/distribution_gammalfit_high_med_low_slice1_record2_0503_prop.eps')