diff --git a/Analyses/CalculateDprime.m b/Analyses/CalculateDprime.m new file mode 100644 index 0000000..65beac9 --- /dev/null +++ b/Analyses/CalculateDprime.m @@ -0,0 +1,26 @@ +function [dPrm, h, fa] = CalculateDprime(responseMatrix) +%% +if sum(responseMatrix(1,:)) == 1 || sum(responseMatrix(2,:)) == 1 + dPrm = nan; + h = nan; + fa = nan; +else + h = responseMatrix(1,1)/sum(responseMatrix(1,:)); + if h == 1 + h = (sum(responseMatrix(1,:))-1)/sum(responseMatrix(1,:)); + elseif h == 0 + h = 1/sum(responseMatrix(1,:)); + end + fa = responseMatrix(2,1)/sum(responseMatrix(2,:)); + if fa == 1 + fa = (sum(responseMatrix(2,:))-1)/sum(responseMatrix(2,:)); + elseif fa == 0 + fa = 1/sum(responseMatrix(2,:)); + end + + dPrm = norminv(h)-norminv(fa); +end +% +% beta = exp((norminv(fa)^2 - norminv(h)^2)/2); +% +% c = -.5 * (norminv(h) + (norminv(fa))); diff --git a/Analyses/CalculateRI.m b/Analyses/CalculateRI.m new file mode 100644 index 0000000..6830631 --- /dev/null +++ b/Analyses/CalculateRI.m @@ -0,0 +1,20 @@ +function riVal = CalculateRI(responseMatrix) +if sum(responseMatrix(1,:)) == 1 || sum(responseMatrix(2,:)) == 1 + riVal = nan; +else + h = responseMatrix(1,1)/sum(responseMatrix(1,:)); + if h == 1 + h = (sum(responseMatrix(1,:))-1)/sum(responseMatrix(1,:)); + elseif h == 0 + h = 1/sum(responseMatrix(1,:)); + end + fa = responseMatrix(2,1)/sum(responseMatrix(2,:)); + if fa == 1 + fa = (sum(responseMatrix(2,:))-1)/sum(responseMatrix(2,:)); + elseif fa == 0 + fa = 1/sum(responseMatrix(2,:)); + end + riVal = (h+fa-1)/(1-((h-fa)^2)); +end + +end \ No newline at end of file diff --git a/Analyses/CurateRipples2_SM.m b/Analyses/CurateRipples2_SM.m new file mode 100644 index 0000000..814f217 --- /dev/null +++ b/Analyses/CurateRipples2_SM.m @@ -0,0 +1,737 @@ +%% CurateRipples +clear all +close all +global plotData +plotData.listSel = 2; % Used to keep track of which list is being selected from for ripple viewing +plotData.Window = 50; +%% Parameters +% envProc = 'RMS'; +envProc = 'HILB'; +powThresh = [1 3]; +durThresh = 25; +durThreshMrg = 15; +syncThresh = 0; +syncWin = 10; +smoothWin = 21; + +%% +rips = RippleDetection_SM(envProc, powThresh, durThresh, durThreshMrg, syncThresh, syncWin, smoothWin); +[trialRips] = ExtractTrialEventRips_SM(rips, [500 500]); +trlRipIndices = cell2mat([trialRips.Events(:,1); trialRips.Events(:,2); trialRips.Events(:,3)]); +allTrialRips = sortrows(trlRipIndices); % Use for ALL (pre-trial, trial and post-trial) Trial Rips + +%% Toss Ripple Features into PlotData +% Need to update the selection for TrialRips if not using only Post-Trial +% Rips +plotData.Rips = rips; +plotData.SessionRips.Events = rips.Ripples.Events; +plotData.SessionRips.Synchrony = rips.Ripples.Synchrony; +plotData.SessionRips.EnsembleAct = rips.Ripples.EnsembleActivity; +plotData.SessionRips.MaxPower = rips.Ripples.MaxPower; +plotData.SessionRips.RipFreq = rips.Ripples.MaxPowerFrequency; +ripsPrTrl = sum(cellfun(@(a)size(a,1), trialRips.Events)); +trlPrdID = sortrows([trlRipIndices(:,1), [ones(ripsPrTrl(1),1); ones(ripsPrTrl(2),1)*2; ones(ripsPrTrl(3),1)*3]]); +plotData.TrialRips.TrialPeriodID = trlPrdID(:,2); +plotData.TrialRips.Events = allTrialRips; +trlSynch = sortrows([trlRipIndices(:,1), cell2mat([trialRips.Synchrony(:,1); trialRips.Synchrony(:,2); trialRips.Synchrony(:,3)])]); +plotData.TrialRips.Synchrony = trlSynch(:,2); +trlNsmbl = sortrows([trlRipIndices(:,1), cell2mat([trialRips.EnsembleAct(:,1); trialRips.EnsembleAct(:,2); trialRips.EnsembleAct(:,3)])]); +plotData.TrialRips.EnsembleAct = trlNsmbl(:,2); +trlPower = sortrows([trlRipIndices(:,1), cell2mat([trialRips.MaxPower(:,1); trialRips.MaxPower(:,2); trialRips.MaxPower(:,3)])]); +plotData.TrialRips.MaxPower = trlPower(:,2); +trlFreq = sortrows([trlRipIndices(:,1), cell2mat([trialRips.RipFreq(:,1); trialRips.RipFreq(:,2); trialRips.RipFreq(:,3)])]); +plotData.TrialRips.RipFreq = trlFreq(:,2); + +%% Plot Descriptives +PlotNearTrialRipStats(trialRips) +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatCorr(rips.Ripples.Duration, rips.Ripples.Synchrony, 'Duration', 'Synchrony') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatCorr(rips.Ripples.Duration, rips.Ripples.EnsembleActivity, 'Duration', 'Ensemble Activity') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatCorr(rips.Ripples.Synchrony, rips.Ripples.EnsembleActivity, 'Synchrony', 'Ensemble Activity') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatsByTrlType(rips, trialRips) +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatsByOdor(rips, trialRips) +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipCountsByEvent(rips) +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatsByEvent(rips, 'Power') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatsByEvent(rips, 'Synchrony') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatsByEvent(rips, 'Spiking') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatsByEvent(rips, 'Duration') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + +PlotRipFeatsByEvent(rips, 'MaxFreq') +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); + + + +%% Create Figure +plotData.PowThresh = rips.FileInfo.PowerThreshold; +plotData.ripCure = figure; +set(plotData.ripCure, 'UserData', [rips.TimeStamps, mean(rips.SessionData.RipEnv,2)]); +plotData.rawAxes = axes(plotData.ripCure, 'position', [0.1, 0.75, 0.7, 0.2]); +set(plotData.rawAxes, 'UserData', rips.SessionData.RawLFP); +plotData.bpfAxes = axes(plotData.ripCure, 'position', [0.1, 0.55, 0.7, 0.2]); +set(plotData.bpfAxes, 'UserData', rips.SessionData.RipBPF); +plotData.spkAxes = axes(plotData.ripCure, 'position', [0.1, 0.2, 0.7, 0.3]); +set(plotData.spkAxes, 'UserData', rips.SessionData.Spikes); + +% Overall Ripple List +ssnRipTitleAx = axes(plotData.ripCure, 'position', [0.825, 0.925, 0.11, 0.05]); +set(ssnRipTitleAx, 'xlim', [-0.5 0.5], 'ylim', [0 0.5]); +text(ssnRipTitleAx, 0,0, 'Session Rips', 'horizontalalignment', 'center', 'verticalalignment', 'bottom'); +axis(ssnRipTitleAx, 'off'); +plotData.ssnRipList = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'listbox', 'String', 1:size(rips.Ripples.Events,1),... + 'Position', [0.825, 0.62, 0.15, 0.3], 'Callback', @SelectSsnRip, 'userData', rips.Ripples.Events); +plotData.ssnRipExport = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Export Session Rips',... + 'Position', [0.825, 0.55, 0.15, 0.05], 'Callback', @ExportSsnRips); + +% Trial Ripple List +trlRipTitleAx = axes(plotData.ripCure, 'position', [0.825, 0.5, 0.11, 0.05]); +set(trlRipTitleAx, 'xlim', [-0.5 0.5], 'ylim', [0 0.5]); +text(trlRipTitleAx, 0,0, 'Trial Rips', 'horizontalalignment', 'center', 'verticalalignment', 'bottom'); +axis(trlRipTitleAx, 'off'); +plotData.trlRipList = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'listbox', 'String', 1:size(allTrialRips,1),... + 'Position', [0.825, 0.25, 0.15, 0.25], 'Callback', @SelectTrlRip, 'userData', allTrialRips); +plotData.trlRipExport = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Export Trial Rips',... + 'Position', [0.825, 0.195, 0.15, 0.05], 'Callback', @ExportTrlRips); + +% Zoom In +zoomOutBtn = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Zm-',... + 'Position', [0.35, 0.06, 0.05, 0.075], 'Callback', @ZoomOut); +% Zoom Out +zoomInBtn = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Zm+',... + 'Position', [0.65, 0.06, 0.05, 0.075], 'Callback', @ZoomIn); + +% Previous Ripple +prevRipBtn = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', '<< Previous Ripple',... + 'Position', [0.05, 0.05, 0.2, 0.1], 'Callback', @PrevRip); +% Next Ripple +nextRipBtn = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Next Ripple >>',... + 'Position', [0.75, 0.05, 0.2, 0.1], 'Callback', @NextRip); + +% Remove Ripple +removeRipBtn = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Remove Ripple',... + 'Position', [0.425, 0.075, 0.2, 0.05], 'Callback', @RmvRip); + +% Rip Playback +playRipBtn = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Play Ripple',... + 'Position', [0.01, 0.9, 0.08, 0.05], 'Callback', @PlayRip); +plotData.playRipLst = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'listbox', 'String', rips.SessionData.TetIDs,... + 'Position', [0.01, 0.75, 0.08, 0.145], 'Callback', @HighlightTrace); +plotData.dcOffsetRadio = uicontrol(plotData.ripCure, 'Units', 'Normalized', 'Style', 'radiobutton', 'String', 'DC Offset',... + 'Position', [0.01, 0.7, 0.08, 0.05]); + + +annotation('textbox', 'position', [0.01 0.005 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfMerge Threshold = \\rm%i ms; \\bfDuration Threshold = \\rm%i ms', powThresh(1), powThresh(2), envProc, durThreshMrg, durThresh),... + 'linestyle', 'none'); +%% Initialize Things +SetPlots; + +%% Callbacks/Functions +function SetPlots +global plotData +if plotData.listSel == 1 + curNdx = plotData.ssnRipList.UserData(plotData.ssnRipList.Value,:); +else + curNdx = plotData.trlRipList.UserData(plotData.trlRipList.Value,:); +end +rawData = plotData.rawAxes.UserData; +bpfData = plotData.bpfAxes.UserData; +spkData = plotData.spkAxes.UserData; +envData = plotData.ripCure.UserData(:,2); +tmpSpkData = spkData(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window,:); +[spkX, spkY] = find(tmpSpkData~=0); +curTS = plotData.ripCure.UserData(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window,1); + +if ~isfield('rawPlot', plotData) + plotData.rawPlot = plot(plotData.rawAxes, curTS, rawData(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window,:), 'color', 'k'); + plotData.rawAxes.UserData = rawData; + for r = 1:length(plotData.rawPlot) + plotData.rawPlot(r).Color(4) = 0.2; + end + hold(plotData.rawAxes, 'on'); + plotData.audMrk = line(plotData.rawAxes, [curTS(1) curTS(1)], get(plotData.rawAxes, 'ylim'), 'color', 'k', 'visible', 'off'); + hold(plotData.rawAxes, 'off'); + plotData.bpfPlot = plot(plotData.bpfAxes, curTS, bpfData(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window,:), 'color', 'k'); + hold(plotData.bpfAxes, 'on'); + plotData.envPlot = plot(plotData.bpfAxes, curTS, envData(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window,:), 'color', 'r', 'linewidth', 2); + plotData.envTH1 = plot(plotData.bpfAxes, curTS,... + ones(1,length(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window))*(mean(plotData.ripCure.UserData(:,2)) + (plotData.PowThresh (1)*std(plotData.ripCure.UserData(:,2)))),... + 'color', 'k', 'linestyle','--', 'linewidth', 2); + plotData.envTH2 = plot(plotData.bpfAxes, curTS,... + ones(1,length(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window))*(mean(plotData.ripCure.UserData(:,2)) + (plotData.PowThresh (2)*std(plotData.ripCure.UserData(:,2)))),... + 'color', 'k', 'linestyle','-', 'linewidth', 2); + hold(plotData.bpfAxes, 'off'); + plotData.bpfAxes.UserData = bpfData; + for b = 1:length(plotData.bpfPlot) + plotData.bpfPlot(b).Color(4) = 0.2; + end + plotData.spkRasts = scatter(plotData.spkAxes, curTS(spkX),spkY, '*k'); + plotData.spkAxes.UserData = spkData; + xlabel(plotData.spkAxes, 'Time (s)'); + + linkaxes([plotData.spkAxes, plotData.bpfAxes, plotData.rawAxes], 'x'); + set(plotData.rawAxes, 'color', 'none', 'ycolor', 'none', 'xcolor', 'none', 'xticklabel', [], 'box', 'off'); + set(plotData.bpfAxes,'color', 'none', 'ycolor', 'none', 'xticklabel', [], 'box', 'off'); + set(plotData.spkAxes, 'color', 'none', 'ycolor', 'none', 'box', 'off'); + axis([plotData.rawAxes, plotData.bpfAxes, plotData.spkAxes], 'tight'); + + plotData.FigLims.Raw = repmat(get(plotData.rawAxes,'ylim'),[2,1]); + plotData.FigLims.BPF = repmat(get(plotData.bpfAxes,'ylim'),[2,1]); + spkLim = repmat(get(plotData.spkAxes,'ylim'),[2,1]); + plotData.FigLims.Spk = [spkLim(:,1)-1, spkLim(:,2)+1]; + + curRipX = [plotData.ripCure.UserData(curNdx,1); flipud(plotData.ripCure.UserData(curNdx,1))]'; + plotData.RipPatch.Raw = patch(plotData.rawAxes, 'XData', curRipX,... + 'YData', plotData.FigLims.Raw(:),... + 'FaceColor', 'y', 'FaceAlpha', 0.15,... + 'EdgeColor', 'y', 'EdgeAlpha', 0.5); + plotData.RipPatch.BPF = patch(plotData.bpfAxes, 'XData', curRipX,... + 'YData', plotData.FigLims.BPF(:),... + 'FaceColor', 'y', 'FaceAlpha', 0.15,... + 'EdgeColor', 'y', 'EdgeAlpha', 0.5); + plotData.RipPatch.Spk = patch(plotData.spkAxes, 'XData', curRipX,... + 'YData', plotData.FigLims.Spk(:),... + 'FaceColor', 'y', 'FaceAlpha', 0.15,... + 'EdgeColor', 'y', 'EdgeAlpha', 0.5); +else + for r = 1:length(plotData.rawPlot) + set(plotData.rawPlot(r), 'XData', curTS, 'YData', rawData(r,:)); + end + for b = 1:length(plotData.bpfPlot) + set(plotData.bpfPlot(b), 'XData', curTS, 'YData', bpfData(b,:)); + end + set(plotData.spkRasts, 'XData', curTS(spkX), 'YData', spkY); + set(plotData.envPlot, 'XData', curTS, 'YData', envData(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window,:)); + set(plotData.envTH1, 'XData', curTS, 'YData', ones(1,length(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window))*(mean(plotData.ripCure.UserData(:,2)) + (plotData.PowThresh(1)*std(plotData.ripCure.UserData(:,2))))); + set(plotData.envTH2, 'XData', curTS, 'YData', ones(1,length(curNdx(1)-plotData.Window:curNdx(2)+plotData.Window))*(mean(plotData.ripCure.UserData(:,2)) + (plotData.PowThresh(2)*std(plotData.ripCure.UserData(:,2))))); + curRipX = [plotData.ripCure.UserData(curNdx,1); flipud(plotData.ripCure.UserData(curNdx,1))]'; + set(plotData.RipPatch.Raw, 'XData', curRipX); + set(plotData.RipPatch.BPF, 'XData', curRipX); + set(plotData.RipPatch.Spk, 'XData', curRipX); +end +HighlightTrace +title(plotData.spkAxes, sprintf('Duration = %i(ms)', diff(curNdx))); +% refreshdata(plotData.ripCure); +end + +function SelectSsnRip(source,event) +global plotData +plotData.listSel = 1; +SetPlots +end + +function SelectTrlRip(source,event) +global plotData +plotData.listSel = 2; +SetPlots +end + +function NextRip(source,event) +global plotData +if plotData.listSel == 1 + if plotData.ssnRipList.Value < size(plotData.ssnRipList.String,1) + plotData.ssnRipList.Value = plotData.ssnRipList.Value + 1; + SetPlots + else + plotData.ssnRipList.Value = size(plotData.ssnRipList.String,1); + end +else + if plotData.trlRipList.Value < size(plotData.trlRipList.String,1) + plotData.trlRipList.Value = plotData.trlRipList.Value + 1; + SetPlots + else + plotData.trlRipList.Value = size(plotData.trlRipList.String,1); + end +end +end + +function PrevRip(source,event) +global plotData +if plotData.listSel == 1 + if plotData.ssnRipList.Value ~= 1 + plotData.ssnRipList.Value = plotData.ssnRipList.Value - 1; + SetPlots + end +else + if plotData.trlRipList.Value ~= 1 + plotData.trlRipList.Value = plotData.trlRipList.Value - 1; + SetPlots + end +end +end + +function PlayRip(source, event) +global plotData +tetID = plotData.playRipLst.Value; +curWave = plotData.rawPlot(tetID).YData; +if plotData.dcOffsetRadio.Value == 1 + curWave = curWave-curWave(1); % To reduce initial popping due to DC offset. +end +% if plotData.detrend.Value ==1 +% curWave = detrend(curWave); +% end +curSound = audioplayer(curWave, 1000); +playblocking(curSound); +% Below code is an attempt to visualize what's being played... it didn't +% work +% curWaveTime = plotData.rawPlot(tetID).XData; +% for t = 1:length(curWaveTime) +% set(plotData.audMrk, 'XData', [curWaveTime(t) curWaveTime(t)]); +% % pause(1/1000); +% drawnow +% end +end + +function HighlightTrace(source, event) +global plotData +tetID = plotData.playRipLst.Value; +for t = 1:size(plotData.playRipLst.String,1) + if t==tetID + plotData.rawPlot(t).Color = [1 0 0 1]; + else + plotData.rawPlot(t).Color = [0 0 0 0.2]; + end +end +end + +function ZoomOut(source,event) +global plotData +plotData.Window = plotData.Window+100; +SetPlots +end + +function ZoomIn(source,event) +global plotData +plotData.Window = plotData.Window-100; +if plotData.Window < 50 + plotData.Window = 50; +end +SetPlots +end + +function RmvRip(source,event) +global plotData +if plotData.listSel == 1 + curNdx = plotData.ssnRipList.UserData(plotData.ssnRipList.Value,:); +else + curNdx = plotData.trlRipList.UserData(plotData.trlRipList.Value,:); +end +ssnList = plotData.ssnRipList.UserData; +ssnListNdx = ssnList(:,1)==curNdx(1); +ssnList(ssnListNdx,:) = []; +plotData.SessionRips.Events(ssnListNdx,:) = []; +plotData.SessionRips.Synchrony(ssnListNdx,:) = []; +plotData.SessionRips.EnsembleAct(ssnListNdx,:) = []; +plotData.SessionRips.MaxPower(ssnListNdx,:) = []; +plotData.SessionRips.RipFreq(ssnListNdx,:) = []; + +trlList = plotData.trlRipList.UserData; +trlListNdx = trlList(:,1)==curNdx(1); +trlList(trlListNdx,:) = []; +plotData.TrialRips.TrialPeriodID(trlListNdx,:) = []; +plotData.TrialRips.Events(trlListNdx,:) = []; +plotData.TrialRips.Synchrony(trlListNdx,:) = []; +plotData.TrialRips.EnsembleAct(trlListNdx,:) = []; +plotData.TrialRips.MaxPower(trlListNdx,:) = []; +plotData.TrialRips.RipFreq(trlListNdx,:) = []; + +plotData.ssnRipList.UserData = ssnList; +plotData.ssnRipList.String = 1:size(ssnList,1); +plotData.trlRipList.UserData = trlList; +plotData.trlRipList.String = 1:size(trlList,1); + +if plotData.listSel == 1 + if plotData.ssnRipList.Value == 1 + plotData.ssnRipList.Value = 1; + elseif plotData.ssnRipList.Value == size(ssnList,1)+1 + plotData.ssnRipList.Value = size(ssnList,1); + end +else + if plotData.trlRipList.Value == 1 + plotData.trlRipList.Value = 1; + elseif plotData.trlRipList.Value == size(trlList,1)+1 + plotData.trlRipList.Value = size(trlList,1); + end +end +SetPlots +end + +function ExportSsnRips(source, event) +global plotData +ripMatrix(:,1) = plotData.ripCure.UserData(:,1); +ripMatrix(:,2) = false(size(ripMatrix,1),1); +ripMatrixColIDs = [{'TimeBin'}, {'Session_Ripple_Log'}]; +ripFeats = [plotData.ssnRipList.UserData, plotData.SessionRips.Synchrony,... + plotData.SessionRips.EnsembleAct, plotData.SessionRips.MaxPower,... + plotData.SessionRips.RipFreq]; +ripFeatsColIDs = [{'RippleStartIndex'}, {'RippleEndIndex'},... + {'RippleSynchrony'}, {'RipplePercentActiveCells'}, {'RipplePower'},... + {'RippleFrequency'}]; +for e = 1:size(ripFeats, 1) + ripMatrix(ripFeats(e,1):ripFeats(e,2),2) = true; +end +save('SessionRipples.mat', 'ripMatrix', 'ripMatrixColIDs', 'ripFeats', 'ripFeatsColIDs'); +msgbox('Session Ripple Indices Saved'); +end + +function ExportTrlRips(source, event) +global plotData +for t = 1:3 + curTrialRipLog = plotData.TrialRips.TrialPeriodID==t; + ripMatrixColIDs = [{'TimeBin'}, {'Trial_Ripple_Log'}]; + ripFeats = [plotData.trlRipList.UserData(curTrialRipLog,:), plotData.TrialRips.Synchrony(curTrialRipLog,:),... + plotData.TrialRips.EnsembleAct(curTrialRipLog,:), plotData.TrialRips.MaxPower(curTrialRipLog,:),... + plotData.TrialRips.RipFreq(curTrialRipLog,:)]; + ripFeatsColIDs = [{'RippleStartIndex'}, {'RippleEndIndex'},... + {'RippleSynchrony'}, {'RipplePercentActiveCells'}, {'RipplePower'},... + {'RippleFrequency'}]; + ripMatrix(:,1) = plotData.ripCure.UserData(:,1); + ripMatrix(:,2) = false(size(ripMatrix,1),1); + for e = 1:size(ripFeats, 1) + ripMatrix(ripFeats(e,1):ripFeats(e,2),2) = true; + end + if t==1 + save('Pre-TrialRipples.mat', 'ripMatrix', 'ripMatrixColIDs', 'ripFeats', 'ripFeatsColIDs'); + elseif t==2 + save('In-TrialRipples.mat', 'ripMatrix', 'ripMatrixColIDs', 'ripFeats', 'ripFeatsColIDs'); + elseif t==3 + save('Post-TrialRipples.mat', 'ripMatrix', 'ripMatrixColIDs', 'ripFeats', 'ripFeatsColIDs'); + end +end +msgbox('Trial Ripple Indices Saved'); +end + +%% Data Organization Functions +function [rips] = RippleDetection_SM(envProc, powThresh, durThresh, durThreshMrg, syncThresh, syncWin, smoothWin) +%% RippleDetection_SM +% Inputs: +% - envProc: Enveloping procedure +% - 'RMS' : Use the root mean squared approach to enveloping +% - 'HILB' : Use hilbert transform envelope +% - powThresh: Thresholds used for defining the ripple. +% - First value is the threshold for defining a ripple epoc. +% - Second value is the threshold needed to for an epoc to be +% considered a ripple. +% - durThresh: Threshold used to select ripples of only a particular +% duration. **CURRENTLY NOT IMPLEMENTED** +% - durThreshMrg: Threshold of the inter-ripple-interval used to +% merge together potential ripples that happen close in time +% - syncThresh: Synchrony threshold used to select ripples of a +% particular coherence. **CURRENTLY NOT IMPLEMENTED** +% - syncWin: Window size used to compute sliding window coherence +% across the session. **CURRENTLY NOT IMPLEMENTED** +% - smoothWin: Window size used for gaussian smoothing. + + +%#ok<*IDISVAR,*NODEF,*USENS,*NASGU,*COLND> +%% +if nargin == 0 +% envProc = 'RMS'; % Enable for RMS determination of envelope + envProc = 'HILB'; % Enable for abs(Hilbert) determinination of envelope + powThresh = [0 4]; + durThresh = 15; % Duration Threshold + durThreshMrg = 15; + syncThresh = 0; + syncWin = 10; + smoothWin = 21; +end +%% +%% Define Analysis Features +w = gausswin(smoothWin); +w = w/sum(w); +%% Load Data +origDir = cd; +[fileDir] = uigetdir(origDir); +if fileDir==0 + disp('Analysis Cancelled') + return +else + cd(fileDir) +end +dirContents = dir(fileDir); +fileNames = {dirContents.name}; +tetFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_T([0-9]*)_SM.mat')); +tetFiles = fileNames(tetFileLog)'; +behavFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_BehaviorMatrix')); +load(fileNames{behavFileLog}); +ensembleFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_EnsembleMatrix')); +if sum(ensembleFileLog)==0 + ensembleMatrix = zeros(size(behavMatrix,1),2); +else + load(fileNames{ensembleFileLog}); +end +behavMatrixTrialStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0], 'PokeIn'); + +%% Extract Raw Values & Compute RMS Power +ripBPF = nan(size(behavMatrix,1),size(tetFiles,1)); +ripVolts = nan(size(behavMatrix,1),size(tetFiles,1)); +ripRMS = nan(size(behavMatrix,1),size(tetFiles,1)); +ripHilb = nan(size(behavMatrix,1),size(tetFiles,1)); +ripTetIDs = cell(size(tetFiles)); +for fl = 1:length(tetFiles) + load(tetFiles{fl}) + samp = mode(diff(statMatrix(:,1))); + wIndx = round((1/200)*(1/samp)); + fprintf('%s......', tetFiles{fl}); + ripCol = find(cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, 'LFP_Ripple$'))); + ripVolts(:,fl) = statMatrix(:,2); + if strcmp(envProc, 'RMS') + ripRMS(:,fl) = conv(sqrt(conv(statMatrix(:,ripCol).^2, ones(wIndx,1)/wIndx, 'same')), w, 'same'); + elseif strcmp(envProc, 'HILB') + ripRMS(:,fl) = conv(abs(hilbert(statMatrix(:,ripCol))),w,'same'); + end + ripBPF(:,fl) = statMatrix(:,ripCol); + ripHilb(:,fl) = statMatrix(:,ripCol+1); + ripTetIDs{fl} = statMatrixColIDs{ripCol}; + fprintf('done\n'); +end + +%% Calculate Thresholds +% Aggregate Power +aggPower = mean(ripRMS,2); % Mean envelope +zAgg = zscore(aggPower); + +% Threshold Based on Mean +/- STD Aggregate Power +rmsThresh1 = (mean(aggPower) + (powThresh(1)*std(aggPower))); +rmsThresh2 = (mean(aggPower) + (powThresh(2)*std(aggPower))); + +%% Identify Ripples +% Define putative ripple periods +abvThresh1 = aggPower>rmsThresh1; +epocWindows = [find(diff(abvThresh1)==1), find(diff(abvThresh1)==-1)]; + +% Apply secondary (peak power) threshold +abvThresh2 = aggPower>rmsThresh2; +dualThreshLog = false(size(epocWindows,1),1); +for epoc = 1:size(epocWindows,1) + if sum(abvThresh2(epocWindows(epoc,1):epocWindows(epoc,2))) >=1 + dualThreshLog(epoc) = true; + end +end +epocWindows(~dualThreshLog,:) = []; % Comment out if not using dual thresholds + +% Merge short latency ripples +interEpocInterval = epocWindows(2:end,1) - epocWindows(1:end-1,2); +slrLog = interEpocIntervale1 + [tempConfMtx(e1,e2),~] = circ_corrcc(ripHilb(epocWindows(epoc,1):epocWindows(epoc,2),e1),... + ripHilb(epocWindows(epoc,1):epocWindows(epoc,2),e2)); + end + end + end + epocSyncConfMtx{epoc} = tempConfMtx; + epocSync(epoc) = mean(tempConfMtx(triu(true(size(ripHilb,2)),1))); +end + +%% Organize Spiking Data Based on Total # Spikes +spkMtx = ensembleMatrix(:,2:end); +sortedSpkCountsAndIndices = sortrows([sum(spkMtx); 1:size(spkMtx,2)]'); +spkMtxSorted = spkMtx(:,sortedSpkCountsAndIndices(:,2)); + +%% Evaluate Ensemble Activity +epocNsmblAct = nan(size(epocWindows,1),1); +for epoc = 1:size(epocWindows,1) + tempSpkMtx = ensembleMatrix(epocWindows(epoc,1):epocWindows(epoc,2),2:end); + epocNsmblAct(epoc) = mean(sum(tempSpkMtx)>=1); +end + +%% Evaluate Spectrogram & Extract Max Power + +ripSpect = cell(size(epocWindows,1),1); +ripFreq = nan(size(epocWindows,1),1); +ripMaxFreq = nan(size(epocWindows,1),1); +epocPow = nan(size(epocWindows,1),1); +freqs = [150 250]; +padSize = 25; +freqsVect = freqs(1):freqs(2); +for e = 1:size(epocWindows,1) + curZagg = zAgg(epocWindows(e,1):epocWindows(e,2)); + epocPow(e) = max(curZagg); + tempSpect = nan(diff(epocWindows(e,:))+(padSize*2+1),freqs(2)-freqs(1)+1,size(ripBPF,2)); + for t = 1:size(ripBPF,2) + tempSpect(:,:,t) = MorletAG(ripVolts(epocWindows(e,1)-padSize:epocWindows(e,2)+padSize,t), 1/samp, freqs(1), freqs(2))'; + end + ripSpect{e} = tempSpect(padSize+1:end-padSize,:,:); + tempMax = mean(ripSpect{e},3); + [~,c] = find((tempMax./repmat(max(tempMax,[],2), [1,size(tempMax,2)]))==1); + ripFreq(e) = mean(freqsVect(c)); + maxPowSpect = tempMax(curZagg==max(curZagg),:); + ripMaxFreq(e) = freqsVect(maxPowSpect==max(maxPowSpect)); +end + +%% Organize Data Output +rips = struct(... + 'TimeStamps', statMatrix(:,1),... + 'Ripples', struct('Events', epocWindows, 'Duration', epocDur,... + 'Synchrony', epocSync, 'EnsembleActivity', epocNsmblAct,... + 'MaxPower', epocPow,... + 'MeanFrequency', ripFreq, 'MaxPowerFrequency', ripMaxFreq),... + 'SessionData', struct('RawLFP', ripVolts, 'RipBPF', ripBPF,... + 'RipEnv', ripRMS, 'RipPhase', ripHilb, 'TetIDs', {ripTetIDs},... + 'Spikes', spkMtxSorted),... + 'TrialInfo', struct('Perf', [behavMatrixTrialStruct.Performance]==1,... + 'TransDist', [behavMatrixTrialStruct.TranspositionDistance],... + 'OdorVect', [behavMatrixTrialStruct.Odor],... + 'PositionVect', [behavMatrixTrialStruct.Position],... + 'TrialPokes', [[behavMatrixTrialStruct.PokeInIndex]', [behavMatrixTrialStruct.PokeOutIndex]'],... + 'TrialRewards', [behavMatrixTrialStruct.RewardIndex]),... + 'FileInfo', struct('Directory', cd, 'EnvelopeProcedure', envProc,... + 'PowerThreshold', powThresh, 'DurationThreshold', durThresh,... + 'DurationMergeThreshold', durThreshMrg,... + 'SynchronyThreshold', syncThresh, 'SynchronyWindow', syncWin,... + 'GaussianDuration', smoothWin)); +end + +function [trialRipStruct] = ExtractTrialEventRips_SM(rips, trialWin) +% ExtractTrialEventRips_SM +% Extracts and organizes ripple data relative to the trial periods +% +% Inputs: +% - rips: Ripple data structure created by RippleDetection_SM +% - trialWin: Periods used for delineation of trial event related +% SWR. +% - First value is period prior to poke initiation considered +% as the "pre-trial" period +% - Second value is the period after poke withdrawal +% considered as the "post-trial" period + +%% Extract Near-Trial Epocs +trialPokeTimes = rips.TrialInfo.TrialPokes; +trialRips = cell(size(trialPokeTimes,1),3); +trialRipLat = cell(size(trialPokeTimes,1),3); +trialRipsDur = cell(size(trialPokeTimes,1),3); +trialRipsSync = cell(size(trialPokeTimes,1),3); +trialRipsNsmblAct = cell(size(trialPokeTimes,1),3); +trialRipsMaxPow = cell(size(trialPokeTimes,1),3); +trialRipsMaxFreq = cell(size(trialPokeTimes,1),3); +for trl = 1:size(trialPokeTimes,1) + preTrlLog = rips.Ripples.Events(:,1)>(trialPokeTimes(trl,1)-trialWin(1)) & rips.Ripples.Events(:,1)trialPokeTimes(trl,1) & rips.Ripples.Events(:,1)trialPokeTimes(trl,2) & (rips.Ripples.Events(:,1)>',... + 'Position', [0.75, 0.05, 0.2, 0.1], 'Callback', @NextRip); + +% Remove Ripple +removeRipBtn = uicontrol(ripCure, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Remove Ripple',... + 'Position', [0.425, 0.075, 0.2, 0.05], 'Callback', @RmvRip); + +%% Plot Stuff +% Plot Raw LFP Traces +raw = plot(rawAxes, rips.TimeStamps, rips.SessionData.RawLFP, 'color', 'k'); +for r = 1:length(raw) + raw(r).Color(4) = 0.2; +end +set(rawAxes, 'Tag', 'Raw_Axes'); +% Plot Ripple Band LFP Traces +bpf = plot(bpfAxes, rips.TimeStamps, rips.SessionData.RipBPF, 'color', 'k'); +for b = 1:length(bpf) + bpf(b).Color(4) = 0.2; +end +set(bpfAxes, 'Tag', 'Bpf_Axes'); +% Plot Spiking Activity +[spkX, spkY] = find(rips.SessionData.Spikes~=0); +scatter(spkAxes, rips.TimeStamps(spkX),spkY, '*k'); +% line(spkAxes, rips.TimeStamps(spkX),spkY, 'marker', '*', 'linestyle', 'none', 'color', 'k'); +xlabel(spkAxes, 'Time (ms)'); +set(spkAxes, 'Tag', 'Spk_Axes'); + +% Fiddle with Axes +set(rawAxes, 'color', 'none', 'ycolor', 'none', 'xcolor', 'none', 'xticklabel', [], 'box', 'off'); +set(bpfAxes,'color', 'none', 'ycolor', 'none', 'xticklabel', [], 'box', 'off'); +set(spkAxes, 'color', 'none', 'ycolor', 'none', 'box', 'off'); +axis([rawAxes, bpfAxes,spkAxes], 'tight'); +rawLim = repmat(get(rawAxes,'ylim'),[2,1]); +bpfLim = repmat(get(bpfAxes,'ylim'),[2,1]); +spkLim = repmat(get(spkAxes,'ylim'),[2,1]); +spkLim(:,1) = spkLim(:,1)-1; +spkLim(:,2) = spkLim(:,2)+1; +% Plot Trial Periods +for trl = 1:size(rips.TrialInfo.TrialPokes,1) + switch rips.TrialInfo.OdorVect(trl) + case 1 + patchColor = [44/255 168/255 224/255]; + case 2 + patchColor = [154/255 133/255 122/255]; + case 3 + patchColor = [9/255 161/255 74/255]; + case 4 + patchColor = [128/255 66/255 151/255]; + case 5 + patchColor = [241/255 103/255 36/255]; + end + patch(rawAxes, 'XData', [rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,1)), rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,2)), rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,2)),rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,1))],... + 'YData', rawLim(:),... + 'FaceColor', patchColor, 'FaceAlpha', 0.5,... + 'EdgeColor', patchColor, 'EdgeAlpha', 0.5); + patch(bpfAxes, 'XData', [rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,1)), rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,2)), rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,2)),rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,1))],... + 'YData', bpfLim(:),... + 'FaceColor', patchColor, 'FaceAlpha', 0.5,... + 'EdgeColor', patchColor, 'EdgeAlpha', 0.5); + patch(spkAxes, 'XData', [rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,1)), rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,2)), rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,2)),rips.TimeStamps(rips.TrialInfo.TrialPokes(trl,1))],... + 'YData', spkLim(:),... + 'FaceColor', patchColor, 'FaceAlpha', 0.5,... + 'EdgeColor', patchColor, 'EdgeAlpha', 0.5); +end + +for rip = 1:size(rips.Ripples.Events,1) + curRipX = [rips.TimeStamps(rips.Ripples.Events(rip,:)); flipud(rips.TimeStamps(rips.Ripples.Events(rip,:)))]'; + patch(rawAxes, 'XData', curRipX,... + 'YData', rawLim(:),... + 'FaceColor', 'y', 'FaceAlpha', 0.15,... + 'EdgeColor', 'y', 'EdgeAlpha', 0.5); + patch(bpfAxes, 'XData', curRipX,... + 'YData', bpfLim(:),... + 'FaceColor', 'y', 'FaceAlpha', 0.15,... + 'EdgeColor', 'y', 'EdgeAlpha', 0.5); + patch(spkAxes, 'XData', curRipX,... + 'YData', spkLim(:),... + 'FaceColor', 'y', 'FaceAlpha', 0.15,... + 'EdgeColor', 'y', 'EdgeAlpha', 0.5); +end + +%% Callbacks +function SelectSsnRip(source,event) +global listSel +listSel = 1; +kids = get(get(source, 'Parent'), 'Children'); +tags = arrayfun(@(a)a.Tag, kids, 'uniformoutput',0); +axTag = strcmp(tags, 'Raw_Axes'); +set(kids(axTag), 'xLim', [source.UserData(source.Value,1)-(0.05),... + source.UserData(source.Value,2)+(0.05)]); +end + +function SelectTrlRip(source,event) +global listSel +listSel = 2; +kids = get(get(source, 'Parent'), 'Children'); +tags = arrayfun(@(a)a.Tag, kids, 'uniformoutput',0); +axTag = strcmp(tags, 'Raw_Axes'); +set(kids(axTag), 'xLim', [source.UserData(source.Value,1)-(0.05),... + source.UserData(source.Value,2)+(0.05)]); +end + +function NextRip(source,event) +global listSel +if listSel == 1 + lstTarg = 'ssnRip_Lst'; +else + lstTarg = 'trlRip_Lst'; +end +kids = get(get(source, 'Parent'), 'Children'); +tags = arrayfun(@(a)a.Tag, kids, 'uniformoutput',0); +lstTag = strcmp(tags, lstTarg); +kids(lstTag).Value = kids(lstTag).Value+1; +axTag = strcmp(tags, 'Raw_Axes'); +set(kids(axTag), 'xLim', [kids(lstTag).UserData(kids(lstTag).Value,1)-(0.05),... + kids(lstTag).UserData(kids(lstTag).Value,2)+(0.05)]); +end + +function PrevRip(source,event) +global listSel +if listSel == 1 + lstTarg = 'ssnRip_Lst'; +else + lstTarg = 'trlRip_Lst'; +end +kids = get(get(source, 'Parent'), 'Children'); +tags = arrayfun(@(a)a.Tag, kids, 'uniformoutput',0); +lstTag = strcmp(tags, lstTarg); +kids(lstTag).Value = kids(lstTag).Value-1; +axTag = strcmp(tags, 'Raw_Axes'); +set(kids(axTag), 'xLim', [kids(lstTag).UserData(kids(lstTag).Value,1)-(0.05),... + kids(lstTag).UserData(kids(lstTag).Value,2)+(0.05)]); +end + +function ZoomOut(source,event) +kids = get(get(source, 'Parent'), 'Children'); +tags = arrayfun(@(a)a.Tag, kids, 'uniformoutput',0); +axTag = strcmp(tags, 'Raw_Axes'); +curX = get(kids(axTag), 'xLim'); +set(kids(axTag), 'xLim', [curX(1)-(0.01),... + curX(2)+(0.01)]); +end + +function ZoomIn(source,event) +kids = get(get(source, 'Parent'), 'Children'); +tags = arrayfun(@(a)a.Tag, kids, 'uniformoutput',0); +axTag = strcmp(tags, 'Raw_Axes'); +curX = get(kids(axTag), 'xLim'); +set(kids(axTag), 'xLim', [curX(1)+(0.01),... + curX(2)-(0.01)]); +end \ No newline at end of file diff --git a/Analyses/CurateSWR_SM.m b/Analyses/CurateSWR_SM.m new file mode 100644 index 0000000..38a65b7 --- /dev/null +++ b/Analyses/CurateSWR_SM.m @@ -0,0 +1,738 @@ +aniIDs = [{'Barat'},... + {'Buchanan'},... + {'Mitt'},... + {'Stella'},... + {'SuperChris'}]; +dataDir = 'D:\WorkBigDataFiles\CA1 Data\1. WellTrained session\'; +aniDirs = cellfun(@(a)sprintf('%s%s\\SWR Tets\\',dataDir, a), aniIDs, 'uniformoutput', 0); +swChans = [{16},... + {21},... + {2},... + {18},... + {12}]; +ripChans = [{21},... + {18},... + {18},... + {14},... + {15}]; +aniInfo = struct('ID', aniIDs, 'Directory', aniDirs, 'SWchan', swChans, 'RIPchan', ripChans,... + 'SWepocs', [], 'SWtrace', [], 'SWpower', [],... + 'RIPepocs', [], 'RIPtrace', [], 'RIPpower', [],... + 'SWRepocs', []); + +swThresh = [0 3]; +ripThresh = [0 3]; +mergeThresh = 15; + +odorColors = [44/255, 168/255, 224/255;... + 154/255, 133/255, 122/255;... + 9/255, 161/255, 74/255;... + 128/255, 66/255, 151/255;... + 241/255, 103/255, 36/255]; + +%% +for a = 1:length(aniInfo) + %% Load Files & Load Behavior/Ensemble Data + aniFiles = dir(aniInfo(a).Directory); + behMatFile = aniFiles(cellfun(@(a)~isempty(a), strfind({aniFiles.name}, 'BehaviorMatrix'))).name; + behav = load([aniInfo(a).Directory behMatFile]); + behavMat = OrganizeTrialData_SM(behav.behavMatrix, behav.behavMatrixColIDs, [0 0], 'PokeIn'); + sessionMatrix = [[behavMat.PokeInIndex]', [behavMat.PokeOutIndex]', [behavMat.Performance]', [behavMat.Position]', [behavMat.Odor]']; + % Extract position and derive velocity + locNdxs = find(sum(posVals~=0,2)>=1); + locVals = behav.behavMatrix(locNdxs,end-1:end)*1.5/100; + timeVals = behav.behavMatrix(locNdxs,1); + instV = nan(size(locVals,1),1); + for v = 2:size(locVals,1) + instV(v) = sqrt((locVals(v,1)-locVals(v-1,1))^2 - (locVals(v,2)-locVals(v,2))^2)/diff(timeVals(v-1:v)); + end + smoothInstV = conv(instV, ones(1,20)/20, 'same'); + clear behav behavMat + nsmblMatFile = aniFiles(cellfun(@(a)~isempty(a), strfind({aniFiles.name}, 'EnsembleMatrix'))).name; + ensemble = load([aniInfo(a).Directory nsmblMatFile]); + + %% Evaluate Sharpwave channel & events + swFile = aniFiles(cell2mat(cellfun(@(a)~isempty(a),regexp({aniFiles.name}, ['\w*T' mat2str(aniInfo(a).SWchan) '_\w*SM.mat\>']),'uniformoutput', 0))).name; + sw = load([aniInfo(a).Directory swFile]); + [swEpocs, swLFP, swPOW] = SharpwaveDetection(sw.statMatrix(:,2), 1/mode(diff(sw.statMatrix(:,1))), swThresh, mergeThresh); + swLog = false(size(sw.statMatrix(:,1))); + for sws = 1:size(swEpocs,1) + swLog(swEpocs(sws,1):swEpocs(sws,2)) = true; + end + swTrace = nan(size(sw.statMatrix(:,1))); + swTrace(swLog) = sw.statMatrix(swLog,2); + aniInfo(a).SWepocs = swEpocs; + aniInfo(a).SWtrace = swLFP; + aniInfo(a).SWpower = swPOW; + + swPV = nan(size(ensemble.ensembleMatrix,2)-1, size(swEpocs,1)); + for sws = 1:size(swEpocs,1) + swPV(:,sws) = mean(ensemble.ensembleMatrix(swEpocs(sws,1):swEpocs(sws,2),2:end),1); + end + + %% Evaluate Ripple channel & events + ripFile = aniFiles(cell2mat(cellfun(@(a)~isempty(a),regexp({aniFiles.name}, ['\w*T' mat2str(aniInfo(a).RIPchan) '_\w*SM.mat\>']),'uniformoutput', 0))).name; + rip = load([aniInfo(a).Directory ripFile]); + [ripEpocs, ripLFP, ripPOW] = RippleDetection(rip.statMatrix(:,2), 1/mode(diff(rip.statMatrix(:,1))), ripThresh, mergeThresh); + ripLog = false(size(rip.statMatrix(:,1))); + for rips = 1:size(ripEpocs,1) + ripLog(ripEpocs(rips,1):ripEpocs(rips,2)) = true; + end + ripTrace = nan(size(rip.statMatrix(:,1))); + ripTrace(ripLog) = rip.statMatrix(ripLog,2); + aniInfo(a).RIPepocs = ripEpocs; + aniInfo(a).RIPtrace = ripLFP; + aniInfo(a).RIPpower = ripPOW; + + ripPV = nan(size(ensemble.ensembleMatrix,2)-1, size(ripEpocs,1)); + for rips = 1:size(ripEpocs,1) + ripPV(:,rips) = mean(ensemble.ensembleMatrix(ripEpocs(rips,1):ripEpocs(rips,2),2:end),1); + end + + %% Identify Sharpwave Ripple events + swrLog = swLog + ripLog; + swrStart = find(diff(swrLog==2)==1); + swrEnd = find(diff(swrLog==2)==-1); + swrWindows = [swrStart nan(length(swrStart),1)]; + for swr = 1:length(swrStart) + tempSWRstart = swrStart(swr); + swrWindows(swr,1) = min([swEpocs(tempSWRstart>=swEpocs(:,1) & tempSWRstart<=swEpocs(:,2),1), ripEpocs(tempSWRstart>=ripEpocs(:,1) & tempSWRstart<=ripEpocs(:,2),1), tempSWRstart]); + + tempSWRend = swrEnd(find(swrEnd>tempSWRstart,1,'first')); + swrWindows(swr,2) = max([swEpocs(tempSWRend>=swEpocs(:,1) & tempSWRend<=swEpocs(:,2),2), ripEpocs(tempSWRend>=ripEpocs(:,1) & tempSWRend<=ripEpocs(:,2),2), tempSWRend]); + end + for swr = 2:size(swrWindows,1) + if ~isnan(swrWindows(swr,1)) && ~isnan(swrWindows(swr-1,1)) + if swrWindows(swr,1) - swrWindows(swr-1,2) <= mergeThresh + swrWindows(swr,1) = swrWindows(swr-1,1); + swrWindows(swr-1,:) = nan; + end + end + end + swrWindows(isnan(swrWindows(:,1)),:) = []; + aniInfo(a).SWRepocs = swrWindows; + + newSWtrace = nan(size(sw.statMatrix(:,1))); + newRIPtrace = nan(size(rip.statMatrix(:,1))); + for swr = 1:size(swrWindows,1) + newSWtrace(swrWindows(swr,1):swrWindows(swr,2)) = sw.statMatrix(swrWindows(swr,1):swrWindows(swr,2),2); + newRIPtrace(swrWindows(swr,1):swrWindows(swr,2)) = rip.statMatrix(swrWindows(swr,1):swrWindows(swr,2),2); + end + + swrPV = nan(size(ensemble.ensembleMatrix,2)-1, size(swrWindows,1)); + swrActv = nan(1,size(swrWindows,1)); + for swrs = 1:size(swrWindows,1) + swrPV(:,swrs) = mean(ensemble.ensembleMatrix(swrWindows(swrs,1):swrWindows(swrs,2),2:end),1); + swrActv(swrs) = mean(swrPV(:,swrs)~=0); + end + + %% Summarize SWR Events + % Tabulate SWR vs Trial Info + trialRIPlog = false(size(swrWindows,1),1); + trialRIPlogPRE = false(size(swrWindows,1),1); + trialRIPlogTRIAL = false(size(swrWindows,1),1); + trialRIPlogPOST = false(size(swrWindows,1),1); + trialsWithRips = nan(size(sessionMatrix,1),1); + trialSWRlat = cell(size(sessionMatrix,1),1); + trialSWRlatPRE = cell(size(sessionMatrix,1),1); + trialSWRlatPOST = cell(size(sessionMatrix,1),1); + for trl = 1:size(sessionMatrix,1) + preTrlSWRlat = swrWindows(:,1) - sessionMatrix(trl,1); + if trl == 1 || sessionMatrix(trl,4)==1 + preTrialSWRlog = (preTrlSWRlat<0) & (preTrlSWRlat>-1000); + else + preTrialSWRlog = (preTrlSWRlat<0) & (preTrlSWRlat>(sessionMatrix(trl-1,2)-sessionMatrix(trl,1))/2); + end + trialSWRlatPRE{trl} = preTrlSWRlat(preTrialSWRlog); + trialRIPlogPRE(preTrialSWRlog) = true; + + trlSWRlog = (swrWindows(:,1) >= sessionMatrix(trl,1)) & (swrWindows(:,1) <= sessionMatrix(trl,2)); + trialSWRlat{trl} = swrWindows(trlSWRlog,1)-sessionMatrix(trl,1); + trialsWithRips(trl) = sum(trlSWRlog) ~= 0; + trialRIPlogTRIAL(trlSWRlog) = true; + + postTrlSWRlat = swrWindows(:,1) - sessionMatrix(trl,2); + if trl == size(sessionMatrix,1) || sessionMatrix(trl,3)==0 || sessionMatrix(trl,4)==max(sessionMatrix(:,4)) + postTrialSWRlog = (postTrlSWRlat>0) & (postTrlSWRlat<1000); + else + postTrialSWRlog = (postTrlSWRlat>0) & (postTrlSWRlat<(sessionMatrix(trl+1,1)-sessionMatrix(trl,2))/2); + end + trialSWRlatPOST{trl} = postTrlSWRlat(postTrialSWRlog); + trialRIPlogPOST(postTrialSWRlog) = true; + + trialRIPlog(preTrialSWRlog | trlSWRlog | postTrialSWRlog) = true; + end + + % Non-Trial SWRs + figure; + spDur = subplot(2,2,1); + swrDurs = swrWindows(:,2)-swrWindows(:,1); + histogram(swrDurs(~trialRIPlog), 0:10:max(swrDurs)+10, 'orientation', 'horizontal'); + set(spDur, 'XDir', 'reverse', 'YAxisLocation', 'right'); + title('SWR Duration'); + spPop = subplot(2,2,4); + histogram(swrActv(~trialRIPlog), 0:0.01:max(swrActv)+0.1); + title('Proportion Active Neurons'); + spDurPopCorr = subplot(2,2,2); + corrScatPlot(swrActv(~trialRIPlog)', swrDurs(~trialRIPlog), '% Active', 'Duration', [], []) + title('Non-Trial SWRs'); + linkaxes([spDur spDurPopCorr], 'y'); + linkaxes([spPop spDurPopCorr], 'x'); + supIRI = subplot(2,2,3); + swrIRI = swrWindows(2:end,2)-swrWindows(1:end-1,1); + histogram(swrIRI); + title('Inter-SWR-Interval'); + annotation(gcf,'textbox', [0 0.95 1 0.05],'String', sprintf('%s Non-Trial SWRs', aniInfo(a).ID),... + 'FontWeight', 'Bold', 'FontSize',10, 'edgecolor', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + + % Trial Period SWRs + figure('toolbar', 'none'); + spDurPRE = subplot(6,2,1); + histogram(swrDurs(trialRIPlogPRE), 0:50:max(swrDurs)+50, 'orientation', 'horizontal'); + set(spDurPRE, 'XDir', 'reverse', 'YAxisLocation', 'right'); + title('SWR Duration'); + spDurPopCorrPRE = subplot(6,2,2); + corrScatPlot(swrActv(trialRIPlogPRE)', swrDurs(trialRIPlogPRE), '% Active', 'Duration', [], []); + title('Pre Trial SWRs'); + spPRElat = subplot(6,2,3); + histogram(cell2mat(trialSWRlatPRE), -4000:200:0); + title('Pre Trial Latency'); + spPopPRE = subplot(6,2,4); + histogram(swrActv(trialRIPlogPRE), 0:0.05:max(swrActv)+0.05); + title('Proportion Active Neurons'); + + spDurTRL = subplot(6,2,5); + histogram(swrDurs(trialRIPlogTRIAL), 0:50:max(swrDurs)+50, 'orientation', 'horizontal'); + set(spDurTRL, 'XDir', 'reverse', 'YAxisLocation', 'right'); + title('SWR Duration'); + spDurPopCorrTRL = subplot(6,2,6); + corrScatPlot(swrActv(trialRIPlogTRIAL)', swrDurs(trialRIPlogTRIAL), '% Active', 'Duration', [], []); + title('Trial Period SWRs'); + spTRLlat = subplot(6,2,7); + histogram(cell2mat(trialSWRlat), 0:200:max(cell2mat(trialSWRlat))); + title('Trial Latency'); + spPopTRL = subplot(6,2,8); + histogram(swrActv(trialRIPlogTRIAL), 0:0.05:max(swrActv)+0.05); + title('Proportion Active Neurons'); + + spDurPOST = subplot(6,2,9); + histogram(swrDurs(trialRIPlogPOST), 0:50:max(swrDurs)+50, 'orientation', 'horizontal'); + set(spDurPOST, 'XDir', 'reverse', 'YAxisLocation', 'right'); + title('SWR Duration'); + spDurPopCorrPOST = subplot(6,2,10); + corrScatPlot(swrActv(trialRIPlogPOST)', swrDurs(trialRIPlogPOST), '% Active', 'Duration', [], []); + title('Post Trial SWRs'); + spPOSTlat = subplot(6,2,11); + histogram(cell2mat(trialSWRlatPOST), 0:200:4000); + title('Post Trial Latency'); + spPopPOST = subplot(6,2,12); + histogram(swrActv(trialRIPlogPOST), 0:0.05:max(swrActv)+0.05); + title('Proportion Active Neurons'); + + linkaxes([spDurPRE spDurTRL spDurPOST spDurPopCorrPRE spDurPopCorrTRL spDurPopCorrPOST], 'y'); + linkaxes([spPopPRE spPopTRL spPopPOST spDurPopCorrPRE spDurPopCorrTRL spDurPopCorrPOST], 'x'); + + linkaxes([spPRElat, spTRLlat, spPOSTlat], 'y'); + annotation(gcf,'textbox', [0 0.95 1 0.05],'String', sprintf('%s Trial SWRs', aniInfo(a).ID),... + 'FontWeight', 'Bold', 'FontSize',10, 'edgecolor', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + + %% Calculate Trial Templates to evaluate behavioral relations of SWR events + perfLog = sessionMatrix(:,3)==1; + isLog = sessionMatrix(:,4)==sessionMatrix(:,5); + + templates = cell(1,max(sessionMatrix(:,5))); + for o = 1:max(sessionMatrix(:,5)) + trlLog = sessionMatrix(:,5) == o & perfLog & isLog; + tempSsnMtx = sessionMatrix(trlLog,:); + tempTemplate = nan(120,size(ensemble.ensembleMatrix,2)-1, size(tempSsnMtx,1)); + for trl = 1:size(tempSsnMtx,1) + tempTrial = ensemble.ensembleMatrix(tempSsnMtx(trl,1):tempSsnMtx(trl,1)+1199,2:end); + for uni = 1:size(tempTrial,2) + tempConv = conv(tempTrial(:,uni), ones(1,10)./(10/1000),'same'); + tempTemplate(:,uni,trl) = downsample(tempConv,10); + end + end + templates{o} = mean(tempTemplate,3); + end + catTemplate = cell2mat(templates'); + timeNdx = downsample(repmat(1:1200, [1,5]), 10); + odrNdx = downsample([ones(1,1200), ones(1,1200)+1, ones(1,1200)+2, ones(1,1200)+3, ones(1,1200)+4], 10); + + %% All SWRs + trlRelRips = swrWindows; + ripDecodeODR = cell(size(trlRelRips,1),1); + ripDecodeTIME = cell(size(trlRelRips,1),1); + for rip = 1:size(trlRelRips,1) + tempEnsemble = ensemble.ensembleMatrix(trlRelRips(rip,1):trlRelRips(rip,2),2:end); + tempEnsConv = nan(size(tempEnsemble)); + for uni = 1:size(tempEnsemble,2) + tempEnsConv(:,uni) = conv(tempEnsemble(:,uni), ones(1,10)./(10/1000), 'same'); + end + post = CalcStaticBayesPost(catTemplate, downsample(tempEnsConv,10), 10); % <---------------- SWR Observation Rate + ripDecodeTIME{rip} = DecodeBayesPost(post, timeNdx); + ripDecodeODR{rip} = DecodeBayesPost(post, odrNdx); + end + + lagBins = 0:1:100; + odrLagDecodeMtx = repmat({zeros(max(sessionMatrix(:,4)), length(lagBins)-1)}, [1, max(sessionMatrix(:,4))]); + odrLagRips = cell(length(ripDecodeODR), max(sessionMatrix(:,4))); + tempHistBins = -1200:100:1200; + timeLag = zeros(1,length(tempHistBins)-1); + odrLagTrans = zeros(max(sessionMatrix(:,4))); + for rip = 1:length(ripDecodeODR) + tempRipODR = ripDecodeODR{rip}; + tempRipTIME = ripDecodeTIME{rip}; + tempRipNdx = 1:length(tempRipODR); + tempODRlagDecodeMtx = odrLagDecodeMtx; + for t = 1:length(tempRipODR) + curOdr = tempRipODR(t); + if ~isnan(curOdr) + for o = 1:max(sessionMatrix(:,4)) + odrTargLog = tempRipODR==o; + odrTargLag = tempRipNdx(odrTargLog) - t; + tempODRlagDecodeMtx{curOdr}(o,:) = tempODRlagDecodeMtx{curOdr}(o,:) + histcounts(odrTargLag, lagBins); + end + end + if t + ripCol = cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, 'LFP_Ripple$')); + lfp = statMatrix(:,ripCol); %#ok + clear statMatrix statMatrixColIDs file path + powThresh = [0 4]; + mergeThresh = 15; +end +%% +lfpFilt = SimpleFilt(lfp, fs, 150, 250); +zPow = zscore(abs(hilbert(lfpFilt))); + +%% Identify Potential Sharpwave Periods +abvThresh1 = zPow > powThresh(1); +epocStart = find(diff(abvThresh1)==1); +epocEnd = find(diff(abvThresh1)==-1); +epocWindows = [epocStart, nan(size(epocStart))]; +for epoc = 1:size(epocStart,1) + tempEpocEnd = epocEnd(find(epocEnd>epocStart(epoc), 1, 'first')); + if sum(zPow(epocStart(epoc):tempEpocEnd)>=powThresh(2))>=1 + epocWindows(epoc,2) = tempEpocEnd; + else + epocWindows(epoc,1) = nan; + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +% Merge short latency sharpwaves +for epoc = 2:size(epocWindows,1) + if ~isnan(epocWindows(epoc,1)) && ~isnan(epocWindows(epoc-1,1)) + if epocWindows(epoc,1) - epocWindows(epoc-1,2) <= mergeThresh + epocWindows(epoc,1) = epocWindows(epoc-1,1); + epocWindows(epoc-1,:) = nan; + end + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +%% +ripEpocs = epocWindows; +end + +function [swEpocs, hpf, zPow] = SharpwaveDetection(lfp, fs, powThresh, mergeThresh) +%% SharpwaveDetection +% Code for detection of sharpwaves on tetrodes presumed to be in the +% stratum radiatum of CA1 +% Inputs: +% lfp: Nx1 input of the raw LFP +% powThresh: 1x2 input with threshold parameters for detection of peak +% event. Initial value is event boundaries, second is peak required +% mergeThresh: threshold for merging two sharpwave events if they happen +% in close temporal proximity +%% +if nargin == 0 + [file,path] = uigetfile('*.mat'); + load([path file]); %#ok + lfp = statMatrix(:,2); %#ok + fs = 1/mode(diff(statMatrix(:,1))); + clear statMatrix statMatrixColIDs file path + powThresh = [0 2]; + mergeThresh = 15; +end +%% Filter & Z-Score Envelope +hpf = highpass(lfp, 4, fs); +zPow = zscore(abs(hilbert(hpf))); + +%% Identify Potential Sharpwave Periods +abvThresh1 = zPow > powThresh(1); +epocStart = find(diff(abvThresh1)==1); +epocEnd = find(diff(abvThresh1)==-1); +epocWindows = [epocStart, nan(size(epocStart))]; +for epoc = 1:size(epocStart,1) + tempEpocEnd = epocEnd(find(epocEnd>epocStart(epoc), 1, 'first')); + if sum(zPow(epocStart(epoc):tempEpocEnd)>=powThresh(2))>=1 + epocWindows(epoc,2) = tempEpocEnd; + else + epocWindows(epoc,1) = nan; + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +% Merge short latency sharpwaves +for epoc = 2:size(epocWindows,1) + if ~isnan(epocWindows(epoc,1)) && ~isnan(epocWindows(epoc-1,1)) + if epocWindows(epoc,1) - epocWindows(epoc-1,2) <= mergeThresh + epocWindows(epoc,1) = epocWindows(epoc-1,1); + epocWindows(epoc-1,:) = nan; + end + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +%% +swEpocs = epocWindows; +%% +end + +%% Simple Filtering +function lfpFilt = SimpleFilt(trace, samp, low, high) +Wn_FRange = [low/(samp/2) high/(samp/2)]; % normalized by the nyquist frequency +[bFRange, aFRange] = butter(3,Wn_FRange); +lfpFilt = filtfilt(bFRange,aFRange,trace); +end + +%% +function post = CalcStaticBayesPost(likely, obsv, binSize) +post = nan(size(obsv,1), size(likely,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(obsv,1) + p = nan(size(likely)); + curPopVect = obsv(t,:,trl)*(binSize/1000); + curPopFact = factorial(curPopVect); + for u = 1:size(likely,2) + curAvgUniFR = likely(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-((binSize/1000)*sum(likely,2))); + tempPost = pp.*ee; + post(t,:,trl) = tempPost./sum(tempPost); + end +end +end + +%% +function decode = DecodeBayesPost(post, id) +% Assumes post is in the structure of ObservTime X LikelyTime X Trial +decode = nan(size(post,1),size(post,3)); +for o = 1:size(post,3) + for d = 1:size(post,1) + if ~isnan(post(d,1,o)) + decode(d,o) = id(find(post(d,:,o)==max(post(d,:,o)),1,'first')); + end + end +end +end \ No newline at end of file diff --git a/Analyses/ExtractTrialEventRips_SM.m b/Analyses/ExtractTrialEventRips_SM.m new file mode 100644 index 0000000..ab69315 --- /dev/null +++ b/Analyses/ExtractTrialEventRips_SM.m @@ -0,0 +1,40 @@ +function [trialRipStruct] = ExtractTrialEventRips_SM(rips, trialWin) +% ExtractTrialEventRips_SM +% Extracts and organizes ripple data relative to the trial periods +% +% Inputs: +% - rips: Ripple data structure created by RippleDetection_SM +% - trialWin: Periods used for delineation of trial event related +% SWR. +% - First value is period prior to poke initiation considered +% as the "pre-trial" period +% - Second value is the period after poke withdrawal +% considered as the "post-trial" period + +%% Extract Near-Trial Epocs +trialPokeTimes = rips.TrialInfo.TrialPokes; +trialRips = cell(size(trialPokeTimes,1),3); +trialRipLat = cell(size(trialPokeTimes,1),3); +trialRipsDur = cell(size(trialPokeTimes,1),3); +trialRipsSync = cell(size(trialPokeTimes,1),3); +for trl = 1:size(trialPokeTimes,1) + preTrlLog = rips.Ripples.Events(:,1)>(trialPokeTimes(trl,1)-trialWin(1)) & rips.Ripples.Events(:,1)trialPokeTimes(trl,1) & rips.Ripples.Events(:,1)trialPokeTimes(trl,2) & (rips.Ripples.Events(:,1)=1); + locVals = behav.behavMatrix(locNdxs,end-1:end)*1.5/100; + timeVals = behav.behavMatrix(locNdxs,1); + instV = nan(size(locVals,1),1); + for v = 2:size(locVals,1) + instV(v) = sqrt((locVals(v,1)-locVals(v-1,1))^2 - (locVals(v,2)-locVals(v,2))^2)/diff(timeVals(v-1:v)); + end + smoothInstV = conv(instV, ones(1,20)/20, 'same'); + clear behav behavMat + + %% Evaluate Sharpwave channel & events + swFile = aniFiles(cell2mat(cellfun(@(a)~isempty(a),regexp({aniFiles.name}, ['\w*T' mat2str(aniInfo(a).SWchan) '_\w*SM.mat\>']),'uniformoutput', 0))).name; + sw = load([aniInfo(a).Directory swFile]); + [swEpocs, swLFP, swPOW] = SharpwaveDetection(sw.statMatrix(:,2), 1/mode(diff(sw.statMatrix(:,1))), swThresh, mergeThresh); + swLog = false(size(sw.statMatrix(:,1))); + for sws = 1:size(swEpocs,1) + swLog(swEpocs(sws,1):swEpocs(sws,2)) = true; + end + swTrace = nan(size(sw.statMatrix(:,1))); + swTrace(swLog) = sw.statMatrix(swLog,2); + aniInfo(a).SWepocs = swEpocs; + aniInfo(a).SWtrace = swLFP; + aniInfo(a).SWpower = swPOW; + + %% Evaluate Ripple channel & events + ripFile = aniFiles(cell2mat(cellfun(@(a)~isempty(a),regexp({aniFiles.name}, ['\w*T' mat2str(aniInfo(a).RIPchan) '_\w*SM.mat\>']),'uniformoutput', 0))).name; + rip = load([aniInfo(a).Directory ripFile]); + [ripEpocs, ripLFP, ripPOW] = RippleDetection(rip.statMatrix(:,2), 1/mode(diff(rip.statMatrix(:,1))), ripThresh, mergeThresh); + ripLog = false(size(rip.statMatrix(:,1))); + for rips = 1:size(ripEpocs,1) + ripLog(ripEpocs(rips,1):ripEpocs(rips,2)) = true; + end + ripTrace = nan(size(rip.statMatrix(:,1))); + ripTrace(ripLog) = rip.statMatrix(ripLog,2); + aniInfo(a).RIPepocs = ripEpocs; + aniInfo(a).RIPtrace = ripLFP; + aniInfo(a).RIPpower = ripPOW; + + %% Identify Sharpwave Ripple events + swrLog = swLog + ripLog; + swrStart = find(diff(swrLog==2)==1); + swrEnd = find(diff(swrLog==2)==-1); + swrWindows = [swrStart nan(length(swrStart),1)]; + for swr = 1:length(swrStart) + tempSWRstart = swrStart(swr); + swrWindows(swr,1) = min([swEpocs(tempSWRstart>=swEpocs(:,1) & tempSWRstart<=swEpocs(:,2),1), ripEpocs(tempSWRstart>=ripEpocs(:,1) & tempSWRstart<=ripEpocs(:,2),1), tempSWRstart]); + + tempSWRend = swrEnd(find(swrEnd>tempSWRstart,1,'first')); + swrWindows(swr,2) = max([swEpocs(tempSWRend>=swEpocs(:,1) & tempSWRend<=swEpocs(:,2),2), ripEpocs(tempSWRend>=ripEpocs(:,1) & tempSWRend<=ripEpocs(:,2),2), tempSWRend]); + end + for swr = 2:size(swrWindows,1) + if ~isnan(swrWindows(swr,1)) && ~isnan(swrWindows(swr-1,1)) + if swrWindows(swr,1) - swrWindows(swr-1,2) <= mergeThresh + swrWindows(swr,1) = swrWindows(swr-1,1); + swrWindows(swr-1,:) = nan; + end + end + end + swrWindows(isnan(swrWindows(:,1)),:) = []; + aniInfo(a).SWRepocs = swrWindows; + + newSWtrace = nan(size(sw.statMatrix(:,1))); + newRIPtrace = nan(size(rip.statMatrix(:,1))); + for swr = 1:size(swrWindows,1) + newSWtrace(swrWindows(swr,1):swrWindows(swr,2)) = sw.statMatrix(swrWindows(swr,1):swrWindows(swr,2),2); + newRIPtrace(swrWindows(swr,1):swrWindows(swr,2)) = rip.statMatrix(swrWindows(swr,1):swrWindows(swr,2),2); + end + + %% Identify Sequence & Non-Sequence SWRs + intSeqSWRlog = false(size(swrWindows,1),1); + betSeqsSWRlog = false(size(swrWindows,1),1); + for swr = 1:size(swrWindows,1) + preSWRtrlNdx = find(swrWindows(swr,1)>sessionMatrix(1:end-1,2) & swrWindows(swr,1) + ripCol = cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, 'LFP_Ripple$')); + lfp = statMatrix(:,ripCol); %#ok + clear statMatrix statMatrixColIDs file path + powThresh = [0 4]; + mergeThresh = 15; +end +%% +lfpFilt = SimpleFilt(lfp, fs, 150, 250); +zPow = zscore(abs(hilbert(lfpFilt))); + +%% Identify Potential Sharpwave Periods +abvThresh1 = zPow > powThresh(1); +epocStart = find(diff(abvThresh1)==1); +epocEnd = find(diff(abvThresh1)==-1); +epocWindows = [epocStart, nan(size(epocStart))]; +for epoc = 1:size(epocStart,1) + tempEpocEnd = epocEnd(find(epocEnd>epocStart(epoc), 1, 'first')); + if sum(zPow(epocStart(epoc):tempEpocEnd)>=powThresh(2))>=1 + epocWindows(epoc,2) = tempEpocEnd; + else + epocWindows(epoc,1) = nan; + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +% Merge short latency sharpwaves +for epoc = 2:size(epocWindows,1) + if ~isnan(epocWindows(epoc,1)) && ~isnan(epocWindows(epoc-1,1)) + if epocWindows(epoc,1) - epocWindows(epoc-1,2) <= mergeThresh + epocWindows(epoc,1) = epocWindows(epoc-1,1); + epocWindows(epoc-1,:) = nan; + end + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +%% +ripEpocs = epocWindows; +end + +function [swEpocs, hpf, zPow] = SharpwaveDetection(lfp, fs, powThresh, mergeThresh) +%% SharpwaveDetection +% Code for detection of sharpwaves on tetrodes presumed to be in the +% stratum radiatum of CA1 +% Inputs: +% lfp: Nx1 input of the raw LFP +% powThresh: 1x2 input with threshold parameters for detection of peak +% event. Initial value is event boundaries, second is peak required +% mergeThresh: threshold for merging two sharpwave events if they happen +% in close temporal proximity +%% +if nargin == 0 + [file,path] = uigetfile('*.mat'); + load([path file]); %#ok + lfp = statMatrix(:,2); %#ok + fs = 1/mode(diff(statMatrix(:,1))); + clear statMatrix statMatrixColIDs file path + powThresh = [0 2]; + mergeThresh = 15; +end +%% Filter & Z-Score Envelope +hpf = highpass(lfp, 4, fs); +zPow = zscore(abs(hilbert(hpf))); + +%% Identify Potential Sharpwave Periods +abvThresh1 = zPow > powThresh(1); +epocStart = find(diff(abvThresh1)==1); +epocEnd = find(diff(abvThresh1)==-1); +epocWindows = [epocStart, nan(size(epocStart))]; +for epoc = 1:size(epocStart,1) + tempEpocEnd = epocEnd(find(epocEnd>epocStart(epoc), 1, 'first')); + if sum(zPow(epocStart(epoc):tempEpocEnd)>=powThresh(2))>=1 + epocWindows(epoc,2) = tempEpocEnd; + else + epocWindows(epoc,1) = nan; + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +% Merge short latency sharpwaves +for epoc = 2:size(epocWindows,1) + if ~isnan(epocWindows(epoc,1)) && ~isnan(epocWindows(epoc-1,1)) + if epocWindows(epoc,1) - epocWindows(epoc-1,2) <= mergeThresh + epocWindows(epoc,1) = epocWindows(epoc-1,1); + epocWindows(epoc-1,:) = nan; + end + end +end +epocWindows(isnan(epocWindows(:,1)),:) = []; +%% +swEpocs = epocWindows; +%% +end + +%% Simple Filtering +function lfpFilt = SimpleFilt(trace, samp, low, high) +Wn_FRange = [low/(samp/2) high/(samp/2)]; % normalized by the nyquist frequency +[bFRange, aFRange] = butter(3,Wn_FRange); +lfpFilt = filtfilt(bFRange,aFRange,trace); +end \ No newline at end of file diff --git a/Analyses/MorletAG.m b/Analyses/MorletAG.m index 4966d0d..4e71156 100644 --- a/Analyses/MorletAG.m +++ b/Analyses/MorletAG.m @@ -25,8 +25,12 @@ freq = minFreq:maxFreq; %% Frequency of Morlet Wavelet %% Bandstop 60Hz signal -[b1, a1] = butter(2, [59/500 61/500], 'stop'); %% Remove 60hz Harmonic (noise) -bsData = filtfilt(b1, a1, lfp); +if minFreq<=60 %% Remove 60hz Harmonic (noise) if necessary + [b1, a1] = butter(2, [59/500 61/500], 'stop'); + bsData = filtfilt(b1, a1, lfp); +else + bsData = lfp; +end % bsData = lfp; freqPower = nan(length(freq),length(time)); %% Create the data matrix dataX = fft(bsData', length(time)*2-1); %% Fast Fourier Transform of Data (correct length) @@ -49,5 +53,5 @@ power = abs(analytic_signal).^2; %% Extract Power power = (10*log10(power)); %% Convert to Logarithmic Scale - freqPower(fi, :) = power; %% Add Data to Matrix + freqPower(fi, 1:length(power)) = power; %% Add Data to Matrix end \ No newline at end of file diff --git a/Analyses/IdentifySWRs_SM.m b/Analyses/Old/IdentifySWRs_SM.m similarity index 78% rename from Analyses/IdentifySWRs_SM.m rename to Analyses/Old/IdentifySWRs_SM.m index e89dd52..4d46d35 100644 --- a/Analyses/IdentifySWRs_SM.m +++ b/Analyses/Old/IdentifySWRs_SM.m @@ -59,7 +59,7 @@ interEpocInterval = epocWindows(2:end,1) - epocWindows(1:end-1,2); % % Merge Ripples that Occur within 15ms of eachother -shortLatRipls = find(interEpocInterval<10); +shortLatRipls = find(interEpocInterval<15); for slr = 1:length(shortLatRipls) epocWindows(shortLatRipls(slr),2) = epocWindows(shortLatRipls(slr)+1,2); end @@ -93,7 +93,7 @@ subplot(2,2,[2 4]); corrScatPlot(epocDur(1:end-1), interEpocInterval, 'Duration', 'Latency',[]); -26.7%% Format Output +%% Format Output tsVect = statMatrix(:,1); swrIndices = tsVect(epocWindows); swrVectLog = false(size(tsVect)); @@ -129,41 +129,41 @@ b = gca; linkaxes([a b], 'x') -%% -peakLoc = nan(size(epocWindows,1),1); -peakPwr = nan(size(epocWindows,1),1); -phaseMtx = cell(size(epocWindows,1),1); -phaseCorr = nan(size(epocWindows,1),1); -parfor epoc = 1:size(epocWindows,1) - curEpocWindow = epocWindows(epoc,1):epocWindows(epoc,2); - [tmpPks, tmpLocs] = findpeaks(aggPower(curEpocWindow), 'MinPeakHeight', rmsThresh, 'MinPeakProminence', rmsThresh); - if isempty(tmpPks) - [tmpPks, tmpLocs] = findpeaks(aggPower(curEpocWindow)); - % if isempty(tmpPks) - % disp('EMPTY PEAKS') - % continue - % % tmpPks = aggPower(curEpocWindow); - % % tmpLocs = 1:length(tmpPks); - % end - end - if ~isempty(tmpPks) - curEpocPhaseMtx = nan(size(bandPhase,2)); - for tetA = 1:size(bandPhase,2) - for tetB = 1:size(bandPhase,2) - curEpocPhaseMtx(tetA,tetB) = circ_corrcc(bandPhase(curEpocWindow,tetA), bandPhase(curEpocWindow,tetB)); - end - end - phaseMtx{epoc} = curEpocPhaseMtx; - phaseCorr(epoc) = mean(curEpocPhaseMtx(triu(true(size(curEpocPhaseMtx)),1))); - peakPwr(epoc) = (max(tmpPks)-mean(aggPower))/std(aggPower); % z-norm peak power; - tmpEpocPkLoc = tmpLocs(tmpPks==max(tmpPks)); - if size(tmpEpocPkLoc)>1 - tmpEpocPkLoc = tmpEpocPkLoc(1); - end - tempEpocPkLoc = epocWindows(epoc,1)+tmpEpocPkLoc; - peakLoc(epoc) = tempEpocPkLoc; - end -end +%% SOMETHING'S BROKE HERE +% peakLoc = nan(size(epocWindows,1),1); +% peakPwr = nan(size(epocWindows,1),1); +% phaseMtx = cell(size(epocWindows,1),1); +% phaseCorr = nan(size(epocWindows,1),1); +% parfor epoc = 1:size(epocWindows,1) +% curEpocWindow = epocWindows(epoc,1):epocWindows(epoc,2); +% [tmpPks, tmpLocs] = findpeaks(aggPower(curEpocWindow), 'MinPeakHeight', rmsThresh, 'MinPeakProminence', rmsThresh); +% if isempty(tmpPks) +% [tmpPks, tmpLocs] = findpeaks(aggPower(curEpocWindow)); +% % if isempty(tmpPks) +% % disp('EMPTY PEAKS') +% % continue +% % % tmpPks = aggPower(curEpocWindow); +% % % tmpLocs = 1:length(tmpPks); +% % end +% end +% if ~isempty(tmpPks) +% curEpocPhaseMtx = nan(size(bandPhase,2)); +% for tetA = 1:size(bandPhase,2) +% for tetB = 1:size(bandPhase,2) +% curEpocPhaseMtx(tetA,tetB) = circ_corrcc(bandPhase(curEpocWindow,tetA), bandPhase(curEpocWindow,tetB)); +% end +% end +% phaseMtx{epoc} = curEpocPhaseMtx; +% phaseCorr(epoc) = mean(curEpocPhaseMtx(triu(true(size(curEpocPhaseMtx)),1))); +% peakPwr(epoc) = (max(tmpPks)-mean(aggPower))/std(aggPower); % z-norm peak power; +% tmpEpocPkLoc = tmpLocs(tmpPks==max(tmpPks)); +% if size(tmpEpocPkLoc)>1 +% tmpEpocPkLoc = tmpEpocPkLoc(1); +% end +% tempEpocPkLoc = epocWindows(epoc,1)+tmpEpocPkLoc; +% peakLoc(epoc) = tempEpocPkLoc; +% end +% end % %% Edit the SWRs % % Combine short SWRs diff --git a/Analyses/Old/UnitSummary_SM.m b/Analyses/Old/UnitSummary_SM.m index d1f6d7b..4db35b7 100644 --- a/Analyses/Old/UnitSummary_SM.m +++ b/Analyses/Old/UnitSummary_SM.m @@ -97,7 +97,7 @@ curUnis = statMatrixColIDs(cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, '-U([0-9]*)'))); unitSummaryUnis = {unitSummary.UnitName}; - clear curTetStatDiffPERF curTetStatDiffTC +% clear curTetStatDiffPERF curTetStatDiffTC %% Plot Per-Tetrode Spectrograms % Performance @@ -114,11 +114,11 @@ PlotTrialEventSpect_SM(curTet, behEventData, behEventDataIDs,... tcCorrLogs, tcCorrLogIDs,... statMatrix, statMatrixColIDs, eventWindow, spectFreqWindow, printYN); - - % Temporal Context - Incorrect - PlotTrialEventSpect_SM(curTet, behEventData, behEventDataIDs,... - tcInCorrLogs, tcInCorrLogIDs,... - statMatrix, statMatrixColIDs, eventWindow, spectFreqWindow, printYN); +% +% % Temporal Context - Incorrect +% PlotTrialEventSpect_SM(curTet, behEventData, behEventDataIDs,... +% tcInCorrLogs, tcInCorrLogIDs,... +% statMatrix, statMatrixColIDs, eventWindow, spectFreqWindow, printYN); %% Spike Phase Relationship Stuff PlotSpikePhaseRelations_SM(statMatrix, statMatrixColIDs,... trialAlignedBehavMatrix,... @@ -138,7 +138,7 @@ % Figure 1: Overall Unit Summary fig1 = figure('Name', [curUnit ' Summary'], 'NumberTitle', 'off'); PlotUnitFeatures_SM(curUnitSummary, curUniSpikeTimes, fig1, printYN); - +% %% Performance PEHs % Overall overallPerf = PlotTrialEventPEH_SM(curUnit, behEventData, behEventDataIDs,... @@ -158,7 +158,7 @@ curUniSpikeLog, eventWindow, pehBinSize, printYN); % F-Ratio Analysis Odor vs Position - curTetStatDiffPERF(uni) = FratioAnalysis_SM(curUnit, perfByOdor, perfByPosition); %#ok +% curTetStatDiffPERF(uni) = FratioAnalysis_SM(curUnit, perfByOdor, perfByPosition); %#ok %% Temporal Context PEH % Overall @@ -179,7 +179,7 @@ curUniSpikeLog, eventWindow, pehBinSize, printYN); % F-Ratio Analysis Odor vs Position - curTetStatDiffTC(uni) = FratioAnalysis_SM(curUnit, tcByOdor, tcByPosition); %#ok +% curTetStatDiffTC(uni) = FratioAnalysis_SM(curUnit, tcByOdor, tcByPosition); %#ok %% Temporal Context X Performance PEH % Overall InSeq v OutSeq Corr @@ -226,7 +226,7 @@ %% close all end - statDiffPerTetPERF{t} = curTetStatDiffPERF; - statDiffPerTetTC{t} = curTetStatDiffTC; +% statDiffPerTetPERF{t} = curTetStatDiffPERF; +% statDiffPerTetTC{t} = curTetStatDiffTC; end %% \ No newline at end of file diff --git a/Analyses/PFC/PFC_MLB.m b/Analyses/PFC/PFC_MLB.m new file mode 100644 index 0000000..e56b524 --- /dev/null +++ b/Analyses/PFC/PFC_MLB.m @@ -0,0 +1,449 @@ + +%% PFC_MLB +clc +clear all + +%% Runtime variables +% if nargin==0 + piWindow = [-0.5 0.5]; + poWindow = [-0.5 0.5]; + binSize = 200; + dsRate = 5; + cLim = [0 0.01]; + smPath = uigetdir; +% end +%% +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Extract Behavioral Periods +% trialInfo = [1:Trial#, 2:Sequence#, 3:Position, 4:Odor, 5:Performance, 6:tDist, 7:PokeDur, 8:WithdrawLat] +[piSpkMtx, piTrialTime, trialInfo] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, 'PokeIn', piWindow, binSize, dsRate); +[poSpkMtx, poTrialTime, ~] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, 'PokeOut', poWindow, binSize, dsRate); + +decodings.SMIbehav = CalculateSMI([sum(trialInfo(trialInfo(:,6)==0,5)), sum(~trialInfo(trialInfo(:,6)==0,5)); sum(~trialInfo(trialInfo(:,6)~=0,5)), sum(trialInfo(trialInfo(:,6)~=0,5))]); +decodings.SMIbehavSFP = CalculateSMI([sum(trialInfo(trialInfo(:,6)==0 & trialInfo(:,3)~=1,5)), sum(~trialInfo(trialInfo(:,6)==0 & trialInfo(:,3)~=1,5)); sum(~trialInfo(trialInfo(:,6)~=0,5)), sum(trialInfo(trialInfo(:,6)~=0,5))]); + +decodings.PItime = piTrialTime; +decodings.POtime = poTrialTime; + +clear ensembleMatrix ensembleMatrixColIDs behavMatrix behavMatrixColIDs +%% Identify Fully InSeq Trials & Calculate FIS Liklihoods (PSTH) +fullInSeqSeqsStart = find(conv(trialInfo(:,4), 1:4, 'valid')==20 & conv(trialInfo(:,3), 1:4, 'valid')==20 & conv(trialInfo(:,5), ones(1,4), 'valid')==4); +inSeqSeqs = nan(3,length(fullInSeqSeqsStart)); +for iS = 1:length(fullInSeqSeqsStart) + inSeqSeqs(1,iS) = fullInSeqSeqsStart(iS); + inSeqSeqs(2,iS) = fullInSeqSeqsStart(iS) + 1; + inSeqSeqs(3,iS) = fullInSeqSeqsStart(iS) + 2; + inSeqSeqs(4,iS) = fullInSeqSeqsStart(iS) + 3; +end + +piFISlikes = repmat({nan(size(piSpkMtx,1), size(piSpkMtx,2))}, 4,1); +poFISlikes = repmat({nan(size(poSpkMtx,1), size(poSpkMtx,2))}, 4,1); +for p = 1:4 + piFISlikes{p} = mean(piSpkMtx(:,:,inSeqSeqs(p,:)),3); + poFISlikes{p} = mean(poSpkMtx(:,:,inSeqSeqs(p,:)),3); +end + +% Plot Likelihoods +figure; +figLims = [0 max(max([cell2mat(piFISlikes); cell2mat(poFISlikes)]))]; +subplot(4,2,1); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{1}', figLims); title(gca, 'Poke In'); ylabel('Odor A'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,2); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{1}', figLims); title(gca, 'Poke Out'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,3); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{2}', figLims); ylabel('Odor B'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,4); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{2}', figLims); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,5); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{3}', figLims); ylabel('Odor C'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,6); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{3}', figLims); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,7); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{4}', figLims); ylabel('Odor D'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,8); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{4}', figLims); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +%% Organized Ensemble Templates +% time = [piTrialTime', poTrialTime'+1+dsRate/100]; +% +% spks = cellfun(@(a,b)[a',b'], piFISlikes, poFISlikes, 'uniformoutput', 0); +% +% grandMean = mean(cell2mat(reshape(spks, [1,1,4])),3); +% maxSpkNdx = [nan(size(grandMean,1),1), (1:size(grandMean,1))']; +% for c = 1:size(grandMean,1) +% maxSpkNdx(c,1) = find(grandMean(c,:)==max(grandMean(c,:)), 1, 'first'); +% end +% sortedMaxSpk = sortrows(maxSpkNdx); +% +% sortedSpks = cellfun(@(a)a(sortedMaxSpk(:,2),:),spks, 'uniformoutput',0); +% maxSpk = max(cell2mat(cellfun(@(a)max(max(a)),spks, 'uniformoutput', 0))); +% +% figure; +% sp1 = subplot(1,4,1); +% imagesc(time, 1:size(grandMean,1),sortedSpks{1}, [0 maxSpk/2]); +% sp2 = subplot(1,4,2); +% imagesc(time, 1:size(grandMean,1),sortedSpks{2}, [0 maxSpk/2]); +% sp3 = subplot(1,4,3); +% imagesc(time, 1:size(grandMean,1),sortedSpks{3}, [0 maxSpk/2]); +% sp4 = subplot(1,4,4); +% imagesc(time, 1:size(grandMean,1),sortedSpks{4}, [0 maxSpk/2]); + +%% Decode via Leave 1 out +issPosts = nan((size(piSpkMtx,1) + size(poSpkMtx,1))*4, (size(piSpkMtx,1) + size(poSpkMtx,1))*4,size(inSeqSeqs,2)); +for s = 1:size(inSeqSeqs,2) + tempISSs = inSeqSeqs; + tempISSs(:,s) = []; + + tempFISlikes = repmat({nan(size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,2) + size(poSpkMtx,2))}, 4,1); + tempObsv = tempFISlikes; + for p = 1:4 + tempFISlikes{p} = [mean(piSpkMtx(:,:,tempISSs(p,:)),3); mean(poSpkMtx(:,:,tempISSs(p,:)),3)]; + tempObsv{p} = [piSpkMtx(:,:,inSeqSeqs(p,s)); poSpkMtx(:,:,inSeqSeqs(p,s))]; + end + + issPosts(:,:,s) = CalcStaticBayesPost(cell2mat(tempFISlikes), cell2mat(tempObsv), binSize); +end +odorLog = [ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*1,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*2,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*3,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*4]; +timeLog = [piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000]; + +figure; +subplot(6,4,1:16); +% imagesc(nanmedian(issPosts,3)', cLim); set(gca, 'ydir', 'normal'); colormap jet +imagesc(nanmean(issPosts,3)', cLim); set(gca, 'ydir', 'normal'); colormap jet +set(gca, 'xtick', [], 'ytick', []); +for op = 1:4 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'white', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2] + repmat(size(piSpkMtx,1) + size(poSpkMtx,1),1,2)*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line([size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1) size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, 'linestyle', '-', 'color', 'white', 'linewidth', 2); + line(get(gca, 'xlim'), [size(piSpkMtx,1)/2 size(piSpkMtx,1)/2] + repmat(size(piSpkMtx,1) + size(poSpkMtx,1),1,2)*(op-1), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line(get(gca, 'xlim'), [size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1) size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +end + +% Odor Decoding (true decoding) +decodeOdor = DecodeBayesPost(issPosts, odorLog); +decodings.Odor = [mean(decodeOdor==1,2), mean(decodeOdor==2,2), mean(decodeOdor==3,2), mean(decodeOdor==4,2)]; +subplot(6,4,17:20) +plot(1:size(decodeOdor,1), decodings.Odor(:,1), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(1:size(decodeOdor,1), decodings.Odor(:,2), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(1:size(decodeOdor,1), decodings.Odor(:,3), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(1:size(decodeOdor,1), decodings.Odor(:,4), 'color', [128/255 66/255 151/255], 'linewidth', 1); +legend('A', 'B', 'C','D', 'location', 'southoutside', 'orientation', 'horizontal'); +ylabel([{'Decoding'};{'(% Trials)'}]); + +axis tight +set(gca, 'ylim', [0 1], 'xtick', []); +for op = 1:4 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +end + +% Temporal Decoding +decodeTime = DecodeBayesPost(issPosts, timeLog); +decodeLag = nan(size(decodeTime)); +for c = 1:size(decodeTime,2) + decodeLag(:,c) = decodeTime(:,c)-timeLog'; +end +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,1,2); +decodings.Time = lagMean; +subplot(6,4,21:24) +plot(lagMean, '-k', 'linewidth', 1); +patch('YData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'XData', [1:length(lagMean), length(lagMean):-1:1], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight +line([0 length(lagMean)], [0 0], 'linestyle', '--', 'color', 'k', 'linewidth', 1); + +for op = 1:4 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +end +set(gca, 'xtick', []); +ylabel(gca,'Lag (s)'); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +%% Investigate the Posteriors... tabulate across odors and break down by trial periods +% Define trial periods +trlPrdLog(:,1) = [piTrialTime<=0; false(size(poTrialTime))]; % Pre-Trial Log +trlPrdLog(:,2) = [piTrialTime>0; false(size(poTrialTime))]; % Early-Trial Log +trlPrdLog(:,3) = [false(size(piTrialTime)); poTrialTime<=0]; % Late-Trial Log +trlPrdLog(:,4) = [false(size(piTrialTime)); poTrialTime>0]; % Post-Trial Log +trlPrdLog = repmat(trlPrdLog, [4,1]); +post = TabulateBayesPost(issPosts, odorLog); + +trlPrdDecodeMean = nan(4,4,4); +trlPrdDprm = nan(1,4); +trlPrdDecodeVar = nan(4,4,4); +for trlPrd = 1:4 + for opObs = 1:4 + for opDec = 1:4 + tempPosts = post(odorLog'==opObs & trlPrdLog(:,trlPrd),:,opDec); + trlPrdDecodeMean(opDec, opObs, trlPrd) = nanmean(tempPosts(:)); + trlPrdDecodeVar(opDec,opObs,trlPrd) = nanstd(nanmean(tempPosts)); + end + end + tempTrlPrdPost = trlPrdDecodeMean(:,:,trlPrd); + trlPrdDprm(trlPrd) = norminv(mean(tempTrlPrdPost(logical(eye(4)))))-norminv(mean(tempTrlPrdPost(~logical(eye(4))))); +end +figure; +subplot(2,2,1) +imagesc(trlPrdDecodeMean(:,:,1), [0 0.5]); +title('Pre-Trial Period'); +xlabel('True Position'); +subplot(2,2,2) +imagesc(trlPrdDecodeMean(:,:,2), [0 0.5]); +title('Early-Trial Period'); +subplot(2,2,3) +imagesc(trlPrdDecodeMean(:,:,3), [0 0.5]); +title('Late-Trial Period'); +xlabel('True Position'); +ylabel('Decoded Position'); +subplot(2,2,4) +imagesc(trlPrdDecodeMean(:,:,4), [0 0.5]); +title('Post-Trial Period'); +xlabel('True Position'); +colormap jet + +decodings.TrialPeriods = trlPrdDecodeMean; +decodings.TrialPeriodsDprm = trlPrdDprm; + +%% Investigate decoding more.... possibly do rank order quantification for each index... tabulate at each index which odor is 1st, 2nd, 3rd, 4th +% Possibly the indexing will demonstrate a lag effect, i.e. 1st = current odor, 2nd = next odor. +% Alternatively, examine decoding of peaks? +% Alternatively (and I like this one the most), calculate total posterior for different odors, i.e. calculate sum or average posterior value for each odor at each index + +%% Step through and decode each OutSeq Trial +outSeqTrials = find(trialInfo(:,6)~=0 & trialInfo(:,5)==1 & trialInfo(:,3)<=4 & trialInfo(:,4)<=4 & trialInfo(:,4)~=1); + +osPosts = nan(size(piSpkMtx,1)+size(poSpkMtx,1),(size(piSpkMtx,1)+size(poSpkMtx,1))*2,length(outSeqTrials)); +for osT = 1:length(outSeqTrials) + tempObsv = [piSpkMtx(:,:,outSeqTrials(osT)); poSpkMtx(:,:,outSeqTrials(osT))]; + osPos = trialInfo(outSeqTrials(osT),3); + osOdr = trialInfo(outSeqTrials(osT),4); + + tempPosLikes = [mean(piSpkMtx(:,:,tempISSs(osPos,:)),3); mean(poSpkMtx(:,:,tempISSs(osPos,:)),3)]; + tempOdrLikes = [mean(piSpkMtx(:,:,tempISSs(osOdr,:)),3); mean(poSpkMtx(:,:,tempISSs(osOdr,:)),3)]; + tempLikes = [tempPosLikes; tempOdrLikes]; + + osPosts(:,:,osT) = CalcStaticBayesPost(tempLikes, tempObsv, binSize); +end +odorLog = [ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*1,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*2]; +timeLog = [piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000]; + +figure; +subplot(6,4,1:16) +% imagesc(nanmedian(osPosts,3), cLim); set(gca, 'ydir', 'normal'); colormap jet +imagesc(nanmean(osPosts,3)', cLim); set(gca, 'ydir', 'normal'); colormap jet +xlabel('Observed'); +ylabel('Decodeded'); +set(gca,... + 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}],... + 'ytick', [size(piSpkMtx,1)/2 size(piSpkMtx,1) size(piSpkMtx,1)+size(poSpkMtx,1)/2 size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1) size(piSpkMtx,1)*2+size(poSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)],... + 'yticklabel', [{'PokeIn'}, {'\bf\fontsize{14}Position'}, {'PokeOut'}, {'PokeIn'}, {'\bf\fontsize{14}Odor'}, {'PokeOut'}]); +line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)], 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2+size(piSpkMtx,1)*2 size(piSpkMtx,1)/2+size(piSpkMtx,1)*2], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1) size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +% Odor Decoding +decodeOdor = DecodeBayesPost(osPosts, odorLog); +posDecode = mean(decodeOdor==1,2); +odrDecode = mean(decodeOdor==2,2); +decodings.OSdiff = posDecode-odrDecode; +subplot(6,4,17:20) +plot(1:size(decodeOdor,1), posDecode-odrDecode, 'color', 'k', 'linewidth', 1); +axis tight +set(gca, 'ylim', [-1 1], 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +ylabel([{'Decoded Difference'};{'(Pos-Odor)'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(piSpkMtx,1) size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + +% Temporal Decoding +decodeTime = DecodeBayesPost(osPosts, timeLog); +decodeLag = nan(size(decodeTime)); +for c = 1:size(decodeTime,2) + decodeLag(:,c) = decodeTime(:,c)-[piTrialTime', poTrialTime'+1+dsRate/1000]'; +end +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,1,2); +subplot(6,4,21:24) +plot(lagMean, '-k', 'linewidth', 1); +patch('YData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'XData', [1:length(lagMean), length(lagMean):-1:1], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight +set(gca, 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(piSpkMtx,1) size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +% Split into Skips and Repeats +tDistVals = trialInfo(outSeqTrials,6); +skps = osPosts(:,:,tDistVals<0); +reps = osPosts(:,:,tDistVals>0); + +figure; +repSP = subplot(6,8,[1:4,9:12,17:20,25:28]); +imagesc(nanmean(reps, 3)', cLim); set(gca, 'ydir', 'normal'); colormap jet; +title('Repeats'); +decodeRep = DecodeBayesPost(reps, odorLog); +posDecode = mean(decodeRep==1,2); +odrDecode = mean(decodeRep==2,2); +decodings.OSdiffREP = posDecode-odrDecode; +subplot(6,8,33:36) +plot(1:size(decodeRep,1), posDecode-odrDecode, 'color', 'k', 'linewidth', 1); +axis tight +set(gca, 'ylim', [-1 1], 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +ylabel([{'Decoded Difference'};{'(Pos-Odor)'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(piSpkMtx,1) size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + + +skpSP = subplot(6,8,[5:8,13:16,21:24,29:32]); +imagesc(nanmean(skps, 3)', cLim); set(gca, 'ydir', 'normal'); colormap jet; +title('Skips'); +decodeSkp = DecodeBayesPost(skps, odorLog); +posDecode = mean(decodeSkp==1,2); +odrDecode = mean(decodeSkp==2,2); +decodings.OSdiffSKP = posDecode-odrDecode; +subplot(6,8,37:40) +plot(1:size(decodeSkp,1), posDecode-odrDecode, 'color', 'k', 'linewidth', 1); +axis tight +set(gca, 'ylim', [-1 1], 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +ylabel([{'Decoded Difference'};{'(Pos-Odor)'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(piSpkMtx,1) size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + + +%% Trial After OutSeq +% For TAO, use FIS as likelihoods and TAO as observations +% How to compare TAO with FIS decoding... Compare both posteriors as well +% as the likelihood of decoding the correct odor. +%% +%%*******************************************************%% +%%********************** Functions **********************%% +%%*******************************************************%% +function [binnedMtx, trialTime, trialInfo] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, alignment, window, binSize, dsRate) +% First check to make sure reward signal is present within the +% behaviorMatrix +if sum(strcmp(behavMatrixColIDs, 'RewardSignal'))==0 + warning('Reward signal missing from behavior matrix, update the behavior matrix. OR ignore this if reward signal wasn''t recorded as plx flag'); +end +% Organize behavior data and Extract Ensemble Spiking +% Taking 1/2 the binSize on either end to get rid of edge effects. +td = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [window(1)-(binSize/2/1000) window(2)+(binSize/2/1000)], alignment); +trialEnsemble = ExtractTrialData_SM(td, ensembleMatrix(:,2:end)); %#ok<*NODEF> +ensembleMtx = cell2mat(reshape(trialEnsemble, [1 1 length(trialEnsemble)])); +if strcmp(alignment, 'PokeIn') + trialTimes = behavMatrix(td(1).TrialLogVect,1) - behavMatrix(td(1).PokeInIndex,1); +else + trialTimes = behavMatrix(td(1).TrialLogVect,1) - behavMatrix(td(1).PokeOutIndex,1); +end + +%% Bin the spiking data +% First convolve the entire trialEnsembleMtx with a square to bin the +% spikes +binnedEnsembleMtx = nan(size(ensembleMtx)); +for t = 1:size(ensembleMtx,3) + for u = 1:size(ensembleMtx,2) + binnedEnsembleMtx(:,u,t) = conv(ensembleMtx(:,u,t), ones(1,binSize)./(binSize/1000), 'same'); +% binnedEnsembleMtx(:,u,t) = conv(trialEnsembleMtx(:,u,t), ones(1,binSize), 'same'); + end +end +% Now remove the binSize/2 padding +unPaddedBinnedEnsembleMtx = binnedEnsembleMtx((binSize/2)+1:end-(binSize/2),:,:); +trialTimes = trialTimes((binSize/2)+1:end-(binSize/2)); +% Now downsample the binned matrix +dsVect = downsample(1:size(unPaddedBinnedEnsembleMtx,1), dsRate); +binnedMtx = unPaddedBinnedEnsembleMtx(dsVect,:,:); +trialTime = trialTimes(dsVect); + +trialInfo = [[td.TrialNum]', [td.SequenceNum]', [td.Position]', [td.Odor]', ... + [td.Performance]',[td.TranspositionDistance]', [td.PokeDuration]', [td.WithdrawLatency]']; + +end + +%% +function post = CalcStaticBayesPost(likely, obsv, binSize) +post = nan(size(obsv,1), size(likely,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(obsv,1) + p = nan(size(likely)); + curPopVect = obsv(t,:,trl)*(binSize/1000); + curPopFact = factorial(curPopVect); + for u = 1:size(likely,2) + curAvgUniFR = likely(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-((binSize/1000)*sum(likely,2))); + tempPost = pp.*ee; + post(t,:,trl) = tempPost./sum(tempPost); + end +end +end + +%% +function decode = DecodeBayesPost(post, id) +% Assumes post is in the structure of ObservTime X LikelyTime X Trial +decode = nan(size(post,1),size(post,3)); +for o = 1:size(post,3) + for d = 1:size(post,1) + if ~isnan(post(d,1,o)) + decode(d,o) = id(find(post(d,:,o)==max(post(d,:,o)),1,'first')); + end + end +end +end + +%% +function decode = TabulateBayesPost(post, id) +idS = unique(id); +decode = nan(size(post,1), size(post,3), length(idS)); +for trl = 1:size(post,3) + for t = 1:size(post,1) + for iD = 1:length(idS) + decode(t,trl,iD) = sum(post(t,id==idS(iD),trl)); + end + end +end +end \ No newline at end of file diff --git a/Analyses/PFC/PFCdualList_MLB.m b/Analyses/PFC/PFCdualList_MLB.m new file mode 100644 index 0000000..41597f0 --- /dev/null +++ b/Analyses/PFC/PFCdualList_MLB.m @@ -0,0 +1,446 @@ +%% PFCdualList_MLB +clc +clear all + +%% Runtime variables +piWindow = [-0.5 0.5]; +poWindow = [-0.5 0.5]; +binSize = 200; +dsRate = 5; +cLim = [0 0.01]; + +%% +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Extract Behavioral Periods +% trialInfo = [1:Trial#, 2:Sequence#, 3:Position, 4:Odor, 5:Performance, 6:tDist, 7:PokeDur, 8:WithdrawLat] +[piSpkMtx, piTrialTime, trialInfo] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, 'PokeIn', piWindow, binSize, dsRate); +[poSpkMtx, poTrialTime, ~] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, 'PokeOut', poWindow, binSize, dsRate); + +decodings.PItime = piTrialTime; +decodings.POtime = poTrialTime; + +clear ensembleMatrix ensembleMatrixColIDs behavMatrix behavMatrixColIDs + +%% Organize Data into Sequences & Identify Novel and Familiar Sequences +seqNums = unique(trialInfo(:,2)); +seqCells = cell(size(seqNums)); +seqTdist = zeros(size(seqNums)); +for obsSeq = 1:length(seqNums) + curSeq = trialInfo(trialInfo(:,2)==seqNums(obsSeq),:); + seqCells{obsSeq} = curSeq; + seqTdist(obsSeq) = sum(curSeq(:,6)); +end +seqLength = cellfun(@(a)size(a,1),seqCells); +listID = cellfun(@(a)a(1,4),seqCells); + +famFISs = seqCells(listID==1 & seqLength==4 & seqTdist==0)'; +novFISs = seqCells(listID==11 & seqLength==4 & seqTdist==0)'; + +famFIStrls = cell2mat(cellfun(@(a)a(:,1), famFISs, 'uniformoutput', 0)); +novFIStrls = cell2mat(cellfun(@(a)a(:,1), novFISs, 'uniformoutput', 0)); + +if ~isempty(intersect(famFIStrls, novFIStrls)) + error('Non-unique Familiar and Novel sequences, check code and files!'); +end + +isSeqs = [famFIStrls, novFIStrls]; +issIDlog = [false(1,size(famFIStrls,2)), true(1,size(novFIStrls,2))]; +%% Run decoding using leave-one-out +issPosts = nan((size(piSpkMtx,1) + size(poSpkMtx,1))*4, (size(piSpkMtx,1) + size(poSpkMtx,1))*8,size([famFIStrls, novFIStrls],2)); +for s = 1:size(isSeqs,2) + tempISSs = isSeqs; + tempISSs(:,s) = []; + tempISSidLog = issIDlog; + tempISSidLog(s) = []; + + tempFAMfisLikes = cell(4,1); + tempNOVfisLikes = cell(4,1); + tempObsv = cell(4,1); + for p = 1:4 + tempFAMfisLikes{p} = [mean(piSpkMtx(:,:,tempISSs(p,~tempISSidLog)),3); mean(poSpkMtx(:,:,tempISSs(p,~tempISSidLog)),3)]; + tempNOVfisLikes{p} = [mean(piSpkMtx(:,:,tempISSs(p,tempISSidLog)),3); mean(poSpkMtx(:,:,tempISSs(p,tempISSidLog)),3)]; + tempObsv{p} = [piSpkMtx(:,:,isSeqs(p,s)); poSpkMtx(:,:,isSeqs(p,s))]; + end + + issPosts(:,:,s) = CalcStaticBayesPost(cell2mat([tempFAMfisLikes;tempNOVfisLikes]), cell2mat(tempObsv), binSize); +end + +%% Plot LOO Data +famISSposts = issPosts(:,:,~issIDlog); +novISSposts = issPosts(:,:,issIDlog); +figure; +famSP = subplot(6,8,[1:4,9:12,17:20,25:28]); +imagesc(nanmean(famISSposts,3)', cLim); set(gca, 'ydir', 'normal'); colormap jet +set(gca, 'xtick', [], 'ytick', []); +for op = 1:8 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'white', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2] + repmat(size(piSpkMtx,1) + size(poSpkMtx,1),1,2)*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line([size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1) size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, 'linestyle', '-', 'color', 'white', 'linewidth', 2); + line(get(gca, 'xlim'), [size(piSpkMtx,1)/2 size(piSpkMtx,1)/2] + repmat(size(piSpkMtx,1) + size(poSpkMtx,1),1,2)*(op-1), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line(get(gca, 'xlim'), [size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1) size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +end +line(get(gca,'xlim'), [size(piSpkMtx,1)+size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*4, 'linestyle', '--', 'color', 'k', 'linewidth', 2); + +novSP = subplot(6,8,[5:8,13:16,21:24,29:32]); +imagesc(nanmean(novISSposts,3)', cLim); set(gca, 'ydir', 'normal'); colormap jet +set(gca, 'xtick', [], 'ytick', []); +for op = 1:8 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'white', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2] + repmat(size(piSpkMtx,1) + size(poSpkMtx,1),1,2)*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line([size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1) size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, 'linestyle', '-', 'color', 'white', 'linewidth', 2); + line(get(gca, 'xlim'), [size(piSpkMtx,1)/2 size(piSpkMtx,1)/2] + repmat(size(piSpkMtx,1) + size(poSpkMtx,1),1,2)*(op-1), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + line(get(gca, 'xlim'), [size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1) size(poSpkMtx,1)/2 + size(piSpkMtx,1)*op + size(poSpkMtx,1)*(op-1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +end +line(get(gca,'xlim'), [size(piSpkMtx,1)+size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*4, 'linestyle', '--', 'color', 'k', 'linewidth', 2); + +%% Decode LOO data +trialTemplate = ones(1,size(piSpkMtx,1)+size(poSpkMtx,1)); +odorLog = [trialTemplate*1,... + trialTemplate*2,... + trialTemplate*3,... + trialTemplate*4,... + trialTemplate*11,... + trialTemplate*12,... + trialTemplate*13,... + trialTemplate*14]; +posLog = [trialTemplate*1,... + trialTemplate*2,... + trialTemplate*3,... + trialTemplate*4,... + trialTemplate*1,... + trialTemplate*2,... + trialTemplate*3,... + trialTemplate*4]; +seqLog = [repmat(trialTemplate*1,1,4),repmat(trialTemplate*2,1,4)]; +timeLog = repmat([piTrialTime', poTrialTime'+1+dsRate/1000], 1,8); + +% Decode Odor ************************************************************* +odorDecode = DecodeBayesPost(issPosts, odorLog); + +famOdorDecode = odorDecode(:,~issIDlog); +decodings.FamOdor = [mean(famOdorDecode==1,2), mean(famOdorDecode==2,2), mean(famOdorDecode==3,2), mean(famOdorDecode==4,2),... + mean(famOdorDecode==11,2), mean(famOdorDecode==12,2), mean(famOdorDecode==13,2), mean(famOdorDecode==14,2)]; +famOdrSP = subplot(6,8,33:36); +plot(1:size(odorDecode,1), smooth(decodings.FamOdor(:,1)-decodings.FamOdor(:,5)), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(1:size(odorDecode,1), smooth(decodings.FamOdor(:,2)-decodings.FamOdor(:,6)), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.FamOdor(:,3)-decodings.FamOdor(:,7)), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.FamOdor(:,4)-decodings.FamOdor(:,8)), 'color', [128/255 66/255 151/255], 'linewidth', 1); +legend('A-W', 'B-X', 'C-Y','D-Z', 'location', 'southoutside', 'orientation', 'horizontal'); +ylabel([{'List Difference'};{'(Fam-Nov)'}]); +axis tight +set(gca, 'ylim', [-1 1], 'xtick', []); +for op = 1:4 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +end + +novOdorDecode = odorDecode(:,issIDlog); +decodings.NovOdor = [mean(novOdorDecode==1,2), mean(novOdorDecode==2,2), mean(novOdorDecode==3,2), mean(novOdorDecode==4,2),... + mean(novOdorDecode==11,2), mean(novOdorDecode==12,2), mean(novOdorDecode==13,2), mean(novOdorDecode==14,2)]; +novOdrSP = subplot(6,8,37:40); +plot(1:size(odorDecode,1), smooth(decodings.NovOdor(:,1)-decodings.NovOdor(:,5)), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(1:size(odorDecode,1), smooth(decodings.NovOdor(:,2)-decodings.NovOdor(:,6)), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.NovOdor(:,3)-decodings.NovOdor(:,7)), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.NovOdor(:,4)-decodings.NovOdor(:,8)), 'color', [128/255 66/255 151/255], 'linewidth', 1); +legend('A-W', 'B-X', 'C-Y','D-Z', 'location', 'southoutside', 'orientation', 'horizontal'); +axis tight +set(gca, 'ylim', [-1 1], 'xtick', []); +for op = 1:4 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +end + +% Decode Position ********************************************************* +posDecode = DecodeBayesPost(issPosts, posLog); + +famPosDecode = posDecode(:,~issIDlog); +decodings.FamPos = [mean(famPosDecode==1,2), mean(famPosDecode==2,2), mean(famPosDecode==3,2), mean(famPosDecode==4,2)]; +famPosSP = subplot(6,8,41:44); +plot(1:size(odorDecode,1), smooth(decodings.FamPos(:,1)), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(1:size(odorDecode,1), smooth(decodings.FamPos(:,2)), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.FamPos(:,3)), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.FamPos(:,4)), 'color', [128/255 66/255 151/255], 'linewidth', 1); +legend('1', '2', '3','4', 'location', 'southoutside', 'orientation', 'horizontal'); +ylabel([{'Decoding'};{'(% Trials)'}]); +axis tight +set(gca, 'ylim', [0 1], 'xtick', []); +for op = 1:4 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +end + +novPosDecode = posDecode(:,issIDlog); +decodings.NovPos = [mean(novPosDecode==1,2), mean(novPosDecode==2,2), mean(novPosDecode==3,2), mean(novPosDecode==4,2)]; +novPosSP = subplot(6,8,45:48); +plot(1:size(odorDecode,1), smooth(decodings.NovPos(:,1)), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(1:size(odorDecode,1), smooth(decodings.NovPos(:,2)), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.NovPos(:,3)), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(1:size(odorDecode,1), smooth(decodings.NovPos(:,4)), 'color', [128/255 66/255 151/255], 'linewidth', 1); +legend('1', '2', '3','4', 'location', 'southoutside', 'orientation', 'horizontal'); +axis tight +set(gca, 'ylim', [0 1], 'xtick', []); +for op = 1:4 + line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*op, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); + line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)]+(size(piSpkMtx,1)+size(poSpkMtx,1))*(op-1), get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +end + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +figure; +subplot(1,2,1) +novDiff = decodings.NovOdor(:,1:4)-decodings.NovOdor(:,5:8); +ndCounts = histcounts(novDiff(:), -1:0.1:1); +famDiff = decodings.FamOdor(:,1:4)-decodings.FamOdor(:,5:8); +fdCounts = histcounts(famDiff(:), -1:0.1:1); +fB = bar(-0.95:0.1:0.95, fdCounts,1); +fB.FaceAlpha = 0.5; +hold on; +nB = bar(-0.95:0.1:0.95, ndCounts, 1, 'r'); +nB.FaceAlpha = 0.5; +legend('Seq1', 'Seq2'); +xlabel([{'Decoding Difference'}; {'Seq1-Seq2'}]); +subplot(1,2,2) +fB = plot(-0.95:0.1:0.95, cumsum(fdCounts)./sum(fdCounts)); +hold on; +nB = plot(-0.95:0.1:0.95, cumsum(ndCounts)./sum(ndCounts), 'color', 'r'); +xlabel([{'Decoding Difference'}; {'Seq1-Seq2'}]); +ylabel('Cumulative Proportion'); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +% Decode Time ************************************************************* +timeDecode = DecodeBayesPost(issPosts, timeLog); + +% Decode Sequence ********************************************************* +seqDecode = DecodeBayesPost(issPosts, seqLog); + +%% Examine Difference in Decoding Using pdfs: Nov X Fam +famFamPost = nanmean(issPosts(:,seqLog==1,~issIDlog),3); +famNovPost = nanmean(issPosts(:,seqLog==2,~issIDlog),3); +novFamPost = nanmean(issPosts(:,seqLog==1,issIDlog),3); +novNovPost = nanmean(issPosts(:,seqLog==2,issIDlog),3); + +figure; +subplot(3,4,2) +corrScatPlot(famFamPost(:), famNovPost(:), 'Fam-Fam', 'Fam-Nov', 'rmvZro'); +subplot(3,4,3) +corrScatPlot(famFamPost(:), novFamPost(:), 'Fam-Fam', 'Nov-Fam', 'rmvZro'); +subplot(3,4,4) +corrScatPlot(famFamPost(:), novNovPost(:), 'Fam-Fam', 'Nov-Nov', 'rmvZro'); +subplot(3,4,7) +corrScatPlot(famNovPost(:), novFamPost(:), 'Fam-Nov', 'Nov-Fam', 'rmvZro'); +subplot(3,4,8) +corrScatPlot(famNovPost(:), novNovPost(:), 'Fam-Nov', 'Nov-Nov', 'rmvZro'); +subplot(3,4,12) +corrScatPlot(novFamPost(:), novNovPost(:), 'Nov-Fam', 'Nov-Nov', 'rmvZro'); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +figure; +subplot(2,2,1) +famDiff = famFamPost - famNovPost; +imagesc(famDiff, [-0.01, 0.01]); set(gca, 'ydir', 'normal'); colormap jet +title([{'Familiar Template'};{'Decode Fam - Decode Nov'}]); +subplot(2,2,2) +novDiff = novFamPost - novNovPost; +imagesc(novDiff, [-0.01, 0.01]); set(gca, 'ydir', 'normal'); colormap jet +title([{'Novel Template'};{'Decode Fam - Decode Nov'}]); +subplot(2,2,3) +corrScatPlot(famDiff(:), novDiff(:), 'FamDiff', 'NovDiff', 'rmvZro'); +title('Difference Similarity'); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + + +%% Collapse Across Odor +odorCollapseDecode = zeros(4,8,2); +odors = unique(odorLog); +osbPosLog = [trialTemplate*1,... + trialTemplate*2,... + trialTemplate*3,... + trialTemplate*4]; +for obsSeq = 1:2 + curPosts = nanmean(issPosts(:,:,issIDlog==(obsSeq-1)),3); + for obsPos = 1:4 + curObsPosLog = osbPosLog==obsPos; + for decOdr = 1:length(odors) + curDecOdrLog = odorLog==odors(decOdr); + odorCollapseDecode(obsPos,decOdr,obsSeq) = mean(sum(curPosts(curObsPosLog,curDecOdrLog),2)); + end + end +end + +figure; +ffSP = subplot(3,3,1); +imagesc(odorCollapseDecode(:,1:4,1), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4, 'xticklabel', [{'A'}, {'B'}, {'C'}, {'D'}], 'yticklabel', [{'A'}, {'B'}, {'C'}, {'D'}]); +colormap(ffSP, 'jet'); +title('Fam Decode Fam'); +fnSP = subplot(3,3,2); +imagesc(odorCollapseDecode(:,5:8,1), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4, 'xticklabel', [{'A'}, {'B'}, {'C'}, {'D'}], 'yticklabel', [{'W'}, {'X'}, {'Y'}, {'X'}]); +colormap(fnSP, 'jet'); +title('Fam Decode Nov'); +fDiffSP = subplot(3,3,3); +famDecodeDiff = odorCollapseDecode(:,1:4,1) - odorCollapseDecode(:,5:8,1); +imagesc(famDecodeDiff, [-0.1 0.1]); +set(gca, 'xtick', 1:4, 'ytick', 1:4, 'xticklabel', [{'A-W'}, {'B-X'}, {'C-Y'}, {'D-Z'}], 'yticklabel', [{'W-A'}, {'X-B'}, {'Y-C'}, {'Z-D'}]); +colormap(fDiffSP, 'gray'); +title('Fam-Nov Difference') +nfSP = subplot(3,3,4); +imagesc(odorCollapseDecode(:,1:4,2), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4, 'xticklabel', [{'W'}, {'X'}, {'Y'}, {'X'}], 'yticklabel', [{'A'}, {'B'}, {'C'}, {'D'}]); +colormap(nfSP, 'jet'); +title('Nov Decode Fam'); +nnSP = subplot(3,3,5); +imagesc(odorCollapseDecode(:,5:8,2), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4, 'xticklabel', [{'W'}, {'X'}, {'Y'}, {'X'}], 'yticklabel', [{'W'}, {'X'}, {'Y'}, {'X'}]); +colormap(nnSP, 'jet'); +title('Nov Decode Nov'); +nDiffSP = subplot(3,3,6); +novDecodeDiff = odorCollapseDecode(:,1:4,2)-odorCollapseDecode(:,5:8,2); +imagesc(novDecodeDiff, [-0.1 0.1]); +set(gca, 'xtick', 1:4, 'ytick', 1:4, 'xticklabel', [{'W-A'}, {'X-B'}, {'Y-C'}, {'Z-D'}], 'yticklabel', [{'A-W'}, {'B-X'}, {'C-Y'}, {'D-Z'}]); +colormap(nDiffSP, 'gray'); + +subplot(3,3,7) +tempFD = famDecodeDiff(2:4,2:4); +tempND = novDecodeDiff(2:4,2:4); +corrScatPlot(tempFD(:), tempND(:), 'Familiar Difference', 'Novel Difference'); +title('Correlation Sans Pos1'); +subplot(3,3,8) +tempFD = famDecodeDiff(:); +tempND = novDecodeDiff(:); +corrScatPlot(tempFD(2:end), tempND(2:end), 'Familiar Difference', 'Novel Difference'); +title('Correlation Sans 1-1'); +subplot(3,3,9) +corrScatPlot(tempFD(:), tempND(:), 'Familiar Difference', 'Novel Difference'); +title('Correlation w/All'); + + +%% +%%*******************************************************%% +%%********************** Functions **********************%% +%%*******************************************************%% +function [binnedMtx, trialTime, trialInfo] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, alignment, window, binSize, dsRate) +% First check to make sure reward signal is present within the +% behaviorMatrix +if sum(strcmp(behavMatrixColIDs, 'RewardSignal'))==0 + warning('Reward signal missing from behavior matrix, update the behavior matrix. OR ignore this if reward signal wasn''t recorded as plx flag'); +end +% Organize behavior data and Extract Ensemble Spiking +% Taking 1/2 the binSize on either end to get rid of edge effects. +td = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [window(1)-(binSize/2/1000) window(2)+(binSize/2/1000)], alignment); +trialEnsemble = ExtractTrialData_SM(td, ensembleMatrix(:,2:end)); %#ok<*NODEF> +ensembleMtx = cell2mat(reshape(trialEnsemble, [1 1 length(trialEnsemble)])); +if strcmp(alignment, 'PokeIn') + trialTimes = behavMatrix(td(1).TrialLogVect,1) - behavMatrix(td(1).PokeInIndex,1); +else + trialTimes = behavMatrix(td(1).TrialLogVect,1) - behavMatrix(td(1).PokeOutIndex,1); +end + +%% Bin the spiking data +% First convolve the entire trialEnsembleMtx with a square to bin the +% spikes +binnedEnsembleMtx = nan(size(ensembleMtx)); +for t = 1:size(ensembleMtx,3) + for u = 1:size(ensembleMtx,2) + binnedEnsembleMtx(:,u,t) = conv(ensembleMtx(:,u,t), ones(1,binSize)./(binSize/1000), 'same'); % Spike Rate +% binnedEnsembleMtx(:,u,t) = conv(trialEnsembleMtx(:,u,t), ones(1,binSize), 'same'); % Spike Count + end +end +% Now remove the binSize/2 padding +unPaddedBinnedEnsembleMtx = binnedEnsembleMtx((binSize/2)+1:end-(binSize/2),:,:); +trialTimes = trialTimes((binSize/2)+1:end-(binSize/2)); +% Now downsample the binned matrix +dsVect = downsample(1:size(unPaddedBinnedEnsembleMtx,1), dsRate); +binnedMtx = unPaddedBinnedEnsembleMtx(dsVect,:,:); +trialTime = trialTimes(dsVect); + +trialInfo = [[td.TrialNum]', [td.SequenceNum]', [td.Position]', [td.Odor]', ... + [td.Performance]',[td.TranspositionDistance]', [td.PokeDuration]', [td.WithdrawLatency]']; + +end + +%% +function post = CalcStaticBayesPost(likely, obsv, binSize) +post = nan(size(obsv,1), size(likely,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(obsv,1) + p = nan(size(likely)); + curPopVect = obsv(t,:,trl)*(binSize/1000); + curPopFact = factorial(curPopVect); + for u = 1:size(likely,2) + curAvgUniFR = likely(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-((binSize/1000)*sum(likely,2))); + tempPost = pp.*ee; + post(t,:,trl) = tempPost./sum(tempPost); + end +end +end + +%% +function decode = DecodeBayesPost(post, id) +% Assumes post is in the structure of ObservTime X LikelyTime X Trial +decode = nan(size(post,1),size(post,3)); +for o = 1:size(post,3) + for d = 1:size(post,1) + if ~isnan(post(d,1,o)) + decode(d,o) = id(find(post(d,:,o)==max(post(d,:,o)),1,'first')); + end + end +end +end + +%% +function decode = TabulateBayesPost(post, id) +idS = unique(id); +decode = nan(size(post,1), size(post,3), length(idS)); +for trl = 1:size(post,3) + for t = 1:size(post,1) + for iD = 1:length(idS) + decode(t,trl,iD) = sum(post(t,id==idS(iD),trl)); + end + end +end +end \ No newline at end of file diff --git a/Analyses/PFC/SimpleBetaViewer_Prototype.m b/Analyses/PFC/SimpleBetaViewer_Prototype.m new file mode 100644 index 0000000..b76f17a --- /dev/null +++ b/Analyses/PFC/SimpleBetaViewer_Prototype.m @@ -0,0 +1,277 @@ +clc +clear all + +%% +piWindow = [-0.5 1.5]; +poWindow = [-1.5 1.5]; +%% +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +% nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +% load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; +% Organize Trial Data and Define Trial Logicals +tdPI = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, piWindow, 'PokeIn'); +tdPO = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, poWindow, 'PokeOut'); +tdRS = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, poWindow, 'RewardSignal'); +isLog = [tdPI.TranspositionDistance]==0; +perfLog = [tdPI.Performance]==1; +p1Log = [tdPI.Position]==1; +p2Log = [tdPI.Position]==2; +p3Log = [tdPI.Position]==3; +p4Log = [tdPI.Position]==4; +pokeDur = [tdPI.PokeDuration]; +wdLat = [tdPI.WithdrawLatency]; + +targDur = nanmean([tdPI.RewardSignalIndex]-[tdPI.PokeInIndex])/1000; +targVar = nanstd([tdPI.RewardSignalIndex]-[tdPI.PokeInIndex])/1000; + +% Define time period of the session based on first and last trial to remove +% sleep periods from the z-score calculation +ssnLog = false(size(behavMatrix,1),1); +ssnLog(tdPI(1).PokeInIndex-500:max([tdPI.PokeOutIndex])+500) = true; + +%% +wlCorrVals = cell(size(smFileList)); +tetIDs = cell(size(smFileList)); +for f = 1:length(smFileList) + % Load File + load([smPath '\' smFileList{f}]); + % Identify Beta, get envelope and z-score + betaCol = cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, '_Beta\>')); + tet = strsplit(statMatrixColIDs{betaCol}, '_'); + tetIDs(f) = tet(1); +% env = abs(hilbert(statMatrix(:,betaCol))); + env = abs(hilbert(statMatrix(:,betaCol))).^2; + zEnv = zeros(size(statMatrix,1),1); + zEnv(ssnLog) = zscore(env(ssnLog)); + + % InSeq v OutSeq Beta Power Overall + iscBetaPI = cell2mat(ExtractTrialData_SM(tdPI(isLog & perfLog), zEnv)); + oscBetaPI = cell2mat(ExtractTrialData_SM(tdPI(~isLog & perfLog), zEnv)); + iscBetaPO = cell2mat(ExtractTrialData_SM(tdPO(isLog & perfLog), zEnv)); + oscBetaPO = cell2mat(ExtractTrialData_SM(tdPO(~isLog & perfLog), zEnv)); +% figure; +% piSP = subplot(6,1,1:2); +% line(piWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(piWindow(1):1/1000:piWindow(2), mean(iscBetaPI,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPI,2)+std(iscBetaPI,1,2)/sqrt(size(iscBetaPI,2)-1); flipud(mean(iscBetaPI,2)-std(iscBetaPI,1,2)/sqrt(size(iscBetaPI,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(piWindow(1):1/1000:piWindow(2), mean(oscBetaPI,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPI,2)+std(oscBetaPI,1,2)/sqrt(size(oscBetaPI,2)-1); flipud(mean(oscBetaPI,2)-std(oscBetaPI,1,2)/sqrt(size(oscBetaPI,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% title('Poke In Aligned'); +% subplot(6,1,3) +% histogram(pokeDur(isLog & perfLog),piWindow(1):0.01:piWindow(2), 'normalization', 'count'); +% hold on; +% histogram(pokeDur(~isLog & perfLog),piWindow(1):0.01:piWindow(2), 'normalization', 'count'); +% axis tight +% set(gca, 'xlim', get(piSP, 'xlim')); +% poSP = subplot(6,1,4:5); +% line(poWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(poWindow(1):1/1000:poWindow(2), mean(iscBetaPO,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPO,2)+std(iscBetaPO,1,2)/sqrt(size(iscBetaPO,2)-1); flipud(mean(iscBetaPO,2)-std(iscBetaPO,1,2)/sqrt(size(iscBetaPO,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(poWindow(1):1/1000:poWindow(2), mean(oscBetaPO,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPO,2)+std(oscBetaPO,1,2)/sqrt(size(oscBetaPO,2)-1); flipud(mean(oscBetaPO,2)-std(oscBetaPO,1,2)/sqrt(size(oscBetaPO,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% title('Poke Out Aligned'); +% subplot(6,1,6) +% histogram(wdLat(isLog & perfLog)*-1, poWindow(1):0.01:poWindow(2)); +% hold on; +% histogram(pokeDur(~isLog & perfLog)*-1, poWindow(1):0.01:poWindow(2)); +% axis tight +% set(gca, 'xlim', get(poSP, 'xlim')); +% annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', smFileList{f},... +% 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +% drawnow; +% close gcf +% +% % InSeq & OutSeq Beta Broken down by Position +% figure; +% sp(1) = subplot(2,4,1); +% iscBetaPI1 = cell2mat(ExtractTrialData_SM(tdPI(isLog & perfLog & p1Log), zEnv)); +% line(piWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(piWindow(1):1/1000:piWindow(2), mean(iscBetaPI1,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPI1,2)+std(iscBetaPI1,1,2)/sqrt(size(iscBetaPI1,2)-1); flipud(mean(iscBetaPI1,2)-std(iscBetaPI1,1,2)/sqrt(size(iscBetaPI1,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% ylabel('Poke In Aligned'); +% title('Position 1'); +% sp(2) = subplot(2,4,2); +% iscBetaPI2 = cell2mat(ExtractTrialData_SM(tdPI(isLog & perfLog & p2Log), zEnv)); +% oscBetaPI2 = cell2mat(ExtractTrialData_SM(tdPI(~isLog & perfLog & p2Log), zEnv)); +% line(piWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(piWindow(1):1/1000:piWindow(2), mean(iscBetaPI2,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPI2,2)+std(iscBetaPI2,1,2)/sqrt(size(iscBetaPI2,2)-1); flipud(mean(iscBetaPI2,2)-std(iscBetaPI2,1,2)/sqrt(size(iscBetaPI2,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(piWindow(1):1/1000:piWindow(2), mean(oscBetaPI2,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPI2,2)+std(oscBetaPI2,1,2)/sqrt(size(oscBetaPI2,2)-1); flipud(mean(oscBetaPI2,2)-std(oscBetaPI2,1,2)/sqrt(size(oscBetaPI2,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% title('Position 2'); +% sp(3) = subplot(2,4,3); +% iscBetaPI3 = cell2mat(ExtractTrialData_SM(tdPI(isLog & perfLog & p3Log), zEnv)); +% oscBetaPI3 = cell2mat(ExtractTrialData_SM(tdPI(~isLog & perfLog & p3Log), zEnv)); +% line(piWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(piWindow(1):1/1000:piWindow(2), mean(iscBetaPI3,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPI3,2)+std(iscBetaPI3,1,2)/sqrt(size(iscBetaPI3,2)-1); flipud(mean(iscBetaPI3,2)-std(iscBetaPI3,1,2)/sqrt(size(iscBetaPI3,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(piWindow(1):1/1000:piWindow(2), mean(oscBetaPI3,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPI3,2)+std(oscBetaPI3,1,2)/sqrt(size(oscBetaPI3,2)-1); flipud(mean(oscBetaPI3,2)-std(oscBetaPI3,1,2)/sqrt(size(oscBetaPI3,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% title('Position 3'); +% sp(4) = subplot(2,4,4); +% iscBetaPI4 = cell2mat(ExtractTrialData_SM(tdPI(isLog & perfLog & p4Log), zEnv)); +% oscBetaPI4 = cell2mat(ExtractTrialData_SM(tdPI(~isLog & perfLog & p4Log), zEnv)); +% line(piWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(piWindow(1):1/1000:piWindow(2), mean(iscBetaPI4,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPI4,2)+std(iscBetaPI4,1,2)/sqrt(size(iscBetaPI4,2)-1); flipud(mean(iscBetaPI4,2)-std(iscBetaPI4,1,2)/sqrt(size(iscBetaPI4,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(piWindow(1):1/1000:piWindow(2), mean(oscBetaPI4,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPI4,2)+std(oscBetaPI4,1,2)/sqrt(size(oscBetaPI4,2)-1); flipud(mean(oscBetaPI4,2)-std(oscBetaPI4,1,2)/sqrt(size(oscBetaPI4,2)-1))],... +% 'XData', [piWindow(1):1/1000:piWindow(2), piWindow(2):-1/1000:piWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% title('Position 4'); +% sp(5) = subplot(2,4,5); +% iscBetaPO1 = cell2mat(ExtractTrialData_SM(tdPO(isLog & perfLog & p1Log), zEnv)); +% line(poWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(poWindow(1):1/1000:poWindow(2), mean(iscBetaPO1,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPO1,2)+std(iscBetaPO1,1,2)/sqrt(size(iscBetaPO1,2)-1); flipud(mean(iscBetaPO1,2)-std(iscBetaPO1,1,2)/sqrt(size(iscBetaPO1,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% ylabel('Poke Out Aligned'); +% sp(6) = subplot(2,4,6); +% iscBetaPO2 = cell2mat(ExtractTrialData_SM(tdPO(isLog & perfLog & p2Log), zEnv)); +% oscBetaPO2 = cell2mat(ExtractTrialData_SM(tdPO(~isLog & perfLog & p2Log), zEnv)); +% line(poWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(poWindow(1):1/1000:poWindow(2), mean(iscBetaPO2,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPO2,2)+std(iscBetaPO2,1,2)/sqrt(size(iscBetaPO2,2)-1); flipud(mean(iscBetaPO2,2)-std(iscBetaPO2,1,2)/sqrt(size(iscBetaPO2,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(poWindow(1):1/1000:poWindow(2), mean(oscBetaPO2,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPO2,2)+std(oscBetaPO2,1,2)/sqrt(size(oscBetaPO2,2)-1); flipud(mean(oscBetaPO2,2)-std(oscBetaPO2,1,2)/sqrt(size(oscBetaPO2,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% sp(7) = subplot(2,4,7); +% iscBetaPO3 = cell2mat(ExtractTrialData_SM(tdPO(isLog & perfLog & p3Log), zEnv)); +% oscBetaPO3 = cell2mat(ExtractTrialData_SM(tdPO(~isLog & perfLog & p3Log), zEnv)); +% line(poWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(poWindow(1):1/1000:poWindow(2), mean(iscBetaPO3,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPO3,2)+std(iscBetaPO3,1,2)/sqrt(size(iscBetaPO3,2)-1); flipud(mean(iscBetaPO3,2)-std(iscBetaPO3,1,2)/sqrt(size(iscBetaPO3,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(poWindow(1):1/1000:poWindow(2), mean(oscBetaPO3,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPO3,2)+std(oscBetaPO3,1,2)/sqrt(size(oscBetaPO3,2)-1); flipud(mean(oscBetaPO3,2)-std(oscBetaPO3,1,2)/sqrt(size(oscBetaPO3,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% sp(8) = subplot(2,4,8); +% iscBetaPO4 = cell2mat(ExtractTrialData_SM(tdPO(isLog & perfLog & p4Log), zEnv)); +% oscBetaPO4 = cell2mat(ExtractTrialData_SM(tdPO(~isLog & perfLog & p4Log), zEnv)); +% line(poWindow, [0 0], 'linestyle', ':', 'color', 'k'); +% hold on; +% plot(poWindow(1):1/1000:poWindow(2), mean(iscBetaPO4,2), 'color', 'blue'); +% patch('YData', [mean(iscBetaPO4,2)+std(iscBetaPO4,1,2)/sqrt(size(iscBetaPO4,2)-1); flipud(mean(iscBetaPO4,2)-std(iscBetaPO4,1,2)/sqrt(size(iscBetaPO4,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); +% plot(poWindow(1):1/1000:poWindow(2), mean(oscBetaPO4,2), 'color', 'red'); +% patch('YData', [mean(oscBetaPO4,2)+std(oscBetaPO4,1,2)/sqrt(size(oscBetaPO4,2)-1); flipud(mean(oscBetaPO4,2)-std(oscBetaPO4,1,2)/sqrt(size(oscBetaPO4,2)-1))],... +% 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... +% 'FaceColor', 'red', 'FaceAlpha', .3, 'EdgeColor', 'red', 'EdgeAlpha', 0.5); +% linkaxes(sp(1:4), 'x'); +% linkaxes(sp(5:8), 'x'); +% set(sp(1), 'xlim', piWindow); +% set(sp(8), 'xlim', poWindow); +% linkaxes(sp, 'y'); +% annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', smFileList{f},... +% 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +% drawnow; + + % Examine Relationship between Withdrawal Latency and Beta Power + iscBetaRS = cell2mat(ExtractTrialData_SM(tdRS(isLog & perfLog & ~p1Log), zEnv)); +% iscBetaRS = cell2mat(ExtractTrialData_SM(tdPO(isLog & perfLog), zEnv)); + pdTrls = pokeDur(isLog & perfLog & ~p1Log); + wlTrls = wdLat(isLog & perfLog & ~p1Log); + figure; + + % Plot Hold Durations + subplot(2,4,[1,5]); + scatter(ones(1,length(pdTrls))+normrnd(0,0.1, [1,length(pdTrls)]), pdTrls, 'marker', '*', 'markeredgecolor', 'k'); + hold on; + line(get(gca, 'xlim'), [targDur targDur], 'color', 'k', 'linewidth', 2); + line(get(gca, 'xlim'), [targDur+targVar targDur+targVar], 'color', 'k', 'linestyle', ':'); + line(get(gca, 'xlim'), [targDur-targVar targDur-targVar], 'color', 'k', 'linestyle', ':'); + set(gca, 'ylim', [0 max(pdTrls)+0.2]); + title ('Poke Dur'); + + % Plot Reaction Times + subplot(2,4,[2,6]); + scatter(ones(1,length(wlTrls))+normrnd(0,0.1, [1,length(wlTrls)]), wlTrls, 'marker', '*', 'markeredgecolor', 'k'); + hold on; + line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linewidth', 2); + title('WD Lat'); + + % Plot Beta Power relative to Reward Signal + subplot(2,4,3:4) + line(poWindow, [0 0], 'linestyle', ':', 'color', 'k'); + hold on; + plot(poWindow(1):1/1000:poWindow(2), mean(iscBetaRS,2), 'color', 'blue'); + patch('YData', [mean(iscBetaRS,2)+std(iscBetaRS,1,2)/sqrt(size(iscBetaRS,2)-1); flipud(mean(iscBetaRS,2)-std(iscBetaRS,1,2)/sqrt(size(iscBetaRS,2)-1))],... + 'XData', [poWindow(1):1/1000:poWindow(2), poWindow(2):-1/1000:poWindow(1)],... + 'FaceColor', 'blue', 'FaceAlpha', .3, 'EdgeColor', 'blue', 'EdgeAlpha', 0.5); + + % Plot Correlation between Beta Power and behavior (overall Poke Duration and Reward Latency) over time + pdCorr = nan(size(iscBetaRS,1),1); + wlCorr = nan(size(iscBetaRS,1),1); + for t = 1:size(iscBetaRS,1) +% pdCorr(t) = corr(iscBetaRS(t,:)', pdTrls'); + pdCorr(t) = corr(iscBetaRS(t,:)', pdTrls', 'Type', 'Spearman'); +% wlCorr(t) = corr(iscBetaRS(t,:)', wlTrls'); + wlCorr(t) = corr(iscBetaRS(t,:)', wlTrls', 'Type', 'Spearman'); + end + wlCorrVals{f} = wlCorr; + subplot(2,4,7:8); + plot(poWindow(1):1/1000:poWindow(2), pdCorr, 'color', 'k'); + hold on; + plot(poWindow(1):1/1000:poWindow(2), wlCorr, 'color', 'k', 'linestyle', '-.'); + legend('Poke Duration', 'Withdrawal Latency', 'location', 'southoutside'); + line(poWindow, [0 0], 'color', 'k', 'linestyle', ':'); + annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', smFileList{f},... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + drawnow; + + figure; imagesc(piWindow(1):1/1000:piWindow(2), 1:size(iscBetaPI,2),iscBetaPI', [-2 5]); colormap jet; + annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', smFileList{f},... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +end + +pkMtx = [([tdPI.PokeInIndex])', ([tdPI.PokeOutIndex])']; +figure; sp1 = subplot(3,1,1); plot(statMatrix(:,2)); sp2 = subplot(3,1,2); plot(statMatrix(:,betaCol)); sp3 = subplot(3,1,3); plot(zEnv); linkaxes([sp1 sp2 sp3], 'x'); hold on; plot(pkMtx', (ones(size(pkMtx))')*5, 'marker', '*', 'color', 'k'); + +%% +wlCorrVals = cell2mat(wlCorrVals'); +tetIDs = tetIDs'; +save('BetaWithdrawLatCorrSQR.mat', 'wlCorrVals', 'tetIDs'); \ No newline at end of file diff --git a/Analyses/PFC/slPFC_MLB.m b/Analyses/PFC/slPFC_MLB.m new file mode 100644 index 0000000..eaeb508 --- /dev/null +++ b/Analyses/PFC/slPFC_MLB.m @@ -0,0 +1,345 @@ +%% +clc +clear all + +%% Runtime variables +piWindow = [-0.5 0.5]; +poWindow = [-0.5 0.5]; +binSize = 200; +dsRate = 5; +cLims = [0 0.005]; + +%% +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Extract Behavioral Periods +% trialInfo = [Trial#, Sequence#, Position, Odor, Performance, tDist, PokeDur, WithdrawLat] +[piSpkMtx, piTrialTime, trialInfo] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, 'PokeIn', piWindow, binSize, dsRate); +[poSpkMtx, poTrialTime, ~] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, 'PokeOut', poWindow, binSize, dsRate); + +clear ensembleMatrix ensembleMatrixColIDs behavMatrix behavMatrixColIDs +%% Identify Fully InSeq Trials & Calculate FIS Liklihoods (PSTH) +fullInSeqSeqsStart = find(conv(trialInfo(:,4), 1:4, 'valid')==20 & conv(trialInfo(:,3), 1:4, 'valid')==20 & conv(trialInfo(:,5), ones(1,4), 'valid')==4); +inSeqSeqs = nan(3,length(fullInSeqSeqsStart)); +for iS = 1:length(fullInSeqSeqsStart) + inSeqSeqs(1,iS) = fullInSeqSeqsStart(iS); + inSeqSeqs(2,iS) = fullInSeqSeqsStart(iS) + 1; + inSeqSeqs(3,iS) = fullInSeqSeqsStart(iS) + 2; + inSeqSeqs(4,iS) = fullInSeqSeqsStart(iS) + 3; +end + +piFISlikes = repmat({nan(size(piSpkMtx,1), size(piSpkMtx,2))}, 4,1); +poFISlikes = repmat({nan(size(poSpkMtx,1), size(poSpkMtx,2))}, 4,1); +for p = 1:4 + piFISlikes{p} = mean(piSpkMtx(:,:,inSeqSeqs(p,:)),3); + poFISlikes{p} = mean(poSpkMtx(:,:,inSeqSeqs(p,:)),3); +end + +% Plot Likelihoods +figure; +figLims = [0 max(max([cell2mat(piFISlikes); cell2mat(poFISlikes)]))]; +subplot(4,2,1); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{1}', figLims); title(gca, 'Poke In'); ylabel('Odor A'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,2); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{1}', figLims); title(gca, 'Poke Out'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,3); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{2}', figLims); ylabel('Odor B'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,4); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{2}', figLims); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,5); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{3}', figLims); ylabel('Odor C'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,6); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{3}', figLims); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,7); imagesc(piTrialTime, 1:size(piFISlikes{1},2), piFISlikes{4}', figLims); ylabel('Odor D'); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); +subplot(4,2,8); imagesc(poTrialTime, 1:size(poFISlikes{1},2), poFISlikes{4}', figLims); hold on; line([0 0], get(gca, 'ylim'), 'color', 'w'); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +%% Decode via Leave 1 out +issPosts = nan((size(piSpkMtx,1) + size(poSpkMtx,1))*4, (size(piSpkMtx,1) + size(poSpkMtx,1))*4,size(inSeqSeqs,2)); +for s = 1:size(inSeqSeqs,2) + tempISSs = inSeqSeqs; + tempISSs(:,s) = []; + + tempFISlikes = repmat({nan(size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,2) + size(poSpkMtx,2))}, 4,1); + tempObsv = tempFISlikes; + for p = 1:4 + tempFISlikes{p} = [mean(piSpkMtx(:,:,tempISSs(p,:)),3); mean(poSpkMtx(:,:,tempISSs(p,:)),3)]; + tempObsv{p} = [piSpkMtx(:,:,inSeqSeqs(p,s)); poSpkMtx(:,:,inSeqSeqs(p,s))]; + end + + issPosts(:,:,s) = CalcStaticBayesPost(cell2mat(tempFISlikes), cell2mat(tempObsv), binSize); +end +odorLog = [ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*1,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*2,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*3,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*4]; +timeLog = [piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000]; + +figure; +subplot(6,4,1:16); +% imagesc(nanmedian(issPosts,3), [0 0.01]); set(gca, 'ydir', 'normal'); colormap jet +imagesc(nanmean(issPosts,3), [0 0.01]); set(gca, 'ydir', 'normal'); colormap jet +set(gca, 'xtick', [], 'ytick', []); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)], 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*2, get(gca, 'ylim'), 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1) size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*2, 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1) size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*3, get(gca, 'ylim'), 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2 size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2 size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*3, 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2 size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2 size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2], 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*4, get(gca, 'ylim'), 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3 size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3 size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*4, 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3 size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3 size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3], 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +% Odor Decoding +decodeOdor = DecodeBayesPost(issPosts, odorLog); +subplot(6,4,17:20) +plot(1:size(decodeOdor,1), mean(decodeOdor==1,2), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(1:size(decodeOdor,1), mean(decodeOdor==2,2), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(1:size(decodeOdor,1), mean(decodeOdor==3,2), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(1:size(decodeOdor,1), mean(decodeOdor==4,2), 'color', [128/255 66/255 151/255], 'linewidth', 1); +legend('A', 'B', 'C','D', 'location', 'southoutside', 'orientation', 'horizontal'); +axis tight +set(gca, 'ylim', [0 1], 'xtick', []); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*2, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*3, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*4, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1) size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2 size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2 size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3 size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3 size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +ylabel([{'Decoding'};{'(% Trials)'}]); + +% Temporal Decoding +decodeTime = DecodeBayesPost(issPosts, timeLog); +decodeLag = nan(size(decodeTime)); +for c = 1:size(decodeTime,2) + decodeLag(:,c) = decodeTime(:,c)-timeLog'; +end +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,1,2); +subplot(6,4,21:24) +plot(lagMean, '-k', 'linewidth', 1); +patch('YData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'XData', [1:length(lagMean), length(lagMean):-1:1], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight +line([0 length(lagMean)], [0 0], 'linestyle', '--', 'color', 'k', 'linewidth', 1); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*2, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*3, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)]*4, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1) size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2 size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2 size(poSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3 size(piSpkMtx,1)/2+size(piSpkMtx,1)*3+size(poSpkMtx,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3 size(poSpkMtx,1)/2+size(piSpkMtx,1)*4+size(poSpkMtx,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +set(gca, 'xtick', []); +ylabel(gca,'Lag (s)'); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +%% Investigate decoding more.... possibly do rank order quantification for each index... tabulate at each index which odor is 1st, 2nd, 3rd, 4th +% Possibly the indexing will demonstrate a lag effect, i.e. 1st = current odor, 2nd = next odor. +% Alternatively, examine decoding of peaks? +% Alternatively (and I like this one the most), calculate total posterior for different odors, i.e. calculate sum or average posterior value for each odor at each index + +%% Step through and decode each OutSeq Trial +outSeqTrials = find(trialInfo(:,6)~=0 & trialInfo(:,5)==1 & trialInfo(:,3)<=4 & trialInfo(:,4)<=4); + +osPosts = nan(size(piSpkMtx,1)+size(poSpkMtx,1),(size(piSpkMtx,1)+size(poSpkMtx,1))*2,length(outSeqTrials)); +for osT = 1:length(outSeqTrials) + tempObsv = [piSpkMtx(:,:,outSeqTrials(osT)); poSpkMtx(:,:,outSeqTrials(osT))]; + osPos = trialInfo(outSeqTrials(osT),3); + osOdr = trialInfo(outSeqTrials(osT),4); + + tempPosLikes = [mean(piSpkMtx(:,:,tempISSs(osPos,:)),3); mean(poSpkMtx(:,:,tempISSs(osPos,:)),3)]; + tempOdrLikes = [mean(piSpkMtx(:,:,tempISSs(osOdr,:)),3); mean(poSpkMtx(:,:,tempISSs(osOdr,:)),3)]; + tempLikes = [tempPosLikes; tempOdrLikes]; + + osPosts(:,:,osT) = CalcStaticBayesPost(tempLikes, tempObsv, binSize); +end +odorLog = [ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*1,... + ones(1,size(piSpkMtx,1)+size(poSpkMtx,1))*2]; +timeLog = [piTrialTime', poTrialTime'+1+dsRate/1000,... + piTrialTime', poTrialTime'+1+dsRate/1000]; + +figure; +subplot(6,4,1:16) +% imagesc(nanmedian(osPosts,3), [0 0.01]); set(gca, 'ydir', 'normal'); colormap jet +imagesc(nanmean(osPosts,3)', [0 0.01]); set(gca, 'ydir', 'normal'); colormap jet +xlabel('Observed'); +ylabel('Decodeded'); +set(gca,... + 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}],... + 'ytick', [size(piSpkMtx,1)/2 size(piSpkMtx,1) size(piSpkMtx,1)+size(poSpkMtx,1)/2 size(piSpkMtx,1)/2+size(piSpkMtx,1)+size(poSpkMtx,1) size(piSpkMtx,1)*2+size(poSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)],... + 'yticklabel', [{'PokeIn'}, {'\bf\fontsize{14}Position'}, {'PokeOut'}, {'PokeIn'}, {'\bf\fontsize{14}Odor'}, {'PokeOut'}]); +line(get(gca, 'xlim'), [size(piSpkMtx,1) + size(poSpkMtx,1), size(piSpkMtx,1) + size(poSpkMtx,1)], 'linestyle', '-', 'color', 'white', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2+size(piSpkMtx,1)*2 size(piSpkMtx,1)/2+size(piSpkMtx,1)*2], 'linestyle', ':', 'color', 'white', 'linewidth', 1); +line(get(gca, 'xlim'), [size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1) size(piSpkMtx,1)/2+size(piSpkMtx,1)*2+size(poSpkMtx,1)], 'linestyle', ':', 'color', 'white', 'linewidth', 1); + +% Odor Decoding +decodeOdor = DecodeBayesPost(osPosts, odorLog); +posDecode = mean(decodeOdor==1,2); +odrDecode = mean(decodeOdor==2,2); +subplot(6,4,17:20) +plot(1:size(decodeOdor,1), posDecode-odrDecode, 'color', 'k', 'linewidth', 1); +axis tight +set(gca, 'ylim', [-1 1], 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +ylabel([{'Decoded Difference'};{'(Pos-Odor)'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(piSpkMtx,1) size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + +% Temporal Decoding +decodeTime = DecodeBayesPost(osPosts, timeLog); +decodeLag = nan(size(decodeTime)); +for c = 1:size(decodeTime,2) + decodeLag(:,c) = decodeTime(:,c)-[piTrialTime', poTrialTime'+1+dsRate/1000]'; +end +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,1,2); +subplot(6,4,21:24) +plot(lagMean, '-k', 'linewidth', 1); +patch('YData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'XData', [1:length(lagMean), length(lagMean):-1:1], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight +set(gca, 'xtick', [size(piSpkMtx,1)/2, size(poSpkMtx,1)/2+size(piSpkMtx,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(piSpkMtx,1) size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(piSpkMtx,1)/2 size(piSpkMtx,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(poSpkMtx,1)/2+size(piSpkMtx,1) size(poSpkMtx,1)/2+size(piSpkMtx,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + +annotation('textbox', 'position', [0 0.935 1 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms; PokeInWindow = [%ims +%ims], PokeOutWindow = [%ims +%ims]', binSize, dsRate, piWindow(1)*1000,piWindow(2)*1000,poWindow(1)*1000, poWindow(2)*1000)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +%% Trial After OutSeq +% For TAO, use FIS as likelihoods and TAO as observations +% How to compare TAO with FIS decoding... Compare both posteriors as well +% as the likelihood of decoding the correct odor. +%% +%%*******************************************************%% +%%********************** Functions **********************%% +%%*******************************************************%% +function [binnedMtx, trialTime, trialInfo] = OrganizeAndBinSpikes(ensembleMatrix, behavMatrix, behavMatrixColIDs, alignment, window, binSize, dsRate) +% First check to make sure reward signal is present within the +% behaviorMatrix +if sum(strcmp(behavMatrixColIDs, 'RewardSignal'))==0 + warning('Reward signal missing from behavior matrix, update the behavior matrix. OR ignore this if reward signal wasn''t recorded as plx flag'); +end +% Organize behavior data and Extract Ensemble Spiking +% Taking 1/2 the binSize on either end to get rid of edge effects. +td = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [window(1)-(binSize/2/1000) window(2)+(binSize/2/1000)], alignment); +trialEnsemble = ExtractTrialData_SM(td, ensembleMatrix(:,2:end)); %#ok<*NODEF> +ensembleMtx = cell2mat(reshape(trialEnsemble, [1 1 length(trialEnsemble)])); +if strcmp(alignment, 'PokeIn') + trialTimes = behavMatrix(td(1).TrialLogVect,1) - behavMatrix(td(1).PokeInIndex,1); +else + trialTimes = behavMatrix(td(1).TrialLogVect,1) - behavMatrix(td(1).PokeOutIndex,1); +end + +%% Bin the spiking data +% First convolve the entire trialEnsembleMtx with a square to bin the +% spikes +binnedEnsembleMtx = nan(size(ensembleMtx)); +for t = 1:size(ensembleMtx,3) + for u = 1:size(ensembleMtx,2) + binnedEnsembleMtx(:,u,t) = conv(ensembleMtx(:,u,t), ones(1,binSize)./(binSize/1000), 'same'); +% binnedEnsembleMtx(:,u,t) = conv(trialEnsembleMtx(:,u,t), ones(1,binSize), 'same'); + end +end +% Now remove the binSize/2 padding +unPaddedBinnedEnsembleMtx = binnedEnsembleMtx((binSize/2)+1:end-(binSize/2),:,:); +trialTimes = trialTimes((binSize/2)+1:end-(binSize/2)); +% Now downsample the binned matrix +dsVect = downsample(1:size(unPaddedBinnedEnsembleMtx,1), dsRate); +binnedMtx = unPaddedBinnedEnsembleMtx(dsVect,:,:); +trialTime = trialTimes(dsVect); + +trialInfo = [[td.TrialNum]', [td.SequenceNum]', [td.Position]', [td.Odor]', ... + [td.Performance]',[td.TranspositionDistance]', [td.PokeDuration]', [td.WithdrawLatency]']; + +end + +%% +function post = CalcStaticBayesPost(likely, obsv, binSize) +post = nan(size(obsv,1), size(likely,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(obsv,1) + p = nan(size(likely)); + curPopVect = obsv(t,:,trl)*(binSize/1000); + curPopFact = factorial(curPopVect); + for u = 1:size(likely,2) + curAvgUniFR = likely(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-((binSize/1000)*sum(likely,2))); + tempPost = pp.*ee; + post(t,:,trl) = tempPost./sum(tempPost); + end +end +end + +%% +function decode = DecodeBayesPost(post, id) +% Assumes post is in the structure of ObservTime X LikelyTime X Trial +decode = nan(size(post,1),size(post,3)); +for o = 1:size(post,3) + for d = 1:size(post,1) + if ~isnan(post(d,1,o)) + decode(d,o) = id(find(post(d,:,o)==max(post(d,:,o)),1,'first')); + end + end +end +end \ No newline at end of file diff --git a/Analyses/PFC/slPFC_MLB_GroupPlot.m b/Analyses/PFC/slPFC_MLB_GroupPlot.m new file mode 100644 index 0000000..2e79705 --- /dev/null +++ b/Analyses/PFC/slPFC_MLB_GroupPlot.m @@ -0,0 +1,186 @@ +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Identify list of all statMatrix files +decodingFiles = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, 'Decodings')))'; + +%% +decodes = cell(1,length(decodingFiles),4); +osDiffs = cell(1,length(decodingFiles)); +skpDiffs = cell(1,length(decodingFiles)); +repDiffs = cell(1,length(decodingFiles)); +trlPrdDecodes = cell(1,length(decodingFiles)); +ssnSMI = nan(1,length(decodingFiles)); +ssnSMIsfp = nan(1,length(decodingFiles)); +trlPrdDprms = nan(4,length(decodingFiles)); +for f = 1:length(decodingFiles) + load(decodingFiles{f}); + decodes{1,f,1} = decodings.Odor(:,1); + decodes{1,f,2} = decodings.Odor(:,2); + decodes{1,f,3} = decodings.Odor(:,3); + decodes{1,f,4} = decodings.Odor(:,4); + osDiffs{f} = decodings.OSdiff; + skpDiffs{f} = decodings.OSdiffSKP; + repDiffs{f} = decodings.OSdiffREP; + trlPrdDecodes{f} = decodings.TrialPeriods; + ssnSMI(f) = decodings.SMIbehav; + ssnSMIsfp(f) = decodings.SMIbehavSFP; + trlPrdDprms(:,f) = decodings.TrialPeriodsDprm; +end +decodes = cell2mat(decodes); +osDiffs = cell2mat(osDiffs); +skpDiffs = cell2mat(skpDiffs); +repDiffs = cell2mat(repDiffs); + +%% +figure; +plot(1:size(decodes,1), smooth(nanmean(decodes(:,:,1),2)), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(1:size(decodes,1), smooth(nanmean(decodes(:,:,2),2)), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(1:size(decodes,1), smooth(nanmean(decodes(:,:,3),2)), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(1:size(decodes,1), smooth(nanmean(decodes(:,:,4),2)), 'color', [128/255 66/255 151/255], 'linewidth', 1); +legend('1', '2', '3','4', 'location', 'southoutside', 'orientation', 'horizontal'); +for o = 1:4 + tempPostMean = smooth(nanmean(decodes(:,:,o),2)); +% tempPostVar = nanstd(decodes(:,:,o),1,2); + tempPostVar = smooth(SEMcalc(decodes(:,:,o)')'); + tp = patch('YData', [tempPostMean+tempPostVar; flipud(tempPostMean-tempPostVar)],... + 'XData', [1:length(tempPostMean), length(tempPostMean):-1:1], 'FaceAlpha', .3); + if o==1 + set(tp, 'FaceColor', [44/255 168/255 224/255], 'edgecolor', [44/255 168/255 224/255], 'EdgeAlpha', .5); + elseif o==2 + set(tp, 'FaceColor', [154/255 133/255 122/255], 'edgecolor', [154/255 133/255 122/255], 'EdgeAlpha', .5); + elseif o==3 + set(tp, 'FaceColor', [9/255 161/255 74/255], 'edgecolor', [9/255 161/255 74/255], 'EdgeAlpha', .5); + else + set(tp, 'FaceColor', [128/255 66/255 151/255], 'edgecolor', [128/255 66/255 151/255], 'EdgeAlpha', .5); + end +end + +axis tight +set(gca, 'ylim', [0 1], 'xtick', []); +line([size(decodings.PItime,1) + size(decodings.POtime,1), size(decodings.PItime,1) + size(decodings.POtime,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1) + size(decodings.POtime,1), size(decodings.PItime,1) + size(decodings.POtime,1)]*2, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1) + size(decodings.POtime,1), size(decodings.PItime,1) + size(decodings.POtime,1)]*3, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1) + size(decodings.POtime,1), size(decodings.PItime,1) + size(decodings.POtime,1)]*4, get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1)/2 size(decodings.PItime,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.POtime,1)/2+size(decodings.PItime,1) size(decodings.POtime,1)/2+size(decodings.PItime,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1)/2+size(decodings.PItime,1)+size(decodings.POtime,1) size(decodings.PItime,1)/2+size(decodings.PItime,1)+size(decodings.POtime,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.POtime,1)/2+size(decodings.PItime,1)*2+size(decodings.POtime,1) size(decodings.POtime,1)/2+size(decodings.PItime,1)*2+size(decodings.POtime,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1)/2+size(decodings.PItime,1)*2+size(decodings.POtime,1)*2 size(decodings.PItime,1)/2+size(decodings.PItime,1)*2+size(decodings.POtime,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.POtime,1)/2+size(decodings.PItime,1)*3+size(decodings.POtime,1)*2 size(decodings.POtime,1)/2+size(decodings.PItime,1)*3+size(decodings.POtime,1)*2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1)/2+size(decodings.PItime,1)*3+size(decodings.POtime,1)*3 size(decodings.PItime,1)/2+size(decodings.PItime,1)*3+size(decodings.POtime,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.POtime,1)/2+size(decodings.PItime,1)*4+size(decodings.POtime,1)*3 size(decodings.POtime,1)/2+size(decodings.PItime,1)*4+size(decodings.POtime,1)*3], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +ylabel([{'Decoded Position'};{'% Trials'}]); +xlabel('Sequence Time'); +title(sprintf('GE11 Decodings (All InSeq, Leave-1-Out; Mean +/- SEM; %ixSessions)', length(decodingFiles))); + +%% +odorLog = [ones(1,size(decodings.PItime,1)+size(decodings.POtime,1))*1,... + ones(1,size(decodings.PItime,1)+size(decodings.POtime,1))*2,... + ones(1,size(decodings.PItime,1)+size(decodings.POtime,1))*3,... + ones(1,size(decodings.PItime,1)+size(decodings.POtime,1))*4]; + +figure; +sps = nan(1,4); +for p = 1:4 + decLog = odorLog==p; + sps(p) = subplot(1,4,p); + plot(1:sum(decLog), smooth(nanmean(decodes(decLog,:,1),2)), 'color', [44/255 168/255 224/255], 'linewidth', 1); + hold on; + plot(1:sum(decLog), smooth(nanmean(decodes(decLog,:,2),2)), 'color', [154/255 133/255 122/255], 'linewidth', 1); + plot(1:sum(decLog), smooth(nanmean(decodes(decLog,:,3),2)), 'color', [9/255 161/255 74/255], 'linewidth', 1); + plot(1:sum(decLog), smooth(nanmean(decodes(decLog,:,4),2)), 'color', [128/255 66/255 151/255], 'linewidth', 1); + for o = 1:4 + tempPostMean = smooth(nanmean(decodes(decLog,:,o),2)); + tempPostVar = smooth(SEMcalc(decodes(decLog,:,o)')'); + tp = patch('YData', [tempPostMean+tempPostVar; flipud(tempPostMean-tempPostVar)],... + 'XData', [1:length(tempPostMean), length(tempPostMean):-1:1], 'FaceAlpha', .3); + if o==1 + set(tp, 'FaceColor', [44/255 168/255 224/255], 'edgecolor', [44/255 168/255 224/255], 'EdgeAlpha', .5); + elseif o==2 + set(tp, 'FaceColor', [154/255 133/255 122/255], 'edgecolor', [154/255 133/255 122/255], 'EdgeAlpha', .5); + elseif o==3 + set(tp, 'FaceColor', [9/255 161/255 74/255], 'edgecolor', [9/255 161/255 74/255], 'EdgeAlpha', .5); + else + set(tp, 'FaceColor', [128/255 66/255 151/255], 'edgecolor', [128/255 66/255 151/255], 'EdgeAlpha', .5); + end + end + axis(sps(p), 'tight'); + set(sps(p), 'ylim', [0 1], 'xticklabels', []); + line([size(decodings.PItime,1)/2 size(decodings.PItime,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + line([size(decodings.POtime,1)/2+size(decodings.PItime,1) size(decodings.POtime,1)/2+size(decodings.PItime,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +end + legend('1', '2', '3','4', 'location', 'southoutside', 'orientation', 'horizontal'); + +%% +figure; +plot(1:size(osDiffs,1), smooth(nanmean(osDiffs,2)), 'color', 'k', 'linewidth', 1); +axis tight +patch('YData', [smooth(nanmean(osDiffs,2)+SEMcalc(osDiffs')'); flipud(smooth(nanmean(osDiffs,2)-SEMcalc(osDiffs')'))],... + 'XData', [1:length(nanmean(osDiffs,2)), length(nanmean(osDiffs,2)):-1:1], 'FaceAlpha', .3); +set(gca, 'ylim', [-1 1], 'xtick', [size(decodings.PItime,1)/2, size(decodings.POtime,1)/2+size(decodings.PItime,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +ylabel([{'Decoded Difference'};{'(Pos-Odor)'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(decodings.PItime,1) size(decodings.PItime,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1)/2 size(decodings.PItime,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.POtime,1)/2+size(decodings.PItime,1) size(decodings.POtime,1)/2+size(decodings.PItime,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +title(sprintf('GE11 OutSeq Decoding Diff (Position-Odor; Mean +/- SEM; %ixSessions)', length(decodingFiles))); + +%% +figure; +skpPlot = plot(1:size(skpDiffs,1), smooth(nanmean(skpDiffs,2)), 'color', 'k', 'linewidth', 1); +patch('YData', [smooth(nanmean(skpDiffs,2)+SEMcalc(skpDiffs')'); smooth(flipud(nanmean(skpDiffs,2)-SEMcalc(skpDiffs')'))],... + 'XData', [1:length(nanmean(skpDiffs,2)), length(nanmean(skpDiffs,2)):-1:1], 'FaceAlpha', .3); +axis tight +hold on; +repPlot = plot(1:size(repDiffs,1), smooth(nanmean(repDiffs,2)), 'color', 'r', 'linewidth', 1); +patch('YData', [smooth(nanmean(repDiffs,2)+SEMcalc(repDiffs')'); smooth(flipud(nanmean(repDiffs,2)-SEMcalc(repDiffs')'))],... + 'XData', [1:length(nanmean(repDiffs,2)), length(nanmean(repDiffs,2)):-1:1], 'FaceColor', 'r', 'EdgeColor', 'r', 'FaceAlpha', .3); +set(gca, 'ylim', [-1 1], 'xtick', [size(decodings.PItime,1)/2, size(decodings.POtime,1)/2+size(decodings.PItime,1)], 'xticklabel', [{'PokeIn'}, {'PokeOut'}]); +legend([skpPlot repPlot], 'Skips', 'Repeats'); +ylabel([{'Decoded Difference'};{'(Pos-Odor)'}]); +line(get(gca, 'xlim'), [0 0], 'color', 'k', 'linestyle', '--'); +line([size(decodings.PItime,1) size(decodings.PItime,1)], get(gca, 'ylim'), 'linestyle', '-', 'color', 'k', 'linewidth', 2); +line([size(decodings.PItime,1)/2 size(decodings.PItime,1)/2], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +line([size(decodings.POtime,1)/2+size(decodings.PItime,1) size(decodings.POtime,1)/2+size(decodings.PItime,1)], get(gca, 'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); +title('OutSeq Diff by Type'); + +%% +meanTrialDecodes = nan(4,4,4); +for p = 1:4 + meanTrialDecodes(:,:,p) = mean(cell2mat(reshape(cellfun(@(a)a(:,:,p),trlPrdDecodes, 'uniformoutput',0), [1,1,length(trlPrdDecodes)])),3); +end + +figure; +subplot(2,4,1) +imagesc(meanTrialDecodes(:,:,1), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4); +title('Pre-Trial Period'); +ylabel('Decoded Position'); +subplot(2,4,2) +imagesc(meanTrialDecodes(:,:,2), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4); +title('Early-Trial Period'); +subplot(2,4,3) +imagesc(meanTrialDecodes(:,:,3), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4); +title('Late-Trial Period'); +xlabel('True Position'); +ylabel('Decoded Position'); +subplot(2,4,4) +imagesc(meanTrialDecodes(:,:,4), [0 0.5]); +set(gca, 'xtick', 1:4, 'ytick', 1:4); +title('Post-Trial Period'); +xlabel('True Position'); +colormap jet + +subplot(2,4,5) +corrScatPlot(ssnSMI', trlPrdDprms(1,:)', 'SMI', 'dPrm'); +subplot(2,4,6) +corrScatPlot(ssnSMI', trlPrdDprms(2,:)', 'SMI', 'dPrm'); +subplot(2,4,7) +corrScatPlot(ssnSMI', trlPrdDprms(3,:)', 'SMI', 'dPrm'); +subplot(2,4,8) +corrScatPlot(ssnSMI', trlPrdDprms(4,:)', 'SMI', 'dPrm'); \ No newline at end of file diff --git a/Analyses/PlotNearTrialRipStats.m b/Analyses/PlotNearTrialRipStats.m new file mode 100644 index 0000000..428d81a --- /dev/null +++ b/Analyses/PlotNearTrialRipStats.m @@ -0,0 +1,28 @@ +function PlotNearTrialRipStats(tRips) +trialRips = tRips.Events; +trialRipsDur = tRips.Duration; +trialRipsSync = tRips.Synchrony; +trialRipsNsmbl = tRips.EnsembleAct; + +figure; +prcntTrlsWrips = mean(cellfun(@(a)~isempty(a),trialRips)); +subplot(4,1,1); +bar(prcntTrlsWrips); +set(gca, 'xticklabels', [], 'box', 'off'); +ylabel('% Trials w/Ripple'); +subplot(4,1,2); +BarPlotErrorbars([mean(cell2mat(trialRipsDur(:,1))),mean(cell2mat(trialRipsDur(:,2))),mean(cell2mat(trialRipsDur(:,3)))],... + [std(cell2mat(trialRipsDur(:,1))),std(cell2mat(trialRipsDur(:,2))),std(cell2mat(trialRipsDur(:,3)))],[],[]); +set(gca, 'xticklabels', [], 'box', 'off'); +ylabel('Duration (ms)'); +subplot(4,1,3); +BarPlotErrorbars([mean(cell2mat(trialRipsSync(:,1))),mean(cell2mat(trialRipsSync(:,2))),mean(cell2mat(trialRipsSync(:,3)))],... + [std(cell2mat(trialRipsSync(:,1))),std(cell2mat(trialRipsSync(:,2))),std(cell2mat(trialRipsSync(:,3)))],[],[]); +set(gca, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); +ylabel('Synchrony'); +subplot(4,1,4); +BarPlotErrorbars([mean(cell2mat(trialRipsNsmbl(:,1))),mean(cell2mat(trialRipsNsmbl(:,2))),mean(cell2mat(trialRipsNsmbl(:,3)))],... + [std(cell2mat(trialRipsNsmbl(:,1))),std(cell2mat(trialRipsNsmbl(:,2))),std(cell2mat(trialRipsNsmbl(:,3)))],[],[]); +set(gca, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); +ylabel('% Active Units'); +end \ No newline at end of file diff --git a/Analyses/PlotRipCountsByEvent.m b/Analyses/PlotRipCountsByEvent.m new file mode 100644 index 0000000..e75da94 --- /dev/null +++ b/Analyses/PlotRipCountsByEvent.m @@ -0,0 +1,36 @@ +function PlotRipCountsByEvent(rips) +%% +pokeInNdxs = rips.TrialInfo.TrialPokes(:,1); +pokeOutNdxs = rips.TrialInfo.TrialPokes(:,2); +rwdNdxs = rips.TrialInfo.TrialRewards; + +if length(pokeInNdxs)~=length(rwdNdxs) + rwdNdxs(end:end+(length(pokeInNdxs)-length(rwdNdxs)))=nan; +end +%% +piDiffs = cell(length(pokeInNdxs),1); +poDiffs = piDiffs; +rdDiffs = piDiffs; +for trl = 1:size(rips.TrialInfo.TrialPokes,1) + curPIdiff = rips.Ripples.Events(:,1) - pokeInNdxs(trl); + piDiffs{trl} = curPIdiff(curPIdiff>=-500 & curPIdiff<=500); + + curPOdiff = rips.Ripples.Events(:,1) - pokeOutNdxs(trl); + poDiffs{trl} = curPOdiff(curPOdiff>=-500 & curPOdiff<=500); + + curRDdiff = rips.Ripples.Events(:,1) - rwdNdxs(trl); + rdDiffs{trl} = curRDdiff(curRDdiff>=-500 & curRDdiff<=500); +end + +%% +figure; +subplot(3,1,1) +histogram(cell2mat(piDiffs), -500:10:500); +title('Ripples Relative to Poke In'); +subplot(3,1,2) +histogram(cell2mat(poDiffs), -500:10:500); +title('Ripples Relative to Poke Out'); +subplot(3,1,3) +histogram(cell2mat(rdDiffs), -500:10:500); +title('Ripples Relative to Reward Delivery'); + diff --git a/Analyses/PlotRipFeatCorr.m b/Analyses/PlotRipFeatCorr.m new file mode 100644 index 0000000..3000cb6 --- /dev/null +++ b/Analyses/PlotRipFeatCorr.m @@ -0,0 +1,28 @@ +function PlotRipFeatCorr(param1, param2, param1Title, param2Title) +%% Plot Duration vs Synchrony Correlation +figure; +p1Hist = subplot(4,4,[1,5,9]); +histogram(param1, 30, 'Orientation', 'Horizontal'); +set(gca, 'XDir', 'reverse'); +line(get(gca, 'xlim'), repmat(mean(param1), [1,2]), 'color', 'r', 'linewidth', 2); +line(get(gca, 'xlim'), repmat(median(param1), [1,2]),'color', 'r', 'linestyle', '--', 'linewidth', 2); +if mean(param1)>median(param1) + set(gca, 'ytick', [median(param1), mean(param1)], 'yticklabel', [{'Median'}, {'Mean'}]); +else + set(gca, 'ytick', [mean(param1), median(param1)], 'yticklabel', [{'Mean'}, {'Median'}]); +end +xlabel('Count'); +ylabel([{['\bf' param1Title '\rm']}; sprintf('Mean: %0.2f; Median: %0.2f', mean(param1), median(param1))]); + +corre = subplot(4,4,[2:4,6:8,10:12]); +corrScatPlot(param2, param1, [], [], []); +title(sprintf('Session Wide Ripple %s vs %s', param1Title, param2Title)); +set(gca, 'xticklabel', [], 'yticklabel', []); + +p2Hist = subplot(4,4,14:16); +histogram(param2, 30); +title([{['\bf' param2Title '\rm']}; sprintf('Mean: %0.2f; Median: %0.2f', mean(param2), median(param2))]); +ylabel('Count'); + +linkaxes([p1Hist, corre], 'y'); +linkaxes([p2Hist, corre], 'x'); \ No newline at end of file diff --git a/Analyses/PlotRipFeatsByEvent.m b/Analyses/PlotRipFeatsByEvent.m new file mode 100644 index 0000000..5144eb0 --- /dev/null +++ b/Analyses/PlotRipFeatsByEvent.m @@ -0,0 +1,61 @@ +function PlotRipFeatsByEvent(rips, param) +%% +pokeInNdxs = rips.TrialInfo.TrialPokes(:,1); +pokeOutNdxs = rips.TrialInfo.TrialPokes(:,2); +rwdNdxs = rips.TrialInfo.TrialRewards; + +if length(pokeInNdxs)~=length(rwdNdxs) + rwdNdxs(end:end+(length(pokeInNdxs)-length(rwdNdxs)))=nan; +end + +%% +switch param + case 'Duration' + feat = rips.Ripples.Duration; + case 'Synchrony' + feat = rips.Ripples.Synchrony; + case 'Spiking' + feat = rips.Ripples.EnsembleActivity; + case 'Power' + feat = rips.Ripples.MaxPower; + case 'MaxFreq' + feat = rips.Ripples.MaxPowerFrequency; +end + +%% +piDiffs = cell(length(pokeInNdxs),1); +piFeat = piDiffs; +poDiffs = piDiffs; +poFeat = piDiffs; +rdDiffs = piDiffs; +rdFeat = piDiffs; +for trl = 1:size(rips.TrialInfo.TrialPokes,1) + curPIdiff = rips.Ripples.Events(:,1) - pokeInNdxs(trl); + piLog = curPIdiff>=-500 & curPIdiff<=500; + piDiffs{trl} = curPIdiff(piLog); + piFeat{trl} = feat(piLog); + + curPOdiff = rips.Ripples.Events(:,1) - pokeOutNdxs(trl); + poLog = curPOdiff>=-500 & curPOdiff<=500; + poDiffs{trl} = curPOdiff(poLog); + poFeat{trl} = feat(poLog); + + curRDdiff = rips.Ripples.Events(:,1) - rwdNdxs(trl); + rdLog = curRDdiff>=-500 & curRDdiff<=500; + rdDiffs{trl} = curRDdiff(rdLog); + rdFeat{trl} = feat(rdLog); +end + +%% +figure; +sp1 = subplot(3,1,1); +scatter(cell2mat(piDiffs), cell2mat(piFeat), '*k'); +title(sprintf('Ripple %s Relative to Poke In', param)); +sp2 = subplot(3,1,2); +scatter(cell2mat(poDiffs), cell2mat(poFeat), '*k'); +title(sprintf('Ripple %s Relative to Poke Out', param)); +sp3 = subplot(3,1,3); +scatter(cell2mat(rdDiffs), cell2mat(rdFeat), '*k'); +title(sprintf('Ripple %s Relative to Reward Delivery', param)); +linkaxes([sp1 sp2 sp3], 'xy'); +set(sp3, 'xlim', [-500 500]); \ No newline at end of file diff --git a/Analyses/PlotRipFeatsByOdor.m b/Analyses/PlotRipFeatsByOdor.m new file mode 100644 index 0000000..98fd41e --- /dev/null +++ b/Analyses/PlotRipFeatsByOdor.m @@ -0,0 +1,113 @@ +function PlotRipFeatsByOdor(rips, trialRips) + +%% Extract Logicals +perfLog = rips.TrialInfo.Perf; +isLog = rips.TrialInfo.TransDist==0; + +%% Plot Data +figure; +% Plot Odor A +aLog = perfLog & isLog & rips.TrialInfo.OdorVect==1; +aP = subplot(4,5,1); + RipLikelyPlot(trialRips.Events, aLog); + ylabel(aP, '% Trials w/Ripple'); + title(aP, 'Odor A'); +aD = subplot(4,5,6); + RipPlotVar(trialRips.Duration, aLog); + ylabel(aD, 'Duration'); +aS = subplot(4,5,11); + RipPlotVar(trialRips.Synchrony, aLog); + ylabel(aS, 'Synchrony'); +aE = subplot(4,5,16); + RipPlotVar(trialRips.EnsembleAct, aLog); + ylabel(aE, '% Units Active'); + set(aE, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +% Plot Odor B +bLog = perfLog & isLog & rips.TrialInfo.OdorVect==2; +bP = subplot(4,5,2); + RipLikelyPlot(trialRips.Events, bLog); + ylabel(bP, '% Trials w/Ripple'); + title(bP, 'Odor B'); +bD = subplot(4,5,7); + RipPlotVar(trialRips.Duration, bLog); + ylabel(bD, 'Duration'); +bS = subplot(4,5,12); + RipPlotVar(trialRips.Synchrony, bLog); + ylabel(bS, 'Synchrony'); +bE = subplot(4,5,17); + RipPlotVar(trialRips.EnsembleAct, bLog); + ylabel(bE, '% Units Active'); + set(bE, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +% Plot Odor C +cLog = perfLog & isLog & rips.TrialInfo.OdorVect==3; +cP = subplot(4,5,3); + RipLikelyPlot(trialRips.Events, cLog); + ylabel(cP, '% Trials w/Ripple'); + title(cP, 'Odor C'); +cD = subplot(4,5,8); + RipPlotVar(trialRips.Duration, cLog); + ylabel(cD, 'Duration'); +cS = subplot(4,5,13); + RipPlotVar(trialRips.Synchrony, cLog); + ylabel(cS, 'Synchrony'); +cE = subplot(4,5,18); + RipPlotVar(trialRips.EnsembleAct, cLog); + ylabel(cE, '% Units Active'); + set(cE, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +% Plot Odor D +dLog = perfLog & isLog & rips.TrialInfo.OdorVect==4; +dP = subplot(4,5,4); + RipLikelyPlot(trialRips.Events, dLog); + ylabel(dP, '% Trials w/Ripple'); + title(dP, 'Odor D'); +dD = subplot(4,5,9); + RipPlotVar(trialRips.Duration, dLog); + ylabel(dD, 'Duration'); +dS = subplot(4,5,14); + RipPlotVar(trialRips.Synchrony, dLog); + ylabel(dS, 'Synchrony'); +dE = subplot(4,5,19); + RipPlotVar(trialRips.EnsembleAct, dLog); + ylabel(dE, '% Units Active'); + set(dE, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +% Plot Odor E +eLog = perfLog & isLog & rips.TrialInfo.OdorVect==5; +eP = subplot(4,5,5); + RipLikelyPlot(trialRips.Events, eLog); + ylabel(eP, '% Trials w/Ripple'); + title(eP, 'Odor E'); +eD = subplot(4,5,10); + RipPlotVar(trialRips.Duration, eLog); + ylabel(eD, 'Duration'); +eS = subplot(4,5,15); + RipPlotVar(trialRips.Synchrony, eLog); + ylabel(eS, 'Synchrony'); +eE = subplot(4,5,20); + RipPlotVar(trialRips.EnsembleAct, eLog); + ylabel(eE, '% Units Active'); + set(eE, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +linkaxes([aP bP cP dP eP], 'xy'); +linkaxes([aD bD cD dD eD], 'xy'); +linkaxes([aS bS cS dS eS], 'xy'); +linkaxes([aE bE cE dE eE], 'xy'); +end + + + +%% Plotting Functions +function RipLikelyPlot(trialRips, log) + prcntTrlsWrips = mean(cellfun(@(a)~isempty(a),trialRips(log,:))); + bar(prcntTrlsWrips); + set(gca, 'xticklabels', [], 'box', 'off'); +end + +function RipPlotVar(trialRipsParam, log) + BarPlotErrorbars([mean(cell2mat(trialRipsParam(log,1))),mean(cell2mat(trialRipsParam(log,2))),mean(cell2mat(trialRipsParam(log,3)))],... + [std(cell2mat(trialRipsParam(log,1))),std(cell2mat(trialRipsParam(log,2))),std(cell2mat(trialRipsParam(log,3)))],[],[]); + set(gca, 'xticklabels', [], 'box', 'off'); +end diff --git a/Analyses/PlotRipFeatsByTrlType.m b/Analyses/PlotRipFeatsByTrlType.m new file mode 100644 index 0000000..9e00a7f --- /dev/null +++ b/Analyses/PlotRipFeatsByTrlType.m @@ -0,0 +1,88 @@ +function PlotRipFeatsByTrlType(rips, trialRips) + +%% Extract Logicals +perfLog = rips.TrialInfo.Perf; +isLog = rips.TrialInfo.TransDist==0; + +%% Plot Data +% Plot InSeq Correct +iscLog = perfLog & isLog; +figure; +iscP = subplot(4,4,1); + RipLikelyPlot(trialRips.Events, iscLog); + ylabel(iscP, '% Trials w/Ripple'); + title(iscP, 'InSeq Correct Trials'); +iscD = subplot(4,4,5); + RipPlotVar(trialRips.Duration, iscLog); + ylabel(iscD, 'Duration'); +iscS = subplot(4,4,9); + RipPlotVar(trialRips.Synchrony, iscLog); + ylabel(iscS, 'Synchrony'); +iscE = subplot(4,4,13); + RipPlotVar(trialRips.EnsembleAct, iscLog); + ylabel(iscE, '% Units Active'); + set(gca, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +% Plot InSeq Incorrect +isiLog = ~perfLog & isLog; +isiP = subplot(4,4,2); + RipLikelyPlot(trialRips.Events, isiLog); + ylabel(isiP, '% Trials w/Ripple'); + title(isiP, 'InSeq Incorrect Trials'); +isiD = subplot(4,4,6); + RipPlotVar(trialRips.Duration, isiLog); + ylabel(isiD, 'Duration'); +isiS = subplot(4,4,10); + RipPlotVar(trialRips.Synchrony, isiLog); + ylabel(isiS, 'Synchrony'); +isiE = subplot(4,4,14); + RipPlotVar(trialRips.EnsembleAct, isiLog); + ylabel(isiE, '% Units Active'); + set(gca, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +% Plot OutSeq Incorrect +osiLog = ~perfLog & ~isLog; +osiP = subplot(4,4,3); + RipLikelyPlot(trialRips.Events, osiLog); + title(osiP, 'OutSeq Incorrect Trials'); +osiD = subplot(4,4,7); + RipPlotVar(trialRips.Duration, osiLog); +osiS = subplot(4,4,11); + RipPlotVar(trialRips.Synchrony, osiLog); +osiE = subplot(4,4,15); + RipPlotVar(trialRips.EnsembleAct, osiLog); + set(gca, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + +% Plot OutSeq Correct +oscLog = perfLog & ~isLog; +oscP = subplot(4,4,4); + RipLikelyPlot(trialRips.Events, oscLog); + title(oscP, 'OutSeq Correct Trials'); +oscD = subplot(4,4,8); + RipPlotVar(trialRips.Duration, oscLog); +oscS = subplot(4,4,12); + RipPlotVar(trialRips.Synchrony, oscLog); +oscE = subplot(4,4,16); + RipPlotVar(trialRips.EnsembleAct, oscLog); + set(gca, 'xticklabels', [{'Pre-Trial'}, {'Trial'}, {'Post-Trial'}], 'box', 'off'); + + +linkaxes([iscP isiP oscP osiP], 'xy'); +linkaxes([iscD isiD oscD osiD], 'xy'); +linkaxes([iscS isiS oscS osiS], 'xy'); +linkaxes([iscE isiE oscE osiE], 'xy'); +end + + +%% Plotting Functions +function RipLikelyPlot(trialRips, log) + prcntTrlsWrips = mean(cellfun(@(a)~isempty(a),trialRips(log,:))); + bar(prcntTrlsWrips); + set(gca, 'xticklabels', [], 'box', 'off'); +end + +function RipPlotVar(trialRipsParam, log) + BarPlotErrorbars([mean(cell2mat(trialRipsParam(log,1))),mean(cell2mat(trialRipsParam(log,2))),mean(cell2mat(trialRipsParam(log,3)))],... + [std(cell2mat(trialRipsParam(log,1))),std(cell2mat(trialRipsParam(log,2))),std(cell2mat(trialRipsParam(log,3)))],[],[]); + set(gca, 'xticklabels', [], 'box', 'off'); +end \ No newline at end of file diff --git a/Analyses/PlotUniSum_SM.m b/Analyses/PlotUniSum_SM.m index a2641d4..2881221 100644 --- a/Analyses/PlotUniSum_SM.m +++ b/Analyses/PlotUniSum_SM.m @@ -274,9 +274,9 @@ if uniSum.TrialEpochStats.Error.Odor(2) +pokeInOrientationISC = pokeInOrientationAll(corrTrlLog & isLog); +pokeOutOrientationAll = ExtractTrialData_SM(pokeOutTrialMatrix, orientMatrix); +pokeOutOrientationISC = pokeOutOrientationAll(corrTrlLog & isLog); +% Now concatenate them into a single cell vector +orientationTrialDataRaw = cellfun(@(a,b)[a;b], pokeInOrientationISC, pokeOutOrientationISC, 'uniformoutput', 0); +% Now correct the timestamps in the vector so that poke In and poke Out are +% equi-distant. +relTimeVects = cellfun(@(a,b,c)[a(:,1); b(:,1) - (b(1,1)-a(end,1)) + (b(2,1)-b(1,1))] - orientMatrix(c,1), pokeInOrientationISC, pokeOutOrientationISC, pokeInNdxsISC, 'uniformoutput',0); +orientationTrialData = cellfun(@(a,b)[a,b(:,2:end)], relTimeVects, orientationTrialDataRaw, 'uniformoutput', 0); + +% Extract Spike Data +pokeInFRall = ExtractTrialData_SM(pokeInTrialMatrix, uniInstFR); %#ok<*NODEF> +pokeInFRisc = pokeInFRall(corrTrlLog & isLog); +pokeOutFRall = ExtractTrialData_SM(pokeOutTrialMatrix, uniInstFR); +pokeOutFRisc = pokeOutFRall(corrTrlLog & isLog); +% Now concatenate them into a single cell vector +firingRateTrialDataRaw = cellfun(@(a,b)[a;b], pokeInFRisc, pokeOutFRisc, 'uniformoutput', 0); +relTimeVects = cellfun(@(a,b,c)[a(:,1); b(:,1) - (b(1,1)-a(end,1)) + (b(2,1)-b(1,1))] - orientMatrix(c,1), pokeInFRisc, pokeOutFRisc, pokeInNdxsISC, 'uniformoutput',0); +firingRateTrialData = cellfun(@(a,b)[a,b(:,2:end)], relTimeVects, firingRateTrialDataRaw, 'uniformoutput', 0); + +% Create Trial Position cell vectors +trialIDall = arrayfun(@(a,b)[ones(sum(a.TrialLogVect),1)*a.Odor; ones(sum(b.TrialLogVect),1)*b.Odor], pokeInTrialMatrix, pokeOutTrialMatrix, 'uniformoutput', 0); +trialIDvals = trialIDall(corrTrlLog & isLog); + +%% Calculate Standard Variables Used in Analysis +% Average Firing Rate +% For this I need to extract the firing rate values for each unit every +% time there's a position value taken. This is simply because I'm using the +% instantaneous firing rate for expedience. If I were simply binning the +% data into discrete time bins then there wouldn't be an issue, I would +% just calculate the average across bins. Since I'm not, I need to extract +% the instantaneous rate at each capture instance and compute the average +% from that. +% I'm using cellfun here to save space/time. +% I'm using the trial wise orientation data to create a logical vector of +% capture times and then applying it to the spike date. Since they're +% both organized by trial with the same indices extracted it's simple to +% do. +allFRvals = cell2mat(cellfun(@(a,b)b(~isnan(a(:,2)),2:end), orientationTrialData, firingRateTrialData, 'uniformoutput', 0)'); +allTimeVals = cell2mat(cellfun(@(a,b)b(~isnan(a(:,2)),1), orientationTrialData, firingRateTrialData, 'uniformoutput', 0)'); +meanFRvals = mean(allFRvals,1); + +% Pull out the trial position value to match each of the camera capture +% times +allTrialIDvals = cell2mat(cellfun(@(a,b)b(~isnan(a(:,2)),1), orientationTrialData, trialIDvals, 'uniformoutput', 0)'); + +% Orientation Occupancy Bins: Define spaces and calculate p(occupy) +% First break the orientation data out of the trial organization. +% Note: 1pixel = ~1.7mm +allOrientData = cell2mat(cellfun(@(a)a(~isnan(a(:,2)),:), orientationTrialData, 'uniformoutput', 0)'); +% Head Position: Head X/Y +headXcolLog = strcmp(orientMatrixColIDs, 'HeadX'); +headXbins = floor(min(allOrientData(:,headXcolLog))/10)*10:spatialBinSize:ceil(max(allOrientData(:,headXcolLog))/10)*10; +headYcolLog = strcmp(orientMatrixColIDs, 'HeadY'); +headYbins = floor(min(allOrientData(:,headYcolLog))/10)*10:spatialBinSize:ceil(max(allOrientData(:,headYcolLog))/10)*10; +headOccupancyMatrix = histcounts2(allOrientData(:,headXcolLog), allOrientData(:,headYcolLog), headXbins, headYbins, 'Normalization', 'probability')'; +headOccupancyMatrix(headOccupancyMatrix==0) = nan; +% Tail Position: Tail X/Y +tailXcolLog = strcmp(orientMatrixColIDs, 'TailX'); +tailXbins = floor(min(allOrientData(:,tailXcolLog))/10)*10:spatialBinSize:ceil(max(allOrientData(:,tailXcolLog))/10)*10; +tailYcolLog = strcmp(orientMatrixColIDs, 'TailY'); +tailYbins = floor(min(allOrientData(:,tailYcolLog))/10)*10:spatialBinSize:ceil(max(allOrientData(:,tailYcolLog))/10)*10; +tailOccupancyMatrix = histcounts2(allOrientData(:,tailXcolLog), allOrientData(:,tailYcolLog), tailXbins, tailYbins, 'Normalization', 'probability')'; +tailOccupancyMatrix(tailOccupancyMatrix==0) = nan; +% Head Angle: Angle at the head between the port and the tail +headAngleColLog = strcmp(orientMatrixColIDs, 'HeadAngle'); +headAngleBins = 0:15:180; +headAngleOccupancyVector = histcounts(allOrientData(:,headAngleColLog), headAngleBins, 'Normalization', 'probability'); +% Tail Angle: Angle at the tail between the port and the head +tailAngleColLog = strcmp(orientMatrixColIDs, 'TailAngle'); +tailAngleBins = 0:15:180; +tailAngleOccupancyVector = histcounts(allOrientData(:,tailAngleColLog), tailAngleBins, 'Normalization', 'probability'); +% Port Angle: Angle at the port between the head and the tail +portAngleColLog = strcmp(orientMatrixColIDs, 'PortAngle'); +portAngleBins = 0:15:180; +portAngleOccupancyVector = histcounts(allOrientData(:,portAngleColLog), portAngleBins, 'Normalization', 'probability'); + +% Trial Position Occupancy Bins: Here I'm considering position to be a 2-D +% where the x-axis is Time and the Y-axis is trial position +posBins = 0.5:4.5; +timeBins = firingRateTrialData{1}(1,1)-timeBinSize:timeBinSize:firingRateTrialData{1}(end,1)+timeBinSize; +timeBinOccupancyMatrix = histcounts2(allTimeVals, allTrialIDvals, timeBins, posBins, 'Normalization', 'probability')'; + +%% Analyze the Orientation Data +% For this I will be breaking down the head and tail spatial position by +% trial position and analyzing the variation across and within trials. +tPosHeadOccupyFig = PlotTrialPositionOccupancy(allOrientData, orientationTrialData, headXcolLog, headYcolLog, headXbins, headYbins, allTrialIDvals, odorIDsISC, timeBins, 'Head'); +figure(tPosHeadOccupyFig); +annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('Spatial Bin = %.02fmm, Temporal Bin = %.02fms', spatialBinSize*1.7, timeBinSize*1000), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +orient(tPosHeadOccupyFig, 'tall'); +orient(tPosHeadOccupyFig, 'landscape'); +% print +print('-painters', tPosHeadOccupyFig, '-dpdf', 'HeadLocationTrialPositionSummary'); +tPosTailOccupyFig = PlotTrialPositionOccupancy(allOrientData, orientationTrialData, tailXcolLog, tailYcolLog, tailXbins, tailYbins, allTrialIDvals, odorIDsISC, timeBins, 'Tail'); +figure(tPosTailOccupyFig); +annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('Spatial Bin = %.02fmm, Temporal Bin = %.02fms', spatialBinSize*1.7, timeBinSize*1000), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +orient(tPosTailOccupyFig, 'tall'); +orient(tPosTailOccupyFig, 'landscape'); +% print +print('-painters', tPosTailOccupyFig, '-dpdf', 'TailLocationTrialPositionSummary'); +% Compute the deviation (distance) for the Head and Tail during the first +% frame of every trial from the spatial position on trial #1 in the +% sequence + +% Compute the deviation (distance) of the Head and Tail during the trial +% period for every trial + +% Calculate the spatial position for Head and Tail for each trial position +% for the entire trial period + +% Calculate the difference across trial positions for the spatial position +% matrix (just do subtraction for now) and plot the difference in grayscale + + + +%% Run Analyses +for uni = 1:length(ensembleUnitSummaries) + %% Port Orientation Alone Analyses + % Head Position Information + [headFRmap, headICmap, headIC, headICrate] = CalculateFieldIC(allOrientData(:,headXcolLog), allOrientData(:,headYcolLog),... + headXbins, headYbins, headOccupancyMatrix, allFRvals(:,uni), meanFRvals(uni)); + % Tail Position Information + [tailFRmap, tailICmap, tailIC, tailICrate] = CalculateFieldIC(allOrientData(:,tailXcolLog), allOrientData(:,tailYcolLog),... + tailXbins, tailYbins, tailOccupancyMatrix, allFRvals(:,uni), meanFRvals(uni)); + + % Head Angle Information + [headAngleFRvect, headAngleICvect, headAngleICval, headAngleICrate] = CalculateVectorIC(allOrientData(:,headAngleColLog),... + headAngleBins, headAngleOccupancyVector, allFRvals(:,uni), meanFRvals(uni)); + % Tail Angle Information + [tailAngleFRvect, tailAngleICvect, tailAngleICval, tailAngleICrate] = CalculateVectorIC(allOrientData(:,tailAngleColLog),... + tailAngleBins, tailAngleOccupancyVector, allFRvals(:,uni), meanFRvals(uni)); + % Port Angle Information + [portAngleFRvect, portAngleICvect, portAngleICval, portAngleICrate] = CalculateVectorIC(allOrientData(:,portAngleColLog),... + portAngleBins, portAngleOccupancyVector, allFRvals(:,uni), meanFRvals(uni)); + + + figure + % Head Occupancy Matrix + subplot(3,3,1) + imagesc(headOccupancyMatrix); + set(gca, 'ydir', 'normal'); + title('Head Occupancy'); + cb = colorbar('southoutside'); + cb.Label.String = 'p(Occupancy)'; + z = colormap('jet'); + z(1,:) = [1 1 1]; + colormap(z); + set(gca, 'clim', [-0.01, max(get(gca, 'clim'))]); + % Head FR Map + subplot(3,3,2) + imagesc(headFRmap); + set(gca, 'ydir', 'normal'); + title('Head Position FR'); + cb = colorbar('southoutside'); + cb.Label.String = 'Mean Firing Rate (spk/s)'; + colormap(z); + % Head IC Map + subplot(3,3,3) + imagesc(headICmap); + set(gca, 'ydir', 'normal'); + title(sprintf('Head Position IC (Overall = %.03f bits | %.03f bit/sec)', headIC, headICrate)); + cb = colorbar('southoutside'); + cb.Label.String = 'Information Content (bits)'; + colormap(z); + + % Tail Occupancy Matrix + subplot(3,3,4) + imagesc(tailOccupancyMatrix); + set(gca, 'ydir', 'normal'); + title('Tail Occupancy'); + cb = colorbar('southoutside'); + cb.Label.String = 'p(Occupancy)'; + colormap(z); + set(gca, 'clim', [-0.01, max(get(gca, 'clim'))]); + % Head FR Map + subplot(3,3,5) + imagesc(tailFRmap); + set(gca, 'ydir', 'normal'); + title('Tail Position FR'); + cb = colorbar('southoutside'); + cb.Label.String = 'Mean Firing Rate (spk/s)'; + colormap(z); + % Head IC Map + subplot(3,3,6) + imagesc(tailICmap); + set(gca, 'ydir', 'normal'); + title(sprintf('Tail Position IC (Overall = %.03f bits | %.03f bit/sec)', tailIC, tailICrate)); + cb = colorbar('southoutside'); + cb.Label.String = 'Information Content (bits)'; + colormap(z); + + % Head Angle + subplot(3,3,7) + yyaxis left + plot(headAngleBins(2:end) - diff(headAngleBins)/2, headAngleOccupancyVector, 'linestyle', '--', 'color', 'k'); + hold on; + yyaxis right + plot(headAngleBins(2:end) - diff(headAngleBins)/2, headAngleFRvect, 'linestyle', '-', 'color', 'k'); + yyaxis left + plot(headAngleBins(2:end) - diff(headAngleBins)/2, headAngleICvect, 'linestyle', '-', 'color', 'r'); + box off; + yyaxis left + ylabel 'Occupancy OR IC (bits)' + yyaxis right + ylabel 'Firing Rate' + legend('Occ', 'FR', 'IC', 'location', 'best'); + title(sprintf('Head Angle (Overall IC = %.03f bits | %.03f bit/sec)', headAngleICval, headAngleICrate)); + + subplot(3,3,8) + yyaxis left + plot(tailAngleBins(2:end) - diff(tailAngleBins)/2, tailAngleOccupancyVector, 'linestyle', '--', 'color', 'k'); + hold on; + yyaxis right + plot(tailAngleBins(2:end) - diff(tailAngleBins)/2, tailAngleFRvect, 'linestyle', '-', 'color', 'k'); + yyaxis left + plot(tailAngleBins(2:end) - diff(tailAngleBins)/2, tailAngleICvect, 'linestyle', '-', 'color', 'r'); + box off; + yyaxis left + ylabel 'Occupancy OR IC (bits)' + yyaxis right + ylabel 'Firing Rate' + legend('Occ', 'FR', 'IC', 'location', 'best'); + title(sprintf('Tail Angle (Overall IC = %.03f bits | %.03f bit/sec)', tailAngleICval, tailAngleICrate)); + + subplot(3,3,9) + yyaxis left + plot(portAngleBins(2:end) - diff(portAngleBins)/2, portAngleOccupancyVector, 'linestyle', '--', 'color', 'k'); + hold on; + yyaxis right + plot(portAngleBins(2:end) - diff(portAngleBins)/2, portAngleFRvect, 'linestyle', '-', 'color', 'k'); + yyaxis left + plot(portAngleBins(2:end) - diff(portAngleBins)/2, portAngleICvect, 'linestyle', '-', 'color', 'r'); + box off; + yyaxis left + ylabel 'Occupancy OR IC (bits)' + yyaxis right + ylabel 'Firing Rate' + legend('Occ', 'FR', 'IC', 'location', 'best'); + title(sprintf('Port Angle (Overall IC = %.03f bits | %.03f bit/sec)', portAngleICval, portAngleICrate)); + + annotation('textbox', [0.05 0.9 0.9 0.1], 'String', ensembleMatrixColIDs{uni+1}, 'linestyle', 'none', 'FontSize', 20); %#ok + annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('Spatial Bin = %.02fmm, Gaussian = %.02fms', spatialBinSize*1.7, slideWindowSize), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); + annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); + drawnow + + orient(gcf, 'tall'); + orient(gcf, 'landscape'); +% print + print('-painters', gcf, '-dpdf', sprintf('%s_OrientInfo_Summary', ensembleMatrixColIDs{uni+1})); +% close(gcf); + + %% Trial Position Alone + % Trial Position + [trialFRmap, trialICmap, trialIC, trialICrate] = CalculateFieldIC(allTimeVals, allTrialIDvals,... + timeBins, posBins, timeBinOccupancyMatrix, allFRvals(:,uni), meanFRvals(uni)); + + figure; + subplot(1,3,1) + imagesc(firingRateTrialData{1}(1,1):0.1:firingRateTrialData{1}(end,1),1:4,timeBinOccupancyMatrix); + set(gca, 'ytick', 1:4); + hold on; + line([0 0], [0.5 4.5], 'linewidth', 2, 'color', 'k'); + title('Trial Occupancy'); + cb = colorbar('southoutside'); + cb.Label.String = 'p(Occupancy)'; + z = colormap('jet'); + z(1,:) = [1 1 1]; + colormap(z); + set(gca, 'clim', [-0.01, max(get(gca, 'clim'))]); + + subplot(1,3,2) + imagesc(firingRateTrialData{1}(1,1):0.1:firingRateTrialData{1}(end,1),1:4,trialFRmap); + set(gca, 'ytick', 1:4); + hold on; + line([0 0], [0.5 4.5], 'linewidth', 2, 'color', 'k'); +% set(gca, 'ydir', 'normal'); + title('Trial Position FR'); + cb = colorbar('southoutside'); + cb.Label.String = 'Mean Firing Rate (spk/s)'; + colormap(z); + + subplot(1,3,3) + imagesc(firingRateTrialData{1}(1,1):0.1:firingRateTrialData{1}(end,1),1:4,trialICmap); + set(gca, 'ytick', 1:4); + hold on; + line([0 0], [0.5 4.5], 'linewidth', 2, 'color', 'k'); +% set(gca, 'ydir', 'normal'); + title(sprintf('Trial Position IC (Overall = %.03f bits | %.03f bit/sec)', trialIC, trialICrate)); + cb = colorbar('southoutside'); + cb.Label.String = 'Information Content (bits)'; + colormap(z); + + annotation('textbox', [0.05 0.9 0.9 0.1], 'String', ensembleMatrixColIDs{uni+1}, 'linestyle', 'none', 'FontSize', 20); + annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('Temporal Bin = %.02fmm, Gaussian = %.02fms', timeBinSize*1000, slideWindowSize), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); + annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); + drawnow + + orient(gcf, 'tall'); + orient(gcf, 'landscape'); +% print + print('-painters', gcf, '-dpdf', sprintf('%s_PositionInfo_Summary', ensembleMatrixColIDs{uni+1})); + close(gcf); +end + +end +%% +function [frMap, icMap, totalICval, overallICrate] = CalculateFieldIC(curXdata, curYdata, xBinLims, yBinLims, occupancyMatrix, uniFR, meanFR) +frMap = nan(length(yBinLims)-1, length(xBinLims)-1); +frStdMap = nan(length(yBinLims)-1, length(xBinLims)-1); +icMap = nan(length(yBinLims)-1, length(xBinLims)-1); +for r = 1:length(yBinLims)-1 + yValLog = (curYdata>=yBinLims(r) & curYdata=xBinLims(c) & curXdata=xBinLims(c) & curXdata=0, 1, 'first'), xColLog); + yFF(trl) = curTrlData(find(curTrlData(:,1)>=0, 1, 'first'), yColLog); + trialMoveVect{trl} = [curTrlData(:,1), cell2mat(arrayfun(@(a,b)sqrt(((a-xFF(trl))^2)+((b-yFF(trl))^2)), curTrlData(:,xColLog), curTrlData(:,yColLog), 'uniformoutput', 0))]; +end +% Compute the average spatial position for Head and Tail across trial +% positions +trialHeadXff = nan(2,4); +trialHeadYff = nan(2,4); +trialMoveVals = repmat({nan(2,length(timeBins)-1)}, [1 4]); +for pos = 1:4 + trialHeadXff(1,pos) = mean(xFF(odorIDsISC==pos)); + trialHeadXff(2,pos) = std(xFF(odorIDsISC==pos)); + + trialHeadYff(1,pos) = mean(yFF(odorIDsISC==pos)); + trialHeadYff(2,pos) = std(yFF(odorIDsISC==pos)); + curPosTrlVects = cell2mat(trialMoveVect(odorIDsISC==pos)'); + tempDistVect = trialMoveVals{pos}; + for tb = 1:length(timeBins)-1 + tempDistVect(1,tb) = mean(curPosTrlVects(curPosTrlVects(:,1)>=timeBins(tb) & curPosTrlVects(:,1)=timeBins(tb) & curPosTrlVects(:,1) +pokeInFRisc = cell2mat(reshape(pokeInFR(trialLog), [1,1,sum(trialLog)])); +pokeOutFR = ExtractTrialData_SM(pokeOutTrialMatrix, uniInstFR); +pokeOutFRisc = cell2mat(reshape(pokeOutFR(trialLog), [1,1,sum(trialLog)])); + +% Pull out and interpolate positional information +pokeInOrientation = ExtractTrialData_SM(pokeInTrialMatrix, orientMatrix); %#ok<*NODEF> +pokeInOrientationInterp = cell(size(pokeInOrientation)); +pokeOutOrientation = ExtractTrialData_SM(pokeOutTrialMatrix, orientMatrix); +pokeOutOrientationInterp = cell(size(pokeOutOrientation)); + +%% Remove Units with low firing rates +uniFRthreshLog = max([max(mean(pokeInFRisc,3)); max(mean(pokeOutFRisc,3))])<1; +pokeInFRisc(:,uniFRthreshLog,:) = []; +pokeOutFRisc(:,uniFRthreshLog,:) = []; +goodUniNames = {ensembleUnitSummaries(~uniFRthreshLog).UnitName}; + +%% Pre-Process the positional data v2 +% First thing to do is nan out the pre trial periods that don't have +% positional data (in the pokeIn aligned) as well as the post trial periods +% that don't have positional data (in the pokeOut aligned) + +for trl = 1:length(pokeInOrientation) + curPIori = pokeInOrientation{trl}; + firstPreTrialNdx = find(~isnan(curPIori(:,headAngleColLog)),1,'first'); + curPIori(1:firstPreTrialNdx, 2:7) = nan; + for ndx = firstPreTrialNdx:size(curPIori,1) + curPIori(ndx,ptLengthColLog) = sqrt((curPIori(ndx,tailXcolLog) - curPIori(ndx,portXcolLog))^2 + (curPIori(ndx,tailYcolLog) - curPIori(ndx,portYcolLog))^2); + curPIori(ndx,hpLengthColLog) = sqrt((curPIori(ndx,portXcolLog) - curPIori(ndx,headXcolLog))^2 + (curPIori(ndx,portYcolLog) - curPIori(ndx,headYcolLog))^2); + curPIori(ndx,htLengthColLog) = sqrt((curPIori(ndx,tailXcolLog) - curPIori(ndx,headXcolLog))^2 + (curPIori(ndx,tailYcolLog) - curPIori(ndx,headYcolLog))^2); + curPIori(ndx,headAngleColLog) = rad2deg(acos((curPIori(ndx,htLengthColLog)^2 + curPIori(ndx,hpLengthColLog)^2 - curPIori(ndx,ptLengthColLog)^2)/(2*curPIori(ndx,htLengthColLog)*curPIori(ndx,hpLengthColLog)))); + curPIori(ndx,portAngleColLog) = rad2deg(acos((curPIori(ndx,ptLengthColLog)^2 + curPIori(ndx,hpLengthColLog)^2 - curPIori(ndx,htLengthColLog)^2)/(2*curPIori(ndx,ptLengthColLog)*curPIori(ndx,hpLengthColLog)))); + curPIori(ndx,tailAngleColLog) = rad2deg(acos((curPIori(ndx,htLengthColLog)^2 + curPIori(ndx,ptLengthColLog)^2 - curPIori(ndx,hpLengthColLog)^2)/(2*curPIori(ndx,htLengthColLog)*curPIori(ndx,ptLengthColLog)))); + end + curPOori = pokeOutOrientation{trl}; + lastTrialNdx = find(~isnan(curPOori(:,headAngleColLog)),1,'last'); + curPOori(lastTrialNdx+1:end, 2:7) = nan; + for ndx = 1:lastTrialNdx + curPOori(ndx,ptLengthColLog) = sqrt((curPOori(ndx,tailXcolLog) - curPOori(ndx,portXcolLog))^2 + (curPOori(ndx,tailYcolLog) - curPOori(ndx,portYcolLog))^2); + curPOori(ndx,hpLengthColLog) = sqrt((curPOori(ndx,portXcolLog) - curPOori(ndx,headXcolLog))^2 + (curPOori(ndx,portYcolLog) - curPOori(ndx,headYcolLog))^2); + curPOori(ndx,htLengthColLog) = sqrt((curPOori(ndx,tailXcolLog) - curPOori(ndx,headXcolLog))^2 + (curPOori(ndx,tailYcolLog) - curPOori(ndx,headYcolLog))^2); + curPOori(ndx,headAngleColLog) = rad2deg(acos((curPOori(ndx,htLengthColLog)^2 + curPOori(ndx,hpLengthColLog)^2 - curPOori(ndx,ptLengthColLog)^2)/(2*curPOori(ndx,htLengthColLog)*curPOori(ndx,hpLengthColLog)))); + curPOori(ndx,portAngleColLog) = rad2deg(acos((curPOori(ndx,ptLengthColLog)^2 + curPOori(ndx,hpLengthColLog)^2 - curPOori(ndx,htLengthColLog)^2)/(2*curPOori(ndx,ptLengthColLog)*curPOori(ndx,hpLengthColLog)))); + curPOori(ndx,tailAngleColLog) = rad2deg(acos((curPOori(ndx,htLengthColLog)^2 + curPOori(ndx,ptLengthColLog)^2 - curPOori(ndx,hpLengthColLog)^2)/(2*curPOori(ndx,htLengthColLog)*curPOori(ndx,ptLengthColLog)))); + end + + htVal(curPosNdx) = sqrt((curTailX - curHeadX)^2 + (curTailY - curHeadY)^2); + hpVal(curPosNdx) = sqrt((curPortX - curHeadX)^2 + (curPortY - curHeadY)^2); + ptVal(curPosNdx) = sqrt((curTailX - curPortX)^2 + (curTailY - curPortY)^2); + + pokeInOrientationInterp{trl} = curPIori; + pokeOutOrientationInterp{trl} = curPOori; +end +% Now bin the orientation data +orientBinValsPI = cell(size(pokeInOrientationInterp)); +orientBinValsPO = cell(size(pokeOutOrientationInterp)); +for trl = 1:length(pokeInOrientation) + curPIori = pokeInOrientationInterp{trl}; + tempPIndxVals = nan(size(curPIori,1),2); + for piT = 1:size(curPIori,1) + if ~isnan(curPIori(piT,headXcolLog)) + tempPIndxVals(piT,1) = sub2ind([length(headYbins)-1 length(headXbins)-1], find(curPIori(piT,headYcolLog)>=headYbins,1,'last'), find(curPIori(piT,headXcolLog)>=headXbins,1,'last')); + tempPIndxVals(piT,2) = sub2ind([length(tailYbins)-1 length(tailXbins)-1], find(curPIori(piT,tailYcolLog)>=tailYbins,1,'last'), find(curPIori(piT,tailXcolLog)>=tailXbins,1,'last')); + end + end + curPOori = pokeOutOrientationInterp{trl}; + tempPOndxVals = nan(size(curPOori,1),2); + for poT = 1:size(curPOori,1) + if ~isnan(curPOori(poT,headXcolLog)) + tempPOndxVals(poT,1) = sub2ind([length(headYbins)-1 length(headXbins)-1], find(curPOori(poT,headYcolLog)>=headYbins,1,'last'), find(curPOori(poT,headXcolLog)>=headXbins,1,'last')); + tempPOndxVals(poT,2) = sub2ind([length(tailYbins)-1 length(tailXbins)-1], find(curPOori(poT,tailYcolLog)>=tailYbins,1,'last'), find(curPOori(poT,tailXcolLog)>=tailXbins,1,'last')); + end + end + orientBinValsPI{trl} = tempPIndxVals; + orientBinValsPO{trl} = tempPOndxVals; +end +pokeInOrientISC = cell2mat(reshape(pokeInOrientationInterp(trialLog), [1,1,sum(trialLog)])); +pokeOutOrientISC = cell2mat(reshape(pokeOutOrientationInterp(trialLog), [1,1,sum(trialLog)])); + +pokeInOrientBinsISC = cell2mat(reshape(orientBinValsPI(trialLog), [1,1,sum(trialLog)])); +pokeOutOrientBinsISC = cell2mat(reshape(orientBinValsPO(trialLog), [1,1,sum(trialLog)])); + +trialOrientBinsISC = [pokeInOrientBinsISC; pokeOutOrientBinsISC]; + +fValsPI = cell(4,length(ensembleUnitSummaries)); +fValsPO = cell(4,length(ensembleUnitSummaries)); + +%% Calculate each unit's FR map and positional firing rates and such... +for uni = 1:length(goodUniNames) + curUniFR = [pokeInFRisc(:,uni,:); pokeOutFRisc(:,uni,:)]; + tempHeadFRmap = nan(length(headYbins)-1, length(headXbins)-1); + for headNdx = 1:((length(headXbins)-1)*(length(headYbins)-1)) + tempHeadFRmap(headNdx) = mean(curUniFR(trialOrientBinsISC(:,1,:)==headNdx)); + end + tempTailFRmap = nan(length(tailYbins)-1, length(tailXbins)-1); + for tailNdx = 1:((length(tailXbins)-1)*(length(tailYbins)-1)) + tempTailFRmap(tailNdx) = mean(curUniFR(trialOrientBinsISC(:,2,:)==tailNdx)); + end + + figure; + sp1 = subplot(1,2,1); + imagesc(tempHeadFRmap) + set(gca, 'ydir', 'normal'); + title('Head Firing Rate Map'); + cb = colorbar('southoutside'); + cb.Label.String = 'Mean Firing Rate (spk/s)'; + z = colormap('jet'); + z(1,:) = [1 1 1]; + colormap(z); + set(gca, 'clim', [-0.01, max(get(gca, 'clim'))]); + sp2 = subplot(1,2,2); + imagesc(tempTailFRmap); + set(gca, 'ydir', 'normal'); + title('Tail Firing Rate Map'); + cb = colorbar('southoutside'); + cb.Label.String = 'Mean Firing Rate (spk/s)'; + colormap(z); + set(sp1, 'clim', [-0.01, max([get(sp1, 'clim'), get(sp2, 'clim')])]); + set(sp2, 'clim', [-0.01, max([get(sp1, 'clim'), get(sp2, 'clim')])]); + annotation('textbox', [0.05 0.9 0.9 0.1], 'String', goodUniNames{uni}, 'linestyle', 'none', 'FontSize', 20); + annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('%s Spatial Bin = %.02fmm Gaussian = %.02fms Number of Permutations = %i', seqType, spatialBinSize*1.7, slideWindowSize, numPerms), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); + annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); + + orient(gcf, 'tall'); + orient(gcf, 'landscape'); + print('-painters', gcf, '-dpdf', sprintf('%s_FiringRateLocationMaps', goodUniNames{uni})); + + %*****************Make these figures broken down by sequence position + % Then do a comparison of FR maps across sequence position to look for + % modifications in FR maps by sequence position. +end + +%% Run Sliding F-Ratio Analysis +for uni = 1:length(goodUniNames) + curUniPokeInFR = reshape(pokeInFRisc(:,uni,:), [size(pokeInFRisc,1), size(pokeInFRisc,3), 1]); + curUniPokeOutFR = reshape(pokeOutFRisc(:,uni,:), [size(pokeOutFRisc,1), size(pokeOutFRisc,3), 1]); + + % Poke In Oriented + [curUniPIfvalPOS, curUniPIfvalPOSz] = SlidingFvalCalc(curUniPokeInFR, posIDsISC, numPerms); + fValsPI{1,uni} = curUniPIfvalPOSz; + [curUniPIfvalHeadLoc, curUniPIfvalHeadLocZ] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientBinsISC(:,1,:), [size(pokeInOrientBinsISC,1), size(pokeInOrientBinsISC,3), 1]), numPerms); + fValsPI{2,uni} = curUniPIfvalHeadLocZ; + [curUniPIfvalTailLoc, curUniPIfvalTailLocZ] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientBinsISC(:,2,:), [size(pokeInOrientBinsISC,1), size(pokeInOrientBinsISC,3), 1]), numPerms); + fValsPI{3,uni} = curUniPIfvalTailLocZ; + + [curUniPIfvalInteract, curUniPIfvalInteractZ] = SlidingFvalCalcInteract(curUniPokeInFR, posIDsISC,... + reshape(pokeInOrientBinsISC(:,1,:), [size(pokeInOrientBinsISC,1), size(pokeInOrientBinsISC,3), 1]),... + reshape(pokeInOrientBinsISC(:,2,:), [size(pokeInOrientBinsISC,1), size(pokeInOrientBinsISC,3), 1]),... + numPerms); + fValsPI{4,uni} = curUniPIfvalInteractZ; + + + % + % [curUniPIfvalHeadX, curUniPIfvalHeadXz] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,headXcolLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % [curUniPIfvalHeadY, curUniPIfvalHeadYz] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,headYcolLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % + % [curUniPIfvalTailX, curUniPIfvalTailXz] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,tailXcolLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % [curUniPIfvalTailY, curUniPIfvalTailYz] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,tailYcolLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % + % [curUniPIfvalPortAngle, curUniPIfvalPortAnglez] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,portAngleColLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % [curUniPIfvalHeadAngle, curUniPIfvalHeadAnglez] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,headAngleColLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % [curUniPIfvalTailAngle, curUniPIfvalTailAnglez] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,tailAngleColLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % + % [curUniPIfvalHeadTailDist, curUniPIfvalHeadTailDistZ] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,htLengthColLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % [curUniPIfvalHeadPortDist, curUniPIfvalHeadPortDistZ] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,hpLengthColLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % [curUniPIfvalTailPortDist, curUniPIfvalTailPortDistZ] = SlidingFvalCalc(curUniPokeInFR, reshape(pokeInOrientISC(:,ptLengthColLog,:), [size(pokeInOrientISC,1), size(pokeInOrientISC,3), 1]), numPerms); + % + % Poke Out Oriented + [curUniPOfvalPOS, curUniPOfvalPOSz] = SlidingFvalCalc(curUniPokeOutFR, posIDsISC, numPerms); + fValsPO{1,uni} = curUniPOfvalPOSz; + [curUniPOfvalHeadLoc, curUniPOfvalHeadLocZ] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientBinsISC(:,1,:), [size(pokeOutOrientBinsISC,1), size(pokeOutOrientBinsISC,3), 1]), numPerms); + fValsPO{2,uni} = curUniPOfvalHeadLocZ; + [curUniPOfvalTailLoc, curUniPOfvalTailLocZ] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientBinsISC(:,2,:), [size(pokeOutOrientBinsISC,1), size(pokeOutOrientBinsISC,3), 1]), numPerms); + fValsPO{3,uni} = curUniPOfvalTailLocZ; + + [curUniPOfvalInteract, curUniPOfvalInteractZ] = SlidingFvalCalcInteract(curUniPokeOutFR, posIDsISC,... + reshape(pokeOutOrientBinsISC(:,1,:), [size(pokeOutOrientBinsISC,1), size(pokeOutOrientBinsISC,3), 1]),... + reshape(pokeOutOrientBinsISC(:,2,:), [size(pokeOutOrientBinsISC,1), size(pokeOutOrientBinsISC,3), 1]),... + numPerms); + fValsPO{4,uni} = curUniPOfvalInteractZ; + % + % [curUniPOfvalHeadX, curUniPOfvalHeadXz] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,headXcolLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % [curUniPOfvalHeadY, curUniPOfvalHeadYz] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,headYcolLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % + % [curUniPOfvalTailX, curUniPOfvalTailXz] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,tailXcolLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % [curUniPOfvalTailY, curUniPOfvalTailYz] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,tailYcolLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % + % [curUniPOvalPortAngle, curUniPOfvalPortAnglez] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,portAngleColLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % [curUniPOfvalHeadAngle, curUniPOfvalHeadAnglez] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,headAngleColLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % [curUniPOfvalTailAngle, curUniPOfvalTailAnglez] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,tailAngleColLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % + % [curUniPOfvalHeadTailDist, curUniPOfvalHeadTailDistZ] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,htLengthColLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % [curUniPOfvalHeadPortDist, curUniPOfvalHeadPortDistZ] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,hpLengthColLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % [curUniPOfvalTailPortDist, curUniPOfvalTailPortDistZ] = SlidingFvalCalc(curUniPokeOutFR, reshape(pokeOutOrientISC(:,ptLengthColLog,:), [size(pokeOutOrientISC,1), size(pokeOutOrientISC,3), 1]), numPerms); + % + figure; + sp1 = subplot(2,1,1); + plot(pokeInTSs, curUniPIfvalPOSz,'linewidth', 2); + hold on; + plot(pokeInTSs, curUniPIfvalHeadLocZ, 'k'); + plot(pokeInTSs, curUniPIfvalTailLocZ, '--k'); + plot(pokeInTSs, curUniPIfvalInteractZ, 'r'); + % plot(pokeInTSs, curUniPIfvalHeadXz, 'k'); + % plot(pokeInTSs, curUniPIfvalHeadYz, '--k'); + % plot(pokeInTSs, curUniPIfvalTailXz, 'r'); + % plot(pokeInTSs, curUniPIfvalTailYz, '--r'); + % plot(pokeInTSs, curUniPIfvalPortAnglez, 'g'); + % plot(pokeInTSs, curUniPIfvalHeadAnglez, '--g'); + % plot(pokeInTSs, curUniPIfvalTailAnglez, '.g'); + % plot(pokeInTSs, curUniPIfvalHeadTailDistZ, 'c'); + % plot(pokeInTSs, curUniPIfvalHeadPortDistZ, '--c'); + % plot(pokeInTSs, curUniPIfvalTailPortDistZ, '.c'); + title('Poke In Aligned') + axis tight + legend('Sequence Position', 'Head', 'Tail', 'Interaction', 'location', 'best'); + % legend('Sequence Position', 'Head Loc X', 'Head Loc Y', 'Tail Loc X', 'Tail Loc Y', 'Port Angle', 'Head Angle', 'Tail Angle', 'Head-Tail', 'Head-Port', 'Tail-Port', 'location', 'best'); + + sp2 = subplot(2,1,2); + plot(pokeOutTSs, curUniPOfvalPOSz, 'linewidth', 2); + hold on; + plot(pokeOutTSs, curUniPOfvalHeadLocZ, 'k'); + plot(pokeOutTSs, curUniPOfvalTailLocZ, '--k'); + plot(pokeOutTSs, curUniPOfvalInteractZ, 'r'); + % plot(pokeOutTSs, curUniPOfvalHeadXz, 'k'); + % plot(pokeOutTSs, curUniPOfvalHeadYz, '--k'); + % plot(pokeOutTSs, curUniPOfvalTailXz, 'r'); + % plot(pokeOutTSs, curUniPOfvalTailYz, '--r'); + % plot(pokeOutTSs, curUniPOfvalPortAnglez, 'g'); + % plot(pokeOutTSs, curUniPOfvalHeadAnglez, '--g'); + % plot(pokeOutTSs, curUniPOfvalTailAnglez, '.g'); + % plot(pokeOutTSs, curUniPOfvalHeadTailDistZ, 'c'); + % plot(pokeOutTSs, curUniPOfvalHeadPortDistZ, '--c'); + % plot(pokeOutTSs, curUniPOfvalTailPortDistZ, '.c'); + title('Poke Out Aligned'); + axis tight + + linkaxes([sp1, sp2], 'y'); + annotation('textbox', [0.05 0.9 0.9 0.1], 'String', goodUniNames{uni}, 'linestyle', 'none', 'FontSize', 20); + annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('%s Spatial Bin = %.02fmm Gaussian = %.02fms Number of Permutations = %i', seqType, spatialBinSize*1.7, slideWindowSize, numPerms), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); + annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); + + orient(gcf, 'tall'); + orient(gcf, 'landscape'); + % print + print('-painters', gcf, '-dpdf', sprintf('%s_OrientFvalInfo_Summary', goodUniNames{uni})); +end + +%% Now summarize the population data +% Row 1 = Position vs Head Location +% Row 2 = Position vs Tail Location +% Row 3 = Head vs Tail Location +piCorr = nan(3,length(goodUniNames)); +poCorr = nan(3,length(goodUniNames)); +allCorr = nan(3,length(goodUniNames)); +for uni = 1:length(goodUniNames) + curPIcorr = corr(cell2mat(fValsPI(:,uni))'); + piCorr(1,uni) = curPIcorr(2,1); + piCorr(2,uni) = curPIcorr(3,1); + piCorr(3,uni) = curPIcorr(3,2); + + curPOcorr = corr(cell2mat(fValsPO(:,uni))'); + poCorr(1,uni) = curPOcorr(2,1); + poCorr(2,uni) = curPOcorr(3,1); + poCorr(3,uni) = curPOcorr(3,2); + + curAllCorr = corr([cell2mat(fValsPI(:,uni)), cell2mat(fValsPO(:,uni))]'); + allCorr(1,uni) = curAllCorr(2,1); + allCorr(2,uni) = curAllCorr(3,1); + allCorr(3,uni) = curAllCorr(3,2); +end +figure; +sp1 = subplot(3,3,1); +histogram(piCorr(1,:), -1:0.1:1); +hold on; +line(gca, [nanmean(piCorr(1,:)) nanmean(piCorr(1,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PI: Position vs. Head'); +sp2 = subplot(3,3,2); +histogram(piCorr(2,:), -1:0.1:1); +hold on; +line(gca, [nanmean(piCorr(2,:)) nanmean(piCorr(2,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PI: Position vs. Tail'); +sp3 = subplot(3,3,3); +histogram(piCorr(3,:), -1:0.1:1); +hold on; +line(gca, [nanmean(piCorr(3,:)) nanmean(piCorr(3,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PI: Head vs. Tail'); +sp4 = subplot(3,3,4); +histogram(poCorr(1,:), -1:0.1:1); +hold on; +line(gca, [nanmean(poCorr(1,:)) nanmean(poCorr(1,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PO: Position vs. Head'); +sp5 = subplot(3,3,5); +histogram(poCorr(2,:), -1:0.1:1); +hold on; +line(gca, [nanmean(poCorr(2,:)) nanmean(poCorr(2,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PO: Position vs. Tail'); +sp6 = subplot(3,3,6); +histogram(poCorr(3,:), -1:0.1:1); +hold on; +line(gca, [nanmean(poCorr(3,:)) nanmean(poCorr(3,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PO: Head vs. Tail'); +sp7 = subplot(3,3,7); +histogram(allCorr(1,:), -1:0.1:1); +hold on; +line(gca, [nanmean(allCorr(1,:)) nanmean(allCorr(1,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('All: Position vs. Head'); +sp8 = subplot(3,3,8); +histogram(allCorr(2,:), -1:0.1:1); +hold on; +line(gca, [nanmean(allCorr(2,:)) nanmean(allCorr(2,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('All: Position vs. Tail'); +sp9 = subplot(3,3,9); +histogram(allCorr(3,:), -1:0.1:1); +hold on; +line(gca, [nanmean(allCorr(3,:)) nanmean(allCorr(3,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('All: Head vs. Tail'); + +linkaxes([sp1, sp2, sp2, sp3, sp4, sp5, sp6, sp7, sp8, sp9], 'y'); + +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +annotation('textbox', [0.05 0.9 0.9 0.1], 'String', 'All Timepoints', 'linestyle', 'none', 'FontSize', 20); +annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('%s Spatial Bin = %.02fmm Gaussian = %.02fms Number of Permutations = %i', seqType, spatialBinSize*1.7, slideWindowSize, numPerms), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +print('-painters', gcf, '-dpdf', 'LocationVsPositionCorrelationSummary(All)'); +%% Now run a thresholded version +% Row 1 = Position vs Head Location +% Row 2 = Position vs Tail Location +% Row 3 = Head vs Tail Location +piCorr = nan(3,length(goodUniNames)); +poCorr = nan(3,length(goodUniNames)); +allCorr = nan(3,length(goodUniNames)); +for uni = 1:length(goodUniNames) + curPIphCorr = corrcoef(fValsPI{1,uni}(fValsPI{1,uni}>1 | fValsPI{2,uni}>1), fValsPI{2,uni}(fValsPI{1,uni}>1 | fValsPI{2,uni}>1)); + piCorr(1,uni) = curPIphCorr(2,1); + curPIptCorr = corrcoef(fValsPI{1,uni}(fValsPI{1,uni}>1 | fValsPI{3,uni}>1), fValsPI{3,uni}(fValsPI{1,uni}>1 | fValsPI{3,uni}>1)); + piCorr(2,uni) = curPIptCorr(2,1); + curPIhtCorr = corrcoef(fValsPI{2,uni}(fValsPI{2,uni}>1 | fValsPI{3,uni}>1), fValsPI{3,uni}(fValsPI{2,uni}>1 | fValsPI{3,uni}>1)); + piCorr(3,uni) = curPIhtCorr(2,1); + + curPOphCorr = corrcoef(fValsPO{1,uni}(fValsPO{1,uni}>1 | fValsPO{2,uni}>1), fValsPO{2,uni}(fValsPO{1,uni}>1 | fValsPO{2,uni}>1)); + poCorr(1,uni) = curPOphCorr(2,1); + curPOptCorr = corrcoef(fValsPO{1,uni}(fValsPO{1,uni}>1 | fValsPO{3,uni}>1), fValsPO{3,uni}(fValsPO{1,uni}>1 | fValsPO{3,uni}>1)); + poCorr(2,uni) = curPOptCorr(2,1); + curPOhtCorr = corrcoef(fValsPO{2,uni}(fValsPO{2,uni}>1 | fValsPO{3,uni}>1), fValsPO{3,uni}(fValsPO{2,uni}>1 | fValsPO{3,uni}>1)); + poCorr(3,uni) = curPOhtCorr(2,1); + + curAllPosF = [fValsPI{1,uni}, fValsPO{1,uni}]; + curAllHeadF = [fValsPI{2,uni}, fValsPO{2,uni}]; + curAllTailF = [fValsPI{3,uni}, fValsPO{3,uni}]; + curALLphCorr = corrcoef(curAllPosF(curAllPosF>1 | curAllHeadF>1), curAllHeadF(curAllPosF>1 | curAllHeadF>1)); + allCorr(1,uni) = curALLphCorr(2,1); + curALLptCorr = corrcoef(curAllPosF(curAllPosF>1 | curAllTailF>1), curAllTailF(curAllPosF>1 | curAllTailF>1)); + allCorr(2,uni) = curALLptCorr(2,1); + curALLhtCorr = corrcoef(curAllHeadF(curAllHeadF>1 | curAllTailF>1), curAllTailF(curAllHeadF>1 | curAllTailF>1)); + allCorr(3,uni) = curALLhtCorr(2,1); + +end +figure; +sp1 = subplot(3,3,1); +histogram(piCorr(1,:), -1:0.1:1); +hold on; +line(gca, [nanmean(piCorr(1,:)) nanmean(piCorr(1,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PI: Position vs. Head'); +sp2 = subplot(3,3,2); +histogram(piCorr(2,:), -1:0.1:1); +hold on; +line(gca, [nanmean(piCorr(2,:)) nanmean(piCorr(2,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PI: Position vs. Tail'); +sp3 = subplot(3,3,3); +histogram(piCorr(3,:), -1:0.1:1); +hold on; +line(gca, [nanmean(piCorr(3,:)) nanmean(piCorr(3,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PI: Head vs. Tail'); +sp4 = subplot(3,3,4); +histogram(poCorr(1,:), -1:0.1:1); +hold on; +line(gca, [nanmean(poCorr(1,:)) nanmean(poCorr(1,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PO: Position vs. Head'); +sp5 = subplot(3,3,5); +histogram(poCorr(2,:), -1:0.1:1); +hold on; +line(gca, [nanmean(poCorr(2,:)) nanmean(poCorr(2,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PO: Position vs. Tail'); +sp6 = subplot(3,3,6); +histogram(poCorr(3,:), -1:0.1:1); +hold on; +line(gca, [nanmean(poCorr(3,:)) nanmean(poCorr(3,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('PO: Head vs. Tail'); +sp7 = subplot(3,3,7); +histogram(allCorr(1,:), -1:0.1:1); +hold on; +line(gca, [nanmean(allCorr(1,:)) nanmean(allCorr(1,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('All: Position vs. Head'); +sp8 = subplot(3,3,8); +histogram(allCorr(2,:), -1:0.1:1); +hold on; +line(gca, [nanmean(allCorr(2,:)) nanmean(allCorr(2,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('All: Position vs. Tail'); +sp9 = subplot(3,3,9); +histogram(allCorr(3,:), -1:0.1:1); +hold on; +line(gca, [nanmean(allCorr(3,:)) nanmean(allCorr(3,:))], get(gca, 'ylim'), 'color','r', 'linewidth', 2); +title('All: Head vs. Tail'); + +linkaxes([sp1, sp2, sp2, sp3, sp4, sp5, sp6, sp7, sp8, sp9], 'y'); + +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +annotation('textbox', [0.05 0.9 0.9 0.1], 'String', 'Threshold Fz>1', 'linestyle', 'none', 'FontSize', 20); +annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('%s Spatial Bin = %.02fmm Gaussian = %.02fms Number of Permutations = %i', seqType, spatialBinSize*1.7, slideWindowSize, numPerms), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +print('-painters', gcf, '-dpdf', 'LocationVsPositionCorrelationSummary(Thresholded)'); +%% Examine the relationship between the peak FR and peak IC +fVals = cellfun(@(a,b)[a,b], fValsPI, fValsPO, 'uniformoutput', 0); +frMean = [mean(pokeInFRisc,3); mean(pokeOutFRisc,3)]; +fvMaxNdx = nan(3,length(goodUniNames)); +frMaxNdx = nan(1,length(goodUniNames)); +for uni = 1:length(goodUniNames) + fvMaxNdx(1,uni) = find(fVals{1,uni}==max(fVals{1,uni}),1,'first'); + fvMaxNdx(2,uni) = find(fVals{2,uni}==max(fVals{2,uni}),1,'first'); + fvMaxNdx(3,uni) = find(fVals{3,uni}==max(fVals{3,uni}),1,'first'); + frMaxNdx(uni) = find(frMean(:,uni)==max(frMean(:,uni)),1,'first'); +end + +figure; +subplot(1,3,1) +corrScatPlot(fvMaxNdx(1,:)', frMaxNdx', 'Index of Max Seq Pos Info', 'Index of Max Firing Rate', []); +subplot(1,3,2) +corrScatPlot(fvMaxNdx(2,:)', frMaxNdx', 'Index of Max Head Loc Info', 'Index of Max Firing Rate', []); +subplot(1,3,3) +corrScatPlot(fvMaxNdx(3,:)', frMaxNdx', 'Index of Max Tail Loc Info', 'Index of Max Firing Rate', []); + +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +annotation('textbox', [0.05 0.9 0.9 0.1], 'String', 'FR vs FZ correlation', 'linestyle', 'none', 'FontSize', 20); +annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('%s Spatial Bin = %.02fmm Gaussian = %.02fms Number of Permutations = %i', seqType, spatialBinSize*1.7, slideWindowSize, numPerms), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +print('-painters', gcf, '-dpdf', 'FzVsFRcorr'); + +figure; +BarPlotErrorbars([mean(abs(fvMaxNdx(1,:) - frMaxNdx)), mean(abs(fvMaxNdx(2,:) - frMaxNdx)), mean(abs(fvMaxNdx(3,:) - frMaxNdx))],... + [std(fvMaxNdx(1,:) - frMaxNdx)/sqrt(length(goodUniNames)-1), std(fvMaxNdx(2,:) - frMaxNdx)/sqrt(length(goodUniNames)-1), std(fvMaxNdx(3,:) - frMaxNdx)/sqrt(length(goodUniNames)-1)]); +set(gca, 'xticklabel', {'Position', 'Head', 'Tail'}); +title('Temporal Difference From Max Firing Rate'); +ylabel('Time (ms)'); + +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +annotation('textbox', [0.2 0.9 0.8 0.1], 'String', sprintf('%s Spatial Bin = %.02fmm Gaussian = %.02fms Number of Permutations = %i', seqType, spatialBinSize*1.7, slideWindowSize, numPerms), 'HorizontalAlignment', 'right', 'linestyle', 'none', 'FontSize', 12); +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string', sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +print('-painters', gcf, '-dpdf', 'PeakInfoFiringRateLatency'); +%% +function [fVectRaw, fVectZ] = SlidingFvalCalc(curUniFR, idVect, numPerms) +% UniFR here is organized as a 2-D matrix where each column is a trial and +% each row is a timepoint. +if size(idVect,1) == 1 + idVect = repmat(idVect, [size(curUniFR,1),1]); +end + +fVectRaw = nan(1,size(curUniFR,1)); +parfor t = 1:size(curUniFR,1) + [~,table,~] = anova1(curUniFR(t,:)', idVect(t,:), 'off'); + if ~isempty(table{2,5}) + fVectRaw(t) = table{2,5}; + else + fVectRaw(t) = 1; + end +end +fVectRaw(isnan(fVectRaw)) = 1; +fVectPerm = nan(numPerms, size(curUniFR,1)); +for r = 1:numPerms + idVectShflVect = randperm(size(idVect,2)); + idVectShfl = idVect(:,idVectShflVect); + parfor t = 1:size(curUniFR,1) + [~,tableRND,~] = anova1(curUniFR(t,:)', idVectShfl(t,:), 'off'); + if ~isempty(tableRND{2,5}) + fVectPerm(r,t) = tableRND{2,5}; + else + fVectPerm(r,t) = 1; + end + end +end +fVectPerm(isnan(fVectPerm)) = 1; +fVectZ = nan(1,size(curUniFR,1)); +for t = 1:size(curUniFR,1) + tempZ = zscore([fVectRaw(t); fVectPerm(:,t)]); + fVectZ(t) = tempZ(1); +end + +end + +%% +function [fVectRaw, fVectZ] = SlidingFvalCalcInteract(curUniFR, idVect1, idVect2, idVect3, numPerms) +if size(idVect1,1) == 1 + idVect1 = repmat(idVect1, [size(curUniFR,1),1]); +end +if size(idVect2,1) == 1 + idVect2 = repmat(idVect2, [size(curUniFR,1),1]); +end +if size(idVect3,1) == 1 + idVect3 = repmat(idVect3, [size(curUniFR,1),1]); +end + +fVectRaw = nan(1,size(curUniFR,1)); +parfor t = 1:size(curUniFR,1) + if mean(isnan(idVect3(t,:)))>0.5 || mean(isnan(idVect2(t,:)))>0.5 || mean(isnan(idVect3(t,:)))>0.5 + continue; + else + [~,table,~] = anovan(curUniFR(t,:)', {idVect1(t,:), idVect2(t,:), idVect3(t,:)}, 'model', [1 1 1], 'sstype', 'h', 'display', 'off') + if ~isempty(table{2,5}) + fVectRaw(t) = table{2,6}; + else + fVectRaw(t) = 1; + end + end +end +fVectRaw(isnan(fVectRaw)) = 1; +fVectPerm = nan(numPerms, size(curUniFR,1)); +for r = 1:numPerms + idVect1ShflVect = randperm(size(idVect1,2)); + idVect1Shfl = idVect1(:,idVect1ShflVect); + idVect2ShflVect = randperm(size(idVect2,2)); + idVect2Shfl = idVect2(:,idVect2ShflVect); + idVect3ShflVect = randperm(size(idVect3,2)); + idVect3Shfl = idVect1(:,idVect3ShflVect); + parfor t = 1:size(curUniFR,1) + if mean(isnan(idVect1Shfl(t,:)))>0.5 || mean(isnan(idVect2Shfl(t,:)))>0.5 || mean(isnan(idVect3Shfl(t,:)))>0.5 + continue; + else + [~,table,~] = anovan(curUniFR(t,:)', {idVect1Shfl(t,:), idVect2Shfl(t,:), idVect3Shfl(t,:)}, 'model', [1 1 1], 'sstype', 'h', 'display', 'off') + if ~isempty(table{2,5}) + fVectPerm(r,t) = table{2,6}; + else + fVectPerm(r,t) = 1; + end + end + end +end +fVectPerm(isnan(fVectPerm)) = 1; +fVectZ = nan(1,size(curUniFR,1)); +for t = 1:size(curUniFR,1) + tempZ = zscore([fVectRaw(t); fVectPerm(:,t)]); + fVectZ(t) = tempZ(1); +end + +end \ No newline at end of file diff --git a/Analyses/Prototypes/BayesPFCbsPROTO.m b/Analyses/Prototypes/BayesPFCbsPROTO.m new file mode 100644 index 0000000..74d0e4a --- /dev/null +++ b/Analyses/Prototypes/BayesPFCbsPROTO.m @@ -0,0 +1,341 @@ +%% +clc +clear all + +%% Runtime variables +binSize = 50; +dsRate = 5; + +%% +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Extract Behavioral Periods +% Taking 1/2 the binSize on either end to get rid of edge effects. +trialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0-(binSize/2/1000) 1.2+(binSize/2/1000)], 'PokeIn'); +% trialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [-1.5-(binSize/2/1000) 0.5+(binSize/2/1000)], 'PokeOut'); +trialEnsemble = ExtractTrialData_SM(trialPeriodTD, ensembleMatrix(:,2:end)); %#ok<*NODEF> +trialEnsembleMtx = cell2mat(reshape(trialEnsemble, [1 1 length(trialEnsemble)])); + +trialTimes = behavMatrix(trialPeriodTD(1).TrialLogVect,1) - behavMatrix(trialPeriodTD(1).PokeInIndex,1); +% trialTimes = behavMatrix(trialPeriodTD(1).TrialLogVect,1) - behavMatrix(trialPeriodTD(1).PokeOutIndex,1); + +clear behavMatrix ensembleMatrix +%% Bin the spiking data +% First convolve the entire trialEnsembleMtx with a square to bin the +% spikes +binnedEnsembleMtx = nan(size(trialEnsembleMtx)); +for t = 1:size(trialEnsembleMtx,3) + for u = 1:size(trialEnsembleMtx,2) + binnedEnsembleMtx(:,u,t) = conv(trialEnsembleMtx(:,u,t), ones(1,binSize)./(binSize/1000), 'same'); +% binnedEnsembleMtx(:,u,t) = conv(trialEnsembleMtx(:,u,t), ones(1,binSize), 'same'); + end +end +% Now remove the binSize/2 padding +unPaddedBinnedEnsembleMtx = binnedEnsembleMtx((binSize/2)+1:end-(binSize/2),:,:); +trialTimes = trialTimes((binSize/2)+1:end-(binSize/2)); +% Now downsample the binned matrix +dsVect = downsample(1:size(unPaddedBinnedEnsembleMtx,1), dsRate); +spikeMatrix = unPaddedBinnedEnsembleMtx(dsVect,:,:); +trialTime = trialTimes(dsVect); + +clear trialEnsembleMtx binnedEnsembleMtx unPaddedBinnedEnsembleMtx +%% Create Logical Vectors +perfLog = [trialPeriodTD.Performance]; +inSeqLog = [trialPeriodTD.TranspositionDistance]==0; +outSeqLog = [trialPeriodTD.TranspositionDistance]~=0 & abs([trialPeriodTD.TranspositionDistance])<10; +odorAlog = [trialPeriodTD.Odor] == 1; +odorBlog = [trialPeriodTD.Odor] == 2; +odorClog = [trialPeriodTD.Odor] == 3; +odorDlog = [trialPeriodTD.Odor] == 4; + +fullInSeqSeqsStart = find(conv([trialPeriodTD.Odor], 1:4, 'valid')==20 & conv([trialPeriodTD.Position], 1:4, 'valid')==20 & conv([trialPeriodTD.Performance]*1, ones(1,4), 'valid')==4); +inSeqSeqs = nan(3,length(fullInSeqSeqsStart)); +for iS = 1:length(fullInSeqSeqsStart) + inSeqSeqs(1,iS) = fullInSeqSeqsStart(iS); + inSeqSeqs(2,iS) = fullInSeqSeqsStart(iS) + 1; + inSeqSeqs(3,iS) = fullInSeqSeqsStart(iS) + 2; + inSeqSeqs(4,iS) = fullInSeqSeqsStart(iS) + 3; +end +fullInSeqLog = false(1,length(trialPeriodTD)); +fullInSeqLog(inSeqSeqs(:)) = true; + +nonAIStrialData = trialPeriodTD(perfLog & inSeqLog & ~fullInSeqLog); +%% +uniFRthreshLog = max(mean(spikeMatrix,3))<1; +spkMtx = spikeMatrix; +spkMtx(:,uniFRthreshLog,:) = []; +goodUniNames = {ensembleUnitSummaries(~uniFRthreshLog).UnitName}; + +clear spikeMatrix +%% Decode Trial Time Across Odors +figure; +corrAisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorAlog),3); % All A InSeq Correct Trials +[postAnorm, postAraw] = CalculatePostProb(corrAisMtx, spkMtx(:,:,perfLog & inSeqLog & odorAlog & ~fullInSeqLog), binSize); +subplot(2,2,1); +aCaxis = PlotPostMtx(trialTimes, postAnorm, 'Odor A'); + +corrBisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorBlog),3); % All B InSeq Correct Trials +[postBnorm, postBraw] = CalculatePostProb(corrBisMtx, spkMtx(:,:,perfLog & inSeqLog & odorBlog & ~fullInSeqLog), binSize); +subplot(2,2,2); +bCaxis = PlotPostMtx(trialTimes, postBnorm, 'Odor B'); + +corrCisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorClog),3); % All C InSeq Correct Trials +[postCnorm, postCraw] = CalculatePostProb(corrCisMtx, spkMtx(:,:,perfLog & inSeqLog & odorClog & ~fullInSeqLog), binSize); +subplot(2,2,3); +cCaxis = PlotPostMtx(trialTimes, postCnorm, 'Odor C'); + +corrDisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorDlog),3); % All D InSeq Correct Trials +[postDnorm, postDraw] = CalculatePostProb(corrDisMtx, spkMtx(:,:,perfLog & inSeqLog & odorDlog & ~fullInSeqLog), binSize); +subplot(2,2,4); +dCaxis = PlotPostMtx(trialTimes, postDnorm, 'Odor D'); + +cAx = [min([aCaxis, bCaxis, cCaxis, dCaxis]), max([aCaxis, bCaxis, cCaxis, dCaxis])/3]; + +annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +colormap jet +axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +axis(axesHandles,'square') +set(axesHandles, 'clim', cAx); +orient(gcf, 'tall'); +orient(gcf, 'landscape'); + +%% Decode Trial Time and Odor Across Odors +% nonAIStrials = spkMtx(:,:,perfLog & inSeqLog & ~fullInSeqLog); +% nonAIStrialData = trialPeriodTD(perfLog & inSeqLog & ~fullInSeqLog); +% nonAISodors = [nonAIStrialData.Odor]; +% corrAisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorAlog),3); % All A InSeq Correct Trials Prior +% corrBisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorBlog),3); % All B InSeq Correct Trials Prior +% corrCisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorClog),3); % All C InSeq Correct Trials Prior +% corrDisMtx = mean(spkMtx(:,:,perfLog & fullInSeqLog & odorDlog),3); % All D InSeq Correct Trials Prior +% +% figure; +% oAfr = subplot(4,4,1); +% imagesc(trialTimes, 1:size(spkMtx,2), corrAisMtx'); +% title('Odor A'); +% abCorr = subplot(4,4,2); +% corrScatPlot(corrAisMtx(:),corrBisMtx(:), 'A','B', 'markerStyle', '.', 'markerColor', 'k'); +% acCorr = subplot(4,4,3); +% corrScatPlot(corrAisMtx(:),corrCisMtx(:), 'A','C', 'markerStyle', '.', 'markerColor', 'k'); +% adCorr = subplot(4,4,4); +% corrScatPlot(corrAisMtx(:),corrDisMtx(:), 'A','B', 'markerStyle', '.', 'markerColor', 'k'); +% +% oBfr = subplot(4,4,6); +% imagesc(trialTimes, 1:size(spkMtx,2), corrBisMtx'); +% title('Odor B'); +% bcCorr = subplot(4,4,7); +% corrScatPlot(corrBisMtx(:),corrCisMtx(:), 'B','C', 'markerStyle', '.', 'markerColor', 'k'); +% bdCorr = subplot(4,4,8); +% corrScatPlot(corrBisMtx(:),corrDisMtx(:), 'B','D', 'markerStyle', '.', 'markerColor', 'k'); +% +% oCfr = subplot(4,4,11); +% imagesc(trialTimes, 1:size(spkMtx,2), corrCisMtx'); +% title('Odor C'); +% cdCorr = subplot(4,4,12); +% corrScatPlot(corrCisMtx(:),corrDisMtx(:), 'C','D', 'markerStyle', '.', 'markerColor', 'k'); +% +% oDfr = subplot(4,4,16); +% imagesc(trialTimes, 1:size(spkMtx,2), corrDisMtx'); +% title('Odor D'); +% +% frMapSPs = [oAfr, oBfr, oCfr, oDfr]; +% curCL = cell2mat(get(frMapSPs, 'clim')); +% set(frMapSPs, 'clim', [min(curCL(:,1)), max(curCL(:,2))*.5], 'ydir', 'normal'); +% corrSPs = [abCorr, acCorr, adCorr, bcCorr, bdCorr, cdCorr]; +% curXL = cell2mat(get(corrSPs, 'xlim')); +% curYL = cell2mat(get(corrSPs, 'ylim')); +% set(corrSPs, 'xlim', [0 max(curXL(:,2))], 'ylim', [0 max(curYL(:,2))]); +% +% axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +% axis(axesHandles,'square'); +% +% annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... +% 'linestyle', 'none', 'horizontalalignment', 'right'); +% annotation('textbox', 'position', [0.025 0.935 0.5 0.05], 'String', '\bf\fontsize{14}Priors',... +% 'linestyle', 'none', 'horizontalalignment', 'left'); +% curDir = cd; +% annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... +% 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +% colormap jet +% orient(gcf, 'tall'); +% orient(gcf, 'landscape'); +% drawnow; +% +% +% [~, aPriorAllPostRaw] = CalculatePostProb(corrAisMtx, nonAIStrials, binSize); +% [~, bPriorAllPostRaw] = CalculatePostProb(corrBisMtx, nonAIStrials, binSize); +% [~, cPriorAllPostRaw] = CalculatePostProb(corrCisMtx, nonAIStrials, binSize); +% [~, dPriorAllPostRaw] = CalculatePostProb(corrDisMtx, nonAIStrials, binSize); +% nonFISaLog = perfLog & inSeqLog & odorAlog & ~fullInSeqLog; +% nonFISbLog = perfLog & inSeqLog & odorBlog & ~fullInSeqLog; +% nonFIScLog = perfLog & inSeqLog & odorClog & ~fullInSeqLog; +% nonFISdLog = perfLog & inSeqLog & odorDlog & ~fullInSeqLog; +% +% allNonFISpost = [aPriorAllPostRaw, bPriorAllPostRaw, cPriorAllPostRaw, dPriorAllPostRaw]; +% for c = 1:size(allNonFISpost,1) +% allNonFISpost(c,:,:) = allNonFISpost(c,:,:)./sum(allNonFISpost(c,:,:)); +% end +% +% aPriorAllPostNorm = allNonFISpost(:,1:size(aPriorAllPostRaw,1),:); +% bPriorAllPostNorm = allNonFISpost(:,size(aPriorAllPostRaw,1)+1:size(aPriorAllPostRaw,1)*2,:); +% cPriorAllPostNorm = allNonFISpost(:,size(aPriorAllPostRaw,1)*2+1:size(aPriorAllPostRaw,1)*3,:); +% dPriorAllPostNorm = allNonFISpost(:,size(aPriorAllPostRaw,1)*3+1:end,:); +% +% figure; +% cAx = nan(4,4,2); +% for prior = 1:4 +% switch prior +% case 1 +% curPrior = aPriorAllPostNorm; +% case 2 +% curPrior = bPriorAllPostNorm; +% case 3 +% curPrior = cPriorAllPostNorm; +% case 4 +% curPrior = dPriorAllPostNorm; +% end +% for post = 1:4 +% curPostLog = nonAISodors == post; +% curDecode = curPrior(:,:,curPostLog); +% subplot(4,4,sub2ind([4 4], post, prior)) +% cAx(prior,post,:) = PlotPostMtx(trialTimes, curDecode, sprintf('Prior%i; Decode%i', prior, post)); +% end +% end +% cAxs = [min(min(cAx(:,:,1))), max(max(cAx(:,:,2)))*.5]; +% +% annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... +% 'linestyle', 'none', 'horizontalalignment', 'right'); +% annotation('textbox', 'position', [0.025 0.935 0.5 0.05], 'String', '\bf\fontsize{14}Decoding Trial and Odor Across Odors',... +% 'linestyle', 'none', 'horizontalalignment', 'left'); +% curDir = cd; +% annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... +% 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +% colormap jet +% axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +% axis(axesHandles,'square') +% set(axesHandles, 'clim', cAxs); +% orient(gcf, 'tall'); +% orient(gcf, 'landscape'); +% drawnow; + +%% +% figure +% corrISmtx = mean(spkMtx(:,:,perfLog & fullInSeqLog),3); % All InSeq Correct Trials +% [post,~] = CalculatePostProb(corrISmtx, spkMtx(:,:,perfLog & inSeqLog & ~fullInSeqLog), binSize); +% PlotPostMtx(trialTimes, post, 'InSeq Correct Trials'); +% +% annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... +% 'linestyle', 'none', 'horizontalalignment', 'right'); +% curDir = cd; +% annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... +% 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +% colormap jet +% axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +% axis(axesHandles,'square') +% orient(gcf, 'tall'); +% orient(gcf, 'landscape'); +% drawnow; + +%% Compare Trial Before with Trial After OutSeq Trial +% nonAIStrials = spkMtx(:,:,perfLog & inSeqLog & ~fullInSeqLog); +% nonAIStrialData = trialPeriodTD(perfLog & inSeqLog & ~fullInSeqLog); +% nonAISodors = [nonAIStrialData.Odor]; +% nonAIStrialNums = [nonAIStrialData.TrialNum]; +% +% preOStrial = false(size(nonAIStrialNums)); +% postOStrial = false(size(nonAIStrialNums)); +% for trl = 1:length(nonAIStrialNums) +% if nonAIStrialNums(trl)~=1 && nonAIStrialNums(trl) ~= length(trialPeriodTD) +% prevTrial = trialPeriodTD(nonAIStrialNums(trl)-1); +% curTrl = trialPeriodTD(nonAIStrialNums(trl)); +% nextTrial = trialPeriodTD(nonAIStrialNums(trl)+1); +% if curTrl.Position ~= 1 +% if curTrl.Position - prevTrial.Position == 1 && prevTrial.TranspositionDistance ~= 0 +% postOStrial(trl) = true; +% preOStrial(trl-2) = true; +% end +% end +% end +% end +% postPostOS = post(:,:,postOStrial); +% postPreOS = post(:,:,preOStrial); +% +% figure; +% subplot(1,2,1) +% PlotPostMtx(trialTimes, postPreOS, 'Trial Before OutSeq'); +% +% subplot(1,2,2) +% PlotPostMtx(trialTimes, postPostOS, 'Trial After OutSeq'); +% +% annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... +% 'linestyle', 'none', 'horizontalalignment', 'right'); +% curDir = cd; +% annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... +% 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +% colormap jet +% axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +% axis(axesHandles,'square') +% cLims = cell2mat(get(axesHandles, 'cLim')); +% set(axesHandles, 'cLim', [min(cLims(:,1)), max(cLims(:,2))]); +% orient(gcf, 'tall'); +% orient(gcf, 'landscape'); +% drawnow; + +%% Comment in if you want to display each trial individually +% figure; +% for tr = 1:size(post,3) +% imagesc(trialTimes, trialTimes, post(:,:,tr), [0 1]); +% title(num2str(nonAISodors(tr))); +% set(gca, 'ydir', 'normal'); +% pause(1); +% end + +%% +function cAx = PlotPostMtx(trialTimes, postMtx, id) +postMtx(isnan(postMtx)) = 0; +imagesc(trialTimes, trialTimes, nanmean(postMtx,3)); +title(id); +set(gca, 'ydir', 'normal') +hold on; +% line(trialTimes, trialTimes, 'linestyle', ':', 'color', 'w', 'linewidth', 2); +xlabel('True Time'); +ylabel('Decoded Time'); +drawnow +cAx = get(gca, 'clim'); +end + + +%% +function [postNorm, postRaw] = CalculatePostProb(likely, obsv, binSize) +postNorm = nan(size(obsv,1), size(likely,1), size(obsv,3)); +postRaw = nan(size(obsv,1), size(likely,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(obsv,1) + p = nan(size(likely)); + curPopVect = obsv(t,:,trl)./(1000/binSize); + curPopFact = factorial(curPopVect); + for u = 1:size(likely,2) + curAvgUniFR = likely(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-(binSize/1000*sum(likely,2))); + tempPost = pp.*ee; + postRaw(t,:,trl) = tempPost; + postNorm(t,:,trl) = tempPost./sum(tempPost); + end +end +end \ No newline at end of file diff --git a/Analyses/Prototypes/BayesPFCbsPROTO_2.m b/Analyses/Prototypes/BayesPFCbsPROTO_2.m new file mode 100644 index 0000000..9a8a44d --- /dev/null +++ b/Analyses/Prototypes/BayesPFCbsPROTO_2.m @@ -0,0 +1,236 @@ +%% +clc +clear all + +%% Runtime variables +binSize = 200; +dsRate = 5; +pokeInWindows = [-0.5 1.5]; +pokeOutWindows = [-1.5 0.5]; + +%% +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Extract Behavioral Periods +% Taking 1/2 the binSize on either end to get rid of edge effects. +pokeInTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [pokeInWindows(1)-(binSize/2/1000) pokeInWindows(2)+(binSize/2/1000)], 'PokeIn'); +pokeInTimes = behavMatrix(pokeInTrialPeriodTD(1).TrialLogVect,1) - behavMatrix(pokeInTrialPeriodTD(1).PokeInIndex,1); +pokeOutTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [pokeOutWindows(1)-(binSize/2/1000) pokeOutWindows(2)+(binSize/2/1000)], 'PokeOut'); +pokeOutTimes = behavMatrix(pokeOutTrialPeriodTD(1).TrialLogVect,1) - behavMatrix(pokeOutTrialPeriodTD(1).PokeOutIndex,1); + +% pokeInTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [pokeInWindows(1)-(binSize/1000) pokeInWindows(2)+(binSize/1000)], 'PokeIn'); +% pokeInTimes = behavMatrix(pokeInTrialPeriodTD(1).TrialLogVect,1) - behavMatrix(pokeInTrialPeriodTD(1).PokeInIndex,1); +% pokeOutTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [pokeOutWindows(1)-(binSize/1000) pokeOutWindows(2)+(binSize/1000)], 'PokeOut'); +% pokeOutTimes = behavMatrix(pokeOutTrialPeriodTD(1).TrialLogVect,1) - behavMatrix(pokeOutTrialPeriodTD(1).PokeOutIndex,1); + +pokeInEnsemble = ExtractTrialData_SM(pokeInTrialPeriodTD, ensembleMatrix(:,2:end)); %#ok<*NODEF> +pokeInEnsembleMtx = cell2mat(reshape(pokeInEnsemble, [1 1 length(pokeInEnsemble)])); +pokeOutEnsemble = ExtractTrialData_SM(pokeOutTrialPeriodTD, ensembleMatrix(:,2:end)); %#ok<*NODEF> +pokeOutEnsembleMtx = cell2mat(reshape(pokeOutEnsemble, [1 1 length(pokeOutEnsemble)])); + + +%% Bin the spiking data +% First convolve the entire trialEnsembleMtx with a square to bin the +% spikes +pokeInBinnedEnsembleMtx = nan(size(pokeInEnsembleMtx)); +pokeOutBinnedEnsembleMtx = nan(size(pokeOutEnsembleMtx)); +for t = 1:size(pokeInEnsembleMtx,3) + for u = 1:size(pokeInEnsembleMtx,2) + pokeInBinnedEnsembleMtx(:,u,t) = conv(pokeInEnsembleMtx(:,u,t), ones(1,binSize)./(binSize/1000), 'same'); + pokeOutBinnedEnsembleMtx(:,u,t) = conv(pokeOutEnsembleMtx(:,u,t), ones(1,binSize)./(binSize/1000), 'same'); + end +end +% Now remove the binSize/2 padding +unPaddedPokeInBinnedEnsembleMtx = pokeInBinnedEnsembleMtx((binSize/2)+1:end-(binSize/2),:,:); +pokeInTimesUnpadded = pokeInTimes((binSize/2)+1:end-(binSize/2)); +unPaddedPokeOutBinnedEnsembleMtx = pokeOutBinnedEnsembleMtx((binSize/2)+1:end-(binSize/2),:,:); +pokeOutTimesUnpadded = pokeOutTimes((binSize/2)+1:end-(binSize/2)); +% Now downsample the binned matrix +dsVect = downsample(1:size(unPaddedPokeInBinnedEnsembleMtx,1), dsRate); +pokeInSpikeMatrix = unPaddedPokeInBinnedEnsembleMtx(dsVect,:,:); +pokeOutSpikeMatrix = unPaddedPokeOutBinnedEnsembleMtx(dsVect,:,:); +trialTimePI = pokeInTimesUnpadded(dsVect); +trialTimePO = pokeOutTimesUnpadded(dsVect); + +%% Alternative way to bin the spike data +% mansWin1 = 1:dsRate:size(pokeInEnsembleMtx,1)-binSize; +% mansWin2 = mansWin1+binSize; +% +% pokeInBinnedEnsembleMtx = nan(length(mansWin1), size(pokeInEnsembleMtx,2), size(pokeInEnsembleMtx,3)); +% pokeOutBinnedEnsembleMtx = nan(length(mansWin1), size(pokeOutEnsembleMtx,2), size(pokeOutEnsembleMtx,3)); +% for trl = 1:size(pokeInEnsembleMtx,3) +% for u = 1:size(pokeInEnsembleMtx,2) +% curUniPI = pokeInEnsembleMtx(:,u,trl); +% pokeInBinnedEnsembleMtx(:,u,trl) = cell2mat(arrayfun(@(a,b)sum(curUniPI(a:b)), mansWin1, mansWin2, 'uniformoutput', 0)); +% curUniPO = pokeOutEnsembleMtx(:,u,trl); +% pokeOutBinnedEnsembleMtx(:,u,trl) = cell2mat(arrayfun(@(a,b)sum(curUniPO(a:b)), mansWin1, mansWin2, 'uniformoutput', 0)); +% end +% end +% pokeInBinnedEnsembleMtx = pokeInBinnedEnsembleMtx./(binSize/1000); +% pokeOutBinnedEnsembleMtx = pokeOutBinnedEnsembleMtx./(binSize/1000); +% pokeInTimesDS = pokeInTimes(mansWin1); +% pokeInUnPadLog = pokeInTimesDS>=pokeInWindows(1) & pokeInTimesDS<=pokeInWindows(2); +% trialTimePI = pokeInTimesDS(pokeInUnPadLog); +% pokeInSpikeMatrix = pokeInBinnedEnsembleMtx(pokeInUnPadLog,:,:); +% pokeOutTimesDS = pokeOutTimes(mansWin1); +% pokeOutUnPadLog = pokeOutTimesDS>=pokeOutWindows(1) & pokeOutTimesDS<=pokeOutWindows(2); +% trialTimePO = pokeOutTimesDS(pokeOutUnPadLog); +% pokeOutSpikeMatrix = pokeOutBinnedEnsembleMtx(pokeOutUnPadLog,:,:); + + +%% Create Logical Vectors +perfLog = [pokeInTrialPeriodTD.Performance]; +inSeqLog = [pokeInTrialPeriodTD.TranspositionDistance]==0; +outSeqLog = [pokeInTrialPeriodTD.TranspositionDistance]~=0 & abs([pokeInTrialPeriodTD.TranspositionDistance])<10; +odorAlog = [pokeInTrialPeriodTD.Odor] == 1; +odorBlog = [pokeInTrialPeriodTD.Odor] == 2; +odorClog = [pokeInTrialPeriodTD.Odor] == 3; +odorDlog = [pokeInTrialPeriodTD.Odor] == 4; + +fullInSeqSeqsStart = find(conv([pokeInTrialPeriodTD.Odor], 1:4, 'valid')==20 & conv([pokeInTrialPeriodTD.Position], 1:4, 'valid')==20 & conv([pokeInTrialPeriodTD.Performance]*1, ones(1,4), 'valid')==4); +inSeqSeqs = nan(3,length(fullInSeqSeqsStart)); +for iS = 1:length(fullInSeqSeqsStart) + inSeqSeqs(1,iS) = fullInSeqSeqsStart(iS); + inSeqSeqs(2,iS) = fullInSeqSeqsStart(iS) + 1; + inSeqSeqs(3,iS) = fullInSeqSeqsStart(iS) + 2; + inSeqSeqs(4,iS) = fullInSeqSeqsStart(iS) + 3; +end +fullInSeqLog = false(1,length(pokeInTrialPeriodTD)); +fullInSeqLog(inSeqSeqs(:)) = true; + +%% +uniFRthreshLog = max([mean(pokeInSpikeMatrix,3); mean(pokeOutSpikeMatrix,3)])<1; +pokeInSpkMtx = pokeInSpikeMatrix; +pokeInSpkMtx(:,uniFRthreshLog,:) = []; +pokeOutSpkMtx = pokeOutSpikeMatrix; +pokeOutSpkMtx(:,uniFRthreshLog,:) = []; +goodUniNames = {ensembleUnitSummaries(~uniFRthreshLog).UnitName}; + +%% +figure +corrISmtxPI = mean(pokeInSpkMtx(:,:,perfLog & fullInSeqLog),3); % All InSeq Correct Trials +[postPI, ~] = CalculatePostProb(corrISmtxPI, pokeInSpkMtx(:,:,perfLog & inSeqLog & ~fullInSeqLog), binSize); +piPlot = subplot(4,4,[1,2,5,6]); +PlotPostMtx(trialTimePI, postPI, 'InSeq Correct Trials (Poke In)'); + +corrISmtxPO = mean(pokeOutSpkMtx(:,:,perfLog & fullInSeqLog),3); +[postPO, ~] = CalculatePostProb(corrISmtxPO, pokeOutSpkMtx(:,:,perfLog & inSeqLog & ~fullInSeqLog), binSize); +poPlot = subplot(4,4,[9,10,13,14]); +PlotPostMtx(trialTimePO, postPO, 'InSeq Correct Trials (Poke Out)'); + +nonAIStrialData = pokeInTrialPeriodTD(perfLog & inSeqLog & ~fullInSeqLog); +nonAISodors = [nonAIStrialData.Odor]; +nonAIStrialNums = [nonAIStrialData.TrialNum]; + +preOStrialLog = false(size(nonAIStrialNums)); +postOStrialLog = false(size(nonAIStrialNums)); +for trl = 1:length(nonAIStrialNums) + if nonAIStrialNums(trl)~=1 && nonAIStrialNums(trl) ~= length(pokeInTrialPeriodTD) + prevTrial = pokeInTrialPeriodTD(nonAIStrialNums(trl)-1); + curTrl = pokeInTrialPeriodTD(nonAIStrialNums(trl)); + nextTrial = pokeInTrialPeriodTD(nonAIStrialNums(trl)+1); + if curTrl.Position ~= 1 + if curTrl.Position - prevTrial.Position == 1 && prevTrial.TranspositionDistance ~= 0 + postOStrialLog(trl) = true; + preOStrialLog(trl-2) = true; + end + end + end +end + +preOSpi = postPI(:,:,preOStrialLog); +prOsPIplt = subplot(4,4,3); +PlotPostMtx(trialTimePI, preOSpi, 'Before OutSeq'); + +postOSpi = postPI(:,:,postOStrialLog); +poOsPIplt = subplot(4,4,7); +PlotPostMtx(trialTimePI, postOSpi, 'After OutSeq'); + +postPreDiffPI = postOSpi - preOSpi; +piDiffPlt = subplot(4,4,4); +PlotPostMtx(trialTimePI, postPreDiffPI, 'After-Before'); + + +preOSpo = postPO(:,:,preOStrialLog); +prOsPOplt = subplot(4,4,11); +PlotPostMtx(trialTimePO, preOSpo, 'Before OutSeq'); + +postOSpo = postPO(:,:,postOStrialLog); +poOsPOplt = subplot(4,4,15); +PlotPostMtx(trialTimePO, postOSpo, 'After OutSeq'); + +postPreDiffPO = postOSpo - preOSpo; +poDiffPlt = subplot(4,4,12); +PlotPostMtx(trialTimePO, postPreDiffPO, 'After-Before'); + +cLimsDecode = get([piPlot, poPlot, prOsPIplt, poOsPIplt, prOsPOplt, poOsPOplt], 'clim'); +cLimsDiff = get([piDiffPlt, poDiffPlt], 'clim'); + +set([piPlot, poPlot, prOsPIplt, poOsPIplt, prOsPOplt, poOsPOplt], 'clim', [0 max(max(cell2mat(cLimsDecode)))\2]); +set([piDiffPlt, poDiffPlt], 'clim', [0 max(max(cell2mat(cLimsDiff)))]); +colormap jet + +annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +colormap jet +axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +axis(axesHandles,'square') +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +drawnow; + + + + +%% +function cAx = PlotPostMtx(trialTimes, postMtx, id) +imagesc(trialTimes, trialTimes, nanmean(postMtx,3)); +set(gca, 'ydir', 'normal') +hold on; +% line(trialTimes, trialTimes, 'linestyle', ':', 'color', 'w', 'linewidth', 2); +title(id); +xlabel('True Time'); +ylabel('Decoded Time'); +drawnow +cAx = get(gca, 'clim'); +end + +%% +function [postNorm, postRaw] = CalculatePostProb(prior, obsv, binSize) +% propVect = 1./sum(prior,2); % Probably wrong +postNorm = nan(size(obsv,1), size(obsv,1), size(obsv,3)); +postRaw = nan(size(obsv,1), size(obsv,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(prior,1) + p = nan(size(prior)); + curPopVect = obsv(t,:,trl)*(binSize/1000); + curPopFact = factorial(curPopVect); + for u = 1:size(prior,2) + curAvgUniFR = prior(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); +% p(:,u) = ((curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-((binSize/1000)*sum(prior,2))); +% ee = exp(-(sum(prior,2))); +% tempPost = propVect.*pp.*ee; % Probably wrong + tempPost = pp.*ee; + postRaw(t,:,trl) = tempPost; +% postNorm(t,:,trl) = tempPost./max(tempPost); % Probably wrong + postNorm(t,:,trl) = tempPost./sum(tempPost); + end +end +end \ No newline at end of file diff --git a/Analyses/Prototypes/BayesPFCproto_VALID.m b/Analyses/Prototypes/BayesPFCproto_VALID.m new file mode 100644 index 0000000..13e4a79 --- /dev/null +++ b/Analyses/Prototypes/BayesPFCproto_VALID.m @@ -0,0 +1,390 @@ +%% +clc +clear all + +%% Runtime variables +window = [-0.2 0.2]; +binSize = 50; +dsRate = 5; +cLims = [0 0.005]; +withdrawTime = 1.2; +%% +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Extract Behavioral Periods +% Taking 1/2 the binSize on either end to get rid of edge effects. +trialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [window(1)-(binSize/2/1000) withdrawTime+window(2)+(binSize/2/1000)], 'PokeIn'); +trialEnsemble = ExtractTrialData_SM(trialPeriodTD, ensembleMatrix(:,2:end)); %#ok<*NODEF> +trialEnsembleMtx = cell2mat(reshape(trialEnsemble, [1 1 length(trialEnsemble)])); + +trialTimes = behavMatrix(trialPeriodTD(1).TrialLogVect,1) - behavMatrix(trialPeriodTD(1).PokeInIndex,1); +% trialTimes = behavMatrix(trialPeriodTD(1).TrialLogVect,1) - behavMatrix(trialPeriodTD(1).PokeOutIndex,1); + +%% Bin the spiking data +% First convolve the entire trialEnsembleMtx with a square to bin the +% spikes +binnedEnsembleMtx = nan(size(trialEnsembleMtx)); +for t = 1:size(trialEnsembleMtx,3) + for u = 1:size(trialEnsembleMtx,2) + binnedEnsembleMtx(:,u,t) = conv(trialEnsembleMtx(:,u,t), ones(1,binSize)./(binSize/1000), 'same'); +% binnedEnsembleMtx(:,u,t) = conv(trialEnsembleMtx(:,u,t), ones(1,binSize), 'same'); + end +end +% Now remove the binSize/2 padding +unPaddedBinnedEnsembleMtx = binnedEnsembleMtx((binSize/2)+1:end-(binSize/2),:,:); +trialTimes = trialTimes((binSize/2)+1:end-(binSize/2)); +% Now downsample the binned matrix +dsVect = downsample(1:size(unPaddedBinnedEnsembleMtx,1), dsRate); +spikeMatrix = unPaddedBinnedEnsembleMtx(dsVect,:,:); +trialTime = trialTimes(dsVect); + +%% Create Logical Vectors +perfLog = [trialPeriodTD.Performance]; +inSeqLog = [trialPeriodTD.TranspositionDistance]==0; +outSeqLog = [trialPeriodTD.TranspositionDistance]~=0 & abs([trialPeriodTD.TranspositionDistance])<10; +odorAlog = [trialPeriodTD.Odor] == 1; +odorBlog = [trialPeriodTD.Odor] == 2; +odorClog = [trialPeriodTD.Odor] == 3; +odorDlog = [trialPeriodTD.Odor] == 4; + +fullInSeqSeqsStart = find(conv([trialPeriodTD.Odor], 1:4, 'valid')==20 & conv([trialPeriodTD.Position], 1:4, 'valid')==20 & conv([trialPeriodTD.Performance]*1, ones(1,4), 'valid')==4); +inSeqSeqs = nan(3,length(fullInSeqSeqsStart)); +for iS = 1:length(fullInSeqSeqsStart) + inSeqSeqs(1,iS) = fullInSeqSeqsStart(iS); + inSeqSeqs(2,iS) = fullInSeqSeqsStart(iS) + 1; + inSeqSeqs(3,iS) = fullInSeqSeqsStart(iS) + 2; + inSeqSeqs(4,iS) = fullInSeqSeqsStart(iS) + 3; +end +fullInSeqLog = false(1,length(trialPeriodTD)); +fullInSeqLog(inSeqSeqs(:)) = true; + +%% Create Standard Likelihood Vector +fullyISlikelyCell = repmat({nan(size(spikeMatrix,1), size(spikeMatrix,2))}, 4,1); +odorCell = cell(4,1); +for p = 1:4 + fullyISlikelyCell{p} = mean(spikeMatrix(:,:,inSeqSeqs(p,:)),3); + odorCell{p} = ones(size(fullyISlikelyCell{p},1),1)*p; +end +fullyISlikely = cell2mat(fullyISlikelyCell); +timeIndexes = repmat(trialTime,[4,1]); +odorIndexes = cell2mat(odorCell); + +xTickNdxs = find(timeIndexes==trialTime(find(trialTime>max(trialTime)/2,1,'first'))); +odorDivs = find(timeIndexes==min(trialTime(trialTime>=window(1)))); +odorTargs = find(timeIndexes==min(trialTime(trialTime>=withdrawTime))); +odorStarts = find(timeIndexes==0); + +noSpikeLog = sum(fullyISlikely)==0; +spikeMatrix(:,noSpikeLog,:) = []; +fullyISlikely(:,noSpikeLog) = []; + +%% +figure; +imagesc(1:length(timeIndexes), 1:size(fullyISlikely,2), fullyISlikely'); +hold on; +set(gca, 'ydir', 'normal', 'xTick', find(timeIndexes==trialTime(find(trialTime>max(trialTime)/2,1,'first'))),... + 'xticklabel', [{'A'}, {'B'}, {'C'}, {'D'}], 'TickDir', 'out'); +for p = 1:4 + plot([odorDivs(p) odorDivs(p)], get(gca, 'ylim'), '-w', 'linewidth', 2); + plot([odorTargs(p) odorTargs(p)], get(gca, 'ylim'), ':w', 'linewidth', 1.5); + plot([odorStarts(p) odorStarts(p)], get(gca, 'ylim'), '--w', 'linewidth', 1.5); +end +title('Likelihoods (PSTH)'); + +annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +%% +figure +spA = subplot(4,5,1:3); +aPost = CalcStaticBayesPost(fullyISlikely, spikeMatrix(:,:,[trialPeriodTD.Odor]==1 & ~fullInSeqLog & perfLog & inSeqLog), binSize); +imagesc(1:length(timeIndexes), trialTime, nanmean(aPost,3),cLims); +hold on; +set(gca, 'ydir', 'normal', 'xtick', [], 'xticklabel', [], 'TickDir', 'out'); +for p = 1:4 + plot([odorDivs(p) odorDivs(p)], get(gca, 'ylim'), '-w', 'linewidth', 2); + plot([odorTargs(p) odorTargs(p)], get(gca, 'ylim'), ':w', 'linewidth', 1.5); + plot([odorStarts(p) odorStarts(p)], get(gca, 'ylim'), '--w', 'linewidth', 1.5); +end +plot([0 length(timeIndexes)], [withdrawTime, withdrawTime], ':w', 'linewidth', 1.5); +plot([0 length(timeIndexes)], [0 0], '--w', 'linewidth', 1); +aDecode = DecodeBayesPost(aPost, odorIndexes); +aDecodePrcnts = nan(size(aDecode,1),4); +for t = 1:size(aDecode,1) + aDecodePrcnts(t,1) = sum(aDecode(t,:)==1)/sum(~isnan(aDecode(t,:))); + aDecodePrcnts(t,2) = sum(aDecode(t,:)==2)/sum(~isnan(aDecode(t,:))); + aDecodePrcnts(t,3) = sum(aDecode(t,:)==3)/sum(~isnan(aDecode(t,:))); + aDecodePrcnts(t,4) = sum(aDecode(t,:)==4)/sum(~isnan(aDecode(t,:))); +end +title('Probability Density'); +curBarA = subplot(4,5,4); +curBar = barh(trialTime,aDecodePrcnts, 1, 'stacked'); +curBar(1).FaceColor = [44/255 168/255 224/255]; curBar(1).EdgeColor = 'none'; +curBar(2).FaceColor = [154/255 133/255 122/255]; curBar(2).EdgeColor = 'none'; +curBar(3).FaceColor = [9/255 161/255 74/255]; curBar(3).EdgeColor = 'none'; +curBar(4).FaceColor = [128/255 66/255 151/255]; curBar(4).EdgeColor = 'none'; +set(gca, 'xlim', [0 1], 'xticklabel', []); +hold on +plot(get(gca, 'xlim'), [0 0], '--w'); +plot(get(gca, 'xlim'), [withdrawTime withdrawTime], ':w'); +box off +legend('A', 'B', 'C', 'D'); +aDecodeTime = DecodeBayesPost(aPost, timeIndexes); +decodeLag = aDecodeTime - repmat(trialTime, [1,size(aDecodeTime,2)]); +title('Odor Decoding'); +subplot(4,5,5); +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,0,2); +plot(lagMean, trialTime, '-k', 'linewidth', 1); +patch('XData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'YData', [trialTime; flipud(trialTime)], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight; +box off; +set(gca, 'tickdir', 'out', 'xlim', [-2 2]); +hold on; +plot([0 0], get(gca, 'ylim'), ':k', 'linewidth', 1.5); +title('Time Decoding'); +drawnow; + +spB = subplot(4,5,6:8); +bPost = CalcStaticBayesPost(fullyISlikely, spikeMatrix(:,:,[trialPeriodTD.Odor]==2 & ~fullInSeqLog & perfLog & inSeqLog), binSize); +imagesc(1:length(timeIndexes), trialTime, nanmean(bPost,3),cLims); +hold on; +set(gca, 'ydir', 'normal', 'xtick', [], 'xticklabel', [], 'TickDir', 'out'); +for p = 1:4 + plot([odorDivs(p) odorDivs(p)], get(gca, 'ylim'), '-w', 'linewidth', 2); + plot([odorTargs(p) odorTargs(p)], get(gca, 'ylim'), ':w', 'linewidth', 1.5); + plot([odorStarts(p) odorStarts(p)], get(gca, 'ylim'), '--w', 'linewidth', 1.5); +end +plot([0 length(timeIndexes)], [withdrawTime, withdrawTime], ':w', 'linewidth', 1.5); +plot([0 length(timeIndexes)], [0 0], '-w', 'linewidth', 1); +bDecode = DecodeBayesPost(bPost, odorIndexes); +bDecodePrcnts = nan(size(bDecode,1),4); +for t = 1:size(aDecode,1) + bDecodePrcnts(t,1) = sum(bDecode(t,:)==1)/sum(~isnan(bDecode(t,:))); + bDecodePrcnts(t,2) = sum(bDecode(t,:)==2)/sum(~isnan(bDecode(t,:))); + bDecodePrcnts(t,3) = sum(bDecode(t,:)==3)/sum(~isnan(bDecode(t,:))); + bDecodePrcnts(t,4) = sum(bDecode(t,:)==4)/sum(~isnan(bDecode(t,:))); +end +curBarB = subplot(4,5,9); +curBar = barh(trialTime,bDecodePrcnts, 1, 'stacked'); +curBar(1).FaceColor = [44/255 168/255 224/255]; curBar(1).EdgeColor = 'none'; +curBar(2).FaceColor = [154/255 133/255 122/255]; curBar(2).EdgeColor = 'none'; +curBar(3).FaceColor = [9/255 161/255 74/255]; curBar(3).EdgeColor = 'none'; +curBar(4).FaceColor = [128/255 66/255 151/255]; curBar(4).EdgeColor = 'none'; +set(gca, 'xlim', [0 1], 'xticklabel', []); +hold on +plot(get(gca, 'xlim'), [0 0], '--w'); +plot(get(gca, 'xlim'), [withdrawTime withdrawTime], ':w'); +box off +bDecodeTime = DecodeBayesPost(bPost, timeIndexes); +decodeLag = bDecodeTime - repmat(trialTime, [1,size(bDecodeTime,2)]); +subplot(4,5,10); +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,0,2); +plot(lagMean, trialTime, '-k', 'linewidth', 1); +patch('XData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'YData', [trialTime; flipud(trialTime)], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight; +box off; +set(gca, 'tickdir', 'out', 'xlim', [-2 2]); +hold on; +plot([0 0], get(gca, 'ylim'), ':k', 'linewidth', 1.5); +drawnow; + +spC = subplot(4,5,11:13); +cPost = CalcStaticBayesPost(fullyISlikely, spikeMatrix(:,:,[trialPeriodTD.Odor]==3 & ~fullInSeqLog & perfLog & inSeqLog), binSize); +imagesc(1:length(timeIndexes), trialTime, nanmean(cPost,3),cLims); +hold on; +set(gca, 'ydir', 'normal', 'xtick', [], 'xticklabel', [], 'TickDir', 'out'); +for p = 1:4 + plot([odorDivs(p) odorDivs(p)], get(gca, 'ylim'), '-w', 'linewidth', 2); + plot([odorTargs(p) odorTargs(p)], get(gca, 'ylim'), ':w', 'linewidth', 1.5); + plot([odorStarts(p) odorStarts(p)], get(gca, 'ylim'), '--w', 'linewidth', 1.5); +end +plot([0 length(timeIndexes)], [withdrawTime, withdrawTime], ':w', 'linewidth', 1.5); +plot([0 length(timeIndexes)], [0 0], '-w', 'linewidth', 1); +cDecode = DecodeBayesPost(cPost, odorIndexes); +cDecodePrcnts = nan(size(cDecode,1),4); +for t = 1:size(aDecode,1) + cDecodePrcnts(t,1) = sum(cDecode(t,:)==1)/sum(~isnan(cDecode(t,:))); + cDecodePrcnts(t,2) = sum(cDecode(t,:)==2)/sum(~isnan(cDecode(t,:))); + cDecodePrcnts(t,3) = sum(cDecode(t,:)==3)/sum(~isnan(cDecode(t,:))); + cDecodePrcnts(t,4) = sum(cDecode(t,:)==4)/sum(~isnan(cDecode(t,:))); +end +curBarC = subplot(4,5,14); +curBar = barh(trialTime,cDecodePrcnts, 1, 'stacked'); +curBar(1).FaceColor = [44/255 168/255 224/255]; curBar(1).EdgeColor = 'none'; +curBar(2).FaceColor = [154/255 133/255 122/255]; curBar(2).EdgeColor = 'none'; +curBar(3).FaceColor = [9/255 161/255 74/255]; curBar(3).EdgeColor = 'none'; +curBar(4).FaceColor = [128/255 66/255 151/255]; curBar(4).EdgeColor = 'none'; +set(gca, 'xlim', [0 1], 'xticklabel', []); +hold on +plot(get(gca, 'xlim'), [0 0], '--w'); +plot(get(gca, 'xlim'), [withdrawTime withdrawTime], ':w'); +box off +cDecodeTime = DecodeBayesPost(cPost, timeIndexes); +decodeLag = cDecodeTime - repmat(trialTime, [1,size(cDecodeTime,2)]); +subplot(4,5,15); +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,0,2); +plot(lagMean, trialTime, '-k', 'linewidth', 1); +patch('XData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'YData', [trialTime; flipud(trialTime)], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight; +box off; +set(gca, 'tickdir', 'out', 'xlim', [-2 2]); +hold on; +plot([0 0], get(gca, 'ylim'), ':k', 'linewidth', 1.5); +drawnow; + +spD = subplot(4,5,16:18); +dPost = CalcStaticBayesPost(fullyISlikely, spikeMatrix(:,:,[trialPeriodTD.Odor]==4 & ~fullInSeqLog & perfLog & inSeqLog), binSize); +imagesc(1:length(timeIndexes), trialTime, nanmean(dPost,3),cLims); +hold on; +set(gca, 'ydir', 'normal', 'xtick', xTickNdxs, 'xticklabel', [{'A'}, {'B'}, {'C'}, {'D'}], 'TickDir', 'out'); +for p = 1:4 + plot([odorDivs(p) odorDivs(p)], get(gca, 'ylim'), '-w', 'linewidth', 2); + plot([odorTargs(p) odorTargs(p)], get(gca, 'ylim'), ':w', 'linewidth', 1.5); + plot([odorStarts(p) odorStarts(p)], get(gca, 'ylim'), '--w', 'linewidth', 1.5); +end +plot([0 length(timeIndexes)], [withdrawTime, withdrawTime], ':w', 'linewidth', 1.5); +plot([0 length(timeIndexes)], [0 0], '-w', 'linewidth', 1); +dDecode = DecodeBayesPost(dPost, odorIndexes); +dDecodePrcnts = nan(size(dDecode,1),4); +for t = 1:size(aDecode,1) + dDecodePrcnts(t,1) = sum(dDecode(t,:)==1)/sum(~isnan(dDecode(t,:))); + dDecodePrcnts(t,2) = sum(dDecode(t,:)==2)/sum(~isnan(dDecode(t,:))); + dDecodePrcnts(t,3) = sum(dDecode(t,:)==3)/sum(~isnan(dDecode(t,:))); + dDecodePrcnts(t,4) = sum(dDecode(t,:)==4)/sum(~isnan(dDecode(t,:))); +end +curBarD = subplot(4,5,19); +curBar = barh(trialTime,dDecodePrcnts, 1, 'stacked'); +curBar(1).FaceColor = [44/255 168/255 224/255]; curBar(1).EdgeColor = 'none'; +curBar(2).FaceColor = [154/255 133/255 122/255]; curBar(2).EdgeColor = 'none'; +curBar(3).FaceColor = [9/255 161/255 74/255]; curBar(3).EdgeColor = 'none'; +curBar(4).FaceColor = [128/255 66/255 151/255]; curBar(4).EdgeColor = 'none'; +set(gca, 'xlim', [0 1], 'xticklabel', []); +hold on +plot(get(gca, 'xlim'), [0 0], '--w'); +plot(get(gca, 'xlim'), [withdrawTime withdrawTime], ':w'); +box off +dDecodeTime = DecodeBayesPost(dPost, timeIndexes); +decodeLag = dDecodeTime - repmat(trialTime, [1,size(dDecodeTime,2)]); +subplot(4,5,20); +lagMean = nanmean(decodeLag,2); +lagVar = nanstd(decodeLag,0,2); +plot(lagMean, trialTime, '-k', 'linewidth', 1); +patch('XData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'YData', [trialTime; flipud(trialTime)], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); +axis tight; +box off; +set(gca, 'tickdir', 'out', 'xlim', [-2 2]); +hold on; +plot([0 0], get(gca, 'ylim'), ':k', 'linewidth', 1.5); +drawnow; + +colormap jet + +linkaxes([curBarA, curBarB, curBarC, curBarD], 'xy'); +linkaxes([spA, spB, spC, spD], 'xy'); +linkaxes([curBarA, spA], 'y'); +axis(curBarA, 'tight'); + +annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +aDecodeSmooth = aDecodePrcnts; +bDecodeSmooth = bDecodePrcnts; +cDecodeSmooth = cDecodePrcnts; +dDecodeSmooth = dDecodePrcnts; +for c = 1:4 + aDecodeSmooth(:,c) = smooth(aDecodePrcnts(:,c),10); + bDecodeSmooth(:,c) = smooth(bDecodePrcnts(:,c),10); + cDecodeSmooth(:,c) = smooth(cDecodePrcnts(:,c),10); + dDecodeSmooth(:,c) = smooth(dDecodePrcnts(:,c),10); +end +figure; +sp1 = subplot(4,1,1); +aPlots = plot(trialTime,aDecodeSmooth); +aPlots(1).Color = [44/255 168/255 224/255]; +aPlots(1).LineWidth = 2; +aPlots(2).Color = [154/255 133/255 122/255]; +aPlots(3).Color = [9/255 161/255 74/255]; +aPlots(4).Color = [128/255 66/255 151/255]; +sp2 = subplot(4,1,2); +bPlots = plot(trialTime,bDecodeSmooth); +bPlots(1).Color = [44/255 168/255 224/255]; +bPlots(2).Color = [154/255 133/255 122/255]; +bPlots(2).LineWidth = 2; +bPlots(3).Color = [9/255 161/255 74/255]; +bPlots(4).Color = [128/255 66/255 151/255]; +sp3 = subplot(4,1,3); +cPlots = plot(trialTime,cDecodeSmooth); +cPlots(1).Color = [44/255 168/255 224/255]; +cPlots(2).Color = [154/255 133/255 122/255]; +cPlots(3).Color = [9/255 161/255 74/255]; +cPlots(3).LineWidth = 2; +cPlots(4).Color = [128/255 66/255 151/255]; +sp4 = subplot(4,1,4); +dPlots = plot(trialTime,dDecodeSmooth); +dPlots(1).Color = [44/255 168/255 224/255]; +dPlots(2).Color = [154/255 133/255 122/255]; +dPlots(3).Color = [9/255 161/255 74/255]; +dPlots(4).Color = [128/255 66/255 151/255]; +dPlots(4).LineWidth = 2; + +linkaxes([sp1 sp2 sp3 sp4], 'xy'); +annotation('textbox', 'position', [0.5 0.935 0.5 0.05], 'String', ['\bf\fontsize{10}' sprintf('Bin = %i ms; Step = %i ms', binSize, dsRate)],... + 'linestyle', 'none', 'horizontalalignment', 'right'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); +%% +function decode = DecodeBayesPost(post, id) +% Assumes post is in the structure of ObservTime X LikelyTime X Trial +decode = nan(size(post,1),size(post,3)); +for o = 1:size(post,3) + for d = 1:size(post,1) + if ~isnan(post(d,1,o)) + decode(d,o) = id(find(post(d,:,o)==max(post(d,:,o)),1,'first')); + end + end +end +end + +%% +function post = CalcStaticBayesPost(likely, obsv, binSize) +post = nan(size(obsv,1), size(likely,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(obsv,1) + p = nan(size(likely)); + curPopVect = obsv(t,:,trl)*(binSize/1000); + curPopFact = factorial(curPopVect); + for u = 1:size(likely,2) + curAvgUniFR = likely(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-((binSize/1000)*sum(likely,2))); + tempPost = pp.*ee; + post(t,:,trl) = tempPost./sum(tempPost); + end +end +end \ No newline at end of file diff --git a/Analyses/Prototypes/DualListMeanPlots_PROTO.m b/Analyses/Prototypes/DualListMeanPlots_PROTO.m new file mode 100644 index 0000000..1476758 --- /dev/null +++ b/Analyses/Prototypes/DualListMeanPlots_PROTO.m @@ -0,0 +1,31 @@ +odor = [bmts.Odor]; +pos = [bmts.Position]; +performance = [bmts.Performance]; +isLog = [bmts.TranspositionDistance]==0; + +for t = 1:length(ensembleMatrixColIDs)-1 + figure; + sp = nan(1,4); + for o = 1:4 + curOdorFam = trialOrgData(odor==o & isLog==1 & performance==1); + curFam = mean(cell2mat(cellfun(@(a)conv(a(:,t),gausswin(200)./max(gausswin(200)),'same'),curOdorFam, 'uniformoutput',0)),2); + curOdorNov = trialOrgData(odor==o+10 & isLog==1 & performance==1); + curNov = mean(cell2mat(cellfun(@(a)conv(a(:,t),gausswin(200)./max(gausswin(200)),'same'),curOdorNov, 'uniformoutput',0)),2); + sp(o) = subplot(1,4,o); + plot(-500:1750, curFam, '-k'); + hold on; + plot(-500:1750, curNov, '--k'); + title(sprintf('Position %i', o)); + xlabel('Time From Poke In (ms)') + end + linkaxes(sp, 'xy'); + legend('Familiar', 'Novel') + for o = 1:4 + plot(sp(o), [0 0], get(sp(o), 'ylim'), '-k'); + end + axis tight; + annotation(gcf,'textbox', [0 0.93 1 0.05],'String', ensembleMatrixColIDs(t+1),... + 'FontWeight','bold', 'FontSize',12, 'edgecolor', 'none', 'horizontalalignment', 'left'); +end + + diff --git a/Analyses/Prototypes/NoiseCorrPROTO.m b/Analyses/Prototypes/NoiseCorrPROTO.m new file mode 100644 index 0000000..57bbfda --- /dev/null +++ b/Analyses/Prototypes/NoiseCorrPROTO.m @@ -0,0 +1,755 @@ +function NoiseCorrPROTO +smPath = uigetdir; +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath '\' behMatFile]); +load([smPath '\' nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Extract Behavioral Periods +preTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [-0.5 0], 'PokeIn'); +preTrialEnsemble = ExtractTrialData_SM(preTrialPeriodTD, ensembleMatrix(:,2:end)); %#ok<*NODEF> +preTrialPopVect = cell2mat(cellfun(@(a)sum(a,1), preTrialEnsemble, 'uniformoutput', 0)'); + +rlyTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0.5], 'PokeIn'); +rlyTrialEnsemble = ExtractTrialData_SM(rlyTrialPeriodTD, ensembleMatrix(:,2:end)); +rlyTrialPopVect = cell2mat(cellfun(@(a)sum(a,1), rlyTrialEnsemble, 'uniformoutput', 0)'); + +latTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [-0.5 0], 'PokeOut'); +latTrialEnsemble = ExtractTrialData_SM(latTrialPeriodTD, ensembleMatrix(:,2:end)); +latTrialPopVect = cell2mat(cellfun(@(a)sum(a,1), latTrialEnsemble, 'uniformoutput', 0)'); + +pstTrialPeriodTD = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0.5], 'PokeOut'); +pstTrialEnsemble = ExtractTrialData_SM(pstTrialPeriodTD, ensembleMatrix(:,2:end)); +pstTrialPopVect = cell2mat(cellfun(@(a)sum(a,1), pstTrialEnsemble, 'uniformoutput', 0)'); + +allTrialPopVectZ = zscore([preTrialPopVect; rlyTrialPopVect; latTrialPopVect;pstTrialPopVect],0,1); + +preTrialPopVectZall = allTrialPopVectZ(1:size(allTrialPopVectZ,1)/4,:); +rlyTrialPopVectZall = allTrialPopVectZ(size(allTrialPopVectZ,1)/4+1:size(allTrialPopVectZ,1)/2,:); +latTrialPopVectZall = allTrialPopVectZ(size(allTrialPopVectZ,1)/2+1:size(allTrialPopVectZ,1)*.75,:); +pstTrialPopVectZall = allTrialPopVectZ(size(allTrialPopVectZ,1)*.75+1:end,:); + +%% Create Session Trial ID Logical Vectors +% Using preTrialPeriodTD here arbitrarilly, any of the TD variables above +% would work and they're all identical. +perfLog = [preTrialPeriodTD.Performance]; +inSeqLog = [preTrialPeriodTD.TranspositionDistance]==0; +outSeqLog = [preTrialPeriodTD.TranspositionDistance]~=0 & abs([preTrialPeriodTD.TranspositionDistance])<10; +odorAlog = [preTrialPeriodTD.Odor] == 1; +odorBlog = [preTrialPeriodTD.Odor] == 2; +odorClog = [preTrialPeriodTD.Odor] == 3; +odorDlog = [preTrialPeriodTD.Odor] == 4; + +fullInSeqSeqsStart = find(conv([preTrialPeriodTD.Odor], 1:4, 'valid')==20 & conv([preTrialPeriodTD.Position], 1:4, 'valid')==20 & conv([preTrialPeriodTD.Performance]*1, ones(1,4), 'valid')==4); +inSeqSeqs = nan(3,length(fullInSeqSeqsStart)); +for iS = 1:length(fullInSeqSeqsStart) + inSeqSeqs(1,iS) = fullInSeqSeqsStart(iS); + inSeqSeqs(2,iS) = fullInSeqSeqsStart(iS) + 1; + inSeqSeqs(3,iS) = fullInSeqSeqsStart(iS) + 2; + inSeqSeqs(4,iS) = fullInSeqSeqsStart(iS) + 3; +end +fullInSeqLog = false(1,length(preTrialPeriodTD)); +fullInSeqLog(inSeqSeqs(:)) = true; + +%% Conv test/verification +% anss = nan(4); +% for a = 1:4 +% for b = 1:4 +% temp = 1:4; +% temp(b) = a; +% anss(a,b) = conv(temp, 1:4, 'valid'); +% end +% end +% anss +%% +% [corrTrlsPop, corrTrlsNoise] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & inSeqLog, 'ISC Trials'); +% PlotPeriodDiffNoiseCorrs(corrTrlsNoise, 'ISC Trials'); +% +% [inCorrTrlsPop, inCorrTrlsNoise] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% ~perfLog & inSeqLog, 'ISIc Trials'); +% PlotPeriodDiffNoiseCorrs(inCorrTrlsNoise, 'ISIc Trials'); +% +% [aTrialsCorrPopISC, aTrialsCorrNoiseISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorAlog & inSeqLog, 'Odor A ISC'); +% PlotPeriodDiffNoiseCorrs(aTrialsCorrNoiseISC, 'Odor A ISC'); +% +% [bTrialsCorrPopISC, bTrialsCorrNoiseISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorBlog & inSeqLog, 'Odor B ISC'); +% PlotPeriodDiffNoiseCorrs(bTrialsCorrNoiseISC, 'Odor B ISC'); +% +% [cTrialsCorrPopISC, cTrialsCorrNoiseISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorClog & inSeqLog, 'Odor C ISC'); +% PlotPeriodDiffNoiseCorrs(cTrialsCorrNoiseISC, 'Odor C ISC'); +% +% [dTrialsCorrPopISC, dTrialsCorrNoiseISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorDlog & inSeqLog, 'Odor D ISC'); +% PlotPeriodDiffNoiseCorrs(dTrialsCorrNoiseISC, 'Odor D ISC'); +% +% [aTrialsCorrPopOSC, aTrialsCorrNoiseOSC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorAlog & outSeqLog, 'Odor A OSC'); +% PlotPeriodDiffNoiseCorrs(aTrialsCorrNoiseOSC, 'Odor A OSC'); +% +% [bTrialsCorrPopOSC, bTrialsCorrNoiseOSC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorBlog & outSeqLog, 'Odor B OSC'); +% PlotPeriodDiffNoiseCorrs(bTrialsCorrNoiseOSC, 'Odor B OSC'); +% +% [cTrialsCorrPopOSC, cTrialsCorrNoiseOSC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorClog & outSeqLog, 'Odor C OSC'); +% PlotPeriodDiffNoiseCorrs(cTrialsCorrNoiseOSC, 'Odor C OSC'); +% +% [dTrialsCorrPopOSC, dTrialsCorrNoiseOSC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorDlog & outSeqLog, 'Odor D OSC'); +% PlotPeriodDiffNoiseCorrs(dTrialsCorrNoiseOSC, 'Odor D OSC'); + +%% Only Trials from Complete InSeq Seqs +% [aTrialsCorrPopCompISC, aTrialsCorrNoiseCompISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorAlog & fullInSeqLog, 'Odor A Complete Seqs'); +% PlotPeriodDiffNoiseCorrs(aTrialsCorrNoiseCompISC, 'Odor A Complete Seqs'); +% +% [bTrialsCorrPopCompISC, bTrialsCorrNoiseCompISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorBlog & fullInSeqLog, 'Odor B Complete Seqs'); +% PlotPeriodDiffNoiseCorrs(bTrialsCorrNoiseCompISC, 'Odor B Complete Seqs'); +% +% [cTrialsCorrPopCompISC, cTrialsCorrNoiseCompISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorClog & fullInSeqLog, 'Odor C Complete Seqs'); +% PlotPeriodDiffNoiseCorrs(cTrialsCorrNoiseCompISC, 'Odor C Complete Seqs'); +% +% [dTrialsCorrPopCompISC, dTrialsCorrNoiseCompISC] = ExaminePopAndNoiseCorrs(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorDlog & fullInSeqLog, 'Odor D Complete Seqs'); +% PlotPeriodDiffNoiseCorrs(dTrialsCorrNoiseCompISC, 'Odor D Complete Seqs'); +% +% PlotOdorDiffNoiseCorrs(aTrialsCorrNoiseCompISC, bTrialsCorrNoiseCompISC, cTrialsCorrNoiseCompISC, dTrialsCorrNoiseCompISC, 'Complete IS') + +%% Run Permutations to derive 'significant' noise correlation values +% [~, aTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorAlog & fullInSeqLog, 1000, 'Odor A Complete Seqs'); +% +% [~, bTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorBlog & fullInSeqLog, 1000, 'Odor B Complete Seqs'); +% +% [~, cTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorClog & fullInSeqLog, 1000, 'Odor C Complete Seqs'); +% +% [~, dTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... +% perfLog & odorDlog & fullInSeqLog, 1000, 'Odor D Complete Seqs'); + +[~, aTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... + perfLog & odorAlog & inSeqLog, 1000, 'Odor A ISC'); + +[~, bTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... + perfLog & odorBlog & inSeqLog, 1000, 'Odor B ISC'); + +[~, cTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... + perfLog & odorClog & inSeqLog, 1000, 'Odor C ISC'); + +[~, dTrialsCorrNoiseCompISCz, ~, ~] = ExaminePopAndNoiseCorrsPerm(preTrialPopVectZall, rlyTrialPopVectZall, latTrialPopVectZall, pstTrialPopVectZall,... + perfLog & odorDlog & inSeqLog, 1000, 'Odor D ISC'); + +% PlotOdorDiffNoiseCorrs(aTrialsCorrNoiseCompISCz, bTrialsCorrNoiseCompISCz, cTrialsCorrNoiseCompISCz, dTrialsCorrNoiseCompISCz, 'Complete IS') + + +%% +% PlotOdorDiffNoiseCorrs(aTrialsCorrNoiseISC, bTrialsCorrNoiseISC, cTrialsCorrNoiseISC, dTrialsCorrNoiseISC, 'ISC') +% PlotOdorDiffNoiseCorrs(aTrialsCorrNoiseOSC, bTrialsCorrNoiseOSC, cTrialsCorrNoiseOSC, dTrialsCorrNoiseOSC, 'OSC') + + +end + +function [popCorrsZ, noiseCorrsZ, popCorrsChance, noiseCorrsChance] = ExaminePopAndNoiseCorrsPerm(preTrial, rlyTrial, latTrial, pstTrial, sortVect, numPerms, sortVectID) +%% Chance up that random stream +randperm(floor(sum(clock))); +threshVal = 0; +%% +preSorted = preTrial(sortVect,:); +rlySorted = rlyTrial(sortVect,:); +latSorted = latTrial(sortVect,:); +pstSorted = pstTrial(sortVect,:); + +noiseCorrs{1} = corr(preSorted); +popCorrs{1} = corr(preSorted'); + +noiseCorrs{2} = corr(rlySorted); +popCorrs{2} = corr(rlySorted'); + +noiseCorrs{3} = corr(latSorted); +popCorrs{3} = corr(latSorted'); + +noiseCorrs{4} = corr(pstSorted); +popCorrs{4} = corr(pstSorted'); + +noiseCorrsZ = repmat({nan(size(noiseCorrs{1}))}, 1, 4); +popCorrsZ = repmat({nan(size(popCorrs{1}))}, 1, 4); +noiseCorrsChance = repmat({nan(size(noiseCorrs{1},1), size(noiseCorrs{1},2), numPerms)},1,4); +popCorrsChance = repmat({nan(size(popCorrs{1},1), size(popCorrs{1},2), numPerms)},1,4); +for perm = 1:numPerms + tempPre = preSorted; + tempRly = rlySorted; + tempLat = latSorted; + tempPst = pstSorted; + + preIDmtx = reshape(1:length(tempPre(:)), size(tempPre,1), size(tempPre,2)); + for c = 1:size(preIDmtx,2) + preIDmtx(:,c) = preIDmtx(randperm(size(preIDmtx,1)),c); + end + noiseCorrsChance{1}(:,:,perm) = corr(tempPre(preIDmtx)); + popCorrsChance{1}(:,:,perm) = corr(tempPre(preIDmtx)'); + + rlyIDmtx = reshape(1:length(tempRly(:)), size(tempRly,1), size(tempRly,2)); + for c = 1:size(rlyIDmtx,2) + rlyIDmtx(:,c) = rlyIDmtx(randperm(size(rlyIDmtx,1)),c); + end + noiseCorrsChance{2}(:,:,perm) = corr(tempRly(rlyIDmtx)); + popCorrsChance{2}(:,:,perm) = corr(tempRly(rlyIDmtx)'); + + latIDmtx = reshape(1:length(tempLat(:)), size(tempLat,1), size(tempLat,2)); + for c = 1:size(latIDmtx,2) + latIDmtx(:,c) = latIDmtx(randperm(size(latIDmtx,1)),c); + end + noiseCorrsChance{3}(:,:,perm) = corr(tempLat(latIDmtx)); + popCorrsChance{3}(:,:,perm) = corr(tempLat(latIDmtx)'); + + pstIDmtx = reshape(1:length(tempPst(:)), size(tempPst,1), size(tempPst,2)); + for c = 1:size(pstIDmtx,2) + pstIDmtx(:,c) = pstIDmtx(randperm(size(pstIDmtx,1)),c); + end + noiseCorrsChance{4}(:,:,perm) = corr(tempPst(pstIDmtx)); + popCorrsChance{4}(:,:,perm) = corr(tempPst(pstIDmtx)'); +end +for nIr = 1:size(noiseCorrsZ{1},1) + for nIc = 1:size(noiseCorrsZ{1},2) + tempZpre = zscore([reshape(noiseCorrsChance{1}(nIr,nIc,:), 1, numPerms), noiseCorrs{1}(nIr,nIc)]); + noiseCorrsZ{1}(nIr,nIc) = tempZpre(end); + + tempZrly = zscore([reshape(noiseCorrsChance{2}(nIr,nIc,:), 1, numPerms), noiseCorrs{2}(nIr,nIc)]); + noiseCorrsZ{2}(nIr,nIc) = tempZrly(end); + + tempZlat = zscore([reshape(noiseCorrsChance{3}(nIr,nIc,:), 1, numPerms), noiseCorrs{3}(nIr,nIc)]); + noiseCorrsZ{3}(nIr,nIc) = tempZlat(end); + + tempZpst = zscore([reshape(noiseCorrsChance{4}(nIr,nIc,:), 1, numPerms), noiseCorrs{4}(nIr,nIc)]); + noiseCorrsZ{4}(nIr,nIc) = tempZpst(end); + end +end + +for pIr = 1:size(popCorrsZ{1},1) + for pIc = 1:size(popCorrsZ{1},2) + tempZpre = zscore([reshape(popCorrsChance{1}(pIr,pIc,:), 1, numPerms), popCorrs{1}(pIr,pIc)]); + popCorrsZ{1}(pIr,pIc) = tempZpre(end); + + tempZrly = zscore([reshape(popCorrsChance{2}(pIr,pIc,:), 1, numPerms), popCorrs{2}(pIr,pIc)]); + popCorrsZ{2}(pIr,pIc) = tempZrly(end); + + tempZlat = zscore([reshape(popCorrsChance{3}(pIr,pIc,:), 1, numPerms), popCorrs{3}(pIr,pIc)]); + popCorrsZ{3}(pIr,pIc) = tempZlat(end); + + tempZpst = zscore([reshape(popCorrsChance{4}(pIr,pIc,:), 1, numPerms), popCorrs{4}(pIr,pIc)]); + popCorrsZ{4}(pIr,pIc) = tempZpst(end); + end +end + +maxAbsZNoise = max(max(abs(cell2mat(noiseCorrsZ)))); +maxAbsZPop = max(max(abs(cell2mat(popCorrsZ)))); + +figure; +subplot(4,4,1) +PlotCombinedMatrix(noiseCorrs{1}, noiseCorrsZ{1}, maxAbsZNoise); +title('Pre Trial') +xlabel('Z-Normed') +ylabel('Observed') + +subplot(4,4,2) +PlotCombinedMatrix(noiseCorrsZ{2}, noiseCorrsZ{1}, maxAbsZNoise); +title('Pre vs Early') +xlabel('Pre'); +ylabel('Early'); + +subplot(4,4,3) +PlotCombinedMatrix(noiseCorrsZ{3}, noiseCorrsZ{1}, maxAbsZNoise); +title('Pre vs Late') +xlabel('Pre'); +ylabel('Late'); + +subplot(4,4,4) +PlotCombinedMatrix(noiseCorrsZ{4}, noiseCorrsZ{1}, maxAbsZNoise); +title('Pre vs Post') +xlabel('Pre'); +ylabel('Post'); + +subplot(4,4,5) +PlotNoiseCorrChanceDist(noiseCorrsChance{1}, noiseCorrsChance{2}, noiseCorrsZ{1}, noiseCorrsZ{2}); +% upperPre = ExtractUpperTriangle(noiseCorrsZ{1}); +% upperEarly = ExtractUpperTriangle(noiseCorrsZ{2}); +% log = (~isnan(upperPre) & ~isnan(upperEarly)) & (abs(upperPre)>=threshVal | abs(upperEarly)>=threshVal); +% corrScatPlot(upperPre(log),upperEarly(log), 'Pre','Early',[]); +title('Pre vs Early'); + +subplot(4,4,6) +PlotCombinedMatrix(noiseCorrs{2}, noiseCorrsZ{2}, maxAbsZNoise); +title('Early Trial') +xlabel('Z-Normed') +ylabel('Observed') + +subplot(4,4,7) +PlotCombinedMatrix(noiseCorrsZ{3}, noiseCorrsZ{2}, maxAbsZNoise); +title('Early vs Late') +xlabel('Early') +ylabel('Late') + +subplot(4,4,8) +PlotCombinedMatrix(noiseCorrsZ{4}, noiseCorrsZ{2}, maxAbsZNoise); +title('Early vs Post') +xlabel('Early') +ylabel('Post') + +subplot(4,4,9) +PlotNoiseCorrChanceDist(noiseCorrsChance{1}, noiseCorrsChance{3}, noiseCorrsZ{1}, noiseCorrsZ{3}); +% upperPre = ExtractUpperTriangle(noiseCorrsZ{1}); +% upperLate = ExtractUpperTriangle(noiseCorrsZ{3}); +% log = (~isnan(upperPre) & ~isnan(upperLate)) & (abs(upperPre)>=threshVal | abs(upperPre)>=threshVal); +% corrScatPlot(upperPre(log),upperLate(log), 'Pre','Late',[]); +title('Pre vs Late') + +subplot(4,4,10) +PlotNoiseCorrChanceDist(noiseCorrsChance{2}, noiseCorrsChance{3}, noiseCorrsZ{2}, noiseCorrsZ{3}); +% upperEarly = ExtractUpperTriangle(noiseCorrsZ{2}); +% upperLate = ExtractUpperTriangle(noiseCorrsZ{3}); +% log = (~isnan(upperEarly) & ~isnan(upperLate)) & (abs(upperEarly)>=threshVal | abs(upperLate)>=threshVal); +% corrScatPlot(upperEarly(log),upperLate(log), 'Early','Late',[]); +title('Early vs Late') + +subplot(4,4,11) +PlotCombinedMatrix(noiseCorrs{3}, noiseCorrsZ{3}, maxAbsZNoise); +title('Late Trial') +xlabel('Z-Normed') +ylabel('Observed') + +subplot(4,4,12) +PlotCombinedMatrix(noiseCorrsZ{4}, noiseCorrsZ{3}, maxAbsZNoise); +title('Late vs Post') +xlabel('Late') +ylabel('Post') + +subplot(4,4,13) +PlotNoiseCorrChanceDist(noiseCorrsChance{1}, noiseCorrsChance{4}, noiseCorrsZ{1}, noiseCorrsZ{4}); +% upperPre = ExtractUpperTriangle(noiseCorrsZ{1}); +% upperPost = ExtractUpperTriangle(noiseCorrsZ{4}); +% log = (~isnan(upperPre) & ~isnan(upperPost)) & (abs(upperPre)>=threshVal | abs(upperPost)>=threshVal); +% corrScatPlot(upperPre(log),upperPost(log), 'Pre','Post',[]); +title('Pre vs Post') + +subplot(4,4,14) +PlotNoiseCorrChanceDist(noiseCorrsChance{2}, noiseCorrsChance{4}, noiseCorrsZ{2}, noiseCorrsZ{4}); +% upperEarly = ExtractUpperTriangle(noiseCorrsZ{2}); +% upperPost = ExtractUpperTriangle(noiseCorrsZ{4}); +% log = (~isnan(upperEarly) & ~isnan(upperPost)) & (abs(upperEarly)>=threshVal | abs(upperPost)>=threshVal); +% corrScatPlot(upperEarly(log),upperPost(log), 'Early','Post',[]); +title('Early vs Post') + +subplot(4,4,15) +PlotNoiseCorrChanceDist(noiseCorrsChance{3}, noiseCorrsChance{4}, noiseCorrsZ{3}, noiseCorrsZ{4}); +% upperLate = ExtractUpperTriangle(noiseCorrsZ{3}); +% upperPost = ExtractUpperTriangle(noiseCorrsZ{4}); +% log = (~isnan(upperLate) & ~isnan(upperPost)) & (abs(upperLate)>=threshVal | abs(upperPost)>=threshVal); +% corrScatPlot(upperLate(log),upperPost(log), 'Late','Post',[]); +title('Late vs Post') + +subplot(4,4,16) +PlotCombinedMatrix(noiseCorrs{4}, noiseCorrsZ{4}, maxAbsZNoise); +title('Post Trial') +xlabel('Z-Normed') +ylabel('Observed') + +annotation('textbox', 'position', [0.025 0.935 0.7 0.05], 'String', ['\bf\fontsize{14}' sortVectID],... + 'linestyle', 'none', 'horizontalalignment', 'left'); +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +colormap jet +axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +axis(axesHandles,'square') +orient(gcf, 'tall'); +orient(gcf, 'landscape'); + +% +% figure; +% subplot(4,4,3) +% PlotCombinedMatrix(popCorrs{1}, popCorrsZ{1}, maxAbsZPop); +% subplot(4,4,7) +% PlotCombinedMatrix(popCorrs{2}, popCorrsZ{2}, maxAbsZPop); +% subplot(4,4,11) +% PlotCombinedMatrix(popCorrs{3}, popCorrsZ{3}, maxAbsZPop); +% subplot(4,4,15) +% PlotCombinedMatrix(popCorrs{4}, popCorrsZ{4}, maxAbsZPop); +% +% colormap jet +% +% axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +% axis(axesHandles,'square') +% orient(gcf, 'tall'); +% orient(gcf, 'landscape'); + +end + +%% +function PlotNoiseCorrChanceDist(chanceX, chanceY, realX, realY) +[upperRealX, ~] = ExtractUpperTriangle(realX); +[upperRealY, ~] = ExtractUpperTriangle(realY); +log = ~isnan(upperRealX) & ~isnan(upperRealY); +realCorr = corr(upperRealX(log), upperRealY(log)); +chanceCorr = nan(1,size(chanceX,3)); +for perm = 1:size(chanceX,3) + [upperX, ~] = ExtractUpperTriangle(chanceX(:,:,perm)); + [upperY, ~] = ExtractUpperTriangle(chanceY(:,:,perm)); + log = ~isnan(upperX) & ~isnan(upperY); + chanceCorr(perm) = corr(upperX(log), upperY(log)); +end +histogram(chanceCorr, -0.2:0.01:.2) +hold on; +line([realCorr, realCorr], get(gca, 'ylim'), 'color', 'r', 'linewidth', 2); +box off; +grid on; +set(gca, 'color', 'none'); +temp = zscore([chanceCorr, realCorr]); +xlabel(sprintf('Z = %.02f', temp(end))) +end +%% +function PlotCombinedMatrix(realVals, zVals, cMax) +[~, realMtxNanD] = ExtractUpperTriangle(realVals); +[~, zMtxNanD] = ExtractUpperTriangle(zVals); +imagesc(nansum(reshape([fliplr(realMtxNanD), fliplr(zMtxNanD')], size(realMtxNanD,1), size(realMtxNanD,2),2),3), [-cMax cMax]); +end + + +%% +function PlotPeriodDiffNoiseCorrs(mtx, id) +figure; +subplot(4,4,1) +imagesc(mtx{1}, [-1 1]); +title('Pre Trial'); + +subplot(4,4,2) +preUpper = ExtractUpperTriangle(mtx{1}); +rlyUpper = ExtractUpperTriangle(mtx{2}); +corrScatPlot(preUpper(~isnan(preUpper) & ~isnan(rlyUpper)),rlyUpper(~isnan(preUpper) & ~isnan(rlyUpper)), 'Pre','Early',[]); + +subplot(4,4,3) +preUpper = ExtractUpperTriangle(mtx{1}); +latUpper = ExtractUpperTriangle(mtx{3}); +corrScatPlot(preUpper(~isnan(preUpper) & ~isnan(latUpper)),latUpper(~isnan(preUpper) & ~isnan(latUpper)), 'Pre','Late',[]); + +subplot(4,4,4) +preUpper = ExtractUpperTriangle(mtx{1}); +pstUpper = ExtractUpperTriangle(mtx{4}); +corrScatPlot(preUpper(~isnan(preUpper) & ~isnan(pstUpper)),pstUpper(~isnan(preUpper) & ~isnan(pstUpper)), 'Pre','Post',[]); + +subplot(4,4,5) +imagesc(mtx{1} - mtx{2}, [-1 1]); +title('Pre - Early'); + +subplot(4,4,6) +imagesc(mtx{2}, [-1 1]); +title('Early Trial') + +subplot(4,4,7) +rlyUpper = ExtractUpperTriangle(mtx{2}); +latUpper = ExtractUpperTriangle(mtx{3}); +corrScatPlot(rlyUpper(~isnan(rlyUpper) & ~isnan(latUpper)),latUpper(~isnan(rlyUpper) & ~isnan(latUpper)), 'Early','Late',[]); + +subplot(4,4,8) +rlyUpper = ExtractUpperTriangle(mtx{2}); +pstUpper = ExtractUpperTriangle(mtx{4}); +corrScatPlot(rlyUpper(~isnan(rlyUpper) & ~isnan(pstUpper)),pstUpper(~isnan(rlyUpper) & ~isnan(pstUpper)), 'Early','Post',[]); + +subplot(4,4,9) +imagesc(mtx{1}-mtx{3}, [-1 1]); +title('Pre - Late'); + +subplot(4,4,10) +imagesc(mtx{2}-mtx{3}, [-1 1]); +title('Early - Late'); + +subplot(4,4,11) +imagesc(mtx{3}, [-1 1]); +title('Late Trial'); + +subplot(4,4,12) +latUpper = ExtractUpperTriangle(mtx{3}); +pstUpper = ExtractUpperTriangle(mtx{4}); +corrScatPlot(latUpper(~isnan(latUpper) & ~isnan(pstUpper)),pstUpper(~isnan(latUpper) & ~isnan(pstUpper)), 'Early','Post',[]); + +subplot(4,4,13) +imagesc(mtx{1}-mtx{4}, [-1 1]); +title('Pre - Post'); + +subplot(4,4,14) +imagesc(mtx{2}-mtx{4}, [-1 1]); +title('Early - Post'); + +subplot(4,4,15) +imagesc(mtx{3}-mtx{4}, [-1 1]); +title('Late - Post'); + +subplot(4,4,16) +imagesc(mtx{4}, [-1 1]); +title('Post Trial'); + +annotation('textbox', 'position', [0.025 0.935 0.7 0.05], 'String', ['\bf\fontsize{14}' id],... + 'linestyle', 'none', 'horizontalalignment', 'left'); + +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +colormap jet + +axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +axis(axesHandles,'square') +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +end + +%% +function [upperMtxVect, lowerMtxNand] = ExtractUpperTriangle(mtx) +upperLog = triu(true(size(mtx,1)),1); +upperMtxVect = mtx(upperLog); +lowerMtxNand = mtx; +lowerMtxNand(~upperLog) = nan; +end + +%% +function PlotOdorDiffNoiseCorrs(aTrialsCorrNoise, bTrialsCorrNoise, cTrialsCorrNoise, dTrialsCorrNoise, id) +trlPrdIDs = [{'Pre-Trial'}, {'Early-Trial'}, {'Late-Trial'}, {'Post-Trial'}]; +for trlPrd = 1:4 + currA = aTrialsCorrNoise{trlPrd}; + currB = bTrialsCorrNoise{trlPrd}; + currC = cTrialsCorrNoise{trlPrd}; + currD = dTrialsCorrNoise{trlPrd}; + figure; + abDiff = currA - currB; + subplot(4,4,2) + imagesc(abDiff, [-1 1]); + title('A-B') + subplot(4,4,5) + upperA = ExtractUpperTriangle(currA); + upperB = ExtractUpperTriangle(currB); + corrScatPlot(upperA(~isnan(upperA) & ~isnan(upperB)),upperB(~isnan(upperA) & ~isnan(upperB)), 'A','B',[]); + set(gca, 'xlim', [-1 1], 'ylim', [-1 1]); +% histogram(abDiff(logical(triu(ones(size(abDiff)),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); + set(gca, 'color', 'none', 'box', 'off'); + grid on + hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + title('A vs B') + + acDiff = currA - currC; + subplot(4,4,3) + imagesc(acDiff, [-1 1]); + title('A-C') + subplot(4,4,9) + upperA = ExtractUpperTriangle(currA); + upperC = ExtractUpperTriangle(currC); + corrScatPlot(upperA(~isnan(upperA) & ~isnan(upperC)),upperC(~isnan(upperA) & ~isnan(upperC)), 'A','C',[]); + set(gca, 'xlim', [-1 1], 'ylim', [-1 1]); +% histogram(acDiff(logical(triu(ones(size(acDiff)),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); + set(gca, 'color', 'none', 'box', 'off'); + grid on + hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + title('A vs C') + + adDiff = currA - currD; + subplot(4,4,4) + imagesc(adDiff, [-1 1]); + title('A-D') + subplot(4,4,13) + upperA = ExtractUpperTriangle(currA); + upperD = ExtractUpperTriangle(currD); + corrScatPlot(upperA(~isnan(upperA) & ~isnan(upperD)),upperD(~isnan(upperA) & ~isnan(upperD)), 'A','D',[]); + set(gca, 'xlim', [-1 1], 'ylim', [-1 1]); +% histogram(adDiff(logical(triu(ones(size(adDiff)),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); + set(gca, 'color', 'none', 'box', 'off'); + grid on + hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + title('A vs D') + + bcDiff = currB - currC; + subplot(4,4,7) + imagesc(bcDiff, [-1 1]); + title('B-C') + subplot(4,4,10) + upperB = ExtractUpperTriangle(currB); + upperC = ExtractUpperTriangle(currC); + corrScatPlot(upperB(~isnan(upperB) & ~isnan(upperC)),upperC(~isnan(upperB) & ~isnan(upperC)), 'B','C',[]); + set(gca, 'xlim', [-1 1], 'ylim', [-1 1]); +% histogram(bcDiff(logical(triu(ones(size(bcDiff)),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); + set(gca, 'color', 'none', 'box', 'off'); + grid on + hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + title('B vs C') + + bdDiff = currB - currD; + subplot(4,4,8) + imagesc(bdDiff, [-1 1]); + title('B-D') + subplot(4,4,14) + upperB = ExtractUpperTriangle(currB); + upperD = ExtractUpperTriangle(currD); + corrScatPlot(upperB(~isnan(upperB) & ~isnan(upperD)),upperD(~isnan(upperB) & ~isnan(upperD)), 'B','D',[]); + set(gca, 'xlim', [-1 1], 'ylim', [-1 1]); +% histogram(bdDiff(logical(triu(ones(size(bdDiff)),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); + set(gca, 'color', 'none', 'box', 'off'); + grid on + hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + title('B vs D') + + cdDiff = currC - currD; + subplot(4,4,12) + imagesc(cdDiff, [-1 1]); + title('C-D') + subplot(4,4,15) + upperC = ExtractUpperTriangle(currC); + upperD = ExtractUpperTriangle(currD); + corrScatPlot(upperC(~isnan(upperC) & ~isnan(upperD)),upperD(~isnan(upperC) & ~isnan(upperD)), 'C','D',[]); + set(gca, 'xlim', [-1 1], 'ylim', [-1 1]); +% histogram(cdDiff(logical(triu(ones(size(cdDiff)),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); + set(gca, 'color', 'none', 'box', 'off'); + grid on + hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'k', 'linewidth', 2); + title('C vs D') + + annotation('textbox', 'position', [0.025 0.935 0.7 0.05], 'String', ['\bf\fontsize{14}' sprintf('%s %s', trlPrdIDs{trlPrd}, id)],... + 'linestyle', 'none', 'horizontalalignment', 'left'); + + curDir = cd; + annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + + colormap jet + + axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); + axis(axesHandles,'square') + orient(gcf, 'tall'); + orient(gcf, 'landscape'); +end +end + +%% +function [popCorrs, noiseCorrs] = ExaminePopAndNoiseCorrs(preTrial, rlyTrial, latTrial, pstTrial, sortVect, sortVectID) +preSorted = preTrial(sortVect,:); +rlySorted = rlyTrial(sortVect,:); +latSorted = latTrial(sortVect,:); +pstSorted = pstTrial(sortVect,:); + +figure; +subplot(4,4,1) +noiseCorrs{1} = corr(preSorted); +imagesc(noiseCorrs{1}, [-1 1]); +title('Pre-Trial Period: Unit Noise Correlations'); +subplot(4,4,2) +histogram(noiseCorrs{1}(logical(triu(ones(size(noiseCorrs{1})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); +subplot(4,4,3) +popCorrs{1} = corr(preSorted'); +imagesc(popCorrs{1}, [-1 1]); +title('Trial Population Correlations'); +subplot(4,4,4) +histogram(popCorrs{1}(logical(triu(ones(size(popCorrs{1})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); + +subplot(4,4,5) +noiseCorrs{2} = corr(rlySorted); +imagesc(noiseCorrs{2}, [-1 1]); +title('Early-Trial Period: Unit Noise Correlations'); +subplot(4,4,6) +histogram(noiseCorrs{2}(logical(triu(ones(size(noiseCorrs{2})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); +subplot(4,4,7) +popCorrs{2} = corr(rlySorted'); +imagesc(popCorrs{2}, [-1 1]); +title('Trial Population Correlations'); +subplot(4,4,8) +histogram(popCorrs{2}(logical(triu(ones(size(popCorrs{2})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); + +subplot(4,4,9) +noiseCorrs{3} = corr(latSorted); +imagesc(noiseCorrs{3}, [-1 1]); +title('Late-Trial Period: Unit Noise Correlations'); +subplot(4,4,10) +histogram(noiseCorrs{3}(logical(triu(ones(size(noiseCorrs{3})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); +subplot(4,4,11) +popCorrs{3} = corr(latSorted'); +imagesc(popCorrs{3}, [-1 1]); +title('Trial Population Correlations'); +subplot(4,4,12) +histogram(popCorrs{3}(logical(triu(ones(size(popCorrs{3})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); + +subplot(4,4,13) +noiseCorrs{4} = corr(pstSorted); +imagesc(noiseCorrs{4}, [-1 1]); +title('Post-Trial Period: Unit Noise Correlations'); +subplot(4,4,14) +histogram(noiseCorrs{4}(logical(triu(ones(size(noiseCorrs{4})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); +subplot(4,4,15) +popCorrs{4} = corr(pstSorted'); +imagesc(popCorrs{4}, [-1 1]); +title('Trial Population Correlations'); +subplot(4,4,16) +histogram(popCorrs{4}(logical(triu(ones(size(popCorrs{4})),1))), -1:0.01:1, 'edgecolor', 'none', 'facecolor', 'k'); +set(gca, 'color', 'none', 'box', 'off'); +grid on +hold on +% line([0 0], get(gca,'ylim'), 'linestyle', ':', 'color', 'r', 'linewidth', 1); + +annotation('textbox', 'position', [0.025 0.935 0.7 0.05], 'String', ['\bf\fontsize{14}' sortVectID],... + 'linestyle', 'none', 'horizontalalignment', 'left'); + +curDir = cd; +annotation('textbox', 'position', [0.025 0.025 0.7 0.05], 'String', curDir,... + 'linestyle', 'none', 'horizontalalignment', 'left', 'interpreter', 'none'); + +colormap jet + +axesHandles = findobj(get(gcf,'Children'), 'flat','Type','axes'); +axis(axesHandles,'square') +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +end + + diff --git a/Analyses/Prototypes/PFC_DualList_PROTO.m b/Analyses/Prototypes/PFC_DualList_PROTO.m new file mode 100644 index 0000000..17eb7c4 --- /dev/null +++ b/Analyses/Prototypes/PFC_DualList_PROTO.m @@ -0,0 +1,44 @@ + +origDir = cd; +[fileDir] = uigetdir(origDir); +if fileDir==0 + disp('Analysis Cancelled') + return +else + cd(fileDir) +end +dirContents = dir(fileDir); +fileNames = {dirContents.name}; + +%% Define Standard Variables +slideWindowSize = 100; +spatialBinSize = 5; +numPerms = 50; + +% Create Gaussian +instFRgauss = gausswin(slideWindowSize); +instFRgauss = instFRgauss/(length(instFRgauss)*mode(diff(behavMatrix(:,1)))); + +%% Load Relevant Data +load(fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}); +% load(fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}); + +%% +pokeInTrialMatrix = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [-0.2 0.5], 'PokeIn'); +pokeInTSs = behavMatrix(pokeInTrialMatrix(1).TrialLogVect,1)-behavMatrix(pokeInTrialMatrix(1).PokeInIndex,1); +pokeOutTrialMatrix = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [-0.5 0.2], 'PokeOut'); +pokeOutTSs = behavMatrix(pokeOutTrialMatrix(1).TrialLogVect,1)-behavMatrix(pokeOutTrialMatrix(1).PokeOutIndex,1); + +% Create Trial Logical Vectors +corrTrlLog = [pokeInTrialMatrix.Performance]; +isLog = [pokeInTrialMatrix.TranspositionDistance]==0; +pos1log = [pokeInTrialMatrix.Position]==1; +% trialLog = (corrTrlLog & isLog & ~pos1log); +% seqType = 'All InSeq Correct Except Position 1'; +trialLog = (corrTrlLog & isLog); +seqType = 'All InSeq Correct Trials'; +% trialLog = (corrTrlLog); +% seqType = 'All Correct Trials'; +posIDsISC = [pokeInTrialMatrix(trialLog).Position]; +odorIDsISC = [pokeInTrialMatrix(trialLog).Odor]; +%% \ No newline at end of file diff --git a/Analyses/Prototypes/SequenceNeuralViewer_SM PROTO.m b/Analyses/Prototypes/SequenceNeuralViewer_SM PROTO.m new file mode 100644 index 0000000..ad7d479 --- /dev/null +++ b/Analyses/Prototypes/SequenceNeuralViewer_SM PROTO.m @@ -0,0 +1,163 @@ +function SequenceNeuralViewer_SM +%% + +%% Load data +[smFile,smPath] = uigetfile('*.mat'); +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath behMatFile]); +load([smPath nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Organize Ensemble Data +% Declare histogram bin size for peak FR latency decision +histBins = 0:0.1:1.2; + +% Extract session variables & ensemble FR +behavMatrixTrialStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [min(histBins) max(histBins)], 'PokeIn'); +ensembleTrialData = ExtractTrialData_SM(behavMatrixTrialStruct, ensembleMatrix(:,2:end)); %#ok<*NODEF> +trialTSvect = behavMatrix(behavMatrixTrialStruct(1).TrialLogVect,1)-behavMatrix(behavMatrixTrialStruct(1).PokeInIndex,1); +inSeqLog = [behavMatrixTrialStruct.TranspositionDistance]==0; +perfLog = [behavMatrixTrialStruct.Performance]==1; +oAlog = [behavMatrixTrialStruct.Position]==1; +% iscEnsembleData = ensembleTrialData(inSeqLog & perfLog); +iscEnsembleData = ensembleTrialData(inSeqLog & perfLog & ~oAlog); + +% Bin trial wise FR +iscEnsembleDataBinned = nan(length(histBins)-1, length(ensembleUnitSummaries), length(iscEnsembleData)); +for tr = 1:length(iscEnsembleData) + for uni = 1:length(ensembleUnitSummaries) + iscEnsembleDataBinned(:,uni,tr) = histcounts(trialTSvect(logical(iscEnsembleData{tr}(:,uni))), histBins, 'Normalization', 'CountDensity'); + end +end +meanISCbinned = mean(iscEnsembleDataBinned,3); + +% Normalize the FR and identify the peak FR bin +iscBinnedNormed = nan(size(meanISCbinned)); +iscPeakLat = nan(size(meanISCbinned,2),3); +for uni = 1:size(meanISCbinned,2); + iscBinnedNormed(:,uni) = meanISCbinned(:,uni)./max(meanISCbinned(:,uni)); + curPeakLat = find(iscBinnedNormed(:,uni)==1,1,'first'); + if isempty(curPeakLat) + iscPeakLat(uni,:) = [size(iscBinnedNormed,1), uni, max(meanISCbinned(:,uni))]; + else + iscPeakLat(uni,:) = [curPeakLat, uni, max(meanISCbinned(:,uni))]; + end +end +% Select cells based on peak FR value +trialFRthreshLog = iscPeakLat(:,3)<1; +iscBinnedNormed(:,trialFRthreshLog) = []; +iscPeakLat(trialFRthreshLog,:) = []; + +% Separate out principal cells vs interneurons using spike width... +%%%%% NOTE: This value is chosen by eye based on the data currently... a +%%%%% more principled method for choosing the value should be used in the +%%%%% future +spkWdth = [ensembleUnitSummaries(~trialFRthreshLog).Spike_Width]*40; +spkRt = [ensembleUnitSummaries(~trialFRthreshLog).Mean_SpikeRate]; +% Width Based +% widthThresh = 0.45; +% pcLog = (spkWdth>widthThresh; +% Spike Rate Based +spkRtThresh = 5; +pcLog = spkRt'))); +lfpBands = cellfun(@(a,b)a(b:end), statMatrixColIDs(lfpColIDs), regexp(statMatrixColIDs(lfpColIDs), '[(A-Z)|(a-z)]*\>'), 'uniformoutput', 0); +lfpVals = statMatrix(:,lfpColIDs(strcmp(lfpBands, band2plot))); +lfpVals = lfpVals/(max(abs(lfpVals))); + +plot(statMatrix(:,1), lfpVals-1, 'color', [0.4 0.4 0.4]); + +% Plot Spikes +hold on; +for uni = 1:size(uniScatData,2) + scatter(uniScatData{1,uni}, uniScatData{2,uni}, '*k'); +end +set(gca, 'ydir', 'reverse', 'color', 'none'); + +% Patch Trial Periods +for trl = 1:length(behavMatrixTrialStruct) + switch behavMatrixTrialStruct(trl).Odor + case 1 + patchColor = [44/255 168/255 224/255]; + case 2 + patchColor = [154/255 133/255 122/255]; + case 3 + patchColor = [9/255 161/255 74/255]; + case 4 + patchColor = [128/255 66/255 151/255]; + case 5 + patchColor = 'k'; + end + patch(gca, 'XData', [behavMatrix(behavMatrixTrialStruct(trl).PokeInIndex,1), behavMatrix(behavMatrixTrialStruct(trl).PokeOutIndex,1), behavMatrix(behavMatrixTrialStruct(trl).PokeOutIndex,1),behavMatrix(behavMatrixTrialStruct(trl).PokeInIndex,1)],... + 'YData', [zeros(1,2), repmat(icScatData{2,end}(1)+1,[1,2])],... + 'FaceColor', patchColor, 'FaceAlpha', 0.15,... + 'EdgeColor', patchColor); +end + +%% +figure; +scatter([ensembleUnitSummaries.Mean_SpikeRate], [ensembleUnitSummaries.Spike_Width]*40); set(gca, 'xscale', 'log') +%% Create Figure +seqViewFig = figure; +figAxes = axes(seqViewFig, 'position', [0.25, 0.1, 0.7, 0.85]); +set(figAxes, 'ydir', 'reverse', 'color', 'none'); + +% UI Control Buttons +selectFilebtn = uicontrol(artifactRemovalFig, 'Units', 'Normalized', 'Style', 'listbox', 'String', smFileList,... + 'Position', [0.0375,0.65,0.125,0.28],'Callback', @selectFile); + +%% \ No newline at end of file diff --git a/Analyses/RippleAnalysis_SM.m b/Analyses/RippleAnalysis_SM.m new file mode 100644 index 0000000..5cb15e2 --- /dev/null +++ b/Analyses/RippleAnalysis_SM.m @@ -0,0 +1,502 @@ +% SWR Detection +%% Define Analysis Features +envProc = 'RMS'; % Enable for RMS determination of envelope +% envProc = 'HILB'; % Enable for abs(Hilbert) determinination of envelope +% %% Thresholds %% % +% Power Threshold % +powThresh1 = 0; % Threshold 1 +powThresh2 = 4; % Threshold 2 +% Duration Thresholds % +durThresh = 15; % Duration Threshold +durThreshMrg = 15; % Merge Duration Threshold +% Synchrony Threshold % +syncThresh = 0; % Synchrony Threshold + +% %% Parameters %% % +% Synchrony Duration % % Not going to worry about this for now... as it will likely be computationally inefficient +syncWin = 10; +% Smoothing Vector % +w = gausswin(21); +w = w/sum(w); + +% %% Trial Windows %% % +% Pre-Trial Window +preTrlWin = 500; +% Post-Trial Window +pstTrlWin = 700; +%% Load Data +origDir = cd; +[fileDir] = uigetdir(origDir); +if fileDir==0 + disp('Analysis Cancelled') + return +else + cd(fileDir) +end +dirContents = dir(fileDir); +fileNames = {dirContents.name}; +tetFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_T([0-9]*)_SM.mat')); +tetFiles = fileNames(tetFileLog)'; +behavFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_BehaviorMatrix')); +ensembleFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_EnsembleMatrix')); +load(fileNames{behavFileLog}); +load(fileNames{ensembleFileLog}); +behavMatrixTrialStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0], 'PokeIn'); + +poi = [behavMatrixTrialStruct.PokeOutIndex]; +ri = [behavMatrixTrialStruct.RewardIndex]; +if length(poi)~=length(ri) + ri(end:end+(length(poi)-length(ri)))=nan; +end +dif = ri-poi; +perfLog = [behavMatrixTrialStruct.Performance]==1; +isLog = [behavMatrixTrialStruct.TranspositionDistance]==0; +iscLog = perfLog & isLog; +isiLog = ~perfLog & isLog; +oscLog = perfLog & ~isLog; +osiLog = ~perfLog & ~isLog; + +figure; +subplot(2,2,1); +histogram(dif(iscLog)); +title('InSeq Correct'); +subplot(2,2,2); +histogram(dif(isiLog)); +title('InSeq Incorrect'); +subplot(2,2,3); +histogram(dif(osiLog)); +title('OutSeq Incorrect'); +subplot(2,2,4); +histogram(dif(oscLog)); +title('OutSeq Correct'); + +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); + +annotation('textbox', 'position', [0.1 0.95 0.8 0.05], 'string',... + '\bfReward Delivery Latency (relative to port withdrawal)', 'horizontalalignment', 'center',... + 'linestyle', 'none', 'fontsize', 15); +%% Extract Raw Values & Compute RMS Power +ripBPF = nan(size(behavMatrix,1),size(tetFiles,1)); +ripVolts = nan(size(behavMatrix,1),size(tetFiles,1)); +ripRMS = nan(size(behavMatrix,1),size(tetFiles,1)); +ripHilb = nan(size(behavMatrix,1),size(tetFiles,1)); +ripTetIDs = cell(size(tetFiles)); +for fl = 1:length(tetFiles) + load(tetFiles{fl}) + samp = mode(diff(statMatrix(:,1))); + wIndx = round((1/200)*(1/samp)); + fprintf('%s......', tetFiles{fl}); + ripCol = find(cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, 'LFP_Ripple$'))); + ripVolts(:,fl) = statMatrix(:,2); + if strcmp(envProc, 'RMS') + ripRMS(:,fl) = conv(sqrt(conv(statMatrix(:,ripCol).^2, ones(wIndx,1)/wIndx, 'same')), w, 'same'); + elseif strcmp(envProc, 'HILB') + ripRMS(:,fl) = conv(abs(hilbert(statMatrix(:,ripCol))),w,'same'); + end + ripBPF(:,fl) = statMatrix(:,ripCol); + ripHilb(:,fl) = statMatrix(:,ripCol+1); + ripTetIDs{fl} = statMatrixColIDs{ripCol}; + fprintf('done\n'); +end +%% Calculate Thresholds +% Aggregate Power +aggPower = mean(ripRMS,2); aggType = 'Mean'; % Mean envelope +% aggPower = zscore(mean(ripRMS,2)); aggType = 'zMean'; % Z-Score Mean envelope +% aggPower = mean(zscore(ripRMS),2); aggType = 'MeanZ'; % Mean Z-Score envelope + +% Threshold Based on Mean +/- STD Aggregate Power +rmsThresh1 = (mean(aggPower) + (powThresh1*std(aggPower))); +rmsThresh2 = (mean(aggPower) + (powThresh2*std(aggPower))); + +%% Identify Ripples +% Define putative ripple periods +abvThresh1 = aggPower>rmsThresh1; +epocWindows = [find(diff(abvThresh1)==1), find(diff(abvThresh1)==-1)]; + +% Apply secondary (peak power) threshold +abvThresh2 = aggPower>rmsThresh2; +dualThreshLog = false(size(epocWindows,1),1); +for epoc = 1:size(epocWindows,1) + if sum(abvThresh2(epocWindows(epoc,1):epocWindows(epoc,2))) >=1 + dualThreshLog(epoc) = true; + end +end +epocWindows(~dualThreshLog,:) = []; % Comment out if not using dual thresholds + +% Merge short latency ripples +interEpocInterval = epocWindows(2:end,1) - epocWindows(1:end-1,2); +slrLog = interEpocIntervalmedian(epocDur) + set(gca, 'ytick', [median(epocDur), mean(epocDur)], 'yticklabel', [{'Median'}, {'Mean'}]); +else + set(gca, 'ytick', [mean(epocDur), median(epocDur)], 'yticklabel', [{'Mean'}, {'Median'}]); +end +xlabel('Count'); +ylabel([{'Ripple Duration'}; sprintf('Mean: %0.2f; Median: %0.2f', mean(epocDur), median(epocDur))]); +corre = subplot(4,4,[2:4,6:8,10:12]); +corrScatPlot(epocSync, epocDur, [], [], []); +title('Session Wide Ripple Duration vs Mean Synchrony'); +set(gca, 'xticklabel', [], 'yticklabel', []); +sync = subplot(4,4,14:16); +histogram(epocSync, 30); +xlabel('Synchrony (r)'); +ylabel('Count'); + +linkaxes([dur, corre], 'y'); +linkaxes([sync, corre], 'x'); +annotation('textbox', 'position', [0.01 0.01 0.9 0.05], 'string',... + sprintf('%s', cd), 'linestyle', 'none', 'interpreter', 'none'); +annotation('textbox', 'position', [0.01 0.95 0.9 0.05], 'string',... + sprintf('\\bfThreshold: \\rm+%i(+%i)SD; \\bfEnvelope = \\rm%s; \\bfAggregate = \\rm%s; \\bfMerge \\bfThreshold = \\rm%i ms', powThresh1 ,powThresh2, envProc, aggType, durThreshMrg),... + 'linestyle', 'none'); + +%% Extract Near-Trial Epocs +trialPokeTimes = [[behavMatrixTrialStruct.PokeInIndex]', [behavMatrixTrialStruct.PokeOutIndex]']; +trialRips = cell(size(trialPokeTimes,1),3); +trialRipLat = cell(size(trialPokeTimes,1),3); +trialRipsDur = cell(size(trialPokeTimes,1),3); +trialRipsSync = cell(size(trialPokeTimes,1),3); +for trl = 1:size(trialPokeTimes,1) + preTrlLog = epocWindows(:,1)>(trialPokeTimes(trl,1)-preTrlWin) & epocWindows(:,1)trialPokeTimes(trl,1) & epocWindows(:,1)trialPokeTimes(trl,2) & (epocWindows(:,1) +%% +if nargin == 0 + envProc = 'RMS'; % Enable for RMS determination of envelope + % envProc = 'HILB'; % Enable for abs(Hilbert) determinination of envelope + powThresh = [0 4]; + durThresh = 15; % Duration Threshold + durThreshMrg = 15; + syncThresh = 0; + syncWin = 10; + smoothWin = 21; +end +%% +%% Define Analysis Features +w = gausswin(smoothWin); +w = w/sum(w); +%% Load Data +origDir = cd; +[fileDir] = uigetdir(origDir); +if fileDir==0 + disp('Analysis Cancelled') + return +else + cd(fileDir) +end +dirContents = dir(fileDir); +fileNames = {dirContents.name}; +tetFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_T([0-9]*)_SM.mat')); +tetFiles = fileNames(tetFileLog)'; +behavFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_BehaviorMatrix')); +ensembleFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_EnsembleMatrix')); +load(fileNames{behavFileLog}); +load(fileNames{ensembleFileLog}); +behavMatrixTrialStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0], 'PokeIn'); + +%% Extract Raw Values & Compute RMS Power +ripBPF = nan(size(behavMatrix,1),size(tetFiles,1)); +ripVolts = nan(size(behavMatrix,1),size(tetFiles,1)); +ripRMS = nan(size(behavMatrix,1),size(tetFiles,1)); +ripHilb = nan(size(behavMatrix,1),size(tetFiles,1)); +ripTetIDs = cell(size(tetFiles)); +for fl = 1:length(tetFiles) + load(tetFiles{fl}) + samp = mode(diff(statMatrix(:,1))); + wIndx = round((1/200)*(1/samp)); + fprintf('%s......', tetFiles{fl}); + ripCol = find(cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, 'LFP_Ripple$'))); + ripVolts(:,fl) = statMatrix(:,2); + if strcmp(envProc, 'RMS') + ripRMS(:,fl) = conv(sqrt(conv(statMatrix(:,ripCol).^2, ones(wIndx,1)/wIndx, 'same')), w, 'same'); + elseif strcmp(envProc, 'HILB') + ripRMS(:,fl) = conv(abs(hilbert(statMatrix(:,ripCol))),w,'same'); + end + ripBPF(:,fl) = statMatrix(:,ripCol); + ripHilb(:,fl) = statMatrix(:,ripCol+1); + ripTetIDs{fl} = statMatrixColIDs{ripCol}; + fprintf('done\n'); +end + +%% Calculate Thresholds +% Aggregate Power +aggPower = mean(ripRMS,2); % Mean envelope +% aggPower = zscore(mean(ripRMS,2)); % Z-Score Mean envelope +% aggPower = mean(zscore(ripRMS),2); % Mean Z-Score envelope + +% Threshold Based on Mean +/- STD Aggregate Power +rmsThresh1 = (mean(aggPower) + (powThresh(1)*std(aggPower))); +rmsThresh2 = (mean(aggPower) + (powThresh(2)*std(aggPower))); + +%% Identify Ripples +% Define putative ripple periods +abvThresh1 = aggPower>rmsThresh1; +epocWindows = [find(diff(abvThresh1)==1), find(diff(abvThresh1)==-1)]; + +% Apply secondary (peak power) threshold +abvThresh2 = aggPower>rmsThresh2; +dualThreshLog = false(size(epocWindows,1),1); +for epoc = 1:size(epocWindows,1) + if sum(abvThresh2(epocWindows(epoc,1):epocWindows(epoc,2))) >=1 + dualThreshLog(epoc) = true; + end +end +epocWindows(~dualThreshLog,:) = []; % Comment out if not using dual thresholds + +% Merge short latency ripples +interEpocInterval = epocWindows(2:end,1) - epocWindows(1:end-1,2); +slrLog = interEpocInterval=1); +end + +%% Organize Data Output +rips = struct(... + 'TimeStamps', statMatrix(:,1),... + 'Ripples', struct('Events', epocWindows, 'Duration', epocDur,... + 'Synchrony', epocSync, 'EnsembleActivity', epocNsmblAct),... + 'SessionData', struct('RawLFP', ripVolts, 'RipBPF', ripBPF,... + 'RipEnv', ripRMS, 'RipPhase', ripHilb, 'TetIDs', {ripTetIDs},... + 'Spikes', spkMtxSorted),... + 'TrialInfo', struct('Perf', [behavMatrixTrialStruct.Performance]==1,... + 'TransDist', [behavMatrixTrialStruct.TranspositionDistance],... + 'OdorVect', [behavMatrixTrialStruct.Odor],... + 'PositionVect', [behavMatrixTrialStruct.Position],... + 'TrialPokes', [[behavMatrixTrialStruct.PokeInIndex]', [behavMatrixTrialStruct.PokeOutIndex]'],... + 'TrialRewards', [behavMatrixTrialStruct.RewardIndex]),... + 'FileInfo', struct('Directory', cd, 'EnvelopeProcedure', envProc,... + 'PowerThreshold', powThresh, 'DurationThreshold', durThresh,... + 'DurationMergeThreshold', durThreshMrg,... + 'SynchronyThreshold', syncThresh, 'SynchronyWindow', syncWin,... + 'GaussianDuration', smoothWin)); +end \ No newline at end of file diff --git a/Analyses/SequenceNeuralViewer_SM.m b/Analyses/SequenceNeuralViewer_SM.m new file mode 100644 index 0000000..f2dcec4 --- /dev/null +++ b/Analyses/SequenceNeuralViewer_SM.m @@ -0,0 +1,166 @@ +function SequenceNeuralViewer_SM +%% Declare Runtime Variables + +% Histogram bins for peak FR latency decision +histBins = -1.2:0.1:1.2; +% FR threshold for trial period firing for inclusion in plot +trialFRthresh = 0.1; +% Spike width threshold for PC determination +widthThresh = 0.6; +% Spike rate threshold for PC determination +spkRtThresh = 4; +% LFP Band to plot +band2plot = 'Raw'; +%% Load data +[smFile,smPath] = uigetfile('*.mat'); +cd(smPath); +files = dir(smPath); +fileNames = {files.name}; +% Load the behavior matrix file for poke events plots +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath behMatFile]); +load([smPath nsmblMatFile]); +% Identify list of all statMatrix files +smFileList = fileNames(cellfun(@(a)~isempty(a), regexp(fileNames, '_SM\>')))'; + +%% Organize Ensemble Data +% Extract session variables & ensemble FR +behavMatrixTrialStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [min(histBins) max(histBins)], 'PokeIn'); +ensembleTrialData = ExtractTrialData_SM(behavMatrixTrialStruct, ensembleMatrix(:,2:end)); %#ok<*NODEF> +trialTSvect = behavMatrix(behavMatrixTrialStruct(1).TrialLogVect,1)-behavMatrix(behavMatrixTrialStruct(1).PokeInIndex,1); +inSeqLog = [behavMatrixTrialStruct.TranspositionDistance]==0; +perfLog = [behavMatrixTrialStruct.Performance]==1; +oAlog = [behavMatrixTrialStruct.Position]==1; +% iscEnsembleData = ensembleTrialData(inSeqLog & perfLog); +iscEnsembleData = ensembleTrialData(inSeqLog & perfLog & oAlog); + +% Bin trial wise FR +iscEnsembleDataBinned = nan(length(histBins)-1, length(ensembleUnitSummaries), length(iscEnsembleData)); +for tr = 1:length(iscEnsembleData) + for uni = 1:length(ensembleUnitSummaries) + iscEnsembleDataBinned(:,uni,tr) = histcounts(trialTSvect(logical(iscEnsembleData{tr}(:,uni))), histBins, 'Normalization', 'CountDensity'); + end +end +meanISCbinned = mean(iscEnsembleDataBinned,3); + +% Normalize the FR and identify the peak FR bin +iscBinnedNormed = nan(size(meanISCbinned)); +iscPeakLat = nan(size(meanISCbinned,2),3); +for uni = 1:size(meanISCbinned,2) + iscBinnedNormed(:,uni) = meanISCbinned(:,uni)./max(meanISCbinned(:,uni)); + curPeakLat = find(iscBinnedNormed(:,uni)==1,1,'first'); + if isempty(curPeakLat) + iscPeakLat(uni,:) = [size(iscBinnedNormed,1), uni, max(meanISCbinned(:,uni))]; + else + iscPeakLat(uni,:) = [curPeakLat, uni, max(meanISCbinned(:,uni))]; + end +end +% Select cells based on peak FR value +trialFRthreshLog = iscPeakLat(:,3)widthThresh; +% Spike Rate Based +% pcLog = spkRt'))); +lfpBands = cellfun(@(a,b)a(b:end), statMatrixColIDs(lfpColIDs), regexp(statMatrixColIDs(lfpColIDs), '[(A-Z)|(a-z)]*\>'), 'uniformoutput', 0); +lfpVals = statMatrix(:,lfpColIDs(strcmp(lfpBands, band2plot))); %#ok<*USENS> +lfpVals = lfpVals/(max(abs(lfpVals))); + +plot(statMatrix(:,1), (lfpVals+2)*-1, 'color', [0.4 0.4 0.4]); + +% Plot Spikes +hold on; +for uni = 1:size(uniScatData,2) + scatter(uniScatData{1,uni}, uniScatData{2,uni}, '*k'); +end +set(gca, 'ydir', 'reverse', 'color', 'none'); + +% Patch Trial Periods +for trl = 1:length(behavMatrixTrialStruct) + switch behavMatrixTrialStruct(trl).Odor + case 1 + patchColor = [44/255 168/255 224/255]; + case 2 + patchColor = [154/255 133/255 122/255]; + case 3 + patchColor = [9/255 161/255 74/255]; + case 4 + patchColor = [128/255 66/255 151/255]; + case 5 + patchColor = 'k'; + end + patch(gca, 'XData', [behavMatrix(behavMatrixTrialStruct(trl).PokeInIndex,1), behavMatrix(behavMatrixTrialStruct(trl).PokeOutIndex,1), behavMatrix(behavMatrixTrialStruct(trl).PokeOutIndex,1),behavMatrix(behavMatrixTrialStruct(trl).PokeInIndex,1)],... + 'YData', [zeros(1,2), repmat(icScatData{2,end}(1)+1,[1,2])],... + 'FaceColor', patchColor, 'FaceAlpha', 0.15,... + 'EdgeColor', patchColor); +end + +%% +figure; +scatter([ensembleUnitSummaries.Mean_SpikeRate], [ensembleUnitSummaries.Spike_Width]*40); set(gca, 'xscale', 'log') +%% Create Figure +% seqViewFig = figure; +% figAxes = axes(seqViewFig, 'position', [0.25, 0.1, 0.7, 0.85]); +% set(figAxes, 'ydir', 'reverse', 'color', 'none'); +% +% % UI Control Buttons +% selectFilebtn = uicontrol(artifactRemovalFig, 'Units', 'Normalized', 'Style', 'listbox', 'String', smFileList,... +% 'Position', [0.0375,0.65,0.125,0.28],'Callback', @selectFile); + +%% \ No newline at end of file diff --git a/Analyses/SequenceViewerNeural_SM.m b/Analyses/SequenceViewerNeural_SM.m new file mode 100644 index 0000000..d7b6ea0 --- /dev/null +++ b/Analyses/SequenceViewerNeural_SM.m @@ -0,0 +1,639 @@ +% SequenceViewerNeural_SM +close all +clear all %#ok +clc +%% Initialize The Data For the Figure +global svnFig figAxes lfpPlotHandle lfpBand2Plot rasterHandles pCellList intCellList numSeqs seqWindows curSeqNumInput behavMatrixTrialStruct smFile +% Get the file +[smFile,smPath] = uigetfile('*.mat'); +if smPath==0 + return; +end +% Change directory +cd(smPath); +% Load the file +load(smFile); +% Identify the LFP columns +lfpNdxNd = cellfun(@(a)regexp(a,'_LFP_', 'end'), statMatrixColIDs, 'uniformoutput', 0); +% Identify the hilbert transform columns... +hilbCols = cell2mat(cellfun(@(a)~isempty(a), strfind(statMatrixColIDs, 'HilbVals'), 'uniformoutput', 0)); +lfpColLog = cellfun(@(a)~isempty(a), lfpNdxNd); +% ... so they can be removed from the selection +lfpColLog(hilbCols) = false; +lfpData = statMatrix(:,lfpColLog); +% Now identify the band names so they can be put in the list +lfpNdxNd(~lfpColLog) = []; +lfpColIDs = statMatrixColIDs(lfpColLog); +lfpBandNames = cellfun(@(a,b)a(b+1:end),lfpColIDs, lfpNdxNd, 'uniformoutput', 0)'; + +% Load the behavior and ensemble matrices +files = dir(smPath); +fileNames = {files.name}; +behMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}; +nsmblMatFile = fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'EnsembleMatrix'))}; +load([smPath behMatFile]); +load([smPath nsmblMatFile]); +% Extract spike times and IDs for each unit +unitSpikeTimes = cell(size(ensembleMatrix,2)-1,1); +for uni = 2:size(ensembleMatrix,2) + unitSpikeTimes{uni-1} = ensembleMatrix(ensembleMatrix(:,uni)~=0,1); +end +unitIDs = ensembleMatrixColIDs(:,2:end)'; + +% To find the time window to use we're going to identify how long the rat +% stayed in the port on average for InSeq correct trials and use that +% window as our timewindow for alinging things to. +% First pull out the poke in indices +trlStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0], 'PokeIn'); +% Pull out relevant logicals +seqLog = [trlStruct.TranspositionDistance] == 0; +perfLog = [trlStruct.Performance] == 1; +% Extract sequence beginning and end points with 1s padding on either side +numSeqs = length(unique([trlStruct.SequenceNum])); +seqWindows = nan(numSeqs,2); +for seq = 1:numSeqs + curSeq = trlStruct([trlStruct.SequenceNum]==seq); + seqWindows(seq,1) = behavMatrix(curSeq(1).PokeInIndex-1500,1); + seqWindows(seq,2) = behavMatrix(curSeq(end).PokeOutIndex+1500,1); +end +% Now determine the mean poke duration +pokeDur = [trlStruct.PokeOutIndex] - [trlStruct.PokeInIndex]; +meanPokeDurISC = mean(pokeDur(seqLog & perfLog))/1000; +trialWindows = [-1.2 ceil(meanPokeDurISC*10)/10]; +% Use the Organize/Extract functions to pull out and organize the trial data +behavMatrixTrialStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, trialWindows, 'PokeIn'); +ensembleTrialData = ExtractTrialData_SM(behavMatrixTrialStruct, ensembleMatrix(:,2:end)); %#ok<*NODEF> + +% Make a timestamp vector for use with the trial relative spiking data +trialTSvect = behavMatrix(behavMatrixTrialStruct(1).TrialLogVect,1)-behavMatrix(behavMatrixTrialStruct(1).PokeInIndex,1); +% Create a timestamp vector +histBins = trialWindows(1):0.1:trialWindows(2); +trialEnsembleDataBinned = nan(length(histBins)-1, length(unitIDs), length(ensembleTrialData)); +for tr = 1:length(ensembleTrialData) + for uni = 1:length(unitIDs) + trialEnsembleDataBinned(:,uni,tr) = histcounts(trialTSvect(logical(ensembleTrialData{tr}(:,uni))), histBins, 'Normalization', 'CountDensity'); + end +end + +plotData = struct('TrialEnsembleBinned', {trialEnsembleDataBinned},... + 'UnitIDs', {unitIDs},... + 'UnitSpikeTimes', {unitSpikeTimes},... + 'SessionTime', {statMatrix(:,1)},... + 'InSeqLog', {[trlStruct.TranspositionDistance]==0},... + 'TrialOdor', {[trlStruct.Odor]},... + 'TrialPosition', {[trlStruct.Position]},... + 'Performance', {[trlStruct.Performance]},... + 'UnitInfo', {ensembleUnitSummaries}); +%% +svnFig = figure; +figAxes = axes(svnFig, 'position', [0.3, 0.2, 0.65, 0.75]); +set(svnFig, 'userData', plotData); + +ensembleData = DetermineEnsembleOrganization; + +[pcData, intData] = SeparatePCandINTs; + +%% Make the initial Figure +lfpVals = statMatrix(:,2); +lfpVals = (lfpVals/(max(abs(lfpVals))))*2; +lfpPlotHandle = plot(figAxes, statMatrix(:,1), lfpVals, 'color', [0.4 0.4 0.4]); +hold on; +rasterHandles = nan(length(unitIDs)+3,1); +for r = 1:length(rasterHandles) + rasterHandles(r) = scatter(figAxes,1,(r+1)*-1, 'markerfacecolor', 'k', 'markeredgecolor', 'none'); +end +UpdateRasters(pcData); +UpdateRasters(intData); + +for trl = 1:length(behavMatrixTrialStruct) + switch behavMatrixTrialStruct(trl).Odor + case 1 + patchColor = [44/255 168/255 224/255]; + case 2 + patchColor = [154/255 133/255 122/255]; + case 3 + patchColor = [9/255 161/255 74/255]; + case 4 + patchColor = [128/255 66/255 151/255]; + case 5 + patchColor = 'k'; + end + patch(gca, 'XData', [behavMatrix(behavMatrixTrialStruct(trl).PokeInIndex,1), behavMatrix(behavMatrixTrialStruct(trl).PokeOutIndex,1), behavMatrix(behavMatrixTrialStruct(trl).PokeOutIndex,1),behavMatrix(behavMatrixTrialStruct(trl).PokeInIndex,1)],... + 'YData', [ones(1,2), repmat(length(plotData.UnitIDs)+1,[1,2])*-1],... + 'FaceColor', patchColor, 'FaceAlpha', 0.15,... + 'EdgeColor', patchColor); +end +refreshdata(svnFig); + +axis tight +title(figAxes, smFile, 'interpreter', 'none'); +set(figAxes, 'yticklabel', []); +set(figAxes, 'xlim', seqWindows(1,:)); + +%% Create the Rest of the Figure +% Choose LFP File Button +chooseLFPfileBtn = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Choose LFP File',... + 'Position', [0.05,0.9,0.2,0.05], 'Tag', 'chooseLFPfile_Btn', 'Callback', @ChooseLFPfile); +% LFP Band Listbox +lfpBandList = axes(svnFig, 'position', [0.05, 0.875, 0.08, 0.05]); +set(lfpBandList, 'xlim', [-0.5 0.5], 'ylim', [0 0.5]); +text(lfpBandList, 0,0, 'LFP Data Options', 'horizontalalignment', 'center', 'verticalalignment', 'bottom'); +axis(lfpBandList, 'off'); +lfpBand2Plot = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'listbox', 'String', lfpBandNames,... + 'Position', [0.05,0.6,0.08,0.275], 'Tag', 'bandToPlot', 'Callback', @ChooseLFPbandToPlot, 'userData', lfpData); + +% Temporal Organization Button Group +tempOrgMethod = uibuttongroup(svnFig, 'Units', 'Normalized', 'Position', [0.05, 0.43, 0.085, 0.15],... + 'Title', 'Organization Method', 'TitlePosition', 'centertop', 'Tag', 'orgMthd_BtnGrp',... + 'SelectionChangedFcn', @ChangeTempOrgMethod); +% Temp Org by Mean A +meanAorg = uicontrol(tempOrgMethod, 'Units', 'Normalized', 'Style', 'radiobutton', 'String', 'Peak Seq FR (reset with new seq)',... + 'Position', [0.05, 0.7, 0.9, 0.2], 'Tag', 'orgMeanA_PB'); +% Temp Org by Mean InSeq +meanISorg = uicontrol(tempOrgMethod, 'Units', 'Normalized', 'Style', 'radiobutton', 'String', 'Mean InSeq',... + 'Position', [0.05, 0.4, 0.9, 0.2], 'Tag', 'orgMeanIS_PB'); +% Temp Org by Non A InSeq +meanISsfpOrg = uicontrol(tempOrgMethod, 'Units', 'Normalized', 'Style', 'radiobutton', 'String', 'IS-SFP',... + 'Position', [0.05, 0.1, 0.9, 0.2], 'Tag', 'orgMeanISsfp_PB'); + +% Criteria for PC/IN Classification +cellTypeWidthClassify = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Spike Width Org',... + 'Position', [0.05, 0.35, 0.052, 0.06], 'Tag', 'classCellWidth', 'Callback', @SpikeWidthOrganize); +cellTypeWidthThresh = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'edit', 'String', '0.6',... + 'Position', [0.105, 0.35, 0.025, 0.06]); + +cellTypeRateClassify = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'Spike Rate Org',... + 'Position', [0.05 0.29, 0.052, 0.06], 'Tag', 'classCellRate', 'Callback', @SpikeRateOrganize); +cellTypeRateThresh = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'edit', 'String', '5',... + 'Position', [0.105, 0.29, 0.025, 0.06]); + +% Principal Cells List +pcListTitleAx = axes(svnFig, 'position', [0.14, 0.875, 0.11, 0.05]); +set(pcListTitleAx, 'xlim', [-0.5 0.5], 'ylim', [0 0.5]); +text(pcListTitleAx, 0,0, 'Principal Cells', 'horizontalalignment', 'center', 'verticalalignment', 'bottom'); +axis(pcListTitleAx, 'off'); +pCellList = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'listbox', 'String', pcData(:,3),... + 'Position', [0.14, 0.575, 0.11, 0.3], 'Tag', 'pcCells_Lst', 'Callback', @SelectPC, 'userData', pcData); + +% Move PC to Int list +movePCtoInt = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'PC>>Int',... + 'Position', [0.14, 0.5175, 0.05, 0.05], 'Callback', @PCtoINT); +% Move Int to PC list +moveInttoPC = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'pushbutton', 'String', 'PC<>',... + 'Position', [0.75, 0.05, 0.2, 0.1], 'Callback', @NextSeq); + +% Sequence Number +curSeqNumInput = uicontrol(svnFig, 'Units', 'Normalized', 'Style', 'edit', 'String', '1',... + 'Position', [0.575, 0.075, 0.05, 0.05], 'Callback', @SelectSeq); +totalSeqNumAxs = axes('position', [0.625, 0.075, 0.05, 0.05]); +set(totalSeqNumAxs, 'xlim', [0 0.5], 'ylim', [-0.5 0.5]); +seqText = text(totalSeqNumAxs, 0,0, sprintf('/%i', numSeqs), 'horizontalalignment', 'left', 'verticalalignment', 'middle'); +axis(totalSeqNumAxs, 'off'); + +%% +function [spikeData] = DetermineEnsembleOrganization(orgType) +global svnFig figAxes +seqWin = round(get(figAxes, 'xlim')); +plotData = get(svnFig, 'userData'); +spikeTimes = plotData.UnitSpikeTimes; +unitIDs = plotData.UnitIDs; +unitInfo = arrayfun(@(a){a}, plotData.UnitInfo); +if nargin==0 + orgType = 1; +end +switch orgType + case 1 + trialLog = plotData.TrialOdor==1 & plotData.TrialPosition==1 & plotData.Performance==1; + case 2 + trialLog = plotData.InSeqLog==1 & plotData.Performance==1; + case 3 + trialLog = plotData.InSeqLog==1 & plotData.Performance==1 & plotData.TrialOdor~=1; +end +if orgType == 2 || orgType == 3 + trialHist = mean(plotData.TrialEnsembleBinned(:,:,trialLog),3)'; + normHist = trialHist./max(trialHist,[],2); +else + instFRgauss = (gausswin(200))/0.2; + normHist = cell2mat(cellfun(@(a){conv(histcounts(a(a>min(seqWin) & amin(seqWin) & plotData.SessionTime=orgVal; + case 'Rate' + pcLog = uniFR<=orgVal; +end + +% Select and Organize Putative Principal Cells +pcData = spikeData(pcLog,:); +pcSortVect = sortrows([cell2mat(pcData(:,1)), [1:sum(pcLog)]']); %#ok +pcLines = 2:size(pcData,1)+1; +pcData = [num2cell(pcLines'), pcData(pcSortVect(:,2),:)]; + +% Select and Organize Putative Interneurons +intData = spikeData(~pcLog,:); +intSortVect = sortrows([cell2mat(intData(:,1)), [1:sum(~pcLog)]']); %#ok +intLines = pcLines(end)+3:pcLines(end)+2+size(intData,1); +intData = [num2cell(intLines'), intData(intSortVect(:,2),:)]; +end +%% +function UpdateRasters(dataMtx) +global rasterHandles +for u = 1:size(dataMtx,1) + set(rasterHandles(dataMtx{u,1}), 'Xdata', dataMtx{u,4}, 'Ydata', ones(1,length(dataMtx{u,4})).*(dataMtx{u,1}*-1)); +end +end +%% +function ChooseLFPfile(source,event) +global svnFig figAxes lfpPlotHandle lfpBand2Plot rasterHandles pCellList intCellList numSeqs seqWindows curSeqNumInput +[smFile,smPath] = uigetfile('*.mat'); +if smPath==0 + return; +end + +if strcmp(smPath, [cd '\']) + load(smFile); + lfpNdxNd = cellfun(@(a)regexp(a,'_LFP_', 'end'), statMatrixColIDs, 'uniformoutput', 0); + hilbCols = cell2mat(cellfun(@(a)~isempty(a), strfind(statMatrixColIDs, 'HilbVals'), 'uniformoutput', 0)); + lfpColLog = cellfun(@(a)~isempty(a), lfpNdxNd); + lfpColLog(hilbCols) = false; + lfpData = statMatrix(:,lfpColLog); + lfpNdxNd(~lfpColLog) = []; + lfpColIDs = statMatrixColIDs(lfpColLog); + lfpBandNames = cellfun(@(a,b)a(b+1:end),lfpColIDs, lfpNdxNd, 'uniformoutput', 0)'; + set(lfpBand2Plot, 'Value', 1); + set(lfpBand2Plot, 'String', lfpBandNames); + set(lfpBand2Plot, 'userData', lfpData); + ChooseLFPbandToPlot + title(figAxes, smFile); +end + +end + +%% +function ChooseLFPbandToPlot(source,event) +global lfpPlotHandle lfpBand2Plot +lfpData = get(lfpBand2Plot, 'userData'); +band2Plot = get(lfpBand2Plot, 'value'); +lfpData2Plot = lfpData(:,band2Plot); +lfpData2Plot = (lfpData2Plot/(max(abs(lfpData2Plot))))*2; +% set(lfpPlotHandle, 'Ydata', lfpData2Plot*-1); +set(lfpPlotHandle, 'Ydata', lfpData2Plot); +end + +%% +function SpikeWidthOrganize(source,event) +error('Make me!') +end +%% +function SpikeRateOrganize(source,event) +error('Make me!') +end +%% +function SelectPC(source,event) +global rasterHandles pCellList +pData = get(pCellList, 'userData'); +curListPos = get(pCellList, 'Value'); +if curListPos>size(pData,1) + curListPos = size(pData,1); +end +set(rasterHandles(cell2mat(pData(:,1))), 'MarkerEdgeColor', 'none', 'MarkerFaceColor', 'k'); +set(rasterHandles(pData{curListPos,1}), 'MarkerFaceColor', 'r'); +end +%% +function RemovePC(source,event) +global rasterHandles pCellList intCellList +pData = get(pCellList, 'userData'); +pStart = pData{1,1}; +iData = get(intCellList, 'userData'); +curListPos = get(pCellList, 'Value'); + +% Remove Index +pData(curListPos,:) = []; +% Resort PCs +pcSortMtx = sortrows([cell2mat(pData(:,2)), [1:size(pData,1)]']); %#ok +pData = pData(pcSortMtx(:,2),:); +pData(:,1) = num2cell(pStart:size(pData,1)+1); +% Resort Ints +intSortMtx = sortrows([cell2mat(iData(:,2)), [1:size(iData,1)]']); %#ok +iData = iData(intSortMtx(:,2),:); +iData(:,1) = num2cell(pData{end,1}+3:pData{end,1}+2+size(iData,1)); + +UpdateRasters(pData); +UpdateRasters(iData); +set(pCellList, 'userData', pData); +set(intCellList, 'userData', iData); +set(pCellList, 'String', pData(:,3)); +if curListPos<=size(pData,1) + set(pCellList, 'Value', curListPos-1); +elseif curListPos > size(pData,1) + set(pCellList, 'Value', size(pData,1)); +end + +set(rasterHandles(~ismember(1:length(rasterHandles), cell2mat([pData(:,1);iData(:,1)]))), 'Xdata', 1, 'Ydata', 1); +SelectPC +end +%% +function SelectInt(source,event) +global rasterHandles intCellList +intData = get(intCellList, 'userData'); +curListPos = get(intCellList, 'Value'); +if curListPos>size(intData,1) || isempty(curListPos) + curListPos = size(intData,1); +end + +set(rasterHandles(cell2mat(intData(:,1))), 'MarkerEdgeColor', 'none', 'MarkerFaceColor', 'k'); +set(rasterHandles(intData{curListPos,1}), 'MarkerFaceColor', [0.1 0.8 0.1]); +end +%% +function RemoveINT(source,event) +global intCellList pCellList rasterHandles +pData = get(pCellList, 'userData'); +pStart = pData{1,1}; +iData = get(intCellList, 'userData'); +curListPos = get(intCellList, 'Value'); + +iData(curListPos,:) = []; +% Resort PCs +pcSortMtx = sortrows([cell2mat(pData(:,2)), [1:size(pData,1)]']); %#ok +pData = pData(pcSortMtx(:,2),:); +pData(:,1) = num2cell(pStart:size(pData,1)+1); +% Resort Ints +intSortMtx = sortrows([cell2mat(iData(:,2)), [1:size(iData,1)]']); %#ok +iData = iData(intSortMtx(:,2),:); +iData(:,1) = num2cell(pData{end,1}+3:pData{end,1}+2+size(iData,1)); +UpdateRasters(iData); +UpdateRasters(pData); +set(pCellList, 'userData', pData); +set(intCellList, 'userData', iData); +set(intCellList, 'String', iData(:,3)); +if curListPos<=length(pData) + set(intCellList, 'Value', curListPos-1); +elseif curListPos > size(pData,1) + set(intCellList, 'Value', size(pData,1)); +end +set(rasterHandles(~ismember(1:length(rasterHandles), cell2mat([pData(:,1);iData(:,1)]))), 'Xdata', 1, 'Ydata', 1); +SelectInt +end +%% +function PCtoINT(source, event) +global rasterHandles pCellList intCellList +pData = get(pCellList, 'userData'); +pStart = pData{1,1}; +curPC = get(pCellList, 'Value'); +pStr = get(pCellList, 'String'); +cell2MoveStr = pStr(curPC); +iData = get(intCellList, 'userData'); + + +% Modify Lists +iData = [iData;pData(curPC,:)]; +pData(curPC,:) = []; + +% Reorganize PCs +pcSortMtx = sortrows([cell2mat(pData(:,2)), [1:size(pData,1)]']); %#ok +pData = pData(pcSortMtx(:,2),:); +pData(:,1) = num2cell(pStart:size(pData,1)+1); +for p = 1:size(pData,1) + set(rasterHandles(pData{p,1}), 'Xdata', pData{p,4}, 'Ydata', ones(1,length(pData{p,4})).*(pData{p,1}*-1)); +end +set(pCellList, 'String', pData(:,3)); + +% Reorganize INTs +intSortMtx = sortrows([cell2mat(iData(:,2)), [1:size(iData,1)]']); %#ok +iData = iData(intSortMtx(:,2),:); +iData(:,1) = num2cell(pData{end,1}+3:pData{end,1}+2+size(iData,1)); +for i = 1:size(iData,1) + set(rasterHandles(iData{i,1}), 'Xdata', iData{i,4}, 'Ydata', ones(1,length(iData{i,4})).*(iData{i,1}*-1)); +end +set(intCellList, 'String', iData(:,3)); + +set(pCellList, 'userData', pData); +set(intCellList, 'userData', iData); +set(intCellList, 'Value', find(strcmp(iData(:,3), cell2MoveStr))); +if curPC > 1 + set(pCellList, 'Value', curPC-1); +end + +nonDataLog = ~ismember(1:length(rasterHandles), cell2mat([pData(:,1); iData(:,1)])); +set(rasterHandles(nonDataLog), 'Xdata', 1, 'Ydata', 1); +SelectInt +SelectPC +end +%% +function INTtoPC(source, event) +global rasterHandles pCellList intCellList +pData = get(pCellList, 'userData'); +iData = get(intCellList, 'userData'); +curInt = get(intCellList, 'Value'); +iStr = get(intCellList, 'String'); +cell2MoveStr = iStr(curInt); + +% Modify Lists +pData = [pData;iData(curInt,:)]; +ndxStart = pData{1,1}; +iData(curInt,:) = []; + +% Reorganize PCs +pcSortMtx = sortrows([cell2mat(pData(:,2)), [1:size(pData,1)]']); %#ok +pData = pData(pcSortMtx(:,2),:); +pData(:,1) = num2cell(ndxStart:size(pData,1)+1); +for p = 1:size(pData,1) + set(rasterHandles(pData{p,1}), 'Xdata', pData{p,4}, 'Ydata', ones(1,length(pData{p,4})).*(pData{p,1}*-1)); +end + +% Reorganize INTs +intSortMtx = sortrows([cell2mat(iData(:,2)), [1:size(iData,1)]']); %#ok +iData = iData(intSortMtx(:,2),:); +iData(:,1) = num2cell(pData{end,1}+3:pData{end,1}+2+size(iData,1)); +for i = 1:size(iData,1) + set(rasterHandles(iData{i,1}), 'Xdata', iData{i,4}, 'Ydata', ones(1,length(iData{i,4})).*(iData{i,1}*-1)); +end + +set(pCellList, 'userData', pData); +set(pCellList, 'String', pData(:,3)); +set(intCellList, 'userData', iData); +set(intCellList, 'String', iData(:,3)); +set(pCellList, 'Value', find(strcmp(pData(:,3), cell2MoveStr))); +if curInt > 1 + set(intCellList, 'Value', curInt-1); +end + +nonDataLog = ~ismember(1:length(rasterHandles), cell2mat([pData(:,1); iData(:,1)])); +set(rasterHandles(nonDataLog), 'Xdata', 1, 'Ydata', 1); +SelectPC +SelectInt +end +%% +function ChangeTempOrgMethod(source,event) +global figAxes pCellList intCellList rasterHandles +orgMethodVal = logical(cell2mat(get(get(source, 'Children'), 'Value'))); +orgMethodTag = get(get(source, 'Children'), 'Tag'); +curMethod = orgMethodTag{orgMethodVal}; +switch curMethod + case 'orgMeanA_PB' + [spikeData] = DetermineEnsembleOrganization(1); + case 'orgMeanIS_PB' + [spikeData] = DetermineEnsembleOrganization(2); + case 'orgMeanISsfp_PB' + [spikeData] = DetermineEnsembleOrganization(3); +end +iData = get(intCellList, 'userData'); +intRmvLog = ismember(spikeData(:,2), iData(:,3)); +pData = spikeData; +pData(intRmvLog,:) = []; +pSortVect = sortrows([cell2mat(pData(:,1)), [1:size(pData,1)]']); %#ok +pLines = 2:size(pData,1)+1; +pData = [num2cell(pLines'), pData(pSortVect(:,2),:)]; +UpdateRasters(pData); +set(pCellList, 'userData', pData); +set(pCellList, 'String', pData(:,3)); + +for i = 1:size(iData,1) + newSpikeData = spikeData(strcmp(iData{i,3}, spikeData(:,2)),:); + if isempty(newSpikeData) + iData{i,1} = nan; + else + iData(i,2:end) = newSpikeData; + end +end +nanCheck = isnan(cell2mat(iData(:,1))); +iData(nanCheck,:) = []; +iData = iData(:,2:end); +iSortVect = sortrows([cell2mat(iData(:,1)), [1:size(iData,1)]']); %#ok +iLines = pLines(end)+3:pLines(end)+2+size(iData,1); +iData = [num2cell(iLines'), iData(iSortVect(:,2),:)]; +UpdateRasters(iData); +set(figAxes, 'ylim', [(iData{end,1}+1)*-1 1]); +set(intCellList, 'userData', iData); +set(intCellList, 'String', iData(:,3)); +SelectPC +SelectInt + +set(rasterHandles(~ismember(1:length(rasterHandles), cell2mat([pData(:,1);iData(:,1)]))), 'Xdata', 1, 'Ydata', 1); +end + +%% +function PrevSeq(source,event) +global seqWindows curSeqNumInput figAxes +curSeqNum = str2double(get(curSeqNumInput, 'String')); +if curSeqNum - 1 >= 1 + set(curSeqNumInput, 'String', num2str(curSeqNum-1)); + set(figAxes, 'xlim', seqWindows(curSeqNum-1,:)); +end +end +%% +function NextSeq(source,event) +global numSeqs seqWindows curSeqNumInput figAxes +curSeqNum = str2double(get(curSeqNumInput, 'String')); +if curSeqNum + 1 <= numSeqs + set(curSeqNumInput, 'String', num2str(curSeqNum+1)); + set(figAxes, 'xlim', seqWindows(curSeqNum+1,:)); +end +end +%% +function SelectSeq(source,event) +global numSeqs seqWindows curSeqNumInput figAxes +curSeqNum = str2double(get(curSeqNumInput, 'String')); +if curSeqNum <= numSeqs + set(curSeqNumInput, 'String', num2str(curSeqNum)); + set(figAxes, 'xlim', seqWindows(curSeqNum,:)); +end +end +%% +function PopoutPlot(source,event) +global svnFig lfpBand2Plot pCellList intCellList seqWindows curSeqNumInput behavMatrixTrialStruct smFile +plotData = get(svnFig, 'userData'); +poFig = figure; +lfpData = get(lfpBand2Plot, 'userData'); +curLFP = lfpData(:,get(lfpBand2Plot, 'Value')); +curLFP = (curLFP/(max(abs(curLFP))))*2; +plot(plotData.SessionTime, curLFP, 'color', [0.4 0.4 0.4]); +hold on; +pData = get(pCellList, 'userData'); +iData = get(intCellList, 'userData'); + +scatterData = [pData(:,1), pData(:,4); iData(:,1), iData(:,4)]; +for u = 1:size(scatterData,1) + scatter(scatterData{u,2}, ones(size(scatterData{u,2})).*scatterData{u,1}*-1, 'markerfacecolor', 'k', 'markeredgecolor', 'none'); +end + +for trl = 1:length(behavMatrixTrialStruct) + switch behavMatrixTrialStruct(trl).Odor + case 1 + patchColor = [44/255 168/255 224/255]; + case 2 + patchColor = [154/255 133/255 122/255]; + case 3 + patchColor = [9/255 161/255 74/255]; + case 4 + patchColor = [128/255 66/255 151/255]; + case 5 + patchColor = 'k'; + end + patch(gca, 'XData', [plotData.SessionTime(behavMatrixTrialStruct(trl).PokeInIndex,1), plotData.SessionTime(behavMatrixTrialStruct(trl).PokeOutIndex,1), plotData.SessionTime(behavMatrixTrialStruct(trl).PokeOutIndex,1),plotData.SessionTime(behavMatrixTrialStruct(trl).PokeInIndex,1)],... + 'YData', [ones(1,2), repmat(iData{end,1}+1,[1,2])*-1],... + 'FaceColor', patchColor, 'FaceAlpha', 0.15,... + 'EdgeColor', patchColor); +end +set(gca, 'xlim', seqWindows(str2double(get(curSeqNumInput, 'String')),:), 'ylim', [-1*iData{end,1}-1, 2]); +title(sprintf('%s; Sequence %s', smFile, get(curSeqNumInput, 'String')), 'interpreter', 'none'); +orient(gcf, 'tall'); +orient(gcf, 'landscape'); +set(gcf, 'Renderer', 'Painters'); +end \ No newline at end of file diff --git a/Analyses/SummarizeUnits_SM.m b/Analyses/SummarizeUnits_SM.m index 33d549e..57d21c0 100644 --- a/Analyses/SummarizeUnits_SM.m +++ b/Analyses/SummarizeUnits_SM.m @@ -61,7 +61,7 @@ end % Number of permutations for chance distribution estimation -numPerms = 10; +numPerms = 5; %% Analysis #1: Examine Average Evoked activity during trial periods fprintf('Starting Analysis #1 @%s....', datetime); @@ -285,8 +285,10 @@ curEpochCorrTable(1,5) = prR(2); curEpochSigTable(1,5) = prS(2); [peR, peS] = corrcoef(curUniPreTrialActivity(~correctTrialLog & inSeqTrialLog), curUniErrTrlActivity(~correctTrialLog & inSeqTrialLog)); - curEpochCorrTable(1,6) = peR(2); - curEpochSigTable(1,6) = peS(2); + if ~isnan(peR(2)) && length(peR)>1 + curEpochCorrTable(1,6) = peR(2); + curEpochSigTable(1,6) = peS(2); + end % Early-Trial lead [elR, elS] = corrcoef(curUniErlyTrialActivity(correctTrialLog & inSeqTrialLog), curUniLtTrialActivity(correctTrialLog & inSeqTrialLog)); curEpochCorrTable(2,3) = elR(2); @@ -298,8 +300,10 @@ curEpochCorrTable(2,5) = erR(2); curEpochSigTable(2,5) = erS(2); [eeR, eeS] = corrcoef(curUniErlyTrialActivity(~correctTrialLog & inSeqTrialLog), curUniErrTrlActivity(~correctTrialLog & inSeqTrialLog)); - curEpochCorrTable(2,6) = eeR(2); - curEpochSigTable(2,6) = eeS(2); + if ~isnan(eeR(2)) && length(eeR)>1 + curEpochCorrTable(2,6) = eeR(2); + curEpochSigTable(2,6) = eeS(2); + end % Late-Trial lead [lpR, lpS] = corrcoef(curUniLtTrialActivity(correctTrialLog & inSeqTrialLog), curUniPstTrlActivity(correctTrialLog & inSeqTrialLog)); curEpochCorrTable(3,4) = lpR(2); @@ -308,15 +312,19 @@ curEpochCorrTable(3,5) = lrR(2); curEpochSigTable(3,5) = lrS(2); [leR, leS] = corrcoef(curUniLtTrialActivity(~correctTrialLog & inSeqTrialLog), curUniErrTrlActivity(~correctTrialLog & inSeqTrialLog)); - curEpochCorrTable(3,6) = leR(2); - curEpochSigTable(3,6) = leS(2); + if ~isnan(leR(2)) && length(leR)>1 + curEpochCorrTable(3,6) = leR(2); + curEpochSigTable(3,6) = leS(2); + end % Post-Trial lead [prR, prS] = corrcoef(curUniPstTrlActivity(correctTrialLog & inSeqTrialLog), curUniRwdTrlActivity(correctTrialLog & inSeqTrialLog)); curEpochCorrTable(4,5) = prR(2); curEpochSigTable(4,5) = prS(2); [peR, peS] = corrcoef(curUniPstTrlActivity(~correctTrialLog & inSeqTrialLog), curUniErrTrlActivity(~correctTrialLog & inSeqTrialLog)); - curEpochCorrTable(4,6) = peR(2); - curEpochSigTable(4,6) = peS(2); + if ~isnan(peR(2)) && length(peR)>1 + curEpochCorrTable(4,6) = peR(2); + curEpochSigTable(4,6) = peS(2); + end unitInfo(u).TrialEpochStats.EpochCorrelations.R = curEpochCorrTable; unitInfo(u).TrialEpochStats.EpochCorrelations.P = curEpochSigTable; @@ -420,57 +428,57 @@ fprintf('Completed\n'); %% Analysis #3: Examine Information content by LFP Phase -fprintf('Starting Analysis 3 @%s....', datetime); -% This is best done using the epoch extraction script since it give lfp -% phase values. -[earlyUnitEpoch, earlyUnitIDs, earlyLfpEpoch, earlyLfpIDs, ~, rlyTimeBins, earlyTrialInfo] = EpochExtraction_SM('PokeIn', -0.9, 2.1, 'org', 'TiUTr', 'lfpBand', 'All', 'lfpData', 'Phase'); - -currPos = nan(size(earlyTrialInfo,1),1); -currOdr = nan(size(earlyTrialInfo,1),1); -prevOdr = nan(size(earlyTrialInfo,1),1); -for trl = 2:size(earlyTrialInfo,1) - if earlyTrialInfo(trl,1)==1 && (earlyTrialInfo(trl,3) - earlyTrialInfo(trl-1,3) == 1) - currPos(trl) = earlyTrialInfo(trl,3); - currOdr(trl) = earlyTrialInfo(trl,4); - prevOdr(trl) = earlyTrialInfo(trl-1,4); - end -end -earlyEpochEnsmbl = earlyUnitEpoch(:,:,~isnan(currPos)); -earlyEpochLFP = earlyLfpEpoch(:,:,~isnan(currPos)); -currPos = currPos(~isnan(currPos)); -currOdr = currOdr(~isnan(currOdr)); -prevOdr = prevOdr(~isnan(prevOdr)); - -lfpIDparts = cellfun(@(b)[b(1);b(3)], cellfun(@(a)strsplit(a, '_'), earlyLfpIDs, 'uniformoutput', 0), 'uniformoutput', 0); -lfpIDparts = [lfpIDparts{:}]; -bands = unique(lfpIDparts(2,:)); -bands(strcmp(bands, 'Raw')) = []; - -for uni = 1:length(earlyUnitIDs) - curUniInfoSpot = strcmp(earlyUnitIDs{uni}, {unitInfo.UnitName}); - curTet = earlyUnitIDs{uni}(1:regexp(earlyUnitIDs{uni}, '-')-1); - curTetEpochLog = logical(earlyEpochEnsmbl(:,uni,:)); - for band = 1:length(bands) - curTetLFPepoch = earlyEpochLFP(:,strcmp(bands{band},lfpIDparts(2,:)) & strcmp(curTet,lfpIDparts(1,:)),:); - curTetSpikePhaseVals = nan(size(curTetEpochLog)); - curTetSpikePhaseVals(curTetEpochLog) = curTetLFPepoch(curTetEpochLog); - for phase = 1:length(phaseBins)-1 - curTetCurBandPhaseBinSpikes = double(curTetSpikePhaseVals>=phaseBins(phase) & curTetSpikePhaseVals=phaseBins(phase) & curTetSpikePhaseVals')))'; +lfps = cell(size(smFileList))'; +for f = 1:length(smFileList) + temp = load(smFileList{f}); + lfps{f} = temp.statMatrix(:,2); +end +lfps = cell2mat(lfps); +gMn = mean(lfps,2); + +%% +for f = 1:length(smFileList) + temp = load(smFileList{f}); + statMatrix = [temp.statMatrix(:,1), temp.statMatrix(:,2)-gMn]; + statMatrixColIDs = temp.statMatrixColIDs(1:2); + fName = [smFileList{f}(1:end-6) 'CARcleaned_SM.mat']; + save(fName, 'statMatrix', 'statMatrixColIDs'); + fprintf('%s Saved\n', fName); +end +fprintf('All files saved\n'); + diff --git a/Data Management/EpochExtraction_SM.m b/Data Management/EpochExtraction_SM.m index c3b4d84..a969d9d 100644 --- a/Data Management/EpochExtraction_SM.m +++ b/Data Management/EpochExtraction_SM.m @@ -178,7 +178,7 @@ lfpCol = cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, lfpColRegXprsnString)); lfpIDs = [lfpIDs, statMatrixColIDs(lfpCol)]; %#ok - lfpEventData = ExtractTrialData_SM(eventAlignedMatrix, statMatrix(:,lfpCol)); %#ok + lfpEventData = ExtractTrialData_SM(eventAlignedMatrix, statMatrix(:,lfpCol)); mptLogLFP = cellfun(@(a)isempty(a), lfpEventData); lfpEventData(mptLogLFP) = {nan(size(eventTimeBins))}; lfpEventData = cellfun(@(a)reshape(a, [1, size(a,1), size(a,2)]), lfpEventData, 'uniformoutput',0); diff --git a/Data Management/EnsembleCompilation_SM.m b/Data Management/Old/EnsembleCompilation_SM.m similarity index 97% rename from Data Management/EnsembleCompilation_SM.m rename to Data Management/Old/EnsembleCompilation_SM.m index 0ff0c87..231849a 100644 --- a/Data Management/EnsembleCompilation_SM.m +++ b/Data Management/Old/EnsembleCompilation_SM.m @@ -1,47 +1,47 @@ -function EnsembleCompilation_SM -%% EnsembleCompilation_SM -% Code to extract all the unit activity from a set of files in the -% statMatrix format FROM THE SAME SESSION and compile them into a common -% variable -% -% 02/14/2018 - Created by GE -% -%% Extract Info and bands and shit idk -origDir = cd; -[fileDir] = uigetdir(origDir); -if fileDir==0 - disp('Analysis Cancelled') - return -else - cd(fileDir) -end -dirContents = dir(fileDir); -fileNames = {dirContents.name}; -tetFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_T([0-9]*).mat')); -tetFiles = fileNames(tetFileLog)'; -load(tetFiles{1}, 'statMatrixColIDs'); - -%% Compile everything! -ensembleMatrix = cell(1,length(tetFiles)); -ensembleMatrixColIDs = cell(1,length(tetFiles)); -ensembleUnitSummaries = cell(1,length(tetFiles)); -for tet = 1:length(tetFiles) - load(tetFiles{tet}); - ensembleUnitSummaries{tet} = unitSummary; - if tet == 1 - tsVect = statMatrix(:,1); %#ok - end - statMatrixColIDs = statMatrixColIDs(cellfun(@(a)~isempty(a), statMatrixColIDs)); - uniColLog = cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, '-U([0-9]*)')); - ensembleMatrix{tet} = statMatrix(:,uniColLog); - ensembleMatrixColIDs{tet} = statMatrixColIDs(uniColLog); - fprintf('%s Complete\n', tetFiles{tet}); -end -%% -ensembleMatrix = [tsVect, cell2mat(ensembleMatrix)]; %#ok -ensembleMatrixColIDs = [{'TimeBin'}, ensembleMatrixColIDs{:}]; %#ok -ensembleUnitSummaries = cell2mat(ensembleUnitSummaries); %#ok - -save('EnsembleMatrix.mat', 'ensembleMatrix', 'ensembleMatrixColIDs', 'ensembleUnitSummaries', '-v7.3'); - - +function EnsembleCompilation_SM +%% EnsembleCompilation_SM +% Code to extract all the unit activity from a set of files in the +% statMatrix format FROM THE SAME SESSION and compile them into a common +% variable +% +% 02/14/2018 - Created by GE +% +%% Extract Info and bands and shit idk +origDir = cd; +[fileDir] = uigetdir(origDir); +if fileDir==0 + disp('Analysis Cancelled') + return +else + cd(fileDir) +end +dirContents = dir(fileDir); +fileNames = {dirContents.name}; +tetFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, '_T([0-9]*).mat')); +tetFiles = fileNames(tetFileLog)'; +load(tetFiles{1}, 'statMatrixColIDs'); + +%% Compile everything! +ensembleMatrix = cell(1,length(tetFiles)); +ensembleMatrixColIDs = cell(1,length(tetFiles)); +ensembleUnitSummaries = cell(1,length(tetFiles)); +for tet = 1:length(tetFiles) + load(tetFiles{tet}); + ensembleUnitSummaries{tet} = unitSummary; + if tet == 1 + tsVect = statMatrix(:,1); %#ok + end + statMatrixColIDs = statMatrixColIDs(cellfun(@(a)~isempty(a), statMatrixColIDs)); + uniColLog = cellfun(@(a)~isempty(a), regexp(statMatrixColIDs, '-U([0-9]*)')); + ensembleMatrix{tet} = statMatrix(:,uniColLog); + ensembleMatrixColIDs{tet} = statMatrixColIDs(uniColLog); + fprintf('%s Complete\n', tetFiles{tet}); +end +%% +ensembleMatrix = [tsVect, cell2mat(ensembleMatrix)]; %#ok +ensembleMatrixColIDs = [{'TimeBin'}, ensembleMatrixColIDs{:}]; %#ok +ensembleUnitSummaries = cell2mat(ensembleUnitSummaries); %#ok + +save('EnsembleMatrix.mat', 'ensembleMatrix', 'ensembleMatrixColIDs', 'ensembleUnitSummaries', '-v7.3'); + + diff --git a/Data Management/OrganizeExtractTrialPeriod_SM.m b/Data Management/OrganizeExtractTrialPeriod_SM.m new file mode 100644 index 0000000..7281c5a --- /dev/null +++ b/Data Management/OrganizeExtractTrialPeriod_SM.m @@ -0,0 +1,14 @@ +function behavTrialMtx = OrganizeExtractTrialPeriod_SM(behavMatrix, behavMatrixColIDs, statMatrix, preStartDur, postEndDur) +% Combines the Organize and Extract functions to pull out trial data from +% the statMatrix input within the window specified by preStartDur and +% postEndDur reflecting the amount of time prior to trial initiation and +% after trial end you want extracted. + +sampleRate = 1/mode(diff(behavMatrix(:,1))); +trlWindow = [round(preStartDur*sampleRate) round(postEndDur*sampleRate)]; + +behavMatrixTrialStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0], 'PokeIn'); +behavTrialMtx = rmfield(behavMatrixTrialStruct, 'TrialLogVect'); +for t = 1:length(behavMatrixTrialStruct) + behavTrialMtx(t).StatMatrixData = statMatrix(behavMatrixTrialStruct(t).PokeInIndex - trlWindow(1) : behavMatrixTrialStruct(t).PokeOutIndex + trlWindow(2),:); +end \ No newline at end of file diff --git a/Data Management/OrganizeTrialData_SM.m b/Data Management/OrganizeTrialData_SM.m index d7b4fd2..0dfb4cd 100644 --- a/Data Management/OrganizeTrialData_SM.m +++ b/Data Management/OrganizeTrialData_SM.m @@ -31,6 +31,7 @@ %% Extract Trial Indexes & Poke Events % separate out odor and position columns odorTrlMtx = behavMatrix(:,cellfun(@(a)~isempty(a), strfind(behavMatrixColIDs, 'Odor'))); +odorVals = cell2mat(cellfun(@(b)str2double(b(5:end)), behavMatrixColIDs(cellfun(@(a)~isempty(a), strfind(behavMatrixColIDs, 'Odor'))), 'uniformoutput', 0)); positionTrlMtx = behavMatrix(:,cellfun(@(a)~isempty(a), regexp(behavMatrixColIDs, 'Position[1-9]$'))); % Sum them on 2d to extract trial indices trialVect = sum(odorTrlMtx,2); @@ -49,6 +50,9 @@ % Pull out Error Indices errorSigVect = behavMatrix(:, cellfun(@(a)~isempty(a), strfind(behavMatrixColIDs, 'ErrorSignal'))); errorSigNdxs = find(errorSigVect); +% Pull out Reward Signal Indices +rwdSigVect = behavMatrix(:, cellfun(@(a)~isempty(a), strfind(behavMatrixColIDs, 'RewardSignal'))); +rewardSigNdxs = find(rwdSigVect); % Pull out Sequence Length seqLength = size(positionTrlMtx,2); % Identify trial performance @@ -56,6 +60,23 @@ % Identify InSeq logical inSeqLog = behavMatrix(:, cellfun(@(a)~isempty(a), strfind(behavMatrixColIDs, 'InSeqLog'))); + +% COMMENT IN IF RUNNING BOSTON-CA1 DATA; OUT IF RUNNING PFC +% if isempty(rewardSigNdxs) +% odorNdxs = find(sum(odorTrlMtx,2)); +% for t = 1:length(odorNdxs) +% if t~=length(odorNdxs) +% if sum(frontRwrdNdxs>odorNdxs(t) & frontRwrdNdxs=1 +% rewardSigNdxs = [rewardSigNdxs; odorNdxs(t)+1200]; %#ok +% end +% elseif t==length(odorNdxs) +% if sum(frontRwrdNdxs>odorNdxs(t))>=1 +% rewardSigNdxs = [rewardSigNdxs; odorNdxs(t)+1200]; %#ok +% end +% end +% end +% end + %% Create Data input structures seqNum = cell(1,numTrials); trialOdor = cell(1,numTrials); @@ -68,15 +89,17 @@ trialPokeOutNdx = repmat({nan}, [1, numTrials]); trialRewardNdx = repmat({nan}, [1, numTrials]); trialErrorNdx = repmat({nan}, [1, numTrials]); +trialRwdSigNdx = repmat({nan}, [1, numTrials]); trialLogVect = cell(1,numTrials); trialNum = cell(1,numTrials); pokeDuration = cell(1,numTrials); +withdrawLat = cell(1,numTrials); seq = 0; %% Go through each trial and pull out trial information and create a logical vector for that trial's time periods specified by the input trialLims for trl = 1:numTrials trialNum{trl} = trl; % Identify Trial/Position/Descriptors - curTrlOdor = find(odorTrlMtx(trialIndices(trl),:)==1); + curTrlOdor = odorVals(odorTrlMtx(trialIndices(trl),:)==1); curTrlPos = find(positionTrlMtx(trialIndices(trl),:)==1); curTrlPerf = trialPerfVect(trialIndices(trl))==1; curTrlInSeqLog = inSeqLog(trialIndices(trl))==1; @@ -97,32 +120,53 @@ trialItmItmDist{trl} = 1; trialTransDist{trl} = 0; else - trialTransDist{trl} = curTrlPos - curTrlOdor; - trialItmItmDist{trl} = curTrlOdor - curTrlPos + 1; + if curTrlOdor < 10 + trialTransDist{trl} = curTrlPos - curTrlOdor; + trialItmItmDist{trl} = curTrlOdor - curTrlPos + 1; + else + trialTransDist{trl} = curTrlPos+10 - curTrlOdor; + trialItmItmDist{trl} = curTrlOdor - (curTrlPos+10) + 1; + end end seqNum{trl} = seq; % Create trial logical vector tempLogVect = false(size(behavMatrix,1),1); - curPokeIn = pokeInNdxs(find(pokeInNdxstrialIndices(trl)==1,1, 'first')); - pokeDuration{trl} = (curPokeOut-curPokeIn)/sampleRate; - + trialPokeInNdx{trl} = curPokeIn; trialOdorNdx{trl} = trialIndices(trl); trialPokeOutNdx{trl} = curPokeOut; curFrontRwrdNdx = frontRwrdNdxs(find(frontRwrdNdxs>trialIndices(trl)==1,1, 'first')); if isempty(curFrontRwrdNdx) || trl==numTrials || curFrontRwrdNdxtrialIndices(trl)==1,1,'first')); if isempty(curErrSigNdx) || trl==numTrials || curErrSigNdxtrialIndices(trl)==1,1,'first')); + if isempty(curRwdSigNdx) || trl==numTrials || curRwdSigNdx0) + if uni == 0 + [~, osmNeural(tet).Spikes.Unsorted] = plx_ts(plxData.Summary.PLXfile, tetChan, uni); + else + [~, osmNeural(tet).Spikes.(sprintf('U%i', uni))] = plx_ts(plxData.Summary.PLXfile, tetChan, uni); + end + uni = uni+1; + end +end + +% Create Timestamp Vector +tsVect = ((0:(fn(1)-1))/samp)+tetTS(1); +% Sometimes the file is composed of multiple fragments, in which case these +% should be combined into a single file +for fragNum = 2:length(tetTS) + tsVect = [tsVect, ((0:(fn(fragNum)-1))/samp)+tetTS(fragNum)]; %#ok +end + +%% Save it all! +save([plxData.Summary.PLXfile(1:end-4), '_OSMdata.mat'], 'osmNeural', 'osmBehavior', 'tsVect'); +fprintf('%s saved!\n', [plxData.Summary.PLXfile(1:end-4), '_OSMdata.mat']); \ No newline at end of file diff --git a/OSMdata Code/SimpleOSMsessionSpectrogram.m b/OSMdata Code/SimpleOSMsessionSpectrogram.m new file mode 100644 index 0000000..b130d11 --- /dev/null +++ b/OSMdata Code/SimpleOSMsessionSpectrogram.m @@ -0,0 +1,37 @@ +freqs = 1:100; +for tet = 1:length(osmNeural) + zData = zscore(osmNeural(tet).LFP); +% zData = zscore(osmLFP(:,tet) - mean(osmLFP(:,2:end),2)); +% zData = osmLFP(:,tet) - mean(osmLFP(:,2:end),2); + [s,fs,t] = spectrogram(zData, 1000, 900, freqs, 1000); + ss = 10*log10(abs(s)); + zSS = ss; + for f = 1:size(ss,1) + zSS(f,:) = zscore(ss(f,:)); + end + figure; + sp1 = subplot(2,3,[1 2]); + imagesc(t,fs,ss); + hold on; + scatter([osmBehavior.PortEntryTime], ones(1,length(osmBehavior))*20, '*k'); + scatter([osmBehavior.PortExitTime], ones(1,length(osmBehavior))*20, 'ok'); + set(gca, 'ydir', 'normal'); + title(osmNeural(tet).TetName); + colorbar; + + sp2 = subplot(2,3,[4 5]); + imagesc(t,fs,zSS, [-4 4]); + hold on; + scatter([osmBehavior.PortEntryTime], ones(1,length(osmBehavior))*20, '*k'); + scatter([osmBehavior.PortExitTime], ones(1,length(osmBehavior))*20, 'ok'); + set(gca, 'ydir', 'normal'); + colormap jet; + linkaxes([sp1 sp2], 'xy'); + colorbar; + + subplot(2,3,3); + periodogram(zData, [], freqs, 1000); + + subplot(2,3,6); + plot(fs,median(zSS,2)) +end diff --git a/OSMdata Code/TEMPosmMLB.m b/OSMdata Code/TEMPosmMLB.m new file mode 100644 index 0000000..e5d8f10 --- /dev/null +++ b/OSMdata Code/TEMPosmMLB.m @@ -0,0 +1,167 @@ +%% Runtime variables +piWindow = [-0.5 0.5]; +poWindow = [-0.5 0.5]; +binSize = 200; +dsRate = 5; +cLim = [0 0.01]; + +piWindowTS = piWindow(1):(dsRate*mode(diff(tsVect))):piWindow(2); +poWindowTS = poWindow(1):(dsRate*mode(diff(tsVect))):poWindow(2); + +%% Create the spikeMtx: the multiunit signal from every tetrode by aggregating the cut and uncut units together. +tempTSvect = tsVect; +tempTSvect(end+1) = tsVect(end)+(mode(diff(tsVect))); +spikeMtx = nan(length(tsVect), length(osmNeural)); +for t = 1:length(osmNeural) + tempTetSpks = osmNeural(t).Spikes; + tempSpikes = []; + if ~isempty(tempTetSpks) + uniNms = fieldnames(tempTetSpks); + for u = 1:length(uniNms) + tempSpikes = [tempSpikes; tempTetSpks.(uniNms{u})]; %#ok + end + spikeMtx(:,t) = histcounts(tempSpikes, tempTSvect); + end +end +tetNames = {osmNeural.TetName}; +tetNames(isnan(spikeMtx(1,:))) = []; +spikeMtx(:,isnan(spikeMtx(1,:))) = []; + +%% Bin spiking on a per trial basis +piSpikeMtx = nan(length(piWindowTS)-1, length(tetNames), length(osmBehavior)); +poSpikeMtx = nan(length(poWindowTS)-1, length(tetNames), length(osmBehavior)); +trlSpikeMtx = nan(length(piWindowTS) + length(poWindowTS) -2, length(tetNames), length(osmBehavior)); +for trl = 1:length(osmBehavior) + pokeInWindowLog = tsVect>osmBehavior(trl).PortEntryTime + piWindow(1) - (binSize/2*mode(diff(tsVect))) & tsVect<=osmBehavior(trl).PortEntryTime + piWindow(2) + (binSize/2*mode(diff(tsVect))); + pokeOutWindowLog = tsVect>osmBehavior(trl).PortExitTime + poWindow(1) - (binSize/2*mode(diff(tsVect))) & tsVect<=osmBehavior(trl).PortExitTime + poWindow(2) + (binSize/2*mode(diff(tsVect))); + + for tet = 1:length(tetNames) + tempSpksPI = conv(spikeMtx(pokeInWindowLog,tet), ones(1,binSize)./(binSize/1000), 'same'); + tempSpksPI = tempSpksPI((binSize/2)+1:end-(binSize/2)); + piSpikeMtx(:,tet,trl) = downsample(tempSpksPI,dsRate); + + tempSpksPO = conv(spikeMtx(pokeOutWindowLog,tet), ones(1,binSize)./(binSize/1000), 'same'); + tempSpksPO = tempSpksPO((binSize/2)+1:end-(binSize/2)); + poSpikeMtx(:,tet,trl) = downsample(tempSpksPO,dsRate); + + trlSpikeMtx(:,tet,trl) = [piSpikeMtx(:,tet,trl);poSpikeMtx(:,tet,trl)]; + end + fprintf('Trial %i\n', trl) +end + +%% Create logical masks +% Use these to select trials +trlPos = [osmBehavior.TrialPosition]; +trlOdr = [osmBehavior.TrialOdor]; +isTrlLog = (trlPos - trlOdr)==0; +perfTrlLog = [osmBehavior.PerformanceLog]==1; + +fisLog = false(1,length(osmBehavior)); +for t = 4:length(osmBehavior) + fisLog(t) = sum([osmBehavior(t-3:t).TrialPosition] == 1:4)==4 &&... + sum([osmBehavior(t-3:t).TrialOdor] == 1:4)==4 &&... + sum([osmBehavior(t-3:t).PerformanceLog])==4; + if fisLog(t) == true + fisLog(t-3:t) = true; + end +end + +% Use these to navigate the FIS trial spike matrix (created below) +piIDvect = repmat([true(1,length(piWindowTS)-1), false(1,length(poWindowTS)-1)], [1,4]); +poIDvect = repmat([false(1,length(piWindowTS)-1), true(1,length(poWindowTS)-1)], [1,4]); +odrIDvect = zeros(1,(length(piWindowTS)-1 + length(poWindowTS)-1)*4); +for o = 1:4 + odrIDvect((o-1)*(length(piWindowTS)+length(poWindowTS)-2)+1:(o*(length(piWindowTS)+length(poWindowTS)-2))) = o; +end +timIDvect = repmat(1:length(piWindowTS)+length(poWindowTS)-2, [1,4]); + +%% Extract FIS Trials to create likelihood matrix +fisSpikeMtx = nan(length(odrIDvect), length(tetNames), sum(fisLog)/4); +for odr = 1:4 + tempFISodrVect = find(fisLog & trlOdr==odr); + for tet = 1:length(tetNames) + for trl = 1:length(tempFISodrVect) + fisSpikeMtx(odrIDvect==odr,tet,trl) = trlSpikeMtx(:,tet,tempFISodrVect(trl)); + end + end +end + +%% Perform leave 1 out decoding on FIS data +fisPost = nan(size(fisSpikeMtx,1), size(fisSpikeMtx,1), size(fisSpikeMtx,3)); +odrDecode = nan(size(fisSpikeMtx,1),size(fisSpikeMtx,3)); +for seq = 1:size(fisSpikeMtx,3) + curObsv = fisSpikeMtx(:,:,seq); + tempLikely = fisSpikeMtx; + tempLikely(:,:,seq) = []; + fisPost(:,:,seq) = CalcStaticBayesPost(mean(tempLikely,3), curObsv, binSize); +end +fisODRdecode = DecodeBayesPost(fisPost, odrIDvect); +fisODRdecoded = nan(4,size(fisODRdecode,1)); +for o = 1:4 + fisODRdecoded(o,:) = smooth(mean(fisODRdecode == o,2),10); +end +fisLATdecode = DecodeBayesPost(fisPost, timIDvect); +for seq = 1:size(fisLATdecode,2) + fisLATdecode(:,seq) = fisLATdecode(:,seq) - timIDvect'; +end +lagMean = smooth(mean(fisLATdecode,2),10); +lagVar = std(fisLATdecode,0,2); + + +%% Plot the MLB summary +figure; +% Plot the probability density +subplot(5,5,[1:4, 6:9, 11:14, 16:19]); +imagesc(mean(fisPost,3), [0 0.01]); +set(gca, 'ydir', 'normal'); +colormap jet; +% Plot odor decoding through the sequence +subplot(5,5,21:24); +plot(fisODRdecoded(1,:), 'color', [44/255 168/255 224/255], 'linewidth', 1); +hold on; +plot(fisODRdecoded(2,:), 'color', [154/255 133/255 122/255], 'linewidth', 1); +plot(fisODRdecoded(3,:), 'color', [9/255 161/255 74/255], 'linewidth', 1); +plot(fisODRdecoded(4,:), 'color', [128/255 66/255 151/255], 'linewidth', 1); +% Plot temporal decoding through the sequence +subplot(5,5,5:5:20) +plot(lagMean, 1:size(fisLATdecode,1), 'k'); +hold on; +plot([0 0], get(gca, 'ylim'), ':k'); +patch('XData', [lagMean+lagVar; flipud(lagMean-lagVar)],... + 'YData', [1:length(lagMean), length(lagMean):-1:1], 'FaceColor', 'k', 'FaceAlpha', .3, 'edgecolor', 'none'); + + +%% Functions %% + +%% +function post = CalcStaticBayesPost(likely, obsv, binSize) +post = nan(size(obsv,1), size(likely,1), size(obsv,3)); +for trl = 1:size(obsv,3) + for t = 1:size(obsv,1) + p = nan(size(likely)); + curPopVect = obsv(t,:,trl)*(binSize/1000); + curPopFact = factorial(curPopVect); + for u = 1:size(likely,2) + curAvgUniFR = likely(:,u); + p(:,u) = (((binSize/1000).*curAvgUniFR).^curPopVect(u))./curPopFact(u); + end + pp = prod(p,2); + ee = exp(-((binSize/1000)*sum(likely,2))); + tempPost = pp.*ee; + post(t,:,trl) = tempPost./sum(tempPost); + end +end +end + +%% +function decode = DecodeBayesPost(post, id) +% Assumes post is in the structure of ObservTime X LikelyTime X Trial +decode = nan(size(post,1),size(post,3)); +for o = 1:size(post,3) + for d = 1:size(post,1) + if ~isnan(post(d,1,o)) + decode(d,o) = id(find(post(d,:,o)==max(post(d,:,o)),1,'first')); + end + end +end +end \ No newline at end of file diff --git a/OSMdata Code/TEMPosmMLBphaseCraziness.m b/OSMdata Code/TEMPosmMLBphaseCraziness.m new file mode 100644 index 0000000..4f826ca --- /dev/null +++ b/OSMdata Code/TEMPosmMLBphaseCraziness.m @@ -0,0 +1,225 @@ +%% Runtime variables +piWindow = [-0.5 0.5]; +poWindow = [-0.5 0.5]; +slideWin = 200; +dsRate = 5; +phaseBins = -pi:pi/3.5:pi; +cLim = [0 0.01]; +spectRanges = [[4,12];... + [16, 32];... + [40 59];... + [61 100]]; + +piWindowTS = piWindow(1):(dsRate*mode(diff(tsVect))):piWindow(2); +poWindowTS = poWindow(1):(dsRate*mode(diff(tsVect))):poWindow(2); + +%% Create the spikeMtx: the multiunit signal from every tetrode by aggregating the cut and uncut units together. +tempTSvect = tsVect; +tempTSvect(end+1) = tsVect(end)+(mode(diff(tsVect))); +spikeMtx = nan(length(tsVect), length(osmNeural)); +lfpInstPhase = nan(length(tsVect), length(osmNeural), size(spectRanges,1)); + +for t = 1:length(osmNeural) + tempTetSpks = osmNeural(t).Spikes; + tempSpikes = []; + if ~isempty(tempTetSpks) + uniNms = fieldnames(tempTetSpks); + if length(uniNms)~=1 + tempTetLFP = osmNeural(t).LFP; + for f = 1:size(spectRanges,1) + lfpInstPhase(:,t,f) = SimpleHilbFilt(tempTetLFP, 1/mode(diff(tsVect)), spectRanges(f,:)); + end + for u = 2:length(uniNms) + tempSpikes = [tempSpikes; tempTetSpks.(uniNms{u})]; %#ok + end + spikeMtx(:,t) = histcounts(tempSpikes, tempTSvect); + end + end +end +tetNames = {osmNeural.TetName}; +tetNames(isnan(spikeMtx(1,:))) = []; +lfpInstPhase(:,isnan(spikeMtx(1,:)),:) = []; +for ph = 1:size(lfpInstPhase,3) + lfpInstPhase(:,:,ph) = [lfpInstPhase(:,end,ph), lfpInstPhase(:,1:end-1, ph)]; % Rotate LFP to other tetrodes to break LFP/spiking relationship +% lfpInstPhase(:,:,ph) = repmat(lfpInstPhase(:,1,ph), [1,size(lfpInstPhase,2)]); % Or... use a common tetrode's LFP signal +end +spikeMtx(:,isnan(spikeMtx(1,:))) = []; + +%% Bin spiking on a per trial basis +piSpikeMtx = nan(length(piWindowTS)-1, length(tetNames), length(osmBehavior)); +poSpikeMtx = nan(length(poWindowTS)-1, length(tetNames), length(osmBehavior)); +trlSpikeMtx = nan(length(piWindowTS) + length(poWindowTS) -2, length(tetNames), length(osmBehavior)); + +piSpikeMtxPhase = repmat({piSpikeMtx}, [size(spectRanges,1), length(phaseBins)-1]); +poSpikeMtxPhase = repmat({piSpikeMtx}, [size(spectRanges,1), length(phaseBins)-1]); +trlSpikeMtxPhase = repmat({[piSpikeMtx;poSpikeMtx]}, [size(spectRanges,1), length(phaseBins)-1]); + +lfpInstPhaseTrlMtx = repmat({nan(length(piWindowTS) + length(poWindowTS) -2, length(tetNames), length(osmBehavior))}, [1 size(spectRanges,1)]); + +for trl = 1:length(osmBehavior) + pokeInWindowLog = tsVect>osmBehavior(trl).PortEntryTime + piWindow(1) - (slideWin/2*mode(diff(tsVect))) & tsVect<=osmBehavior(trl).PortEntryTime + piWindow(2) + (slideWin/2*mode(diff(tsVect))); + pokeOutWindowLog = tsVect>osmBehavior(trl).PortExitTime + poWindow(1) - (slideWin/2*mode(diff(tsVect))) & tsVect<=osmBehavior(trl).PortExitTime + poWindow(2) + (slideWin/2*mode(diff(tsVect))); + + for tet = 1:length(tetNames) + curPIspikes = spikeMtx(pokeInWindowLog,tet); + tempSpksPI = conv(curPIspikes, ones(1,slideWin)./(slideWin/1000), 'same'); + piSpikeMtx(:,tet,trl) = downsample(tempSpksPI((slideWin/2)+1:end-(slideWin/2)),dsRate); + + curPOspikes = spikeMtx(pokeOutWindowLog,tet); + tempSpksPO = conv(curPOspikes, ones(1,slideWin)./(slideWin/1000), 'same'); + poSpikeMtx(:,tet,trl) = downsample(tempSpksPO((slideWin/2)+1:end-(slideWin/2)),dsRate); + + trlSpikeMtx(:,tet,trl) = [piSpikeMtx(:,tet,trl);poSpikeMtx(:,tet,trl)]; + for freq = 1:size(spectRanges,1) + curTetFreqHilbPI = lfpInstPhase(pokeInWindowLog,tet,freq); + curTetFreqHilbPO = lfpInstPhase(pokeOutWindowLog,tet,freq); + lfpInstPhaseTrlMtx{freq}(:,tet,trl) = [downsample(curTetFreqHilbPI((slideWin/2)+1:end-(slideWin/2)), dsRate);... + downsample(curTetFreqHilbPO((slideWin/2)+1:end-(slideWin/2)), dsRate)]; + for phase = 2:length(phaseBins) + tempPIspks = curPIspikes; + curPhaseLogPI = curTetFreqHilbPI>=phaseBins(phase-1) & curTetFreqHilbPI=phaseBins(phase-1) & curTetFreqHilbPOosmBehavior(trl).PortEntryTime + piWindow(1) - (spectWin/2000) & tsVect<=osmBehavior(trl).PortEntryTime + piWindow(2) + (spectWin/2000); + pokeOutWindowLog = tsVect>osmBehavior(trl).PortExitTime + poWindow(1) - (spectWin/2000) & tsVect<=osmBehavior(trl).PortExitTime + poWindow(2) + (spectWin/2000); + + betaHilbPI = nan(sum(pokeInWindowLog), length(osmNeural)); + betaHilbPO = nan(sum(pokeOutWindowLog), length(osmNeural)); + osmBehavior(trl).ThetaPhaseBinPI = nan(length(0:spectWin-spectOverlap:diff(piWindow)*1000),length(osmNeural)); + osmBehavior(trl).ThetaPhaseBinPO = nan(length(0:spectWin-spectOverlap:diff(poWindow)*1000),length(osmNeural)); + + + osmBehavior(trl).PIspect = nan(length(freqs), length(0:spectWin-spectOverlap:diff(piWindow)*1000), length(osmNeural)); %#ok<*SAGROW> + osmBehavior(trl).POspect = nan(length(freqs), length(0:spectWin-spectOverlap:diff(poWindow)*1000), length(osmNeural)); + for tet = 1:length(osmNeural) + tetPokeInLFP = osmNeural(tet).LFP(pokeInWindowLog); + tetPokeOutLFP = osmNeural(tet).LFP(pokeOutWindowLog); + if tet == 1 + [tempPIspect, trlFreqs{trl}, ts] = spectrogram(tetPokeInLFP, spectWin, spectOverlap, freqs, 1000); + tempTs = ts - (spectWin/2000); + [tempPOspect, ~, ~] = spectrogram(tetPokeOutLFP, spectWin, spectOverlap, freqs, 1000); + else + [tempPIspect, ~, ~] = spectrogram(tetPokeInLFP, spectWin, spectOverlap, freqs, 1000); + [tempPOspect, ~, ~] = spectrogram(tetPokeOutLFP, spectWin, spectOverlap, freqs, 1000); + end + osmBehavior(trl).PIspect(:,:,tet) = 10*log10(abs(tempPIspect)); + for t = 1:size(osmBehavior(trl).PIspect,2) + osmBehavior(trl).PIspect(:,t,tet) = (osmBehavior(trl).PIspect(:,t,tet)-spectNormMean(:,tet))./spectNormVar(:,tet); + end + osmBehavior(trl).POspect(:,:,tet) = 10*log10(abs(tempPOspect)); + for t = 1:size(osmBehavior(trl).POspect,2) + osmBehavior(trl).POspect(:,t,tet) = (osmBehavior(trl).POspect(:,t,tet)-spectNormMean(:,tet))./spectNormVar(:,tet); + end + [betaHilbPI(:,tet), ~] = PhaseFreqDetectAbbr(tetPokeInLFP, tsVect(pokeInWindowLog), 16, 32); + [betaHilbPO(:,tet), ~] = PhaseFreqDetectAbbr(tetPokeOutLFP, tsVect(pokeOutWindowLog), 16, 32); + [thetaHilbPI, ~] = PhaseFreqDetectAbbr(tetPokeInLFP, tsVect(pokeInWindowLog), 4, 12); + piNndx = 0; + for tBin = 0:spectWin-spectOverlap:diff(piWindow)*1000 + piNndx = piNndx+1; + osmBehavior(trl).ThetaPhaseBinPI(piNndx,tet) = circ_mean(thetaHilbPI(tBin+1:tBin+(spectWin-spectOverlap))); + end + [thetaHilbPO, ~] = PhaseFreqDetectAbbr(tetPokeInLFP, tsVect(pokeOutWindowLog), 4, 12); + poNndx = 0; + for tBin = 0:spectWin-spectOverlap:diff(poWindow)*1000 + poNndx = poNndx+1; + osmBehavior(trl).ThetaPhaseBinPO(poNndx,tet) = circ_mean(thetaHilbPO(tBin+1:tBin+(spectWin-spectOverlap))); + end + end + tempTrlCoherPI = nan(length(osmNeural), length(osmNeural), length(0:spectWin-spectOverlap:diff(piWindow)*1000)); + tempTrlCoherPO = nan(length(osmNeural), length(osmNeural), length(0:spectWin-spectOverlap:diff(piWindow)*1000)); + for tet1 = 1:length(osmNeural) + for tet2 = 1:length(osmNeural) + if tet1 == tet2 + continue; + else + tsNdx = 1; + for ts = 1:(spectWin-spectOverlap):size(betaHilbPI,1)-(spectWin)+1 + [tempTrlCoherPI(tet1, tet2, tsNdx), ~] = circ_corrcc(betaHilbPI(ts:ts+spectWin-1,tet1), betaHilbPI(ts:ts+spectWin-1,tet2)); + [tempTrlCoherPO(tet1, tet2, tsNdx), ~] = circ_corrcc(betaHilbPO(ts:ts+spectWin-1,tet1), betaHilbPO(ts:ts+spectWin-1,tet2)); + tsNdx = tsNdx+1; + end + end + end + end + osmBehavior(trl).PIcoher = tempTrlCoherPI; + osmBehavior(trl).PIcoherMean = nanmean(tempTrlCoherPI,3); + osmBehavior(trl).POcoher = tempTrlCoherPO; + osmBehavior(trl).POcoherMean = nanmean(tempTrlCoherPO,3); +end + +%% +isTrlLog = ([osmBehavior.TrialPosition] - [osmBehavior.TrialOdor])==0; +perfTrlLog = [osmBehavior.PerformanceLog]==1; +iscTrials = osmBehavior(isTrlLog & perfTrlLog); +oscTrials = osmBehavior(~isTrlLog & perfTrlLog); + +for tet = 1:length(osmNeural) + iscPIspect = median(cell2mat(reshape(cellfun(@(a)a(:,:,tet), {iscTrials.PIspect}, 'uniformoutput', 0), [1,1,length(iscTrials)])),3); + oscPIspect = median(cell2mat(reshape(cellfun(@(a)a(:,:,tet), {oscTrials.PIspect}, 'uniformoutput', 0), [1,1,length(oscTrials)])),3); + iscPOspect = median(cell2mat(reshape(cellfun(@(a)a(:,:,tet), {iscTrials.POspect}, 'uniformoutput', 0), [1,1,length(iscTrials)])),3); + oscPOspect = median(cell2mat(reshape(cellfun(@(a)a(:,:,tet), {oscTrials.POspect}, 'uniformoutput', 0), [1,1,length(oscTrials)])),3); + figure; + annotation('textbox', 'Position',[0.05 0.95 0.9 0.05],... + 'String', osmNeural(tet).TetName, 'HorizontalAlignment', 'Left',... + 'Fontweight', 'bold',... + 'VerticalAlignment', 'bottom', 'FitHeightToText','off',... + 'LineStyle','none', 'Interpreter', 'none'); + subplot(2,2,1); + imagesc((0:spectWin-spectOverlap:diff(piWindow)*1000)-500, freqs, iscPIspect, [-2 2]); + title('ISC Poke In Aligned'); + set(gca, 'ydir', 'normal'); + subplot(2,2,2); + imagesc((0:spectWin-spectOverlap:diff(poWindow)*1000)-500, freqs, iscPOspect, [-2 2]); + title('ISC Poke Out Aligned'); + set(gca, 'ydir', 'normal'); + subplot(2,2,3); + imagesc((0:spectWin-spectOverlap:diff(piWindow)*1000)-500, freqs, oscPIspect, [-2 2]); + title('ISC Poke In Aligned'); + set(gca, 'ydir', 'normal'); + subplot(2,2,4); + imagesc((0:spectWin-spectOverlap:diff(poWindow)*1000)-500, freqs, oscPOspect, [-2 2]); + title('ISC Poke Out Aligned'); + set(gca, 'ydir', 'normal'); +end + +figure; +iscPIcoher = median(cell2mat(reshape({iscTrials.PIcoherMean}, [1,1,length(iscTrials)])),3); +oscPIcoher = median(cell2mat(reshape({oscTrials.PIcoherMean}, [1,1,length(oscTrials)])),3); +iscPOcoher = median(cell2mat(reshape({iscTrials.POcoherMean}, [1,1,length(iscTrials)])),3); +oscPOcoher = median(cell2mat(reshape({oscTrials.POcoherMean}, [1,1,length(oscTrials)])),3); +subplot(2,2,1); +imagesc(1:length(osmNeural), 1:length(osmNeural), iscPIcoher, [-1 1]); +set(gca, 'xtick', 1:length(osmNeural), 'xticklabel', {osmNeural.TetName}, 'ytick', 1:length(osmNeural), 'yticklabel', {osmNeural.TetName}); +title('ISC Beta Coherence (PI)'); + +subplot(2,2,2); +imagesc(1:length(osmNeural), 1:length(osmNeural), iscPOcoher, [-1 1]); +set(gca, 'xtick', 1:length(osmNeural), 'xticklabel', {osmNeural.TetName}, 'ytick', 1:length(osmNeural), 'yticklabel', {osmNeural.TetName}); +title('ISC Beta Coherence (PO)'); + +subplot(2,2,3); +imagesc(1:length(osmNeural), 1:length(osmNeural), oscPIcoher, [-1 1]); +set(gca, 'xtick', 1:length(osmNeural), 'xticklabel', {osmNeural.TetName}, 'ytick', 1:length(osmNeural), 'yticklabel', {osmNeural.TetName}); +title('OSC Beta Coherence (PI)'); + +subplot(2,2,4); +imagesc(1:length(osmNeural), 1:length(osmNeural), oscPOcoher, [-1 1]); +set(gca, 'xtick', 1:length(osmNeural), 'xticklabel', {osmNeural.TetName}, 'ytick', 1:length(osmNeural), 'yticklabel', {osmNeural.TetName}); +title('OSC Beta Coherence (PI)'); +colormap jet + +%% +phaseBins = -pi:pi/5:pi; +for tet = 1:length(osmNeural) + tpbPI = cell2mat(cellfun(@(a)a(:,tet),{iscTrials.ThetaPhaseBinPI}, 'uniformoutput', 0)); + tpbPO = cell2mat(cellfun(@(a)a(:,tet),{iscTrials.ThetaPhaseBinPO}, 'uniformoutput', 0)); + betaPowerPI = cell2mat(cellfun(@(a)mean(a(16:32,:,tet),1)', {iscTrials.PIspect}, 'uniformoutput', 0)); + betaPowerPO = cell2mat(cellfun(@(a)mean(a(16:32,:,tet),1)', {iscTrials.POspect}, 'uniformoutput', 0)); + + piThetaBetaMod = nan(length(phaseBins)-1, length(0:spectWin-spectOverlap:diff(piWindow)*1000)); + for t = 1:length(0:spectWin-spectOverlap:diff(piWindow)*1000) + curTPB = tpbPI(t,:); + for p = 1:length(phaseBins)-1 + tpbLog = curTPB>=phaseBins(p) & curTPB=phaseBins(p) & curTPB +end +tsVect(end+1) = tsVect(end)+(1/samp); + +seqLength = plxData.Summary.SequenceLength; +maxSeqLength = max([plxData.Raw.OrdinalPosition]); +%% +% Step through each sequence item/position and identify when odors were +% presented +% Do position first because it doesn't change with multiple lists +% fprintf(outfile, 'Position Counts\n'); +posVals = nan(length(tsVect)-1, seqLength); +posHeaders = cell(1,seqLength); +for pos = 1:maxSeqLength + posPresTimes = [plxData.Raw([plxData.Raw.OrdinalPosition]==pos).ItemPresentationTime]; + posVals(:,pos) = histcounts(posPresTimes, tsVect)'; + posHeaders{pos} = ['Position' num2str(pos)]; + fprintf(outfile, ' Position #%i = %i trials\n', pos, length(posPresTimes)); +end +% fprintf(outfile, 'Odor Counts\n'); +seqVals = nan(length(tsVect)-1, seqLength); +seqHeaders = cell(1,seqLength); +for seq = 1:seqLength + itemPresTimes = [plxData.Raw([plxData.Raw.SequenceItem]==seq).ItemPresentationTime]; + seqVals(:,seq) = histcounts(itemPresTimes, tsVect)'; + seqHeaders{seq} = ['Odor' num2str(seq)]; + fprintf(outfile, ' Odor #%i = %i trials\n', seq, length(itemPresTimes)); +end +if isfield(plxData.Summary, 'DualListLog') && plxData.Summary.DualListLog + dlSeqVals = nan(length(tsVect)-1,seqLength); + dlSeqHeaders = cell(1,seqLength); + for seq = 11:seqLength+10 + itemPresTimes = [plxData.Raw([plxData.Raw.SequenceItem]==seq).ItemPresentationTime]; + dlSeqVals(:,seq-10) = histcounts(itemPresTimes, tsVect)'; + dlSeqHeaders{seq-10} = ['Odor' num2str(seq)]; + fprintf(outfile, ' Odor #%i = %i trials\n', seq, length(itemPresTimes)); + end + seqVals = [seqVals, dlSeqVals]; + seqHeaders = [seqHeaders, dlSeqHeaders]; +end +% In Seq Vect +inSeqOdorPres = [plxData.Raw([plxData.Raw.TranspositionDistance]==0).ItemPresentationTime]; +outSeqOdorPres = [plxData.Raw(~([plxData.Raw.TranspositionDistance]==0)).ItemPresentationTime]; +isVals = histcounts(inSeqOdorPres, tsVect)' - histcounts(outSeqOdorPres,tsVect)'; +fprintf(outfile, '\nCompiling InSeq trials.....\n %i trials were InSeq (%i%%)\n', length(inSeqOdorPres), round(length(inSeqOdorPres)/length(plxData.Raw),2)*100); + +itmPresTimes = [plxData.Raw.ItemPresentationTime]; +trialPerformance = [plxData.Raw.Performance]; +corrTrials = itmPresTimes(logical(trialPerformance)); +corTrlHistCounts = histcounts(corrTrials, tsVect)'; +inCorrTrials = itmPresTimes(~logical(trialPerformance)); +inCorTrlHistCounts = histcounts(inCorrTrials, tsVect)'; +perfVals = corTrlHistCounts + (inCorTrlHistCounts*-1); +fprintf(outfile, 'Compiling Performance.....\n %i trials were correct (%i%%)\n', sum(trialPerformance), round(mean(trialPerformance),2)*100); + +lightVals = histcounts([plxData.Raw.TrialLightTime], tsVect)'; + +pokeVals = histcounts([plxData.Raw.OdorTrigPokeTime], tsVect)' - histcounts([plxData.Raw.OdorPokeWithdrawTime], tsVect)'; + +rwdVals = histcounts([plxData.Raw.FrontRewardTime], tsVect)'; + +backRwdVals = histcounts([plxData.Raw.BackRewardTime], tsVect)'; + +errVals = histcounts([plxData.Raw.ErrorSignalTime], tsVect)'; + +rwdSigVals = histcounts([plxData.Raw.RewardSignalTime], tsVect)'; + +[numChans, chanNames] = plx_event_names(plxData.Summary.PLXfile); +findingStrobed = 1; +aniPosVals = nan(length(tsVect)-1, 2); +while findingStrobed + for chan = 1:numChans + curChan = chanNames(chan,:); + intVals = double(curChan); + valLim = find(~(intVals==0), 1, 'last'); + strobedChanLog = strcmp(curChan(1:valLim), 'Strobed'); + if strobedChanLog + [~, strobedTS, strobedSV] = plx_event_ts(plxData.Summary.PLXfile, curChan); + [~, ~, ~, aniPosition] = plx_vt_interpret(strobedTS, strobedSV); + aniPosition(aniPosition(:,1)=5 + for t = 1:size(aniPosition,1) + if (aniPosition(t,2)==0 && aniPosition(t,3)==0) &&... + (aniPosition(t,4)>0 && aniPosition(t,5)>0) + aniX(t) = aniPosition(t,4); + aniY(t) = aniPosition(t,5); + elseif (aniPosition(t,4)==0 && aniPosition(t,5)==0) &&... + (aniPosition(t,2)>0 && aniPosition(t,3)>0) + aniX(t) = aniPosition(t,2); + aniY(t) = aniPosition(t,3); + elseif (aniPosition(t,2)>0 && aniPosition(t,3)>0) &&... + (aniPosition(t,3)>0 && aniPosition(t,5)>0) + aniX(t) = mean([aniPosition(t,2) aniPosition(t,4)]); + aniY(t) = mean([aniPosition(t,3) aniPosition(t,5)]); + elseif (aniPosition(t,2)==0 && aniPosition(t,3)==0) &&... + (aniPosition(t,3)==0 && aniPosition(t,5)==0) + aniX(t) = 0; + aniY(t) = 0; + end + end + end + aniPosHistBins = find(histcounts(aniPosition(:,1), tsVect)); + aniPosVals(aniPosHistBins,1) = aniX'; + aniPosVals(aniPosHistBins,2) = aniY'; + findingStrobed = 0; + end + end +end + +behavMatrix = [tsVect(1:end-1)', posVals, seqVals, isVals, perfVals, lightVals, pokeVals,... + rwdVals, backRwdVals, errVals, rwdSigVals, aniPosVals]; +behavMatrixColIDs = ['TimeBin', posHeaders, seqHeaders, 'InSeqLog', 'PerformanceLog', 'PortLight', 'PokeEvents',... + 'FrontReward', 'BackReward', 'ErrorSignal', 'RewardSignal', 'XvalRatMazePosition', 'YvalRatMazePosition']; + +save([plxData.Summary.PLXfile(1:end-4) '_BehaviorMatrix.mat'], 'behavMatrix', 'behavMatrixColIDs', 'plxData'); +disp('Behavior data saved.'); +fprintf(outfile, 'Behavior Matrix saved as %s_BehaviorMatrix.mat\n', plxData.Summary.PLXfile(1:end-4)); +end \ No newline at end of file diff --git a/statMatrix Creation/CreateOrientationMatrix.m b/statMatrix Creation/CreateOrientationMatrix.m new file mode 100644 index 0000000..8790485 --- /dev/null +++ b/statMatrix Creation/CreateOrientationMatrix.m @@ -0,0 +1,114 @@ +function CreateOrientationMatrix + +origDir = cd; +[fileDir] = uigetdir(origDir); +if fileDir==0 + disp('Analysis Cancelled') + return +else + cd(fileDir) +end +dirContents = dir(fileDir); +fileNames = {dirContents.name}; + +%% Load BehaviorMatrix and Orientation_Data Files +load(fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}); +load(fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'Orientation_Data'))}); + +%% Compare the timestamps from the behavMatrix and orientation_data files. +% Since the timestamps used in the statMatrix files is constructed based +% on the LFP sample rate they don't match up identically with the frame +% indices taken from the .AVI file. Therefore we are expecting some +% discrepancy to exist between the video timestamps ('FrameTimestamp' +% column) and the behavMatrix timestamps ('TimeBin' column), but that +% discrepancy should be very small. +frameIndices = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'FrameIndex')}]; +frameTimestamps = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'FrameTimestamp')}]; + +% To assess whether they are from the same data we first check to make sure +% the indices expected in the orientData file can be found within the +% behavMatrix. Then we compare the mean and median for the difference +% between the orientData and behavMatrix and as long as it's below a +% floating point threshold odds are they're from the same data and we can +% assume the frameIndices are correct. +if max(frameIndices) > size(behavMatrix,1) + error('More frameIndices than actual indices in the behavMatrix. Double check files'); +elseif mean(behavMatrix(frameIndices,1) - frameTimestamps') - median(behavMatrix(frameIndices,1) - frameTimestamps') >= 1.0e-10 + error('Difference between mean/median for behavior and orientation timestamp differences is larget than 1.0e-10. Double check files or change threhsold for match violations'); +end + +%% Create the orientMatrix and orientMatrixColIDs variables +orientMatrixColIDs = [{'TimeBin'}, {'PortX'}, {'PortY'}, {'PortAngle'},... + {'HeadX'}, {'HeadY'}, {'HeadAngle'},... + {'TailX'}, {'TailY'}, {'TailAngle'},... + {'HeadTailLength'}, {'HeadPortLength'}, {'PortTailLength'}]; +orientMatrix = [behavMatrix(:,1), nan(size(behavMatrix,1), 12)]; + +%% Fill in the orientation values from the Orientation_Data file +orientMatrix(frameIndices,strcmp(orientMatrixColIDs, 'PortX')) = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'PortX')}]; +orientMatrix(frameIndices,strcmp(orientMatrixColIDs, 'PortY')) = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'PortY')}]; +orientMatrix(frameIndices,strcmp(orientMatrixColIDs, 'HeadX')) = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'HeadX')}]; +orientMatrix(frameIndices,strcmp(orientMatrixColIDs, 'HeadY')) = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'HeadY')}]; +orientMatrix(frameIndices,strcmp(orientMatrixColIDs, 'TailX')) = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'TailX')}]; +orientMatrix(frameIndices,strcmp(orientMatrixColIDs, 'TailY')) = [orientData.FileIndices{:,strcmp(orientData.FileIndicesColIDs, 'TailY')}]; + +%% Calculate the angle and length values +posIndices = find(~isnan(orientMatrix(:,2))); + +for pos = 1:length(posIndices) + curPosNdx = posIndices(pos); + curPortX = orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'PortX')); + curPortY = orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'PortY')); + curHeadX = orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'HeadX')); + curHeadY = orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'HeadY')); + curTailX = orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'TailX')); + curTailY = orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'TailY')); + + htVal = sqrt((curTailX - curHeadX)^2 + (curTailY - curHeadY)^2); + orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'HeadTailLength')) = htVal; + hpVal = sqrt((curPortX - curHeadX)^2 + (curPortY - curHeadY)^2); + orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'HeadPortLength')) = hpVal; + ptVal = sqrt((curTailX - curPortX)^2 + (curTailY - curPortY)^2); + orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'PortTailLength')) = ptVal; + + orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'PortAngle')) = rad2deg(acos((ptVal^2 + hpVal^2 - htVal^2)/(2*ptVal*hpVal))); + orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'HeadAngle')) = rad2deg(acos((htVal^2 + hpVal^2 - ptVal^2)/(2*htVal*hpVal))); + orientMatrix(curPosNdx, strcmp(orientMatrixColIDs, 'TailAngle')) = rad2deg(acos((htVal^2 + ptVal^2 - hpVal^2)/(2*htVal*ptVal))); +end + +%% Save the orientationMatrix File +fileParts = strsplit(fileNames{cellfun(@(a)~isempty(a), strfind(fileNames, 'BehaviorMatrix'))}, '_'); +save(sprintf('%s_%s_OrientationMatrix', fileParts{1}, fileParts{2}), 'orientMatrix', 'orientMatrixColIDs'); + +%% Create a summary figure +figure; +scatAll = subplot(2,2,1); +scatter(orientMatrix(:,strcmp(orientMatrixColIDs, 'HeadX')), orientMatrix(:,strcmp(orientMatrixColIDs, 'HeadY')), 15, 'markeredgecolor', 'none', 'markerfacecolor', 'b', 'markerfacealpha', 0.25); +hold on; +scatter(orientMatrix(:,strcmp(orientMatrixColIDs, 'TailX')), orientMatrix(:,strcmp(orientMatrixColIDs, 'TailY')), 15, 'markeredgecolor', 'none', 'markerfacecolor', 'r', 'markerfacealpha', 0.25); +scatter(orientMatrix(:,strcmp(orientMatrixColIDs, 'PortX')), orientMatrix(:,strcmp(orientMatrixColIDs, 'PortY')), 100, 'markeredgecolor', 'k', 'markerfacecolor', 'k') + +scatter(nanmean(orientMatrix(:,strcmp(orientMatrixColIDs, 'HeadX'))), nanmean(orientMatrix(:,strcmp(orientMatrixColIDs, 'HeadY'))), 100, 'x', 'markeredgecolor', 'k', 'markerfacecolor', 'b', 'linewidth', 2); +scatter(nanmean(orientMatrix(:,strcmp(orientMatrixColIDs, 'TailX'))), nanmean(orientMatrix(:,strcmp(orientMatrixColIDs, 'TailY'))), 100, 'x', 'markeredgecolor', 'k', 'markerfacecolor', 'r', 'linewidth', 2); +title(sprintf('%s %s PreTrial = %i ms, PostTrial = %i ms', fileParts{1}, fileParts{2}, orientData.Params.PreTrialDuration*1000, orientData.Params.PostTrialDuration*1000)); + +trlStruct = OrganizeTrialData_SM(behavMatrix, behavMatrixColIDs, [0 0], 'PokeIn'); +headSP = subplot(2,2,3); +tailSP = subplot(2,2,4); +linkaxes([scatAll, headSP, tailSP], 'xy'); +for trl = 1:length(trlStruct) + winStart = trlStruct(trl).PokeInIndex - (orientData.Params.PreTrialDuration*1000); + winEnd = trlStruct(trl).PokeOutIndex + (orientData.Params.PostTrialDuration*1000); + trlOrient = orientMatrix(winStart:winEnd,:); + omx = trlOrient(sum(~isnan(trlOrient),2)==size(trlOrient,2),:); + tempHead = plot(headSP, omx(:,strcmp(orientMatrixColIDs, 'HeadX')), omx(:,strcmp(orientMatrixColIDs, 'HeadY')), 'k'); + tempHead.Color(4) = 0.25; + hold(headSP, 'on'); + tempTail = plot(tailSP, omx(:,strcmp(orientMatrixColIDs, 'TailX')), omx(:,strcmp(orientMatrixColIDs, 'TailY')), 'k'); + tempTail.Color(4) = 0.25; + hold(tailSP, 'on'); + drawnow; + pause(1) +end + +' \ No newline at end of file diff --git a/statMatrix Creation/StatMatrixCreator.m b/statMatrix Creation/StatMatrixCreator.m index 7029a39..b2bf739 100644 --- a/statMatrix Creation/StatMatrixCreator.m +++ b/statMatrix Creation/StatMatrixCreator.m @@ -175,15 +175,15 @@ end end if rig==1 - multiListCheck = questdlg('Use a different .plx file for behavioral events?', 'Event Check', 'Yes', 'No', 'Yes'); - switch multiListCheck + diffPLXflBehavChck = questdlg('Use a different .plx file for behavioral events?', 'Event Check', 'Yes', 'No', 'Yes'); + switch diffPLXflBehavChck case 'Yes' - multiList = 1; + diffPLXflBehav = 1; [fileName, filePath] = uigetfile('.plx', 'Identify the ORIGINAL .plx file'); plxFileBehav = [filePath '\' fileName]; fprintf(outfile, ' Plexon File used for behavior = %s\n', plxFileBehav); case 'No' - multiList = 0; + diffPLXflBehav = 0; end end elseif rig==3 || rig==4 || rig==5 @@ -204,7 +204,7 @@ %% Now create the statMatrix files %% Create Behavior Matrix if rig == 1 % Irvine .plx files - if multiList + if diffPLXflBehav [plxData] = SummarizePLXevents_SD(plxFileBehav, [], outfile); summary = plxData.Summary; summary.PLXfileBehav = summary.PLXfile; @@ -496,7 +496,7 @@ function CreateNeuralMatrixPLX(exp, data, rig, loc, tsVect, summary, outputFileN % Now run through each channel individually to identify things % tetLFPchanNames % tetsWithUnits - for chan = 6:length(tetLFPchanNames) + for chan = 1:length(tetLFPchanNames) if rig == 1 || rig == 2 curADchan = tetLFPchanNames{chan}; curTet = curADchan(1:end-2); diff --git a/statMatrix Creation/Supporting Code/SummarizePLXevents_SD.m b/statMatrix Creation/Supporting Code/SummarizePLXevents_SD.m index 4d09f91..b32da5e 100644 --- a/statMatrix Creation/Supporting Code/SummarizePLXevents_SD.m +++ b/statMatrix Creation/Supporting Code/SummarizePLXevents_SD.m @@ -17,11 +17,12 @@ plxFile = [path fileName]; [path, fileName] = fileparts(plxFile); path = [path '\']; + cd(path); flContents = dir(path); fileNames = {flContents.name}; matFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, [fileName '_([0-9]*)-([A-Z | a-z]*)-([0-9]*).mat'])); if sum(matFileLog)==0 - [matFileName, matFilePath] = uigetfile('.mat', 'No .MAT file found in the folder with the .PLX file, select the ssnData file'); + [matFileName, matFilePath] = uigetfile('.mat', 'No matching .MAT file found in the folder with the .PLX file, select the ssnData file'); if matFileName == 0 disp('No .MAT file selected, analysis cancelled') return @@ -31,14 +32,14 @@ matFile = [path fileNames{matFileLog}]; [~, matFileName] = fileparts(matFile); end - outfile = fopen(sprintf('%s_PLXeventSummary.txt', matFileName), 'At'); + outfile = fopen(sprintf('%s_PLXeventSummary.txt', matFileName), 'a+'); end if isempty(matFile) [path, fileName] = fileparts(plxFile); path = [path '\']; flContents = dir(path); fileNames = {flContents.name}; - matFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, [fileName '_([0-9]*)-([A-Z | a-z]*)-([0-9]*).mat'])); + matFileLog = cellfun(@(a)~isempty(a), regexp(fileNames, [fileName '_([0-9]*)-([A-Z | a-z]*)-([0-9]*).mat$'])); if sum(matFileLog)==0 [matFileName, matFilePath] = uigetfile('.mat', 'No .MAT file found in the folder with the .PLX file, select the ssnData file'); if matFileName == 0 @@ -52,15 +53,16 @@ end end if isempty(outfile) - outfile = fopen(sprintf('%s_PLXeventSummary.txt', matFileName), 'At'); + outfile = fopen(sprintf('%s_PLXeventSummary.txt', matFileName), 'a+'); end else - outfile = fopen(sprintf('%s_PLXeventSummary.txt', matFileName), 'At'); %#ok + outfile = fopen(sprintf('%s_PLXeventSummary.txt', matFileName), 'a+'); %#ok end -plxSummary.MATfile = matFileName; -plxSummary.PLXfile = [fileName '.plx']; +plxData.Summary.MATfile = matFileName; +plxData.Summary.PLXfile = [fileName '.plx']; +plxData.Summary.Dir = path; -fprintf(outfile, '\n****Beginning behavioral analysis using SummarizePLXevents_SD.m. ****\n Mat File = %s\n Plx File = %s\n', plxSummary.MATfile, plxSummary.PLXfile); +fprintf(outfile, '\n****Beginning behavioral analysis using SummarizePLXevents_SD.m. ****\n Mat File = %s\n Plx File = %s\n', plxData.Summary.MATfile, plxData.Summary.PLXfile); %% Load Data % Load the ssnData file first load(matFile); @@ -90,9 +92,9 @@ % error('This data was collected with an old version of the code that didn''t allow declaration of buffer duration, please use an older plxAnalysis script for it'); end if isfield(ssnData(1).Settings, 'GracePeriodDur') - gracePeriod = ssnData(1).Settings.GracePeriodDur; + graceDur = arrayfun(@(a)a.Settings.GracePeriodDur, ssnData); else - gracePeriod = 0; + graceDur = zeros(size(ssnData)); end sequenceLength = ssnData(1).Settings.SequenceLength; % Now extract event data from the .plx file @@ -120,13 +122,13 @@ % terminateChannelLog = strcmp(channels, 'Terminate'); % if ~(sum(terminateChannelLog)==0) && ~(plxStruct(terminateChannelLog).n == 0) % term = 1; -% plxSummary.Terminate = 1; +% plxData.Summary.Terminate = 1; % terminateTime = plxStruct(terminateChannelLog).ts(find(plxStruct(terminateChannelLog).ts>0, 1, 'first')); % else term = 0; - plxSummary.Terminate = 0; + plxData.Summary.Terminate = 0; % end -plxSummary.Errors = []; +plxData.Summary.Errors = []; %% Pull Information from Buzzer channel (Sequence Block, Trial and Error Identifiers) % The easiest to parse the session is using the buzzer channel as it % has unique ways/times of activating during the trial. @@ -172,7 +174,8 @@ end % The number of double buzzer activations should match the number of % sequences recorded in the ssnData structure -if ~(length(sequenceBlockInitiationTimes)==length(unique([ssnData.SequenceNumber]))) +if ~(length(sequenceBlockInitiationTimes)==length(unique([ssnData.SequenceNumber]))) &&... + ~(length(sequenceBlockInitiationTimes)-1==length(unique([ssnData.SequenceNumber]))) fprintf('PLX file = %s\n', plxFile); fprintf('MAT file = %s\n', matFile); fprintf(outfile, 'Number of Sequences don''t match, check files and code for source of discrepancy\n PLX Count = %i\n MAT Count = %i\n', length(sequenceBlockInitiationTimes), length(unique([ssnData.SequenceNumber]))); @@ -183,12 +186,19 @@ % (reflecting sequence start), minus the number of error trials that % occurred, should equal the total number of trials that occurred if ~(length(nonDoubleBuzzBuzzer)+length(sequenceBlockInitiationTimes)-sum([ssnData.Performance]==0) == length(ssnData)) &&... - ~(length(nonDoubleBuzzBuzzer)+length(sequenceBlockInitiationTimes)-sum([ssnData.Performance]==0) == length(ssnData)-1) + ~(length(nonDoubleBuzzBuzzer)+length(sequenceBlockInitiationTimes)-sum([ssnData.Performance]==0)-1 == length(ssnData)) fprintf('PLX file = %s\n', plxFile); fprintf('MAT file = %s\n', matFile); fprintf(outfile, 'Number of Buzzer activations don''t match the number of trials, check files and code for source of discrepancy\n PLX Count = %i\n MAT Count = %i\n', length(nonDoubleBuzzBuzzer)+length(sequenceBlockInitiationTimes)-sum([ssnData.Performance]==0), length(ssnData)); warning('Number of Buzzer activations don''t match the number of trials, check files and code for source of discrepancy'); end +%% Identify Port Light times +portLightChan = strcmp(channels, 'Port Light A (front)'); +lightOnTimes = plxStruct(portLightChan).ts; + +if term + lightOnTimes(lightOnTimes>terminateTime) = []; +end %% Identify Beep (Reward Signal) Times beepChanNum = strcmp(channels, 'Tone'); beepTimes = plxStruct(beepChanNum).ts; @@ -248,17 +258,17 @@ if length(odorPresTime{1}) < length(odorPresTime{2}) fprintf(outfile, 'More Bs than As\n'); - plxSummary.Errors = {'More Bs than As'}; + plxData.Summary.Errors = {'More Bs than As'}; % error('More Bs than As') plxData.Session = plxSession; %#ok - plxData.Summary = plxSummary; + plxData.Summary = plxData.Summary; return end if ~exist('sequenceLength', 'var') sequenceLength = sum(cellfun(@(a)~isempty(a), odorPresTime)); end -plxSummary.SequenceLength = sequenceLength; +plxData.Summary.SequenceLength = sequenceLength; odorPresSsn = odorPresTime; for opt = 1:length(odorPresSsn) @@ -279,9 +289,9 @@ end if sum(unique(odorPresSsn(:,1)) > 5)>=1 - plxSummary.DualListLog = true; + plxData.Summary.DualListLog = true; else - plxSummary.DualListLog = false; + plxData.Summary.DualListLog = false; end %% Identify Poke Times % The key information used here is when the poke was initiated and how @@ -298,19 +308,19 @@ pokeChanDiff = diff(allPokes(:,2)); pokeChanRep = find(pokeChanDiff==0); if isempty(pokeChanRep) && (length(pokeInitiationTimes) > length(pokeEndTimes)) - plxSummary.Errors = [plxSummary.Errors; {'More pokes initiated than ended'}]; + plxData.Summary.Errors = [plxData.Summary.Errors; {'More pokes initiated than ended'}]; pokeInitiationTimes(end) = []; elseif isempty(pokeChanRep) && (length(pokeInitiationTimes) < length(pokeEndTimes)) - plxSummary.Errors = [plxSummary.Errors; {'More pokes ended than initiated'}]; + plxData.Summary.Errors = [plxData.Summary.Errors; {'More pokes ended than initiated'}]; pokeEndTimes(1) = []; elseif ~isempty(pokeChanRep) if allPokes(pokeChanRep,2)==2 pokeOutChanNumLog = pokeEndTimes==allPokes(pokeChanRep+1,1); - plxSummary.Errors = [plxSummary.Errors; {['More pokes ended than initiated @' num2str(pokeEndTimes(pokeOutChanNumLog))]}]; + plxData.Summary.Errors = [plxData.Summary.Errors; sprintf('More pokes ended than initiated @%f', pokeEndTimes(pokeOutChanNumLog))]; pokeEndTimes(pokeOutChanNumLog) = []; elseif allPokes(pokeChanRep,2)==1 pokeInitiationTimeLog = pokeInitiationTimes==allPokes(pokeChanRep,1); - plxSummary.Errors = [plxSummary.Errors; {['More pokes initiated than ended @' num2str(pokeInitiationTimes(pokeInitiationTimeLog))]}]; + plxData.Summary.Errors = [plxData.Summary.Errors; sprintf('More pokes initiated than ended @%f', pokeInitiationTimes(pokeInitiationTimeLog))]; pokeInitiationTimes(pokeInitiationTimeLog) = []; end end @@ -414,21 +424,34 @@ % Convert the strobed channel into x-y coordinates using plexon % functions posChanNum = strcmp(channels, 'Strobed'); -[~, ~, plxSummary.PositionVTmode, aniPosition] = plx_vt_interpret(plxStruct(posChanNum).ts, plxStruct(posChanNum).sv); +[~, ~, plxData.Summary.PositionVTmode, aniPosition] = plx_vt_interpret(plxStruct(posChanNum).ts, plxStruct(posChanNum).sv); % clean position data of non-values nonPositionLog = (aniPosition(:,2) + aniPosition(:,3))==0; aniPosition(nonPositionLog,:) = []; %% Identify and correct issues caused by asynchronous starts of Plexon and Matlab -if odorPresTime{1}(1)plxSession(trl).ItemPresentationTime,1,'first')); @@ -502,6 +531,7 @@ if sum(trialPokesLog) == 1 % i.e. if there is only one poke that occurred during the trial period plxSession(trl).PokeDuration = trialPokeDurations; + tempPokeNum = nan; elseif sum(trialPokesLog) > 1 tempPokeDur = trialPokeDurations(1); tempPokeNum = 1; @@ -510,29 +540,45 @@ if plxSession(trl).TranspositionDistance == 0 && plxSession(trl).Performance == 0 break elseif plxSession(trl).TranspositionDistance == 0 && plxSession(trl).Performance == 1 - if tempPokeDur >= ssnData(trl).TargetPokeDur - gracePeriod +% if plxSession(trl).TargetDuration - tempPokeDur <= graceDur(trl) + if floor((plxSession(trl).TargetDuration - tempPokeDur)*100)/100 <= graceDur(trl) % Potential fix... may cause problems though so keep an eye on this. + break + else +% msgbox(sprintf('Trial #%i: InSeq trial where buffer was triggered and duration elapsed but it was counted as correct\n\n Re-run the analysis with the error line commented in place of this line', trl), 'Poke Buffer Warning', 'warn'); +% error('Trial #%i: InSeq trial where buffer was triggered and duration elapsed but it was counted as correct', trl); +% fprintf(outfile, 'Trial #%i: InSeq trial where buffer was triggered and duration elapsed but it was counted as correct\n', trl); + tempPokeNum = tempPokeNum+1; + tempPokeDur = tempPokeDur + trialInterPokeIntervals(tempPokeNum-1)+trialPokeDurations(tempPokeNum); + fprintf(outfile, 'Trial #%i: InSeq trial where buffer was triggered and buffer duration elapsed but it was counted as correct\n', trl); + plxData.Summary.Errors = [plxData.Summary.Errors; + {['Trial #' num2str(trl) ': InSeq trial where buffer was triggered and buffer duration elapsed but it was counted as correct']}]; + plxSession(trl).QuestionableTrialLog = true; break end -% msgbox(sprintf('Trial #%i: InSeq trial where buffer was triggered and duration elapsed but it was counted as correct\n\n Re-run the analysis with the error line commented in place of this line', trl), 'Poke Buffer Warning', 'warn'); - warning('Trial #%i: InSeq trial where buffer was triggered and duration elapsed but it was counted as correct', trl); - fprintf(outfile, 'Trial #%i: InSeq trial where buffer was triggered and duration elapsed but it was counted as correct\n', trl); - tempPokeNum = tempPokeNum+1; - tempPokeDur = tempPokeDur + trialInterPokeIntervals(tempPokeNum-1)+trialPokeDurations(tempPokeNum); elseif ~(plxSession(trl).TranspositionDistance == 0) && plxSession(trl).Performance == 1 break elseif ~(plxSession(trl).TranspositionDistance == 0) && plxSession(trl).Performance == 0 if tempPokeDur < 0.2 tempPokeNum = tempPokeNum+1; tempPokeDur = tempPokeDur + trialInterPokeIntervals(tempPokeNum-1)+trialPokeDurations(tempPokeNum); + elseif plxSession(trl).TargetDuration - tempPokeDur <= graceDur(trl) + break else - msgbox(sprintf('Trial #%i: OutSeq trial where buffer was triggered and duration elapsed but it was counted as incorrect\n\n Re-run the analysis with the error line commented in place of this line', trl), 'Poke Buffer Warning', 'warn'); - warning('Trial #%i: OutSeq trial where buffer was triggered and duration elapsed but it was counted as incorrect', trl); +% msgbox(sprintf('Trial #%i: OutSeq trial where buffer was triggered and duration elapsed but it was counted as incorrect\n\n Re-run the analysis with the error line commented in place of this line', trl), 'Poke Buffer Warning', 'warn'); +% error('Trial #%i: OutSeq trial where buffer was triggered and duration elapsed but it was counted as incorrect', trl); % fprintf('Trial #%i: OutSeq trial where buffer was triggered and duration elapsed but it was counted as incorrect\n', trl); tempPokeNum = tempPokeNum+1; tempPokeDur = tempPokeDur + trialInterPokeIntervals(tempPokeNum-1)+trialPokeDurations(tempPokeNum); + fprintf(outfile, 'Trial #%i: OutSeq trial where buffer was triggered and buffer duration elapsed but it was counted as incorrect\n', trl); + plxData.Summary.Errors = [plxData.Summary.Errors; + {['Trial #' num2str(trl) ': OutSeq trial where buffer was triggered and buffer duration elapsed but it was counted as incorrect']}]; + plxSession(trl).QuestionableTrialLog = true; + break end + elseif abs(plxSession(trl).TranspositionDistance) == 10 + break end - elseif tempPokeNum > sum(trialPokesLog) + elseif tempPokeNum > sum(trialPokesLog) || plxSession(trl).TargetDuration - tempPokeDur < graceDur(trl) || isnan(trialInterPokeIntervals(tempPokeNum)) break else tempPokeNum = tempPokeNum+1; @@ -542,6 +588,9 @@ tempPokeDur = tempPokeDur + trialInterPokeIntervals(tempPokeNum-1)+trialPokeDurations(tempPokeNum); end end + if sum(trialPokeDurations) + sum(trialInterPokeIntervals(1:end-1)) == ssnData(trl).PokeDuration + tempPokeDur = sum(trialPokeDurations) + sum(trialInterPokeIntervals(1:end-1)); + end plxSession(trl).PokeDuration = tempPokeDur; elseif sum(trialPokesLog)==0 error('Trial #%i: No pokes detected', trl); @@ -564,7 +613,7 @@ fprintf(outfile, 'Trial #%i: Abberant performance value\n', trl); error('Trial #%i: Abberant performance value', trl); end - + plxSession(trl).MultiPokeCounts = tempPokeNum; %% ******Logical Checks****** % If these trigger they indicate a need for debugging. Either % there's an issue with the assumptions of this code, @@ -577,11 +626,10 @@ % Check to ensure poke durations match well between the .PLX ans .MAT % files. The only differences should be floating point, hence the % threshold of 0.00001 - if plxSession(trl).PokeDuration - ssnData(trl).PokeDuration > 0.00001 + if abs(plxSession(trl).PokeDuration - ssnData(trl).PokeDuration) > 0.00001 % error('Trial #%i: Trial poke durations for .PLX and .MAT don''t match', trl); fprintf(outfile, 'Trial #%i: Poke Duration discrepancy of %i\n', trl, plxSession(trl).PokeDuration - ssnData(trl).PokeDuration); - plxSummary.Errors = [plxSummary.Errors; sprintf('Trial #%i: Poke duration discrepancy of %.03f', trl, plxSession(trl).PokeDuration - ssnData(trl).PokeDuration) - ['Trial #' num2str(trl) ': Poke Duration discrepancy of ' num2str(plxSession(trl).PokeDuration - ssnData(trl).PokeDuration)]]; + plxData.Summary.Errors = [plxData.Summary.Errors; {['Trial #' num2str(trl) ': Poke Duration discrepancy of ' num2str(plxSession(trl).PokeDuration - ssnData(trl).PokeDuration)]}]; end % Check to ensure trial start came before trial end @@ -602,7 +650,7 @@ if ~((plxSession(trl).RewardSignalTime - plxSession(trl).OdorTrigPokeTime) > plxSession(trl).TargetDuration) if isfield(ssnData(1).Settings, 'GracePeriodDur') && plxSession(trl).TargetDuration - plxSession(trl).PokeDuration > ssnData(trl).Settings.GracePeriodDur fprintf(outfile, 'Trial #%i: Reward signal time occurred before target duration elapsed\n', trl); - error('Trial #%i: Reward signal time occurred before target duration elapsed', trl); +% error('Trial #%i: Reward signal time occurred before target duration elapsed', trl); end end % Check to ensure reward was presented AFTER the reward signal @@ -622,7 +670,6 @@ %% Compile Outputs plxData.Raw = plxSession; -plxData.Summary = plxSummary; fprintf(outfile, 'Behavioral Analysis Completed\n\n********************************************************\n');