PageRenderTime 57ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/MatlabCode/branches/Greg's Branch/Analysis/WhiteNoise/WNAnalysis.m

http://horwitzlab.googlecode.com/
MATLAB | 1351 lines | 1227 code | 47 blank | 77 comment | 64 complexity | 88de9d76cb6fc4a79c34fe2e4283db7c MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. % Scripts to analyze white noise data
  2. %
  3. % Loading the data
  4. WN=nex2stro;
  5. framerate = WN.sum.exptParams.framerate;
  6. nstixperside = WN.sum.exptParams.nstixperside;
  7. ntrials = length(WN.sum.absTrialNum);
  8. stimonidx = find(strcmp(WN.sum.trialFields(1,:),'stim_on'));
  9. stimoffidx = find(strcmp(WN.sum.trialFields(1,:),'all_off'));
  10. nframesidx = find(strcmp(WN.sum.trialFields(1,:),'num_frames'));
  11. noisetypeidx = find(strcmp(WN.sum.trialFields(1,:),'noise_type'));
  12. sigmaidxs = strmatch('sigma',WN.sum.trialFields(1,:));
  13. hepidx = find(strcmp(WN.sum.rasterCells(1,:),'AD11'));
  14. vepidx = find(strcmp(WN.sum.rasterCells(1,:),'AD12'));
  15. anlgStartTimeidx = find(strcmp(WN.sum.rasterCells(1,:),'anlgStartTime'));
  16. eyestart_t = [WN.ras{:,anlgStartTimeidx}]';
  17. eyesampperiod = 1/WN.sum.analog.storeRates{1};
  18. gammaTable = WN.sum.exptParams.gamma_table;
  19. gammaTable = reshape(gammaTable, length(gammaTable)/3, 3);
  20. gammaTable1 = interp1(linspace(0,255,256),gammaTable,linspace(0,255,65536), 'spline');
  21. invgamma = InvertGamma(gammaTable, 0);
  22. % Reconstructing the M matrix
  23. fundamentals = WN.sum.exptParams.fundamentals;
  24. fundamentals = reshape(fundamentals,[length(fundamentals)/3,3]);
  25. mon_spd = WN.sum.exptParams.mon_spd;
  26. mon_spd = reshape(mon_spd,[length(mon_spd)/3, 3]);
  27. mon_spd = SplineRaw([380:4:780]', mon_spd, [380:5:780]');
  28. M = fundamentals'*mon_spd;
  29. % Getting the background rgb/lms
  30. ridx = find(strcmp(WN.sum.trialFields(1,:),'bkgnd_r'));
  31. gidx = find(strcmp(WN.sum.trialFields(1,:),'bkgnd_g'));
  32. bidx = find(strcmp(WN.sum.trialFields(1,:),'bkgnd_b'));
  33. bkgndRGB = [mode(WN.trial(:,ridx)), mode(WN.trial(:,gidx)), mode(WN.trial(:,bidx))];
  34. bkgndrgb = [gammaTable(bkgndRGB(1)+1,1); gammaTable(bkgndRGB(2)+1,2); gammaTable(bkgndRGB(3)+1,3)];
  35. bkgndlms = M*bkgndrgb;
  36. %%
  37. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  38. % Stuff for looking at spike-triggered averages, etc.
  39. spikename = getSpikenum(WN);
  40. spikeidx = find(strcmp(WN.sum.rasterCells(1,:),spikename));
  41. maxT = 9;
  42. Lgunnoise = WN.trial(:,noisetypeidx) == 1;
  43. Lconenoise = WN.trial(:,noisetypeidx) == 2;
  44. if (sum(Lconenoise) == 0)
  45. whichnoisetype = 1;
  46. disp('Gun noise only');
  47. elseif (sum(Lgunnoise) == 0)
  48. whichnoisetype = 2;
  49. disp('Cone noise only');
  50. else
  51. querystr = ['Which noisetype? 1=gun (n=',num2str(sum(Lgunnoise)),') 2=cone (n=',num2str(sum(Lconenoise)),'): '];
  52. whichnoisetype = input(querystr);
  53. end
  54. tmpstro = WN;
  55. if (whichnoisetype == 2) && (any(Lgunnoise)) % Removing gun noise
  56. disp(['Getting rid of ',num2str(sum(Lgunnoise)),' gun noise trials!']);
  57. tmpstro.ras(Lgunnoise,:) = [];
  58. tmpstro.trial(Lgunnoise,:) = [];
  59. elseif (whichnoisetype == 1) && (any(Lconenoise)) % Removing cone noise
  60. disp(['Getting rid of ',num2str(sum(Lconenoise)),' cone noise trials!']);
  61. tmpstro.ras(Lconenoise,:) = [];
  62. tmpstro.trial(Lconenoise,:) = [];
  63. end
  64. out = getWhtnsStats(tmpstro,maxT,'STCOVmex', {nstixperside^2, 3, maxT}, spikename);
  65. tmpstro = [];
  66. STAs = out{1};
  67. STCs = out{2};
  68. nspikes = out{3};
  69. %%
  70. % Plotting the STA and PCs
  71. if (~exist('mask'))
  72. mask = zeros(nstixperside, nstixperside); % Pixel mask. Someday make a tool to make this non-zero.
  73. end
  74. Lmask = logical(repmat(~mask(:),[3 1]));
  75. PCs = [];
  76. for i = 1:size(STCs,2)
  77. STC = reshape(STCs(:,i), 3*nstixperside^2, 3*nstixperside^2);
  78. subSTC = STC(Lmask, Lmask);
  79. subSTA = STAs(Lmask,i);
  80. P = eye(size(subSTC))-subSTA*inv(subSTA'*subSTA)*subSTA';
  81. subSTC = P*subSTC*P';
  82. [tmp,d] = eig(subSTC);
  83. v = repmat(double(Lmask),[1 size(tmp,2)]);
  84. v(Lmask,:) = tmp;
  85. [newd, idxs] = sort(diag(d));
  86. v = v(:,idxs);
  87. v = v(:,[end end-1 end-2 2]); % Not taking last (trivially zero) vector
  88. PCs = cat(3, PCs, v);
  89. end
  90. % Normalizing images
  91. nstixperside = WN.sum.exptParams.nstixperside;
  92. template = reshape([1:nstixperside^2],nstixperside,nstixperside);
  93. edgepixels = [template(:,1); template(1,[2:end-1])'; template(end,[2:end-1])'; template(:,end)];
  94. if (all(mask(edgepixels)))
  95. PCs = PCs.*max(STAs(:));
  96. else
  97. edgepixelidxs = [edgepixels; edgepixels+nstixperside^2; edgepixels+2*(nstixperside^2)];
  98. PCelements = PCs(edgepixelidxs,:,:);
  99. PCsds = std(PCelements); % One std calculated per PC
  100. PCs = PCs.*repmat(std(STAs(:,1))./PCsds,[size(PCs,1),1,1]);
  101. end
  102. rowidxs = reshape([1:3*nstixperside^2],[nstixperside^2 3]);
  103. maxes = []; mins = [];
  104. imagevectors = [STAs, reshape(PCs,[300 size(PCs,2)*size(PCs,3)])];
  105. for i = 1:3
  106. maxes = [maxes; max(max(imagevectors(rowidxs(:,i),:)))];
  107. mins = [mins; min(min(imagevectors(rowidxs(:,i),:)))];
  108. end
  109. potentialnormfactors = [(1-[.5; .5; .5]-eps)./(maxes-[.5; .5; .5]); (-[.5; .5; .5]+eps)./(mins-[.5; .5; .5])];
  110. % 'eps' in above line is a kludge that is required for avoiding
  111. % out of bounds errors.
  112. potentialnormfactors(potentialnormfactors < 0) = []; % if min > mu or max < mu
  113. normfactor = min(potentialnormfactors);
  114. %muvect = reshape(repmat(bkgndrgb',nstixperside^2,1),nstixperside^2*3,1);
  115. muvect = reshape(repmat([.5 .5 .5],nstixperside^2,1),nstixperside^2*3,1);
  116. % Plotting
  117. figure;
  118. for i = 1:size(STAs,2)
  119. STA = normfactor*(STAs(:,i)-muvect)+muvect;
  120. STA = reshape(STA,[nstixperside nstixperside 3]);
  121. subplot(6,size(STAs,2),i);
  122. image(STA);
  123. set(gca,'XTick',[],'YTick',[]); axis square;
  124. if (i == 1)
  125. ylabel('STA');
  126. end
  127. for j = 1:size(v,2)
  128. PC = normfactor*(PCs(:,j,i)-muvect)+muvect;
  129. PC = reshape(PC,[nstixperside nstixperside 3]);
  130. subplot(6,size(STAs,2), j*size(STAs,2)+i);
  131. image(PC);
  132. set(gca,'XTick',[],'YTick',[]); axis square;
  133. end
  134. STC = reshape(STCs(:,i),[sqrt(length(STCs(:,i))),sqrt(length(STCs(:,i)))]);
  135. STV = reshape(diag(STC),[nstixperside nstixperside 3]);
  136. STV = (STV-mean(STV(:)))./(2*range(STV(:)))+.5;
  137. subplot(6,size(STAs,2),5*size(STAs,2)+i);
  138. image(STV);
  139. set(gca,'XTick',[],'YTick',[]); axis square;
  140. if (i == 1)
  141. ylabel('STV');
  142. end
  143. end
  144. %%
  145. % Significance testing on the STAs, STVs, broken down by color
  146. L = WN.trial(:,noisetypeidx)==1;
  147. mu1idx = find(strcmp(WN.sum.trialFields(1,:),'mu1'));
  148. mu2idx = find(strcmp(WN.sum.trialFields(1,:),'mu2'));
  149. mu3idx = find(strcmp(WN.sum.trialFields(1,:),'mu3'));
  150. sigma1idx = find(strcmp(WN.sum.trialFields(1,:),'sigma1'));
  151. sigma2idx = find(strcmp(WN.sum.trialFields(1,:),'sigma2'));
  152. sigma3idx = find(strcmp(WN.sum.trialFields(1,:),'sigma3'));
  153. muvect = unique(WN.trial(L,[mu1idx mu2idx mu3idx]),'rows')/1000;
  154. sigmavect = unique(WN.trial(L,[sigma1idx sigma2idx sigma3idx]),'rows')/1000;
  155. sigmavect(all(any(sigmavect == 0),2),:) = [];
  156. gausslims = [WN.sum.exptParams.gauss_locut WN.sum.exptParams.gauss_hicut]/1000;
  157. mumat = repmat(reshape(repmat(muvect,nstixperside^2,1),[nstixperside^2*3, 1]),[1,size(STAs,2)]);
  158. sigmamat = repmat(reshape(repmat(sigmavect,nstixperside^2,1),[nstixperside^2* 3, 1]),[1,size(STAs,2)]);
  159. zscoremeans = (STAs-mumat)./(sigmamat*sqrt(nspikes));
  160. % Doing the calculations for the variances
  161. % Only considering one correction factor per dimension
  162. % (assuming variances on green and blue guns are same as red gun)
  163. NPOINTS = 65536;
  164. x = linspace(gausslims(1),gausslims(2),NPOINTS);
  165. Fx = norminv(x)*sigmavect(1);
  166. sigmacorrectionfactor = std(Fx)./sigmavect(1);
  167. for i = 1:size(STCs,2)
  168. STC = reshape(STCs(:,i),[sqrt(length(STCs(:,i))),sqrt(length(STCs(:,i)))]);
  169. STVs(:,i) = diag(STC)./nspikes;
  170. end
  171. muvar = (sigmavect(1)*sigmacorrectionfactor)^2;
  172. sigmavar = muvar*sqrt(2/nspikes);
  173. zscorevars = (STVs-muvar)./sigmavar;
  174. maxzscore = max(abs([zscoremeans(:);zscorevars(:)]));
  175. alpha = 0.01;
  176. crit = norminv(1-alpha,0,1);
  177. % Plotting
  178. figure;
  179. for i = 1:size(STAs,2)
  180. % First STAs
  181. zmat = reshape(zscoremeans(:,i),[nstixperside nstixperside 3]);
  182. for j = 1:3
  183. pmat = logical(abs(zmat(:,:,j))>crit);
  184. im = zmat(:,:,j)./(2*maxzscore)+.5;
  185. im = repmat(im,[1 1 3]);
  186. sigidxs = find(pmat);
  187. im(sigidxs) = .5; % red to .5 where sig. Looks red on dark and cyan on bright.
  188. subplot(6,size(STAs,2),(j-1)*size(STAs,2)+i);
  189. image(im);
  190. axis image;
  191. set(gca,'XTick',[],'YTick',[]);
  192. end
  193. % Then STVs
  194. zmat = reshape(zscorevars(:,i),[nstixperside nstixperside 3]);
  195. for j = 4:6
  196. pmat = logical(abs(zmat(:,:,j-3))>crit);
  197. im = zmat(:,:,j-3)./(2*maxzscore)+.5;
  198. im = repmat(im,[1 1 3]);
  199. sigidxs = find(pmat);
  200. im(sigidxs) = .5;
  201. subplot(6,size(STAs,2),(j-1)*size(STAs,2)+i);
  202. image(im);
  203. axis image;
  204. set(gca,'XTick',[],'YTick',[]);
  205. end
  206. end
  207. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  208. % Looking at the responses to synthetic images
  209. % Finding which trials were synthetic image trials
  210. imageidx = find(strcmp(WN.sum.rasterCells(1,:),'synth_image'));
  211. allimages = WN.ras(:,imageidx);
  212. L = [];
  213. for i = 1:length(allimages)
  214. L = [L; ~isnan(allimages{i}(1))];
  215. end
  216. figure;
  217. plot(L);
  218. [x,y] = ginput(2);
  219. close;
  220. imageidxs = find(L);
  221. imageidxs = imageidxs(imageidxs<max(x) & imageidxs>min(x));
  222. % Pulling out the images and putting them through the gamma functions
  223. % to get them in normalized intensity units.
  224. nelements = length(allimages{imageidxs(1)});
  225. npix = nelements/3;
  226. npixperside = sqrt(npix);
  227. images = nan(nelements,length(imageidxs));
  228. for i = 1:length(imageidxs)
  229. im = allimages{imageidxs(i)};
  230. for j = 1:3
  231. idxs = [1:npix]+npix*(j-1);
  232. images(idxs,i) = gammaTable1(im(idxs),j);
  233. end
  234. end
  235. % Subtracting the background
  236. bkgndrgbmat = repmat(bkgndrgb', npix, 1);
  237. bkgndrgbmat = repmat(bkgndrgbmat(:), 1, length(imageidxs));
  238. [uniqueimages, i, whichimage] = unique((images-bkgndrgbmat)','rows');
  239. nuniqueims = max(whichimage);
  240. spikerates = {};
  241. meanfr = [];
  242. stdfr = [];
  243. ns = [];
  244. for i = 1:max(whichimage)
  245. Lcont = whichimage == i;
  246. stimon_t = WN.trial(imageidxs(Lcont),stimonidx);
  247. numframes = WN.trial(imageidxs(Lcont),nframesidx)
  248. stimoff_t = stimon_t+numframes/framerate;
  249. spikes = WN.ras(imageidxs(Lcont),spikeidx);
  250. stimdurations = stimoff_t-stimon_t;
  251. for j = 1:sum(Lcont)
  252. spikerates{i}(j) = sum((spikes{j}>stimon_t(j)) & (spikes{j} < stimoff_t(j)))/stimdurations(j);
  253. end
  254. meanfr = [meanfr; mean(spikerates{i})];
  255. stdfr = [stdfr; std(spikerates{i})];
  256. ns = [ns; sum(Lcont)];
  257. end
  258. sem = stdfr./sqrt(ns);
  259. sem(ns < 2) = nan;
  260. [u,s,v] = svd(uniqueimages');
  261. if ((size(s,2) == 1) || s(1,1)./s(2,2) > 1000) % 1-D images
  262. [y,contrastsort] = sort(v(:,1));
  263. figure;
  264. subplot(2,1,1); hold on;
  265. plot(v(contrastsort,1)*s(1),meanfr(contrastsort),'ko-', 'Linewidth', 1,'MarkerSize',4)
  266. plot([v(contrastsort,1) v(contrastsort,1)]*s(1),[meanfr(contrastsort)-sem(contrastsort) meanfr(contrastsort)+sem(contrastsort)],'k-.')
  267. ylabel('sp/sec');
  268. xlabel('Projection');
  269. subplot(2,2,3);
  270. avgim = v(contrastsort(1))*u(:,1)+bkgndrgbmat(:,1);
  271. image(reshape(avgim,npixperside, npixperside, 3));
  272. axis image; set(gca,'Xtick',[],'Ytick',[]);
  273. subplot(2,2,4);
  274. avgim = v(contrastsort(end))*u(:,1)+bkgndrgbmat(:,1);
  275. image(reshape(avgim,npixperside, npixperside, 3));
  276. axis image; set(gca,'Xtick',[],'Ytick',[]);
  277. figure; % Subplots may not be arranged in a meaningful order
  278. for i = 1:nuniqueims
  279. subplot(1,nuniqueims,i);
  280. scalefactor = .5/max(abs(uniqueimages(:)));
  281. image(reshape(scalefactor*uniqueimages(i,:)',[nstixperside, nstixperside, 3])+.5);
  282. title(num2str(meanfr(i),2));
  283. set(gca,'Xtick',[],'YTick',[]);
  284. axis image;
  285. end
  286. else % 2-D images
  287. % Rotating coordinate axes
  288. dists = sum(v(:,1).^2+v(:,2).^2,2);
  289. corneridx = find(dists == max(dists),1);
  290. thetas = [atan(v(corneridx,2)./v(corneridx,1))+pi/4;...
  291. atan(v(corneridx,2)./v(corneridx,1))-pi/4];
  292. theta = thetas(abs(thetas) == min(abs(thetas)));
  293. rotmat = [cos(theta) sin(theta); -sin(theta) cos(theta)];
  294. basis = u(:,[1 2])*rotmat' * rotmat*s([1 2], [1 2])*rotmat';
  295. basis = pinv(basis)'; % im = b'*w so w = im*pinv(b)
  296. norms = sqrt(sum(basis.^2));
  297. basis = basis./repmat(norms, size(basis,1),1);
  298. % This is flawed because the noise in the STA contributes to
  299. % its norm but we're zeroing out nuisance elements in the PC1 so the
  300. % when the are constrained to have the same norm, the "signal" in the
  301. % PC1 vector is huge, and so the weights onto the PC1 vector are
  302. % artificially small (relative to projections onto the STA).
  303. %weights = (rotmat*s([1 2], [1 2])*rotmat') * rotmat*v(:,[1 2])';
  304. weights = uniqueimages*basis;
  305. normweights = [(weights(:,1)-min(weights(:,1)))/(max(weights(:,1))-min(weights(:,1))),...
  306. (weights(:,2)-min(weights(:,2)))/(max(weights(:,2))-min(weights(:,2)))];
  307. rankweights = round(normweights*(sqrt(nuniqueims)-1))+1;
  308. frim = zeros(sqrt(nuniqueims));
  309. semim = zeros(sqrt(nuniqueims));
  310. figure;
  311. for i = 1:nuniqueims;
  312. frim(rankweights(i,1),rankweights(i,2)) = meanfr(i);
  313. semim(rankweights(i,1),rankweights(i,2)) = sem(i);
  314. ind = sub2ind(max(rankweights), rankweights(i,1), rankweights(i,2))
  315. subplot(max(rankweights(:,1)), max(rankweights(:,2)), ind);
  316. scalefactor = .5/max(abs(uniqueimages(:)));
  317. image(reshape(scalefactor*uniqueimages(i,:)',[nstixperside, nstixperside, 3])+.5);
  318. title(num2str(meanfr(i),2));
  319. set(gca,'Xtick',[],'YTick',[]);
  320. axis image;
  321. end
  322. frim = frim';
  323. semim = semim';
  324. figure; imagesc(frim); axis xy; axis image;
  325. colormap(gray);
  326. end
  327. %%
  328. % For L vs M replays
  329. % L is on the x axis, M is on the y axis
  330. LMScontrast = [];
  331. for i = 1:nuniqueims
  332. im = reshape(uniqueimages(i,:),[nstixperside^2 3]);
  333. [u,s,v] = svd(im);
  334. if (max(abs(u(:,1))) ~= max(u(:,1)))
  335. s(1) = -s(1);
  336. end
  337. LMScontrast(:,i) = (M*im(find(abs(u(:,1))==max(abs(u(:,1)))),:)')./bkgndlms;
  338. end
  339. rmscontrast = unique(sqrt(mean(LMScontrast.^2))); % in case we're interested in this
  340. totalcontrast = sqrt(sum(LMScontrast.^2));
  341. uniquecontrasts = unique(round(totalcontrast*100))/100;
  342. data = [];
  343. for i = 1:length(uniquecontrasts)
  344. L = abs(totalcontrast-uniquecontrasts(i)) < 1/100;
  345. if (sum(L) == 8)
  346. frs = meanfr(L);
  347. theta = atan2(LMScontrast(2,L), LMScontrast(1,L))';
  348. [theta,j] = sort(theta);
  349. data = cat(3,data,[theta, frs(j)]);
  350. disp('theta contrast');
  351. disp([theta, totalcontrast(L)']);
  352. end
  353. end
  354. figure; subplot(3,3,5);
  355. posbColors = {'k', 'b', 'm', 'c', 'g', 'r'};
  356. for i = size(data,3):-1:1
  357. theta = data(:,1,i);
  358. resp = data(:,2,i);
  359. polar([theta; theta(1)],[resp; resp(1)],[posbColors{i}, '-']);
  360. hold on;
  361. end
  362. ims = uniqueimages(L,:);
  363. theta = squeeze(data(:,1,end));
  364. resp = squeeze(data(:,2,end));
  365. for i = 1:8
  366. binnedtheta = round(mod(theta(i),2*pi)./(pi/4));
  367. if (binnedtheta == 8 | binnedtheta == 0)
  368. plotnum = 6;
  369. elseif (binnedtheta > 4)
  370. plotnum = binnedtheta +2;
  371. elseif (binnedtheta == 4)
  372. plotnum = 4;
  373. else
  374. plotnum = 4-binnedtheta;
  375. end
  376. subplot(3,3,plotnum);
  377. image(reshape(ims(j(i),:)',[nstixperside, nstixperside, 3])+.5);
  378. title(num2str(resp(i),2));
  379. set(gca,'Xtick',[],'YTick',[]);
  380. axis image;
  381. end
  382. %%
  383. % For L vs M replays at multiple contrasts
  384. if (size(data,3) > 1)
  385. posbColors = {'k', 'b', 'm', 'c', 'g', 'r'};
  386. figure; axes; hold on;
  387. for i = 1:size(data,3);
  388. plot(data(:,1,i),data(:,2,i),[posbColors{i}, 'o-'])
  389. end
  390. end
  391. set(gca,'YScale','log');
  392. %%
  393. % Rasters for the replay images
  394. figure; axes; hold on;
  395. counter = 0;
  396. for i = 1:size(uniqueimages,2)
  397. Lcont = whichimage == i;
  398. stimon_t = WN.trial(imageidxs(Lcont),stimonidx);
  399. numframes = WN.trial(imageidxs(Lcont),nframesidx);
  400. stimoff_t = stimon_t+numframes/framerate;
  401. spikes = WN.ras(imageidxs(Lcont),spikeidx);
  402. for j = 1:sum(Lcont)
  403. nsp = length(spikes{j})
  404. if (nsp > 0)
  405. plot(0,counter,'g*');
  406. plot(stimoff_t(j)-stimon_t(j),counter,'r*');
  407. else
  408. plot(0,counter,'k*');
  409. plot(stimoff_t(j)-stimon_t(j),counter,'k*');
  410. end
  411. plot([spikes{j} spikes{j}]'-stimon_t(j),[zeros(nsp,1) .5*ones(nsp,1)]'+counter,'k-')
  412. counter = counter + 1;
  413. end
  414. plot([-.2 1],[counter counter],'k-');
  415. end
  416. set(gca,'Xlim',[-.2 1]); xlabel('time(s)');
  417. title(WN.sum.fileName);
  418. %%
  419. % Getting the projections onto the PC1 and STA
  420. % Just experimenting with the code
  421. whichframe = 4; % in the middle
  422. nframestoconsider = 2;
  423. msperframe = 1000/WN.sum.exptParams.framerate;
  424. %%%%%%%%%%%%
  425. % Skip this part if using a basis that came from somewhere else
  426. %%%%%%%%%%
  427. if (~exist('basis'))
  428. STC = reshape(STCs(:,whichframe), 3*nstixperside^2, 3*nstixperside^2);
  429. [v,d] = eig(STC);
  430. basis = [STAs(:,whichframe) v(:,end)];
  431. basis = basis./repmat(sqrt(sum(basis.^2)), size(basis,1),1);
  432. end
  433. nframestotal = sum(WN.trial(:,nframesidx));
  434. initargs = {mkbasis(repmat(basis,nframestoconsider,1)) 3, nframestotal, [nstixperside^2 3 nframestoconsider]};
  435. out = getWhtnsStats(WN,whichframe-ceil(nframestoconsider/2),'STPROJmod',initargs);
  436. projs = out{1};
  437. Lspike = out{2};
  438. % 1-D firing rate plot
  439. whichvect = 2;
  440. nbins = 5;
  441. x = linspace(prctile(projs(:,whichvect), 5), prctile(projs(:,whichvect), 95),nbins+2);
  442. Na = hist(projs(:,whichvect), x);
  443. Ns = zeros(size(Na));
  444. for i = 1:max(Lspike)
  445. Ns = Ns + hist(projs(Lspike >=i,whichvect), x);
  446. end
  447. figure;
  448. plot(x(2:end-1),Ns(2:end-1)./Na(2:end-1)/msperframe*1000,'ko');
  449. % 2-D firing rate plot
  450. if (round(sqrt(nuniqueims)) == sqrt(nuniqueims));
  451. nbins = sqrt(nuniqueims);
  452. else
  453. nbins = 4;
  454. end
  455. x = [nbins nbins; prctile(projs, 10); prctile(projs, 90)];
  456. %x = [nbins nbins; min(weights); max(weights)];
  457. Na = hist2(projs, x);
  458. Ns = zeros(size(Na));
  459. for i = 1:max(Lspike)
  460. Ns = Ns + hist2(projs(Lspike >=i,:), x);
  461. end
  462. figure;
  463. imageprops = mkbasis([-1 1; 0 1; 1 1; -1 0; 0 0; 1 0; -1 -1; 0 -1; 1 -1]')';
  464. for i = [1 2 3 4 6 7 8 9]
  465. subplot(3,3,i);
  466. tmpim = basis/2*imageprops(i,:)'+.5; % just for a quick rendering
  467. image(reshape(tmpim,[nstixperside nstixperside 3]));
  468. axis image; set(gca,'XTick',[]); set(gca,'Ytick',[]);
  469. end
  470. subplot(3,3,5)
  471. imagesc(Ns./Na);
  472. axis image; set(gca,'XTick',[]); set(gca,'Ytick',[]);
  473. colormap gray;
  474. figure;
  475. plot(frim,(Ns./Na)/msperframe*1000,'k.');
  476. %%
  477. % Rotating the basis vectors onto which we project the spike-triggered
  478. % stimuli. Ideally, we'll see the best correlation between the projected
  479. % firing rate plot and the empirical firing rate plot when we don't rotate
  480. % at all.
  481. nbins = sqrt(length(frim(:)));
  482. x = [nbins nbins; min(weights); max(weights)];
  483. data = [];
  484. for theta = linspace(-pi/4,pi/4,5)
  485. theta
  486. rotmat = [cos(theta) sin(theta); -sin(theta) cos(theta)];
  487. initargs = {basis*rotmat', 3, nframestotal, [nstixperside^2 3 1]};
  488. out = getWhtnsStats(WN,whichframe,'STPROJmod',initargs);
  489. projs = out{1};
  490. Lspike = out{2};
  491. Na = hist2(projs, x);
  492. Ns = zeros(size(Na));
  493. for i = 1:max(Lspike)
  494. Ns = Ns + hist2(projs(Lspike >=i,:), x);
  495. end
  496. [rho,p] = corr(frim(:),Ns(:)./Na(:),'type','Kendall')
  497. data = [data; theta rho p];
  498. end
  499. figure;
  500. plot(data(:,1)*180/pi,data(:,2),'k-.');
  501. xlabel('Deg axes rotation')
  502. ylabel('r')
  503. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  504. % Everything below this point is more special-purpose code...
  505. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  506. %%
  507. % Looking for missed frames
  508. % (Late peak is from the synth image trials)
  509. stimon_t = WN.trial(:,stimonidx);
  510. stimoff_t = WN.trial(:,stimoffidx);
  511. framerate = WN.sum.exptParams.framerate;
  512. predstimoff_t = stimon_t+WN.trial(:,nframesidx)/framerate;
  513. x = stimoff_t-predstimoff_t;
  514. hist(x(x<0),100);
  515. plot(WN.trial(:,nframesidx), x,'k.')
  516. %%
  517. % Analyzing fixational saccades
  518. sacstats = getSacData(WN);
  519. L = logical(WN.trial(:,noisetypeidx)~= 0);
  520. amplitudes = [];
  521. directions = [];
  522. peakv = [];
  523. pathlengths = [];
  524. durations = [];
  525. BINWIDTH = .01;
  526. timebins = [-.25:BINWIDTH:.5];
  527. PSTHmat = zeros(sum(L),length(timebins));
  528. for i = find(L')
  529. stimon_t = WN.trial(i,stimonidx);
  530. numframes = WN.trial(i,nframesidx);
  531. stimoff_t = stimon_t+numframes/WN.sum.exptParams.framerate;
  532. st = sacstats.starttimes{i};
  533. Lsac = (st > stimon_t) & (st < stimoff_t-.1); %.1 to avoid a saccade that leaves the window
  534. if any(Lsac)
  535. if any(sacstats.amplitudes{i}(Lsac) > 2)
  536. keyboard
  537. end
  538. amplitudes = [amplitudes; sacstats.amplitudes{i}(Lsac)];
  539. directions = [directions; sacstats.directions{i}(Lsac)];
  540. peakv = [peakv; sacstats.peakv{i}(Lsac)];
  541. pathlengths = [pathlengths; sacstats.pathlengths{i}(Lsac)];
  542. durations = [durations; sacstats.durations{i}(Lsac)];
  543. spiketimes = [];
  544. for j = find(Lsac')
  545. tmp = WN.ras{i,1}-sacstats.starttimes{i}(j);
  546. spiketimes = [spiketimes; tmp((tmp > timebins(1)-BINWIDTH/2) & (tmp < timebins(end)+BINWIDTH/2))];
  547. end
  548. [n,x] = hist(spiketimes, timebins);
  549. PSTHmat(i,:) = n./(BINWIDTH*sum(Lsac));
  550. end
  551. end
  552. figure;
  553. subplot(3,2,1);
  554. hist(amplitudes,100);
  555. xlabel('amplitude'); ylabel('count');
  556. subplot(3,2,3);
  557. plot(amplitudes,peakv,'k.');
  558. xlabel('amplitude'); ylabel('peak vel.');
  559. subplot(3,2,4);
  560. plot(amplitudes,pathlengths,'k.');
  561. xlabel('amplitude'); ylabel('traj. length');
  562. subplot(3,2,5);
  563. [rho, theta]= hist(directions,20);
  564. polar([theta theta(1)],[rho rho(1)],'k-')
  565. subplot(3,2,6); hold on;
  566. plot(timebins, mean(PSTHmat),'k-');
  567. plot([0 0],[0 max(mean(PSTHmat))],'b:');
  568. set(gca,'Xlim',[min(timebins) max(timebins)]);
  569. xlabel('time wrt saccade onset (s)'); ylabel('sp/sec');
  570. %%
  571. % Cross validation to find static nonlinearities
  572. % 1-D version
  573. niters = 2;
  574. CVprop = .7;
  575. whichframe = 4;
  576. nbins = 5;
  577. Lgaussnoise = WN.trial(:,noisetypeidx) == 1;
  578. binlim = 2*mode(WN.trial(Lgaussnoise,9))/1000
  579. ntrials = size(WN.trial,1);
  580. ntrialsSTC = round(ntrials*CVprop);
  581. frs = [];
  582. vs = [];
  583. for iter = 1:niters
  584. trialidxs = randperm(ntrials);
  585. tmpstro = WN;
  586. tmpstro.trial = WN.trial(trialidxs(1:ntrialsSTC),:);
  587. tmpstro.ras = WN.ras(trialidxs(1:ntrialsSTC),:);
  588. out = getWhtnsStats(tmpstro, maxT, 'STCOVmex', {nstixperside^2, 3, whichframe});
  589. STAs = out{1};
  590. STCs = out{2};
  591. STC = reshape(STCs(:,whichframe), 3*nstixperside^2, 3*nstixperside^2);
  592. STC = STC.*~Lmask;
  593. [v,d] = eig(STC);
  594. d = diag(d);
  595. basis = [STAs(:,whichframe) v(:,end)];
  596. basis = basis./sqrt(sum(basis.^2));
  597. if (basis'*synthimvect < 0)% synthimvect is created by the chunk of code above
  598. basis = -basis;
  599. end
  600. tmpstro = WN;
  601. tmpstro.trial = WN.trial(trialidxs(ntrialsSTC+1:end),:);
  602. tmpstro.ras = WN.ras(trialidxs(ntrialsSTC+1:end),:);
  603. nframestotal = sum(WN.trial(:,nframesidx));
  604. initargs = {basis, whichframe-1, nframestotal, [nstixperside^2 3 1]};
  605. out = getWhtnsStats(tmpstro,whichframe,'STPROJmod',initargs);
  606. projs = out{1};
  607. Lspike = out{2};
  608. x = linspace(-binlim, binlim, nbins+2);
  609. Na = hist(projs(:,1), x);
  610. Ns = zeros(size(Na));
  611. for i = 1:max(Lspike)
  612. Ns = Ns + hist(projs(Lspike >=i,1), x);
  613. end
  614. frs = [frs; Ns./Na]
  615. vs = [vs,basis];
  616. end
  617. figure; subplot(2,1,1);
  618. plot(x,mean(frs));
  619. subplot(2,2,4);
  620. image(reshape(mean(vs,2),[nstixperside, nstixperside, 3])+.5); % Not rendered accurately
  621. axis image; set(gca,'XTick',[],'YTick',[]);
  622. subplot(2,2,3);
  623. image(reshape(-mean(vs,2),[nstixperside, nstixperside, 3])+.5); % Not rendered accurately
  624. axis image; set(gca,'XTick',[],'YTick',[]);
  625. %%
  626. % Cross validation to find static nonlinearities
  627. % 2-D version
  628. niters = 10;
  629. CVprop = .7;
  630. whichframe = 4;
  631. nbins = 10;
  632. Lgaussnoise = WN.trial(:,noisetypeidx) == 1;
  633. binlim = 1*mode(WN.trial(Lgaussnoise,9))/1000;
  634. ntrials = size(WN.trial,1);
  635. ntrialsSTC = round(ntrials*CVprop);
  636. Nas = [];
  637. Nss = [];
  638. for iter = 1:niters
  639. trialidxs = randperm(ntrials);
  640. tmpstro = WN;
  641. tmpstro.trial = WN.trial(trialidxs(1:ntrialsSTC),:);
  642. tmpstro.ras = WN.ras(trialidxs(1:ntrialsSTC),:);
  643. out = getWhtnsStats(tmpstro, maxT, 'STCOVmex', {nstixperside^2, 3, whichframe});
  644. STAs = out{1};
  645. STCs = out{2};
  646. STC = reshape(STCs(:,whichframe), 3*nstixperside^2, 3*nstixperside^2);
  647. [v,d] = eig(STC);
  648. basis = mkbasis([STAs(:,whichframe) v(:,end)]);
  649. basis(:,2) = sign(basis(:,1)'*basis(:,2))*basis(:,2); % PC constrained to have a + proj onto STA
  650. tmpstro = WN;
  651. tmpstro.trial = WN.trial(trialidxs(ntrialsSTC+1:end),:);
  652. tmpstro.ras = WN.ras(trialidxs(ntrialsSTC+1:end),:);
  653. nframestotal = sum(WN.trial(:,nframesidx));
  654. initargs = {basis, whichframe-1, nframestotal, [nstixperside^2 3 1]};
  655. out = getWhtnsStats(tmpstro,whichframe,'STPROJmod',initargs);
  656. projs = out{1};
  657. Lspike = out{2};
  658. x = [nbins nbins; -binlim -binlim; binlim binlim];
  659. Na = hist2(projs, x);
  660. Ns = zeros(size(Na));
  661. for i = 1:max(Lspike)
  662. Ns = Ns + hist2(projs(Lspike >=i,:), x);
  663. end
  664. Nas = cat(3,Nas,Na);
  665. Nss = cat(3,Nss,Ns);
  666. end
  667. fr = Nss./Nas;
  668. figure;
  669. imagesc(mean(fr,3));
  670. %% Looking at STA from the multielectrode array (no STC analysis because stimulus is too big).
  671. %
  672. WN=nex2stro;
  673. LFPsamprate = WN.sum.analog.storeRates{1}; % Assuming all channels are sampled at the same rate
  674. framerate = WN.sum.exptParams.framerate;
  675. nstixperside = WN.sum.exptParams.nstixperside;
  676. ntrials = length(WN.sum.absTrialNum);
  677. stimonidx = find(strcmp(WN.sum.trialFields(1,:),'stim_on'));
  678. stimoffidx = find(strcmp(WN.sum.trialFields(1,:),'all_off'));
  679. nframesidx = find(strcmp(WN.sum.trialFields(1,:),'num_frames'));
  680. noisetypeidx = find(strcmp(WN.sum.trialFields(1,:),'noise_type'));
  681. sigmaidxs = strmatch('sigma',WN.sum.trialFields(1,:));
  682. hepidx = find(strcmp(WN.sum.rasterCells(1,:),'AD11'));
  683. vepidx = find(strcmp(WN.sum.rasterCells(1,:),'AD12'));
  684. anlgStartTimeidx = find(strcmp(WN.sum.rasterCells(1,:),'anlgStartTime'));
  685. eyestart_t = [WN.ras{:,anlgStartTimeidx}]';
  686. eyesampperiod = 1/WN.sum.analog.storeRates{1};
  687. gammaTable = WN.sum.exptParams.gamma_table;
  688. gammaTable = reshape(gammaTable, length(gammaTable)/3, 3);
  689. gammaTable1 = interp1(linspace(0,255,256),gammaTable,linspace(0,255,65536), 'spline');
  690. invgamma = InvertGamma(gammaTable, 0);
  691. % Reconstructing the M matrix
  692. fundamentals = WN.sum.exptParams.fundamentals;
  693. fundamentals = reshape(fundamentals,[length(fundamentals)/3,3]);
  694. mon_spd = WN.sum.exptParams.mon_spd;
  695. mon_spd = reshape(mon_spd,[length(mon_spd)/3, 3]);
  696. mon_spd = SplineRaw([380:4:780]', mon_spd, [380:5:780]');
  697. M = fundamentals'*mon_spd;
  698. % Getting the background rgb/lms
  699. ridx = find(strcmp(WN.sum.trialFields(1,:),'bkgnd_r'));
  700. gidx = find(strcmp(WN.sum.trialFields(1,:),'bkgnd_g'));
  701. bidx = find(strcmp(WN.sum.trialFields(1,:),'bkgnd_b'));
  702. bkgndRGB = [mode(WN.trial(:,ridx)), mode(WN.trial(:,gidx)), mode(WN.trial(:,bidx))];
  703. bkgndrgb = [gammaTable(bkgndRGB(1)+1,1); gammaTable(bkgndRGB(2)+1,2); gammaTable(bkgndRGB(3)+1,3)];
  704. bkgndlms = M*bkgndrgb;
  705. maxT = 9;
  706. potentialspikeidxs = find(strncmp(WN.sum.rasterCells,'sig',3))
  707. for spikeidx = potentialspikeidxs
  708. out = getWhtnsStats(WN,maxT,'STAmex', {nstixperside^2, 3, maxT}, WN.sum.rasterCells{spikeidx});
  709. nspikes = out{3};
  710. STAs = out{1};
  711. %STVs = (out{2}-out{1}.^2)./nspikes;
  712. STVs = out{2}./nspikes;
  713. % Significance testing on the STAs, STVs, broken down by color
  714. L = WN.trial(:,noisetypeidx)==1; % 1 = gun noise
  715. mu1idx = find(strcmp(WN.sum.trialFields(1,:),'mu1'));
  716. mu2idx = find(strcmp(WN.sum.trialFields(1,:),'mu2'));
  717. mu3idx = find(strcmp(WN.sum.trialFields(1,:),'mu3'));
  718. sigma1idx = find(strcmp(WN.sum.trialFields(1,:),'sigma1'));
  719. sigma2idx = find(strcmp(WN.sum.trialFields(1,:),'sigma2'));
  720. sigma3idx = find(strcmp(WN.sum.trialFields(1,:),'sigma3'));
  721. muvect = unique(WN.trial(L,[mu1idx mu2idx mu3idx]),'rows')/1000;
  722. sigmavect = unique(WN.trial(L,[sigma1idx sigma2idx sigma3idx]),'rows')/1000;
  723. sigmavect(all(any(sigmavect == 0),2),:) = [];
  724. gausslims = [WN.sum.exptParams.gauss_locut WN.sum.exptParams.gauss_hicut]/1000;
  725. if (sum(L) > sum(~L)) % If more gun noise than cone noise
  726. mumat = repmat(reshape(repmat(muvect,nstixperside^2,1),[nstixperside^2*3, 1]),[1,size(STAs,2)]);
  727. sigmamat = repmat(reshape(repmat(sigmavect,nstixperside^2,1),[nstixperside^2* 3, 1]),[1,size(STAs,2)]);
  728. zscoremeans = (STAs-mumat)./(sigmamat*sqrt(nspikes));
  729. % Doing the calculations for the variances
  730. % Only considering one correction factor per dimension
  731. % (assuming variances on green and blue guns are same as red gun)
  732. NPOINTS = 65536;
  733. x = linspace(gausslims(1),gausslims(2),NPOINTS);
  734. Fx = norminv(x)*sigmavect(1);
  735. sigmacorrectionfactor = std(Fx)./sigmavect(1);
  736. muvar = (sigmavect(1)*sigmacorrectionfactor)^2;
  737. sigmavar = muvar*sqrt(2/nspikes);
  738. zscorevars = (STVs-muvar)./sigmavar;
  739. else
  740. zscoremeans = (STAs-mumat)./sqrt(nspikes);
  741. zscorevars = zeros(size(zscoremeans));
  742. end
  743. maxzscore = max(abs([zscoremeans(:);zscorevars(:)]));
  744. alpha = 0.01;
  745. crit = norminv(1-alpha,0,1);
  746. % Plotting
  747. figure;
  748. for i = 1:size(STAs,2)
  749. % First STAs
  750. zmat = reshape(zscoremeans(:,i),[nstixperside nstixperside 3]);
  751. for j = 1:3
  752. pmat = logical(abs(zmat(:,:,j))>crit);
  753. im = zmat(:,:,j)./(2*maxzscore)+.5;
  754. im = repmat(im,[1 1 3]);
  755. sigidxs = find(pmat);
  756. im(sigidxs) = .5; % red to .5 where sig. Looks red on dark and cyan on bright.
  757. subplot(6,size(STAs,2),(j-1)*size(STAs,2)+i);
  758. image(im);
  759. axis image;
  760. set(gca,'XTick',[],'YTick',[]);
  761. end
  762. % Then STVs
  763. zmat = reshape(zscorevars(:,i),[nstixperside nstixperside 3]);
  764. for j = 4:6
  765. pmat = logical(abs(zmat(:,:,j-3))>crit);
  766. im = zmat(:,:,j-3)./(2*maxzscore)+.5;
  767. im = repmat(im,[1 1 3]);
  768. sigidxs = find(pmat);
  769. im(sigidxs) = .5;
  770. subplot(6,size(STAs,2),(j-1)*size(STAs,2)+i);
  771. image(im);
  772. axis image;
  773. set(gca,'XTick',[],'YTick',[]);
  774. end
  775. end
  776. set(gcf,'Name',WN.sum.rasterCells{spikeidx});
  777. drawnow;
  778. end
  779. %%
  780. % Looking at LFP-triggered averages (filtered, interpolated LFPs)
  781. centerfreq = 100; % Hz
  782. cyclespersample = centerfreq./LFPsamprate;
  783. ncyclesper6sigma = 3; % Controls the bandwidth
  784. nsamplesper6sigma = ceil(ncyclesper6sigma/cyclespersample);
  785. ncycles = nsamplesper6sigma*cyclespersample;
  786. filtkernel1 = normpdf(linspace(-3,3,nsamplesper6sigma),0,1).*cos(linspace(0,2*pi*ncycles,nsamplesper6sigma));
  787. filtkernel2 = normpdf(linspace(-3,3,nsamplesper6sigma),0,1).*sin(linspace(0,2*pi*ncycles,nsamplesper6sigma));
  788. filtkernel1 = filtkernel1./norm(filtkernel1);
  789. filtkernel2 = filtkernel2./norm(filtkernel2);
  790. for whichADchan = 1:32;
  791. ntrials = size(WN.trial,1);
  792. nstixperside = WN.sum.exptParams.nstixperside; %get number of stixels per side
  793. msperframe = 1000/WN.sum.exptParams.framerate; %calculate msec per frame
  794. secsperframe = 1/WN.sum.exptParams.framerate;
  795. gammaTable = WN.sum.exptParams.gamma_table; %get gamma_table
  796. gammaTable = reshape(gammaTable,length(gammaTable)/3,3); %reshapse gamma_table into three columns
  797. invgammaTable = InvertGamma(gammaTable,1); %invert gamma_table
  798. ngammasteps = size(invgammaTable,1); %get number of rows of gamma_table (65536)
  799. seedidx = strcmp(WN.sum.trialFields(1,:),'seed'); %get seed index from trialFields
  800. nframesidx = strcmp(WN.sum.trialFields(1,:),'num_frames'); %get nframes index from trialFields
  801. stimonidx = strcmp(WN.sum.trialFields(1,:),'stim_on'); %get stimon index from trialFields
  802. muidxs = [find(strcmp(WN.sum.trialFields(1,:),'mu1')),... %get mu indices into vector from trialFields
  803. find(strcmp(WN.sum.trialFields(1,:),'mu2')),...
  804. find(strcmp(WN.sum.trialFields(1,:),'mu3'))];
  805. sigmaidxs = [find(strcmp(WN.sum.trialFields(1,:),'sigma1')),... %get sigma indices into vector from trialFields
  806. find(strcmp(WN.sum.trialFields(1,:),'sigma2')),...
  807. find(strcmp(WN.sum.trialFields(1,:),'sigma3'))];
  808. LFPstarttimes = [WN.ras{:,strcmp(WN.sum.rasterCells,'anlgStartTime')}];
  809. feval('STAmex','init', {nstixperside^2, 3, maxT});
  810. % This code was largely lifted from getWhtnsStats
  811. hwait = waitbar(0,'Finding stimuli...'); %display progress bar
  812. L = WN.trial(:,noisetypeidx)==1; % 1 = gun noise
  813. for i = 1:ntrials %get values and insert into given column
  814. if (WN.trial(i,noisetypeidx)==1)
  815. if (sum(L) > sum(~L))
  816. noisetype = 1;
  817. else
  818. continue
  819. end
  820. end
  821. if (WN.trial(i,noisetypeidx)==2)
  822. if (sum(~L) > sum(L))
  823. noisetype = 2;
  824. else
  825. continue
  826. end
  827. end
  828. seed = WN.trial(i,seedidx);
  829. nframes = WN.trial(i,nframesidx);
  830. mu = WN.trial(i,muidxs)/1000;
  831. sigma = WN.trial(i,sigmaidxs)/1000;
  832. if (noisetype == 1) % Gaussian gun
  833. x = linspace(WN.sum.exptParams.gauss_locut/1000, WN.sum.exptParams.gauss_hicut/1000, ngammasteps);%dividing gauss by 1000 and making equal intervals so that there are 65536 values
  834. for gun = 1:3
  835. invnormcdf(:,gun) = norminv(x)*sigma(gun)+mu(gun);
  836. end
  837. randnums = getEJrandnums(3*nstixperside^2*nframes, seed);
  838. randnums = reshape(randnums, [nstixperside^2*3, nframes]);
  839. for j = 1:3
  840. idxs = [1:nstixperside^2]+nstixperside^2*(j-1);
  841. randnums(idxs,:) = reshape(invnormcdf(randnums(idxs,:)+1,j),[length(idxs),nframes]);
  842. end
  843. elseif (noisetype == 2) % Binary cone
  844. colordirlms = sign(fullfact([2,2,2])-1.5);
  845. randnums = getEJrandnums(nstixperside^2*nframes, seed);
  846. randnums = reshape(randnums, [nstixperside^2, nframes]);
  847. randnums = mod(randnums, size(colordirlms,1))+1;
  848. tmp = colordirlms(randnums,:);
  849. tmp = reshape(tmp, [nstixperside^2 nframes 3]);
  850. tmp = permute(tmp,[1 3 2]);
  851. randnums = reshape(tmp,[nstixperside^2*3 nframes]);
  852. end
  853. t_stimon = WN.trial(i,stimonidx);
  854. LFP = WN.ras{i,strcmp(WN.sum.rasterCells,['AD',num2str(16+whichADchan)])};
  855. filteredLFP = conv(LFP, filtkernel1,'same').^2+conv(LFP, filtkernel2,'same').^2;
  856. LFPtimes = LFPstarttimes(i)+[0:length(filteredLFP)-1]/LFPsamprate; % sec
  857. frametimes = t_stimon+(linspace(0, nframes*secsperframe, nframes)+(secsperframe/2)'); % sec
  858. rectLFP = interp1(LFPtimes, filteredLFP, frametimes);
  859. % plot(LFPtimes,abs(LFP)); hold on; plot(frametimes,rectLFP,'m-');
  860. feval('STAmex',randnums(:),rectLFP);
  861. if (ishandle(hwait))
  862. waitbar(i/ntrials,hwait);
  863. else
  864. break;
  865. end
  866. end
  867. close(hwait);
  868. out = feval('STAmex','return');
  869. eval('clear STAmex');
  870. % Now doing some plotting
  871. STAs = out{1};
  872. STVs = out{2};
  873. STAlims = [min(STAs(:)) max(STAs(:))];
  874. STVlims = [min(STVs(:)) max(STVs(:))];
  875. STAs = (STAs-STAlims(2))/(STAlims(1)-STAlims(2));
  876. STVs = (STVs-STVlims(2))/(STVlims(1)-STVlims(2));
  877. figure; colormap(gray(255));
  878. set(gcf,'Name',['LFP ',num2str(whichADchan)]);
  879. for i = 1:size(STAs,2)
  880. % First STAs
  881. mat = reshape(STAs(:,i),[nstixperside nstixperside 3]);
  882. for j = 1:3
  883. im = mat(:,:,j);
  884. subplot(6,size(STAs,2),(j-1)*size(STAs,2)+i);
  885. image(im*255);
  886. axis image;
  887. set(gca,'XTick',[],'YTick',[]);
  888. end
  889. % Then STVs
  890. mat = reshape(STVs(:,i),[nstixperside nstixperside 3]);
  891. for j = 1:3
  892. im = mat(:,:,j);
  893. subplot(6,size(STAs,2),(j-1+3)*size(STAs,2)+i);
  894. image(im*255);
  895. axis image;
  896. set(gca,'XTick',[],'YTick',[]);
  897. end
  898. end
  899. end
  900. %%
  901. % Looking at rectified LFPs at the time of stimus onset
  902. ADchans = find(strncmp('AD',WN.sum.rasterCells,2));
  903. LFPchans = ADchans(3:end); % Getting rid of the eye position channels
  904. hwait = waitbar(0,'Computing stimulus-locked LFPs...'); %display progress bar
  905. poststim_t = 0.5; % secs
  906. prestim_t = 0.3; % secs
  907. nprestimsamples = prestim_t*LFPsamprate;
  908. npoststimsamples = poststim_t*LFPsamprate;
  909. nsamples = nprestimsamples+npoststimsamples+1;
  910. PSTHs = zeros(length(LFPchans),nsamples);
  911. for i = 1:ntrials %get values and insert into given column
  912. t_stimon = WN.trial(i, stimonidx);
  913. for ADchan1 = LFPchans
  914. LFP = WN.ras{i,ADchan1};
  915. LFPtimes = LFPstarttimes(i)+[0:length(LFP)-1]/LFPsamprate; % sec
  916. err = (LFPtimes-t_stimon).^2;
  917. startidx = find(err == min(err),1);
  918. if (startidx > nprestimsamples & length(LFP)-startidx > npoststimsamples)
  919. LFPclip = LFP(startidx+[-nprestimsamples:npoststimsamples]);
  920. PSTHs(ADchan1 == LFPchans,:) = PSTHs(ADchan1 == LFPchans,:) + abs(LFPclip)';
  921. end
  922. end
  923. waitbar(i/ntrials,hwait);
  924. end
  925. close(hwait);
  926. figure; subplot(2,1,1);
  927. imagesc(PSTHs);
  928. subplot(2,1,2);
  929. tvect = linspace(-prestim_t, poststim_t, nsamples);
  930. plot(tvect,mean(PSTHs));
  931. % Cool. I think we're seeing the stimulus refresh in the LFP.
  932. L = tvect>.3;
  933. freqs = linspace(0, LFPsamprate/2, sum(L)/2);
  934. [Pxx,F] = periodogram(mean(PSTHs(:,L)),[],[],LFPsamprate)
  935. figure; plot(F,Pxx); set(gca,'YScale','log');
  936. %%
  937. % Looking at the auto- and cross-correlation functions of the LFPs
  938. hwait = waitbar(0,'Finding stimuli...'); %display progress bar
  939. maxlag = 0.2; % sec
  940. delayfromstimon = 0.25;
  941. maxlagsamples = maxlag*LFPsamprate;
  942. nsamples = 2*maxlagsamples+1;
  943. data = zeros(length(LFPchans),length(LFPchans), nsamples);
  944. for i = 1:ntrials % get values and insert into given column
  945. t_stimon = WN.trial(i, stimonidx);
  946. t_stimoff = WN.trial(i, stimoffidx);
  947. for idx1 = 1:length(LFPchans)
  948. for idx2 = idx1:length(LFPchans)
  949. LFP1 = WN.ras{i,LFPchans(idx1)};
  950. LFP2 = WN.ras{i,LFPchans(idx2)};
  951. LFPtimes = LFPstarttimes(i)+[0:length(LFP1)-1]/LFPsamprate; % sec
  952. err = (LFPtimes-t_stimon-delayfromstimon).^2;
  953. startidx = find(err == min(err),1);
  954. err = (LFPtimes-t_stimoff).^2;
  955. endidx = find(err == min(err),1);
  956. LFP1 = LFP1(startidx:endidx);
  957. LFP2 = LFP2(startidx:endidx);
  958. if (length(LFP1) >= nsamples)
  959. tmp = xcorr(LFP1,LFP2,maxlagsamples,'coeff');
  960. data(idx1,idx2,:) = tmp;
  961. end
  962. end
  963. end
  964. waitbar(i/ntrials,hwait);
  965. end
  966. close(hwait);
  967. % First looking at all the autocorrelation functions
  968. tvect = [-maxlagsamples:maxlagsamples]/LFPsamprate;
  969. tmp = zeros(length(LFPchans),nsamples);
  970. for i = 1:length(LFPchans)
  971. tmp(i,:) = data(i,i,:);
  972. end
  973. figure;
  974. subplot(2,1,1);
  975. title('Autocorrelations');
  976. imagesc(tmp); set(gca,'Xtick',[]);
  977. subplot(2,1,2);
  978. plot(tvect,tmp');
  979. xlabel('lag secs');
  980. % Now looking at cross-correlations
  981. tmp = [];
  982. for sig1 = 1:length(LFPchans)
  983. for sig2 = sig1+1:length(LFPchans)
  984. tmp = [tmp;squeeze(data(sig1,sig2,:))'];
  985. end
  986. end
  987. figure;
  988. imagesc(tmp);
  989. % % Looking at cross correlograms of adjacent and non-adjacent pairs of electrodes
  990. % % Only appropriate for most medial bank of 32 (port C).
  991. tmp1 = []; tmp2 = [];
  992. for i = 1:length(LFPchans)-1
  993. if (mod(i,2)) % if i is odd
  994. tmp1 = [tmp1; squeeze(data(i,i+1,:))'];
  995. else % if i is even
  996. tmp2 = [tmp2; squeeze(data(i,i+1,:))'];
  997. end
  998. end
  999. figure;
  1000. subplot(1,2,1); % Nearby pairs
  1001. plot(tvect, tmp1);
  1002. set(gca,'Ylim',[min([tmp1(:);tmp2(:)])*.9 max([tmp1(:);tmp2(:)])*1.1]);
  1003. subplot(1,2,2); % Distant pairs
  1004. plot(tvect, tmp2);
  1005. set(gca,'Ylim',[min([tmp1(:);tmp2(:)])*.9 max([tmp1(:);tmp2(:)])*1.1]);
  1006. %%
  1007. % Cranking through a bunch of frequencies to find where we get the best
  1008. % signal in the LFP-TA and LFP-TV
  1009. LFPsamprate = WN.sum.analog.storeRates{1}; % Assuming all channels are sampled at the same rate
  1010. whichADchan = 4; % Pick something good
  1011. nfreqs = 10;
  1012. lowfreq = 30;
  1013. highfreq = 300;
  1014. %highfreq = LFPsamprate/2; % Nyquist
  1015. ncyclesper6sigma = 3; % Controls the bandwidth
  1016. ntrials = size(WN.trial,1);
  1017. nstixperside = WN.sum.exptParams.nstixperside; %get number of stixels per side
  1018. msperframe = 1000/WN.sum.exptParams.framerate; %calculate msec per frame
  1019. secsperframe = 1/WN.sum.exptParams.framerate;
  1020. gammaTable = WN.sum.exptParams.gamma_table; %get gamma_table
  1021. gammaTable = reshape(gammaTable,length(gammaTable)/3,3); %reshapse gamma_table into three columns
  1022. invgammaTable = InvertGamma(gammaTable,1); %invert gamma_table
  1023. ngammasteps = size(invgammaTable,1); %get number of rows of gamma_table (65536)
  1024. seedidx = strcmp(WN.sum.trialFields(1,:),'seed'); %get seed index from trialFields
  1025. nframesidx = strcmp(WN.sum.trialFields(1,:),'num_frames'); %get nframes index from trialFields
  1026. stimonidx = strcmp(WN.sum.trialFields(1,:),'stim_on'); %get stimon index from trialFields
  1027. muidxs = [find(strcmp(WN.sum.trialFields(1,:),'mu1')),... %get mu indices into vector from trialFields
  1028. find(strcmp(WN.sum.trialFields(1,:),'mu2')),...
  1029. find(strcmp(WN.sum.trialFields(1,:),'mu3'))];
  1030. sigmaidxs = [find(strcmp(WN.sum.trialFields(1,:),'sigma1')),... %get sigma indices into vector from trialFields
  1031. find(strcmp(WN.sum.trialFields(1,:),'sigma2')),...
  1032. find(strcmp(WN.sum.trialFields(1,:),'sigma3'))];
  1033. LFPstarttimes = [WN.ras{:,strcmp(WN.sum.rasterCells,'anlgStartTime')}];
  1034. for centerfreq = logspace(log10(lowfreq),log10(highfreq),nfreqs); % Hz
  1035. cyclespersample = centerfreq./LFPsamprate;
  1036. nsamplesper6sigma = ceil(ncyclesper6sigma/cyclespersample);
  1037. ncycles = nsamplesper6sigma*cyclespersample;
  1038. filtkernel1 = normpdf(linspace(-3,3,nsamplesper6sigma),0,1).*cos(linspace(0,2*pi*ncycles,nsamplesper6sigma));
  1039. filtkernel2 = normpdf(linspace(-3,3,nsamplesper6sigma),0,1).*sin(linspace(0,2*pi*ncycles,nsamplesper6sigma));
  1040. filtkernel1 = filtkernel1./norm(filtkernel1);
  1041. filtkernel2 = filtkernel2./norm(filtkernel2);
  1042. feval('STAmex','init', {nstixperside^2, 3, maxT});
  1043. % This code was largely lifted from getWhtnsStats
  1044. hwait = waitbar(0,'Finding stimuli...'); %display progress bar
  1045. L = WN.trial(:,noisetypeidx)==1; % 1 = gun noise
  1046. for i = 1:ntrials %get values and insert into given column
  1047. if (WN.trial(i,noisetypeidx)==1)
  1048. if (sum(L) > sum(~L))
  1049. noisetype = 1;
  1050. else
  1051. continue
  1052. end
  1053. end
  1054. if (WN.trial(i,noisetypeidx)==2)
  1055. if (sum(~L) > sum(L))
  1056. noisetype = 2;
  1057. else
  1058. continue
  1059. end
  1060. end
  1061. seed = WN.trial(i,seedidx);
  1062. nframes = WN.trial(i,nframesidx);
  1063. mu = WN.trial(i,muidxs)/1000;
  1064. sigma = WN.trial(i,sigmaidxs)/1000;
  1065. if (noisetype == 1) % Gaussian gun
  1066. x = linspace(WN.sum.exptParams.gauss_locut/1000, WN.sum.exptParams.gauss_hicut/1000, ngammasteps);%dividing gauss by 1000 and making equal intervals so that there are 65536 values
  1067. for gun = 1:3
  1068. invnormcdf(:,gun) = norminv(x)*sigma(gun)+mu(gun);
  1069. end
  1070. randnums = getEJrandnums(3*nstixperside^2*nframes, seed);
  1071. randnums = reshape(randnums, [nstixperside^2*3, nframes]);
  1072. for j = 1:3
  1073. idxs = [1:nstixperside^2]+nstixperside^2*(j-1);
  1074. randnums(idxs,:) = reshape(invnormcdf(randnums(idxs,:)+1,j),[length(idxs),nframes]);
  1075. end
  1076. elseif (noisetype == 2) % Binary cone
  1077. colordirlms = sign(fullfact([2,2,2])-1.5);
  1078. randnums = getEJrandnums(nstixperside^2*nframes, seed);
  1079. randnums = reshape(randnums, [nstixperside^2, nframes]);
  1080. randnums = mod(randnums, size(colordirlms,1))+1;
  1081. tmp = colordirlms(randnums,:);
  1082. tmp = reshape(tmp, [nstixperside^2 nframes 3]);
  1083. tmp = permute(tmp,[1 3 2]);
  1084. randnums = reshape(tmp,[nstixperside^2*3 nframes]);
  1085. end
  1086. t_stimon = WN.trial(i, stimonidx);
  1087. LFP = WN.ras{i,strcmp(WN.sum.rasterCells,['AD',num2str(16+whichADchan)])};
  1088. filteredLFP = conv(LFP, filtkernel1,'same').^2+conv(LFP, filtkernel2,'same').^2;
  1089. LFPtimes = LFPstarttimes(i)+[0:length(filteredLFP)-1]/LFPsamprate; % sec
  1090. frametimes = t_stimon+(linspace(0, nframes*secsperframe, nframes)+(secsperframe/2)'); % sec
  1091. rectLFP = interp1(LFPtimes, abs(filteredLFP), frametimes); % This is probably not the best
  1092. % plot(LFPtimes,abs(LFP)); hold on; plot(frametimes,rectLFP,'m-');
  1093. feval('STAmex',randnums(:),rectLFP);
  1094. if (ishandle(hwait))
  1095. waitbar(i/ntrials,hwait);
  1096. else
  1097. break;
  1098. end
  1099. end
  1100. close(hwait);
  1101. out = feval('STAmex','return');
  1102. eval('clear STAmex');
  1103. % Now doing some plotting
  1104. STAs = out{1};
  1105. STVs = out{2};
  1106. STAlims = [-max(abs(STAs(:))) max(abs(STAs(:)))];
  1107. STVlims = [min(STVs(:)) max(STVs(:))];
  1108. STAs = (STAs-STAlims(2))/(STAlims(1)-STAlims(2));
  1109. STVs = (STVs-STVlims(2))/(STVlims(1)-STVlims(2));
  1110. figure; colormap(gray(255));
  1111. set(gcf,'Name',['LFP ',num2str(whichADchan),' ',num2str(centerfreq),' Hz']);
  1112. for i = 1:size(STAs,2)
  1113. % First STAs
  1114. mat = reshape(STAs(:,i),[nstixperside nstixperside 3]);
  1115. for j = 1:3
  1116. im = mat(:,:,j);
  1117. subplot(6,size(STAs,2),(j-1)*size(STAs,2)+i);
  1118. image(im*255);
  1119. axis image;
  1120. set(gca,'XTick',[],'YTick',[]);
  1121. end
  1122. % Then STVs
  1123. mat = reshape(STVs(:,i),[nstixperside nstixperside 3]);
  1124. for j = 1:3
  1125. im = mat(:,:,j);
  1126. subplot(6,size(STAs,2),(j-1+3)*size(STAs,2)+i);
  1127. image(im*255);
  1128. axis image;
  1129. set(gca,'XTick',[],'YTick',[]);
  1130. end
  1131. end
  1132. end
  1133. %%
  1134. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1135. % The stuff below is basically obsolete. It's stuff I was working on just
  1136. % to make sure that could do offline analysis at all.
  1137. %
  1138. % First, looking at eye movements
  1139. figure;
  1140. for i = 1:ntrials
  1141. hep = WN.ras{i,hepidx}*4096/400;
  1142. vep = WN.ras{i,vepidx}*4096/400;
  1143. nsamps = length(hep);
  1144. t = [0:1:nsamps-1]*eyesampperiod+eyestart_t(i);
  1145. subplot(3,1,1); hold on;
  1146. plot(hep,vep);
  1147. % subplot(3,1,2); hold on;
  1148. % plot(t-stimon_t(i), hep,'m-');
  1149. % plot(t-stimon_t(i), vep,'g-');
  1150. end
  1151. subplot(3,1,1)
  1152. axis square
  1153. % Theory on the eye movements:
  1154. % in nex2stro.m we multiply the raw AD values by 10/2^12 to get to
  1155. % "millivolts". But we know that on REX 40 AD values is 1 degree and we
  1156. % know that REX and Plexon have similar A/D cards. Both Rex and Plexon
  1157. % appear to want A/D signals from -5V to +5V (they both saturate outside of
  1158. % this range).
  1159. %
  1160. % 10 V/102.4 deg * 4096 steps/10 V = 40 steps/deg
  1161. %%
  1162. % Select a pixel for analysis
  1163. [x,y] = ginput;
  1164. whichpix = [round(x) round(y)];
  1165. idx = (whichpix(1)-1)*nstixperside+whichpix(2);
  1166. STA_t = STAs([idx, idx+nstixperside^2, idx+2*nstixperside^2],:);
  1167. figure; axes; hold on;
  1168. plot(STA_t(1,:),'r-','LineWidth',2);
  1169. plot(STA_t(2,:),'g-','LineWidth',2);
  1170. plot(STA_t(3,:),'b-','LineWidth',2);
  1171. %%
  1172. % Looking at the gun intensities of STA and PCs
  1173. % at a single frame
  1174. colors = {'red','green','blue'};
  1175. rowidxs = reshape([1:3*nstixperside^2],[nstixperside^2, 3]);
  1176. whichframe = input('Which frame would you like to see?');
  1177. figure;
  1178. subplot(6,1,1); hold on;
  1179. maxval = max(abs([STAs(:,whichframe);PCs(:,1,whichframe)]));
  1180. for gun = 1:3
  1181. plot(STAs(rowidxs(:,gun),whichframe),'Color',colors{gun});
  1182. end
  1183. set(gca,'Ylim', [-1.5 1.5]*maxval);
  1184. for i = 1:4
  1185. subplot(6,1,1+i); hold on;
  1186. for gun = 1:3
  1187. plot(PCs(rowidxs(:,gun),i,whichframe),'Color',colors{gun});
  1188. end
  1189. set(gca,'Ylim', [-1.5 1.5]*maxval);
  1190. end
  1191. STC = reshape(STCs(:,whichframe),[sqrt(length(STCs(:,whichframe))),sqrt(length(STCs(:,whichframe)))]);
  1192. STV = reshape(diag(STC),[nstixperside nstixperside 3]);
  1193. STV = (STV-mean(STV(:)));
  1194. subplot(6,1,6); hold on;
  1195. for gun = 1:3
  1196. plot(reshape(STV(:,:,gun),[nstixperside^2 1]),'Color',colors{gun});
  1197. end
  1198. %% Looking trial by trial at eye movements, spikes, events, etc.
  1199. figure; axes; hold on;
  1200. framerate = WN.sum.exptParams.framerate;
  1201. predstimoff_t = stimon_t+WN.trial(:,nframesidx)/framerate;
  1202. for i = 1:ntrials
  1203. timeanchor = stimon_t(i);
  1204. hep = WN.ras{i,hepidx}*4096/400;
  1205. vep = WN.ras{i,vepidx}*4096/400;
  1206. spiketimes = WN.ras{i,spikeidx}-timeanchor;
  1207. nspikes = length(spiketimes);
  1208. nsamps = length(hep);
  1209. t = [0:1:nsamps-1]*eyesampperiod+eyestart_t(i)-timeanchor;
  1210. minep = min([hep; vep]);
  1211. plot(t, hep,'m-');
  1212. plot(t, vep

Large files files are truncated, but you can click here to view the full file