VideoAnalysis_ChR2.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. clear all;
  2. analyzedlcfiles=0;
  3. %% get data from DeepLabCut files
  4. %for getting data from DLC and timestamps from videos
  5. if analyzedlcfiles
  6. %original videos needed, available upon request. otherwise, use
  7. %pre-generated struct below
  8. ffmpeg_path='C:\FFmpeg\bin';
  9. address=['']; %where are the running files located
  10. files=dir([address,'\\*_*']);
  11. videoaddress=[''];
  12. videofiles=dir([videoaddress,'\\*Ch*']);
  13. for k=1:length(files)
  14. filename=fullfile(files(k).folder,files(k).name);
  15. rat=str2num(files(k).name(6:7)); %rat #
  16. videofile=[videofiles(k).folder '\' videofiles(k).name];
  17. %get timestamp data
  18. [timestamps,xcoordinates,ycoordinates]=AnalyzeDeepLabCutPP(filename,videofile,ffmpeg_path);
  19. VideoData{rat,1}=timestamps;
  20. VideoData{rat,2}=xcoordinates;
  21. VideoData{rat,3}=ycoordinates;
  22. end
  23. save('ChVideoData.mat','VideoData');
  24. else
  25. load('ChVideoData.mat');
  26. end
  27. %%
  28. %how long after reward delivery do we start looking at location?
  29. posttime=15; %10 is default
  30. spreadsheet=importdata('ChVideoKey.xlsx');
  31. spreadsheetrat=spreadsheet.textdata(2:end,1);
  32. for i=1:length(spreadsheetrat)
  33. sprat(i,1)=str2num(spreadsheetrat{i,1}(3:4));
  34. end
  35. lighton(sprat,1)=spreadsheet.data(:,1);
  36. portcoord(sprat,1)=spreadsheet.data(:,2);
  37. portcoord(sprat,2)=spreadsheet.data(:,3);
  38. %cutoff(sprat,1)=spreadsheet.data(:,5);
  39. Colors = load_colors();
  40. trlactivity={[];[];[]};
  41. trldistance={[];[];[]};
  42. address=['/Data/ChR2Behavior'];
  43. files=dir([address,'//*!*']);
  44. for k=1:length(files)
  45. filename=fullfile(files(k).folder,files(k).name);
  46. file=fopen(filename);
  47. L=textscan(file,'%s','Delimiter',':');
  48. fclose('all');
  49. rat=str2num(files(k).name(end-1:end));
  50. if sum(rat==3 | rat==15)==0 %don't analyze rats without videos
  51. %find start of A, start of C, and end of C
  52. Jstrt=find(strcmp('J',L{1,1})); %Cue
  53. Kstrt=find(strcmp('K',L{1,1})); %Sucrose Delivery
  54. Ostrt=find(strcmp('O',L{1,1})); %Port entry times
  55. Pstrt=find(strcmp('P',L{1,1})); %Port durations
  56. Qstrt=find(strcmp('Q',L{1,1})); %Laser stimulations
  57. Xstrt=find(strcmp('X',L{1,1})); %List (marks end of laser stims)
  58. %trial times
  59. choicet=(L{1,1}(Jstrt+2:2:Kstrt-1));
  60. choicetime=[];
  61. for i=1:length(choicet)
  62. medtext=textscan(char(choicet(i,1)),'%f','Delimiter',' ');
  63. ctime=medtext{1,1}(:,1);
  64. choicetime=(cat(1,choicetime,ctime(isnan(ctime)==0)));
  65. end
  66. choicetime(choicetime==0)=[]; %delete 0s
  67. %Sucrose delivery times
  68. sucrosedel=(L{1,1}(Kstrt+2:2:Ostrt-1));
  69. sucrosedeltime=[];
  70. for i=1:length(sucrosedel)
  71. medtext=textscan(char(sucrosedel(i,1)),'%f','Delimiter',' ');
  72. sdtime=medtext{1,1}(:,1);
  73. sucrosedeltime=(cat(1,sucrosedeltime,sdtime(isnan(sdtime)==0)));
  74. end
  75. sucrosedeltime(sucrosedeltime==0)=[]; %delete 0s
  76. %Port entry times
  77. pet=(L{1,1}(Ostrt+2:2:Pstrt-1));
  78. petime=[];
  79. for i=1:length(pet)
  80. medtext=textscan(char(pet(i,1)),'%f','Delimiter',' ');
  81. portentry=medtext{1,1}(:,1);
  82. petime=(cat(1,petime,portentry(isnan(portentry)==0)));
  83. end
  84. removes=petime==0;
  85. petime(petime==0)=[]; %delete 0s
  86. %Port entry durations
  87. durationt=(L{1,1}(Pstrt+2:2:Qstrt-1));
  88. durationtime=[];
  89. for i=1:length(durationt)
  90. medtext=textscan(char(durationt(i,1)),'%f','Delimiter',' ');
  91. duration=medtext{1,1}(:,1);
  92. durationtime=(cat(1,durationtime,duration(isnan(duration)==0)));
  93. end
  94. durationtime(removes)=[]; %delete 0s
  95. pexits=petime(1:length(durationtime))+durationtime;
  96. %Laser stims
  97. ST=(L{1,1}(Qstrt+2:2:Xstrt-1));
  98. STtime=[];
  99. for i=1:length(ST)
  100. medtext=textscan(char(ST(i,1)),'%f','Delimiter',' ');
  101. stime=medtext{1,1}(:,1);
  102. STtime=(cat(1,STtime,stime(isnan(stime)==0)));
  103. end
  104. STtime(STtime==0)=[]; %delete 0s
  105. %Sucrose or water?
  106. latency=[];
  107. for i=1:length(choicetime)
  108. sucrose=find(sucrosedeltime(:,1) > choicetime(i,1),1);
  109. sucrosetime=sucrosedeltime(sucrose);
  110. if sucrosetime
  111. latency(i,1)=sucrosetime-choicetime(i,1)-0.5; %delay is 0.5s
  112. else
  113. latency(i,1)=NaN;
  114. end
  115. end
  116. latency(latency>10)=NaN;
  117. completed=latency>0;
  118. %stim trials
  119. post_stimmed=zeros(length(choicetime),1);
  120. for stim=1:length(STtime)
  121. trialtime=min(choicetime(choicetime>STtime(stim)));
  122. if ~isempty(trialtime)
  123. post_stimmed(choicetime==trialtime)=1;
  124. end
  125. end
  126. %no stim trials
  127. postsuc=zeros(length(choicetime),1);
  128. for suctrial=1:length(sucrosedeltime)
  129. trialtime=min(choicetime(choicetime>sucrosedeltime(suctrial)));
  130. if ~isempty(trialtime)
  131. postsuc(choicetime==trialtime)=1;
  132. end
  133. end
  134. nostim=postsuc==1 & post_stimmed==0;
  135. rdtimes=sucrosedeltime;
  136. cuetimes=choicetime;
  137. petimes=petime;
  138. included_cue_trials=[];
  139. for trial=1:length(rdtimes)
  140. if sum(cuetimes>rdtimes(trial))>0
  141. included_cue_trials(trial,1)=find(cuetimes>rdtimes(trial),1,'first');
  142. end
  143. end
  144. post_stim=post_stimmed(included_cue_trials);
  145. %get coordinates from deeplabcut analysis
  146. timestamps=VideoData{rat,1}-lighton(rat,1); %adjust for when session started in video
  147. xcoordinates=VideoData{rat,2};
  148. ycoordinates=VideoData{rat,3};
  149. %for each cue onset
  150. xypoints={};
  151. xtrial=[];
  152. ytrial=[];
  153. ITI_distance=[];
  154. ITI_dfp=[];
  155. licks_trl=[];
  156. for trial=1:length(cuetimes)
  157. if sum(timestamps>(cuetimes(trial)-0.25) & timestamps<(cuetimes(trial)+0.25))>0
  158. xtrial(trial)=mean(xcoordinates((timestamps>cuetimes(trial)-0.25) & (timestamps<cuetimes(trial)+0.25)));
  159. ytrial(trial)=mean(ycoordinates((timestamps>cuetimes(trial)-0.25) & (timestamps<cuetimes(trial)+0.25)));
  160. elseif sum(timestamps>(cuetimes(trial)-1) & timestamps<(cuetimes(trial)+0.3))>0
  161. xtrial(trial)=mean(xcoordinates((timestamps>cuetimes(trial)-1) & (timestamps<cuetimes(trial)+0.3)));
  162. ytrial(trial)=mean(ycoordinates((timestamps>cuetimes(trial)-1) & (timestamps<cuetimes(trial)+0.3)));
  163. else
  164. xtrial(trial)=NaN;
  165. ytrial(trial)=NaN;
  166. end
  167. %total distance traveled during ITI, and mean distance from port
  168. binsize=0.2; %seconds
  169. if sum(rdtimes<cuetimes(trial))>0 & postsuc(trial)==1
  170. rd_time=max(rdtimes(rdtimes<cuetimes(trial)));
  171. pe_time=max(petimes(petimes<(rd_time+posttime)));
  172. start_time=min([pexits(petimes==pe_time) rd_time+posttime]);
  173. %bins=start_time:binsize:cuetimes(trial);
  174. bins=start_time:binsize:cuetimes(trial)+binsize/2;
  175. bn=0;
  176. bin_t=[];
  177. bin_x=[];
  178. bin_y=[];
  179. bin_dfp=[];
  180. %location for each bin
  181. for bin=1:length(bins)-1
  182. if sum(timestamps>bins(bin) & timestamps<bins(bin+1))>0
  183. bn=bn+1;
  184. bin_t(bn,1)=bins(bin)+binsize/2;
  185. bin_x(bn,1)=mean(xcoordinates(timestamps>bins(bin) & timestamps<bins(bin+1)));
  186. bin_y(bn,1)=mean(ycoordinates(timestamps>bins(bin) & timestamps<bins(bin+1)));
  187. bin_dfp(bn,1)=sqrt((bin_x(bn,1)-portcoord(rat,1))^2+(bin_y(bn,1)-portcoord(rat,2))^2);
  188. end
  189. end
  190. xypoints{trial,1}=cat(2,bin_x,bin_y);
  191. % subplot(5,5,rat);
  192. % hold on;
  193. % plot(bin_dfp);
  194. % xypoints{trial,1}=cat(2,bin_x,bin_y);
  195. % axis([0 25 0 500]);
  196. ITI_dfp(trial)=trapz(bin_t,bin_dfp)/(bin_t(end)-bin_t(1)); %dfp = distance from port
  197. else
  198. ITI_dfp(trial)=NaN;
  199. xypoints{trial,1}=NaN;
  200. end
  201. end
  202. %plot example traces
  203. if rat==8
  204. figure;
  205. %scatterplot of rat locations
  206. xypoints=xypoints(included_cue_trials,:);
  207. xtrial_inc=xtrial(included_cue_trials);
  208. ytrial_inc=ytrial(included_cue_trials);
  209. sucrosexy=cat(1,xypoints{post_stim==0});
  210. maltodextrinxy=cat(1,xypoints{post_stim==1});
  211. opacity=0.1;
  212. dotsize=24;
  213. sucrosetrls=xypoints(post_stim==0);
  214. maltodextrintrls=xypoints(post_stim==1);
  215. %sucrose traces
  216. subplot(1,4,1);
  217. hold on;
  218. s1=scatter(sucrosexy(:,1),sucrosexy(:,2),dotsize,[.4 .4 .4],'filled');
  219. s1.MarkerFaceAlpha = opacity;
  220. sc=scatter(xtrial_inc(post_stim==0),ytrial_inc(post_stim==0),'k','x');
  221. %plot individual trial traces
  222. % for i=1:length(sucrosetrls)
  223. % if sucrosetrls{i,1}
  224. % plot(sucrosetrls{i,1}(:,1),sucrosetrls{i,1}(:,2),'color',Colors('sucrose'));
  225. % end
  226. % end
  227. axis([0 1050 75 750]);
  228. set(gca,'Ydir','reverse')
  229. set(gca,'xtick',[]);
  230. set(gca,'ytick',[]);
  231. plot([950 portcoord(rat,1)],[450 portcoord(rat,2)],'color','k');
  232. legend(sc,'Location at cue onset');
  233. text(955,450,'Reward Port');
  234. title('No laser');
  235. %maltodextrin traces
  236. subplot(1,4,2);
  237. hold on;
  238. s2=scatter(maltodextrinxy(:,1),maltodextrinxy(:,2),dotsize,[0 .3 1],'filled');
  239. s2.MarkerFaceAlpha = opacity;
  240. scatter(xtrial_inc(post_stim==1),ytrial_inc(post_stim==1),[],'k','x')
  241. %plot individual trial traces
  242. % for i=1:length(maltodextrintrls)
  243. % if maltodextrintrls{i,1}
  244. % plot(maltodextrintrls{i,1}(:,1),maltodextrintrls{i,1}(:,2),'color',Colors('maltodextrin'));
  245. % end
  246. % end
  247. set(gca,'Ydir','reverse')
  248. set(gca,'xtick',[]);
  249. set(gca,'ytick',[]);
  250. axis([0 1050 75 750]);
  251. plot([950 portcoord(rat,1)],[450 portcoord(rat,2)],'color','k');
  252. legend(sc,'Location at cue onset');
  253. text(955,450,'Reward Port');
  254. title('Laser');
  255. end
  256. ITI_dfp_inc=ITI_dfp(included_cue_trials)';
  257. mean_distance(rat,1)=nanmean(ITI_dfp_inc(post_stim==0));
  258. mean_distance(rat,2)=nanmean(ITI_dfp_inc(post_stim==1));
  259. completed_trials(rat,1)=length(sucrosedeltime);
  260. end
  261. disp(['File #' num2str(k)]);
  262. end
  263. %% plotting measures
  264. %included rats
  265. yfp=[4 6 10 11 13 14 21];
  266. chr=[1 2 7 8 9 16 18 22 23 24];
  267. colors{2}=[0 0.2 1];
  268. colors{1}=[0.4 0.4 0.4];
  269. groups{1,1}=yfp;
  270. groups{2,1}=chr;
  271. subplot(1,8,5);
  272. hold on;
  273. plot([1 2],mean_distance(yfp,:),'color',[0.4 0.4 0.4]);
  274. errorbar(1,nanmean(mean_distance(yfp,1)),nanste(mean_distance(yfp,1),1),'color',[0.4 0.4 0.4],'marker','o','linewidth',1.5);
  275. errorbar(2,nanmean(mean_distance(yfp,2)),nanste(mean_distance(yfp,2),1),'color',[0 0.3 1],'marker','o','linewidth',1.5);
  276. ylabel('Distance from port during ITI (pixels)');
  277. xticks([1 2]);
  278. xticklabels({'No laser','Laser'});
  279. xtickangle(45);
  280. axis([0.5 2.5 0 400]);
  281. title('YFP');
  282. pval=signrank(mean_distance(yfp,1),mean_distance(yfp,2));
  283. text(1.2,375,['p = ' num2str(round(pval,5))]);
  284. subplot(1,8,6);
  285. hold on;
  286. plot([1 2],mean_distance(chr,:),'color',[0.4 0.4 0.4]);
  287. errorbar(1,nanmean(mean_distance(chr,1)),nanste(mean_distance(chr,1),1),'color',[0.4 0.4 0.4],'marker','o','markerfacecolor',[0.4 0.4 0.4],'linewidth',1.5);
  288. errorbar(2,nanmean(mean_distance(chr,2)),nanste(mean_distance(chr,2),1),'color',[0 0.3 1],'marker','o','markerfacecolor',[0 0.3 1],'linewidth',1.5);
  289. ylabel('Distance from port during ITI (pixels)');
  290. xticks([1 2]);
  291. xticklabels({'No laser','Laser'});
  292. xtickangle(45);
  293. axis([0.5 2.5 0 400]);
  294. title('ChR2');
  295. pval=signrank(mean_distance(chr,1),mean_distance(chr,2));
  296. text(1.2,375,['p = ' num2str(round(pval,5))]);
  297. included=zeros(24,1);
  298. included(chr)=1;
  299. included(yfp)=1;
  300. arclog=zeros(24,1);
  301. arclog(chr)=1;
  302. subplot(1,4,4);
  303. hold on;
  304. difference=(mean_distance(:,2)-mean_distance(:,1))./mean_distance(:,1);
  305. boxplot(difference(included==1),arclog(included==1),'colorgroup',[0 1],'colors',[colors{2};colors{2}],'boxstyle','filled');
  306. scatter(rand([length(yfp) 1])/4+1.2,difference(yfp),55,colors{2});
  307. scatter(rand([length(chr) 1])/4+2.2,difference(chr),55,colors{2},'filled');
  308. axis([0.7 2.74 -0.5 0.5]);
  309. plot([0 3],[0 0],'color','k');
  310. pval=ranksum(difference(yfp),difference(chr));
  311. text(1.2,0.4,['p = ' num2str(round(pval,5))]);
  312. ylabel('Fold-change over no laser');
  313. xticks([1.22 2.22]);
  314. xticklabels({'YFP','ChR2'});
  315. dataforanova=[mean_distance(chr,1) mean_distance(chr,2);mean_distance(yfp,1) mean_distance(yfp,2)];