processDFF_Isopull.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. clear;
  2. %% IMPORTANT NOTES
  3. % Voltage conversion equation: Force = m * ([Voltage] - b)
  4. % These constants will change if you use a different pull module or
  5. % recalibrate it (use Check_Pull_Calibration_Values script to recalculate)
  6. % paper position for saving .pdfs
  7. % x = -0.8, y = 1.0, width = 11.0, height = 7.1875
  8. %% Set Variables
  9. fr = 29.6; %Framerate
  10. frames = 10000; %Number of Frames in the Session
  11. m = 25.045; %Contants from Pull Calibration Script:
  12. b = 1.628; %Force = m * ([Voltage] - b)
  13. % m = 21.973, b = 0.049 (Newer values, but recalibrate for future experiments)
  14. %% Select one h5 file:
  15. foldername = uigetdir('C:\','Choose folder to save results');
  16. [filename, pathname] = uigetfile('*.h5', 'Pick a Sync Episode file');
  17. if isequal(filename,0) || isequal(pathname,0)
  18. disp('User pressed cancel')
  19. return
  20. else
  21. disp(['User selected ', fullfile(pathname, filename)])
  22. end
  23. fnam = [pathname,filename];
  24. dataOut = ThorsyncLoadSimple(fnam);
  25. time = dataOut.time;
  26. trial = dataOut.FrameIn;
  27. time(trial(1,:) == 0) = [];
  28. Frame_In = uniquetol(time', 0.0001) - 0.05;
  29. pTA = 2;
  30. end_frames = frames - 1;
  31. lower = (15/m) + b;
  32. upper = (18/m) + b;
  33. three = (3/m) + b;
  34. nine = (9/m) + b;
  35. %% Extract and Classify Pulls from Thorsync File
  36. [pks, locs, widths] = findpeaks(dataOut.Pull, dataOut.time, 'MinPeakHeight', three, 'MinPeakDistance', 0.4, 'MaxPeakWidth', 1); %Finds peaks and their corresponding locations for pulls over 3 grams at least 0.4s apart
  37. peakTimes = locs;
  38. peakFrames = peakTimes * fr;
  39. pks = pks(1: length(peakTimes));
  40. NumPeaks = length(peakFrames);
  41. trial_start = 1:1:NumPeaks;
  42. trial_end = 1:1:NumPeaks;
  43. widthFrames = (widths/2) * fr;
  44. widthFrames_full = widths * fr;
  45. avg_pull_frame = mean(widthFrames_full);
  46. avg_pull_frame = round(avg_pull_frame, 0);
  47. if avg_pull_frame == 0
  48. avg_pull_frame = 1;
  49. end
  50. intFrames = round(peakFrames);
  51. intTimes = round((peakFrames/29.6) * 100000);
  52. avg_pull_time = round((avg_pull_frame/29.6) * 100000);
  53. if avg_pull_time == 0
  54. avg_pull_time = 1;
  55. end
  56. for i = 1:NumPeaks
  57. trial_start(1,i) = peakFrames(1,i) - widthFrames(1,i);
  58. trial_end(1,i) = peakFrames(1,i) + widthFrames(1,i);
  59. end
  60. R_trial_start = floor(trial_start);
  61. R_trial_end = ceil(trial_end);
  62. %Find start and end times of pulls based on the width of the peak
  63. pullFrames = reshape([R_trial_start(:) R_trial_end(:)]', [1, 2* NumPeaks]);
  64. if pullFrames(1,1) < 3 %excludes first trial if there are an insufficient number of pull Frames for it
  65. pullFrames(:,1) = [];
  66. pullFrames(:,1) = [];
  67. pks(:,1) = [];
  68. end
  69. %excludes pulls that are cut off when ThorSync recording stops
  70. pullFrames(pullFrames > end_frames - pTA) = [];
  71. if mod(length(pullFrames), 2) > 0
  72. pullFrames(end) = [];
  73. pks(end) = [];
  74. end
  75. pullForce = m * (pks - b);
  76. save(fullfile(foldername,'pullForce'),'pullForce','-v7.3');
  77. [row, col] = find(pks > lower & pks < upper);
  78. temp = peakTimes;
  79. temp(:,unique(col)) = [];
  80. widthFrames(:,unique(col)) = [];
  81. unsuccessWidth = widthFrames;
  82. unsuccessPeaks = temp * fr;
  83. [row, col] = find(pks > three & pks < nine);
  84. threetonine = peakTimes(:,col);
  85. threetonineFrames = threetonine * fr;
  86. [row, col] = find(pks > nine & pks < lower);
  87. ninetofifteen = peakTimes(:,col);
  88. ninetofifteenFrames = ninetofifteen * fr;
  89. [row, col] = find(pks > upper);
  90. eighteenplus = peakTimes(:,col);
  91. eighteenplusFrames = eighteenplus * fr;
  92. %% Classify Successful and Unsuccessful Peaks based on Thorsync Voltage
  93. trial_start = 1:1:length(unsuccessPeaks);
  94. trial_end = 1:1:length(unsuccessPeaks);
  95. for i = 1:length(unsuccessPeaks)
  96. trial_start(1,i) = unsuccessPeaks(1,i) - unsuccessWidth(1,i);
  97. trial_end(1,i) = unsuccessPeaks(1,i) + unsuccessWidth(1,i);
  98. end
  99. R_trial_start = floor(trial_start);
  100. R_trial_end = ceil(trial_end);
  101. unsuccessFrames = reshape([R_trial_start(:) R_trial_end(:)]', [1, 2* length(unsuccessPeaks)]);
  102. if unsuccessFrames(1,1) < 3 %excludes first trial if there are an insufficient number of pull Frames for it
  103. unsuccessFrames(:,1) = [];
  104. unsuccessFrames(:,1) = [];
  105. end
  106. %excludes pulls that are cut off when ThorSync recording stops
  107. unsuccessFrames(unsuccessFrames > frames - pTA) = [];
  108. if mod(length(unsuccessFrames), 2) > 0
  109. unsuccessFrames(end) = [];
  110. end
  111. [pks, locs, widths] = findpeaks(dataOut.Pull, dataOut.time, 'MinPeakHeight', lower , 'MinPeakDistance', 0.4, 'MaxPeakWidth', 1);
  112. if pks > 0
  113. for i = 1:length(pks)
  114. if pks(:,i) > upper
  115. locs(:,i) = 1;
  116. widths(:,i) = 1;
  117. end
  118. end
  119. locs(locs == 1) = [];
  120. widths(widths == 1) = [];
  121. if locs > 0
  122. successPeaks = locs * fr;
  123. successWidth = (widths/2) * fr;
  124. trial_start = 1:1:length(locs);
  125. trial_end = 1:1:length(locs);
  126. for i = 1:length(locs)
  127. trial_start(1,i) = successPeaks(1,i) - successWidth(1,i);
  128. trial_end(1,i) = successPeaks(1,i) + successWidth(1,i);
  129. end
  130. R_trial_start = floor(trial_start);
  131. R_trial_end = ceil(trial_end);
  132. successFrames = reshape([R_trial_start(:) R_trial_end(:)]', [1, 2* length(locs)]);
  133. if successFrames(1,1) < 3 %excludes first trial if there are an insufficient number of pull Frames for it
  134. successFrames(:,1) = [];
  135. successFrames(:,1) = [];
  136. end
  137. %excludes pulls that are cut off when ThorSync recording stops
  138. successFrames(successFrames > frames - pTA) = [];
  139. if mod(length(successFrames), 2) > 0
  140. successFrames(end) = [];
  141. end
  142. else
  143. successPeaks = [];
  144. successFrames = [];
  145. end
  146. else
  147. successPeaks = [];
  148. successFrames = [];
  149. end
  150. %outputs an array of pulls between 15 and 18 grams
  151. for i = 1:NumPeaks
  152. mean_start(1,i) = intFrames(1,i) - avg_pull_frame;
  153. mean_end(1,i) = intFrames(1,i) + avg_pull_frame;
  154. time_start(1,i) = intTimes(1,i) - avg_pull_time;
  155. time_end(1,i) = intTimes(1,i) + avg_pull_time;
  156. end
  157. meanFrames = reshape([mean_start(:) mean_end(:)]', [1, 2*NumPeaks]);
  158. meanTimes = reshape([time_start(:) time_end(:)]', [1, 2*NumPeaks]);
  159. if meanFrames(1,1) < 3
  160. meanFrames(:,1) = [];
  161. meanFrames(:,1) = [];
  162. end
  163. meanFrames(meanFrames > end_frames) = [];
  164. if mod(length(meanFrames), 2) > 0
  165. meanFrames(end) = [];
  166. end
  167. if meanTimes(1,1) < (3/29.6 * 100000)
  168. meanTimes(:,1) = [];
  169. meanTimes(:,1) = [];
  170. end
  171. meanTimes(meanTimes > (end_frames/29.6 * 100000)) = [];
  172. if mod(length(meanTimes), 2) > 0
  173. meanTimes(end) = [];
  174. end
  175. window = 5; %# of seconds in each trial
  176. Frame_In = round(Frame_In * 100000);
  177. Frame_Out = Frame_In + (window * 100000);
  178. Frame_times = reshape([Frame_In(:) Frame_Out(:)]', [1, 2*length(Frame_In)]);
  179. Frame_times(Frame_times > ((end_frames/29.6)*100000)) = [];
  180. if mod(length(Frame_times), 2) > 0
  181. Frame_times(end) = [];
  182. end
  183. %% Initialize variables for Correlations and Classification
  184. dir = '';
  185. autoClassifyNeurons = true;
  186. pTA = 2; % frames before and after pull that should be included in the average
  187. [newNeurons,fluorescenceData,classifications,binaryPullTimes,pulls,options] = processDFFVars(dir,pullFrames,fr,autoClassifyNeurons,pTA);
  188. % Unpack Data from function call
  189. numFrames = options.numFrames;
  190. numNeurons = options.numNeurons;
  191. xpoints = options.xpoints;
  192. framerate = options.framerate;
  193. %
  194. Fdf = fluorescenceData.Fdf;
  195. Cd = fluorescenceData.Cd;
  196. Sp = fluorescenceData.Sp;
  197. if locs > 0
  198. binarySuccessTimes = zeros(1,numFrames);
  199. for i = 1:2:length(successFrames)
  200. binarySuccessTimes(successFrames(i) - pTA:successFrames(i+1) + pTA) = 1;
  201. end
  202. else
  203. binarySuccessTimes = [];
  204. end
  205. binaryUnsuccessTimes = zeros(1,numFrames);
  206. for i = 1:2:length(unsuccessFrames)
  207. binaryUnsuccessTimes(unsuccessFrames(i) - pTA:unsuccessFrames(i+1) + pTA) = 1;
  208. end
  209. Cd_N = [];
  210. for i = 1:numNeurons
  211. Cd_N(i,:) = (Cd(i,:) - min(Cd(i,:))) / (max(Cd(i,:)) - min(Cd(i,:)));
  212. end
  213. fulldff = Cd_N';
  214. fullCd = Cd;
  215. activeCd = Cd_N(classifications.active,:);
  216. quiescentCd = Cd_N(classifications.quiescent,:);
  217. indiscCd = Cd_N(classifications.indisc,:);
  218. cells = cat(1, classifications.active, classifications.quiescent, classifications.indisc);
  219. cells = sortrows(cells, 'ascend');
  220. Cd_N = Cd_N(cells,:);
  221. Cd = Cd(cells,:);
  222. numNeurons = size(Cd_N,1);
  223. numPulls = length(peakFrames);
  224. peakFrames_2 = round(peakFrames');
  225. n = 10;
  226. peakFrames(peakFrames < n + 1) = [];
  227. start = 1:1:numPulls;
  228. finish = 1:1:numPulls;
  229. for i = 1:numPulls % modify it to look at n frames before and after pull
  230. start(1,i) = peakFrames_2(i,1) - n;
  231. finish(1,i) = peakFrames_2(i,1) + n;
  232. end
  233. pullFrames_2 = reshape([start(:) finish(:)]', [1, 2* numPulls]);
  234. pullFrames_2(pullFrames_2 > length(Cd_N)) = [];
  235. if mod(length(pullFrames_2), 2) > 0
  236. pullFrames_2(end) = [];
  237. end
  238. behavior = cell(1, length(meanFrames) / 2);
  239. activity = cell(numNeurons, length(meanFrames) / 2);
  240. for i = 1:numNeurons
  241. for j = 1:2:length(meanFrames)%j = 1:2:length(Frame_times)
  242. behavior{1,j} = dataOut.Pull(1, meanTimes(j) : meanTimes(j+1));
  243. activity{i,j} = Cd_N(i, pullFrames_2(j) : pullFrames_2(j+1));
  244. end
  245. end
  246. activity(cellfun('isempty',activity)) = [];
  247. activity = reshape(activity, [numNeurons, length(meanFrames)/2]);
  248. behavior(cellfun('isempty',behavior)) = [];
  249. activity_cat = cell2mat(activity);
  250. % [coeff,score,latent,tsquared,explained,mu] = pca(activity_cat);
  251. %Preliminary pca analysis for activity
  252. for i = 1:numNeurons
  253. for j = 1:size(behavior,2) - 1
  254. temp = corrcoef(behavior{1,j}, behavior{1,j+1});
  255. pull_corr{1,j} = temp(1,2);
  256. end
  257. end
  258. for i = 1:numNeurons - 1
  259. temp2 = corrcoef(activity_cat(i,:), activity_cat(i+1,:));
  260. activity_corr(i,:) = temp2(1,2);
  261. end
  262. avg_pull_corr = mean(abs(cell2mat(pull_corr)));
  263. avg_act_corr = mean(activity_corr);
  264. Correlations = struct('pull_corr',avg_pull_corr, 'activity_corr', avg_act_corr);
  265. %% Code for activity correlation between successful pulls and previous or following pull
  266. % [~, index_successPeaks, index_peakTimes] = intersect(successPeaks',peakFrames','rows');
  267. % successloc = zeros(1, length(peakTimes));
  268. %
  269. % successloc(:,index_peakTimes) = 1;
  270. % successloc(1,1) = 0;
  271. %
  272. % for i = 1:size(behavior,2) - 1
  273. % if successloc(:,i) == 1
  274. % temp = corrcoef(behavior{1,i}, behavior{1,i-1});
  275. % suc_prevcorr{1,i} = temp(1,2);
  276. % else
  277. % temp = NaN;
  278. % suc_prevcorr{1,i} = NaN;
  279. % end
  280. % end
  281. %
  282. % for i = 1:size(behavior,2) - 1
  283. % if successloc(:,i) == 1
  284. % temp = corrcoef(behavior{1,i}, behavior{1,i+1});
  285. % suc_postcorr{1,i} = temp(1,2);
  286. % else
  287. % temp = NaN;
  288. % suc_postcorr{1,i} = NaN;
  289. % end
  290. % end
  291. %
  292. % avg_presucc_corr = nanmean(abs(cell2mat(suc_prevcorr)));
  293. % avg_postsucc_corr = nanmean(abs(cell2mat(suc_postcorr)));
  294. %
  295. %
  296. % x1 = [1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]';
  297. % temp = repmat(x1, size(activity,2));
  298. % x1 = temp(:,1);
  299. % x2 = [0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0]';
  300. % temp = repmat(x2, size(activity,2));
  301. % x2 = temp(:,1);
  302. % x3 = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1]';
  303. % temp = repmat(x3, size(activity,2));
  304. % x3 = temp(:,1);
  305. %
  306. % activity_cat = cell2mat(activity);
  307. %
  308. % coefficients = cell(numNeurons,1);
  309. % for i = 1:numNeurons
  310. % x4 = activity_cat(i,:)';
  311. % tbl = table(x1,x2,x3,x4, 'VariableNames', {'pre', 'pull', 'post', 'activity'});
  312. % mdl = fitlm(tbl);
  313. % coefficients{i,1} = mdl.Coefficients;
  314. % %r_square{i,1} = mdl.Rsquared;
  315. % end
  316. %% Preliminary Analysis of Peaks during Pulls vs Queiscent Periods
  317. flourFrames = cell(1,numNeurons);
  318. behaviorPeaks = zeros(1,numNeurons);
  319. nonBehaviorPeaks = zeros(1,numNeurons);
  320. SbehaviorPeaks = zeros(1,numNeurons);
  321. UbehaviorPeaks = zeros(1,numNeurons);
  322. allPeaks = zeros(1,numNeurons);
  323. for i = 1:numNeurons
  324. ROI = Cd_N(i,:)';
  325. [pks, locs, widths] = findpeaks(ROI, xpoints/framerate, 'MinPeakHeight', 0.1);
  326. temp = locs * fr;
  327. temp2 = locs * fr;
  328. temp2 = locs * fr;
  329. flourFrames{1,i} = round(temp,0);
  330. for k = 1:length(locs)
  331. if binaryPullTimes(1,flourFrames{1,i}(1,k)) > 0
  332. temp(1,k) = 1;
  333. else
  334. temp(1,k) = 0;
  335. end
  336. end
  337. for k = 1:length(locs)
  338. if isempty(binarySuccessTimes)
  339. temp2(1,k) = 0;
  340. elseif binarySuccessTimes(1,flourFrames{1,i}(1,k)) > 0
  341. temp2(1,k) = 1;
  342. end
  343. end
  344. for k = 1:length(locs)
  345. if binaryUnsuccessTimes(1,flourFrames{1,i}(1,k)) > 0
  346. temp2(1,k) = 1;
  347. end
  348. end
  349. behaviorPeaks(1,i) = length(temp(temp == 1));
  350. nonBehaviorPeaks(1,i) = length(temp(temp == 0));
  351. SbehaviorPeaks(1,i) = length(temp2(temp2 == 1));
  352. UbehaviorPeaks(1,i) = length(temp2(temp2 == 1));
  353. allPeaks(1,i) = length(temp);
  354. end
  355. peakPercent = behaviorPeaks ./ allPeaks;
  356. peakPercent(allPeaks < 5) = [];
  357. [plotPercent,index] = sortrows(peakPercent', 'descend');
  358. x = 1:length(peakPercent);
  359. % figure
  360. % scatter(x, plotPercent)
  361. behavior_ca = struct('behaviorPeaks', behaviorPeaks, 'nonBehaviorPeaks', nonBehaviorPeaks, 'SbehaviorPeaks', SbehaviorPeaks, 'UbehaviorPeaks', UbehaviorPeaks, 'allPeaks', allPeaks);
  362. % Choose which data we want to use for everything.
  363. dff = Cd_N';
  364. %Cd_N = normalized, Cd = not normalized
  365. figure;
  366. K = heatmap(Cd);
  367. K.GridVisible = 'off';
  368. K.Colormap = hot;
  369. %% Save files for segmentation
  370. save(fullfile(foldername,'Cd_N'),'Cd_N','-v7.3');
  371. save(fullfile(foldername,'classifications'),'classifications','-v7.3');
  372. save(fullfile(foldername,'activeCd'),'activeCd','-v7.3');
  373. save(fullfile(foldername,'quiescentCd'),'quiescentCd','-v7.3');
  374. save(fullfile(foldername,'indiscCd'),'indiscCd','-v7.3');
  375. save(fullfile(foldername,'peakFrames'),'peakFrames','-v7.3');
  376. save(fullfile(foldername,'successPeaks'),'successPeaks','-v7.3');
  377. save(fullfile(foldername,'unsuccessFrames'),'unsuccessPeaks','-v7.3');
  378. save(fullfile(foldername,'threetonineFrames'),'threetonineFrames','-v7.3');
  379. save(fullfile(foldername,'ninetofifteenFrames'),'ninetofifteenFrames','-v7.3');
  380. save(fullfile(foldername,'eighteenplusFrames'),'eighteenplusFrames','-v7.3');
  381. save(fullfile(foldername,'behavior_ca'),'behavior_ca','-v7.3');
  382. save(fullfile(foldername,'Correlations'),'Correlations','-v7.3');
  383. %% Start by looking at all neurons plotted on same plot and stacked
  384. % Colors
  385. co = ...
  386. [0 0.4470 0.7410;
  387. 0.8500 0.3250 0.0980;
  388. 0.9290 0.6940 0.1250;
  389. 0.4940 0.1840 0.5560;
  390. 0.4660 0.6740 0.1880;
  391. 0.3010 0.7450 0.9330;
  392. 0.6350 0.0780 0.1840];
  393. %% Plot shows all neuron plots stacked.
  394. figure;
  395. plot(xpoints/framerate, bsxfun(@plus,dff,0:numNeurons-1))
  396. hold on
  397. p = patch(xpoints/framerate, binaryUnsuccessTimes * numNeurons, 'k');
  398. set(p, 'FaceAlpha', 0.2)
  399. set(p, 'EdgeAlpha', 0)
  400. if successPeaks > 0
  401. m = patch(xpoints/framerate, binarySuccessTimes * numNeurons, 'r');
  402. set(m, 'FaceAlpha', 0.4)
  403. set(m, 'EdgeAlpha', 0)
  404. end
  405. nvs = gca;
  406. nvs.XTick = 0:50:max(xpoints/framerate);
  407. nvs.YTick = 0:10:numNeurons;
  408. if framerate ~= 1
  409. xlabel('Time (seconds)');
  410. else
  411. xlabel('Frame');
  412. end
  413. ylabel('Neuron ID');
  414. title('All Neurons Stacked');
  415. set(gca,'fontsize',24)
  416. set(gca,'LooseInset',get(gca,'TightInset'));
  417. saveas(gcf,strcat(foldername,'/dff','.fig'));
  418. %% Population, Active, Quiescent, Indiscriminant Averages
  419. active = classifications.active;
  420. quiesc = classifications.quiescent;
  421. indisc = classifications.indisc;
  422. figure;
  423. plot(xpoints/framerate, mean(fulldff,2)+3, 'col', co(1,:)) % Population Average
  424. hold on;
  425. plot(xpoints/framerate, mean(fulldff(:,active),2)+2, 'col', co(2,:)) % Active Average
  426. plot(xpoints/framerate, mean(fulldff(:,quiesc),2)+1, 'col', co(3,:)) % Quiescent Average
  427. plot(xpoints/framerate, mean(fulldff(:,indisc),2), 'col', co(4,:)) % Indiscriminant Active Average
  428. lgd = legend(['Population Average (n=' num2str(length(newNeurons)) ')'], ...
  429. ['Active Average (n=' num2str(length(active)) ')'], ...
  430. ['Quiescent Average (n=' num2str(length(quiesc)) ')'], ...
  431. ['Indiscriminant Average (n=' num2str(length(indisc)) ')'], ...
  432. 'Location', 'eastoutside');
  433. % plot(xpoints/framerate, mean(dffActive,2)+2,'color', [0,0,0]+0.8)
  434. % plot(xpoints/framerate, mean(dffActive,2)+2, 'col', co(2,:)) % Active Average
  435. lgd.FontSize = 24;
  436. p = patch(xpoints/framerate, binaryPullTimes * 4, 'b');
  437. set(p, 'FaceAlpha', 0.4)
  438. set(p, 'EdgeAlpha', 0) % Pull Bars
  439. set(gca,'YTick',[])
  440. xlabel('Time (seconds)');
  441. set(gca,'fontsize',24)
  442. set(gca,'LooseInset',get(gca,'TightInset'));