PageRenderTime 32ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/MatlabCode/branches/Greg's Branch/Analysis/DetectionTask/DTgui.m

http://horwitzlab.googlecode.com/
MATLAB | 1199 lines | 1028 code | 84 blank | 87 comment | 68 complexity | 9c9067e12fd40c22671ba84c6df29abc 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. function DTgui
  2. % an interactive tool for doing data analysis on detection data
  3. %open a control pannel. This will specify the different files to analyze
  4. %and keep track of a file history. The control pannel calls a seperate
  5. %function that sets up all the plots.
  6. cntrlPanHand = currentFigOpen('DT GUI Control Pannel');
  7. if isempty(cntrlPanHand)
  8. cPan.figHand = figure;
  9. else
  10. cPan.figHand = cntrlPanHand;
  11. end
  12. set(cPan.figHand, 'name', 'DT GUI Control Pannel', 'numbertitle', 'off');
  13. set(cPan.figHand, 'units', 'normalize', 'position', [0.1891 0.7754 0.6047 0.1309]);
  14. uicontrol('style', 'text', 'string', 'Detection Files', 'units', 'normalize', 'position', [.4, .61, .2, .16], 'fontsize', 13, 'backgroundColor', get(gcf, 'color'));
  15. cPan.dtTextHand = uicontrol('style', 'edit', 'string', 'input DT file', 'units', 'normalized', 'position', [.38, .42, .24, .18], 'backgroundColor', [1 1 1], 'fontsize', 12);
  16. uicontrol('style', 'text', 'string', 'Grating Files', 'units', 'normalize', 'position', [.1, .76, .2, .16], 'fontsize', 13, 'backgroundColor', get(gcf, 'color'));
  17. cPan.gtTextHand = uicontrol('style', 'edit', 'string', 'input GT file', 'units', 'normalized', 'max', 4, 'min', 1, 'position', [.08, .25, .24, .5], 'backgroundColor', [1 1 1], 'fontsize', 12);
  18. cPan.applyHand = uicontrol('style', 'pushbutton', 'string', 'Apply', 'callback', {@analyzeData, cPan.figHand}, 'units', 'normalized', 'position', [.7, .63 .2, .2], 'fontsize', 11, 'interruptible', 'off', 'busyaction', 'cancel');
  19. cPan.resetHand = uicontrol('style', 'pushbutton', 'string', 'Reset', 'callback', @resetTextFields, 'units', 'normalized', 'position', [0.7 .3 .2 .2], 'fontsize', 11, 'interruptible', 'off', 'busyaction', 'cancel');
  20. set(cPan.figHand, 'userdata', cPan);
  21. %
  22. % RESETTING THE TEXT FIELDS
  23. %
  24. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  25. function resetTextFields(h, ev)
  26. set(cPan.dtTextHand, 'string', 'input DT file')
  27. set(cPan.gtTextHand, 'string', 'input GT file')
  28. end
  29. end %DTgui
  30. %***********************************************************
  31. %
  32. % NON NESTED SUBFUNCTIONS
  33. %
  34. %***********************************************************
  35. %
  36. % ANALYZE DATA (ROUTER FUNCTION)
  37. %
  38. % the main analysis script is a non-nested function and calls other
  39. % non-nested functions to carry out each analysis. GT and DT data are
  40. % stored in the userdata field of each figure. The grating figure has a
  41. % sturcture named 'g' that contains these data. The DT structure is
  42. % called 'd'.
  43. %
  44. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  45. function analyzeData(h, ev, cntrlPanHand)
  46. cPan = get(cntrlPanHand, 'userdata');
  47. set(cPan.applyHand, 'string', 'Finding Data Files...', 'FontSize', 9,'BackgroundColor',[0.92549 0.913725 0.847059]);
  48. drawnow;
  49. %open the appropriate files. Be nice and change the user input to all
  50. %caps in case they forgot.
  51. DTfname = upper(get(cPan.dtTextHand, 'string'));
  52. GTfname = upper(get(cPan.gtTextHand, 'string'));
  53. %setup the gratings GUI
  54. if ~strcmpi(GTfname, 'input GT file') && ~isempty(GTfname)
  55. %iterate over all the available GT files
  56. for a = 1:size(GTfname,1)
  57. fPath = findfile(GTfname(a,:));
  58. if isempty(fPath)
  59. set(cPan.applyHand, 'string', sprintf('GT file <%d> not found', a), 'FontSize', 11);
  60. set(cPan.applyHand,'BackgroundColor',[1 0.8 0.8]);
  61. drawnow
  62. return
  63. end
  64. g.GT{a} = nex2stro(findfile(GTfname(a,:)));
  65. g.GT{a}.orients = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'orient')));
  66. g.GT{a}.sfs = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'sf')));
  67. g.GT{a}.diams = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'diam')));
  68. g.GT{a}.protocols = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'protocol')));
  69. framerate = g.GT{a}.sum.exptParams.framerate;
  70. nframes = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'nframes')));
  71. g.GT{a}.stimon_t = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'stim_on')));
  72. g.GT{a}.stimoff_t= g.GT{a}.trial(:,strcmp(g.GT{a}.sum.trialFields(1,:),'stim_off'));;
  73. spikeidx = find(strcmp(g.GT{a}.sum.rasterCells(1,:),getSpikenum(g.GT{a})));
  74. Lcc = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'lcont')));
  75. Mcc = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'mcont')));
  76. Scc = g.GT{a}.trial(:,find(strcmp(g.GT{a}.sum.trialFields(1,:),'scont')));
  77. %standardize the colors contained in the .trial field. The L
  78. %cones should have a positive sign. S-iso should also be
  79. %positive.
  80. LMS = [Lcc, Mcc, Scc];
  81. l_negL = LMS(:,1) < 0;
  82. LMS(l_negL,:) = LMS(l_negL,:) .* -1; %deal with all non-siso colors
  83. l_negSiso = ismember(sign(LMS), [0 0 -1], 'rows');
  84. LMS(l_negSiso,:) = LMS(l_negSiso,:) .* -1; %deal with the Siso colors
  85. g.GT{a}.colordirections = LMS;
  86. g.GT{a}.spikerates = [];
  87. g.GT{a}.baselines = [];
  88. baseline_t = 0.25;
  89. for i = 1:size(g.GT{a}.trial,1)
  90. spiketimes = g.GT{a}.ras{i,spikeidx};
  91. nspikes = sum(spiketimes > g.GT{a}.stimon_t(i) & spiketimes < g.GT{a}.stimoff_t(i));
  92. g.GT{a}.spikerates = [g.GT{a}.spikerates; nspikes./(g.GT{a}.stimoff_t(i)-g.GT{a}.stimon_t(i))];
  93. nspikes = sum(spiketimes > g.GT{a}.stimon_t(i)-baseline_t & spiketimes < g.GT{a}.stimon_t(i));
  94. g.GT{a}.baselines = [g.GT{a}.baselines; nspikes./baseline_t];
  95. end
  96. end
  97. gtGuiHand = currentFigOpen('Grating Explorer');
  98. if isempty(gtGuiHand)
  99. g.figHand = figure;
  100. set(g.figHand, 'name', 'Grating Explorer', 'numbertitle', 'off')
  101. else
  102. g.figHand = gtGuiHand;
  103. end
  104. figure(g.figHand); %declare this to be the current fig
  105. analysisList = {'OrientCart'; 'OrientPolar'; 'SptFreq'; 'Diam'; 'Color'; 'CRF'; 'CVvsRate'; 'LFPSTA'; 'LFPSpect'};
  106. set(g.figHand, 'units', 'normalized', 'position', [0.0148 0.0813 0.4375 0.5250])
  107. g.listHand = uicontrol('style', 'popupmenu', 'string', analysisList, 'value', 1, 'callback', {@gratingAnalysis, g.figHand}, 'units', 'normalized', 'position', [0.02 0.89 .15 .1]);
  108. g.plotcolors = {'b', 'r', 'g', 'm', 'c', 'y'}; %for ploting multiple GT files
  109. set(g.figHand, 'userdata', g);
  110. gratingAnalysis([], [], g.figHand);
  111. end
  112. %setup the detection GUI
  113. if ~strcmpi(DTfname, 'input DT file') && ~isempty(DTfname)
  114. fPath = findfile(DTfname);
  115. if isempty(fPath)
  116. set(cPan.applyHand, 'string', 'DTspot file not found', 'FontSize', 11); %setting it back from 'finding files'
  117. set(cPan.applyHand,'BackgroundColor',[1 0.8 0.8]);
  118. drawnow;
  119. return
  120. end
  121. d.DT = dtobj(DTfname);
  122. [d.DT, d.grating] = stripOutGratingTrials(d.DT); %remove grating catch trials!!
  123. d.analParams.val.cellNum = 1;
  124. d.analParams.val.start = 'gabor on'; %gabor onset
  125. d.analParams.val.end = 'gabor off'; %gabor offset
  126. d.analParams.val.lowCutoff = 5; %min number of trials to compute cp
  127. d.analParams.val.meth = 'rate';
  128. [d.monk, d.cell, d.expt] = DTunpack(d.DT, d.analParams.val); %use the default params for the first analysis
  129. %initialize the dt gui
  130. dtGuiHand = currentFigOpen('Detection Explorer');
  131. if isempty(dtGuiHand);
  132. d.figHand = figure;
  133. set(d.figHand, 'name', 'Detection Explorer', 'numbertitle', 'off')
  134. else
  135. d.figHand = dtGuiHand;
  136. end
  137. figure(d.figHand) %declare this the current fig
  138. colorDir = reshape(d.DT.sum.exptParams.RF_colors, 3, 3)';
  139. colorDir(sum(abs(colorDir), 2) == 0, :) = [];
  140. norms = sqrt(sum(colorDir.^2, 2));
  141. colorDir = colorDir./repmat(norms, 1, 3);
  142. colorDir = num2str(colorDir, 2);
  143. plotTypes = {'CRF'; 'Raster'; 'PSTH'; 'CP'; 'CatchTrials'; 'Summary'};
  144. parseOpt = {'Flash Loc', 'Choice'};
  145. trigEvent = {'Flash On', 'Frame On', 'Go Sig', 'Sac Onset'};
  146. set(d.figHand, 'units', 'normalized', 'position', [0.4813 0.0410 0.5086 0.6475]);
  147. uicontrol('style', 'text', 'string', 'Color Direction', 'fontsize', 8, 'units', 'normalized', 'position', [0.015 .97 .12 .02],'backgroundColor', get(gcf, 'color'));
  148. d.colorDirHand = uicontrol('style', 'popupmenu', 'string', colorDir, 'value', 1, 'units', 'normalized', 'position', [.015 .867 .2 .1]);
  149. uicontrol('style', 'text', 'string', 'PlotType', 'fontsize', 8, 'units', 'normalized', 'position', [0.23 0.97 .1 .02], 'backgroundColor', get(gcf, 'color'));
  150. d.plotTypeHand = uicontrol('style', 'popupmenu', 'string', plotTypes, 'value', 1, 'units', 'normalized', 'position', [0.23 0.836 .12 .13]);
  151. uicontrol('style', 'text', 'string', 'Parse Opt', 'units', 'normalized', 'position', [0.37 0.97 .1 .02], 'backgroundColor', get(gcf, 'color'))
  152. d.parsOptHand = uicontrol('style', 'popupmenu', 'string', parseOpt, 'value', 1, 'units', 'normalized', 'position', [0.37 0.847 .12 .12]);
  153. uicontrol('style', 'text', 'string', 'Trigger Event', 'units', 'normalized', 'position', [0.5 0.97 .1 .02], 'backgroundColor', get(gcf, 'color'));
  154. d.trigEventHand = uicontrol('style', 'popupmenu', 'string', trigEvent, 'value', 1, 'units', 'normalized', 'position', [0.5 0.847 .12 .12]);
  155. uicontrol('style', 'text', 'string', 'Pre-Time', 'units', 'normalized', 'position', [0.64 0.97 .1 .02], 'backgroundColor', get(gcf, 'color'));
  156. d.preTimeHand = uicontrol('style', 'edit', 'string', num2str(200), 'units', 'normalized', 'position', [0.64 0.932 .1 .03]);
  157. uicontrol('style', 'text', 'string', 'Post-Time', 'units', 'normalized', 'position', [0.76 0.97 .1 .02], 'backgroundColor', get(gcf, 'color'));
  158. d.postTimeHand = uicontrol('style', 'edit', 'string', num2str(800), 'units', 'normalized', 'position', [0.76 0.932 .1 .03]);
  159. d.applyHand = uicontrol('style', 'pushbutton', 'string', 'Apply', 'callback', {@detectionAnalysis, d.figHand}, 'units', 'normalized', 'position', [0.88 0.93 .1 .04], 'fontsize', 9, 'interruptible', 'off', 'busyaction', 'cancel');
  160. set(d.figHand, 'userdata', d);
  161. detectionAnalysis([], [], d.figHand);
  162. end
  163. set(cPan.applyHand, 'string', 'Apply', 'FontSize', 11) %setting it back from 'finding files'
  164. drawnow
  165. end
  166. %
  167. % GRATING ANALYSIS
  168. % A router for subsequent GT analyses. This just calls analysis modules as
  169. % non-nested subfunctions
  170. %
  171. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  172. function gratingAnalysis(h, ev, gtFigHand);
  173. g = get(gtFigHand, 'userdata');
  174. %the uicontrols from the CRF window linger. force them to go away
  175. if isfield(g,'crfHand')
  176. set(cell2mat(struct2cell(g.crfHand)), 'visible', 'off')
  177. end
  178. analysisOptions = get(g.listHand, 'string');
  179. analysisIdx = get(g.listHand, 'value');
  180. analysisToRun = analysisOptions{analysisIdx};
  181. try
  182. feval([analysisToRun, '_GTanalysisFxn'], gtFigHand);
  183. catch
  184. wtf %for debugging
  185. end
  186. end
  187. function OrientCart_GTanalysisFxn(gtFigHand)
  188. g = get(gtFigHand, 'userdata');
  189. subplot(1,1,1); %reset the figure window
  190. figure(g.figHand)
  191. cla reset,
  192. hold on,
  193. for a = 1:length(g.GT);
  194. orienttrials = find(g.GT{a}.protocols == 1);
  195. %bail if there are no orient trials
  196. if isempty(orienttrials)
  197. continue
  198. end
  199. protocolswitches = orienttrials(find(diff(orienttrials) > 1)+1);
  200. starts = [find(orienttrials == 1,1,'first'); protocolswitches];
  201. stops = [];
  202. for i = 1:length(starts)
  203. if (i == length(starts))
  204. stops = [stops; max(orienttrials(orienttrials > starts(i)))];
  205. else
  206. stops = [stops; max(orienttrials(orienttrials > starts(i) & orienttrials < starts(i+1)))];
  207. end
  208. end
  209. for i = 1:length(starts)
  210. trlidxs = [starts(i):stops(i)];
  211. [trlidxs, p1params] = gratingCheckTrials(g.GT{a}, 'orient', trlidxs);
  212. x = g.GT{a}.orients(trlidxs);
  213. y = g.GT{a}.spikerates(trlidxs);
  214. Ltmp = x == min(x);
  215. y = [y; y(Ltmp)];
  216. x = [x; x(Ltmp)+2*pi];
  217. %pp = csape(x,y,'periodic');
  218. xx = linspace(0,2*pi,100);
  219. %fit = ppval(pp,xx);
  220. subplot(1,length(starts),i);
  221. hold on;
  222. plot(180/pi*x,y, [g.plotcolors{a},'.']);
  223. %plot(180/pi*xx,fit, g.plotcolors{a});
  224. sf = unique(g.GT{a}.sfs(trlidxs)); % For axis label
  225. title(['SF: ',num2str(p1params.sf),' cyc/deg']);
  226. xlabel('orientation (deg)');
  227. ylabel('response (sp/sec)');
  228. set(gca,'YLim',[0 max(g.GT{a}.spikerates)]);
  229. mu = []; sem = [];
  230. for j = unique(x)'
  231. mu(find(j == unique(x)))= mean(y(x==j));
  232. sem(find(j == unique(x))) = std(y(x==j))/sqrt(sum(x==j));
  233. end
  234. errorbar(unique(x)*180/pi,mu,sem, g.plotcolors{a});
  235. plot([0 max(x)*180/pi], repmat(mean(g.GT{a}.baselines),1,2),[g.plotcolors{a},':']);
  236. cd = unique(g.GT{a}.colordirections(trlidxs,:),'rows');
  237. t = text(.8*max(x),0.1*max(mu),['color direction: ',num2str(p1params.color*100,'%2.1d, %2.1d, %2.1d')]);
  238. set(t, 'color', g.plotcolors{a});
  239. axis tight
  240. drawnow
  241. end
  242. end
  243. end
  244. function OrientPolar_GTanalysisFxn(gtFigHand)
  245. g = get(gtFigHand, 'userdata');
  246. figure(g.figHand)
  247. subplot(1,1,1);
  248. cla reset,
  249. mu = {};
  250. sem = {};
  251. uniqX = {};
  252. for a = 1:length(g.GT)
  253. orienttrials = find(g.GT{a}.protocols == 1);
  254. protocolswitches = orienttrials(find(diff(orienttrials) > 1)+1);
  255. starts = [find(orienttrials == 1,1,'first'); protocolswitches];
  256. stops = [];
  257. for i = 1:length(starts)
  258. if (i == length(starts))
  259. stops = [stops; max(orienttrials(orienttrials > starts(i)))];
  260. else
  261. stops = [stops; max(orienttrials(orienttrials > starts(i) & orienttrials < starts(i+1)))];
  262. end
  263. end
  264. for i = 1:length(starts)
  265. trlidxs = [starts(i):stops(i)];
  266. trlidxs = gratingCheckTrials(g.GT{a}, 'orient', trlidxs);
  267. x = g.GT{a}.orients(trlidxs);
  268. y = g.GT{a}.spikerates(trlidxs);
  269. Ltmp = x == min(x);
  270. y = [y; y(Ltmp)];
  271. x = [x; x(Ltmp)+2*pi];
  272. pp = csape(x,y,'periodic');
  273. xx = linspace(0,2*pi,100);
  274. fit = ppval(pp,xx);
  275. for j = unique(x)'
  276. mu{a,i}(find(j == unique(x)))= mean(y(x==j));
  277. sem{a,i}(find(j == unique(x))) = std(y(x==j))/sqrt(sum(x==j));
  278. end
  279. uniqX{a,i} = unique(x)';
  280. end
  281. maxEcc(a) = 0;
  282. for i = 1:length(starts)
  283. ecc = max(mu{a,i} + sem{a,i});
  284. maxEcc(a) = max([maxEcc(a) ecc]);
  285. end
  286. end
  287. %plotting
  288. [val, exptWithMax] = max(maxEcc);
  289. plotOrder = 0:length(g.GT);
  290. plotOrder(plotOrder == exptWithMax) = [];
  291. plotOrder(1) = exptWithMax;
  292. for a = 1:length(g.GT)
  293. exptToPlot = plotOrder(a);
  294. for i = 1:size(mu, 2);
  295. if a > size(uniqX,1) %some times there's no orient data.
  296. continue
  297. end
  298. polar(uniqX{exptToPlot, i},mu{exptToPlot, i}+sem{exptToPlot, i}, [g.plotcolors{exptToPlot}, ':']);
  299. hold on,
  300. h = polar(uniqX{exptToPlot, i},mu{exptToPlot, i}, g.plotcolors{exptToPlot});
  301. set(h,'LineWidth',2);
  302. polar(uniqX{exptToPlot, i},mu{exptToPlot, i}-sem{exptToPlot, i}, [g.plotcolors{exptToPlot}, ':']);
  303. %polar(linspace(0,2*pi,100),repmat(mean(g.GT{a}.baselines),1,100), g.plotcolors{a});
  304. end
  305. end
  306. end
  307. function SptFreq_GTanalysisFxn(gtFigHand)
  308. g = get(gtFigHand, 'userdata');
  309. subplot(1,1,1); %reset the figure window
  310. cla reset,
  311. hold on,
  312. axes
  313. for a = 1:length(g.GT)
  314. sftrials = find(g.GT{a}.protocols == 2);
  315. protocolswitches = sftrials(find(diff(sftrials) > 1)+1);
  316. starts = [min(sftrials); protocolswitches];
  317. stops = [];
  318. for i = 1:length(starts)
  319. if (i == length(starts))
  320. stops = [stops; max(sftrials(sftrials > starts(i)))];
  321. else
  322. stops = [stops; max(sftrials(sftrials > starts(i) & sftrials < starts(i+1)))];
  323. end
  324. end
  325. for i = 1:length(starts)
  326. trlidxs = [starts(i):stops(i)];
  327. [trlidxs, p2params] = gratingCheckTrials(g.GT{a}, 'sptFreq', trlidxs);
  328. x = g.GT{a}.sfs(trlidxs);
  329. y = g.GT{a}.spikerates(trlidxs);
  330. pp = csape(x,y,'variational');
  331. xx = linspace(min(g.GT{a}.sfs),max(g.GT{a}.sfs),100);
  332. fit = ppval(pp,xx);
  333. subplot(1,length(starts),i);
  334. hold on;
  335. plot(x,y,[g.plotcolors{a},'.']);
  336. plot(xx,fit,[g.plotcolors{a}, '-']);
  337. orient = unique(g.GT{a}.orients(trlidxs)); % for axis labeling
  338. title(['orientation: ',num2str(p2params.orient*180/pi),' deg']);
  339. set(gca,'XScale','log');
  340. xlabel('spatial frequency (cyc/deg)');
  341. ylabel('response (sp/sec)');
  342. set(gca,'YLim',[0 max(g.GT{a}.spikerates)]);
  343. mu = []; sem = [];
  344. for j = unique(x)'
  345. mu(find(j == unique(x)))= mean(y(x==j));
  346. sem(find(j == unique(x))) = std(y(x==j))/sqrt(sum(x==j));
  347. end
  348. end
  349. if ~isempty(starts)
  350. errorbar(unique(x),mu,sem, [g.plotcolors{a}, '-']);
  351. plot([min(x) max(x)], repmat(mean(g.GT{a}.baselines),1,2),[g.plotcolors{a}, ':']);
  352. axis tight
  353. end
  354. end
  355. end
  356. function Diam_GTanalysisFxn(gtFigHand)
  357. g = get(gtFigHand, 'userdata');
  358. figure(g.figHand);
  359. subplot(1,1,1)
  360. cla reset,
  361. hold on,
  362. for a = 1:length(g.GT)
  363. if (any(g.GT{a}.protocols == 5))
  364. Lprotocol = g.GT{a}.protocols == 5;
  365. uniquesizes = unique(g.GT{a}.diams(Lprotocol));
  366. else
  367. continue % nothing to do
  368. end
  369. mu = []; sem = [];
  370. for i = 1:length(uniquesizes)
  371. L = Lprotocol & g.GT{a}.diams == uniquesizes(i);
  372. tList = find(L);
  373. tList = gratingCheckTrials(g.GT{a}, 'diam', tList);
  374. L = zeros(size(L));
  375. L(tList) = 1; %just a hack to use gratingCheckTrials
  376. L = logical(L);
  377. mu = [mu; mean(g.GT{a}.spikerates(L))];
  378. sem = [sem; sqrt(var(g.GT{a}.spikerates(L))/sum(L))];
  379. end
  380. errorbar(uniquesizes, mu, sem, g.plotcolors{a});
  381. xlabel('Aperture diameter (deg)');
  382. ylabel('sp/sec');
  383. end
  384. end
  385. function Color_GTanalysisFxn(gtFigHand)
  386. g = get(gtFigHand, 'userdata');
  387. subplot(1,1,1); %reset the figure window
  388. cla reset,
  389. hold on,
  390. for a = 1:length(g.GT)
  391. Lprotocol = g.GT{a}.protocols == 4;
  392. if (any(Lprotocol))
  393. uniquecolordirs = unique(g.GT{a}.colordirections(Lprotocol,:),'rows');
  394. data = [];
  395. for i = 1:size(uniquecolordirs,1)
  396. L = Lprotocol &...
  397. g.GT{a}.colordirections(:,1) == uniquecolordirs(i,1) & ...
  398. g.GT{a}.colordirections(:,2) == uniquecolordirs(i,2) & ...
  399. g.GT{a}.colordirections(:,3) == uniquecolordirs(i,3);
  400. tList = find(L);
  401. tList = gratingCheckTrials(g.GT{a}, 'color', tList);
  402. L = zeros(size(L));
  403. L(tList) = 1; %just a hack to use gratingCheckTrials
  404. L = logical(L);
  405. data = [data; mean(g.GT{a}.spikerates(L)) sqrt(var(g.GT{a}.spikerates(L))/sum(L))];
  406. nTrials(i) = sum(L);
  407. end
  408. % Plotting
  409. basis = [1 1 0; 1 -1 0; 0 0 1];
  410. DKLs = (basis*uniquecolordirs')';
  411. coordinates = sign(DKLs);
  412. peakfr = max(data(:,1));
  413. labels = {'L+M','L-M';'S','L-M';'S','L+M'};
  414. for i = 1:3
  415. subplot(1,3,i);
  416. polar(0,peakfr, g.plotcolors{a});
  417. hold on;
  418. polar(linspace(0,2*pi,100), repmat(mean(g.GT{a}.baselines),1,100), g.plotcolors{a});
  419. if a == 1
  420. text(0,2*peakfr,labels{i,1},'HorizontalAlignment','center');
  421. text(.7*peakfr,.15*peakfr,labels{i,2});
  422. end
  423. end
  424. for i = 1:size(uniquecolordirs,1)
  425. subplot(1,3,1);
  426. if (coordinates(i,3) == 0)
  427. theta = atan2(coordinates(i,1),coordinates(i,2));
  428. polarerrbar(theta, data(i,1), data(i,2), g.plotcolors{a});
  429. end
  430. subplot(1,3,2);
  431. if (coordinates(i,1) == 0)
  432. theta = atan2(coordinates(i,3),coordinates(i,2));
  433. polarerrbar(theta, data(i,1), data(i,2), g.plotcolors{a});
  434. end
  435. subplot(1,3,3);
  436. if (coordinates(i,2) == 0)
  437. theta = atan2(coordinates(i,3),coordinates(i,1));
  438. polarerrbar(theta, data(i,1), data(i,2), g.plotcolors{a});
  439. end
  440. end
  441. for i = 1:3
  442. subplot(1,3,i);
  443. polar(linspace(0,2*pi,100),repmat(mean(g.GT{a}.baselines),1,100), [g.plotcolors{a}, ':']);
  444. end
  445. if length(g.GT) == 1;
  446. %charlie's addition for determining the pref color and the CSI
  447. [dummy, lumIdx] = ismember([1 1 0], sign(uniquecolordirs), 'rows');
  448. lumResp = data(lumIdx, 1);
  449. isoLumBasis = [1, -1, 0; 0, 0, 1; -0.0636, 0.0636, 0.45; -0.0636, 0.0636, -0.45];
  450. isoLumNorms = sqrt(sum(isoLumBasis.^2,2));
  451. isoLumUnits = isoLumBasis ./ repmat(isoLumNorms, 1, 3);
  452. uniqueColorNorms = sqrt(sum(uniquecolordirs.^2,2));
  453. uniqueColorUnits = uniquecolordirs ./ repmat(uniqueColorNorms, 1, 3);
  454. for a = 1:size(isoLumBasis, 1);
  455. clrIdx = abs(isoLumUnits(a,:) * uniqueColorUnits') > (1-eps);
  456. isoLumResp(a) = data(clrIdx,1);
  457. end
  458. [maxIsoLumResp, maxIdx] = max(isoLumResp);
  459. CSI = maxIsoLumResp./lumResp;
  460. prefColorIdx = abs(isoLumUnits(maxIdx,:) * uniqueColorUnits') > (1-eps);
  461. prefColor = uniquecolordirs(prefColorIdx, :);
  462. % Greg's linear model stuff
  463. % This should really be a weighted regression, but for now just
  464. % fitting the mean responses.
  465. signmat = 2*fullfact(repmat(2,size(uniquecolordirs,1),1))-3;
  466. normedcolordirs = mkbasis(uniquecolordirs')';
  467. normedresponses = data(:,1)./sqrt(sum(transpose(uniquecolordirs.^2)))';
  468. err = Inf;
  469. for i = 1:size(signmat,1)
  470. b = regress(normedresponses,normedcolordirs.*repmat(signmat(i,:)',1,3));
  471. pred = (normedcolordirs.*repmat(signmat(i,:)',1,3))*b;
  472. if (norm(pred-normedresponses) < err)
  473. linmodelprefcolor = b;
  474. err = norm(pred-normedresponses);
  475. end
  476. end
  477. linmodelprefcolor = mkbasis(linmodelprefcolor);
  478. if (sum(sign(linmodelprefcolor)) <= -2)
  479. linmodelprefcolor = -linmodelprefcolor;
  480. end
  481. textax = axes('position',[.25 .2, .5, .1]);
  482. set(textax,'DefaultTextHorizontalAlignment','center')
  483. text(.5,.9, sprintf('Pref Color: [%s] \n CSI: %.2f', num2str(prefColor, 3), CSI));
  484. text(.5,.4, sprintf('Cone weights from linear model: [%s]', num2str(linmodelprefcolor', 3)));
  485. text(.5, .1, sprintf('Min Num Trials: %d', min(nTrials)));
  486. set(textax,'Visible','off');
  487. end
  488. end
  489. end
  490. % Support function for grating analysis
  491. function polarerrbar(theta, x, e, color)
  492. p(1)=polar([theta theta], [x-e x+e], [color, '-']);
  493. p(2)=polar([theta+pi theta+pi], [x-e x+e], [color, '-']);
  494. p(3)=polar(theta, x, [color, '.']);
  495. p(4)=polar(theta+pi, x, [color, '.']);
  496. set(p, 'markersize', 15, 'linewidth', 3)
  497. end
  498. end
  499. function CRF_GTanalysisFxn(gtFigHand)
  500. g = get(gtFigHand, 'userdata');
  501. %pick a color direction to analyze
  502. g.crfHand.color = uicontrol('style', 'popupmenu', 'string', num2str([1, -1, 0; 0, 0, 1]), 'callback', @plotGTcrf, 'value', 1, 'units', 'normalized', 'position', [0.4 0.87 .12 .12]);
  503. g.crfHand.text = uicontrol('style', 'text', 'string', 'Color Dir', 'units', 'normalized', 'position', [0.28 0.94 .1 .04]);
  504. set(gtFigHand, 'userdata', g); %so that the uicontrols can be deleted later
  505. plotGTcrf(1, 1); %call the subFxn with some dummy arguments.
  506. function plotGTcrf(ev, h)
  507. subplot(1,1,1); %reset the figure window
  508. cla reset,
  509. menuVal = get(g.crfHand.color, 'value');
  510. colorDirs = get(g.crfHand.color, 'string');
  511. colorToPlot = str2num(colorDirs(menuVal,:));
  512. legendText = {};
  513. linetype = {'-', '--', ':'};
  514. hold on,
  515. for exptNum = 1:length(g.GT);
  516. LMS = g.GT{exptNum}.colordirections;
  517. l_color = ismember(sign(LMS), colorToPlot, 'rows');
  518. l_crf = g.GT{exptNum}.protocols == 7;
  519. % if sum(l_crf) ==0
  520. % continue %nothing to do.
  521. % end
  522. tmp = unique(LMS((l_color & l_crf), :), 'rows');
  523. contrasts = zeros(size(tmp,1)+1, 3);
  524. contrasts(2:size(tmp,1)+1, :) = tmp; %add the zero contrast cond.
  525. norms = sqrt(sum(contrasts.^2, 2));
  526. gtmu = []; gtsem = [];
  527. for a = 1:size(contrasts,1)
  528. l_contrasts = softEq(contrasts(a,:), LMS, 5, 'rows');
  529. if a == 1;
  530. l_trials = l_contrasts;
  531. else
  532. l_trials = l_crf & l_color & l_contrasts;
  533. end
  534. gtmu(a) = mean(g.GT{exptNum}.spikerates(l_trials));
  535. gtsem(a) = std(g.GT{exptNum}.spikerates(l_trials)) ./ sqrt(sum(l_trials));
  536. nGTTrials(exptNum, a) = sum(l_trials);
  537. end
  538. % set up the plot
  539. if length(g.GT) < 3;
  540. if sum(colorToPlot) == 1;
  541. lineColor = 'b';
  542. elseif sum(colorToPlot) == 0;
  543. lineColor = 'r';
  544. end
  545. linestyle = linetype{exptNum};
  546. else
  547. lineColor = g.plotcolors{exptNum};
  548. linestyle = '-';
  549. end
  550. if all(~isnan(gtmu))
  551. errorbar(norms, gtmu, gtsem, [lineColor, '.', linestyle])
  552. legendText{exptNum} = sprintf('GT run: %d', exptNum);
  553. end
  554. end
  555. %determine if there is any DT data (from the same color dir) to plot.
  556. dtFigHand = currentFigOpen('Detection Explorer');
  557. if ~isempty(dtFigHand)
  558. d = get(dtFigHand, 'userdata');
  559. clrIdx = ismember(sign(d.expt.standColors), colorToPlot, 'rows');
  560. if any(clrIdx)
  561. dtmu = cellfun(@mean, d.cell.crfIn{clrIdx});
  562. dtsigma = cellfun(@std, d.cell.crfIn{clrIdx});
  563. nTrials = cellfun(@length, d.cell.crfIn{clrIdx});
  564. dtsem = dtsigma./sqrt(nTrials);
  565. errorbar(d.expt.norms{clrIdx}, dtmu, dtsem, 'k.:')
  566. legendText{end+1} = 'Detection';
  567. end
  568. end
  569. %tidy up the plot
  570. set(gca, 'xscale', 'log')
  571. axis tight
  572. hold off
  573. set(gtFigHand, 'userdata', g); %so that the uicontrols can be deleted later
  574. hold off
  575. if ~isempty(legendText)
  576. legend(legendText, 'location', 'northwest')
  577. xlabel(sprintf('Min Num Trials = [%s] (one N per GT expt)', num2str(min(nGTTrials, [], 2)')))
  578. end
  579. end
  580. end
  581. function LFPSpect_GTanalysisFxn(gtFigHand)
  582. end
  583. %
  584. % DETECTION ANALYSIS
  585. %
  586. % gets evaluated when the apply button on the Detection analysis sub-pannel
  587. % is pressed. Basically just redirects to the appropriate analysis module
  588. %
  589. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  590. function detectionAnalysis(h, ev, dtFigHand);
  591. d = get(dtFigHand, 'userdata');
  592. %the uicontrols from the summary window linger. force them to go away
  593. if isfield(d.analParams,'hand')
  594. set(cell2mat(struct2cell(d.analParams.hand)), 'visible', 'off')
  595. end
  596. %call the appropriate sub function based on what type of plot the user
  597. %wants to compute.
  598. plotType = get(d.plotTypeHand, 'string');
  599. plotTypeIdx = get(d.plotTypeHand, 'value');
  600. plotType = plotType{plotTypeIdx};
  601. endString = '_analysisFxn';
  602. feval([plotType, endString], dtFigHand);
  603. end
  604. %
  605. % CRF ANALYSIS MODULE FOR (DT)
  606. %
  607. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  608. function CRF_analysisFxn(dtFigHand)
  609. d = get(dtFigHand, 'userdata');
  610. %first for in the RF
  611. whichColorDir = get(d.colorDirHand, 'value');
  612. statAvgIn = cellfun(@mean, d.cell.crfIn{whichColorDir});
  613. statStd = cellfun(@std, d.cell.crfIn{whichColorDir});
  614. statN = cellfun(@length, d.cell.crfIn{whichColorDir});
  615. stdErrIn = statStd./sqrt(statN);
  616. %now for out of the RF
  617. statAvgOut = cellfun(@mean, d.cell.crfOut{whichColorDir});
  618. statStd = cellfun(@std, d.cell.crfOut{whichColorDir});
  619. statN = cellfun(@length, d.cell.crfOut{whichColorDir});
  620. stdErrOut = statStd./sqrt(statN);
  621. %plotting
  622. figure(d.figHand); % assert this as the current fig
  623. subplot(1, 1, 1)% set things back to just one axis
  624. hold on,
  625. set(gca, 'position', [0.15 0.13 .7 .75])
  626. errorbar(d.expt.norms{whichColorDir}, statAvgIn, stdErrIn, 'b');
  627. errorbar(d.expt.norms{whichColorDir}, statAvgOut, stdErrOut, 'k');
  628. set(gca, 'xlim', [d.expt.norms{whichColorDir}(2).*.97 max(d.expt.norms{whichColorDir}).*1.02]);
  629. set(gca, 'xscale', 'log')
  630. set(gca, 'xticklabel', (10.^str2num(get(gca, 'xticklabel')).*100))
  631. set(get(gca, 'ylabel'), 'string', 'Avg Trial Stat', 'fontsize', 12)
  632. set(get(gca, 'xlabel'), 'string', 'Percent Cone Contrast', 'fontsize', 12)
  633. set(get(gca, 'children'), 'linewidth', 2)
  634. legend('In RF', 'Out of RF')
  635. legend boxoff
  636. hold off
  637. end
  638. %
  639. % RASTER ANALYSIS MODULE (DT)
  640. %
  641. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  642. function Raster_analysisFxn(dtFigHand)
  643. d = get(dtFigHand, 'userdata');
  644. subplot(1, 1, 1) %clear out the old data.
  645. colorDirInd = strmatch('color_dir', [d.DT.sum.trialFields(1,:)]);
  646. flashXInd = strmatch('flash_x', [d.DT.sum.trialFields(1,:)]);
  647. flashYInd = strmatch('flash_y', [d.DT.sum.trialFields(1,:)]);
  648. correctInd = strmatch('correct', [d.DT.sum.trialFields(1,:)]);
  649. cntrstLevInd = strmatch('cntrst_lev', [d.DT.sum.trialFields(1,:)]);
  650. %unpack the user settings
  651. colorDir = get(d.colorDirHand, 'value');
  652. parseOpt = get(d.parsOptHand, 'string');
  653. parseIdx = get(d.parsOptHand, 'value');
  654. parseOpt = parseOpt{parseIdx};
  655. trigOpt = get(d.trigEventHand, 'string');
  656. trigIdx = get(d.trigEventHand, 'value');
  657. trigOpt = trigOpt{trigIdx};
  658. preTime = str2num(get(d.preTimeHand, 'string'))./1000;
  659. postTime = str2num(get(d.postTimeHand, 'string'))./1000;
  660. %determine which index in the stro.trial field to extract the time zero
  661. %value. This will be specified by the trigOpt.
  662. flashOnIdx = strmatch('rep_flash_on', [d.DT.sum.trialFields(1,:)]);
  663. frameOnIdx = strmatch('frame_on', [d.DT.sum.trialFields(1,:)]);
  664. targOnIdx = strmatch('targ_on', [d.DT.sum.trialFields(1,:)]);
  665. choiceTimeIdx = strmatch('choice_time', [d.DT.sum.trialFields(1,:)]);
  666. numFramesIdx = strmatch('numframes', [d.DT.sum.trialFields(1,:)]);
  667. switch lower(trigOpt)
  668. case 'flash on'
  669. timeZeroIdx = flashOnIdx;
  670. case 'frame on'
  671. timeZeroIdx = frameOnIdx;
  672. case 'go sig'
  673. timeZeroIdx = targOnIdx;
  674. case 'sac onset'
  675. timeZeroIdx = choiceTimeIdx;
  676. end
  677. % loop twice, one for each parse option.
  678. maxNumTrials = 0;
  679. numContrasts = length(unique(d.DT.trial(:,cntrstLevInd)));
  680. axAddress = reshape(1:numContrasts.*2, 2, numContrasts)';
  681. subPlotCounter = 0;
  682. for a = 1:2
  683. l_color = d.DT.trial(:,colorDirInd) == colorDir;
  684. switch lower(parseOpt)
  685. case 'choice'
  686. rfx = d.DT.sum.exptParams.rf_x;
  687. rfy = d.DT.sum.exptParams.rf_y;
  688. inRF = (d.DT.trial(:,flashXInd) == rfx) & (d.DT.trial(:,flashYInd) == rfy);
  689. corrects = d.DT.trial(:, correctInd);
  690. T1choices = zeros(size(d.DT.trial, 1), 1);
  691. T1choices(corrects & inRF) = 1; %in the RF and correct
  692. T1choices(~corrects & ~inRF) = 1; %incorrect but not in the RF
  693. if a == 1
  694. l_parseOpt = T1choices;
  695. elseif a == 2
  696. l_parseOpt = ~T1choices;
  697. end
  698. case 'flash loc'
  699. rfx = d.DT.sum.exptParams.rf_x;
  700. rfy = d.DT.sum.exptParams.rf_y;
  701. inRF = (d.DT.trial(:,flashXInd) == rfx) & (d.DT.trial(:,flashYInd) == rfy);
  702. if a == 1
  703. l_parseOpt = inRF;
  704. elseif a == 2
  705. l_parseOpt = ~inRF;
  706. end
  707. end
  708. %loop through the trials (cntrst by cntrst) making raster plots
  709. for cntrst = 1:numContrasts;
  710. l_contrast = d.DT.trial(:, cntrstLevInd) == cntrst;
  711. if cntrst == 1; %treat the 'zero' contrast separately
  712. tList = (l_contrast & l_parseOpt);
  713. else
  714. tList = (l_color & l_contrast & l_parseOpt);
  715. end
  716. %place the subplot window in a reasonable place. then do the plotting\
  717. subPlotCounter = subPlotCounter+1;
  718. spHand(subPlotCounter) = subplot(numContrasts, 2, axAddress(cntrst, a));
  719. height = (0.8./numContrasts) .* 0.8;
  720. currentPos = get(gca, 'position');
  721. currentPos(end) = height;
  722. currentPos(2) = currentPos(2) - .02;
  723. set(gca, 'position', currentPos)
  724. hold on,
  725. zeroTimes = mat2cell(d.DT.trial(tList, timeZeroIdx), ones(sum(tList),1),1);
  726. spikeTimes = cellfun(@(x,y)(x-y), d.DT.ras(tList,d.expt.cellNum), zeroTimes, 'UniformOutput', 0);
  727. counter = mat2cell([0:sum(tList)-1]', ones(sum(tList), 1), 1);
  728. cellfun(@(x, y)plot([x, x]', [zeros(1,length(x))+y; [ones(1, length(x)).*0.8 + y]], 'k'), spikeTimes, counter);
  729. %mark the relavant trial events
  730. plot([d.DT.trial(tList, frameOnIdx) - d.DT.trial(tList, timeZeroIdx)], [0:sum(tList)-1]+0.5, 'r.');%frame on
  731. plot([d.DT.trial(tList, flashOnIdx) - d.DT.trial(tList, timeZeroIdx)], [0:sum(tList)-1]+0.5, 'c.');%flash onset
  732. stimOffTime = [d.DT.trial(tList, flashOnIdx) - d.DT.trial(tList, timeZeroIdx)] + [d.DT.trial(tList, numFramesIdx)./d.DT.sum.exptParams.frame_rate];
  733. plot(stimOffTime, [0:sum(tList)-1], 'b.'); %flash offset
  734. plot([d.DT.trial(tList, targOnIdx) - d.DT.trial(tList, timeZeroIdx)], [0:sum(tList)-1], 'g.'); %go signal
  735. plot([d.DT.trial(tList, choiceTimeIdx) - d.DT.trial(tList, timeZeroIdx)], [0:sum(tList)-1], 'm.') %sac time
  736. hold off,
  737. %keep track of the nTrials and use this to scale all the axes
  738. maxNumTrials = max(maxNumTrials, sum(tList));
  739. end
  740. end
  741. %now loop through again, this time standardizing the axes
  742. subPlotCounter = 0;
  743. for a = 1:2;
  744. for cntrst = 1:numContrasts;
  745. subPlotCounter = subPlotCounter+1;
  746. set(spHand(subPlotCounter), 'ytick', [], 'xtick', [-preTime, 0, postTime], 'xticklabel', [], 'box', 'off')
  747. set(spHand(subPlotCounter), 'ylim', [0 maxNumTrials+1], 'xlim', [-preTime postTime]);
  748. if a == 1;
  749. set(get(spHand(subPlotCounter), 'ylabel'), 'string', num2str(cntrst-1));
  750. end
  751. if cntrst == numContrasts;
  752. set(spHand(subPlotCounter), 'xticklabel', [-preTime, 0, postTime]);
  753. set(get(spHand(subPlotCounter), 'xlabel'), 'string', sprintf('Parse Opt %d', a));
  754. end
  755. end
  756. end
  757. end
  758. %
  759. % PSTH ANALYSIS MODULE (DT)
  760. %
  761. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  762. function PSTH_analysisFxn(dtFigHand)
  763. d = get(dtFigHand, 'userdata');
  764. subplot(1, 1, 1) %clear out the old data.
  765. colorDirInd = strmatch('color_dir', [d.DT.sum.trialFields(1,:)]);
  766. flashXInd = strmatch('flash_x', [d.DT.sum.trialFields(1,:)]);
  767. flashYInd = strmatch('flash_y', [d.DT.sum.trialFields(1,:)]);
  768. correctInd = strmatch('correct', [d.DT.sum.trialFields(1,:)]);
  769. cntrstLevInd = strmatch('cntrst_lev', [d.DT.sum.trialFields(1,:)]);
  770. %unpack the user settings
  771. colorDir = get(d.colorDirHand, 'value');
  772. parseOpt = get(d.parsOptHand, 'string');
  773. parseIdx = get(d.parsOptHand, 'value');
  774. parseOpt = parseOpt{parseIdx};
  775. trigOpt = get(d.trigEventHand, 'string');
  776. trigIdx = get(d.trigEventHand, 'value');
  777. trigOpt = trigOpt{trigIdx};
  778. preTime = str2num(get(d.preTimeHand, 'string'))./1000;
  779. postTime = str2num(get(d.postTimeHand, 'string'))./1000;
  780. %determine which index in the stro.trial field to extract the time zero
  781. %value. This will be specified by the trigOpt.
  782. flashOnIdx = strmatch('rep_flash_on', [d.DT.sum.trialFields(1,:)]);
  783. frameOnIdx = strmatch('frame_on', [d.DT.sum.trialFields(1,:)]);
  784. targOnIdx = strmatch('targ_on', [d.DT.sum.trialFields(1,:)]);
  785. choiceTimeIdx = strmatch('choice_time', [d.DT.sum.trialFields(1,:)]);
  786. numFramesIdx = strmatch('numframes', [d.DT.sum.trialFields(1,:)]);
  787. switch lower(trigOpt)
  788. case 'flash on'
  789. timeZeroIdx = flashOnIdx;
  790. case 'frame on'
  791. timeZeroIdx = frameOnIdx;
  792. case 'go sig'
  793. timeZeroIdx = targOnIdx;
  794. case 'sac onset'
  795. timeZeroIdx = choiceTimeIdx;
  796. end
  797. % loop twice, one for each parse option.
  798. maxRate = 0;
  799. numContrasts = length(unique(d.DT.trial(:,cntrstLevInd)));
  800. axAddress = reshape(1:numContrasts.*2, 2, numContrasts)';
  801. for a = 1:2
  802. l_color = d.DT.trial(:,colorDirInd) == colorDir;
  803. switch lower(parseOpt)
  804. case 'choice'
  805. rfx = d.DT.sum.exptParams.rf_x;
  806. rfy = d.DT.sum.exptParams.rf_y;
  807. inRF = (d.DT.trial(:,flashXInd) == rfx) & (d.DT.trial(:,flashYInd) == rfy);
  808. corrects = d.DT.trial(:, correctInd);
  809. T1choices = zeros(size(d.DT.trial, 1), 1);
  810. T1choices(corrects & inRF) = 1; %in the RF and correct
  811. T1choices(~corrects & ~inRF) = 1; %incorrect but not in the RF
  812. if a == 1
  813. l_parseOpt = T1choices;
  814. elseif a == 2
  815. l_parseOpt = ~T1choices;
  816. end
  817. case 'flash loc'
  818. rfx = d.DT.sum.exptParams.rf_x;
  819. rfy = d.DT.sum.exptParams.rf_y;
  820. inRF = (d.DT.trial(:,flashXInd) == rfx) & (d.DT.trial(:,flashYInd) == rfy);
  821. if a == 1
  822. l_parseOpt = inRF;
  823. elseif a == 2
  824. l_parseOpt = ~inRF;
  825. end
  826. end
  827. %loop through the trials (cntrst by cntrst) making raster plots
  828. for cntrst = 1:numContrasts;
  829. l_contrast = d.DT.trial(:, cntrstLevInd) == cntrst;
  830. if cntrst == 1; %treat the 'zero' contrast separately
  831. tList = (l_contrast & l_parseOpt);
  832. else
  833. tList = (l_color & l_contrast & l_parseOpt);
  834. end
  835. %place the subplot window in a reasonable place. then do the plotting
  836. subplot(numContrasts, 2, axAddress(cntrst, a));
  837. hold on,
  838. zeroTimes = mat2cell(d.DT.trial(tList, timeZeroIdx), ones(sum(tList),1),1);
  839. spikeTimes = cellfun(@(x,y)(x-y), d.DT.ras(tList,d.expt.cellNum), zeroTimes, 'UniformOutput', 0);
  840. binSize = 0.025;
  841. edges = -preTime:binSize:postTime;
  842. edges = mat2cell(repmat(edges, sum(tList), 1), ones(sum(tList),1), length(edges));
  843. countsPerBin = cellfun(@(x, y)histc(x, y), spikeTimes, edges, 'uniformoutput', 0);
  844. countsPerBin = cellfun(@(x)(x(:)'), countsPerBin, 'uniformoutput', 0); %allign for vertcat
  845. countsPerBin = vertcat(countsPerBin{:});
  846. avgCountsPerBin = mean(countsPerBin, 1);
  847. avgRatePerBin = avgCountsPerBin ./ binSize;
  848. if (~isempty(avgCountsPerBin))
  849. bar(edges{1}, avgRatePerBin, 1);
  850. end
  851. %keep track of the nTrials and use this to scale all the axes
  852. maxRate = max(max(avgRatePerBin), maxRate);
  853. end
  854. end
  855. %now loop through again, this time standardizing the axes
  856. for a = 1:2;
  857. for cntrst = 1:numContrasts;
  858. subplot(numContrasts, 2, axAddress(cntrst, a))
  859. hold on,
  860. plot([0, 0], [0, maxRate], 'k', 'linewidth', 2);
  861. hold off,
  862. set(gca, 'ytick', [0, round(maxRate./2), maxRate], 'yticklabel', [], 'xtick', [-preTime, 0, postTime], 'xticklabel', [], 'box', 'off')
  863. ylim([0 maxRate]);
  864. xlim([-preTime postTime]);
  865. if a == 1;
  866. ylabel(num2str(cntrst-1));
  867. end
  868. if cntrst == numContrasts;
  869. set(gca, 'xticklabel', [-preTime, 0, postTime]);
  870. xlabel(sprintf('Parse Opt %d', a));
  871. if a == 1;
  872. set(gca, 'yticklabel', [0, round(maxRate./2), maxRate])
  873. end
  874. end
  875. %make sure the size of the subplot is o.k
  876. height = (0.8./numContrasts) .* 0.8;
  877. currentPos = get(gca, 'position');
  878. currentPos(end) = height;
  879. currentPos(2) = currentPos(2) - .02;
  880. set(gca, 'position', currentPos)
  881. end
  882. end
  883. end
  884. %
  885. % CHOICE PROBABILITY MODULE (DT)
  886. %
  887. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  888. function CP_analysisFxn(dtFigHand)
  889. d = get(dtFigHand, 'userdata');
  890. colorDir = get(d.colorDirHand, 'value');
  891. figure(d.figHand) %assert as the current fig
  892. subplot(1,1,1); %clear out the old axes
  893. hold on,
  894. plot((1:length(d.expt.norms{colorDir, 1})), d.cell.cp.in{colorDir, 1}, 'g.', 'markersize', 15)
  895. plot((1:length(d.expt.norms{colorDir, 1})), d.cell.cp.out{colorDir, 1}, 'k.', 'markersize', 15)
  896. plot([0.5 length(d.expt.norms{colorDir, 1})+0.5], [0.5 0.5], 'k:')
  897. set(gca, 'xtick', [1:length(d.expt.norms{colorDir, 1})], 'xticklabel', round(d.expt.norms{colorDir, 1}.*10000)./100)
  898. set(gca, 'units', 'normalized', 'position', [0.13 0.49 0.775 0.4])
  899. ylim([0 1])
  900. xlim([0 length(d.expt.norms{colorDir, 1})+1])
  901. xlabel('Percent Cone Contrast')
  902. ylabel('Choice Probability')
  903. legend('Stim In RF', 'Stim Out of RF')
  904. legend boxoff
  905. hold off
  906. %print out the pooled CP values.
  907. bkgndColor = get(d.figHand, 'color');
  908. ax = axes('position', [0.05 0.05 0.9 0.35]);
  909. set(ax, 'xcolor', bkgndColor, 'ycolor', bkgndColor, 'color', bkgndColor)
  910. ylim([0 1]) %makes placing text easier
  911. xlim([0 1])
  912. txt = text(0.1, 0.8, sprintf('Pooled Choice Probability \n\n* In RF: %.3f \n* Out of RF: %.3f',...
  913. d.cell.cp.poolConIn.val(colorDir, 1), d.cell.cp.poolConOut.val(colorDir,1)));
  914. end
  915. %
  916. % SUMMARY SLIDE FOR DETECTION (DT)
  917. %
  918. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  919. function Summary_analysisFxn(dtFigHand);
  920. d = get(dtFigHand, 'userdata');
  921. figure(d.figHand) %assert this to be the current fig
  922. subplot(1,1,1);
  923. bkgndColor = get(d.figHand, 'color');
  924. set(gca, 'position', [0.05 0.05 0.9 0.85], 'xcolor', bkgndColor, 'ycolor', bkgndColor, 'color', bkgndColor)
  925. ylim([0 1]) %makes placing text easier
  926. xlim([0 1])
  927. %Num Trials
  928. cntrstLevInd = strmatch('cntrst_lev', [d.DT.sum.trialFields(1,:)]);
  929. colorDirInd = strmatch('color_dir', [d.DT.sum.trialFields(1,:)]);
  930. colorDirs = get(d.colorDirHand, 'string');
  931. numContrasts = length(unique(d.DT.trial(:,cntrstLevInd)));
  932. nTrials = nan(numContrasts, size(colorDirs,1));
  933. for clr = 1:size(colorDirs,1)
  934. l_color = d.DT.trial(:,colorDirInd) == clr;
  935. for cntrst = 1:numContrasts
  936. l_cntrst = d.DT.trial(:,cntrstLevInd) == cntrst;
  937. if cntrst == 1;
  938. nTrials(cntrst, clr) = sum(l_cntrst);
  939. else
  940. nTrials(cntrst, clr) = sum(l_cntrst&l_color);
  941. end
  942. end
  943. end
  944. nTrialTxt = text(0.05, .94, sprintf('Num Trials:\n min: %d\n max: %d', min(nTrials(:)), max(nTrials(:))));
  945. %Choice bias, measured for Zero contrast trials.
  946. flashXInd = strmatch('flash_x', [d.DT.sum.trialFields(1,:)]);
  947. flashYInd = strmatch('flash_y', [d.DT.sum.trialFields(1,:)]);
  948. correctInd = strmatch('correct', [d.DT.sum.trialFields(1,:)]);
  949. rfx = d.DT.sum.exptParams.rf_x;
  950. rfy = d.DT.sum.exptParams.rf_y;
  951. inRF = (d.DT.trial(:,flashXInd) == rfx) & (d.DT.trial(:,flashYInd) == rfy);
  952. corrects = d.DT.trial(:, correctInd);
  953. T1choices = zeros(size(d.DT.trial, 1), 1);
  954. T1choices(corrects & inRF) = 1; %in the RF and correct
  955. T1choices(~corrects & ~inRF) = 1; %incorrect but not in the RF
  956. tList = d.DT.trial(:, cntrstLevInd) == 1;
  957. ChoicesAtZero(1) = sum(tList & T1choices);
  958. ChoicesAtZero(2) = sum(tList & ~T1choices);
  959. [val, prefChoice] = max(ChoicesAtZero);
  960. p = 1-binocdf(ChoicesAtZero(prefChoice), sum(ChoicesAtZero), 0.5);
  961. biasTxt = text(0.05, 0.78, sprintf('Bias: \n T1 choices: %d\n T2 choices %d\n p = %.4f', ChoicesAtZero(1), ChoicesAtZero(2), p));
  962. % ANOVA on noise trials vs. outRF trials
  963. text(0.05, 0.63, 'Comparison of Zero Contrast to Out RF Responses Kruskal-Wallis:');
  964. for clrDir = 1:length(d.cell.crfOut)
  965. nSamples = cellfun(@(x)size(x,2), d.cell.crfOut{clrDir}(:)); %nTrials at each contrast
  966. group = cellfun(@(x)ones(x,1), mat2cell(nSamples, ones(length(nSamples),1)), 'uniformoutput', 0); %making a 'group' vec for anova1
  967. group = cellfun(@(x,y)(x.*y), group, mat2cell([1:length(group)]', ones(length(group),1)), 'uniformoutput', 0);
  968. group = vertcat(group{:});
  969. responses = horzcat(d.cell.crfOut{clrDir}{:})';
  970. p(clrDir) = kruskalwallis(responses, group, 'off');
  971. text(0.05, 0.63-0.04*clrDir, sprintf(' [%s] p = %.4f', colorDirs(clrDir,:), p(clrDir)));
  972. end
  973. % Threshold ratios
  974. text(0.05, 0.46,'Threshold Ratios:');
  975. for clrDir = 1:length(d.cell.crfOut)
  976. TR = d.cell.alpha(clrDir)./d.monk.alpha(clrDir);
  977. text(0.05, 0.46-0.04*clrDir, sprintf(' [%s] => %.3f', colorDirs(clrDir,:), TR));
  978. end
  979. % User input for manipulating the default params for DT analysis
  980. text(0.05, 0.29, 'Analysis Parameters:');
  981. text(0.05, 0.25, ' Cell Number:');
  982. text(0.05, 0.20, ' Start Time(sec):');
  983. text(0.05, 0.15, ' End Time(sec):');
  984. text(0.05, 0.10, ' Min Num Trials for CP:');
  985. text(0.05, 0.05, ' Analysis Method:');
  986. d.analParams.hand.cellNum = uicontrol('style', 'edit', 'string', num2str(d.analParams.val.cellNum), 'callback', @updateAnalParams, 'units', 'normalized', 'position', [.28, 0.245, .1, .03]);
  987. d.analParams.hand.start = uicontrol('style', 'edit', 'string', num2str(d.analParams.val.start), 'callback', @updateAnalParams, 'units', 'normalized', 'position', [.28, 0.205, .1, .03]);
  988. d.analParams.hand.end = uicontrol('style', 'edit', 'string', num2str(d.analParams.val.end), 'callback', @updateAnalParams, 'units', 'normalized', 'position', [.28, 0.

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