diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 0b3beba..0000000 --- a/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -*.mlx -crlf -diff -merge -*.mat -crlf -diff -merge -*.fig -crlf -diff -merge -*.p -crlf -diff -merge -*.slx -crlf -diff -merge -*.mdl -crlf -diff -merge \ No newline at end of file diff --git a/GUIs/CellDataCurator.m b/GUIs/CellDataCurator.m index e172e71..e8f7be9 100755 --- a/GUIs/CellDataCurator.m +++ b/GUIs/CellDataCurator.m @@ -15,7 +15,6 @@ dataSet %vector of epoch indices allKeys epochsInDataSets = []; - quickParamsFilterList = {}; end properties (Hidden, Constant) @@ -73,26 +72,18 @@ function buildUIComponents(obj) L_diaryPlot = uiextras.VBox('Parent', L_dataPanels); obj.handles.diaryPlotAxes = axes('Parent', L_diaryPlot); - L_diaryMenu = uiextras.HBox('Parent', L_diaryPlot); - diaryYMenuText = uicontrol('Parent', L_diaryMenu, ... + L_diaryYMenu = uiextras.HBox('Parent', L_diaryPlot); + diaryYMenuText = uicontrol('Parent', L_diaryYMenu, ... 'Style', 'text', ... 'String', 'Diary plot y-axis', ... 'FontSize', 11); - obj.handles.diaryYMenu = uicontrol('Parent', L_diaryMenu, ... + obj.handles.diaryYMenu = uicontrol('Parent', L_diaryYMenu, ... 'Style', 'popupmenu', ... 'String', obj.allKeys, ... 'Units', 'normalized', ... + 'Position', [0.2, 0, 0.4, .8], ...%position control not working 'Callback', @(uiobj, evt)obj.updateDiaryPlot); - diaryXMenuText = uicontrol('Parent', L_diaryMenu, ... - 'Style', 'text', ... - 'String', 'Diary plot x-axis', ... - 'FontSize', 11); - obj.handles.diaryXMenu = uicontrol('Parent', L_diaryMenu, ... - 'Style', 'popupmenu', ... - 'String', {'epochNum','time'}, ... - 'Units', 'normalized', ... - 'Callback', @(uiobj, evt)obj.updateDiaryPlot); - set(L_diaryMenu, 'Sizes', [80, 220, 80, 200], 'Spacing', 20); + set(L_diaryYMenu, 'Sizes', [100, 250], 'Spacing', 20); set(L_diaryPlot, 'Sizes', [-1, 20], 'Padding', 5); L_dataPlot = uiextras.VBox('Parent', L_dataPanels); @@ -142,33 +133,8 @@ function buildUIComponents(obj) 'Style', 'pushbutton', ... 'String', 'Delete data set', ... 'Callback', @(uiobj, evt)obj.deleteDataSet); - uicontrol('Parent', L_controls, ... - 'Style', 'pushbutton', ... - 'String', 'Reset view', ... - 'Callback', @(uiobj, evt)obj.resetView); - set(L_dataPanels, 'Sizes', [-1, -1, 40], 'Padding', 5); - set(L_controls, 'Sizes', [100, 200, 100, 100, 100]); - - L_quickFilterBox = uiextras.HBox('Parent',L_filterPanels); - L_filterDisplayNames = uiextras.VBox('Parent',L_quickFilterBox); - obj.handles.filterDisplayNamesMenu = uicontrol('Parent',L_filterDisplayNames, ... - 'Style', 'popupmenu', ... - 'String', {'default'}, ... - 'Callback', @(uiobj, evt) obj.makeDisplayNameFilter); - - L_filterVoltages = uiextras.VBox('Parent',L_quickFilterBox); - obj.handles.filterVoltagesMenu = uicontrol('Parent',L_filterVoltages, ... - 'Style', 'popupmenu', ... - 'String', {'default'}, ... - 'Callback', @(uiobj, evt) obj.makeVoltagesFilter); - - L_filterParams = uiextras.VBox('Parent',L_quickFilterBox); - obj.handles.filterParamsMenu = uicontrol('Parent',L_filterParams, ... - 'Style', 'popupmenu', ... - 'String', {'default'}, ... - 'Callback', @(uiobj, evt) obj.makeParamsFilter); - + set(L_controls, 'Sizes', [100, 200, 100, 100]); L_filterBox = uiextras.VBox('Parent',L_filterPanels); filterText = uicontrol('Parent', L_filterBox, ... @@ -275,7 +241,7 @@ function buildUIComponents(obj) 'RowName', [], ... 'Data', cell(6,4), ... 'CellEditCallback', @(uiobj, evt)obj.curEpochTableEdit(evt), ... - 'TooltipString', 'table for current epoch parameters'); + 'TooltipString', 'table for current eoch parameters'); L_viewControls = uiextras.HButtonBox('Parent', L_currentEpochParamsBox, ... 'ButtonSize', [100 30], ... 'Spacing', 20); @@ -289,7 +255,7 @@ function buildUIComponents(obj) 'Callback', @(uiboj, evt)obj.loadViewFunc); set(L_currentEpochParamsBox, 'Sizes', [25, -1 50], 'Padding', 5); - set(L_filterPanels, 'Sizes', [20, -1, -1, -1], 'Padding', 5); + set(L_filterPanels, 'Sizes', [-1, -1, -1], 'Padding', 5); end @@ -300,9 +266,7 @@ function updateDataPlot(obj) end channels = get(obj.handles.channelMenu,'String'); selectedChannelStr = channels{get(obj.handles.channelMenu,'Value')}; - epochNum = obj.dataSet(obj.selectedEpochInd); - obj.cellData.epochs(epochNum).plotData(selectedChannelStr, obj.handles.dataPlotAxes); - title(obj.handles.dataPlotAxes, sprintf('Epoch number: %g', epochNum)); + obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)).plotData(selectedChannelStr, obj.handles.dataPlotAxes); end function updateParamsList(obj) @@ -327,27 +291,16 @@ function updateDiaryPlot(obj) if isempty(obj.dataSet) return; end -% epochTimes = obj.cellData.getEpochVals('epochStartTime', obj.dataSet); - epochNums = obj.cellData.getEpochVals('epochNum', obj.dataSet); epochTimes = obj.cellData.getEpochVals('epochStartTime', obj.dataSet); - a = get(obj.handles.diaryXMenu,'Value'); - s = get(obj.handles.diaryXMenu,'String'); - xmode = s(a); - if strcmp(xmode, 'epochNum') - xvals = epochNums; - else - xvals = epochTimes; - end displayParam = obj.allKeys{get(obj.handles.diaryYMenu,'Value')}; displayVals = obj.cellData.getEpochVals(displayParam, obj.dataSet); - if isnumeric(displayVals) hold(obj.handles.diaryPlotAxes, 'on'); inDataSetInd = ismember(obj.dataSet, obj.epochsInDataSets); - obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, xvals(~inDataSetInd), displayVals(~inDataSetInd), 'bo'); - obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, xvals(inDataSetInd), displayVals(inDataSetInd), 'go', 'MarkerFaceColor', 'g'); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochTimes(~inDataSetInd), displayVals(~inDataSetInd), 'bo'); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochTimes(inDataSetInd), displayVals(inDataSetInd), 'go', 'MarkerFaceColor', 'g'); - plot(obj.handles.diaryPlotAxes, xvals(obj.selectedEpochInd), displayVals(obj.selectedEpochInd), 'bo', ... + plot(obj.handles.diaryPlotAxes, epochTimes(obj.selectedEpochInd), displayVals(obj.selectedEpochInd), 'bo', ... 'MarkerFaceColor', 'r'); ylabel(obj.handles.diaryPlotAxes, displayParam); else @@ -357,14 +310,11 @@ function updateDiaryPlot(obj) valInd(strcmp(displayVals, uniqueVals{i})) = i; end hold(obj.handles.diaryPlotAxes, 'on'); - inDataSetInd = ismember(obj.dataSet, obj.epochsInDataSets); - - - - obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, xvals(~inDataSetInd), valInd(~inDataSetInd), 'bo'); - obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, xvals(inDataSetInd), valInd(inDataSetInd), 'go', 'MarkerFaceColor', 'g'); + inDataSetInd = ismember(obj.dataSet, obj.epochsInDataSets); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochTimes(~inDataSetInd), valInd(~inDataSetInd), 'bo'); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochTimes(inDataSetInd), valInd(inDataSetInd), 'go', 'MarkerFaceColor', 'g'); - plot(obj.handles.diaryPlotAxes, xvals(obj.selectedEpochInd), valInd(obj.selectedEpochInd), 'bo', ... + plot(obj.handles.diaryPlotAxes, epochTimes(obj.selectedEpochInd), valInd(obj.selectedEpochInd), 'bo', ... 'MarkerFaceColor', 'r'); set(obj.handles.diaryPlotAxes, 'Ytick', unique(valInd), ... 'YtickLabel', uniqueVals); @@ -372,12 +322,7 @@ function updateDiaryPlot(obj) set(obj.handles.diaryPlotAxes, 'Ylim', [0 max(valInd)+1]); %text labels here end - - if strcmp(xmode, 'epochNum') - xlabel('Epoch Number'); - else - xlabel('Epoch Time (sec)'); - end + xlabel('Time (s)'); hold(obj.handles.diaryPlotAxes, 'off'); @@ -439,7 +384,7 @@ function filterTableEdit(obj, eventData) %show unique values vals = obj.cellData.getEpochVals(newData); vals = vals(~isnan_cell(vals)); - vals = unique(vals); + vals = unique(vals); D{rowInd,3} = makeDelimitedString(vals); end @@ -552,17 +497,19 @@ function updateCurEpochTable(obj) D = get(obj.handles.curEpochTable,'Data'); z=1; for i=1:size(D,1) - for col = [1, 3] - if ~isempty(D{i,col}) - value = obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)).get(D{i,col}); - D{i,col+1} = num2str(value, '%d'); -% value; - obj.curViewParams{z} = D{i,col}; - obj.curViewLocations{z} = [i,col]; - z=z+1; - end + if ~isempty(D{i,1}) + D{i,2} = obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)).get(D{i,1}); + obj.curViewParams{z} = D{i,1}; + obj.curViewLocations{z} = [i,1]; + z=z+1; end - end + if ~isempty(D{i,3}) + D{i,4} = obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)).get(D{i,3}); + obj.curViewParams{z} = D{i,3}; + obj.curViewLocations{z} = [i,3]; + z=z+1; + end + end set(obj.handles.curEpochTable,'Data', D); end @@ -579,46 +526,17 @@ function updateFilterResultsTable(obj) set(obj.handles.filterResultsText, ... 'String', ['Parameters With Multiple Values: ' num2str(length(obj.dataSet)) ' Epochs']); [params, vals] = obj.cellData.getNonMatchingParamVals(obj.dataSet); - numParams = length(params); - D = cell(numParams,2); - quickParamListData = {}; - quickParamListStrings = {}; - quickParamIndex = 1; - for i=1:numParams + L = length(params); + D = cell(L,2); + for i=1:L D{i,1} = params{i}; if length(vals{i}) == 1 D{i,2} = vals{i}; else D{i,2} = makeDelimitedString(vals{i}); end - - if length(vals{i}) < 6 - v = vals{i}; - for vi = 1:length(v) - if iscell(v) - quickParamListData{quickParamIndex,2} = v{vi}; - else - quickParamListData{quickParamIndex,2} = v(vi); - end - quickParamListData{quickParamIndex,1} = params{i}; - if ischar(quickParamListData{quickParamIndex,2}) - quickParamListStrings{1,quickParamIndex} = sprintf('%s: %s', quickParamListData{quickParamIndex,1}, quickParamListData{quickParamIndex,2}); - else - quickParamListStrings{1,quickParamIndex} = sprintf('%s: %g', quickParamListData{quickParamIndex,1}, quickParamListData{quickParamIndex,2}); - end - quickParamIndex = quickParamIndex + 1; - end - end end set(obj.handles.filterResultsTable, 'Data', D); - - % update string for dropdown quick filter - if quickParamIndex == 1 - obj.handles.filterParamsMenu.String = {'No params'}; - else - obj.handles.filterParamsMenu.String = horzcat('Quick change params', quickParamListStrings); - end - obj.quickParamsFilterList = quickParamListData; end function initializeFilterTable(obj) @@ -636,29 +554,13 @@ function initializeFilterTable(obj) set(obj.handles.filterTable, 'Data', cell(12,3)); set(obj.handles.filterPatternEdit, 'String', ''); - - % initialize the list of display names dropdown for quick filter construction - displayNames = unique(obj.cellData.getEpochVals('displayName', obj.dataSet)); - obj.handles.filterDisplayNamesMenu.String = horzcat('Quick change display name', displayNames); - voltages = num2cell(unique(obj.cellData.getEpochVals('ampHoldSignal', obj.dataSet))); - obj.handles.filterVoltagesMenu.String = horzcat('Quick change voltages', voltages); - end function diaryPlotClick(obj) epochTimes = obj.cellData.getEpochVals('epochStartTime', obj.dataSet); - epochNums = obj.cellData.getEpochVals('epochNum', obj.dataSet); - a = get(obj.handles.diaryXMenu,'Value'); - s = get(obj.handles.diaryXMenu,'String'); - xmode = s(a); - if strcmp(xmode, 'epochNum') - xvals = epochNums; - else - xvals = epochTimes; - end p = get(obj.handles.diaryPlotAxes,'CurrentPoint'); xval = p(1,1); - [~, closestInd] = min(abs(xval - xvals)); + [~, closestInd] = min(abs(xval - epochTimes)); obj.selectedEpochInd = closestInd; obj.updateDiaryPlot(); obj.updateDataPlot(); @@ -687,12 +589,7 @@ function saveViewFunc(obj) end function saveDataSetFunc(obj) - displayName = obj.cellData.epochs(obj.dataSet(1)).attributes('displayName'); % fill in dataset name guess - displayName = strrep(displayName, ' ', ''); - saveName = inputdlg('Enter data set name','',1,{displayName}); - if isempty(saveName) - return - end + saveName = inputdlg('Enter data set name'); saveName = saveName{1}; %inputdlg returns cell instead of string obj.cellData.savedDataSets(saveName) = obj.dataSet; obj.epochsInDataSets = unique([obj.epochsInDataSets obj.dataSet]); %todo - look for double-counted epochs? @@ -707,88 +604,6 @@ function saveDataSetFunc(obj) obj.saveCellData(); end - function makeDisplayNameFilter(obj) - filterTableData = get(obj.handles.filterTable, 'Data'); - - displayNameList = get(obj.handles.filterDisplayNamesMenu,'String'); - ind = get(obj.handles.filterDisplayNamesMenu,'Value'); - obj.handles.filterDisplayNamesMenu.Value = 1; - if ind == 1 - return - end - - displayName = displayNameList{ind}; - filterTableData(1,:) = {'displayName', '==', displayName}; - set(obj.handles.filterTable, 'Data', filterTableData); - - obj.updateFilter(); - if strcmp(obj.handles.filterPatternEdit.String, '') - set(obj.handles.filterPatternEdit, 'String', '@1'); - end - obj.updateFilter(); - end - - - function makeVoltagesFilter(obj) - voltageList = get(obj.handles.filterVoltagesMenu,'String'); - ind = get(obj.handles.filterVoltagesMenu,'Value'); - obj.handles.filterVoltagesMenu.Value = 1; - if ind == 1 - if strcmp(obj.handles.filterPatternEdit.String, '@1 && @2') - set(obj.handles.filterPatternEdit, 'String', '@1'); - elseif strcmp(obj.handles.filterPatternEdit.String, '@1 && @2 && @3') - set(obj.handles.filterPatternEdit, 'String', '@1 && @3'); - end - obj.handles.filterTable.Data(2,:) = {'','',''}; - return - end - voltage = voltageList{ind}; - - filterTableData = get(obj.handles.filterTable, 'Data'); - filterTableData(2,:) = {'ampHoldSignal', '==', voltage}; - set(obj.handles.filterTable, 'Data', filterTableData); - - obj.updateFilter(); - if strcmp(obj.handles.filterPatternEdit.String, '@1') - set(obj.handles.filterPatternEdit, 'String', '@1 && @2'); - end - if strcmp(obj.handles.filterPatternEdit.String, '@1 && @3') - set(obj.handles.filterPatternEdit, 'String', '@1 && @2 && @3'); - end - obj.updateFilter(); - end - - function makeParamsFilter(obj) - ind = get(obj.handles.filterParamsMenu,'Value'); - obj.handles.filterParamsMenu.Value = 1; - if ind == 1 - if strcmp(obj.handles.filterPatternEdit.String, '@1 && @3') - set(obj.handles.filterPatternEdit, 'String', '@1'); - elseif strcmp(obj.handles.filterPatternEdit.String, '@1 && @2 && @3') - set(obj.handles.filterPatternEdit, 'String', '@1 && @2'); - end - obj.handles.filterTable.Data(3,:) = {'','',''}; - obj.updateFilter(); - return - end - param = obj.quickParamsFilterList(ind - 1, :); - - filterTableData = get(obj.handles.filterTable, 'Data'); - filterTableData(3,:) = {param{1}, '==', num2str(param{2})}; - set(obj.handles.filterTable, 'Data', filterTableData); - obj.updateFilter(); - - obj.updateFilter(); - if strcmp(obj.handles.filterPatternEdit.String, '@1') - set(obj.handles.filterPatternEdit, 'String', '@1 && @3'); - end - - if strcmp(obj.handles.filterPatternEdit.String, '@1 && @2') - set(obj.handles.filterPatternEdit, 'String', '@1 && @2 && @3'); - end - obj.updateFilter(); - end - function loadViewFunc(obj) [fname,fpath] = uigetfile('*.mat','Load view file...','~/analysis/views/'); load(fullfile(fpath, fname), 'viewParams', 'viewLocations'); @@ -802,17 +617,6 @@ function loadViewFunc(obj) obj.updateCurEpochTable(); end - function resetView(obj) - obj.handles.dataSetsMenu.Value = 1; - obj.dataSet = 1:obj.cellData.get('Nepochs'); - obj.initializeFilterTable(); - obj.initializeFilterResultsTable(); - obj.selectedEpochInd = 1; - obj.updateDataPlot(); - obj.updateDiaryPlot(); - obj.updateCurEpochTable(); - end - function loadDataSet(obj) dataSetNames = get(obj.handles.dataSetsMenu,'String'); ind = get(obj.handles.dataSetsMenu,'Value'); @@ -848,10 +652,7 @@ function renameDataSet(obj) %todo: make filter names stay in sync!!! if ind==1 warndlg('You must select a data set'); else - saveName = inputdlg('Enter new data set name', 'New name', 1, {dataSetNames{ind}}); - if isempty(saveName) - return - end + saveName = inputdlg('Enter new data set name'); saveName = saveName{1}; %inputdlg returns cell instead of string remove(obj.cellData.savedDataSets, dataSetNames{ind}); obj.cellData.savedDataSets(saveName) = obj.dataSet; diff --git a/GUIs/CellDataCurator_newer.m b/GUIs/CellDataCurator_newer.m new file mode 100755 index 0000000..1ab61ef --- /dev/null +++ b/GUIs/CellDataCurator_newer.m @@ -0,0 +1,1003 @@ +classdef CellDataCurator < handle + %GUI for curating epoch data from single cells + + properties + cellData + end + + properties (Hidden) + fig + handles + filter = SearchQuery(); + selectedEpochInd = 1; + curViewParams = {}; + curViewLocations = {}; + dataSet %vector of epoch indices + allKeys + epochsInDataSets = []; + quickParamsFilterList = {}; + end + + properties (Hidden, Constant) + operators = {' ','==','>','<','>=','<=','~='}; + end + + methods + function obj = CellDataCurator(cellData) + if nargin < 1 + return + end + + obj.cellData = cellData; + obj.dataSet = 1:cellData.get('Nepochs'); + + obj.buildUIComponents(); + obj.updateParamsList(); + obj.initializeFilterTable(); + obj.initializeEpochsInDataSetsList(); + obj.updateDataPlot(); + obj.updateDiaryPlot(); + obj.initializeFilterResultsTable(); + obj.initializeCurEpochTable(); + obj.updateDataSetMenu(); + if isempty(obj.cellData.savedFileName) + obj.chooseSaveLocation(); + end + + % self.isBusy = true; + % self.initAnalysisTools; + % self.initTreeBrowser; + % self.isBusy = false; + end + + function buildUIComponents(obj) + bounds = screenBounds; + obj.fig = figure( ... + 'Name', ['CellDataCurator: ' obj.cellData.savedFileName], ... + 'NumberTitle', 'off', ... + 'ToolBar', 'none',... + 'Menubar', 'none', ... + 'Position', [0 0.85*bounds(4), 0.8*bounds(3), 0.6*bounds(4)], ... + 'KeyPressFcn',@(uiobj,evt)obj.keyHandler(evt), ... + 'ResizeFcn', @(uiobj,evt)obj.resizeWindow); + + L_main = uiextras.VBox('Parent', obj.fig); + L_panels = uiextras.HBoxFlex('Parent', L_main, ... + 'Spacing', 10); + set(L_main, 'Sizes', -1); + + L_dataPanels = uiextras.VBoxFlex('Parent', L_panels); + L_filterPanels = uiextras.VBoxFlex('Parent', L_panels, ... + 'Spacing', 10); + set(L_panels, 'Sizes', [-1, -1], 'Padding', 5); + + L_diaryPlot = uiextras.VBox('Parent', L_dataPanels); + obj.handles.diaryPlotAxes = axes('Parent', L_diaryPlot); + L_diaryYMenu = uiextras.HBox('Parent', L_diaryPlot); + diaryYMenuText = uicontrol('Parent', L_diaryYMenu, ... + 'Style', 'text', ... + 'String', 'Diary plot y-axis', ... + 'FontSize', 11); + obj.handles.diaryYMenu = uicontrol('Parent', L_diaryYMenu, ... + 'Style', 'popupmenu', ... + 'String', obj.allKeys, ... + 'Units', 'normalized', ... + 'Position', [0.2, 0, 0.4, .8], ...%position control not working + 'Callback', @(uiobj, evt)obj.updateDiaryPlot); + set(L_diaryYMenu, 'Sizes', [100, 250], 'Spacing', 20); + set(L_diaryPlot, 'Sizes', [-1, 20], 'Padding', 5); + + L_dataPlot = uiextras.VBox('Parent', L_dataPanels); + + obj.handles.dataPlotAxes = axes('Parent', L_dataPlot); + L_dataPlotControls = uiextras.HBox('Parent', L_dataPlot); + set(L_dataPlot, 'Sizes', [-1, 35], 'Padding', 5); + + channelMenuText = uicontrol('Parent', L_dataPlotControls, ... + 'Style', 'text', ... + 'String', 'Data channel', ... + 'FontSize', 11); + obj.handles.channelMenu = uicontrol('Parent', L_dataPlotControls, ... + 'Style', 'popupmenu', ... + 'String', {'Amplifier_Ch1', 'Amplifier_Ch2'}, ... + 'Callback', @(uiobj, evt)obj.updateDataPlot); + + L_scrollButtons = uiextras.HButtonBox('Parent', L_dataPlotControls); + set(L_dataPlotControls, 'Sizes', [100, 150, 100], 'Spacing', 20); + + obj.handles.dataBackwardButton = uicontrol('Parent', L_scrollButtons, ... + 'Style', 'pushbutton', ... + 'String', '<', ... + 'Callback', @(uiobj, evt)obj.decrementEpochInd); + obj.handles.dataForwardButton = uicontrol('Parent', L_scrollButtons, ... + 'Style', 'pushbutton', ... + 'String', '>', ... + 'Callback', @(uiobj, evt)obj.incrementEpochInd); + + set(L_scrollButtons, ... + 'ButtonSize', [30 20]); + L_controls = uiextras.HBox('Parent', L_dataPanels, 'Spacing', 20); + + obj.handles.saveDataSetButton = uicontrol('Parent', L_controls, ... + 'Style', 'pushbutton', ... + 'String', 'Save data set', ... + 'Callback', @(uiobj, evt)obj.saveDataSetFunc); + obj.handles.dataSetsMenu = uicontrol('Parent', L_controls, ... + 'Style', 'popupmenu', ... + 'String', 'Data sets ...', ... + 'Callback', @(uiobj,evt)obj.loadDataSet); + obj.handles.renameDataSetButton = uicontrol('Parent', L_controls, ... + 'Style', 'pushbutton', ... + 'String', 'Rename data set', ... + 'Callback', @(uiobj, evt)obj.renameDataSet); + obj.handles.deleteDataSetButton = uicontrol('Parent', L_controls, ... + 'Style', 'pushbutton', ... + 'String', 'Delete data set', ... + 'Callback', @(uiobj, evt)obj.deleteDataSet); + uicontrol('Parent', L_controls, ... + 'Style', 'pushbutton', ... + 'String', 'Reset view', ... + 'Callback', @(uiobj, evt)obj.resetView); + + set(L_dataPanels, 'Sizes', [-1, -1, 40], 'Padding', 5); + set(L_controls, 'Sizes', [100, 200, 100, 100, 100]); + + L_quickFilterBox = uiextras.HBox('Parent',L_filterPanels); + L_filterDisplayNames = uiextras.VBox('Parent',L_quickFilterBox); + obj.handles.filterDisplayNamesMenu = uicontrol('Parent',L_filterDisplayNames, ... + 'Style', 'popupmenu', ... + 'String', {'default'}, ... + 'Callback', @(uiobj, evt) obj.makeDisplayNameFilter); + + L_filterVoltages = uiextras.VBox('Parent',L_quickFilterBox); + obj.handles.filterVoltagesMenu = uicontrol('Parent',L_filterVoltages, ... + 'Style', 'popupmenu', ... + 'String', {'default'}, ... + 'Callback', @(uiobj, evt) obj.makeVoltagesFilter); + + L_filterParams = uiextras.VBox('Parent',L_quickFilterBox); + obj.handles.filterParamsMenu = uicontrol('Parent',L_filterParams, ... + 'Style', 'popupmenu', ... + 'String', {'default'}, ... + 'Callback', @(uiobj, evt) obj.makeParamsFilter); + + + L_filterBox = uiextras.VBox('Parent',L_filterPanels); + filterText = uicontrol('Parent', L_filterBox, ... + 'Style', 'text', ... + 'String', 'Filter Construction', ... + 'FontSize', 12); + obj.handles.filterTable = uitable('Parent', L_filterBox, ... + 'Units', 'pixels', ... + 'FontSize', 11, ... + 'ColumnName', {'Param', 'Operator', 'Value'}, ... + 'ColumnEditable', logical([1 1 1]), ... + 'Data', cell(12,3), ... + 'CellEditCallback', @(uiobj, evt)obj.filterTableEdit(evt), ... + 'TooltipString', 'table for filter contruction'); + L_filterPattern = uiextras.HBox('Parent',L_filterBox); + filterPatternText = uicontrol('Parent', L_filterPattern, ... + 'Style', 'text', ... + 'String', 'Filter pattern string', ... + 'FontSize', 11); + obj.handles.filterPatternEdit = uicontrol('Parent', L_filterPattern, ... + 'Style', 'Edit', ... + 'FontSize', 11, ... + 'CallBack', @(uiobj, evt)obj.updateFilter); + set(L_filterPattern, 'Sizes', [100, -1], 'Spacing', 20); + L_filterControls = uiextras.HButtonBox('Parent', L_filterBox, ... + 'ButtonSize', [100 30], ... + 'Spacing', 20); + obj.handles.saveFilterButton = uicontrol('Parent', L_filterControls, ... + 'Style', 'pushbutton', ... + 'String', 'Save filter', ... + 'Callback', @(uiobj,evt)obj.saveFilter); + obj.handles.loadFilterButton = uicontrol('Parent', L_filterControls, ... + 'Style', 'pushbutton', ... + 'String', 'Load filter', ... + 'Callback', @(uiobj,evt)obj.loadFilter); + set(L_filterBox, 'Sizes', [25, -1, 25, 40]); + + L_filterResultsBox = uiextras.VBox('Parent',L_filterPanels); + obj.handles.filterResultsText = uicontrol('Parent', L_filterResultsBox, ... + 'Style', 'text', ... + 'String', 'Parameters With Multiple Values', ... + 'FontSize', 12); + obj.handles.filterResultsTable = uitable('Parent', L_filterResultsBox, ... + 'Units', 'pixels', ... + 'FontSize', 11, ... + 'ColumnEditable', logical([0 0]), ... + 'ColumnName', [], ... + 'RowName', [], ... + 'ColumnFormat', {'char', 'char'}, ... + 'Data', cell(12,2), ... + 'TooltipString', 'table for filter results'); + L_paramControl = uiextras.Grid('Parent', L_filterResultsBox, 'Spacing', 10); + paramControl_text = uicontrol('Parent', L_paramControl, ... + 'Style', 'text', ... + 'String', 'Add/delete parameters', ... + 'FontSize', 11); + uiextras.Empty('Parent', L_paramControl); + paramName_text = uicontrol('Parent', L_paramControl, ... + 'Style', 'text', ... + 'String', 'Name:', ... + 'FontSize', 11); + obj.handles.paramNameEdit = uicontrol('Parent', L_paramControl, ... + 'Style', 'edit', ... + 'String', '', ... + 'FontSize', 11); + paramVal_text = uicontrol('Parent', L_paramControl, ... + 'Style', 'text', ... + 'String', 'Value:', ... + 'FontSize', 11); + obj.handles.paramValEdit = uicontrol('Parent', L_paramControl, ... + 'Style', 'edit', ... + 'String', '', ... + 'FontSize', 11); + obj.handles.addParamToEpochButton = uicontrol('Parent', L_paramControl, ... + 'Style', 'pushbutton', ... + 'String', 'Add to current epoch', ... + 'Callback', @(uiobj,evt)obj.addParamToEpoch); + obj.handles.addParamToDataSetButton = uicontrol('Parent', L_paramControl, ... + 'Style', 'pushbutton', ... + 'String', 'Add to data set', ... + 'Callback', @(uiobj,evt)obj.addParamToDataSet); + obj.handles.deleteParamFromEpochButton = uicontrol('Parent', L_paramControl, ... + 'Style', 'pushbutton', ... + 'String', 'Delete from current epoch', ... + 'Callback', @(uiobj,evt)obj.deleteParamFromEpoch); + obj.handles.deleteParamFromDataSetButton = uicontrol('Parent', L_paramControl, ... + 'Style', 'pushbutton', ... + 'String', 'Delete from data set', ... + 'Callback', @(uiobj,evt)obj.deleteParamFromDataSet); + set(L_paramControl, 'ColumnSizes', [100 -1 -1 150 150], ... + 'RowSizes', [40 40], 'Padding', 0); + set(L_filterResultsBox, 'Sizes', [25, -1, 90], 'Padding', 5); + + L_currentEpochParamsBox = uiextras.VBox('Parent',L_filterPanels); + currentEpochParamsText = uicontrol('Parent', L_currentEpochParamsBox, ... + 'Style', 'text', ... + 'String', 'Current Epoch Parameters', ... + 'FontSize', 12); + obj.handles.curEpochTable = uitable('Parent', L_currentEpochParamsBox, ... + 'Units', 'pixels', ... + 'FontSize', 11, ... + 'ColumnEditable', logical([1, 0, 1, 0]), ... + 'ColumnName', {'Param', 'Value', 'Param', 'Value'}, ... + 'RowName', [], ... + 'Data', cell(6,4), ... + 'CellEditCallback', @(uiobj, evt)obj.curEpochTableEdit(evt), ... + 'TooltipString', 'table for current epoch parameters'); + L_viewControls = uiextras.HButtonBox('Parent', L_currentEpochParamsBox, ... + 'ButtonSize', [100 30], ... + 'Spacing', 20); + obj.handles.saveViewButton = uicontrol('Parent', L_viewControls, ... + 'Style', 'pushbutton', ... + 'String', 'Save view', ... + 'Callback', @(uiboj, evt)obj.saveViewFunc); + obj.handles.loadViewButton = uicontrol('Parent', L_viewControls, ... + 'Style', 'pushbutton', ... + 'String', 'Load view', ... + 'Callback', @(uiboj, evt)obj.loadViewFunc); + set(L_currentEpochParamsBox, 'Sizes', [25, -1 50], 'Padding', 5); + + set(L_filterPanels, 'Sizes', [20, -1, -1, -1], 'Padding', 5); + + end + + function updateDataPlot(obj) + cla(obj.handles.dataPlotAxes); + if isempty(obj.dataSet) + return; + end + channels = get(obj.handles.channelMenu,'String'); + selectedChannelStr = channels{get(obj.handles.channelMenu,'Value')}; + obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)).plotData(selectedChannelStr, obj.handles.dataPlotAxes); + end + + function updateParamsList(obj) + obj.allKeys = obj.cellData.getEpochKeysetUnion(obj.dataSet); + if isempty(obj.allKeys) + warning('No epochs match these settings'); + + else + set(obj.handles.diaryYMenu,'String',obj.allKeys); + %set to displayName as default + displayNameInd = find(strcmp(obj.allKeys, 'displayName')); + set(obj.handles.diaryYMenu, 'Value', displayNameInd); + %update popupmenu for filter table + props = [' ', obj.allKeys]; + columnFormat = {props, obj.operators, 'char'}; + set(obj.handles.filterTable,'ColumnFormat',columnFormat) + end + end + + function updateDiaryPlot(obj) + cla(obj.handles.diaryPlotAxes); + if isempty(obj.dataSet) + return; + end +% epochTimes = obj.cellData.getEpochVals('epochStartTime', obj.dataSet); + epochNums = obj.cellData.getEpochVals('epochNum', obj.dataSet); + displayParam = obj.allKeys{get(obj.handles.diaryYMenu,'Value')}; + displayVals = obj.cellData.getEpochVals(displayParam, obj.dataSet); + if isnumeric(displayVals) + hold(obj.handles.diaryPlotAxes, 'on'); + inDataSetInd = ismember(obj.dataSet, obj.epochsInDataSets); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochNums(~inDataSetInd), displayVals(~inDataSetInd), 'bo'); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochNums(inDataSetInd), displayVals(inDataSetInd), 'go', 'MarkerFaceColor', 'g'); + + plot(obj.handles.diaryPlotAxes, epochNums(obj.selectedEpochInd), displayVals(obj.selectedEpochInd), 'bo', ... + 'MarkerFaceColor', 'r'); + ylabel(obj.handles.diaryPlotAxes, displayParam); + else + uniqueVals = unique(displayVals); + valInd = zeros(1,length(displayVals)); + for i=1:length(uniqueVals) + valInd(strcmp(displayVals, uniqueVals{i})) = i; + end + hold(obj.handles.diaryPlotAxes, 'on'); + inDataSetInd = ismember(obj.dataSet, obj.epochsInDataSets); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochNums(~inDataSetInd), valInd(~inDataSetInd), 'bo'); + obj.handles.diaryPlotLine = plot(obj.handles.diaryPlotAxes, epochNums(inDataSetInd), valInd(inDataSetInd), 'go', 'MarkerFaceColor', 'g'); + + plot(obj.handles.diaryPlotAxes, epochNums(obj.selectedEpochInd), valInd(obj.selectedEpochInd), 'bo', ... + 'MarkerFaceColor', 'r'); + set(obj.handles.diaryPlotAxes, 'Ytick', unique(valInd), ... + 'YtickLabel', uniqueVals); + + set(obj.handles.diaryPlotAxes, 'Ylim', [0 max(valInd)+1]); + %text labels here + end + xlabel('Epoch Number'); + hold(obj.handles.diaryPlotAxes, 'off'); + + + set(obj.handles.diaryPlotLine, ... + 'ButtonDownFcn', @(uiobj,evt)obj.diaryPlotClick); + end + + function keyHandler(obj, evt) + switch evt.Key + case 'leftarrow' + obj.decrementEpochInd(); + case 'rightarrow' + obj.incrementEpochInd(); + case 'escape' + delete(obj.fig); + otherwise + disp(evt.Key); + end + end + + function initializeEpochsInDataSetsList(obj) + k = obj.cellData.savedDataSets.keys; + for i=1:length(k) + obj.epochsInDataSets = [obj.epochsInDataSets obj.cellData.savedDataSets(k{i})]; + end + end + + function curEpochTableEdit(obj, eventData) + newData = eventData.EditData; + rowInd = eventData.Indices(1); + colInd = eventData.Indices(2); + D = get(obj.handles.curEpochTable,'Data'); + + if strcmp(newData,' ') %blank the param + D{rowInd,colInd} = ''; + D{rowInd,colInd+1} = ''; + else + D{rowInd,colInd} = newData; + end + + set(obj.handles.curEpochTable,'Data',D); + obj.updateCurEpochTable(); + end + + function filterTableEdit(obj, eventData) + newData = eventData.EditData; + rowInd = eventData.Indices(1); + colInd = eventData.Indices(2); + D = get(obj.handles.filterTable,'Data'); + + if strcmp(newData,' ') %blank the row + D{rowInd,1} = ''; + D{rowInd,2} = ''; + D{rowInd,3} = ''; + else + D{rowInd,colInd} = newData; + end + if colInd == 1 %edited parameter name + %show unique values + vals = obj.cellData.getEpochVals(newData); + vals = vals(~isnan_cell(vals)); + vals = unique(vals); + D{rowInd,3} = makeDelimitedString(vals); + end + + set(obj.handles.filterTable,'Data',D); + + if colInd > 1 %why? + obj.updateFilter(); + end + end + + function updateFilter(obj) + D = get(obj.handles.filterTable,'Data'); + N = size(D,1); + if isempty(obj.filter) || isempty(obj.filter.fieldnames) + previousL = 0; + else + previousL = length(obj.filter.fieldnames); + end + rowsComplete = true; + for i=1:N + if ~isempty(D{i,1}) %change stuff and add stuff + obj.filter.fieldnames{i} = D{i,1}; + obj.filter.operators{i} = D{i,2}; + value_str = D{i,3}; + if isempty(value_str) + value = []; + elseif strfind(value_str, ',') + z = 1; + r = value_str; + while ~isempty(r) + [token, r] = strtok(r, ','); + value{z} = strtrim(token); + z=z+1; + end + else + value = str2num(value_str); %#ok + end + if ~isempty(value) + obj.filter.values{i} = value; + else + obj.filter.values{i} = value_str; + end + if i>previousL + pattern_str = get(obj.handles.filterPatternEdit,'String'); + if previousL == 0 %first condition + pattern_str = '@1'; + else + pattern_str = [pattern_str ' && @' num2str(i)]; + end + set(obj.handles.filterPatternEdit,'String',pattern_str); + end + if isempty(obj.filter.fieldnames{i}) ... + || isempty(obj.filter.operators{i}) ... + || isempty(obj.filter.values{i}) + rowsComplete = false; + end + elseif i == previousL %remove last condition + obj.filter.fieldnames = obj.filter.fieldnames(1:i-1); + obj.filter.operators = obj.filter.operators(1:i-1); + obj.filter.values = obj.filter.values(1:i-1); + + pattern_str = get(obj.handles.filterPatternEdit,'String'); + pattern_str = regexprep(pattern_str, ['@' num2str(i)], '?'); + set(obj.handles.filterPatternEdit,'String',pattern_str); + end + end + + obj.filter.pattern = get(obj.handles.filterPatternEdit,'String'); + if rowsComplete + obj.applyFilter(); + end + if isempty(obj.filter.fieldnames) + %reset to null filter + obj.filter = SearchQuery(); + obj.applyFilter(true); + end + end + + function applyFilter(obj) + if nargin < 2 + queryString = obj.filter.makeQueryString(); + else + queryString = 'true'; + end + obj.dataSet = obj.cellData.filterEpochs(queryString); + obj.updateParamsList(); + obj.selectedEpochInd = 1; + obj.updateDiaryPlot(); + obj.updateDataPlot(); + obj.updateFilterResultsTable(); + obj.updateCurEpochTable(); + end + + function initializeCurEpochTable(obj) + props = [' ', obj.allKeys]; + columnFormat = {props, 'char', props, 'char'}; + set(obj.handles.curEpochTable,'ColumnFormat',columnFormat); + + tablePos = get(obj.handles.curEpochTable,'Position'); + tableWidth = tablePos(3); + col1W = round(tableWidth*.25); + col2W = round(tableWidth*.25); + col3W = round(tableWidth*.25); + col4W = round(tableWidth*.25); + set(obj.handles.curEpochTable,'ColumnWidth',{col1W, col2W, col3W, col4W}); + obj.updateCurEpochTable(); + end + + function updateCurEpochTable(obj) + D = get(obj.handles.curEpochTable,'Data'); + z=1; + for i=1:size(D,1) + for col = [1, 3] + if ~isempty(D{i,col}) + value = obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)).get(D{i,col}); + D{i,col+1} = num2str(value, '%d'); +% value; + obj.curViewParams{z} = D{i,col}; + obj.curViewLocations{z} = [i,col]; + z=z+1; + end + end + end + set(obj.handles.curEpochTable,'Data', D); + end + + function initializeFilterResultsTable(obj) + tablePos = get(obj.handles.filterResultsTable,'Position'); + tableWidth = tablePos(3); + col1W = round(tableWidth*.25); + col2W = round(tableWidth*.75); + set(obj.handles.filterResultsTable,'ColumnWidth',{col1W, col2W}); + obj.updateFilterResultsTable(); + end + + function updateFilterResultsTable(obj) + set(obj.handles.filterResultsText, ... + 'String', ['Parameters With Multiple Values: ' num2str(length(obj.dataSet)) ' Epochs']); + [params, vals] = obj.cellData.getNonMatchingParamVals(obj.dataSet); + numParams = length(params); + D = cell(numParams,2); + quickParamListData = {}; + quickParamListStrings = {}; + quickParamIndex = 1; + for i=1:numParams + D{i,1} = params{i}; + if length(vals{i}) == 1 + D{i,2} = vals{i}; + else + D{i,2} = makeDelimitedString(vals{i}); + end + + if length(vals{i}) < 6 + v = vals{i}; + for vi = 1:length(v) + if iscell(v) + quickParamListData{quickParamIndex,2} = v{vi}; + else + quickParamListData{quickParamIndex,2} = v(vi); + end + quickParamListData{quickParamIndex,1} = params{i}; + if ischar(quickParamListData{quickParamIndex,2}) + quickParamListStrings{1,quickParamIndex} = sprintf('%s: %s', quickParamListData{quickParamIndex,1}, quickParamListData{quickParamIndex,2}); + else + quickParamListStrings{1,quickParamIndex} = sprintf('%s: %g', quickParamListData{quickParamIndex,1}, quickParamListData{quickParamIndex,2}); + end + quickParamIndex = quickParamIndex + 1; + end + end + end + set(obj.handles.filterResultsTable, 'Data', D); + + % update string for dropdown quick filter + if quickParamIndex == 1 + obj.handles.filterParamsMenu.String = {'No params'}; + else + obj.handles.filterParamsMenu.String = horzcat('Quick change params', quickParamListStrings); + end + obj.quickParamsFilterList = quickParamListData; + end + + function initializeFilterTable(obj) + props = [' ', obj.allKeys]; + columnFormat = {props, obj.operators, 'char'}; + set(obj.handles.filterTable,'ColumnFormat',columnFormat); + + %filtTable + tablePos = get(obj.handles.filterTable,'Position'); + tableWidth = tablePos(3); + col1W = round(tableWidth*.4); + col2W = round(tableWidth*.10); + col3W = round(tableWidth*.4); + set(obj.handles.filterTable,'ColumnWidth',{col1W, col2W, col3W}); + set(obj.handles.filterTable, 'Data', cell(12,3)); + + set(obj.handles.filterPatternEdit, 'String', ''); + + % initialize the list of display names dropdown for quick filter construction + displayNames = unique(obj.cellData.getEpochVals('displayName', obj.dataSet)); + obj.handles.filterDisplayNamesMenu.String = horzcat('Quick change display name', displayNames); + voltages = num2cell(unique(obj.cellData.getEpochVals('ampHoldSignal', obj.dataSet))); + obj.handles.filterVoltagesMenu.String = horzcat('Quick change voltages', voltages); + + end + + function diaryPlotClick(obj) +% epochTimes = obj.cellData.getEpochVals('epochStartTime', obj.dataSet); + epochNums = obj.cellData.getEpochVals('epochNum', obj.dataSet); + p = get(obj.handles.diaryPlotAxes,'CurrentPoint'); + xval = p(1,1); + [~, closestInd] = min(abs(xval - epochNums)); + obj.selectedEpochInd = closestInd; + obj.updateDiaryPlot(); + obj.updateDataPlot(); + obj.updateCurEpochTable(); + end + + function decrementEpochInd(obj) + obj.selectedEpochInd = max(1, obj.selectedEpochInd-1); + obj.updateDataPlot(); + obj.updateDiaryPlot(); + obj.updateCurEpochTable(); + end + + function incrementEpochInd(obj) + obj.selectedEpochInd = min(length(obj.dataSet), obj.selectedEpochInd+1); + obj.updateDataPlot(); + obj.updateDiaryPlot(); + obj.updateCurEpochTable(); + end + + function saveViewFunc(obj) + [fname,fpath] = uiputfile('*.mat','Save view file...','~/analysis/views/'); + viewParams = obj.curViewParams; + viewLocations = obj.curViewLocations; + save(fullfile(fpath, fname), 'viewParams', 'viewLocations'); + end + + function saveDataSetFunc(obj) + displayName = obj.cellData.epochs(obj.dataSet(1)).attributes('displayName'); % fill in dataset name guess + displayName = strrep(displayName, ' ', ''); + saveName = inputdlg('Enter data set name','',1,{displayName}); + if isempty(saveName) + return + end + saveName = saveName{1}; %inputdlg returns cell instead of string + obj.cellData.savedDataSets(saveName) = obj.dataSet; + obj.epochsInDataSets = unique([obj.epochsInDataSets obj.dataSet]); %todo - look for double-counted epochs? + obj.updateDataSetMenu(); + %save filter + filtStruct.filterData = get(obj.handles.filterTable,'Data'); + filtStruct.filterPatternString = get(obj.handles.filterPatternEdit, 'String'); + obj.cellData.savedFilters(saveName) = filtStruct; + %to reflect change in epochsIndDataSets status + obj.updateDiaryPlot(); + %save cellData + obj.saveCellData(); + end + + function makeDisplayNameFilter(obj) + filterTableData = get(obj.handles.filterTable, 'Data'); + + displayNameList = get(obj.handles.filterDisplayNamesMenu,'String'); + ind = get(obj.handles.filterDisplayNamesMenu,'Value'); + obj.handles.filterDisplayNamesMenu.Value = 1; + if ind == 1 + return + end + + displayName = displayNameList{ind}; + filterTableData(1,:) = {'displayName', '==', displayName}; + set(obj.handles.filterTable, 'Data', filterTableData); + + obj.updateFilter(); + if strcmp(obj.handles.filterPatternEdit.String, '') + set(obj.handles.filterPatternEdit, 'String', '@1'); + end + obj.updateFilter(); + end + + + function makeVoltagesFilter(obj) + voltageList = get(obj.handles.filterVoltagesMenu,'String'); + ind = get(obj.handles.filterVoltagesMenu,'Value'); + obj.handles.filterVoltagesMenu.Value = 1; + if ind == 1 + if strcmp(obj.handles.filterPatternEdit.String, '@1 && @2') + set(obj.handles.filterPatternEdit, 'String', '@1'); + elseif strcmp(obj.handles.filterPatternEdit.String, '@1 && @2 && @3') + set(obj.handles.filterPatternEdit, 'String', '@1 && @3'); + end + obj.handles.filterTable.Data(2,:) = {'','',''}; + return + end + voltage = voltageList{ind}; + + filterTableData = get(obj.handles.filterTable, 'Data'); + filterTableData(2,:) = {'ampHoldSignal', '==', voltage}; + set(obj.handles.filterTable, 'Data', filterTableData); + + obj.updateFilter(); + if strcmp(obj.handles.filterPatternEdit.String, '@1') + set(obj.handles.filterPatternEdit, 'String', '@1 && @2'); + end + if strcmp(obj.handles.filterPatternEdit.String, '@1 && @3') + set(obj.handles.filterPatternEdit, 'String', '@1 && @2 && @3'); + end + obj.updateFilter(); + end + + function makeParamsFilter(obj) + ind = get(obj.handles.filterParamsMenu,'Value'); + obj.handles.filterParamsMenu.Value = 1; + if ind == 1 + if strcmp(obj.handles.filterPatternEdit.String, '@1 && @3') + set(obj.handles.filterPatternEdit, 'String', '@1'); + elseif strcmp(obj.handles.filterPatternEdit.String, '@1 && @2 && @3') + set(obj.handles.filterPatternEdit, 'String', '@1 && @2'); + end + obj.handles.filterTable.Data(3,:) = {'','',''}; + obj.updateFilter(); + return + end + param = obj.quickParamsFilterList(ind - 1, :); + + filterTableData = get(obj.handles.filterTable, 'Data'); + filterTableData(3,:) = {param{1}, '==', num2str(param{2})}; + set(obj.handles.filterTable, 'Data', filterTableData); + obj.updateFilter(); + + obj.updateFilter(); + if strcmp(obj.handles.filterPatternEdit.String, '@1') + set(obj.handles.filterPatternEdit, 'String', '@1 && @3'); + end + + if strcmp(obj.handles.filterPatternEdit.String, '@1 && @2') + set(obj.handles.filterPatternEdit, 'String', '@1 && @2 && @3'); + end + obj.updateFilter(); + end + + function loadViewFunc(obj) + [fname,fpath] = uigetfile('*.mat','Load view file...','~/analysis/views/'); + load(fullfile(fpath, fname), 'viewParams', 'viewLocations'); + obj.curViewParams = viewParams; + obj.curViewLocations = viewLocations; + D = cell(6,4); + for i=1:length(obj.curViewParams) + D{obj.curViewLocations{i}(1), obj.curViewLocations{i}(2)} = obj.curViewParams{i}; + end + set(obj.handles.curEpochTable,'Data', D) + obj.updateCurEpochTable(); + end + + function resetView(obj) + obj.handles.dataSetsMenu.Value = 1; + obj.dataSet = 1:obj.cellData.get('Nepochs'); + obj.initializeFilterTable(); + obj.initializeFilterResultsTable(); + obj.selectedEpochInd = 1; + obj.updateDataPlot(); + obj.updateDiaryPlot(); + obj.updateCurEpochTable(); + end + + function loadDataSet(obj) + dataSetNames = get(obj.handles.dataSetsMenu,'String'); + ind = get(obj.handles.dataSetsMenu,'Value'); + if ind == 1 %reset + obj.dataSet = 1:obj.cellData.get('Nepochs'); + obj.initializeFilterTable(); + obj.initializeFilterResultsTable(); + + else + setName = dataSetNames{ind}; + obj.dataSet = obj.cellData.savedDataSets(setName); + %load filter + if ~isempty(obj.cellData.savedFilters) + if obj.cellData.savedFilters.isKey(setName) + filtStruct = obj.cellData.savedFilters(setName); + set(obj.handles.filterTable,'Data',filtStruct.filterData); + set(obj.handles.filterPatternEdit, 'String', filtStruct.filterPatternString); + obj.updateFilter(); + end + end + obj.updateFilterResultsTable(); + + end + obj.selectedEpochInd = 1; + obj.updateDataPlot(); + obj.updateDiaryPlot(); + obj.updateCurEpochTable(); + end + + function renameDataSet(obj) %todo: make filter names stay in sync!!! + dataSetNames = get(obj.handles.dataSetsMenu,'String'); + ind = get(obj.handles.dataSetsMenu,'Value'); + if ind==1 + warndlg('You must select a data set'); + else + saveName = inputdlg('Enter new data set name', 'New name', 1, {dataSetNames{ind}}); + if isempty(saveName) + return + end + saveName = saveName{1}; %inputdlg returns cell instead of string + remove(obj.cellData.savedDataSets, dataSetNames{ind}); + obj.cellData.savedDataSets(saveName) = obj.dataSet; + obj.updateDataSetMenu(); + dataSetNames = get(obj.handles.dataSetsMenu,'String'); + ind = strmatch(saveName, dataSetNames); + set(obj.handles.dataSetsMenu,'Value', ind); + end + obj.saveCellData(); + end + + function deleteDataSet(obj) + dataSetNames = get(obj.handles.dataSetsMenu,'String'); + ind = get(obj.handles.dataSetsMenu,'Value'); + if ind==1 + warndlg('You must select a data set'); + else + remove(obj.cellData.savedDataSets, dataSetNames{ind}); + obj.epochsInDataSets = setdiff(obj.epochsInDataSets, obj.dataSet); %todo - look for double-counted epochs? + set(obj.handles.dataSetsMenu,'Value', 1); + obj.updateDataSetMenu(); + end + obj.saveCellData(); + end + + function updateDataSetMenu(obj) + dataSetKeys = obj.cellData.savedDataSets.keys; + set(obj.handles.dataSetsMenu,'String', ['Data sets...' dataSetKeys]); + end + + function addParamToEpoch(obj) + paramName = get(obj.handles.paramNameEdit, 'String'); + paramVal = get(obj.handles.paramValEdit, 'String'); + curEpoch = obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)); + if isKey(curEpoch.attributes, paramName) + answer = questdlg('Overwrite current parameter value?', 'Overwrite warning:', 'No','Yes','Yes'); + if strcmp(answer, 'Yes') + if evalsToNumeric(paramVal) + curEpoch.attributes(paramName) = eval(paramVal); + else + curEpoch.attributes(paramName) = paramVal; + end + end + else + if evalsToNumeric(paramVal) + curEpoch.attributes(paramName) = eval(paramVal); + else + curEpoch.attributes(paramName) = paramVal; + end + end + obj.saveCellData(); + obj.updateParamsList(); + obj.updateCurEpochTable(); + obj.updateFilterResultsTable(); + end + + function addParamToDataSet(obj) + paramName = get(obj.handles.paramNameEdit, 'String'); + paramVal = get(obj.handles.paramValEdit, 'String'); + addParam = false; + if strmatch(paramName, obj.allKeys) + answer = questdlg('Overwrite current parameter value?', 'Overwrite warning:', 'No','Yes','Yes'); + if strcmp(answer, 'Yes') + addParam = true; + end + else + addParam = true; + end + if addParam + for i=1:length(obj.dataSet) + curEpoch = obj.cellData.epochs(obj.dataSet(i)); + if evalsToNumeric(paramVal) + curEpoch.attributes(paramName) = eval(paramVal); + else + curEpoch.attributes(paramName) = paramVal; + end + end + end + obj.saveCellData(); + obj.updateParamsList(); + obj.updateCurEpochTable(); + obj.updateFilterResultsTable(); + end + + function deleteParamFromEpoch(obj) + paramName = get(obj.handles.paramNameEdit, 'String'); + if isempty(strmatch(paramName, obj.allKeys)) + msgbox(['Parameter ' paramName ' not found'], 'Parameter not found', 'error'); + else + answer = questdlg(['Delete parameter ' paramName ' from this epoch?'], 'Are you sure?', 'No','Yes','Yes'); + if strcmp(answer, 'Yes') + curEpoch = obj.cellData.epochs(obj.dataSet(obj.selectedEpochInd)); + remove(curEpoch.attributes, paramName); + end + end + obj.saveCellData(); + obj.updateParamsList(); + obj.updateCurEpochTable(); + obj.updateFilterResultsTable(); + end + + function deleteParamFromDataSet(obj) + paramName = get(obj.handles.paramNameEdit, 'String'); + if isempty(strmatch(paramName, obj.allKeys)) + msgbox(['Parameter ' paramName ' not found'], 'Parameter not found', 'error'); + else + answer = questdlg(['Delete parameter ' paramName ' from all epochs in this data set?'], 'Are you sure?', 'No','Yes','Yes'); + if strcmp(answer, 'Yes') + for i=1:length(obj.dataSet) + curEpoch = obj.cellData.epochs(obj.dataSet(i)); + remove(curEpoch.attributes, paramName); + end + end + end + obj.updateParamsList(); + obj.updateCurEpochTable(); + obj.updateFilterResultsTable(); + end + + + function chooseSaveLocation(obj) + [fname, fpath] = uiputfile('*.mat', 'Choose save location for data file...', ['~/analysis/cellData/' obj.cellData.rawfilename]); + fname_full = fullfile(fpath, fname); + obj.cellData.savedFileName = fname_full; + set(obj.fig, 'Name',['CellDataCurator: ' obj.cellData.savedFileName]); + end + + function saveCellData(obj) + saveAndSyncCellData(obj.cellData); + end + + function saveFilter(obj) + [fname,fpath] = uiputfile('*.mat','Save view file...','~/analysis/filters/'); + filterData = get(obj.handles.filterTable,'Data'); + filterPatternString = get(obj.handles.filterPatternEdit, 'String'); + save(fullfile(fpath, fname), 'filterData', 'filterPatternString'); + end + + function loadFilter(obj) + [fname,fpath] = uigetfile('*.mat','Load view file...','~/analysis/filters/'); + if ~isempty(fname) %if selected something + load(fullfile(fpath, fname), 'filterData', 'filterPatternString'); + set(obj.handles.filterTable,'Data',filterData); + set(obj.handles.filterPatternEdit, 'String', filterPatternString); + obj.updateFilter(); + obj.applyFilter(); + end + end + + function resizeWindow(obj) + %filtTable + if isfield(obj.handles, 'filterTable') + tablePos = get(obj.handles.filterTable,'Position'); + tableWidth = tablePos(3); + col1W = round(tableWidth*.4); + col2W = round(tableWidth*.10); + col3W = round(tableWidth*.4); + set(obj.handles.filterTable,'ColumnWidth',{col1W, col2W, col3W}); + end + + %filter results table + if isfield(obj.handles, 'filterResultsTable') + tablePos = get(obj.handles.filterResultsTable,'Position'); + tableWidth = tablePos(3); + col1W = round(tableWidth*.25); + col2W = round(tableWidth*.75); + set(obj.handles.filterResultsTable,'ColumnWidth',{col1W, col2W}); + end + + %curEpochTable + if isfield(obj.handles, 'curEpochTable') + tablePos = get(obj.handles.curEpochTable,'Position'); + tableWidth = tablePos(3); + col1W = round(tableWidth*.25); + col2W = round(tableWidth*.25); + col3W = round(tableWidth*.25); + col4W = round(tableWidth*.25); + set(obj.handles.curEpochTable,'ColumnWidth',{col1W, col2W, col3W, col4W}); + end + end + + end + +end + diff --git a/GUIs/LabDataGUI.m b/GUIs/LabDataGUI.m index ab89a16..435e2b5 100755 --- a/GUIs/LabDataGUI.m +++ b/GUIs/LabDataGUI.m @@ -69,7 +69,7 @@ %copy newer versions of local cellData files to server if SYNC_TO_SERVER - syncLocalCellDataToServer(); + %syncLocalCellDataToServer(); end %read in CellTags.txt file @@ -93,7 +93,7 @@ obj.buildUIComponents(); obj.loadCellNames(); - try % this will error when displays are weird + try % this will error when obj.loadTree(); catch disp('loadTree stumbled on multi-display configuration. Resize the window to continue'); @@ -458,11 +458,6 @@ function buildUIComponents(obj) 'String', 'Load filter', ... 'FontSize', 12, ... 'Callback', @(uiobj,evt)obj.loadFilter); - obj.handles.loadFilterListButton = uicontrol('Parent', L_filterControls, ... - 'Style', 'pushbutton', ... - 'String', 'Load list & analyze', ... - 'FontSize', 10, ... - 'Callback', @(uiobj,evt)obj.loadFilterList); set(L_filterBox, 'Sizes', [-1, 25, -2, 25, 25, -2, 25, 40]); @@ -616,11 +611,8 @@ function cellSelectedFcn(obj) obj.updateCellPositionTable(); %set online label - if ~iscell(obj.curCellData.get('label')) - set(obj.handles.labelTextVal, 'String', sprintf('Label: %s', obj.curCellData.get('label'))); - else - set(obj.handles.labelTextVal, 'String', sprintf('S2 Online Type: %s',obj.curCellData.get('type'))); - end + set(obj.handles.labelTextVal, 'String', obj.curCellData.get('label')); + %set notes set(obj.handles.notesTextVal, 'String', obj.curCellData.notes); @@ -867,74 +859,6 @@ function loadFilter(obj) end end - function loadFilterList(obj) - disp(obj.labData.allCellTypes) - global ANALYSIS_FOLDER; - [fname,fpath] = uigetfile(ANALYSIS_FOLDER,'Load filter file'); - if ~isempty(fname) %if selected something - load(fullfile(fpath, fname)) - - for fi = 1:length(filterFileNames) - fname = filterFileNames{fi}; - fprintf('Loading filter %g of %g, %s\n', fi, length(filterFileNames), fname); - - % load filter - load(fname, 'filterData', 'filterPatternString','analysisType', 'cellType'); - - epochFilt = SearchQuery(); -% epochFilter.fieldnames = {}; -% epochFilter.operators = {}; - for i=1:size(filterData,1) - if ~isempty(filterData{i,1}) - epochFilt.fieldnames{i} = filterData{i,1}; - epochFilt.operators{i} = filterData{i,2}; - - value_str = filterData{i,3}; - if isempty(value_str) - value = []; - elseif strfind(value_str, ',') - z = 1; - r = value_str; - while ~isempty(r) - [token, r] = strtok(r, ','); - value{z} = strtrim(token); - z=z+1; - end - else - value = str2num(value_str); %#ok - end - - epochFilt.values{i} = value; - end - end - epochFilt.pattern = filterPatternString; - - if strcmp(cellType, 'All') - cellType = obj.labData.allCellTypes; - end - - cellFilt = []; - -% analysisType -% epochFilt - tempTree = obj.labData.collectAnalysis(analysisType, cellType, cellFilt, epochFilt); - - % save tree - - analysisTree = tempTree; - - sfile = fullfile('analysisTrees/automaticData/treeData/', num2str(fi)); - save(sfile, 'analysisTree'); - disp(['Saved analysis tree to ' sfile]); - - end - disp('Done with all files'); - - end - end - - - function loadCellNames(obj) cellDataFolder = obj.cellData_folder; diff --git a/GUIs/SpikeDetectorGUI.m b/GUIs/SpikeDetectorGUI.m index a44955d..7b8e91a 100755 --- a/GUIs/SpikeDetectorGUI.m +++ b/GUIs/SpikeDetectorGUI.m @@ -268,10 +268,6 @@ function updateUI(obj) plot(obj.handles.ax, 1:length(obj.data), obj.data, 'k'); hold(obj.handles.ax, 'on'); plot(obj.handles.ax, obj.spikeTimes, obj.data(obj.spikeTimes), 'rx', 'MarkerSize', 15, 'linewidth', 4); - if strcmp(obj.mode, 'Simple threshold') - xax = xlim(); - line(xax, [1,1]*obj.threshold, 'LineStyle', '--'); - end hold(obj.handles.ax, 'off'); displayName = obj.cellData.epochs(obj.epochInd(obj.curEpochInd)).get('displayName'); set(obj.fig, 'Name',['Spike Detector: Epoch ' num2str(obj.epochInd(obj.curEpochInd)) ' (' displayName '): ' num2str(length(obj.spikeTimes)) ' spikes']); diff --git a/GUIs/TreeBrowserGUI.m b/GUIs/TreeBrowserGUI.m index cdf7c45..2809e70 100755 --- a/GUIs/TreeBrowserGUI.m +++ b/GUIs/TreeBrowserGUI.m @@ -364,7 +364,7 @@ function setEpochTags(obj, tagName, tagVal) curNode = obj.analysisTree.get(curNodeIndex); figName = get(obj.handles.fig, 'Name'); %4 cases: at data set level, at cell level, below data set level, above cell level - if isfield(curNode, 'cellName') %at data set cell level + if isfield(curNode, 'cellName') %at data set cell level curCellName = curNode.cellName; epochIDs = []; treePart = obj.analysisTree.subtree(curNodeIndex); @@ -404,7 +404,7 @@ function setEpochTags(obj, tagName, tagVal) %get siglings of parent (actual cell level instead of %dataset level siblings = obj.analysisTree.getsiblings(obj.analysisTree.getparent(childInd)); - for c = 1:length(siblings) + for c = 1:length(siblings); dataSetNodeInd = obj.analysisTree.getchildren(siblings(c)); for d=1:length(dataSetNodeInd) curNodeIndex = dataSetNodeInd(d); @@ -588,7 +588,7 @@ function makePlotSelectionTable(obj) end function resetPlotControls(obj) - if isfield(obj.handles, 'L_plotXY_box') + if isfield(obj.handles, 'L_plotXY_box'); delete(obj.handles.L_plotXY_box); set(obj.handles.L_plotControls, 'Sizes', [-1, 40, 40, 40]); end @@ -597,7 +597,7 @@ function resetPlotControls(obj) function addXYselectionToPlotControls(obj, xList, yList) plotControls_children = get(obj.handles.L_plotControls, 'children'); for i=1:length(plotControls_children) - if ~strcmp(get(plotControls_children(i), 'Tag'), 'plotSelectionMenu') + if ~strcmp(get(plotControls_children(i), 'Tag'), 'plotSelectionMenu'); delete(plotControls_children(i)); end end @@ -650,12 +650,12 @@ function updatePlot(obj) selectedNodes = get(obj.guiTree, 'selectedNodes'); curNodeIndex = get(selectedNodes(1), 'Value'); plotClass = obj.plotSelectionTable{curNodeIndex, 1}; - if isempty(plotClass) + if isempty(plotClass), return; end plotFuncIndex = obj.plotSelectionTable{curNodeIndex, 3} - 1; %-1 to account for 'none' option - if plotFuncIndex == 0 + if plotFuncIndex == 0, reset(obj.handles.plotAxes); cla(obj.handles.plotAxes); obj.resetPlotControls(); @@ -666,16 +666,8 @@ function updatePlot(obj) curNode = obj.analysisTree.subtree(curNodeIndex); cellName = obj.analysisTree.getCellName(curNodeIndex); %load([obj.cellDataFolder cellName]); - %obj.curCellData = cellData; - -% cellData = loadAndSyncCellData(cellName); - if ~isempty(obj.curCellData) && isprop(obj.curCellData, 'savedFileName') && strcmp(obj.curCellData.savedFileName, cellName) %cellData already loaded - %do nothing - else %load it - obj.curCellData = loadAndSyncCellData(cellName); - end - cellData = obj.curCellData; % load it locally for later plot functions - + cellData = loadAndSyncCellData(cellName); + obj.curCellData = cellData; %do the plot set(obj.handles.fig,'KeyPressFcn',[]); %get rid of callback for non SingleEpoch plots @@ -787,14 +779,13 @@ function updatePlot(obj) obj.printCodeForPlotterFunction_singleVal(xName,yName); else obj.resetPlotControls(); - plotterString = [plotClass '.' plotFunc '(curNode, cellData);']; - eval(plotterString); + eval([plotClass '.' plotFunc '(curNode, cellData);']); end end end - function printCodeForPlotterFunction_singleVal(~, xName, yName) + function printCodeForPlotterFunction_singleVal(obj, xName, yName) disp('%%%%%%%%%%%%%% plotter code %%%%%%%%%%%%%%'); disp(['function plot_' xName 'Vs' yName '(node, cellData)']); disp('rootData = node.get(1);'); @@ -808,7 +799,7 @@ function printCodeForPlotterFunction_singleVal(~, xName, yName) disp('%%%%%%%%%%%%%% plotter code %%%%%%%%%%%%%%'); end - function printCodeForPlotterFunction_byEpoch(~, xName, yName) + function printCodeForPlotterFunction_byEpoch(obj, xName, yName) disp('%%%%%%%%%%%%%% plotter code %%%%%%%%%%%%%%'); disp(['function plot_' xName 'Vs' yName '(node, cellData)']); disp('rootData = node.get(1);'); @@ -847,36 +838,18 @@ function onNodeSelected(obj) end end - curNodeData = obj.analysisTree.get(curNodeIndex); - allFields = fieldnames(curNodeData); - curCellName = obj.analysisTree.getCellName(curNodeIndex); - - % handle multichannel here, I believe: - [~, namePart] = strtok(curNodeData.name, ':'); - if ~isempty(namePart) - namePart = strtok(namePart, ':'); - namePart = strtrim(namePart(2:end)); - end - if (length(namePart) == 9 || length(namePart) == 10) && isfield(curNodeData, 'device') %cell node - curCellName = namePart; - end - - % load celldata into this object if needed - if ~isempty(curCellName) - if ~isempty(obj.curCellData) && isprop(obj.curCellData, 'savedFileName') && strcmp(obj.curCellData.savedFileName, curCellName) %cellData already loaded - else %load it - obj.curCellData = loadAndSyncCellData(curCellName); - end - end - - obj.populateEpochTagsTable(curNodeIndex, curNodeData); - obj.populateCellTagsTable(curCellName); - obj.populateNodePropertiesTable(curNodeData, allFields); + obj.populateEpochTagsTable(); + obj.populateCellTagsTable(); + obj.populateNodePropertiesTable(); obj.updatePlot(); end - function populateNodePropertiesTable(obj, curNodeData, allFields) - + function populateNodePropertiesTable(obj) + selectedNodes = get(obj.guiTree, 'selectedNodes'); + curNodeIndex = get(selectedNodes(1), 'Value'); + curNodeData = obj.analysisTree.get(curNodeIndex); + allFields = fieldnames(curNodeData); + L = length(allFields); D = cell(L,2); z=1; @@ -901,8 +874,16 @@ function populateNodePropertiesTable(obj, curNodeData, allFields) set(obj.handles.nodePropertiesTable, 'data', D) end - function populateEpochTagsTable(obj, curNodeIndex, curNodeData) - + function populateEpochTagsTable(obj) + selectedNodes = get(obj.guiTree, 'selectedNodes'); + curNodeIndex = get(selectedNodes(1), 'Value'); + curNodeData = obj.analysisTree.get(curNodeIndex); + curCellName = obj.analysisTree.getCellName(curNodeIndex); + if isfield(obj.curCellData, 'savedFileName') && strcmp(obj.curCellData.savedFileName, curCellName) %cellData already loaded + %do nothing + else %load it + obj.curCellData = loadAndSyncCellData(curCellName); + end D = cell(5,2); if isfield(curNodeData, 'class') %only display for level of data sets %get all epochsIDs under this node @@ -941,10 +922,23 @@ function populateEpochTagsTable(obj, curNodeIndex, curNodeData) set(obj.handles.epochTagsTable, 'data', D) end - function populateCellTagsTable(obj, curCellName) - + function populateCellTagsTable(obj) + selectedNodes = get(obj.guiTree, 'selectedNodes'); + curNodeIndex = get(selectedNodes(1), 'Value'); + curNode = obj.analysisTree.get(curNodeIndex); + curCellName = obj.analysisTree.getCellName(curNodeIndex); + [~, namePart] = strtok(curNode.name, ':'); + if ~isempty(namePart) + namePart = strtok(namePart, ':'); + namePart = strtrim(namePart(2:end)); + end + if (length(namePart) == 9 || length(namePart) == 10) && isfield(curNode, 'device') %cell node + curCellName = namePart; + end + D = cell(1,2); if ~isempty(curCellName) + obj.curCellData = loadAndSyncCellData(curCellName); tagNames = obj.curCellData.tags.keys; L = length(tagNames); D = cell(L,2); diff --git a/analysisSupportFunctions/addDSIandOSI.m b/analysisSupportFunctions/addDSIandOSI.m index 098d47a..ac9b0c6 100755 --- a/analysisSupportFunctions/addDSIandOSI.m +++ b/analysisSupportFunctions/addDSIandOSI.m @@ -1,44 +1,43 @@ function rootData = addDSIandOSI(rootData, angleParam) %DSI, DSang, OSI, OSang; -angles = deg2rad(rootData.(angleParam)); +Nangles = length(rootData.(angleParam)); +angles = rootData.(angleParam); fnames = fieldnames(rootData); for i=1:length(fnames) curField = fnames{i}; if isfield(rootData.(curField), 'type') - responseMagnitudes = getRespVectors(rootData, {curField}); + respVals = getRespVectors(rootData, {curField}); - if isempty(responseMagnitudes) - continue + if ~isempty(respVals) + R=0; + RDirn=0; + ROrtn=0; + for j=1:Nangles + R=R+respVals(j); + RDirn = RDirn + (respVals(j)*exp(sqrt(-1)*angles(j)*pi/180)); + ROrtn = ROrtn + (respVals(j)*exp(2*sqrt(-1)*angles(j)*pi/180)); + end + + DSI = abs(RDirn/R); + OSI = abs(ROrtn/R); + DSang = angle(RDirn/R)*180/pi; + OSang = angle(ROrtn/R)*90/pi; + + if DSang < 0 + DSang = 360 + DSang; + end + + if OSang < 0 + OSang = 360 + OSang; + end + + OSang = mod(OSang,180); %OSangles should be between [0,180] + + rootData.([curField '_DSI']) = DSI; + rootData.([curField '_DSang']) = DSang; + rootData.([curField '_OSI']) = OSI; + rootData.([curField '_OSang']) = OSang; end - - responseSum = sum(responseMagnitudes); - responseVectorSumDir = sum(responseMagnitudes .* exp(sqrt(-1) * angles)); - responseVectorSumOrth = sum(responseMagnitudes .* exp(sqrt(-1) * angles * 2)); - - DSI = abs(responseVectorSumDir / responseSum); - OSI = abs(responseVectorSumOrth / responseSum); - DSang = rad2deg(angle(responseVectorSumDir / responseSum)); - OSang = rad2deg(angle(responseVectorSumOrth / responseSum)) / 2; - - % directional variance - DVar = var(responseMagnitudes ./ mean(responseMagnitudes)); - - if DSang < 0 - DSang = 360 + DSang; - end - - if OSang < 0 - OSang = 360 + OSang; - end - - OSang = mod(OSang,180); %OSangles should be between [0,180] - - rootData.([curField '_DSI']) = DSI; - rootData.([curField '_DSang']) = DSang; - rootData.([curField '_OSI']) = OSI; - rootData.([curField '_OSang']) = OSang; - - rootData.([curField '_DVar']) = DVar; end end \ No newline at end of file diff --git a/analysisSupportFunctions/getEpochResponses_CA.m b/analysisSupportFunctions/getEpochResponses_CA.m index 23ce066..94365d6 100755 --- a/analysisSupportFunctions/getEpochResponses_CA.m +++ b/analysisSupportFunctions/getEpochResponses_CA.m @@ -375,11 +375,18 @@ outputStruct.ONSET_FRhalfMaxLatency.type = 'singleValue'; outputStruct.ONSET_FRhalfMaxLatency.value = NaN; -% %%%%Adam 9/22/15 -% outputStruct.ONSET_FRhalfMaxSusLatency.units = 's'; -% outputStruct.ONSET_FRhalfMaxSusLatency.type = 'singleValue'; -% outputStruct.ONSET_FRhalfMaxSusLatency.value = NaN; -% %%%% + %%%%Adam 9/22/15 + outputStruct.ONSET_FRhalfMaxSusLatency.units = 's'; + outputStruct.ONSET_FRhalfMaxSusLatency.type = 'singleValue'; + outputStruct.ONSET_FRhalfMaxSusLatency.value = NaN; + %%%% + + %%%%Adam 4/23/16 for use if too few epochs + outputStruct.ONSET_FRhalfMaxSusLatency20.units = 's'; + outputStruct.ONSET_FRhalfMaxSusLatency20.type = 'singleValue'; + outputStruct.ONSET_FRhalfMaxSusLatency20.value = NaN; + %%%% + outputStruct.ONSET_FRrampLatency.units = 's'; outputStruct.ONSET_FRrampLatency.type = 'singleValue'; @@ -460,7 +467,7 @@ outputStruct.ONSETsuspauseDiff.type = 'singleValue'; outputStruct.ONSETsuspauseDiff.value = 0; - %Amurta 12/10/15 + %Amurta 12/10/15 - peak ISI 1st epoch outputStruct.ONSET_ISI_peak.units = 'ms'; outputStruct.ONSET_ISI_peak.type = 'singleValue'; outputStruct.ONSET_ISI_peak.value = []; @@ -470,6 +477,15 @@ outputStruct.ONSET_ISI_peakLatency.type = 'singleValue'; outputStruct.ONSET_ISI_peakLatency.value = []; + outputStruct.spikeCount_afterStim.units = 'spikes'; + outputStruct.spikeCount_afterStim.type = 'byEpoch'; + outputStruct.spikeCount_afterStim.value = ones(1,L).*0; + + %Adam 2/21/17 - peak ISI all epochs + outputStruct.ONSET_ISI_peakByEpoch.units = 'ms'; + outputStruct.ONSET_ISI_peakByEpoch.type = 'byEpoch'; + outputStruct.ONSET_ISI_peakByEpoch.value = []; + end curEpoch = cellData.epochs(epochInd(i)); @@ -533,6 +549,12 @@ %count spikes 100 ms offset till epoch end tailSpikeCount = length(find(spikeTimes >= intervalEnd + 0.1 & spikeTimes < intervalEnd+tailTime)); + %count spikes after stim offset + spikeCount = length(find(spikeTimes > intervalEnd & spikeTimes <= intervalEnd+tailTime)); + outputStruct.spikeCount_afterStim.value(i) = spikeCount; + + + %subtract baseline spikeCount_baselineSubtracted = spikeCount - meanBaselineRate.*responseIntervalLen; %division?? should be *. luckily it's usually 1. outputStruct.spikeCount_stimInterval_baselineSubtracted.value(i) = spikeCount_baselineSubtracted; @@ -578,7 +600,13 @@ spikeTimes_ONSET = spikeTimes(spikeTimes >= 0 & spikeTimes <= 1); outputStruct.ONSET_ISI_peakLatency.value = (spikeTimes_ONSET(ONSET_ISI_peak_index) - intervalStart) * 1E3; end - %Amurta + %Amurta; + %Adam (same as Amurta, only all Epochs intead only first + + ISI_100msTo500ms = diff(spikeTimes((spikeTimes >= intervalStart + 0.1) & (spikeTimes <= intervalStart + 0.5))); + outputStruct.ONSET_ISI_peakByEpoch.value(i) = max(ISI_100msTo500ms)* 1E3; %ms + %Adam + end %offset latency, spike count, duration, fullISI, and mean rate @@ -657,11 +685,12 @@ OFFSETresponseStartTime_min = min(OFFSETresponseStartTime_all); OFFSETresponseEndTime_max = max(OFFSETresponseEndTime_all); [psth, xvals] = cellData.getPSTH(epochInd, ip.Results.BinWidth, ip.Results.DeviceName); +[psth20, xvals20] = cellData.getPSTH(epochInd, 20, ip.Results.DeviceName); %%%%%%%%%Adam 8/27/15 temp hack centerOfMassLatency respOffs = 0.15; stimXvals = xvals((xvals >= respOffs)&(xvals <= 1 + respOffs)); -stimPsth = psth((xvals >= respOffs)&(xvals <= 1 + respOffs)); +stimPsth = psth((xvals >= respOffs)&(xvals <= 1 + respOffs)); cellData.getPSTH(epochInd, ip.Results.BinWidth, ip.Results.DeviceName); comTime = sum(stimXvals.*stimPsth)/sum(stimPsth); outputStruct.centerOfMassLatency.value = comTime; %%%%%%%%%% @@ -757,6 +786,9 @@ psth_onset = psth(xvals >= ONSETresponseStartTime_min & xvals < ONSETresponseEndTime_max); xvals_stimToEnd = xvals(xvals >= 0); psth_stimToEnd = psth(xvals >= 0); + + xvals20_stimToEnd = xvals20(xvals20 >= 0); + psth20_stimToEnd = psth20(xvals20 >= 0); %Amurta transEndTime = 0.2; %s %duration of transient response pauseStart = 0.1; %s @@ -780,7 +812,10 @@ FRthres = outputStruct.ONSET_FRmax.value / 2; %half max if FRthres>0 outputStruct.ONSET_FRhalfMaxLatency.value = min(xvals_stimToEnd(getThresCross(psth_stimToEnd, FRthres, 1))); -% outputStruct.ONSET_FRhalfMaxSusLatency.value = min(xvals_stimToEnd(getSustainedThresCross(psth_onset))); % Adam 9/22/15 %2/14/16 changed "PSTH_onset" to "psth_stimToEnd" + + outputStruct.ONSET_FRhalfMaxSusLatency.value = min(xvals_stimToEnd(getSustainedThresCross(psth_stimToEnd))); + outputStruct.ONSET_FRhalfMaxSusLatency20.value = min(xvals20_stimToEnd(getSustainedThresCross(psth20_stimToEnd))); % Adam 4/23/15 for too few epochs + outputStruct.ONSET_FRrange.value = outputStruct.ONSET_FRmax.value - min(psth_onset(maxLoc:end)); %range from max to end outputStruct.ONSET_FRrangeFrac.value = outputStruct.ONSET_FRrange.value / outputStruct.ONSET_FRmax.value; end diff --git a/analysisSupportFunctions/getEpochResponses_WC.m b/analysisSupportFunctions/getEpochResponses_WC.m index e8fec95..c1af270 100755 --- a/analysisSupportFunctions/getEpochResponses_WC.m +++ b/analysisSupportFunctions/getEpochResponses_WC.m @@ -45,6 +45,13 @@ responseIntervalLen = intervalEnd - intervalStart; %s baselineIntervalLen = baselineEnd - baselineStart; %s postIntervalLen = xvals(end) - intervalEnd; %s +stimToEndIntervalLen = xvals(end) - intervalStart; %s +shortInt200 = xvals >= intervalStart+0.2 & xvals < intervalStart + 0.22; +shortInt800 = xvals >= intervalStart+0.8 & xvals < intervalStart + 0.82; +shortInt900 = xvals >= intervalStart+0.9 & xvals < intervalStart + 0.92; +shortInt150 = xvals >= intervalStart+0.15 & xvals < intervalStart + 0.17; +shortInt400 = xvals >= intervalStart+0.4 & xvals < intervalStart + 0.42; +shortInt500 = xvals >= intervalStart+0.5 & xvals < intervalStart + 0.52; Mstim = zeros(L, sum(responseInterval)); %full data matrix, baseline subtracted on each epoch Mtrans = zeros(L, sum(transientInterval)); %transient data matrix, baseline subtracted on each epoch @@ -67,7 +74,7 @@ stimData = data(responseInterval); transData = data(transientInterval); susData = data(sustainedInterval); - postData = data(postInterval); + postData = data(postInterval); if responseIntervalLen >= 0.2 stimData200 = data(xvals > 0 & xvals <= 0.2); @@ -102,6 +109,38 @@ else stimData_next1000 = []; end + if responseIntervalLen >= 0.22 + shortData200 = data(shortInt200); + else + shortData200 = []; + end + if responseIntervalLen >= 0.82 + shortData800 = data(shortInt800); + else + shortData800 = []; + end + if responseIntervalLen >= 0.92 + shortData900 = data(shortInt900); + else + shortData900 = []; + end + if responseIntervalLen >= 0.17 + shortData150 = data(shortInt150); + else + shortData150 = []; + end + if responseIntervalLen >= 0.42 + shortData400 = data(shortInt400); + else + shortData400 = []; + end + if responseIntervalLen >= 0.52 + shortData500 = data(shortInt500); + else + shortData500 = []; + end + + Mstim(i,:) = stimData; Mtrans(i,:) = transData; @@ -156,6 +195,50 @@ outputStruct.stimInterval_charge.type = 'byEpoch'; outputStruct.stimInterval_charge.value = ones(1,L) * NaN; + %Adam 11/25/16 + outputStruct.stimInterval_inCharge.units = 'pC'; + outputStruct.stimInterval_inCharge.type = 'byEpoch'; + outputStruct.stimInterval_inCharge.value = ones(1,L) * NaN; + %Adam 11/25/16 + outputStruct.stimInterval_outCharge.units = 'pC'; + outputStruct.stimInterval_outCharge.type = 'byEpoch'; + outputStruct.stimInterval_outCharge.value = ones(1,L) * NaN; + + %Adam 6/30/16 + outputStruct.stimToEnd_charge.units = 'pC'; + outputStruct.stimToEnd_charge.type = 'byEpoch'; + outputStruct.stimToEnd_charge.value = ones(1,L) * NaN; + + %Adam 8/9/16 + outputStruct.stimAfter200_charge.units = 'pC'; + outputStruct.stimAfter200_charge.type = 'byEpoch'; + outputStruct.stimAfter200_charge.value = ones(1,L) * NaN; + + outputStruct.shortInt200_peak.units = 'pA'; + outputStruct.shortInt200_peak.type = 'byEpoch'; + outputStruct.shortInt200_peak.value = ones(1,L) * NaN; + + outputStruct.shortInt800_peak.units = 'pA'; + outputStruct.shortInt800_peak.type = 'byEpoch'; + outputStruct.shortInt800_peak.value = ones(1,L) * NaN; + + outputStruct.shortInt900_peak.units = 'pA'; + outputStruct.shortInt900_peak.type = 'byEpoch'; + outputStruct.shortInt900_peak.value = ones(1,L) * NaN; + + outputStruct.shortInt400_peak.units = 'pA'; + outputStruct.shortInt400_peak.type = 'byEpoch'; + outputStruct.shortInt400_peak.value = ones(1,L) * NaN; + + outputStruct.shortInt500_peak.units = 'pA'; + outputStruct.shortInt500_peak.type = 'byEpoch'; + outputStruct.shortInt500_peak.value = ones(1,L) * NaN; + + outputStruct.shortInt150_peak.units = 'pA'; + outputStruct.shortInt150_peak.type = 'byEpoch'; + outputStruct.shortInt150_peak.value = ones(1,L) * NaN; + + outputStruct.ONSET_peak.units = units; outputStruct.ONSET_peak.type = 'byEpoch'; outputStruct.ONSET_peak.value = ones(1,L) * NaN; @@ -264,16 +347,26 @@ outputStruct.stimToEnd_latencyToPeak.value(i) = pos / sampleRate; end - %ONSET - if abs(max(stimData)) > abs(min(stimData)) %outward current larger - [outputStruct.ONSET_peak.value(i), pos] = max(stimData); - outputStruct.ONSET_latencyToPeak.value(i) = pos / sampleRate; - else %inward current larger - [outputStruct.ONSET_peak.value(i), pos] = min(stimData); - outputStruct.ONSET_latencyToPeak.value(i) = pos / sampleRate; - end +% %ONSET +% if abs(max(stimData)) > abs(min(stimData)) %outward current larger +% [outputStruct.ONSET_peak.value(i), pos] = max(stimData); +% outputStruct.ONSET_latencyToPeak.value(i) = pos / sampleRate; +% else %inward current larger +% [outputStruct.ONSET_peak.value(i), pos] = min(stimData); +% outputStruct.ONSET_latencyToPeak.value(i) = pos / sampleRate; +% end + + + %TEMP HACK ADAM 10/19/16 assume excitation!!! take min even if occasional larger peak outward drugs + [outputStruct.ONSET_peak.value(i), pos] = min(stimData); + outputStruct.ONSET_latencyToPeak.value(i) = pos / sampleRate; + + outputStruct.stimInterval_charge.value(i) = sum(stimData) * responseIntervalLen / sampleRate; %pC - + outputStruct.stimInterval_inCharge.value(i) = sum( (-0.5*sign(stimData)+0.5).*stimData) * responseIntervalLen / sampleRate; %pC AM 11/25/16 + outputStruct.stimInterval_outCharge.value(i) = sum( (0.5*sign(stimData)+0.5).*stimData) * responseIntervalLen / sampleRate; %pC AM 11/25/16 + outputStruct.stimToEnd_charge.value(i) = sum(stimToEndData) * stimToEndIntervalLen / sampleRate; %pC AM 6/30/16 + outputStruct.stimAfter200_charge.value(i) = sum(stimData200to1000) * (responseIntervalLen-0.2) / sampleRate; %p %ONSET if ~isempty(transData) if abs(max(transData)) > abs(min(transData)) %outward current larger @@ -332,6 +425,27 @@ outputStruct.ONSET_charge400ms.value(i) = sum(stimData400) * 0.4 / sampleRate; end + %ONSET + if ~isempty(shortData200) + outputStruct.shortInt200_peak.value(i) = mean(shortData200); %max(shortData200); + end + if ~isempty(shortData800) + outputStruct.shortInt800_peak.value(i) = mean(shortData800); %max(shortData200); + end + if ~isempty(shortData900) + outputStruct.shortInt900_peak.value(i) = mean(shortData900); %max(shortData200); + end + if ~isempty(shortData400) + outputStruct.shortInt400_peak.value(i) = mean(shortData400); %max(shortData200); + end + if ~isempty(shortData500) + outputStruct.shortInt500_peak.value(i) = mean(shortData500); %max(shortData200); + end + if ~isempty(shortData150) + outputStruct.shortInt150_peak.value(i) = mean(shortData150); %max(shortData200); + end + + %OFFSET if abs(max(postData)) > abs(min(postData)) %outward current larger diff --git a/analysisSupportFunctions/getEpochResponses_gratings_CA.m b/analysisSupportFunctions/getEpochResponses_gratings_CA.m index b3fb5cb..58d5ab8 100755 --- a/analysisSupportFunctions/getEpochResponses_gratings_CA.m +++ b/analysisSupportFunctions/getEpochResponses_gratings_CA.m @@ -90,10 +90,6 @@ outputStruct.cycleAvgPSTH_y.type = 'combinedAcrossEpochs'; outputStruct.cycleAvgPSTH_y.value = []; - outputStruct.F0amplitude.units = 'Hz'; - outputStruct.F0amplitude.type = 'singleValue'; - outputStruct.F0amplitude.value = NaN; - outputStruct.F1amplitude.units = 'Hz/s^2'; %? outputStruct.F1amplitude.type = 'singleValue'; outputStruct.F1amplitude.value = NaN; @@ -105,13 +101,11 @@ outputStruct.F2overF1.units = ''; outputStruct.F2overF1.type = 'singleValue'; outputStruct.F2overF1.value = NaN; - + %Adam 2/13/17 outputStruct.cycleAvgPeakFR.units = 'Hz'; outputStruct.cycleAvgPeakFR.type = 'singleValue'; - outputStruct.cycleAvgPeakFR.value = []; - - + outputStruct.cycleAvgPeakFR.value = []; end @@ -152,10 +146,11 @@ % plot(abs(ft)) % Pull out the F1 and F2 amplitudes. -outputStruct.F0amplitude.value = abs(ft(1))/length(ft); outputStruct.F1amplitude.value = abs(ft(2))/length(ft)*2; outputStruct.F2amplitude.value = abs(ft(3))/length(ft)*2; outputStruct.F2overF1.value = abs(ft(3))/abs(ft(2)); %Adam 2/13/17 outputStruct.cycleAvgPeakFR.value = max(avgCycle); + + diff --git a/analysisSupportFunctions/getEpochResponses_gratings_WC.m b/analysisSupportFunctions/getEpochResponses_gratings_WC.m index 3d3281e..d49c4ab 100755 --- a/analysisSupportFunctions/getEpochResponses_gratings_WC.m +++ b/analysisSupportFunctions/getEpochResponses_gratings_WC.m @@ -87,11 +87,7 @@ outputStruct.cycleAvg_y.units = units; outputStruct.cycleAvg_y.type = 'combinedAcrossEpochs'; - outputStruct.cycleAvg_y.value = []; - - outputStruct.minCycleAvg.units = units; - outputStruct.minCycleAvg.type = 'combinedAcrossEpochs'; - outputStruct.minCycleAvg.value = []; + outputStruct.cycleAvg_y.value = []; outputStruct.F0amplitude.units = 'pA'; outputStruct.F0amplitude.type = 'singleValue'; @@ -135,7 +131,6 @@ avgCycle = mean(cycles(2:end,:),1); outputStruct.cycleAvg_y.value = avgCycle; outputStruct.cycleAvg_x.value = xvals(1:length(avgCycle)); -outputStruct.minCycleAvg.value = min(outputStruct.cycleAvg_y.value); % Do the FFT. ft = fft(avgCycle); diff --git a/analysisSupportFunctions/noiseFilter.m b/analysisSupportFunctions/noiseFilter.m deleted file mode 100644 index 7a033e0..0000000 --- a/analysisSupportFunctions/noiseFilter.m +++ /dev/null @@ -1,414 +0,0 @@ -% Model generator for RG cells. - -% function returnStruct = noiseFilter(cellData, epochIndices, model) - -%% load data -load cellData/102816Ac3.mat -epochIndices = 311:319; - -% load cellData/102516Ac2.mat -% epochIndices = [167]; - -% load cellData/110216Ac19.mat -% epochIndices = 218:251; - -% spiking WFDS -% load cellData/121616Ac2.mat -% epochIndices = 133:135; - -% spiking On Off DS -% load cellData/121616Ac4.mat -% epochIndices = 30; - -% WC on wfds -% load cellData/121616Ac7.mat -% epochIndices = 63; - -%% organize epochs - -centerEpochs = []; -numberOfEpochs = length(epochIndices); -for ei=1:numberOfEpochs - - epoch = cellData.epochs(epochIndices(ei)); - centerNoiseSeed = epoch.get('centerNoiseSeed'); - stimulusAreaMode = epoch.get('currentStimulus'); - - if strcmp(stimulusAreaMode, 'Center') - centerEpochs(end+1) = epochIndices(ei); - end -end -epochIndices = centerEpochs; - -% organize epochs by seed: repeats and nonrepeats -% probably this'd be a quarter this length in Python, god help me MathWorks -numberOfEpochs = length(epochIndices); -seedByEpoch = []; -for ei=1:numberOfEpochs - - epoch = cellData.epochs(epochIndices(ei)); - centerNoiseSeed = epoch.get('centerNoiseSeed'); - stimulusAreaMode = epoch.get('currentStimulus'); - - seedByEpoch(ei) = centerNoiseSeed; -end - -uniqueSeeds = unique(seedByEpoch); -uniqueSeedCounts = []; -for ui = 1:length(uniqueSeeds) - uniqueSeedCounts(ui) = sum(seedByEpoch == uniqueSeeds(ui)); -end - -repeatSeeds = uniqueSeeds(uniqueSeedCounts > 1); -if ~isempty(repeatSeeds) - repeatSeed = repeatSeeds(1); -else - repeatSeed = []; -end -singleSeeds = uniqueSeeds(uniqueSeedCounts == 1); -repeatRunEpochIndices = epochIndices(seedByEpoch == repeatSeed); - -singleRunEpochIndices = []; -for ei = 1:numberOfEpochs - if any(singleSeeds == seedByEpoch(ei)) - singleRunEpochIndices(end+1) = epochIndices(ei); - end -end - - -frameRate = cellData.epochs(epochIndices(1)).get('patternRate'); -stimFilter = designfilt('lowpassfir','PassbandFrequency',6, ... - 'StopbandFrequency',8,'PassbandRipple',0.5, 'SampleRate', frameRate, ... - 'StopbandAttenuation',65,'DesignMethod','kaiserwin'); - - -%% generate responses and stims, then glue them all together -responseFull = []; -stimulusFull = []; -repeatMarkerFull = []; - -averageRepeatSeedEpochs = true; - -for ei=1:numberOfEpochs - - epoch = cellData.epochs(epochIndices(ei)); - centerNoiseSeed = epoch.get('centerNoiseSeed'); - stimulusAreaMode = epoch.get('currentStimulus'); - isRepeatSeed = any(centerNoiseSeed == repeatSeeds); - - if ~strcmp(stimulusAreaMode, 'Center') - return - end - - fprintf('Starting on epoch %g w/ center seed %g\n', ei, centerNoiseSeed); - - % Generate stimulus - - centerNoiseStream = RandStream('mt19937ar', 'Seed', centerNoiseSeed); - stimulus = []; - - % chunkLen = epoch.get('frameDwell') / displayFrameRate; - preFrames = round(frameRate * (epoch.get('preTime')/1e3)); - stimFrames = round(frameRate * (epoch.get('stimTime')/1e3)); - stimulus(1:preFrames, 1) = zeros(preFrames, 1); - for fi = preFrames+1:floor(stimFrames/epoch.get('frameDwell')) - stimulus(fi, 1) = centerNoiseStream.randn; - end - ml = epoch.get('meanLevel'); - contrast = 1; %epoch.get('currentContrast') - stimulus = ml + contrast * ml * stimulus; - - stimulus(stimulus < 0) = 0; - stimulus(stimulus > ml * 2) = ml * 2; - stimulus(stimulus > 1) = 1; -% stimulus = smooth(stimulus, 3); - -% stimulusFiltered = filtfilt(stimFilter, stimulus); - - % generate response - sampleRate = epoch.get('sampleRate'); - - if strcmp(epoch.get('ampMode'), 'Cell attached') - spikeTimes = epoch.get('spikes_ch1') / sampleRate; - response = NIM.Spks2Robs(spikeTimes, 1/frameRate, size(stimulus,1) ); - useOutputNonlinearity = true; - else - useOutputNonlinearity = false; - - responseRaw = epoch.getData('Amplifier_Ch1'); - response = responseRaw * sign(mean(responseRaw)); - response = response / max(response); -% response = response + 0.08*(max(response) - min(response)); - response = response - min(response); - % response = response + 2; - % response = zscore(response); - response = resample(response, frameRate, sampleRate); - - response(response < 0) = 0; - - m = min([length(stimulus), length(response)]); - response = response(1:m); - stimulus = stimulus(1:m); -% while length(stimulus) < length(response) -% stimulus = [stimulus; ml]; -% end - end - - % compose data together - - assert(all(size(stimulus) == size(response))) - repeatMarker = isRepeatSeed * ones(size(stimulus)); - - if averageRepeatSeedEpochs - - stimulusFull = [stimulus, stimulusFull]; - responseFull = [response, responseFull]; - repeatMarkerFull = [repeatMarker, repeatMarkerFull]; - else - - stimulusFull = [stimulus; stimulusFull]; - responseFull = [response; responseFull]; - repeatMarkerFull = [repeatMarker; repeatMarkerFull]; - end - -end - -if averageRepeatSeedEpochs - stimulusFull = mean(stimulusFull, 2); - responseFull = mean(responseFull, 2); - repeatMarkerFull = mean(repeatMarkerFull, 2); -end - - -figure(6);clf; -handles = tight_subplot(3,1); -plot(handles(1), stimulusFull) -plot(handles(2), responseFull) -plot(handles(3), repeatMarkerFull) - - -%% Generate model parameters - -stimulus = stimulusFull; -stimulusFiltered = filtfilt(stimFilter, stimulus); -response = responseFull; -modelFitIndices = repeatMarkerFull; - -% Set parameters of fits -up_samp_fac = 1; % temporal up-sampling factor applied to stimulus -tent_basis_spacing = 1; % represent stimulus filters using tent-bases with this spacing (in up-sampled time units) -timeCutoff = 0.5; -updateRate = frameRate/epoch.get('frameDwell'); -nLags = round(timeCutoff * updateRate); - -% Create structure with parameters using static NIM function -params_stim = NIM.create_stim_params([nLags 1 1], 'stim_dt', 1/frameRate); - -% Create T x nLags 'design matrix' representing the relevant stimulus history at each time point -Xstim = NIM.create_time_embedding(stimulus, params_stim); - -%% Generate Model - -% use a saved filter to get things looking right at the start (avoid inversions) -% nim = NIM(params_stim, NL_types, subunit_signs, 'd2t', lambda_d2t, 'init_filts', {savedFilter}); - -% doc on the regularization types: -% nld2 second derivative of tent basis coefs -% d2xt spatiotemporal laplacian -% d2x 2nd spatial deriv -% d2t 2nd temporal deriv -% l2 L2 on filter coefs -% l1 L1 on filter coefs - -% doc on output nonlinearities -% {'lin','rectpow','exp','softplus','logistic'} - -nim = NIM(params_stim, [], [], 'spkNL', 'softplus'); -nim = nim.add_subunits('lin', 1); -nim = nim.set_reg_params('d2t', 10); - -% add negative subunit starting with a delayed copy of the first -nim = nim.fit_filters( response, Xstim, 'silent', 1); -useDelayedCopy = true; -if useDelayedCopy - nim = nim.fit_filters(response, Xstim, 'silent', 1 ); - delayed_filt = nim.shift_mat_zpad( nim.subunits(1).filtK, 4 ); - nim = nim.add_subunits( {'lin'}, -1, 'init_filts', {delayed_filt}); -else - nim = nim.add_subunits( {'lin'}, -1); -end - -% add subunit as an OFF filter -% nim = nim.fit_filters( response, Xstim, 'silent', 1); -% flipped_filt = -1 * nim.subunits(1).filtK; -% nim = nim.add_subunits( {'rectlin'}, 1, 'init_filts', {flipped_filt} ); -% nim = nim.fit_filters(response, Xstim, 'silent', 1); - -% add subunit as an -OFF filter -% flipped_filt = -1 * nim.subunits(3).filtK; -% delayed_filt = nim.shift_mat_zpad( nim.subunits(1).filtK, 4 ); -% nim = nim.add_subunits( {'rectlin'}, -1, 'init_filts', {flipped_filt} ); -% nim = nim.fit_filters(response, Xstim, 'silent', 1); - -% fit upstream nonlinearities - -nonpar_reg = 20; % set regularization value -enforceMonotonicSubunitNonlinearity = false; -nim = nim.init_nonpar_NLs( Xstim, 'lambda_nld2', nonpar_reg, 'NLmon', enforceMonotonicSubunitNonlinearity); - -% use this later: -% nim = nim.init_spkhist( 20, 'doubling_time', 5 ); - -numFittingLoops = 3; - -for fi = 1:numFittingLoops - nim = nim.fit_filters( response, Xstim, 'silent', 1); - nim = nim.fit_upstreamNLs( response, Xstim, 'silent', 1); - nim = nim.fit_spkNL(response, Xstim, 'silent', 1); - [ll, responsePrediction_s, mod_internals] = nim.eval_model(response, Xstim); - r2 = 1-mean((response-responsePrediction_s).^2)/var(response); -end -fprintf('Log likelihood: %g R2: %g\n', -1*ll, r2); - - -generatingFunction = mod_internals.G; -subunitOutputLN = mod_internals.fgint; -subunitOutputL = mod_internals.gint; - -% Display model components -colorsBySubunit = [1,0,.5; 0,.5,1; 0,1,.9; 1,.3,0]; - -figure(200);clf; -handles = tight_subplot(2,2, .05); -numSubunits = length(nim.subunits); - -% subunit filters -axes(handles(1)); -filterTime = 1:nLags; -filterTime = (filterTime-1) / updateRate; -h = []; -for si = 1:numSubunits - f = nim.subunits(si).filtK; - h(si) = plot(filterTime, f, 'Color', colorsBySubunit(si,:)); - hold on -end -line([0,max(filterTime)],[0,0],'Color','k', 'LineStyle',':'); -legString = cellfun(@num2str, num2cell(1:10), 'UniformOutput', 0); -legend(h, legString) -title('subunit linear filters') - -% Subunit nonlinearity -axes(handles(2)); -for si=1:numSubunits - yyaxis left - histogram(subunitOutputL(:,si), 'DisplayStyle','stairs','EdgeColor', colorsBySubunit(si,:), 'Normalization', 'Probability') - hold on - gendist_x = xlim(); - - subunit = nim.subunits(si); - if strcmp(subunit.NLtype, 'nonpar') - x = subunit.NLnonpar.TBx; y = subunit.NLnonpar.TBy; - else - x = gendist_x; y = subunit.apply_NL(x); - end - yyaxis right - plot(x, y, '-', 'Color', colorsBySubunit(si,:), 'LineWidth',1) - hold on - -end -yyaxis right -line(xlim(),[0,0],'Color','k', 'LineStyle',':') -line([0,0], ylim(),'Color','k', 'LineStyle',':') -title('subunit generator & output nonlinearity') - -% Subunit outputs -axes(handles(3)) -for si = 1:numSubunits - histogram(nim.subunits(si).weight * subunitOutputLN(:,si), 'DisplayStyle','stairs', 'EdgeColor', colorsBySubunit(si,:), 'Normalization','Probability'); - hold on -end -legend(legString) -title('subunit output (after weights)') -hold on - -% Overall output nonlinearity -axes(handles(4)) -yyaxis left -title('overall output'); -generatorOffset = nim.spkNL.theta; -histogram(generatingFunction + generatorOffset, 'DisplayStyle','stairs','EdgeColor','k', 'Normalization','Probability'); -hold on -yticklabels([]) - -yyaxis right -x = linspace(min(generatingFunction + generatorOffset), max(generatingFunction + generatorOffset)); -y = nim.apply_spkNL(x); -plot(x,y, 'r') -xticklabels('auto') - -legend('generator + offset', 'output NL') - - -% notes for LN: -% generate nonlinearity using repeated epochs -% get mean filter from the single run epochs - - - -% Display time signals - -figure(201);clf; -warning('off', 'MATLAB:legend:IgnoringExtraEntries') -handles = tight_subplot(3,1,0, [.05,.01], .05); - -% stimulus -axes(handles(1)); -t = linspace(0, length(stimulus) / frameRate, length(stimulus)); -plot(t, stimulusFiltered, 'Color','k') -grid on -legend('stim lowpass') - -axes(handles(2)) -for si = 1:numSubunits - plot(t, nim.subunits(si).weight * subunitOutputLN(:,si)/3, 'Color', colorsBySubunit(si,:)) - hold on -end -legend('sub 1 out weighted (ON+)','sub 2 out weighted (ON-)','sub 3 out weighted (OFF)') -grid on - -% response -axes(handles(3)); -plot(t, response, 'g') -hold on -% plot(t, generatingFunction, 'b:') -plot(t, responsePrediction_s, 'r') -grid on -legend('response','prediction') - -linkaxes(handles, 'x') -xlim([5,7]) - -pan xon - -%% step response -stepStartTime = 0.5; -stepEndTime = 1.5; - -t = (0:1/updateRate:3)'; -artStim = zeros(size(t)); -artStim(t >= stepStartTime & t <= stepEndTime) = 0.5; -artXstim = NIM.create_time_embedding(artStim, params_stim); - -figure(205);clf; -plot(t, artStim); - -hold on -[~, artResponsePrediction_s] = nim.eval_model([], artXstim); -plot(t, artResponsePrediction_s) - -legend('stimulus','response') - - - - - diff --git a/analysisSupportFunctions/noiseFilter_spatial.m b/analysisSupportFunctions/noiseFilter_spatial.m deleted file mode 100644 index 0c71e29..0000000 --- a/analysisSupportFunctions/noiseFilter_spatial.m +++ /dev/null @@ -1,464 +0,0 @@ -% Model generator for RG cells. - -% function returnStruct = noiseFilter(cellData, epochIndices, model) - -%% load data -load cellData/102816Ac3.mat -epochIndices = 311:319; - -% load cellData/102516Ac2.mat -% epochIndices = [167]; - -% load cellData/110216Ac19.mat -% epochIndices = 218:251; - -% spiking WFDS -% load cellData/121616Ac2.mat -% epochIndices = 133:135; - -% spiking On Off DS -% load cellData/121616Ac4.mat -% epochIndices = 30; - -% WC on wfds -% load cellData/121616Ac7.mat -% epochIndices = 63; - -%% organize epochs - -% locationByEpoch = []; -% numberOfEpochs = length(epochIndices); -% for ei=1:numberOfEpochs -% -% epoch = cellData.epochs(epochIndices(ei)); -% centerNoiseSeed = epoch.get('centerNoiseSeed'); -% stimulusAreaMode = epoch.get('currentStimulus'); -% -% if strcmp(stimulusAreaMode, 'Center') -% centerEpochs(end+1) = epochIndices(ei); -% end -% end -% epochIndices = centerEpochs; - -% organize epochs by seed: repeats and nonrepeats -% probably this'd be a quarter this length in Python, god help me MathWorks -numberOfEpochs = length(epochIndices); -seedByEpoch = []; -for ei=1:numberOfEpochs - - epoch = cellData.epochs(epochIndices(ei)); - centerNoiseSeed = epoch.get('centerNoiseSeed'); - surroundNoiseSeed = epoch.get('surroundNoiseSeed'); - stimulusAreaMode = epoch.get('currentStimulus'); - - seedByEpoch(ei,:) = [centerNoiseSeed, surroundNoiseSeed]; -end - -% uniqueSeeds = unique(seedByEpoch); -% uniqueSeedCounts = []; -% for ui = 1:length(uniqueSeeds) -% uniqueSeedCounts(ui) = sum(seedByEpoch == uniqueSeeds(ui)); -% end -% -% repeatSeeds = uniqueSeeds(uniqueSeedCounts > 1); -% if ~isempty(repeatSeeds) -% repeatSeed = repeatSeeds(1); -% else -% repeatSeed = []; -% end -% singleSeeds = uniqueSeeds(uniqueSeedCounts == 1); -% repeatRunEpochIndices = epochIndices(seedByEpoch == repeatSeed); -% -% singleRunEpochIndices = []; -% for ei = 1:numberOfEpochs -% if any(singleSeeds == seedByEpoch(ei)) -% singleRunEpochIndices(end+1) = epochIndices(ei); -% end -% end - - -frameRate = cellData.epochs(epochIndices(1)).get('patternRate'); -stimFilter = designfilt('lowpassfir','PassbandFrequency',6, ... - 'StopbandFrequency',8,'PassbandRipple',0.5, 'SampleRate', frameRate, ... - 'StopbandAttenuation',65,'DesignMethod','kaiserwin'); - -sampleRate = cellData.epochs(epochIndices(1)).get('sampleRate'); -% responseFilter = designfilt('highpassiir','PassbandFrequency',3, ... -% 'StopbandFrequency',2,'PassbandRipple',0.5, 'SampleRate', sampleRate, ... -% 'StopbandAttenuation',50,'DesignMethod','butter'); - -%% generate responses and stims, then glue them all together -responseFull = []; -stimulusFull = []; -repeatMarkerFull = []; - -averageRepeatSeedEpochs = false; - -for ei=1:numberOfEpochs - - epoch = cellData.epochs(epochIndices(ei)); - stimulusAreaMode = epoch.get('currentStimulus'); -% isRepeatSeed = any(centerNoiseSeed == repeatSeeds); - -% if ~strcmp(stimulusAreaMode, 'Center') -% return -% end - - fprintf('Starting on epoch %g mode %s w/ center seed %g surround seed %g\n', ei,stimulusAreaMode, seedByEpoch(ei,1),seedByEpoch(ei,2)); - - % Generate stimulus - - stimulus = []; - - preFrames = round(frameRate * (epoch.get('preTime')/1e3)); - stimFrames = round(frameRate * (epoch.get('stimTime')/1e3)); - - if strcmp(stimulusAreaMode, 'Center') - locations = 1; - elseif strcmp(stimulusAreaMode, 'Surround') - locations = 2; - else - locations = 1:2; - end - - for location = locations - stimLocation = []; - stimLocation(1:preFrames, 1) = zeros(preFrames, 1); - - noiseStream = RandStream('mt19937ar', 'Seed', seedByEpoch(ei,location)); - - for fi = preFrames+1:floor(stimFrames/epoch.get('frameDwell')) - stimLocation(fi, 1) = noiseStream.randn; - end - ml = epoch.get('meanLevel'); - contrast = 1; %epoch.get('currentContrast') - stimLocation = ml + contrast * ml * stimLocation; - - stimLocation(stimLocation < 0) = 0; -% stimLocation(stimLocation > ml * 2) = ml * 2; - stimLocation(stimLocation > 1) = 1; - stimulus(:,location) = stimLocation; - - end - - if strcmp(stimulusAreaMode, 'Center') - stimulus(:,2) = epoch.get('meanLevel') + zeros(size(stimulus,1), 1); - elseif strcmp(stimulusAreaMode, 'Surround') - stimulus(:,1) = epoch.get('meanLevel') + zeros(size(stimulus,1), 1); - end - -% stimulus = smooth(stimulus, 3); - -% stimulusFiltered = filtfilt(stimFilter, stimulus); - - % generate response - - if strcmp(epoch.get('ampMode'), 'Cell attached') - spikeTimes = epoch.get('spikes_ch1') / sampleRate; - response = NIM.Spks2Robs(spikeTimes, 1/frameRate, size(stimulus,1) ); - useOutputNonlinearity = true; - else - useOutputNonlinearity = false; - - responseRaw = epoch.getData('Amplifier_Ch1'); - response = responseRaw * sign(mean(responseRaw)); - response = response / max(response); -% response = response - mean(response); - response = response - median(response); - response = response + 0.03*(max(response) - min(response)); - - % response = response + 2; - % response = zscore(response); - response = resample(response, frameRate, sampleRate); -% response = filtfilt(responseFilter, response); - - -% response(response < 0) = 0; - - m = min([size(stimulus,1), length(response)]); - response = response(1:m); - stimulus = stimulus(1:m,:); -% while length(stimulus) < length(response) -% stimulus = [stimulus; ml]; -% end - end - - % compose data together - - assert(all(size(stimulus, 1) == size(response, 1))) - repeatMarker = isRepeatSeed * ones(size(stimulus)); - - if averageRepeatSeedEpochs - - stimulusFull = [stimulusFull, stimulus]; - responseFull = [response, responseFull]; - repeatMarkerFull = [repeatMarker, repeatMarkerFull]; - else - - stimulusFull = [stimulusFull; stimulus]; - responseFull = [responseFull; response]; - repeatMarkerFull = [repeatMarkerFull; repeatMarker]; - end - -end - -if averageRepeatSeedEpochs - stimulusFull = mean(stimulusFull, 2); - responseFull = mean(responseFull, 2); - repeatMarkerFull = mean(repeatMarkerFull, 2); -end - - -figure(6);clf; -handles = tight_subplot(3,1); -plot(handles(1), stimulusFull) -plot(handles(2), responseFull) -plot(handles(3), repeatMarkerFull) - - -%% Generate model parameters - -stimulus = stimulusFull; -stimulusFiltered = filtfilt(stimFilter, stimulus); -response = responseFull; -modelFitIndices = repeatMarkerFull; - -% Set parameters of fits -up_samp_fac = 1; % temporal up-sampling factor applied to stimulus -tent_basis_spacing = 1; % represent stimulus filters using tent-bases with this spacing (in up-sampled time units) -timeCutoff = 0.5; -updateRate = frameRate/epoch.get('frameDwell'); -nLags = round(timeCutoff * updateRate); - -% Create structure with parameters using static NIM function -params_stim = NIM.create_stim_params([nLags 2 1], 'stim_dt', 1/frameRate); - -% Create T x nLags 'design matrix' representing the relevant stimulus history at each time point -Xstim = NIM.create_time_embedding(stimulus, params_stim); - -% Generate Model - -% use a saved filter to get things looking right at the start (avoid inversions) -% nim = NIM(params_stim, NL_types, subunit_signs, 'd2t', lambda_d2t, 'init_filts', {savedFilter}); - -% doc on the regularization types: -% nld2 second derivative of tent basis coefs -% d2xt spatiotemporal laplacian -% d2x 2nd spatial deriv -% d2t 2nd temporal deriv -% l2 L2 on filter coefs -% l1 L1 on filter coefs - -% Output nonlinearities -% {'lin','rectpow','exp','softplus','logistic'} - -% Subunit nonlinearities -% {'lin','quad','rectlin','rectpow','softplus','exp','nonpar'} - -nim = NIM(params_stim, [], [], 'spkNL', 'lin'); -nim = nim.add_subunits('lin', 1); -nim = nim.set_reg_params('d2t', 10); -nim = nim.set_reg_params('d2x', 10); -nim = nim.fit_filters( response, Xstim, 'silent', 1); - - -% add negative subunit starting with a delayed copy of the first -% useDelayedCopy = true; -% if useDelayedCopy -% nim = nim.fit_filters(response, Xstim, 'silent', 1); -% delayed_filt = nim.shift_mat_zpad(nim.subunits(1).filtK, 4); -% nim = nim.add_subunits( {'lin'}, -1, 'init_filts', {delayed_filt}); -% else -% nim = nim.add_subunits( {'lin'}, -1); -% end - -% add subunit as an OFF filter -% nim = nim.fit_filters( response, Xstim, 'silent', 1); -% flipped_filt = -1 * nim.subunits(1).filtK; -% nim = nim.add_subunits( {'lin'}, 1, 'init_filts', {flipped_filt} ); -% nim = nim.fit_filters(response, Xstim, 'silent', 1); - -% add subunit as an -OFF filter -% flipped_filt = -1 * nim.subunits(3).filtK; -% delayed_filt = nim.shift_mat_zpad( nim.subunits(1).filtK, 4 ); -% nim = nim.add_subunits( {'rectlin'}, -1, 'init_filts', {flipped_filt} ); -% nim = nim.fit_filters(response, Xstim, 'silent', 1); - -% fit upstream nonlinearities - -nonpar_reg = 20; % set regularization value -useNonparametricSubunitNonlinearity = true; -enforceMonotonicSubunitNonlinearity = false; -if useNonparametricSubunitNonlinearity - nim = nim.init_nonpar_NLs( Xstim, 'lambda_nld2', nonpar_reg, 'NLmon', enforceMonotonicSubunitNonlinearity); -end - -% use this later: -% nim = nim.init_spkhist( 20, 'doubling_time', 5 ); - -numFittingLoops = 2; -nim = nim.set_reg_params('d2t', 40); -nim = nim.set_reg_params('d2x', 40); -for fi = 1:numFittingLoops - nim = nim.fit_filters( response, Xstim, 'silent', 1, 'fit_offsets', 1); - if useNonparametricSubunitNonlinearity - nim = nim.fit_upstreamNLs( response, Xstim, 'silent', 1); - end - nim = nim.fit_spkNL(response, Xstim, 'silent', 1); - [ll, responsePrediction, mod_internals] = nim.eval_model(response, Xstim); - r2 = 1-mean((response-responsePrediction).^2)/var(response); -end -fprintf('Log likelihood: %g R2: %g\n', -1*ll, r2); - - -generatingFunction = mod_internals.G; -subunitOutputLN = mod_internals.fgint; -subunitOutputL = mod_internals.gint; - - - - - - -% Display model components -colorsBySubunit = [1,0,.5; 0,.5,1; 0,1,.9; 1,.3,0]; - -figure(200);clf; -handles = tight_subplot(2,2, .05); -numSubunits = length(nim.subunits); - -% subunit filters -axes(handles(1)); -filterTime = 1:nLags; -filterTime = (filterTime-1) / updateRate; -h = []; -for si = 1:numSubunits - f = reshape(nim.subunits(si).filtK, [], 2); - for fi = 1:size(f,2) - c = colorsBySubunit(si,:) - .2 * (fi-1); % plot spatial filters a little darker - c(c < 0) = 0; - h(si,fi) = plot(filterTime, f(:,fi), 'Color', c); - hold on - end -end -line([0,max(filterTime)],[0,0],'Color','k', 'LineStyle',':'); -% legString = cellfun(@num2str, num2cell(1:10), 'UniformOutput', 0); -% legend(h(:), legString) -title('subunit linear filters') - -% Subunit nonlinearity -axes(handles(2)); -for si=1:numSubunits - yyaxis left - histogram(subunitOutputL(:,si), 'DisplayStyle','stairs','EdgeColor', colorsBySubunit(si,:), 'Normalization', 'Probability') - hold on - gendist_x = xlim(); - - subunit = nim.subunits(si); - if strcmp(subunit.NLtype, 'nonpar') - x = subunit.NLnonpar.TBx; y = subunit.NLnonpar.TBy; - else - x = gendist_x; y = subunit.apply_NL(x); - end - yyaxis right - plot(x, y, '-', 'Color', colorsBySubunit(si,:), 'LineWidth',1) - hold on - -end -yyaxis right -line(xlim(),[0,0],'Color','k', 'LineStyle',':') -line([0,0], ylim(),'Color','k', 'LineStyle',':') -title('subunit generator & output nonlinearity') - -% Subunit outputs -axes(handles(3)) -for si = 1:numSubunits - histogram(nim.subunits(si).weight * subunitOutputLN(:,si), 'DisplayStyle','stairs', 'EdgeColor', colorsBySubunit(si,:), 'Normalization','Probability'); - hold on -end -legend(legString) -title('subunit output (after weights)') -hold on - -% Overall output nonlinearity -axes(handles(4)) -yyaxis left -title('overall output'); -generatorOffset = nim.spkNL.theta; -histogram(generatingFunction + generatorOffset, 'DisplayStyle','stairs','EdgeColor','k', 'Normalization','Probability'); -hold on -yticklabels([]) - -yyaxis right -x = linspace(min(generatingFunction + generatorOffset), max(generatingFunction + generatorOffset)); -y = nim.apply_spkNL(x); -plot(x,y, 'r') -xticklabels('auto') - -legend('generator + offset', 'output NL') - - -% notes for LN: -% generate nonlinearity using repeated epochs -% get mean filter from the single run epochs - - - -% Display time signals - -figure(201);clf; -warning('off', 'MATLAB:legend:IgnoringExtraEntries') -handles = tight_subplot(3,1,0, [.05,.01], .05); - -% stimulus -axes(handles(1)); -t = linspace(0, length(stimulus) / frameRate, length(stimulus)); -plot(t, stimulusFiltered, 'Color','k') -grid on -legend('stim lowpass') - -axes(handles(2)) -for si = 1:numSubunits - plot(t, nim.subunits(si).weight * subunitOutputLN(:,si)/3, 'Color', colorsBySubunit(si,:)) - hold on -end -legend('sub 1 out weighted (ON+)','sub 2 out weighted (ON-)','sub 3 out weighted (OFF)') -grid on - -% response -axes(handles(3)); -plot(t, response, 'g') -hold on -% plot(t, generatingFunction, 'b:') -plot(t, responsePrediction, 'r') -ylim('auto') -grid on -legend('response','prediction') - -linkaxes(handles, 'x') -xlim([5,7]) - -pan xon - -%% step response -stepStartTime = 0.5; -stepEndTime = 1.5; - -t = (0:1/updateRate:3)'; -artStim = zeros(size(t)); -artStim(t >= stepStartTime & t <= stepEndTime) = 0.5; -artXstim = NIM.create_time_embedding(artStim, params_stim); - -figure(205);clf; -plot(t, artStim); - -hold on -[~, artResponsePrediction_s] = nim.eval_model([], artXstim); -plot(t, artResponsePrediction_s) - -legend('stimulus','response') - - - - - diff --git a/analysisSupportFunctions/runNoiseFilterSimply.m b/analysisSupportFunctions/runNoiseFilterSimply.m deleted file mode 100644 index 16f3ba2..0000000 --- a/analysisSupportFunctions/runNoiseFilterSimply.m +++ /dev/null @@ -1,40 +0,0 @@ - - -% load cellData/102816Ac3.mat -% epochIndices = [311 314 317]; - -% load cellData/102516Ac2.mat -% epochIndices = [167]; - -load cellData/110216Ac19.mat -epochIndices = 218:251; - -% spiking WFDS -load cellData/121616Ac2.mat -epochIndices = 133:135; - -centerEpochs = []; -numberOfEpochs = length(epochIndices); -for ei=1:numberOfEpochs - - epoch = cellData.epochs(epochIndices(ei)); - centerNoiseSeed = epoch.get('centerNoiseSeed') - stimulusAreaMode = epoch.get('currentStimulus'); - - if strcmp(stimulusAreaMode, 'Center') - centerEpochs(end+1) = epochIndices(ei); - end -end -epochIndices = centerEpochs; - -modelStruct = noiseFilter(cellData, epochIndices, 'NIM LN'); - -% figure(201);clf; -% % plot(t, allFilters); -% % hold on -% allFilters = cell2mat(modelStruct.filtersByEpoch); -% mn = mean(allFilters); -% se = std(allFilters)/sqrt(size(allFilters, 1)); -% plot([mn; mn+se; mn-se]', 'LineWidth', 1) -% % hold off -% title('Filter mean and sem') diff --git a/analysisSupportFunctions/shape/plotShapeData.m b/analysisSupportFunctions/shape/plotShapeData.m index eb9f0b9..bef3e3e 100755 --- a/analysisSupportFunctions/shape/plotShapeData.m +++ b/analysisSupportFunctions/shape/plotShapeData.m @@ -84,16 +84,11 @@ if posIndex >= 3 gfit = plotSpatial(goodPositions, vals, sprintf('%s at V = %d mV, intensity = %f', smode, voltage, intensity), 1, sign(voltage)); -% if ~isnan(gfit) -% % caxis([0, max(vals)]); -% % colormap(flipud(colormap)) -% disp(gfit.keys) -% disp(cell2mat(gfit.values)) -% else -% disp('NaN fit'); -% end + % caxis([0, max(vals)]); + % colormap(flipud(colormap)) end - + disp(gfit.keys) + disp(cell2mat(gfit.values)) data(vi, ii, 1:2) = {goodPositions, vals}; end end diff --git a/analysisTreeClasses/AnnulusAnalysis.m b/analysisTreeClasses/AnnulusAnalysis.m index abbd9fc..c96b599 100644 --- a/analysisTreeClasses/AnnulusAnalysis.m +++ b/analysisTreeClasses/AnnulusAnalysis.m @@ -277,6 +277,7 @@ function plot_innerDiameterVsstimInterval_charge(node, cellData) errorbar(xvals, yvals, errs); xlabel('inner diameter'); ylabel(['stimInterval_charge (' yField.units ')']); + xvals' end function plot_innerDiameterVsstimInterval_chargeNORM(node, cellData) @@ -593,7 +594,101 @@ function plot_innerDiameterVsspikeCount_stimInt_gblSubtNORM(node, cellData) errorbar(xvals, yvals, errs); xlabel('inner diameter'); ylabel(['spikeCount_stimInterval_granBaselineSubtracted (' yField.units ')']); - end + end + + function plot_curInnerDiameterVsshortInt900_peak(node, cellData) + rootData = node.get(1); + xvals = rootData.curInnerDiameter; + yField = rootData.shortInt900_peak; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('curInnerDiameter'); + ylabel(['shortInt900_peak (' yField.units ')']); + end + + function plot_curInnerDiameterVsstimInterval_outCharge(node, cellData) + rootData = node.get(1); + xvals = rootData.curInnerDiameter; + yField = rootData.stimInterval_outCharge; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('curInnerDiameter'); + ylabel(['stimInterval_outCharge (' yField.units ')']); + end + + function plot_curInnerDiameterVsstimInterval_inCharge(node, cellData) + rootData = node.get(1); + xvals = rootData.curInnerDiameter; + yField = rootData.stimInterval_inCharge; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('curInnerDiameter'); + ylabel(['stimInterval_outCharge (' yField.units ')']); + end + + + function plot_curInnerDiameterVsstimInterval_outChargeNORM(node, cellData) + rootData = node.get(1); + xvals = rootData.curInnerDiameter; + yField = rootData.stimInterval_outCharge; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + [M, Mind] = max(abs(yvals)); + if yvals(Mind) < 0 + yvals = -yvals./M; + else + yvals = yvals./M; + end; + errs = errs./M; + errorbar(xvals, yvals, errs); + xlabel('curInnerDiameter'); + ylabel(['stimInterval_outCharge (' yField.units ')']); + end + + function plot_curInnerDiameterVsstimInterval_inChargeNORM(node, cellData) + rootData = node.get(1); + xvals = rootData.curInnerDiameter; + yField = rootData.stimInterval_inCharge; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + [M, Mind] = max(abs(yvals)); + if yvals(Mind) < 0 + yvals = -yvals./M; + else + yvals = yvals./M; + end; + errs = errs./M; + errorbar(xvals, yvals, errs); + xlabel('curInnerDiameter'); + ylabel(['stimInterval_outCharge (' yField.units ')']); + end + + + + end end diff --git a/analysisTreeClasses/BarsMultiAngleAnalysis.m b/analysisTreeClasses/BarsMultiAngleAnalysis.m old mode 100755 new mode 100644 index 7561658..a430144 --- a/analysisTreeClasses/BarsMultiAngleAnalysis.m +++ b/analysisTreeClasses/BarsMultiAngleAnalysis.m @@ -51,7 +51,7 @@ 'splitValue', 'barAngle'); %baseline subtraction and normalization (factor out in the - %future? + %future? if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') for i=1:L %for each leaf node curNode = obj.get(leafIDs(i)); @@ -85,7 +85,8 @@ curNode = mergeIntoNode(curNode, tempStruct); obj = obj.set(leafIDs(i), curNode); - end + end + end @@ -331,7 +332,9 @@ function plot_barAngleVsspikeCount_stimAfter200ms(node, cellData) title(['OSI = ' num2str(rootData.spikeCount_stimAfter200ms_OSI) ', OSang = ' num2str(rootData.spikeCount_stimAfter200ms_OSang)]); hold off; end - function plot_barAngleVsspikeCount_stimInt_gblSubt(node, cellData) + + + function plot_barAngleVsspikeCount_stimInt_gblSubt(node, cellData) rootData = node.get(1); xvals = rootData.barAngle; yField = rootData.spikeCount_stimInterval_grndBlSubt; @@ -362,7 +365,7 @@ function plot_barAngleVsspikeCount_stimInt_gblSubtNORM(node, cellData) errorbar(xvals, yvals, errs); xlabel('barAngle'); ylabel(['spikeCount_stimInterval_granBaselineSubtracted_norm (' yField.units ')']); - end + end end end \ No newline at end of file diff --git a/analysisTreeClasses/BarsMultiAngleAnalysis_David.m b/analysisTreeClasses/BarsMultiAngleAnalysis_David.m new file mode 100644 index 0000000..a430144 --- /dev/null +++ b/analysisTreeClasses/BarsMultiAngleAnalysis_David.m @@ -0,0 +1,371 @@ +classdef BarsMultiAngleAnalysis < AnalysisTree + properties + StartTime = 0; + EndTime = 0; + end + + methods + function obj = BarsMultiAngleAnalysis(cellData, dataSetName, params) + if nargin < 3 + params.deviceName = 'Amplifier_Ch1'; + end + if strcmp(params.deviceName, 'Amplifier_Ch1') + params.ampModeParam = 'ampMode'; + else + params.ampModeParam = 'amp2Mode'; + end + + nameStr = [cellData.savedFileName ': ' dataSetName ': BarsMultiAngleAnalysis']; + obj = obj.setName(nameStr); + dataSet = cellData.savedDataSets(dataSetName); + obj = obj.copyAnalysisParams(params); + obj = obj.copyParamsFromSampleEpoch(cellData, dataSet, ... + {'RstarMean', 'RstarIntensity', params.ampModeParam, 'offsetX', 'offsetY'}); + obj = obj.buildCellTree(1, cellData, dataSet, {'barAngle'}); + end + + function obj = doAnalysis(obj, cellData) + rootData = obj.get(1); + leafIDs = obj.findleaves(); + L = length(leafIDs); + baseline = zeros(1,L); %for grandBaseline subt. + for i=1:L + curNode = obj.get(leafIDs(i)); + if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') + outputStruct = getEpochResponses_CA(cellData, curNode.epochID, ... + 'DeviceName', rootData.deviceName,'StartTime', obj.StartTime, 'EndTime', obj.EndTime); + outputStruct = getEpochResponseStats(outputStruct); + curNode = mergeIntoNode(curNode, outputStruct); + baseline(i) = outputStruct.baselineRate.mean_c; %for grandBaseline subt. Adam 2/13/17 + else %whole cell + outputStruct = getEpochResponses_WC(cellData, curNode.epochID, ... + 'DeviceName', rootData.deviceName); + outputStruct = getEpochResponseStats(outputStruct); + curNode = mergeIntoNode(curNode, outputStruct); + end + + obj = obj.set(leafIDs(i), curNode); + end + + obj = obj.percolateUp(leafIDs, ... + 'splitValue', 'barAngle'); + + %baseline subtraction and normalization (factor out in the + %future? + if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') + for i=1:L %for each leaf node + curNode = obj.get(leafIDs(i)); + %baseline subtraction + baselineMean = outputStruct.baselineRate.mean_c; %THIS WAS WRONGLY NAMED "GRAND_BASELINE" Adam 2/13/17 + tempStruct.ONSETrespRate_baselineSubtracted = curNode.ONSETrespRate; + tempStruct.ONSETrespRate_baselineSubtracted.value = curNode.ONSETrespRate.value - baselineMean; + tempStruct.OFFSETrespRate_baselineSubtracted = curNode.OFFSETrespRate; + tempStruct.OFFSETrespRate_baselineSubtracted.value = curNode.OFFSETrespRate.value - baselineMean; + tempStruct.ONSETspikes_baselineSubtracted = curNode.ONSETspikes; + tempStruct.ONSETspikes_baselineSubtracted.value = curNode.ONSETspikes.value - baselineMean.*curNode.ONSETrespDuration.value; %fix nan and INF here + tempStruct.OFFSETspikes_baselineSubtracted = curNode.OFFSETspikes; + tempStruct.OFFSETspikes_baselineSubtracted.value = curNode.OFFSETspikes.value - baselineMean.*curNode.OFFSETrespDuration.value; + tempStruct.ONSETspikes_400ms_baselineSubtracted = curNode.spikeCount_ONSET_400ms; + tempStruct.ONSETspikes_400ms_baselineSubtracted.value = curNode.spikeCount_ONSET_400ms.value - baselineMean.*0.4; %fix nan and INF here + tempStruct.OFFSETspikes_400ms_baselineSubtracted = curNode.OFFSETspikes; + tempStruct.OFFSETspikes_400ms_baselineSubtracted.value = curNode.OFFSETspikes.value - baselineMean.*0.4; + tempStruct = getEpochResponseStats(tempStruct); + + curNode = mergeIntoNode(curNode, tempStruct); + obj = obj.set(leafIDs(i), curNode); + end + + grandBaselineMean = mean(baseline); + for i=1:L %for each leaf node + curNode = obj.get(leafIDs(i)); + + tempStruct.spikeCount_stimInterval_grndBlSubt = curNode.spikeCount_stimInterval; + tempStruct.spikeCount_stimInterval_grndBlSubt.value = curNode.spikeCount_stimInterval.value - grandBaselineMean; %assumes 1 sec stim interval + tempStruct = getEpochResponseStats(tempStruct); + + curNode = mergeIntoNode(curNode, tempStruct); + obj = obj.set(leafIDs(i), curNode); + end + + + end + + [byEpochParamList, singleValParamList, collectedParamList] = getParameterListsByType(curNode); + obj = obj.percolateUp(leafIDs, byEpochParamList, byEpochParamList); + obj = obj.percolateUp(leafIDs, singleValParamList, singleValParamList); + obj = obj.percolateUp(leafIDs, collectedParamList, collectedParamList); + + %OSI, OSang + rootData = obj.get(1); + ind = find(rootData.barAngle >= 180); + rootData.barAngle(ind) = rootData.barAngle(ind) - 180; + rootData = addOSI(rootData, 'barAngle'); + rootData.stimParameterList = {'barAngle'}; + rootData.byEpochParamList = byEpochParamList; + rootData.singleValParamList = singleValParamList; + rootData.collectedParamList = collectedParamList; + obj = obj.set(1, rootData); + end + + end + + methods(Static) + + function plot_barAngleVsspikeCount_stimInterval(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.spikeCount_stimInterval; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['spikeCount_stimInterval (' yField.units ')']); + + end + + function plot_barAngleVsONSETspikes(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.ONSETspikes; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['ONSETspikes (' yField.units ')']); + + hold on; + x = [rootData.ONSETspikes_OSang,rootData.ONSETspikes_OSang]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.ONSETspikes_OSI) ', OSang = ' num2str(rootData.ONSETspikes_OSang)]); + hold off; + end + + function plot_barAngleVsOFFSETspikes(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.OFFSETspikes; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['OFFSETspikes (' yField.units ')']); + + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['OFFSETspikes (' yField(1).units ')']); + + hold on; + x = [rootData.OFFSETspikes_OSang,rootData.OFFSETspikes_OSang]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.OFFSETspikes_OSI) ', OSang = ' num2str(rootData.OFFSETspikes_OSang)]); + hold off; + end + + function plot_barAngleVsONSET_peak(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.ONSET_peak; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['ONSET_peak (' yField.units ')']); + + hold on; + x = [rootData.ONSET_peak_OSang,rootData.ONSET_peak_OSang]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.ONSET_peak_OSI) ', OSang = ' num2str(rootData.ONSET_peak_OSang)]); + hold off; + end + + function plot_barAngleVsOFFSET_peak(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.OFFSET_peak; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['OFFSET_peak (' yField.units ')']); + + hold on; + x = [rootData.OFFSET_peak_OSang,rootData.OFFSET_peak_OSang]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.OFFSET_peak_OSI) ', OSang = ' num2str(rootData.OFFSET_peak_OSang)]); + hold off; + end + + function plot_barAngleVsspikeCount_ONSET_400ms(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.spikeCount_ONSET_400ms; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['spikeCount_ONSET_400ms (' yField.units ')']); + end + + function plot_barAngleVsONSET_charge400ms(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.ONSET_charge400ms; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['ONSET_charge400ms (' yField.units ')']); + end + + function plot_barAngleVsONSET_avgTracePeak(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.ONSET_avgTracePeak; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('barAngle'); + ylabel(['ONSET_avgTracePeak (' yField.units ')']); + + hold on; + x = [rootData.ONSET_avgTracePeak_OSang,rootData.ONSET_avgTracePeak_OSang]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.ONSET_avgTracePeak_OSI) ', OSang = ' num2str(rootData.ONSET_avgTracePeak_OSang)]); + hold off; + end + + function plot_barAngleVsspikeCount_stimInterval_baselineSubtracted(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.spikeCount_stimInterval_baselineSubtracted; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['spikeCount_stimInterval_baselineSubtracted (' yField.units ')']); + + hold on; + x = [rootData.spikeCount_stimInterval_baselineSubtracted,rootData.spikeCount_stimInterval_baselineSubtracted]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.spikeCount_stimInterval_baselineSubtracted_OSI) ', OSang = ' num2str(rootData.spikeCount_stimInterval_baselineSubtracted_OSang)]); + hold off; + end + + function plot_barAngleVsspikeCount_stimTo200ms(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.spikeCount_stimTo200ms; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['spikeCount_stimTo200ms (' yField.units ')']); + + hold on; + x = [rootData.spikeCount_stimTo200ms,rootData.spikeCount_stimTo200ms]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.spikeCount_stimTo200ms_OSI) ', OSang = ' num2str(rootData.spikeCount_stimTo200ms_OSang)]); + hold off; + end + + function plot_barAngleVsspikeCount_stimAfter200ms(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.spikeCount_stimAfter200ms; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['spikeCount_stimAfter200ms (' yField.units ')']); + + hold on; + x = [rootData.spikeCount_stimAfter200ms,rootData.spikeCount_stimAfter200ms]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.spikeCount_stimAfter200ms_OSI) ', OSang = ' num2str(rootData.spikeCount_stimAfter200ms_OSang)]); + hold off; + end + + + function plot_barAngleVsspikeCount_stimInt_gblSubt(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.spikeCount_stimInterval_grndBlSubt; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['spikeCount_stimInterval_granBaselineSubtracted (' yField.units ')']); + end + + function plot_barAngleVsspikeCount_stimInt_gblSubtNORM(node, cellData) + rootData = node.get(1); + xvals = rootData.barAngle; + yField = rootData.spikeCount_stimInterval_grndBlSubt; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + M = max(abs(yvals)); + yvals = yvals./M; + errs = errs./M; + errorbar(xvals, yvals, errs); + xlabel('barAngle'); + ylabel(['spikeCount_stimInterval_granBaselineSubtracted_norm (' yField.units ')']); + end + end + +end \ No newline at end of file diff --git a/analysisTreeClasses/CenterSurroundNoiseAnalysis.m b/analysisTreeClasses/CenterSurroundNoiseAnalysis.m deleted file mode 100644 index c975f2f..0000000 --- a/analysisTreeClasses/CenterSurroundNoiseAnalysis.m +++ /dev/null @@ -1,71 +0,0 @@ -classdef CenterSurroundNoiseAnalysis < AnalysisTree - properties - StartTime = 0; - EndTime = 0; - modelStruct - end - - methods - function obj = CenterSurroundNoiseAnalysis(cellData, dataSetName, params) - if nargin < 3 - params.deviceName = 'Amplifier_Ch1'; - end - if strcmp(params.deviceName, 'Amplifier_Ch1') - params.ampModeParam = 'ampMode'; - params.holdSignalParam = 'ampHoldSignal'; - else - params.ampModeParam = 'amp2Mode'; - params.holdSignalParam = 'amp2HoldSignal'; - end - - nameStr = [cellData.savedFileName ': ' dataSetName ': WhiteNoiseFlickerAnalysis']; - obj = obj.setName(nameStr); - dataSet = cellData.savedDataSets(dataSetName); - obj = obj.copyAnalysisParams(params); - obj = obj.copyParamsFromSampleEpoch(cellData, dataSet, ... - {'RstarMean', 'RstarIntensity', params.ampModeParam, params.holdSignalParam}); - obj = obj.buildCellTree(1, cellData, dataSet, {'ampMode'}); - end - - function obj = doAnalysis(obj, cellData) - - rootData = obj.get(1); - leafIDs = obj.findleaves(); - mainLeaf = leafIDs(1); - node = obj.get(mainLeaf); - - numberOfEpochs = length(node.epochID); - - epochIndices = []; - for ei=1:numberOfEpochs - eid = node.epochID(ei); - epoch = cellData.epochs(eid); - stimulusAreaMode = epoch.get('currentStimulus'); - - if strcmp(stimulusAreaMode, 'Center') - epochIndices(end+1) = eid; - end - end - - -% obj.modelStruct = noiseFilter(cellData, epochIndices); -% -% -% figure(197);clf; -% allFilters = cell2mat(obj.modelStruct.filtersByEpoch); -% mn = mean(allFilters); -% se = std(allFilters)/sqrt(size(allFilters, 1)); -% plot([mn; mn+se; mn-se]', 'LineWidth', 1) %obj.modelStruct.timeByEpoch{1}, -% % hold off -% title('Filter mean \{pm} sem') - - end - end - - methods(Static) - - function plotMeanTraces(~, ~) - - end - end -end \ No newline at end of file diff --git a/analysisTreeClasses/ColorResponseAnalysis.m b/analysisTreeClasses/ColorResponseAnalysis.m deleted file mode 100644 index 473e049..0000000 --- a/analysisTreeClasses/ColorResponseAnalysis.m +++ /dev/null @@ -1,156 +0,0 @@ -classdef ColorResponseAnalysis < AnalysisTree - properties - - end - - methods - function obj = ColorResponseAnalysis(cellData, dataSetName, params) - if nargin < 3 - params.deviceName = 'Amplifier_Ch1'; - end - if strcmp(params.deviceName, 'Amplifier_Ch1') - params.ampModeParam = 'ampMode'; - else - params.ampModeParam = 'amp2Mode'; - end - - nameStr = [cellData.savedFileName ': ' dataSetName ': ContrastRespAnalysis']; - obj = obj.setName(nameStr); - dataSet = cellData.savedDataSets(dataSetName); - obj = obj.copyAnalysisParams(params); - obj = obj.copyParamsFromSampleEpoch(cellData, dataSet, ... - {'RstarMean', params.ampModeParam}); - obj = obj.buildCellTree(1, cellData, dataSet, {'colorChangeMode', 'colorPattern2', 'intensity2'}); - end - - function obj = doAnalysis(obj, cellData) - rootData = obj.get(1); - leafIDs = obj.findleaves(); - L = length(leafIDs); - baseline = zeros(1,L); - - for i=1:L %for each leaf node - curNode = obj.get(leafIDs(i)); - if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') - outputStruct = getEpochResponses_CA(cellData, curNode.epochID, ... - 'DeviceName', rootData.deviceName); - outputStruct = getEpochResponseStats(outputStruct); - curNode = mergeIntoNode(curNode, outputStruct); - baseline(i) = outputStruct.baselineRate.mean_c; - else %whole cell - outputStruct = getEpochResponses_WC(cellData, curNode.epochID, ... - 'DeviceName', rootData.deviceName); - outputStruct = getEpochResponseStats(outputStruct); - curNode = mergeIntoNode(curNode, outputStruct); - end - - obj = obj.set(leafIDs(i), curNode); - end - - obj = obj.percolateUp(leafIDs, ... - 'splitValue', 'contrast', 'sortColors'); - - [byEpochParamList, singleValParamList, collectedParamList] = getParameterListsByType(curNode); - obj = obj.percolateUp(leafIDs, byEpochParamList, byEpochParamList); - obj = obj.percolateUp(leafIDs, singleValParamList, singleValParamList); - obj = obj.percolateUp(leafIDs, collectedParamList, collectedParamList); - - rootData = obj.get(1); - rootData.byEpochParamList = byEpochParamList; - rootData.singleValParamList = singleValParamList; - rootData.collectedParamList = collectedParamList; - rootData.stimParameterList = {'baseColor'}; - obj = obj.set(1, rootData); - end - end - - methods(Static) - - function plot_colorRatioVsONSETspikes(node, ~) - rootData = node.get(1); - xvals = rootData.contrast; - yField = rootData.ONSETspikes; - if strcmp(yField(1).units, 's') - yvals = yField.median_c; - else - yvals = yField.mean_c; - end - errs = yField.SEM; - errorbar(xvals, yvals, errs); - xlabel('color'); - ylabel(['ONSETspikes (' yField.units ')']); - end - - function plot_colorRatioVsOFFSETspikes(node, ~) - rootData = node.get(1); - xvals = rootData.contrast; - yField = rootData.OFFSETspikes; - if strcmp(yField(1).units, 's') - yvals = yField.median_c; - else - yvals = yField.mean_c; - end - errs = yField.SEM; - errorbar(xvals, yvals, errs); - xlabel('color'); - ylabel(['OFFSETspikes (' yField.units ')']); - end - - function plot_ramp_ONSETspikes(tree, cellData) - ColorResponseAnalysis.plot_ramp(tree, cellData, 'ONSETspikes_mean'); - end - - function plot_ramp_OFFSETspikes(tree, cellData) - ColorResponseAnalysis.plot_ramp(tree, cellData, 'OFFSETspikes_mean'); - end - - - function plot_ramp(tree, cellData, variableName) - colorNodeIds = tree.getchildren(1); - data = {}; - colors = {}; - for colornode = 1:length(colorNodeIds) - colorData = struct(); - colorData.intensity = []; - colorData.response = []; - currentStepColorNode = tree.get(colorNodeIds(colornode)); - colors{colornode} = currentStepColorNode.splitValue; - rampnodes = tree.getchildren(colorNodeIds(colornode)); - - % get contrast from sample epoch - - for ri = 1:length(rampnodes) - datanode = tree.get(rampnodes(ri)); - contrastepoch = cellData.epochs(datanode.epochID(1)); - contrast = contrastepoch.get('contrast'); - colorData.intensity(end+1) = datanode.splitValue / contrast; - colorData.response(end+1) = datanode.(variableName); - end - data{colornode} = colorData; - end - for ci = 1:length(colors) - d = data{ci}; - switch colors{ci} - case 'uv' - color = [.3, 0, .9]; - case 'blue' - color = [0, .5, 1]; - case 'green' - color = [0, .8, .1]; - end - - plot(d.intensity, d.response, 'Color', color, 'LineWidth', 3); - - hold on - - end -% legend(colors, 'Location', 'north') - hold off - xlabel('varying : step ratio') - - end - end - -end - - diff --git a/analysisTreeClasses/ContrastRespAnalysis.m b/analysisTreeClasses/ContrastRespAnalysis.m index 9bf1978..69a082c 100755 --- a/analysisTreeClasses/ContrastRespAnalysis.m +++ b/analysisTreeClasses/ContrastRespAnalysis.m @@ -295,19 +295,6 @@ function plot_contrastVsONSET_respIntervalT25(node, cellData) xlabel('contrast'); ylabel(['ONSET_respIntervalT25 (' yField.units ')']); end - ONSETlatency - - function plot_contrastVsONSETlatency(node, cellData) - rootData = node.get(1); - xvals = rootData.contrast; - yField = rootData.ONSETlatency; - yvals = yField.mean; - plot(xvals, yvals, 'bx-'); - xlim([min(xvals), max(xvals)]); - xlabel('contrast'); - ylabel(['ONSET_ONSETlatency (' yField.units ')']); - end - function plotData(node, cellData) rootData = node.get(1); @@ -335,6 +322,38 @@ function plot_contrastVsONSETspikes_grandBaselineSubtracted(node, cellData) ylabel(['ONSETspikes_grandBaselineSubtracted (' yField.units ')']); end + function plot_contrastVsStimIntervalSpks_gbl(node, cellData) + rootData = node.get(1); + xvals = rootData.contrast; + yField = rootData.spikeCount_stimInterval_grandBaselineSubtracted; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('contrast'); + ylabel(['spikes stimInterval grandBaselineSubtracted (' yField.units ')']); + end + + function plot_contrastVsStimIntervalSpks_gblNORM(node, cellData) + rootData = node.get(1); + xvals = rootData.contrast; + yField = rootData.spikeCount_stimInterval_grandBaselineSubtracted; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + M = max(abs(yvals)); + yvals = yvals./M; + errs = errs./M; + errorbar(xvals, yvals, errs); + xlabel('contrast'); + ylabel(['spikes stimInterval grandBaselineSubtracted (' yField.units ')']); + end end diff --git a/analysisTreeClasses/DriftingGratingsAnalysis.m b/analysisTreeClasses/DriftingGratingsAnalysis.m index 032cf44..7dfb49b 100755 --- a/analysisTreeClasses/DriftingGratingsAnalysis.m +++ b/analysisTreeClasses/DriftingGratingsAnalysis.m @@ -24,7 +24,8 @@ obj = obj.copyAnalysisParams(params); obj = obj.copyParamsFromSampleEpoch(cellData, dataSet, ... {'RstarMean', 'RstarIntensity', params.ampModeParam, params.holdSignalParam, 'gratingProfile', 'contrast', 'offsetX', 'offsetY'}); - obj = obj.buildCellTree(1, cellData, dataSet, {'contrast','temporalFreq', 'spatialFreq','gratingAngle'}); +% obj = obj.buildCellTree(1, cellData, dataSet, {'contrast','temporalFreq', 'spatialFreq','gratingAngle'}); + obj = obj.buildCellTree(1, cellData, dataSet, {'gratingAngle'}); end function obj = doAnalysis(obj, cellData) @@ -71,7 +72,7 @@ %OSI, OSang rootData = obj.get(1); - %rootData = addDSIandOSI(rootData, 'gratingAngle'); + rootData = addDSIandOSI(rootData, 'gratingAngle'); %rootData.stimParameterList = {'gratingAngle'}; %rootData.byEpochParamList = byEpochParamList; %rootData.singleValParamList = singleValParamList; @@ -86,93 +87,79 @@ function plotMeanTraces(node, cellData) rootData = node.get(1); chInd = node.getchildren(1); L = length(chInd); - ax = gca; + ax = axes; for i=1:L + hold(ax, 'on'); epochInd = node.get(chInd(i)).epochID; - if isfield(rootData, 'ampModeParam') - if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') - cellData.plotPSTH(epochInd, 10, rootData.deviceName, ax); - else - cellData.plotMeanData(epochInd, false, [], rootData.deviceName, ax); - end + if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') + cellData.plotPSTH(epochInd, 10, rootData.deviceName, ax); + else + cellData.plotMeanData(epochInd, false, [], rootData.deviceName, ax); end - hold(ax, 'on'); end hold(ax, 'off'); end - function plot_gratingAngleVsminCurrent(node, ~) + function plot_gratingAngleVsF0(node, cellData) rootData = node.get(1); xvals = rootData.gratingAngle; - yField = rootData.minCycleAvg; + yField = rootData.F0amplitude; yvals = yField.value; plot(xvals, yvals); xlabel('Grating Angle'); - ylabel(['Current (' yField.units ')']); - - end - - function plot_gratingAngleVsF0(node, ~) - rootData = node.get(1); - xvals = rootData.gratingAngle; - yField = rootData.F0amplitude; - yvals = yField.value; - - polarerror(xvals*pi/180, yvals, zeros(1,length(xvals))); - hold on; + ylabel(['F0 amplitude (' yField.units ')']); - polar([0 rootData.F0amplitude_DSang*pi/180], [0 (100*rootData.F0amplitude_DSI)], 'r-'); - polar([0 rootData.F0amplitude_OSang*pi/180], [0 (100*rootData.F0amplitude_OSI)], 'g-'); - xlabel('Grating Angle'); - ylabel(['F0 amplitude (' yField.units ')']); - addDsiOsiVarTitle(rootData, 'F1amplitude') - hold off; + hold on; + x = [rootData.F0amplitude_OSang,rootData.F0amplitude_OSang]; + y = get(gca, 'ylim'); + plot(x,y); + title(['OSI = ' num2str(rootData.F0amplitude_OSI) ', OSang = ' num2str(rootData.F0amplitude_OSang)]); + hold off; end - function plot_gratingAngleVsF1(node, ~) - rootData = node.get(1); - xvals = rootData.gratingAngle; - yField = rootData.F1amplitude; - yvals = yField.value; - polarerror(xvals*pi/180, yvals, zeros(1,length(xvals))); - hold on; - polar([0 rootData.F1amplitude_DSang*pi/180], [0 (100*rootData.F1amplitude_DSI)], 'r-'); - polar([0 rootData.F1amplitude_OSang*pi/180], [0 (100*rootData.F1amplitude_OSI)], 'g-'); - xlabel('gratingAngle'); - ylabel(['F1 (' yField(1).units ')']); - addDsiOsiVarTitle(rootData, 'F1amplitude') - hold off; + function plot_gratingAngleVsF1(node, cellData) + rootData = node.get(1); + xvals = rootData.gratingAngle; + yField = rootData.F1amplitude; + yvals = yField.value; + polarerror(xvals*pi/180, yvals, zeros(1,length(xvals))); + hold on; + polar([0 rootData.F1amplitude_DSang*pi/180], [0 (100*rootData.F1amplitude_DSI)], 'r-'); + polar([0 rootData.F1amplitude_OSang*pi/180], [0 (100*rootData.F1amplitude_OSI)], 'g-'); + xlabel('Grating Angle'); + ylabel(['F1 (' yField(1).units ')']); + title(['DSI = ' num2str(rootData.F1amplitude_DSI) ', DSang = ' num2str(rootData.F1amplitude_DSang) ... + ' and OSI = ' num2str(rootData.F1amplitude_OSI) ', OSang = ' num2str(rootData.F1amplitude_OSang)]); + hold off; end - function plot_gratingAngleVsF2(node, ~) - rootData = node.get(1); - xvals = rootData.gratingAngle; - yField = rootData.F2amplitude; - yvals = yField.value; - polarerror(xvals*pi/180, yvals, zeros(1,length(xvals))); - hold on - polar([0 rootData.F2amplitude_DSang*pi/180], [0 (100*rootData.F2amplitude_DSI)], 'r-'); - polar([0 rootData.F2amplitude_OSang*pi/180], [0 (100*rootData.F2amplitude_OSI)], 'g-'); - xlabel('gratingAngle'); - ylabel(['F2 (' yField(1).units ')']); - addDsiOsiVarTitle(rootData, 'F2amplitude') + function plot_gratingAngleVsF2(node, cellData) + rootData = node.get(1); + xvals = rootData.gratingAngle; + yField = rootData.F2amplitude; + yvals = yField.value; + polarerror(xvals*pi/180, yvals, zeros(1,length(xvals))); + hold on; + polar([0 rootData.F2amplitude_DSang*pi/180], [0 (100*rootData.F2amplitude_DSI)], 'r-'); + polar([0 rootData.F2amplitude_OSang*pi/180], [0 (100*rootData.F2amplitude_OSI)], 'g-'); + xlabel('Grating Angle'); + ylabel(['F2 (' yField(1).units ')']); + title(['DSI = ' num2str(rootData.F2amplitude_DSI) ', DSang = ' num2str(rootData.F2amplitude_DSang) ... + ' and OSI = ' num2str(rootData.F2amplitude_OSI) ', OSang = ' num2str(rootData.F2amplitude_OSang)]); + hold off; end - function plot_gratingAngleVsF2overF1(node, ~) + function plot_gratingAngleVsF2overF1(node, cellData) rootData = node.get(1); xvals = rootData.gratingAngle; yField = rootData.F2overF1; yvals = yField.value; polarerror(xvals*pi/180, yvals, zeros(1,length(xvals))); - hold on - polar([0 rootData.F2overF1_DSang*pi/180], [0 (20*rootData.F2overF1_DSI)], 'r-'); - polar([0 rootData.F2overF1_OSang*pi/180], [0 (20*rootData.F2overF1_OSI)], 'g-'); xlabel('gratingAngle'); ylabel('F2 over F1'); - addDsiOsiVarTitle(rootData, 'F2overF1') end - - %Adam 2/14/17 + + %Adam 2/14/17 function plot_gratingAngleVsCycleAvgPeakFR_polar(node, cellData) rootData = node.get(1); xvals = rootData.gratingAngle; @@ -249,12 +236,18 @@ function plot_gratingAngleVsCycleAvgPeakFR_NROM(node, cellData) hold off; end + % % % % % % % % - function plotLeaf(node, ~) + function plotLeaf(node, cellData) leafData = node.get(1); - xField = leafData.cycleAvg_x; + if ~isfield(leafData, 'cycleAvg_y') + yField = leafData.cycleAvgPSTH_y; + xField = leafData.cycleAvgPSTH_x; + else + yField = leafData.cycleAvg_y; + xField = leafData.cycleAvg_x; + end xvals = xField.value; - yField = leafData.cycleAvg_y; yvals = yField.value; plot (xvals,yvals); xlabel('Time (s)'); diff --git a/analysisTreeClasses/DriftingTextureAnalysis.m b/analysisTreeClasses/DriftingTextureAnalysis.m index 00341d7..57a05a4 100644 --- a/analysisTreeClasses/DriftingTextureAnalysis.m +++ b/analysisTreeClasses/DriftingTextureAnalysis.m @@ -108,13 +108,21 @@ function plot_textureAngleVsspikeCount_stimAfter500ms(node, cellData) polar([0 rootData.spikeCount_stimAfter500ms_OSang*pi/180], [0 (100*rootData.spikeCount_stimAfter500ms_OSI)], 'g-'); xlabel('TextureAngle'); ylabel(['spikeCount_stimAfter500ms (' yField(1).units ')']); - addDsiOsiVarTitle(rootData, 'spikeCount_stimAfter500ms') + title(['DSI = ' num2str(rootData.spikeCount_stimAfter500ms_DSI) ', DSang = ' num2str(rootData.spikeCount_stimAfter500ms_DSang) ... + ' and OSI = ' num2str(rootData.spikeCount_stimAfter500ms_OSI) ', OSang = ' num2str(rootData.spikeCount_stimAfter500ms_OSang)]); hold off; + + hold on + polar([0 rootData.spikeCount_stimAfter500ms_DSang*pi/180], [0 (100*rootData.spikeCount_stimAfter500ms_DSI)], 'r-'); + polar([0 rootData.spikeCount_stimAfter500ms_OSang*pi/180], [0 (100*rootData.spikeCount_stimAfter500ms_OSI)], 'g-'); + title(['DSI = ' num2str(rootData.spikeCount_stimAfter500ms_DSI) ', DSang = ' num2str(rootData.spikeCount_stimAfter500ms_DSang) ... + ' and OSI = ' num2str(rootData.spikeCount_stimAfter500ms_OSI) ', OSang = ' num2str(rootData.spikeCount_stimAfter500ms_OSang)]); + hold off end - function plot_textureAngleVsStimToEnd_avgTracePeak(node, cellData) + function plot_textureAngleVsCharge_stimInterval(node, cellData) rootData = node.get(1); xvals = rootData.textureAngle; yField = rootData.stimToEnd_avgTracePeak; @@ -127,8 +135,14 @@ function plot_textureAngleVsStimToEnd_avgTracePeak(node, cellData) polar([0 rootData.stimToEnd_avgTracePeak_DSang*pi/180], [0 (100*rootData.stimToEnd_avgTracePeak_DSI)], 'r-'); polar([0 rootData.stimToEnd_avgTracePeak_OSang*pi/180], [0 (100*rootData.stimToEnd_avgTracePeak_OSI)], 'g-'); xlabel('TextureAngle'); - ylabel(['stimToEnd_avgTracePeak (' yField.units ')']); - addDsiOsiVarTitle(rootData, 'stimToEnd_avgTracePeak') + ylabel(['spikeCount_stimAfter500ms (' yField.units ')']); + + hold on + polar([0 rootData.stimToEnd_avgTracePeak_DSang*pi/180], [0 (100*rootData.stimToEnd_avgTracePeak_DSI)], 'r-'); + polar([0 rootData.stimToEnd_avgTracePeak_OSang*pi/180], [0 (100*rootData.stimToEnd_avgTracePeak_OSI)], 'g-'); + + title(['DSI = ' num2str(rootData.stimToEnd_avgTracePeak_DSI) ', DSang = ' num2str(rootData.stimToEnd_avgTracePeak_DSang) ... + ' and OSI = ' num2str(rootData.stimToEnd_avgTracePeak_OSI) ', OSang = ' num2str(rootData.stimToEnd_avgTracePeak_OSang)]); hold off; end end diff --git a/analysisTreeClasses/IVAnalysis.m b/analysisTreeClasses/IVAnalysis.m index 84eb5ea..735f3fc 100644 --- a/analysisTreeClasses/IVAnalysis.m +++ b/analysisTreeClasses/IVAnalysis.m @@ -82,24 +82,69 @@ function plotMeanTraces(node, cellData) hold(ax, 'off'); end - function plot_holdSignalVsshortIntCurrent(node, cellData) + + function plot_holdSignalVsshortIntCurrent200_900(node, cellData) rootData = node.get(1); - xvals = rootData.holdSignal(2:end); + %xvals = rootData.holdSignal(2:end); + xvals = rootData.holdSignal; yField = rootData.shortInt200_peak; - yvals = yField.mean_c(2:end); - errs = yField.SEM(2:end); + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; + errorbar(xvals, yvals, errs,'DisplayName','current at 0.2s'); + hold on; + yField = rootData.shortInt900_peak; + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; + errorbar(xvals, yvals, errs,'DisplayName','current at 0.9s'); + xlabel('holdSignal'); + ylabel(['Current (' yField.units ')']); + title('I-V at 200ms (blue); at 900ms (red)'); + hold off + end + + function plot_holdSignalVsshortIntCurrent200_800(node, cellData) + rootData = node.get(1); + %xvals = rootData.holdSignal(2:end); + xvals = rootData.holdSignal; + yField = rootData.shortInt200_peak; + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; errorbar(xvals, yvals, errs,'DisplayName','current at 0.2s'); hold on; yField = rootData.shortInt800_peak; - yvals = yField.mean_c(2:end); - errs = yField.SEM(2:end); + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; errorbar(xvals, yvals, errs,'DisplayName','current at 0.8s'); xlabel('holdSignal'); ylabel(['Current (' yField.units ')']); title('I-V at 200ms (blue); at 800ms (red)'); + xvals' hold off end + function plot_holdSignalVsshortInt500_peak(node, cellData) + rootData = node.get(1); + xvals = rootData.holdSignal; + yField = rootData.shortInt500_peak; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('holdSignal'); + ylabel(['shortInt500_peak (' yField.units ')']); + end + end end \ No newline at end of file diff --git a/analysisTreeClasses/IVAnnulusAnalysis.m b/analysisTreeClasses/IVAnnulusAnalysis.m index 9ace477..a08d3c6 100644 --- a/analysisTreeClasses/IVAnnulusAnalysis.m +++ b/analysisTreeClasses/IVAnnulusAnalysis.m @@ -84,15 +84,76 @@ % function plot_holdSignalVsshortIntCurrent(node, cellData) rootData = node.get(1); - xvals = rootData.holdSignal(2:end); + xvals = rootData.holdSignal; %(2:end); +% yField = rootData.shortInt200_peak; +% yvals = yField.mean_c; %(2:end); +% errs = yField.SEM; %(2:end); +% errorbar(xvals, yvals, errs,'DisplayName','current at 0.2s'); + + yField = rootData.shortInt150_peak; + yvals = yField.mean_c; %(2:end); + errs = yField.SEM; %(2:end); + errorbar(xvals, yvals, errs,'DisplayName','current at 0.15s'); + + hold on; + + yField = rootData.shortInt400_peak; + yvals = yField.mean_c; %(2:end); + errs = yField.SEM; %(2:end); + errorbar(xvals, yvals, errs,'DisplayName','current at 0.4s'); + + yField = rootData.shortInt800_peak; + yvals = yField.mean_c; %(2:end); + errs = yField.SEM; %(2:end); + errorbar(xvals, yvals, errs,'DisplayName','current at 0.8s'); + xlabel('holdSignal'); + ylabel(['Current (' yField.units ')']); + %title('I-V at 200ms (red); at 800ms (blue)'); + title('I-V at 150ms (blue), 400ms (red), 800ms (orange)'); + hold off + end + + function plot_holdSignalVsshortIntCurrent200_900(node, cellData) + rootData = node.get(1); + %xvals = rootData.holdSignal(2:end); + xvals = rootData.holdSignal; yField = rootData.shortInt200_peak; - yvals = yField.mean_c(2:end); - errs = yField.SEM(2:end); + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; + errorbar(xvals, yvals, errs,'DisplayName','current at 0.2s'); + hold on; + yField = rootData.shortInt900_peak; + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; + errorbar(xvals, yvals, errs,'DisplayName','current at 0.9s'); + xlabel('holdSignal'); + ylabel(['Current (' yField.units ')']); + title('I-V at 200ms (blue); at 900ms (red)'); + xvals' + hold off + end + + function plot_holdSignalVsshortIntCurrent200_800(node, cellData) + rootData = node.get(1); + %xvals = rootData.holdSignal(2:end); + xvals = rootData.holdSignal; + yField = rootData.shortInt200_peak; + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; errorbar(xvals, yvals, errs,'DisplayName','current at 0.2s'); hold on; yField = rootData.shortInt800_peak; - yvals = yField.mean_c(2:end); - errs = yField.SEM(2:end); + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; + errorbar(xvals, yvals, errs,'DisplayName','current at 0.8s'); xlabel('holdSignal'); ylabel(['Current (' yField.units ')']); @@ -100,6 +161,30 @@ function plot_holdSignalVsshortIntCurrent(node, cellData) hold off end + function plot_holdSignalVsshortIntCurrent500_900(node, cellData) + rootData = node.get(1); + %xvals = rootData.holdSignal(2:end); + xvals = rootData.holdSignal; + yField = rootData.shortInt500_peak; + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; + errorbar(xvals, yvals, errs,'DisplayName','current at 0.5s'); + hold on; + yField = rootData.shortInt900_peak; + %yvals = yField.mean_c(2:end); + %errs = yField.SEM(2:end); + yvals = yField.mean_c; + errs = yField.SEM; + errorbar(xvals, yvals, errs,'DisplayName','current at 0.9s'); + xlabel('holdSignal'); + ylabel(['Current (' yField.units ')']); + title('I-V at 500ms (blue); at 900ms (red)'); + xvals' + hold off + end + end end \ No newline at end of file diff --git a/analysisTreeClasses/MovingBarAnalysis.m b/analysisTreeClasses/MovingBarAnalysis.m index bad1157..8192a3d 100755 --- a/analysisTreeClasses/MovingBarAnalysis.m +++ b/analysisTreeClasses/MovingBarAnalysis.m @@ -116,7 +116,8 @@ function plot_barAngleVsONSETspikes(node, cellData) polar([0 rootData.ONSETspikes_OSang*pi/180], [0 (100*rootData.ONSETspikes_OSI)], 'g-'); xlabel('barAngle'); ylabel(['ONSETspikes (' yField(1).units ')']); - addDsiOsiVarTitle(rootData, 'ONSETspikes') + title(['DSI = ' num2str(rootData.ONSETspikes_DSI) ', DSang = ' num2str(rootData.ONSETspikes_DSang) ... + ' and OSI = ' num2str(rootData.ONSETspikes_OSI) ', OSang = ' num2str(rootData.ONSETspikes_OSang)]); hold off; end @@ -132,7 +133,8 @@ function plot_barAngleVsONSET_avgTracePeak(node, cellData) polar([0 rootData.ONSET_avgTracePeak_OSang*pi/180], [0 (100*rootData.ONSET_avgTracePeak_OSI)], 'g-'); xlabel('barAngle'); ylabel(['ONSET_avgTracePeak (' yField.units ')']); - addDsiOsiVarTitle(rootData, 'ONSET_avgTracePeak') + title(['DSI = ' num2str(rootData.ONSET_avgTracePeak_DSI) ', DSang = ' num2str(rootData.ONSET_avgTracePeak_DSang) ... + ' and OSI = ' num2str(rootData.ONSET_avgTracePeak_OSI) ', OSang = ' num2str(rootData.ONSET_avgTracePeak_OSang)]); hold off; end @@ -148,7 +150,8 @@ function plot_barAngleVsspikeCount_stimToEnd(node, cellData) polar([0 rootData.spikeCount_stimToEnd_OSang*pi/180], [0 (100*rootData.spikeCount_stimToEnd_OSI)], 'g-'); xlabel('barAngle'); ylabel(['spikeCount_stimToEnd (' yField.units ')']); - addDsiOsiVarTitle(rootData, 'spikeCount_stimToEnd') + title(['DSI = ' num2str(rootData.spikeCount_stimToEnd_DSI) ', DSang = ' num2str(rootData.spikeCount_stimToEnd_DSang) ... + ' and OSI = ' num2str(rootData.spikeCount_stimToEnd_OSI) ', OSang = ' num2str(rootData.spikeCount_stimToEnd_OSang)]); hold off; end @@ -156,15 +159,15 @@ function plotMeanTraces(node, cellData) rootData = node.get(1); chInd = node.getchildren(1); L = length(chInd); - ax = gca; + ax = axes; for i=1:L + hold(ax, 'on'); epochInd = node.get(chInd(i)).epochID; if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') cellData.plotPSTH(epochInd, 10, rootData.deviceName, ax); else cellData.plotMeanData(epochInd, false, [], rootData.deviceName, ax); end - hold(ax, 'on'); end hold(ax, 'off'); end diff --git a/analysisTreeClasses/SpotsMultiSizeAnalysis.m b/analysisTreeClasses/SpotsMultiSizeAnalysis.m index 45e3901..1291f16 100755 --- a/analysisTreeClasses/SpotsMultiSizeAnalysis.m +++ b/analysisTreeClasses/SpotsMultiSizeAnalysis.m @@ -28,7 +28,7 @@ rootData = obj.get(1); leafIDs = obj.findleaves(); L = length(leafIDs); - baseline = zeros(1,L); %for grandBaseline subt. %Adam 2/13/17 + baseline = zeros(1,L); %for grandBaseline subt. Adam 2/17/13 %get grand mean for multi-peak fitting (with zero crossings) % if strcmp(rootData.(rootData.ampModeParam), 'Whole cell') @@ -72,7 +72,7 @@ 'FitPSTH', 0); outputStruct = getEpochResponseStats(outputStruct); curNode = mergeIntoNode(curNode, outputStruct); - baseline(i) = outputStruct.baselineRate.mean_c; %for grandBaseline subt. %Adam 2/13/17 + baseline(i) = outputStruct.baselineRate.mean_c; %for grandBaseline subt. Adam 2/17/13 else %whole cell outputStruct = getEpochResponses_WC(cellData, curNode.epochID, ... 'DeviceName', rootData.deviceName); @@ -87,14 +87,17 @@ obj = obj.percolateUp(leafIDs, ... 'splitValue', 'spotSize'); - %grand baseline subtraction %Adam 2/13/17 + %grand baseline subtraction Adam 2/17/13 if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') - %baseline subtraction + grandBaselineMean = mean(baseline); for i=1:L %for each leaf node curNode = obj.get(leafIDs(i)); + + tempStruct.spikeCount_ONSET_after200ms_grndBlSubt = curNode.spikeCount_ONSET_after200ms; + tempStruct.spikeCount_ONSET_after200ms_grndBlSubt.value = curNode.spikeCount_ONSET_after200ms.value - grandBaselineMean.*0.8; %assumes 1 sec stim interval tempStruct.spikeCount_stimInterval_grndBlSubt = curNode.spikeCount_stimInterval; tempStruct.spikeCount_stimInterval_grndBlSubt.value = curNode.spikeCount_stimInterval.value - grandBaselineMean; %assumes 1 sec stim interval tempStruct = getEpochResponseStats(tempStruct); @@ -102,8 +105,7 @@ curNode = mergeIntoNode(curNode, tempStruct); obj = obj.set(leafIDs(i), curNode); end - end - % % % % % + end [byEpochParamList, singleValParamList, collectedParamList] = getParameterListsByType(curNode); %fnames = fnames{1}; @@ -173,9 +175,6 @@ function plot0_spotSizeVsspikeCount_stimInterval(node, cellData) errorbar(xvals, yvals, errs); xlabel('spotSize'); ylabel(['spikeCount_stimInterval (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsONSETspikes(node, cellData) @@ -191,9 +190,6 @@ function plot_spotSizeVsONSETspikes(node, cellData) errorbar(xvals, yvals, errs); xlabel('spotSize'); ylabel(['ONSETspikes (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsOFFSETspikes(node, cellData) @@ -209,9 +205,6 @@ function plot_spotSizeVsOFFSETspikes(node, cellData) errorbar(xvals, yvals, errs); xlabel('spotSize'); ylabel(['OFFSETspikes (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsONSET_peak(node, cellData) rootData = node.get(1); @@ -226,9 +219,6 @@ function plot_spotSizeVsONSET_peak(node, cellData) errorbar(xvals, yvals, errs); xlabel('spotSize'); ylabel(['ONSET_peak (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsONSETsuppressedSpikes(node, cellData) @@ -239,9 +229,6 @@ function plot_spotSizeVsONSETsuppressedSpikes(node, cellData) plot(xvals, yvals, 'bx-'); xlabel('spotSize'); ylabel(['ONSETsuppressedSpikes (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsONSETsuppressionTime(node, cellData) @@ -252,9 +239,6 @@ function plot_spotSizeVsONSETsuppressionTime(node, cellData) plot(xvals, yvals, 'bx-'); xlabel('spotSize'); ylabel(['ONSETsuppressionTime (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plotEpochData(node, cellData, device, epochIndex) @@ -313,9 +297,6 @@ function plot_spotSizeVsONSET_FRhalfMaxLatency(node, cellData) plot(xvals, yvals, 'bx-'); xlabel('spotSize'); ylabel(['ONSET_FRhalfMaxLatency (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsONSET_FRmax(node, cellData) @@ -326,9 +307,6 @@ function plot_spotSizeVsONSET_FRmax(node, cellData) plot(xvals, yvals, 'bx-'); xlabel('spotSize'); ylabel(['ONSET_FRmax (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsstimInterval_charge(node, cellData) @@ -344,9 +322,6 @@ function plot_spotSizeVsstimInterval_charge(node, cellData) errorbar(xvals, yvals, errs); xlabel('spotSize'); ylabel(['stimInterval_charge (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsstimInterval_chargeNORM(node, cellData) @@ -369,9 +344,6 @@ function plot_spotSizeVsstimInterval_chargeNORM(node, cellData) errorbar(xvals, yvals, errs); xlabel('spotSize'); ylabel(['stimInterval_charge (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsONSET_avgTracePeak(node, cellData) @@ -410,6 +382,16 @@ function plot_spotSizeVsONSET_FRhalfMaxSusLatency(node, cellData) ylabel(['ONSET_FRhalfMaxSusLatency (' yField.units ')']); end + function plot_spotSizeVsONSET_FRhalfMaxSusLatency20(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSET_FRhalfMaxSusLatency20; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSET_FRhalfMaxSusLatency (' yField.units ')']); + end + function plot_spotSizeVsONSET_FRhalfMaxSusLatency_inXlimits(node, cellData) xRangeMin = 180; xRangeMax = 700; @@ -440,9 +422,6 @@ function plot_spotSizeVsONSETspikesNORM(node, cellData) errorbar(xvals, yvals, errs); xlabel('spotSize'); ylabel(['ONSETspikes (' yField.units ')']); - [~,i] = max(yvals); - bestSize = xvals(i); - title(sprintf('Pref Size: %g �m', bestSize)); end function plot_spotSizeVsONSETspikesNORM_inXlimits(node, cellData) @@ -553,7 +532,7 @@ function plot_spotSizeVsspikeCount_stimInt_gblSubt(node, cellData) ylabel(['spikeCount_stimInterval_granBaselineSubtracted (' yField.units ')']); end - function plot_spotSizeVsspikeCount_stimInt_gblSubtNORM(node, cellData) + function plot_spotSizeVsspikeCount_stimInt_gblSubtNORM(node, cellData) rootData = node.get(1); xvals = rootData.spotSize; yField = rootData.spikeCount_stimInterval_grndBlSubt; @@ -567,9 +546,25 @@ function plot_spotSizeVsspikeCount_stimInt_gblSubtNORM(node, cellData) yvals = yvals./M; errs = errs./M; errorbar(xvals, yvals, errs); - xlabel('Spot Size'); - ylabel(['spikeCount_stimInterval_granBaselineSubtracted_norm (' yField.units ')']); - end + xlabel('spotSize'); + ylabel(['spikeCount_stimInterval_granBaselineSubtracted (' yField.units ')']); + end + + function plot_spotSizeVsstimAfter200_charge(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.stimAfter200_charge; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['stimAfter200_charge (' yField.units ')']); + end + end end diff --git a/analysisTreeClasses/SpotsMultiSizeAnalysis_David.m b/analysisTreeClasses/SpotsMultiSizeAnalysis_David.m new file mode 100644 index 0000000..4d7d211 --- /dev/null +++ b/analysisTreeClasses/SpotsMultiSizeAnalysis_David.m @@ -0,0 +1,578 @@ +classdef SpotsMultiSizeAnalysis < AnalysisTree + properties + StartTime = 0; + EndTime = 1000; + end + + methods + function obj = SpotsMultiSizeAnalysis(cellData, dataSetName, params) + if nargin < 3 + params.deviceName = 'Amplifier_Ch1'; + end + if strcmp(params.deviceName, 'Amplifier_Ch1') + params.ampModeParam = 'ampMode'; + else + params.ampModeParam = 'amp2Mode'; + end + + nameStr = [cellData.savedFileName ': ' dataSetName ': SpotsMultiSizeAnalysis']; + obj = obj.setName(nameStr); + dataSet = cellData.savedDataSets(dataSetName); + obj = obj.copyAnalysisParams(params); + obj = obj.copyParamsFromSampleEpoch(cellData, dataSet, ... + {'RstarMean', 'RstarIntensity', params.ampModeParam, 'offsetX', 'offsetY'}); + obj = obj.buildCellTree(1, cellData, dataSet, {'curSpotSize'}); + end + + function obj = doAnalysis(obj, cellData) + rootData = obj.get(1); + leafIDs = obj.findleaves(); + L = length(leafIDs); + baseline = zeros(1,L); %for grandBaseline subt. %Adam 2/13/17 + + + %get grand mean for multi-peak fitting (with zero crossings) + % if strcmp(rootData.(rootData.ampModeParam), 'Whole cell') + % allEpochIDs = []; + % lowPassFreq = 10; + % + % for i=1:L %for each leaf node + % curNode = obj.get(leafIDs(i)); + % allEpochIDs = [allEpochIDs, curNode.epochID]; + % end + % [dataMean, xvals] = cellData.getMeanData(allEpochIDs, rootData.deviceName); + % + % %multiple peaks from zero crossings + % [zeroCrossings, directions] = findZeroCrossings(dataMean, xvals, obj.EndTime*1E-3, lowPassFreq, 1E-4); + % for i=1:length(zeroCrossings) + % + % + % end + % + % zeroCrossings = [zeroCrossings getThresCross(xvals, obj.EndTime*1E-3, 1)]; %add end time to get last peak; + % directions = [directions, 0]; + % zeroCrossings(1) = getThresCross(xvals, 0, 1); %replace first zero crossing with stim start + % zeroCrossings(2) = getThresCross(xvals, 0.14, 1); %temp hack + % + % Npeaks = length(zeroCrossings)-1; + % if Npeaks > 1 + % crossingParam = [zeroCrossings; directions] + % else + % crossingParam = []; + % end + % %keyboard; + % end + + + + for i=1:L %for each leaf node + curNode = obj.get(leafIDs(i)); + if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') + outputStruct = getEpochResponses_CA(cellData, curNode.epochID, ... + 'DeviceName', rootData.deviceName,'StartTime', obj.StartTime, 'EndTime', obj.EndTime, ... + 'FitPSTH', 0); + outputStruct = getEpochResponseStats(outputStruct); + curNode = mergeIntoNode(curNode, outputStruct); + baseline(i) = outputStruct.baselineRate.mean_c; %for grandBaseline subt. %Adam 2/13/17 + else %whole cell + outputStruct = getEpochResponses_WC(cellData, curNode.epochID, ... + 'DeviceName', rootData.deviceName); + %'ZeroCrossingPeaks', crossingParam); + outputStruct = getEpochResponseStats(outputStruct); + curNode = mergeIntoNode(curNode, outputStruct); + end + + obj = obj.set(leafIDs(i), curNode); + end + + obj = obj.percolateUp(leafIDs, ... + 'splitValue', 'spotSize'); + + %grand baseline subtraction %Adam 2/13/17 + if strcmp(rootData.(rootData.ampModeParam), 'Cell attached') + %baseline subtraction + + grandBaselineMean = mean(baseline); + for i=1:L %for each leaf node + curNode = obj.get(leafIDs(i)); + + tempStruct.spikeCount_stimInterval_grndBlSubt = curNode.spikeCount_stimInterval; + tempStruct.spikeCount_stimInterval_grndBlSubt.value = curNode.spikeCount_stimInterval.value - grandBaselineMean; %assumes 1 sec stim interval + tempStruct = getEpochResponseStats(tempStruct); + + curNode = mergeIntoNode(curNode, tempStruct); + obj = obj.set(leafIDs(i), curNode); + end + end + % % % % % + + [byEpochParamList, singleValParamList, collectedParamList] = getParameterListsByType(curNode); + %fnames = fnames{1}; + obj = obj.percolateUp(leafIDs, byEpochParamList, byEpochParamList); + obj = obj.percolateUp(leafIDs, singleValParamList, singleValParamList); + obj = obj.percolateUp(leafIDs, collectedParamList, collectedParamList); + + % %Meta-analysis parameters - curve fits, normalization, interpolation, etc + + % metaAnalysisParamList = { + % 'meanONenhancedSpikes'; + % 'meanOFFenhancedSpikes'; + % 'meanONpeakFR'; + % 'meanOFFpeakFR' + % }; + % + % numParamsMeta = length(metaAnalysisParamList); + % rootData = obj.get(1); + % spotSize = rootData.spotSize; + % for paramInd = 1:numParamsMeta + % paramName = metaAnalysisParamList{paramInd}; + % + % eval(['tempParamVariable = rootData.', paramName,';']); + % + % [maxVal, maxInd] = max(tempParamVariable); + % Xmax = spotSize(maxInd); + % infVal = mean(tempParamVariable(end-2: end)); %"asymptotic" value. + % YinfOverYmax = infVal/maxVal; + % + % halfMaxLeftInd = find(tempParamVariable > maxVal/2, 1, 'first'); + % halfMaxRightInd = find(tempParamVariable > maxVal/2, 1, 'last'); + % Xwidth = spotSize(halfMaxRightInd) - spotSize(halfMaxLeftInd); %This is a wrong metric, have to extrapolate. + % + % eval(['rootData.',paramName,'_Xmax = Xmax;']); + % eval(['rootData.',paramName,'_YinfOverYmax = YinfOverYmax;']); + % eval(['rootData.',paramName,'_Xwidth = Xwidth;']); + % end; + + %to add more here + rootData = obj.get(1); + rootData.byEpochParamList = byEpochParamList; + rootData.singleValParamList = singleValParamList; + rootData.collectedParamList = collectedParamList; + rootData.stimParameterList = {'spotSize'}; + obj = obj.set(1, rootData); + % % % + + end + + end + + + + + methods(Static) + + function plot0_spotSizeVsspikeCount_stimInterval(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.spikeCount_stimInterval; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['spikeCount_stimInterval (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsONSETspikes(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSETspikes; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['ONSETspikes (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsOFFSETspikes(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.OFFSETspikes; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['OFFSETspikes (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + function plot_spotSizeVsONSET_peak(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSET_peak; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['ONSET_peak (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsONSETsuppressedSpikes(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSETsuppressedSpikes; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSETsuppressedSpikes (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsONSETsuppressionTime(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSETsuppressionTime; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSETsuppressionTime (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plotEpochData(node, cellData, device, epochIndex) + nodeData = node.get(1); + cellData.epochs(nodeData.epochID(epochIndex)).plotData(device); + title(['Epoch # ' num2str(nodeData.epochID(epochIndex)) ': ' num2str(epochIndex) ' of ' num2str(length(nodeData.epochID))]); + if strcmp(device, 'Amplifier_Ch1') + spikesField = 'spikes_ch1'; + else + spikesField = 'spikes_ch2'; + end + spikeTimes = cellData.epochs(nodeData.epochID(epochIndex)).get(spikesField); + if ~isnan(spikeTimes) + [data, xvals] = cellData.epochs(nodeData.epochID(epochIndex)).getData(device); + hold('on'); + plot(xvals(spikeTimes), data(spikeTimes), 'rx'); + hold('off'); + end + + ONendTime = cellData.epochs(nodeData.epochID(epochIndex)).get('stimTime')*1E-3; %s + ONstartTime = 0; + if isfield(nodeData, 'ONSETlatency') && ~isnan(nodeData.ONSETlatency.value(1)) + %draw lines here + hold on + firingStart = node.get(1).ONSETlatency.value(epochIndex)+ONstartTime; + firingEnd = firingStart + node.get(1).ONSETrespDuration.value(epochIndex); + burstBound = firingStart + node.get(1).ONSETburstDuration.value(epochIndex); + upperLim = max(data)+50; + lowerLim = min(data)-50; + plot([firingStart firingStart], [upperLim lowerLim], 'LineStyle','--','Color',[1 0 0]); + plot([firingEnd firingEnd], [upperLim lowerLim], 'LineStyle','--','Color',[1 0 0]); + plot([burstBound burstBound], [upperLim lowerLim], 'LineStyle','--'); + hold off + end; + if isfield(nodeData, 'OFFSETlatency') && ~isnan(nodeData.OFFSETlatency.value(1)) + %draw lines here + hold on + firingStart = node.get(1).OFFSETlatency.value(epochIndex)+ONendTime; + firingEnd = firingStart + node.get(1).OFFSETrespDuration.value(epochIndex); + burstBound = firingStart + node.get(1).OFFSETburstDuration.value(epochIndex); + upperLim = max(data)+50; + lowerLim = min(data)-50; + plot([firingStart firingStart], [upperLim lowerLim], 'LineStyle','--','Color',[1 0 0]); + plot([firingEnd firingEnd], [upperLim lowerLim], 'LineStyle','--','Color',[1 0 0]); + plot([burstBound burstBound], [upperLim lowerLim], 'LineStyle','--'); + hold off + end + + end + + function plot_spotSizeVsONSET_FRhalfMaxLatency(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSET_FRhalfMaxLatency; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSET_FRhalfMaxLatency (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsONSET_FRmax(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSET_FRmax; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSET_FRmax (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsstimInterval_charge(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.stimInterval_charge; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['stimInterval_charge (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsstimInterval_chargeNORM(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.stimInterval_charge; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + [M, Mind] = max(abs(yvals)); + if yvals(Mind) < 0 + yvals = -yvals./M; + else + yvals = yvals./M; + end; + errs = errs./M; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['stimInterval_charge (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsONSET_avgTracePeak(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSET_avgTracePeak; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSET_avgTracePeak (' yField.units ')']); + end + + function plot_spotSizeVsspikeCount_stimInterval_baselineSubtracted(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.spikeCount_stimInterval_baselineSubtracted; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['spikeCount_stimInterval_baselineSubtracted (' yField.units ')']); + end + +%%<<<<<<< Updated upstream + function plot_spotSizeVsONSET_FRhalfMaxSusLatency(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSET_FRhalfMaxSusLatency; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSET_FRhalfMaxSusLatency (' yField.units ')']); + end + + function plot_spotSizeVsONSET_FRhalfMaxSusLatency_inXlimits(node, cellData) + xRangeMin = 180; + xRangeMax = 700; + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSET_FRhalfMaxSusLatency; + yvals = yField.value; + xvalsNew = xvals((xvals>=xRangeMin)&(xvals<=xRangeMax)); + yvalsNew = yvals((xvals>=xRangeMin)&(xvals<=xRangeMax)); + plot(xvalsNew, yvalsNew, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSET_FRhalfMaxSusLatency (' yField.units ')']); + end + + function plot_spotSizeVsONSETspikesNORM(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSETspikes; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + M = max(abs(yvals)); + yvals = yvals./M; + errs = errs./M; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['ONSETspikes (' yField.units ')']); + [~,i] = max(yvals); + bestSize = xvals(i); + title(sprintf('Pref Size: %g �m', bestSize)); + end + + function plot_spotSizeVsONSETspikesNORM_inXlimits(node, cellData) + xRangeMin = 180; + xRangeMax = 700; + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.ONSETspikes; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + M = max(abs(yvals)); + yvals = yvals./M; + errs = errs./M; + xvalsNew = xvals((xvals>=xRangeMin)&(xvals<=xRangeMax)); + yvalsNew = yvals((xvals>=xRangeMin)&(xvals<=xRangeMax)); + errsNew = errs((xvals>=xRangeMin)&(xvals<=xRangeMax)); + errorbar(xvalsNew, yvalsNew, errsNew); + xlabel('spotSize'); + ylabel(['ONSETspikes (' yField.units ')']); + end + + function plot_spotSizeVsstimToEnd_respIntervalT25(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.stimToEnd_respIntervalT25; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['ONSET_respIntervalT25 (' yField.units ')']); + end + + function plot_spotSizeVsstimToEnd_respIntervalT50(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.stimToEnd_respIntervalT50; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['stimToEnd_respIntervalT50 (' yField.units ')']); + end + + function plot_spotSizeVsstimToEnd_avgTrace_latencyToT50(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.stimToEnd_avgTrace_latencyToT50; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['stimToEnd_avgTrace_latencyToT50 (' yField.units ')']); + end + + function plot_spotSizeVsstimToEnd_avgTrace_latencyToT25(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.stimToEnd_avgTrace_latencyToT25; + yvals = yField.value; + plot(xvals, yvals, 'bx-'); + xlabel('spotSize'); + ylabel(['stimToEnd_avgTrace_latencyToT25 (' yField.units ')']); + end + + function plot_spotSizeVsspikeCount_stimTo200ms(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.spikeCount_stimTo200ms; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['spikeCount_stimTo200ms (' yField.units ')']); + end + + function plot_spotSizeVsspikeCount_stimAfter200ms(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.spikeCount_stimAfter200ms; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['spikeCount_stimAfter200ms (' yField.units ')']); + end + + function plot_spotSizeVsspikeCount_stimInt_gblSubt(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.spikeCount_stimInterval_grndBlSubt; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + errorbar(xvals, yvals, errs); + xlabel('spotSize'); + ylabel(['spikeCount_stimInterval_granBaselineSubtracted (' yField.units ')']); + end + + function plot_spotSizeVsspikeCount_stimInt_gblSubtNORM(node, cellData) + rootData = node.get(1); + xvals = rootData.spotSize; + yField = rootData.spikeCount_stimInterval_grndBlSubt; + if strcmp(yField.units, 's') + yvals = yField.median_c; + else + yvals = yField.mean_c; + end + errs = yField.SEM; + M = max(abs(yvals)); + yvals = yvals./M; + errs = errs./M; + errorbar(xvals, yvals, errs); + xlabel('Spot Size'); + ylabel(['spikeCount_stimInterval_granBaselineSubtracted_norm (' yField.units ')']); + end + + + end + +end diff --git a/analysisTreeClasses/TextureMatrixAnalysis.m b/analysisTreeClasses/TextureMatrixAnalysis.m index 8b477b0..c3867fb 100755 --- a/analysisTreeClasses/TextureMatrixAnalysis.m +++ b/analysisTreeClasses/TextureMatrixAnalysis.m @@ -498,6 +498,100 @@ function plotMeanData_stimToEnd_gblSubt(node, cellData) hold('off'); end + % % % WC plotter % % % + + + function plotAllData_charge(node, cellData) + seedChildren = node.getchildren(childrenByValue(node, 1, 'name', 'Across blur tree')); + % c = ['b', 'r', 'g', 'k', 'm']; + for i=1:length(seedChildren) %i=[1,4] + curNode = node.get(seedChildren(i)); + xvals = curNode.pixelBlur; + % yvals = curNode.overEpochs_ONSETspikes.mean_c; + % yerrs = curNode.overEpochs_ONSETspikes.SEM; + yvals = curNode.overEpochs_stimInterval_charge.mean_c; + yerrs = curNode.overEpochs_stimInterval_charge.SEM; + %plot(xvals, yvals, [c(mod(i,5)+1) 'o']); + errorbar(xvals, yvals, yerrs,'b','marker','o','LineStyle','none'); %,'LineStyle','none' + % errorbar(node.get(seedChildren(i)).pixelBlurVals, node.get(seedChildren(i)).respMean_blur, node.get(seedChildren(i)).respSEM_blur, ... + % [c(mod(i,5)+1) 'o-']); + hold('on'); + end + blurRootData = node.get(childrenByValue(node, 1, 'name', 'Across seed tree')); + % yMean = blurRootData.ONSETspikes.mean_c;` + % yMeanErr = blurRootData.ONSETspikes.SEM_c; + yMean = blurRootData.stimInterval_charge.mean_c; + yMeanErr = blurRootData.stimInterval_charge.SEM_c; + errorbar(xvals, yMean, yMeanErr,'r'); + xlabel('Pixel blur'); + ylabel('stimIntervalCharge'); + hold('off'); + end + + function plotMeanData_chargeNORM(node, cellData) + blurRootData = node.get(childrenByValue(node, 1, 'name', 'Across seed tree')); + xvals = blurRootData.pixelBlur; + yMean = blurRootData.stimInterval_charge.mean_c; + yMeanErr = blurRootData.stimInterval_charge.SEM_c; + [M, Mind] = max(abs(yMean)); + if yMean(Mind) < 0 + yMean = -yMean./M; + else + yMean = yMean./M; + end; + yMeanErr = yMeanErr./M; + errorbar(xvals, yMean, yMeanErr,'r'); + xlabel('Pixel blur'); + ylabel('stimIntervalCharge (norm)'); + hold('off'); + end + + function plotAllData_stimToEndCharge(node, cellData) + seedChildren = node.getchildren(childrenByValue(node, 1, 'name', 'Across blur tree')); + % c = ['b', 'r', 'g', 'k', 'm']; + for i=1:length(seedChildren) %i=[1,4] + curNode = node.get(seedChildren(i)); + xvals = curNode.pixelBlur; + % yvals = curNode.overEpochs_ONSETspikes.mean_c; + % yerrs = curNode.overEpochs_ONSETspikes.SEM; + yvals = curNode.overEpochs_stimToEnd_charge.mean_c; + yerrs = curNode.overEpochs_stimToEnd_charge.SEM; + %plot(xvals, yvals, [c(mod(i,5)+1) 'o']); + errorbar(xvals, yvals, yerrs,'b','marker','o','LineStyle','none'); %,'LineStyle','none' + % errorbar(node.get(seedChildren(i)).pixelBlurVals, node.get(seedChildren(i)).respMean_blur, node.get(seedChildren(i)).respSEM_blur, ... + % [c(mod(i,5)+1) 'o-']); + hold('on'); + end + blurRootData = node.get(childrenByValue(node, 1, 'name', 'Across seed tree')); + % yMean = blurRootData.ONSETspikes.mean_c;` + % yMeanErr = blurRootData.ONSETspikes.SEM_c; + yMean = blurRootData.stimToEnd_charge.mean_c; + yMeanErr = blurRootData.stimToEnd_charge.SEM_c; + errorbar(xvals, yMean, yMeanErr,'r'); + xlabel('Pixel blur'); + ylabel('stimtoEndCharge'); + hold('off'); + end + + function plotMeanData_stimToEndChargeNORM(node, cellData) + blurRootData = node.get(childrenByValue(node, 1, 'name', 'Across seed tree')); + xvals = blurRootData.pixelBlur; + yMean = blurRootData.stimToEnd_charge.mean_c; + yMeanErr = blurRootData.stimToEnd_charge.SEM_c; + [M, Mind] = max(abs(yMean)); + if yMean(Mind) < 0 + yMean = -yMean./M; + else + yMean = yMean./M; + end; + yMeanErr = yMeanErr./M; + errorbar(xvals, yMean, yMeanErr,'r'); + xlabel('Pixel blur'); + ylabel('stimtoEndCharge (norm)'); + hold('off'); + end + + end end \ No newline at end of file diff --git a/autodata/autoData2.m b/autodata/autoData2.m deleted file mode 100644 index ff2f9ed..0000000 --- a/autodata/autoData2.m +++ /dev/null @@ -1,212 +0,0 @@ -% dataExtractionGeneral -global PREFERENCE_FILES_FOLDER -global CELL_DATA_FOLDER; -fid = fopen([PREFERENCE_FILES_FOLDER 'DataSetAnalyses.txt'], 'r'); -analysisTable = textscan(fid, '%s\t%s'); -fclose(fid); - -%% load cell list - -f = fopen(cellNamesListLocation,'r'); -cellFileNames = textscan(f,'%s'); -cellFileNames = cellFileNames{1}; -fclose(f); - - -%% make full table -dtab_add = table(); -numTableCells = length(cellFileNames); - -%% loop through cells - -for ci = 1:numTableCells - - fprintf('Processing cell %g of %g\n', ci, numTableCells); - % make table row - trow = table(); - - % make a list of which analyses have been added validly to avoid overwriting earlier - validAnalyses = false(numAnalyses,1); - - %how many cell data in this cell? - cellNamesInThisCell = cellFileNames{ci}; - cellNamesInThisCell = strsplit(cellNamesInThisCell, ','); - - for sci = 1:length(cellNamesInThisCell) - - c = load([CELL_DATA_FOLDER cellNamesInThisCell{sci} '.mat']); %load cellData - cellData = c.cellData; - - % add basic info from cellData - if sci == 1 % only use first file for this data - loc = cellData.location; - if ~isempty(loc) - trow{1, {'location_x', 'location_y', 'eye'}} = loc; - else - trow{1, {'location_x', 'location_y', 'eye'}} = [nan, nan, nan]; - end - typ = cellData.cellType; - trow{1, 'cellType'} = {typ}; - - tags = cellData.tags; - if isKey(tags, 'QualityRating') - qr = str2double(tags('QualityRating')); - else - qr = nan; - end - trow{1, 'QualityRating'} = qr; - end - - - % loop through filters - - for ai = 1:numAnalyses - - % check if another cellData for this cell has already given this analysis - if validAnalyses(ai) - continue - end - - analysis = analyses(ai,:); - - atree = doSingleAnalysis(cellNamesInThisCell{sci}, analysis{1,'analysisType'}{1}, [], analysis{1,'epochFilt'}, cellData, analysisTable); - hasValidAnalysis = ~isempty(atree); - - paramsColumnNames = analysis{1,'columnNames'}{1}; - params = analysis{1,'params'}{1}; - treeVariableMode = analysis{1,'treeVariableMode'}; - - if treeVariableMode == 1 - if hasValidAnalysis - [~, ~, paramForCells] = allParamsAcrossCells(atree, params); - paramForCells(cellfun(@isempty, paramForCells)) = {nan}; - data = paramForCells'; - data = cell2mat(data); - if size(data,1) > 1 % sometimes the filter catches two data sets... so pick the first one - data = data(1,:); - end - else - data = nan*zeros(1, length(paramsColumnNames)); - end - - elseif treeVariableMode == 0 - if hasValidAnalysis - data = extractVectorOverSplitParamFromSingleCellTree(atree, params); - else - data = cell(1, length(paramsColumnNames)); - end - - elseif treeVariableMode == 2 - if hasValidAnalysis - data = extractLightStepParamsFromTree(atree, false); - if ~isempty(data) - data = data(1,3); - end - else - data = cell(1, length(paramsColumnNames)); - end - - end - - trow{1,paramsColumnNames} = data; - validAnalyses(ai) = hasValidAnalysis; - end - end - - - %% combine table row - dtab_add(cellNamesInThisCell{1}, trow.Properties.VariableNames) = trow; - - -end - -%% Load external data table for non-automated analyses -tic -if ~isempty(externalTableFilename) - load(externalTableFilename); - origTableVars = dtab_add.Properties.VariableNames; - warning('off','MATLAB:table:RowsAddedNewVars') - for rowIndex = 1:size(dtab_add,1) - cellName = dtab_add.Properties.RowNames{rowIndex}; - - % find if the external cell is not already present in the table so we can fill in nans - % have to put in nan for the missing values because otherwise it'll get filled with 0 - if ismember(cellName, externalCellDataTable.Properties.RowNames) - externalRow = externalCellDataTable(cellName,:); - dtab_add(cellName, externalRow.Properties.VariableNames) = externalRow(1,:); - else - a = width(externalCellDataTable(1,:)); - dtab_add(cellName, externalCellDataTable.Properties.VariableNames) = num2cell(nan(1,a)); - end - -% if ~ismember(cellName, externalCellDataTable.Properties.RowNames) -% for vi = 1:length(origTableVars) -% varName = origTableVars{vi}; -% -% if strcmp(varName, 'cellType') -% externalRow{cellName, varName} = {''}; -% elseif isempty(strfind(varName, 'SMS')) && isempty(strfind(varName, 'Contrast')) && isempty(strfind(varName, 'params')) -% externalRow(cellName, varName) = {nan}; -% end -% end -% end - - end - - % clear empties -% numericalVarColumns = externalCellDataTable.Properties.VariableNames; -% for tableRow = 1:size(dtab_add,1) -% d = dtab_add{tableRow, numericalVarColumns}; -% if all(d == 0) -% dtab_add(tableRow, numericalVarColumns) = num2cell(nan*zeros(1,length(numericalVarColumns))); -% end -% end - - % - - disp('Loaded external data table') - toc -end - -%% combine Additional rows with current table -if exist('dtab','var') - for rowIndex = 1:size(dtab_add,1) - cellName = dtab_add.Properties.RowNames{rowIndex}; - addRow = dtab_add(cellName,:); - addTableVars = addRow.Properties.VariableNames; - -% for vi = 1:length(addTableVars) -% varName = addTableVars{vi} -% -% if strcmp(varName, 'cellType') -% -% elseif isempty(strfind(varName, 'SMS')) && isempty(strfind(varName, 'Contrast')) && isempty(strfind(varName, 'params')) -% addRow(cellName, varName) = {nan}; -% end -% end - - - dtab(cellName, addRow.Properties.VariableNames) = addRow(1,:); - end -else - dtab = dtab_add; -end - -%% process full table - -% generate cell select map -% valid = ~cellfun(@isempty, dtab.cellType); -[cellTypes, ia, ic] = unique(dtab.cellType); -cellTypeSelect = containers.Map; -for i = 1:length(cellTypes) - cellTypeSelect(cellTypes{i}) = ic == i; -end -numCells = size(dtab, 1); -cellNames = dtab.Properties.RowNames; - -if ~isempty(outputSaveFilename) - save(outputSaveFilename, 'dtab','cellNames','numCells','cellTypeSelect'); - fprintf('saved data to %s \n', outputSaveFilename); -end - -fprintf('done processing %g cells\nhave a nice day!\n', numCells) \ No newline at end of file diff --git a/autodata/autoData2_setup.m b/autodata/autoData2_setup.m deleted file mode 100644 index 1c8d967..0000000 --- a/autodata/autoData2_setup.m +++ /dev/null @@ -1,91 +0,0 @@ -global ANALYSIS_FOLDER; -cellNamesListLocation = [ANALYSIS_FOLDER 'Projects' filesep 'UltraLowDef/cellNames.txt']; - -% set this to [] if no external table -externalTableFilename = 'analysisTrees/automaticData/externalCellDataTable'; - -% output save location, set to [] to not save -outputSaveFilename = 'analysisTrees/automaticData/autodata'; - -%% load filter/analysis list -filterFileNames = {'analysisTrees/automaticData/filter light step CA.mat'; - 'analysisTrees/automaticData/filter sms CA.mat'; - 'analysisTrees/automaticData/filter drifting texture CA.mat'; - 'analysisTrees/automaticData/filter drifting gratings CA.mat'; - 'analysisTrees/automaticData/filter sms WC -60.mat'; - 'analysisTrees/automaticData/filter sms WC 20.mat'; - 'analysisTrees/automaticData/filter moving bar 1000 narrow CA.mat'; - 'analysisTrees/automaticData/filter moving bar 500 narrow CA.mat'; - 'analysisTrees/automaticData/filter moving bar 250 narrow CA.mat'; - 'analysisTrees/automaticData/filter light step WC -60.mat'; - 'analysisTrees/automaticData/filter light step WC 20.mat'; - 'analysisTrees/automaticData/filter contrast CA.mat'; - }; - -% 1 for single params (Light step on spike count mean), 0 for vectors (spike count by spot size), 2 for extracting params for a curve -treeVariableModes = [1,0,1,1,0,0,1,1,1,2,2,0]; - -paramsByTree = {{'ONSETspikes_mean', 'OFFSETspikes_mean'}; - {'ONSETspikes','OFFSETspikes','ONSETrespDuration'}; - {'spikeCount_stimAfter500ms_mean','spikeCount_stimAfter500ms_DSI', 'spikeCount_stimAfter500ms_DSang','spikeCount_stimAfter500ms_OSI', 'spikeCount_stimAfter500ms_OSang', 'spikeCount_stimAfter500ms_DVar'}; - {'F1amplitude_mean','F1amplitude_DSI','F1amplitude_DSang','F1amplitude_OSI','F1amplitude_OSang','F1amplitude_DVar'} - {'stimInterval_charge','ONSET_peak'}; - {'stimInterval_charge','ONSET_peak'}; - {'spikeCount_stimInterval_mean','spikeCount_stimInterval_DSI', 'spikeCount_stimInterval_DSang','spikeCount_stimInterval_OSI', 'spikeCount_stimInterval_OSang', 'spikeCount_stimInterval_DVar'}; - {'spikeCount_stimInterval_mean','spikeCount_stimInterval_DSI', 'spikeCount_stimInterval_DSang','spikeCount_stimInterval_OSI', 'spikeCount_stimInterval_OSang', 'spikeCount_stimInterval_DVar'}; - {'spikeCount_stimInterval_mean','spikeCount_stimInterval_DSI', 'spikeCount_stimInterval_DSang','spikeCount_stimInterval_OSI', 'spikeCount_stimInterval_OSang', 'spikeCount_stimInterval_DVar'}; - {'params'}; - {'params'}; - {'ONSETspikes','ONSETlatency'};}; -paramsColumnNames = {{'LS_ON_sp','LS_OFF_sp'}; - {'SMS_spotSize_sp','SMS_onSpikes','SMS_offSpikes','SMS_onDuration'}; - {'DrifTex_mean_sp','DrifTex_DSI_sp','DrifTex_DSang_sp','DrifTex_OSI_sp','DrifTex_OSang_sp','DrifTex_DVar_sp'}; - {'DrifGrat_mean_sp','DrifGrat_DSI_sp','DrifGrat_DSang_sp','DrifGrat_OSI_sp','DrifGrat_OSang_sp','DrifGrat_DVar_sp'}; - {'SMS_spotSize_ex','SMS_charge_ex','SMS_peak_ex'}; - {'SMS_spotSize_in','SMS_charge_in','SMS_peak_in'}; - {'MB_1000_mean_sp','MB_1000_DSI_sp','MB_1000_DSang_sp','MB_1000_OSI_sp','MB_1000_OSang_sp','MB_1000_DVar_sp'}; - {'MB_500_mean_sp','MB_500_DSI_sp','MB_500_DSang_sp','MB_500_OSI_sp','MB_500_OSang_sp','MB_500_DVar_sp'}; - {'MB_250_mean_sp','MB_250_DSI_sp','MB_250_DSang_sp','MB_250_OSI_sp','MB_250_OSang_sp','MB_250_DVar_sp'}; - {'LS_ON_params_ex'}; - {'LS_ON_params_in'}; - {'Contrast_contrastVal_sp','Contrast_onSpikes','Contrast_onLatency'};}; -%% -analyses = table(); -for fi = 1:length(filterFileNames) - fname = filterFileNames{fi}; - load(fname, 'filterData','filterPatternString','analysisType'); - analyses{fi,'filterFileName'} = {fname}; - analyses{fi,'analysisType'} = {analysisType}; - - epochFilt = SearchQuery(); - for i=1:size(filterData,1) - if ~isempty(filterData{i,1}) - epochFilt.fieldnames{i} = filterData{i,1}; - epochFilt.operators{i} = filterData{i,2}; - - value_str = filterData{i,3}; - if isempty(value_str) - value = []; - elseif strfind(value_str, ',') - z = 1; - r = value_str; - while ~isempty(r) - [token, r] = strtok(r, ','); - value{z} = strtrim(token); - z=z+1; - end - else - value = str2num(value_str); %#ok - end - - epochFilt.values{i} = value; - end - end - epochFilt.pattern = filterPatternString; - analyses{fi,'epochFilt'} = epochFilt; -end - -analyses.treeVariableMode = treeVariableModes'; -analyses.params = paramsByTree; -analyses.columnNames = paramsColumnNames; -numAnalyses = size(analyses, 1); \ No newline at end of file diff --git a/autodata/autoData_secondary.m b/autodata/autoData_secondary.m deleted file mode 100644 index 6c91c6c..0000000 --- a/autodata/autoData_secondary.m +++ /dev/null @@ -1,53 +0,0 @@ -%% Secondary analysis - - -%% SMS peak and tail -for ci = 1:size(dtab,1) - spotSize = dtab{ci, 'SMS_spotSize_sp'}{1}; - if ~isempty(spotSize) - onspikes = dtab{ci, 'SMS_onSpikes'}{1}; - offspikes = dtab{ci, 'SMS_offSpikes'}{1}; - [m, mi] = max(onspikes); - peakValueOn(ci) = m; - peakSizeOn(ci) = spotSize(mi); - tailSpikesOn(ci) = mean(onspikes(spotSize > 550)); - [m, mi] = max(offspikes); - peakValueOff(ci) = m; - peakSizeOff(ci) = spotSize(mi); - tailSpikesOff(ci) = mean(offspikes(spotSize > 550)); - else - peakValueOn(ci) = nan; - peakSizeOn(ci) = nan; - tailSpikesOn(ci) = nan; - end -end - -dtab{:,'SMS_onSpikes_prefSize'} = peakSizeOn'; -dtab{:,'SMS_onSpikes_peakSpikes'} = peakValueOn'; -dtab{:,'SMS_onSpikes_tailSpikes'} = tailSpikesOn'; -dtab{:,'SMS_offSpikes_prefSize'} = peakSizeOff'; -dtab{:,'SMS_offSpikes_peakSpikes'} = peakValueOff'; -dtab{:,'SMS_offSpikes_tailSpikes'} = tailSpikesOff'; - -%% Best DS - -src = {'DrifTex_DSI_sp','DrifGrat_DSI_sp','MB_1000_DSI_sp','MB_500_DSI_sp','MB_250_DSI_sp'}; -ang = {'DrifTex_DSang_sp','DrifGrat_DSang_sp','MB_1000_DSang_sp','MB_500_DSang_sp','MB_250_DSang_sp'}; -for ci = 1:numCells - dsis = dtab{ci, src}; - angs = dtab{ci, ang}; - [m, i] = max(dsis); - dtab{ci,'best_DSI_sp'} = m; - dtab{ci,'best_DSang_sp'} = angs(i); - dtab{ci,'best_source'} = {src(i)}; -end - -%% Autocenter offset - -diffX = dtab.spatial_ex_centerX - dtab.spatial_in_centerX; -diffY = dtab.spatial_ex_centerY - dtab.spatial_in_centerY; -avgSigma = mean(dtab{:,{'spatial_in_sigma2X','spatial_ex_sigma2X','spatial_in_sigma2Y','spatial_ex_sigma2Y'}}, 2); -autocenterOffsetDistance = sqrt(diffX.^2 + diffY.^2); -autocenterOffsetDistanceNormalized = autocenterOffsetDistance ./ avgSigma; -autocenterOffsetDirections = angle(diffX + sqrt(-1) * diffY); -dtab.spatial_exin_offset = autocenterOffsetDistance .* exp(sqrt(-1) * autocenterOffsetDirections); \ No newline at end of file diff --git a/autodata/extractLightStepParamsFromTree.m b/autodata/extractLightStepParamsFromTree.m deleted file mode 100644 index 736c49b..0000000 --- a/autodata/extractLightStepParamsFromTree.m +++ /dev/null @@ -1,112 +0,0 @@ -function output = extractLightStepParamsFromTree(analysisTree, justGetCellNames) - - nodes = analysisTree.Node; - - %% Extraction code - - global CELL_DATA_FOLDER; - - output = {}; - - for ni = 1:length(nodes) - - node = nodes{ni}; - if isfield(node, 'cellName') - cellName = node.cellName; - li = analysisTree.getchildren(ni); - eids = nodes{li}.epochID; - load(fullfile(CELL_DATA_FOLDER, [cellName, '.mat'])) - data = []; - stimTime = nan; - for eid = eids - epoc = cellData.epochs(eid); - if isnan(stimTime) || stimTime == epoc.get('stimTime') - data(end+1,:) = epoc.getData('Amplifier_Ch1'); - stimTime = epoc.get('stimTime'); - end - end - mn = mean(data, 1); - output(end+1, :) = {cellName, mn, epoc.get('ampHoldSignal')}; - end - end - - if justGetCellNames - return - end - - - %% Fitting code - sim_timeStep = 0.005; - for ci = 1:size(output, 1) - stepResponse = output{ci,2}; - voltage = output{ci,3}; - - preTimeSec = cellData.epochs(eid).get('preTime') / 1000; - stepResponse = stepResponse - mean(stepResponse(1:(preTimeSec * 10000))); - stepResponse = stepResponse(1:10000 * 1.5); - stepResponse = stepResponse ./ prctile(abs(stepResponse), 99.5); - stepResponse = stepResponse ./ sign(voltage); - stepResponse = stepResponse(preTimeSec * 10000 : end); - r = resample(stepResponse, round(1/sim_timeStep), 10000); - r = reshape(r,length(r),1); - - % delay, rise dur, hold dur, decay time constant, baseline to peak ratio - x0 = [.05, .1, .02, .2, 0]; - w = 15.^(linspace(1,0,length(r)))'; - fToMin = @(p) mean(w .* power(abs(makeParametricResponse(p, sim_timeStep, length(r)) - r), 2)); - - % plot(makeParametricResponse(x0, sim_timeStep, length(r))) - - - % fitData = {}; - % for fi = 1:20 - % p = rand(1,5)/10 + x0; - - p = x0; - for li = 1:10 - [p, ~] = fminsearch(fToMin, p); - end - % fitData(fi,:) = {f, p}; - % end - % - % [~, bestFit] = max(cell2mat(fitData(:,1))); - % p = fitData{bestFit,2}; - - - fit = makeParametricResponse(p, sim_timeStep, length(r)); - mn = mean(r) * ones(size(fit)); - - % check the fit quality - r2 = 1 - sum((r - fit).^2)/sum((r - mn).^2); - if r2 < 0.7 - p = nan*zeros(1,6); - else - p = [sign(voltage), p]; - end - - output{ci, 3} = p; - -% figure(10);clf; -% hold on -% plot(r) -% plot(fit) -% hold off -% legend('signal','initial','final') -% title(sprintf('%g',r2*100)) -% drawnow -% pause - end -end - -function d = makeParametricResponse(p, sim_timeStep, len) - - delay = zeros(1, round(p(1) / sim_timeStep)); - rise = linspace(0, 1, round(p(2) / sim_timeStep)); - holds = ones(1, round(p(3) / sim_timeStep)); - decay = (1-p(5))*exp(-1 * (sim_timeStep:sim_timeStep:10) / p(4)) + p(5); - - sig = horzcat(delay, rise, holds, decay); -% d = diff(sig); - d = sig(1:len)'; - -end \ No newline at end of file diff --git a/autodata/wfds_dataExtraction.m b/autodata/wfds_dataExtraction.m deleted file mode 100644 index aaaec65..0000000 --- a/autodata/wfds_dataExtraction.m +++ /dev/null @@ -1,298 +0,0 @@ -%% Cell data summary processing script -% Script loads analysis trees and compiles all the results into a table -% -% This table can be used easily and flexibly to make analysis and comparisons -% -% Make the file for loading and processing in the LabDataGui -% -% Edit and run this code segment, then use the button in the bottom right -% corner of the LabDataGUI to open the filterFileNames file - -filterFileNames = {'analysisTrees/automaticData/filter light step CA.mat'; - 'analysisTrees/automaticData/filter sms CA.mat'; - 'analysisTrees/automaticData/filter drifting texture CA.mat'; - 'analysisTrees/automaticData/filter drifting gratings CA.mat'; - 'analysisTrees/automaticData/filter sms WC -60.mat'; - 'analysisTrees/automaticData/filter sms WC 20.mat'; - 'analysisTrees/automaticData/filter moving bar 1000 narrow CA.mat'; - 'analysisTrees/automaticData/filter moving bar 500 narrow CA.mat'; - 'analysisTrees/automaticData/filter moving bar 250 narrow CA.mat'; - 'analysisTrees/automaticData/filter light step WC -60.mat'; - 'analysisTrees/automaticData/filter light step WC 20.mat'; - 'analysisTrees/automaticData/filter contrast CA.mat'; - }; - - -save('analysisTrees/automaticData/filterFileNames', 'filterFileNames'); -%% Accumulate all parameters -% Modify the cellNameReplacements variable to compensate for joined cells. Not -% pretty, but it works. - -treeVariableModes = [1,0,1,1,0,0,1,1,1,2,2,0]; % 1 for single params (Light step on spike count mean), 0 for vectors (spike count by spot size), 2 for extracting params for a curve -paramsByTree = {{'ONSETspikes_mean', 'OFFSETspikes_mean'}; - {'ONSETspikes','OFFSETspikes','ONSETrespDuration'}; - {'spikeCount_stimAfter500ms_mean','spikeCount_stimAfter500ms_DSI', 'spikeCount_stimAfter500ms_DSang','spikeCount_stimAfter500ms_OSI', 'spikeCount_stimAfter500ms_OSang', 'spikeCount_stimAfter500ms_DVar'}; - {'F1amplitude_mean','F1amplitude_DSI','F1amplitude_DSang','F1amplitude_OSI','F1amplitude_OSang','F1amplitude_DVar'} - {'stimInterval_charge','ONSET_peak'}; - {'stimInterval_charge','ONSET_peak'}; - {'spikeCount_stimInterval_mean','spikeCount_stimInterval_DSI', 'spikeCount_stimInterval_DSang','spikeCount_stimInterval_OSI', 'spikeCount_stimInterval_OSang', 'spikeCount_stimInterval_DVar'}; - {'spikeCount_stimInterval_mean','spikeCount_stimInterval_DSI', 'spikeCount_stimInterval_DSang','spikeCount_stimInterval_OSI', 'spikeCount_stimInterval_OSang', 'spikeCount_stimInterval_DVar'}; - {'spikeCount_stimInterval_mean','spikeCount_stimInterval_DSI', 'spikeCount_stimInterval_DSang','spikeCount_stimInterval_OSI', 'spikeCount_stimInterval_OSang', 'spikeCount_stimInterval_DVar'}; - {'params'}; - {'params'}; - {'ONSETspikes','ONSETlatency'};}; -paramsColumnNamesByTree = {{'LS_ON_sp','LS_OFF_sp'}; - {'SMS_spotSize_sp','SMS_onSpikes','SMS_offSpikes','SMS_onDuration'}; - {'DrifTex_mean_sp','DrifTex_DSI_sp','DrifTex_DSang_sp','DrifTex_OSI_sp','DrifTex_OSang_sp','DrifTex_DVar_sp'}; - {'DrifGrat_mean_sp','DrifGrat_DSI_sp','DrifGrat_DSang_sp','DrifGrat_OSI_sp','DrifGrat_OSang_sp','DrifGrat_DVar_sp'}; - {'SMS_spotSize_ex','SMS_charge_ex','SMS_peak_ex'}; - {'SMS_spotSize_in','SMS_charge_in','SMS_peak_in'}; - {'MB_1000_mean_sp','MB_1000_DSI_sp','MB_1000_DSang_sp','MB_1000_OSI_sp','MB_1000_OSang_sp','MB_1000_DVar_sp'}; - {'MB_500_mean_sp','MB_500_DSI_sp','MB_500_DSang_sp','MB_500_OSI_sp','MB_500_OSang_sp','MB_500_DVar_sp'}; - {'MB_250_mean_sp','MB_250_DSI_sp','MB_250_DSang_sp','MB_250_OSI_sp','MB_250_OSang_sp','MB_250_DVar_sp'}; - {'LS_ON_params_ex'}; - {'LS_ON_params_in'}; - {'Contrast_contrastVal_sp','Contrast_onSpikes','Contrast_onLatency'};}; - -% on -cellNameReplacements = containers.Map(); -cellNameReplacements('010716Ac4') = '010716Ac1'; -cellNameReplacements('010716Ac2') = '010716Ac1'; -cellNameReplacements('011216Ac4') = '011216Ac3'; -cellNameReplacements('020516Ac9') = '020516Ac8'; -cellNameReplacements('030515Bc4') = '030515Bc3'; -cellNameReplacements('030515Bc12') = '030515Bc3'; -cellNameReplacements('040716Ac8') = '040716Ac6'; -cellNameReplacements('041416Ac10') = '041416Ac9'; -cellNameReplacements('041416Ac11') = '041416Ac9'; -cellNameReplacements('042116Ac3') = '042116Ac2'; -cellNameReplacements('070115Ac6') = '070115Ac5'; -cellNameReplacements('082814Bc4') = '082814Bc3'; -cellNameReplacements('092016Ac8') = '092016Ac7'; -cellNameReplacements('092716Ac14') = '092716Ac13'; -cellNameReplacements('111915Ac5') = '111915Ac3'; -cellNameReplacements('111915Ac6') = '111915Ac4'; -% off -cellNameReplacements('040716Ac5') = '040716Ac2'; -%ULD -cellNameReplacements('041416Ac12') = '041416Ac13'; - -%% load cell names for data - -tic -numTrees = length(treeVariableModes); - -allCellNames = {}; -for ti = 1:numTrees - fname = fullfile('analysisTrees/automaticData/treeData/', num2str(ti)); - fprintf('Loading tree %s for cell names\n', fname) - load(fname); - fprintf('Processing tree\n'); - cellNames = {}; - - if treeVariableModes(ti) == 1 - [cellNames, ~, ~] = allParamsAcrossCells(analysisTree, paramsByTree{ti,:}); - elseif treeVariableModes(ti) == 0 - data = extractVectorOverSplitParamFromMultiCellTree(analysisTree, paramsByTree{ti,:}); - if ~isempty(data) - cellNames = data(:,1); - end - elseif treeVariableModes(ti) == 2 - data = extractLightStepParamsFromTree(analysisTree, true); - if ~isempty(data) - cellNames = data(:,1); - end - end - - for ni = 1:length(cellNames) - if isKey(cellNameReplacements, cellNames{ni}) - cellNames{ni} = cellNameReplacements(cellNames{ni}); - end - end - allCellNames = vertcat(allCellNames, cellNames); -end - -allCellNames = unique(allCellNames); -disp('done loading') -toc -%% build table - -warning('off','MATLAB:table:RowsAddedNewVars') -dtab = table('RowNames',allCellNames); -tic - -for ti = 1:numTrees - fname = fullfile('analysisTrees/automaticData/treeData/', num2str(ti)); - fprintf('Loading tree %s (%g of %g) \n', fname, ti, numTrees) - load(fname); - disp('Processing'); - - if treeVariableModes(ti) == 1 - - [cellNames, dataSetNames, paramForCells] = allParamsAcrossCells(analysisTree, paramsByTree{ti,:}); - % add new columns from this data set - dtab(:,paramsColumnNamesByTree{ti}) = num2cell(nan(length(allCellNames), length(paramsColumnNamesByTree{ti}))); - % fill these new empty columns - paramForCells(cellfun(@isempty, paramForCells)) = {nan}; - paramForCells = paramForCells'; - % load the columns with data - for ci = 1:length(cellNames) - name = cellNames{ci}; - if isKey(cellNameReplacements, name) - name = cellNameReplacements(name); - end - dtab(name, paramsColumnNamesByTree{ti}) = paramForCells(ci,:); - end - elseif treeVariableModes(ti) == 0 - data = extractVectorOverSplitParamFromMultiCellTree(analysisTree, paramsByTree{ti,:}); - if ~isempty(data) - cellNames = data(:,1); - for ci = 1:length(cellNames) - name = cellNames{ci}; - if isKey(cellNameReplacements, name) - name = cellNameReplacements(name); - end - dtab{name,paramsColumnNamesByTree{ti}} = data(ci,2:end); - end - end - elseif treeVariableModes(ti) == 2 - data = extractLightStepParamsFromTree(analysisTree, false); - if ~isempty(data) - cellNames = data(:,1); - - - for ci = 1:length(cellNames) - name = cellNames{ci}; - if isKey(cellNameReplacements, name) - name = cellNameReplacements(name); - end - dtab{name,paramsColumnNamesByTree{ti}} = data(ci,3); - end - end - - end - % if cellType(ti) - % for i = 1:length(cellNames) - % dtab{cellNames{i}, 'cellType'} = {'WFDS ON'}; - % end - % else - % for i = 1:length(cellNames) - % dtab{cellNames{i}, 'cellType'} = {'unknown'}; - % end - % end -end - -disp('done') -toc -%% Load other tables with manually-entered data - -tic -load 'analysisTrees/automaticData/wfdsSpatialOffsetTable.mat' -externalTable = wfdsSpatialOffsetTable; -origTableVars = dtab.Properties.VariableNames; -warning('off','MATLAB:table:RowsAddedNewVars') -for i = 1:size(externalTable,1) - cellName = externalTable.Properties.RowNames{i}; - - % find if the cell is not already present so we can fill in nans - % have to put in nan for the missing values because otherwise it'll get filled with 0 - c = strfind(dtab.Properties.RowNames, cellName); - c2 = [c{:}]; - - insertRow = externalTable(cellName,:); - - if isempty(c2) - if isKey(cellNameReplacements, cellName) - cellName = cellNameReplacements(cellName); - end - for vi = 1:length(origTableVars) - varName = origTableVars{vi}; - if ~strcmp(varName, 'cellType') && isempty(strfind(varName, 'SMS')) && isempty(strfind(varName, 'Contrast')) && isempty(strfind(varName, 'params')) - insertRow(cellName, varName) = {nan}; - end - end - end - dtab(cellName, insertRow.Properties.VariableNames) = insertRow(1,:); -end - -% % clear empties -numericalVarColumns = externalTable.Properties.VariableNames; -for i = 1:size(dtab,1) - d = dtab{i,numericalVarColumns}; - if all(d == 0) - dtab(i, numericalVarColumns) = num2cell(nan*zeros(1,length(numericalVarColumns))); - end -end - -% - -disp('Loaded external data table') -toc -%% load cell locations & types from cell data files -% change the first line variable if you've added new cells since the last run, -% since this uses caching to save time - -loadCellDataFiles = true; - -numCells = size(dtab, 1); -cellNames = dtab.Properties.RowNames; - -warning('off','MATLAB:table:RowsAddedNewVars') - -% cellLocationsAndTypes = table(); -if loadCellDataFiles - - disp('Begin loading cell locations and types from files') - tic - for ci = 1:numCells - load([ANALYSIS_FOLDER 'cellData' filesep cellNames{ci} '.mat']); %load cellData - loc = cellData.location; - if ~isempty(loc) - dtab{cellNames{ci}, {'location_x', 'location_y', 'eye'}} = loc; - else - dtab{cellNames{ci}, {'location_x', 'location_y', 'eye'}} = [nan, nan, nan]; - end - - typ = cellData.cellType; - dtab{cellNames{ci}, 'cellType'} = {typ}; - - tags = cellData.tags; - if isKey(tags, 'QualityRating') - qr = str2double(tags('QualityRating')); - else - qr = nan; - end - dtab{cellNames{ci}, 'QualityRating'} = {qr}; - end - - cellLocationsAndTypes = dtab(:,{'cellType','location_x', 'location_y', 'eye', 'QualityRating'}); - save('analysisTrees/automaticData/cellLocationsAndTypes', 'cellLocationsAndTypes'); - disp('Done') - toc - -else - load('analysisTrees/automaticData/cellLocationsAndTypes'); - cellNames = dtab.Properties.RowNames; - - dtab(:, {'cellType','location_x', 'location_y', 'eye','QualityRating'}) = cellLocationsAndTypes(cellNames,{'cellType','location_x', 'location_y', 'eye','QualityRating'}); -end -%% Finish up the number vars - -dtab = sortrows(dtab, 'RowNames'); -cellNames = dtab.Properties.RowNames; -selectWfdsOn = ~cellfun(@isempty, strfind(dtab{:,'cellType'}, 'ON WFDS')); -selectWfdsOff = ~cellfun(@isempty, strfind(dtab{:,'cellType'}, 'OFF WFDS')); -selectControl = ~(selectWfdsOn | selectWfdsOff); -selectOtherDS = ~cellfun(@isempty, strfind(dtab{:,'cellType'}, 'ON-OFF DS transient')); - -%% Save data table -% Change the save file name if desired - -save('analysisTrees/automaticData/wfds_data_table', 'dtab','selectWfdsOn','selectWfdsOff','selectControl','selectOtherDS','numCells','cellNames'); -%% Initial numbers - -fprintf('Total count: %g\n', numCells) -fprintf('ON WFDS: %g\n', sum(selectWfdsOn)) -fprintf('ON WFDS: %g\n', sum(selectWfdsOff)) -fprintf('Non WFDS: %g\n', sum(selectControl)) -fprintf('Other DS: %g\n', sum(selectOtherDS)) \ No newline at end of file diff --git a/autodata/wfds_figures.m b/autodata/wfds_figures.m deleted file mode 100644 index daeb26a..0000000 --- a/autodata/wfds_figures.m +++ /dev/null @@ -1,1438 +0,0 @@ -%% *CELL ATTACHED DATA* - - -colo = [.1, .3, .7]; -colo2 = [.68, .1, .2]; - -% col_exc = [1 0 1]; -% col_inh = [0 1 1]; - -col_exc = [0 0 1]; -col_inh = [1 0 0]; - -selectWfdsOn = cellTypeSelect('ON WFDS'); -selectWfdsOff = cellTypeSelect('OFF WFDS'); -selectULD = cellTypeSelect('UltraLowDefinition'); -selectControl = ~(cellTypeSelect('ON WFDS') | selectWfdsOff | selectULD); - -set(0,'DefaultAxesFontSize',14) - -%% -% -%% Plot many SMS curves - -% spots multiple sizes - -select = selectWfdsOn; - -figure(101);clf; -handles = tight_subplot(2,2, .1); -peakSize = []; -tailSpikes = []; -axes(handles(1)); -for ci = 1:size(dtab,1) - if ~select(ci) - continue - end - spotSize = dtab{ci, 'SMS_spotSize_sp'}{1}; - if ~isempty(spotSize) - spikes = dtab{ci, 'SMS_onSpikes'}{1}; - hold on - plot(spotSize, spikes); - end -end -xlabel('spot size um') -ylabel('spike count on') -title('sms on') -hold off - -axes(handles(2)); -histogram(dtab{select,'SMS_onSpikes_prefSize'}, 10) -title('sms preferred spot size') - -axes(handles(3)); -histogram(dtab{select,'SMS_onSpikes_tailSpikes'}, 10) -title('tail spikes') - -axes(handles(4)); -histogram(dtab{select,'SMS_onSpikes_peakSpikes'}, 10) -title('preferred spot spikes') - -%% Plot a set of SMS - - - -%% -% -%% Population stats for WFDS OFF - -% spots multiple sizes - -figure(101);clf; -handles = tight_subplot(1,3); -peakSize = []; -tailSpikes = []; -axes(handles(1)); -for ci = 1:size(dtab,1) - if ~selectWfdsOff(ci) - continue - end - spotSize = dtab{ci, 'SMS_spotSize_sp'}{1}; - if ~isempty(spotSize) - spikes = dtab{ci, 'SMS_offSpikes'}{1}; - hold on - plot(spotSize, spikes); - [m, mi] = max(spikes); - peakSize(ci) = spotSize(mi); - tailSpikes(ci) = mean(spikes(end-2:end)); - end -end -xlabel('spot size um') -ylabel('spike count off') -title('sms off') -hold off - -axes(handles(2)); -peakSize(peakSize == 0) = nan; -histogram(peakSize, 10) -title('sms peak spot size') - -axes(handles(3)); -tailSpikes(tailSpikes == 0) = nan; -histogram(tailSpikes, 10) -title('tail spikes') -%% light step - -figure(111) -subplot(1,2,1) -histogram(dtab{cellTypeSelect('ON WFDS'),'LS_ON_sp'},'Normalization','pdf') -hold on -histogram(dtab{selectWfdsOff,'LS_ON_sp'}, 'Normalization','pdf') -histogram(dtab{selectControl,'LS_ON_sp'}, 'Normalization','pdf') -hold off -legend('ON','OFF','other'); -title('ls on spikes') - -subplot(1,2,2) -histogram(dtab{cellTypeSelect('ON WFDS'),'LS_OFF_sp'}, 'Normalization','pdf') -hold on -histogram(dtab{selectWfdsOff,'LS_OFF_sp'}, 'Normalization','pdf') -histogram(dtab{selectControl,'LS_OFF_sp'}, 'Normalization','pdf') -hold off -legend('ON','OFF','other'); -title('ls off spikes') -%% calculate the best DS - - - -% - -figure(121);clf; -handles = tight_subplot(2, 2, .05, .05); - -axes(handles(1)); -histogram(dtab{cellTypeSelect('ON WFDS'),'best_DSI_sp'}, 12) -hold on -histogram(dtab{~cellTypeSelect('ON WFDS'),'best_DSI_sp'}, 12) -hold off -title('best DSI') - -axes(handles(2)); -boxplot(dtab{:,'best_DSI_sp'}, cellTypeSelect('ON WFDS') + 2 * selectWfdsOff, 'Labels',{'other','wfds on', 'off'}) -title('best DSI') - -axes(handles(3)); -polarhistogram(deg2rad(dtab{cellTypeSelect('ON WFDS'),'best_DSang_sp'}), 12) -hold on -polarhistogram(deg2rad(dtab{~cellTypeSelect('ON WFDS'),'best_DSang_sp'}), 12) -hold off -title('best DS angle') - -axes(handles(4)); -above = dtab{:, 'location_y'} > 0; -polarhistogram(deg2rad(dtab{cellTypeSelect('ON WFDS') & above,'best_DSang_sp'}), 12) -hold on -polarhistogram(deg2rad(dtab{cellTypeSelect('ON WFDS') & ~above,'best_DSang_sp'}), 12) -hold off -title('WFDS vertical pos comparison') -legend('above midline','below midline'); -angles = dtab{:,'best_DSang_sp'}; -%% Moving Bar DSI - -figure(125);clf -handles = tight_subplot(3, 2, .05, .05); - - -axes(handles(1)); -histogram(dtab{cellTypeSelect('ON WFDS'),'MB_1000_DSI_sp'}, 12) -title('MB 1000 DSI') - -axes(handles(2)); -polarhistogram(deg2rad(dtab{cellTypeSelect('ON WFDS'),'MB_1000_DSang_sp'}), 12) -title('MB 1000 DS angle') - -axes(handles(3)); -histogram(dtab{cellTypeSelect('ON WFDS'),'MB_500_DSI_sp'}, 12) -title('MB 500 DSI') - -axes(handles(4)); -polarhistogram(deg2rad(dtab{cellTypeSelect('ON WFDS'),'MB_500_DSang_sp'}), 12) -title('MB 500 DS angle') - -axes(handles(5)); -histogram(dtab{cellTypeSelect('ON WFDS'),'MB_250_DSI_sp'}, 12) -title('MB 250 DSI') - -axes(handles(6)); -polarhistogram(deg2rad(dtab{cellTypeSelect('ON WFDS'),'MB_250_DSang_sp'}), 12) -title('MB 250 DS angle') -%% DSI over speed - -figure(126);clf -handles = tight_subplot(1, 2, .05, .1, .1); - -axes(handles(1)); -for i = 1:numCells - plot([250, 500, 1000],dtab{i,{'MB_250_DSI_sp', 'MB_500_DSI_sp', 'MB_1000_DSI_sp'}}) - hold on -end -xlabel('speed') -ylabel('DSI') -hold off - -axes(handles(2)); -plot(dtab{cellTypeSelect('ON WFDS'),'MB_1000_DSI_sp'} .* exp(sqrt(-1) * deg2rad(dtab{cellTypeSelect('ON WFDS'),'MB_1000_DSang_sp'})), 'o') -hold on -plot(dtab{cellTypeSelect('ON WFDS'),'MB_500_DSI_sp'} .* exp(sqrt(-1) * deg2rad(dtab{cellTypeSelect('ON WFDS'),'MB_500_DSang_sp'})), 'o') -plot(dtab{cellTypeSelect('ON WFDS'),'MB_250_DSI_sp'} .* exp(sqrt(-1) * deg2rad(dtab{cellTypeSelect('ON WFDS'),'MB_250_DSang_sp'})), 'o') -title('DS (index and direction)') -legend('1000','500','250') - -line([-.5,.5],[0,0]) -line([0,0],[-.5,.5]) -axis equal -%% spatial RF offset - -figure(131);clf; -handles = tight_subplot(3,3, .05, .1); -% angleOffset = zeros(length(cellNames),1); -% for i = 1:length(cellNames) -% if ~isempty(strfind(cellNames{i}, 'B')) -% angleOffset(i) = 270; -% else -% angleOffset(i) = 180; -% end -% end -% angleOffset = deg2rad(angleOffset); - -autocenterOffsetDirections = angle(dtab.spatial_exin_offset); -autocenterOffsetDistance = abs(dtab.spatial_exin_offset); - -axes(handles(1)); -plot(autocenterOffsetDistance(cellTypeSelect('ON WFDS')) .* exp(sqrt(-1) * autocenterOffsetDirections(cellTypeSelect('ON WFDS'))), 'ob') -hold on -plot(autocenterOffsetDistance(~cellTypeSelect('ON WFDS')) .* exp(sqrt(-1) * autocenterOffsetDirections(~cellTypeSelect('ON WFDS'))), 'or') -hold off -line([-10,10],[0,0]) -line([0,0],[-10,10]) -axis square -title('spatial offset Ex from In') -legend('WFDS','Other') - -axes(handles(2)); -plot(autocenterOffsetDistanceNormalized(cellTypeSelect('ON WFDS')) .* exp(sqrt(-1) * autocenterOffsetDirections(cellTypeSelect('ON WFDS'))), 'ob') -hold on -plot(autocenterOffsetDistanceNormalized(~cellTypeSelect('ON WFDS')) .* exp(sqrt(-1) * autocenterOffsetDirections(~cellTypeSelect('ON WFDS'))), 'or') -hold off -line([-1,1],[0,0]) -line([0,0],[-1,1]) -axis square -title('spatial offset Ex from In (norm)') -legend('WFDS','Other') - - -axes(handles(3)); -boxplot(autocenterOffsetDistance, cellTypeSelect('ON WFDS'), 'Labels',{'other','wfds'}) -% histogram(autocenterOffsetDistance(selectWfds), 10) -% hold on -% histogram(autocenterOffsetDistance(~selectWfds), 10) -% hold off -% xlabel('offset um') -title('magnitude of spatial offset') -% legend('WFDS','Other') - -axes(handles(4)); -boxplot(autocenterOffsetDistanceNormalized, cellTypeSelect('ON WFDS'), 'Labels',{'other','wfds'}) -title('magnitude of spatial offset (norm)') - - -axes(handles(5)); -polarhistogram(autocenterOffsetDirections(cellTypeSelect('ON WFDS')), 10) -hold on -polarhistogram(autocenterOffsetDirections(~cellTypeSelect('ON WFDS')), 10) -hold off -title('angle of spatial offset') - -axes(handles(6)); -spatialToTextureDiff = dtab.best_DSang_sp - rad2deg(autocenterOffsetDirections); -polarhistogram(deg2rad(spatialToTextureDiff(cellTypeSelect('ON WFDS'))), 10) -hold on -polarhistogram(deg2rad(spatialToTextureDiff(~cellTypeSelect('ON WFDS'))), 10) -title('difference between tex angle and offset angle') - -spatialToImageDiff = mod(autocenterOffsetDirections(cellTypeSelect('ON WFDS')) - dtab.imageAngle(cellTypeSelect('ON WFDS')), 360); -axes(handles(7)); -polarhistogram(deg2rad(spatialToImageDiff), 10) -title('difference between image angle and offset angle') - - -axes(handles(8)); -plot(autocenterOffsetDistanceNormalized(cellTypeSelect('ON WFDS')), dtab{cellTypeSelect('ON WFDS'),'best_DSI_sp'}, 'o') -hold on -plot(autocenterOffsetDistanceNormalized(~cellTypeSelect('ON WFDS')), dtab{~cellTypeSelect('ON WFDS'),'best_DSI_sp'}, 'o') -hold off -title('Offset vs DSI') -xlabel('offset distance normalized') -ylabel('DSI') -line([0,1],[0,0]) -line([0,0],[0,.6]) -%% Cell location analysis - -figure(141);clf -ha = tight_subplot(2,3); - -axes(ha(1)) -plot(dtab{cellTypeSelect('ON WFDS'),'location_x'}, dtab{cellTypeSelect('ON WFDS'),'location_y'},'o') -line([-100,100],[0,0]) -line([0,0],[-100,100]) -axis(1.2*[-2000,2000, -2000,2000]) -axis square -title('all wfds locations') - -map_data = dtab{cellTypeSelect('ON WFDS'), {'location_x','location_y','best_DSang_sp','best_DSI_sp','eye','imageAngle'}}; - -% map_data: X, Y, angle, DSI, right=1 -map_data(map_data(:,1) == 0 & map_data(:,2) == 0, :) = []; - -x = -1*map_data(:,1); % compensate for rig spatial flip in dimension (negative right) -y = map_data(:,2); -ang = map_data(:,3); -mag = map_data(:,4); -left = map_data(:,5) == -1; -right = map_data(:,5) == 1; -u = mag .* cosd(ang); -v = mag .* sind(ang); -cellTypeSelect('ON WFDS') -% Together -axes(ha(2)); -x_eyesTogether = x; -x_eyesTogether(right) = -1 * x_eyesTogether(right); -uRigFlipped = u; -uRigFlipped(right) = -1 * uRigFlipped(right); -sel = left == 1; -quiver(x_eyesTogether(sel),y(sel),uRigFlipped(sel),v(sel),1.3,'color','red','linewidth',2) -hold on -sel = right == 1; -quiver(x_eyesTogether(sel),y(sel),uRigFlipped(sel),v(sel),1.3,'color','blue','linewidth',2) -legend('left','right'); -line([-500, 500],[0,0],'color','k') -line([0,0],[-500, 500],'color','k') -axis(1.2*[-2000,2000, -2000,2000]) -axis square -title('Both eyes') -xlabel('Nasal -- Caudal') - -% left -axes(ha(3)); -sel = left == 1; -quiver(x(sel),y(sel),u(sel),v(sel),1.3,'color','red','linewidth',2) -line([-500, 500],[0,0],'color','k') -line([0,0],[-500, 500],'color','k') -axis(1.2*[-2000,2000, -2000,2000]) -axis square -title('Left') -xlabel('Nasal -- Caudal') - -% right -axes(ha(4)); -sel = right == 1; -quiver(x(sel),y(sel),u(sel),v(sel),1.3,'color','red','linewidth',2) -line([-500, 500],[0,0],'color','k') -line([0,0],[-500, 500],'color','k') -axis(1.2*[-2000,2000, -2000,2000]) -axis square -title('Right') -xlabel('Caudal -- Nasal') - - -% Image angle -ang = map_data(:,6); -u = cosd(ang); -v = sind(ang); -axes(ha(5)); -quiver(x,y,u,v) -title('image angles') -axis(1.2*[-2000,2000, -2000,2000]) -axis square - -% Autocenter offset angle -ang = rad2deg(autocenterOffsetDirections(cellTypeSelect('ON WFDS'))); -u = autocenterOffsetDistance(cellTypeSelect('ON WFDS')) .* cosd(ang); -v = autocenterOffsetDistance(cellTypeSelect('ON WFDS')) .* sind(ang); -axes(ha(6)); -quiver(x,y,u,v,2) -title('autocenter offset angles') -axis(1.2*[-2000,2000, -2000,2000]) -axis square -%% LIGHT STEP - -figure(100);clf - -histogram(dtab{selectWfds,'LS_ON_sp'}, 12, 'Normalization','pdf', 'FaceColor', colo) -hold on -histogram(dtab{:,'LS_OFF_sp'}, 10,'Normalization','pdf', 'FaceColor', colo2) -hold off -xlabel('Spike count') -ylabel('PDF across cells') -title('Light Step Spike Counts') -legend({'Onset','Offset'}) -%% SPOTS MULTI SIZE population averages - -figure(102);clf; -peakSize = []; -tailSpikes = []; -spikesOverBaselineByVar = {}; -outstruct = struct(); - -varsToMean = {'SMS_onSpikes','SMS_offSpikes','SMS_charge_ex','SMS_peak_ex','SMS_charge_in','SMS_peak_in'}; -ylabels = {'ON spikes','OFF spikes','Ex Charge','Ex Peak','In Charge','In Peak'}; -baselinesToMean = {'SMS_spotSize_sp','SMS_spotSize_sp','SMS_spotSize_ex','SMS_spotSize_ex','SMS_spotSize_in','SMS_spotSize_in'}; -cellTypeSelects = {cellTypeSelect('UltraLowDefinition')}; -cellTypeNames = {'WFDS ON','WFDS OFF'}; - -handles = tight_subplot(length(varsToMean), length(cellTypeSelects), [0.01, .1], 0.1, .1); -% tight_subplot(Nh, Nw, gap, marg_h, marg_w) - -mean_spotSize = linspace(0,1199); - -for vari = 1:length(varsToMean) - cellCount = 0; - - for cellTypeIndex = 1:length(cellTypeSelects) - spikesOverSpotSize = []; - - - for ci = 1:numCells - sel = cellTypeSelects{cellTypeIndex}; - if ~sel(ci) - continue - end - spotSize = dtab{ci, baselinesToMean{vari}}{1}; - - if ~isempty(spotSize) - cellCount = cellCount + 1; - spikes = dtab{ci, varsToMean{vari}}{1}; - % make mean spikes for each size due to repeat epochs - unique_sizes = unique(spotSize); - averagedOverRepeats = zeros(size(unique_sizes)); - for si = 1:length(unique_sizes) - averagedOverRepeats(si) = mean(spikes(spotSize == unique_sizes(si))); - end - - % hold on - % plot(spotSize, spikes); - [maxx, mi] = max(spikes); - peakSize(ci) = spotSize(mi); - tailSpikes(ci) = mean(spikes(end-2:end)); - - % add to average - spikesOverSpotSize(end+1,:) = interp1(unique_sizes, averagedOverRepeats, mean_spotSize); - end - end - spikesOverBaselineByVar{cellTypeIndex, vari} = spikesOverSpotSize; - - i = (vari-1) * length(cellTypeSelects) + cellTypeIndex; - axes(handles(i)); - m = nanmean(spikesOverBaselineByVar{cellTypeIndex, vari}); - s = nanstd(spikesOverBaselineByVar{cellTypeIndex, vari}) / sqrt(cellCount); - plot(mean_spotSize, m, 'r', 'LineWidth',3, 'Color', colo) - hold on - plot(mean_spotSize, m+s, '--', 'Color', colo) - plot(mean_spotSize, m-s, '--', 'Color', colo) - line([0,1200],[0,0],'Color','k') - - if vari < length(varsToMean) - xticks([]) - end - - [~, i] = max(abs(m)); - mx = m(i); - if ~isnan(mx) - if abs(mx) >= 1 - ticks = [0, round(mx/2,0), ceil(mx)]; - else - ticks = [0, mx/2, mx]; - end - yticks(sort(ticks)) - end - - xlim([0,1200]) - - - ylabel(ylabels{vari}) - if vari == 1 - title(sprintf('%s', cellTypeNames{cellTypeIndex})) - end - if vari == length(varsToMean) - xlabel('Spot diameter (�m)') - end - - outstruct.([varsToMean{vari} '_mean']) = m; - outstruct.([varsToMean{vari} '_sem']) = s; - end -end -outstruct.spotSize = mean_spotSize; - -%% SMS example traces - -figure(103);clf; -handles = tight_subplot(2,4, .005, .1, .08); -load('analysisTrees/automaticData/sms_data'); - -t = -.5:.0001:1.9999; -for vi = 1:3 - for si = 1:4 - if vi == 1 %spikes - axes(handles(si)) - elseif vi == 2 - axes(handles(si + 4)) - yyaxis left - else - axes(handles(si + 4)) - yyaxis right - end - r = sms_responsesCaExIn{vi,si}; - if vi > 1 - r = smooth(r,50); - end - - if vi == 1 - r = r ./ max(abs(r)); - end - - % convert to conductance - if vi == 2 - r = r / -60; - elseif vi == 3 - r = r / 80; - end - r = r - mean(r(abs(t) < .03)); - - c = {'k', col_exc, col_inh}; - wid = [1,2,2]; - plot(t, r, 'Color', c{vi},'LineWidth',wid(vi)) - xlim([-.1,.5]) - ylabel('') - - - if si > 1 || (si == 1 && (vi == 1 || vi ==3)) - yticks([]) - end - if si == 1 && vi > 1 - ylabel('conductance (nS)') - end - if si == 1 && vi == 3 - xlabel('Time after light onset (sec)') - legend({'Excitatory','Inhibitory'}) - end - if vi == 1 - title(sprintf('%g �m diameter',sms_sizes(si))) - ylim([-1,.5]) - line([0,0],[-1,.5],'Color','y','LineWidth',3); - xticks([]) - else - ylim([-.5,5]) - xticks('auto') - xticklabels('auto') - end - if vi == 3 - line([0,0],[-0.5,5],'Color','y','LineWidth',3); - end - set(gca,'box','off') - set(gca,'xcolor','w','ycolor','w','xtick',[],'ytick',[]) - end -end -%% SMS traces WC - -figure(104);clf; -handles = tight_subplot(2,4, [.1, .05], .08, .05); -load('analysisTrees/automaticData/sms_data'); - -t = -.5:.0001:1.9999; -for si = 1:4 - axes(handles(si)) - responses = []; - for vi = 2:3 - r = sms_responsesCaExIn{vi,si}; - r = r - mean(r(t < 0)); - r = smooth(r,100); - r = r ./ sign(mean(r)); - plot(t,r) - hold on - responses(vi-1,:) = r; - end - - xlabel('Time after light onset (sec)') - title(sprintf('Diameter: %g �m',sms_sizes(si))) - hold off - xlim([min(t),max(t)]) - - axes(handles(si + 4)) - plot(t, -1*diff(responses)) - r = -1*diff(responses); - plot(t, r) - xlim([min(t),max(t)]) -end - -linkaxes(handles) -yl = ylim; -for si = 1:8 - axes(handles(si)) - hold on - c = rectangle('Position',[0,-1000,1,2000],'FaceColor',[0.999, 0.999, .8],'LineStyle','none'); - uistack(c,'bottom') -end -%% Individual contrast responses - -clf -h = tight_subplot(1,2, .1, .1, .05); -selectWfdsOn = cellTypeSelect('ON WFDS'); - -for ci = 1:size(dtab,1) - - if selectWfdsOn(ci) - col = 'b'; - width = 3; - elseif selectControl(ci) - col = 'r'; - width = 1; - end - - spotSize = dtab{ci, 'Contrast_contrastVal_sp'}{1}; - if ~isempty(spotSize) - [spotSize, order] = sort(spotSize); - spikes = dtab{ci, 'Contrast_onSpikes'}{1}; - spikes = spikes(order); - - axes(h(1)) - plot(spotSize, spikes, col, 'LineWidth',width); - hold on - xlabel('contrast') - - axes(h(2)) - lat = dtab{ci, 'Contrast_onLatency'}{1}; - lat = lat(order); - plot(spotSize, lat, col, 'LineWidth',width); - hold on - xlabel('contrast') - ylim([0,.3]) - end -end - -title(h(1), 'spikes') -title(h(2),'latency') -%% Contrast Responses averaged - -figure(102);clf; -peakSize = []; -tailSpikes = []; -spikesOverBaselineByVar = {}; - -varsToMean = {'Contrast_onSpikes','Contrast_onLatency'}; -ylabels = {'spikes','sec'}; -baselinesToMean = {'Contrast_contrastVal_ca','Contrast_contrastVal_ca'}; - -handles = tight_subplot(length(varsToMean), 2, [0.01, .1], 0.1, .1); -% tight_subplot(Nh, Nw, gap, marg_h, marg_w) - -mean_contrast = linspace(-1,1); - -for vari = 1:length(varsToMean) - cellCount = 0; - - for cellTypeIndex = 1:2 - spikesOverSpotSize = []; - - cellTypeSelects = {cellTypeSelect('ON WFDS'), selectControl}; - - for ci = 1:numCells - sel = cellTypeSelects{cellTypeIndex}; - if ~sel(ci) - continue - end - spotSize = dtab{ci, baselinesToMean{vari}}{1}; - - if ~isempty(spotSize) - cellCount = cellCount + 1; - spikes = dtab{ci, varsToMean{vari}}{1}; - % make mean spikes for each size due to repeat epochs - unique_sizes = unique(spotSize); - averagedOverRepeats = zeros(size(unique_sizes)); - for si = 1:length(unique_sizes) - averagedOverRepeats(si) = mean(spikes(spotSize == unique_sizes(si))); - end - - % hold on - % plot(spotSize, spikes); - [maxx, mi] = max(spikes); - peakSize(ci) = spotSize(mi); - tailSpikes(ci) = mean(spikes(end-2:end)); - - % add to average - spikesOverSpotSize(end+1,:) = interp1(unique_sizes, averagedOverRepeats, mean_contrast); - end - end - spikesOverBaselineByVar{cellTypeIndex, vari} = spikesOverSpotSize; - - i = (vari-1) * 2 + cellTypeIndex; - axes(handles(i)); - m = nanmean(spikesOverBaselineByVar{cellTypeIndex, vari}); - s = nanstd(spikesOverBaselineByVar{cellTypeIndex, vari}) / sqrt(cellCount); - plot(mean_contrast, m, 'r', 'LineWidth',3, 'Color', colo) -% hold on -% plot(mean_spotSize, m+s, '--', 'Color', colo) -% plot(mean_spotSize, m-s, '--', 'Color', colo) -% line([0,1200],[0,0],'Color','k') -% -% if vari < length(varsToMean) -% xticks([]) -% end -% -% [~, i] = max(abs(m)); -% mx = m(i); -% if ~isnan(mx) -% yticks(sort([0, round(mx)])) -% end -% -% xlim([0,1200]) -% -% ylabel(ylabels{vari}) -% cellTs = {'On','Off'}; -% if vari == 1 -% title(sprintf('%s', cellTs{cellTypeIndex})) -% end -% if vari == length(varsToMean) -% xlabel('Spot diameter (�m)') -% end - - hold off - end -end - -%% SPEED / DEPENDENT DS Index - -figure(105);clf; - -handles = tight_subplot(1,2, .0, [.13, .08], .1); - -% DSI over Speed -axes(handles(1)); -for i = 1:numCells - if selectControl(i) - continue - end - selectWfdsOn = cellTypeSelect('ON WFDS'); - if selectWfdsOn(i) - c = colo; - x = 0; - end -% c = colo2; -% x = 50; -% end - plot([250, 500, 1000]+x,dtab{i,{'MB_250_DSI_sp', 'MB_500_DSI_sp', 'MB_1000_DSI_sp'}},... - '+-', 'Color', c, 'MarkerSize',10) - hold on -end -xlim([100,1150]) -ylim([0,.7]) -xlabel('Movement speed (�m/sec)') -ylabel('DSI') - -plot([250, 500, 1000], nanmean(dtab{cellTypeSelect('ON WFDS'),{'MB_250_DSI_sp', 'MB_500_DSI_sp', 'MB_1000_DSI_sp'}}),'.-r','LineWidth',2,'MarkerSize',40); - -% DS cells controls: -plot([250, 500, 1000], nanmean(dtab{selectOtherDS,{'MB_250_DSI_sp', 'MB_500_DSI_sp', 'MB_1000_DSI_sp'}}),'.-g','LineWidth',2,'MarkerSize',40); - -% plot([250, 500, 1000]+50, nanmean(dtab{selectWfdsOff,{'MB_250_DSI_sp', 'MB_500_DSI_sp', 'MB_1000_DSI_sp'}}),'o-r','LineWidth',2); - -% title('Moving Bar DSI Speed Dependence') - -axes(handles(2)) -d1 = dtab{cellTypeSelect('ON WFDS'), 'DrifTex_DSI_sp'}; -x = 0*ones(length(d1), 1); -plot(x,d1, '+', 'Color', colo, 'MarkerSize',10) -hold on -% d2 = dtab{selectWfdsOff, 'DrifTex_DSI_sp'}; -% x = 0*ones(length(d2), 1) + .1; -% plot(x,d2, '+', 'Color', colo2, 'MarkerSize',10) -ylim([0,.7]) -yticks([]) - -d3 = dtab{cellTypeSelect('ON WFDS'), 'DrifGrat_DSI_sp'}; -x = 1*ones(length(d3), 1); -plot(x,d3, '+', 'Color', colo, 'MarkerSize',10) - -% d4 = dtab{selectWfdsOff, 'DrifGrat_DSI_sp'}; -% x = 1*ones(length(d4), 1) + .1; -% plot(x,d4, '+', 'Color', colo2, 'MarkerSize',10) - -ylim([0,.7]) -yticks([]) -xlim([-.5, 1.5]) -xticks([0,1]) -xticklabels({'Texture','Grating'}) - -% plot([0, .1,1, 1.1], [nanmean(d1),nanmean(d2),nanmean(d3), nanmean(d4)],'or','LineWidth',2); -plot([0, 1], [nanmean(d1),nanmean(d3)],'.r','LineWidth',2,'MarkerSize',40); -plot([0, 1], [nanmean(dtab{selectOtherDS,'DrifTex_DSI_sp'}),nanmean(dtab{selectOtherDS,'DrifGrat_DSI_sp'})],'.g','MarkerSize',40); - - -% Which stimulus is best for each cell's DSI -% axes(handles(2)) -% boxplot(dtab{selectWfds,'best_DSI_sp'}, dtab{selectWfds,'best_source'},... -% 'GroupOrder',{'MB_250_DSI_sp','MB_500_DSI_sp','MB_1000_DSI_sp','DrifTex_DSI_sp','DrifGrat_DSI_sp'},... -% 'Labels',{'MB 250','MB 500','MB 1000','Texture','Grating'},... -% 'Colors',colo, 'LabelOrientation','inline') -% ylabel('DSI') -% title('Pop. DSI for Several Stimuli') - -% axes(handles(2)) -% vars = {'MB_250_DSI_sp','MB_500_DSI_sp','MB_1000_DSI_sp','DrifTex_DSI_sp','DrifGrat_DSI_sp'}; -% dsiByStim = {}; -% for vi = 1:length(vars) -% dsi = dtab{:,vars{vi}}; -% dsi(isnan(dsi)) = []; -% dsiByStim{vi} = dsi; -% end -% -% distributionPlot(dsiByStim, 'color', colo); -% xticklabels({'MB 250','MB 500','MB 1000','Texture','Grating'}); -% ax = gca; -% ax.XTickLabelRotation = 90; -% title('Population DSI for Various Stimuli') -% y = linspace(0,1,5); -% yticks(y) -% yticklabels('auto') -% ylabel('DSI') - -%% SPEED DEPENDENT DS Variance - -figure(105);clf; - -handles = tight_subplot(1,2, .0, [.13, .08], .1); - -% DVar over Speed -axes(handles(1)); -for i = 1:numCells - if selectControl(i) - continue - end - selectWfdsOn = cellTypeSelect('ON WFDS'); - if selectWfdsOn(i) - c = colo; - x = 0; - else - c = colo2; - x = 50; - end - plot([250, 500, 1000]+x,dtab{i,{'MB_250_DVar_sp', 'MB_500_DVar_sp', 'MB_1000_DVar_sp'}},... - '+-', 'Color', c, 'MarkerSize',10) - hold on -end -xlim([100,1150]) -ylim([0,1]) -xlabel('Movement speed (�m/sec)') -ylabel('DVar') - -plot([250, 500, 1000], nanmean(dtab{cellTypeSelect('ON WFDS'),{'MB_250_DVar_sp', 'MB_500_DVar_sp', 'MB_1000_DVar_sp'}}),'o-r','LineWidth',2); -plot([250, 500, 1000]+50, nanmean(dtab{selectWfdsOff,{'MB_250_DVar_sp', 'MB_500_DVar_sp', 'MB_1000_DVar_sp'}}),'o-r','LineWidth',2); - -% title('Moving Bar DVar Speed Dependence') - -axes(handles(2)) -d1 = dtab{cellTypeSelect('ON WFDS'), 'DrifTex_DVar_sp'}; -x = 0*ones(length(d1), 1); -plot(x,d1, '+', 'Color', colo, 'MarkerSize',10) -hold on -d2 = dtab{selectWfdsOff, 'DrifTex_DVar_sp'}; -x = 0*ones(length(d2), 1) + .1; -plot(x,d2, '+', 'Color', colo2, 'MarkerSize',10) -ylim([0,.7]) -yticks([]) - -d3 = dtab{cellTypeSelect('ON WFDS'), 'DrifGrat_DVar_sp'}; -x = 1*ones(length(d3), 1); -plot(x,d3, '+', 'Color', colo, 'MarkerSize',10) - -d4 = dtab{selectWfdsOff, 'DrifGrat_DVar_sp'}; -x = 1*ones(length(d4), 1) + .1; -plot(x,d4, '+', 'Color', colo2, 'MarkerSize',10) - -ylim([0,1]) -yticks([]) -xlim([-.5, 1.5]) -xticks([0,1]) -xticklabels({'Texture','Grating'}) - -plot([0, .1,1, 1.1], [nanmean(d1),nanmean(d2),nanmean(d3), nanmean(d4)],'or','LineWidth',2); - -%% Example polar plots - -figure(106);clf; - -handles = tight_subplot(1,5, .02, .0, .01); -load('analysisTrees/automaticData/polarPlotsByStimForExampleCell'); -plotNames = {'MB 500','MB 1000','MB 2000','Tex 1000','Gratings'}; - -% polarPlots{1,2} = nodeData.ONSETspikes.mean; -% polarPlots{1,1} = nodeData.barAngle; -% polarPlots{3,1} = nodeData.barAngle; -% polarPlots{4,1} = nodeData.textureAngle; -% polarPlots{4,2} = nodeData.spikeCount_stimAfter500ms.mean; -% polarPlots{5,1} = nodeData.gratingAngle; -% polarPlots{5,2} = nodeData.F1amplitude.value; - - -for si = 1:length(plotNames) - axes(handles(si)); - - polarplotImproved(polarPlots{si,1}, polarPlots{si,2}); - thetaticklabels([]) - - if si > 4 - rticklabels([]) - end - - if strcmp(plotNames{si}, 'Gratings') - title(sprintf('%s F1 Amp', plotNames{si})); - else - title(sprintf('%s Spike Count', plotNames{si})); - end -end - -%% another polar set - - -figure(108);clf; - -load('analysisTrees/automaticData/polarPlotsByStimForExampleCell'); -plotNames = {'MB 250','MB 500','MB 1000','MB 2000'}; -handles = tight_subplot(1,length(plotNames), .02, .0, .01); - - -% polarPlots{1,2} = nodeData.ONSETspikes.mean; -% polarPlots{1,1} = nodeData.barAngle; -% polarPlots{3,1} = nodeData.barAngle; -% polarPlots{4,1} = nodeData.textureAngle; -% polarPlots{4,2} = nodeData.spikeCount_stimAfter500ms.mean; -% polarPlots{5,1} = nodeData.gratingAngle; -% polarPlots{5,2} = nodeData.F1amplitude.value; - - -for si = 1:length(plotNames) - axes(handles(si)); - - polarplotImproved(polarPlots{si,1}, polarPlots{si,2}); - thetaticklabels([]) - - if si > 4 - rticklabels([]) - end - - if strcmp(plotNames{si}, 'Gratings') - title(sprintf('%s F1 Amp', plotNames{si})); - else - title(sprintf('%s Spike Count', plotNames{si})); - end -end -%% Sample drifting grating responses - -figure(199);clf; - -cellName = '092816Bc5'; -epochs = 117:128; -t = 0:.0001:5.4999; - - -% cellName = '032416Ac2'; -% epochs = 141:(141+11); -% t = 0:.0001:6.4999; - - -global CELL_DATA_FOLDER -load([CELL_DATA_FOLDER filesep cellName]) -% -angles = []; -handles = tight_subplot(length(epochs), 1, .02, .1); - -for hi = 1:length(epochs) - epoch = cellData.epochs(epochs(hi)); - angles(hi) = epoch.get('textureAngle'); -end - -[angles,i] = sort(angles); -epochs = epochs(i); - -for hi = 1:length(epochs) - axes(handles(hi)); - epoch = cellData.epochs(epochs(hi)); - r = epoch.getData() - mean(epoch.getData()); - plot(t, r); - if angles(hi) == 210 - s = '("Preferred")'; - elseif angles(hi) == 60 - s = '("Null")'; - else - s = ''; - end -% title(sprintf('Movement Direction: %g deg %s', angles(hi), s)) - yticks([]) - if hi < 12 - xticks([]) - else - xlabel('Time (sec)'); - end -end - -linkaxes(handles) -xlim(handles(1), [0,5.5]) -ylim([-120,40]) -%% WHOLE CELL DATA - -% EI maps - - - - - -% example gratings - -load analysisTrees/automaticData/exampleGratings010716Ac1 -figure(111);clf; -polarplotImproved(exampleGratings010716Ac1{1},exampleGratings010716Ac1{2}) -%% LOCATION DATA - -figure(141);clf; -ha = tight_subplot(1,3, .05, .05, .05); - - - -map_data = dtab{cellTypeSelect('ON WFDS'), {'location_x','location_y','best_DSang_sp','best_DSI_sp','eye','imageAngle'}}; -% map_data = dtab{cellTypeSelect('ON WFDS'), {'location_x','location_y','DrifTex_DSang_sp','DrifTex_DSI_sp','eye','imageAngle'}}; - - -% map_data: X, Y, angle, DSI, right=1 -map_data(map_data(:,1) == 0 & map_data(:,2) == 0, :) = []; - -x = -1*map_data(:,1)/1000; % compensate for rig spatial flip in dimension (negative right) -y = map_data(:,2)/1000; -ang = map_data(:,3); -mag = map_data(:,4); -left = map_data(:,5) == -1; -right = map_data(:,5) == 1; -u = mag .* cosd(ang); -v = mag .* sind(ang); - - -theta = linspace(0, 2*pi); -circx = cos(theta)*2; -circy = sin(theta)*2; - -% axes(ha(1)) -% plot(x, y,'o', 'Color', colo) -% line([-100,100],[0,0]) -% line([0,0],[-100,100]) -% axis(1.2*[-2000,2000, -2000,2000]) -% axis square -% title('all wfds locations') - -% % Together -axes(ha(1)); -x_eyesTogether = x; -x_eyesTogether(right) = -1 * x_eyesTogether(right); -uRigFlipped = u; -uRigFlipped(right) = -1 * uRigFlipped(right); -sel = left == 1; -quiver(x_eyesTogether(sel),y(sel),uRigFlipped(sel),v(sel),1.3,'color',colo2,'linewidth',2) -hold on -sel = right == 1; -quiver(x_eyesTogether(sel),y(sel),uRigFlipped(sel),v(sel),1.3,'color',colo,'linewidth',2) -plot(circx, circy, '--k') -legend('left','right'); -line([-.500, .500],[0,0],'color','k') -line([0,0],[-.500, .500],'color','k') -axis(1.2*[-2,2, -2,2]) -axis square -title('Both eyes (Right X Flipped)') -xlabel('Nasal -- Caudal') - -% left -axes(ha(2)); -sel = left == 1; -quiver(x(sel),y(sel),u(sel),v(sel),1.3,'linewidth',2, 'Color', colo2) -hold on -plot(circx, circy, '--k') -line([-.500, .500],[0,0],'color','k') -line([0,0],[-.500, .500],'color','k') -axis(1.2*[-2,2, -2,2]) -axis square -title('Left Eye') -xlabel('Nasal -- Caudal') - -% right -axes(ha(3)); -sel = right == 1; -quiver(x(sel),y(sel),u(sel),v(sel),1.3,'linewidth',2, 'Color', colo) -hold on -plot(circx, circy, '--k') -line([-.500, .500],[0,0],'color','k') -line([0,0],[-.500, .500],'color','k') -axis(1.2*[-2,2, -2,2]) -axis square -title('Right Eye') -xlabel('Caudal -- Nasal') - - -% % Image angle -% ang = map_data(:,6); -% u = cosd(ang); -% v = sind(ang); -% axes(ha(5)); -% quiver(x,y,u,v, 'Color', colo,'linewidth',2) -% title('image angles') -% axis(1.2*[-2000,2000, -2000,2000]) -% axis square -% -% % Autocenter offset angle -% ang = rad2deg(autocenterOffsetDirections(selectWfds)); -% u = autocenterOffsetDistance(selectWfds) .* cosd(ang); -% v = autocenterOffsetDistance(selectWfds) .* sind(ang); -% axes(ha(6)); -% quiver(x,y,u,v,2, 'Color', colo,'linewidth',2) -% title('autocenter offset angles') -% axis(1.2*[-2000,2000, -2000,2000]) -% axis square -%% autocenter data - -figure(131);clf; -handles = tight_subplot(2,2, .1, .05, .05); -% angleOffset = zeros(length(cellNames),1); -% for i = 1:length(cellNames) -% if ~isempty(strfind(cellNames{i}, 'B')) -% angleOffset(i) = 270; -% else -% angleOffset(i) = 180; -% end -% end -% angleOffset = deg2rad(angleOffset); - -diffX = dtab.spatial_in_centerX - dtab.spatial_ex_centerX; -diffY = dtab.spatial_in_centerY - dtab.spatial_ex_centerY; -avgSigma = mean(dtab{:,{'spatial_in_sigma2X','spatial_ex_sigma2X','spatial_in_sigma2Y','spatial_ex_sigma2Y'}}, 2); -autocenterOffsetDistance = sqrt(diffX.^2 + diffY.^2); -autocenterOffsetDistanceNormalized = autocenterOffsetDistance ./ avgSigma; -autocenterOffsetDirections = angle(diffX + sqrt(-1) * diffY); -dtab.spatial_exin_offset = autocenterOffsetDistance .* exp(sqrt(-1) * autocenterOffsetDirections); - -axes(handles(1)); -plot(autocenterOffsetDistance(cellTypeSelect('ON WFDS')) .* exp(sqrt(-1) * autocenterOffsetDirections(cellTypeSelect('ON WFDS'))), '+b') -hold on -plot(autocenterOffsetDistance(selectControl) .* exp(sqrt(-1) * autocenterOffsetDirections(selectControl)), 'or') -hold off -line([-1,1]*40,[0,0]) -line([0,0],[-1,1]*40) -ylim([-40,40]) -xlim([-40,40]) -xlabel('x (�m)'); -ylabel('y (�m)'); -title('spatial offset In from Ex') -legend('FminiON','Other') - -axes(handles(2)); -plot(autocenterOffsetDistanceNormalized(cellTypeSelect('ON WFDS')) .* exp(sqrt(-1) * autocenterOffsetDirections(cellTypeSelect('ON WFDS'))), '+b') -hold on -plot(autocenterOffsetDistanceNormalized(selectControl) .* exp(sqrt(-1) * autocenterOffsetDirections(selectControl)), 'or') -hold off -line([-1,1],[0,0]) -line([0,0],[-1,1]) -ylim([-1,1]) -xlim([-1,1]) -xlabel('x (norm)'); -ylabel('y (norm)'); -axis square -title('spatial offset In from Ex (norm)') -legend('FminiON','Other') - - -axes(handles(3)); -% boxplot(autocenterOffsetDistance, selectWfds, 'Labels',{'Control','FminiON'}) -distributionPlot(autocenterOffsetDistance, 'groups', cellTypeSelect('ON WFDS')) -% hold on -% histogram(autocenterOffsetDistance(~selectWfds), 10) -% hold off -% xlim([-.5,1.5]) -xlabel('type') -title('magnitude of spatial offset') -% legend('WFDS','Other') - -axes(handles(4)); -distributionPlot(autocenterOffsetDistanceNormalized, 'groups',cellTypeSelect('ON WFDS')) -title('magnitude of spatial offset (norm)') -%% -% - -figure(135);clf; - -% axes(handles(5)); -polarhistogram(autocenterOffsetDirections(cellTypeSelect('ON WFDS')), linspace(0, 2*pi, 13), 'Normalization','pdf') -thetaticklabels([]) -% hold on -% polarhistogram(autocenterOffsetDirections(~selectWfds), 10) -% hold off -% title('angle of spatial offset') -%% Comparing autocenter to image and DS - -outputstruct = struct(); - -figure(132);clf; -handles = tight_subplot(3,1, .1, .1, .1); -angleBins = deg2rad(linspace(0,360,13)); -outputstruct.angleBins = angleBins; -outputstruct.binCenters = angleBins(1:12) + pi/24; - -goodDSI = dtab.DrifGrat_DSI_sp > 0.1; -sel = cellTypeSelect('ON WFDS') & goodDSI; - -axes(handles(1)); -spatialToTextureDiff = dtab.DrifGrat_DSang_sp - rad2deg(autocenterOffsetDirections); -xvar = polarhistogram(deg2rad(spatialToTextureDiff(sel)), angleBins); -% hold on -% polarhistogram(deg2rad(spatialToTextureDiff(~selectWfds)), 10) -title('difference between texture response angle and RF offset angle') -outputstruct.angle_LR_to_RF = xvar.Values; - -axes(handles(2)); -spatialToImageDiff = mod(autocenterOffsetDirections(sel) - dtab.imageAngle(sel), 360); -yvar = polarhistogram(deg2rad(spatialToImageDiff), angleBins); -title('difference between soma to dendrites image angle and RF offset angle') -outputstruct.angle_Image_to_RF = yvar.Values; - - -axes(handles(3)); -lightResponseToImageDiff = mod(dtab.DrifGrat_DSang_sp(sel) - dtab.imageAngle(sel), 360); -c = polarhistogram(deg2rad(lightResponseToImageDiff), angleBins); -title('difference between soma to dendrites image angle and texture response angle') -outputstruct.angle_Image_to_LR = c.Values; - -%% Compare offset to DSI with a fit line - -figure(133);clf; -plot(autocenterOffsetDistanceNormalized(selectWfds), dtab{selectWfds,'best_DSI_sp'}, 'o') -title('Offset vs DSI') -xlabel('AC Offset Distance Normalized') -ylabel('DSI') -line([0,1],[0,0]) -line([0,0],[0,.6]) - - - -%% Plot an example light step and psth - -clf; -handles = tight_subplot(2,1, .01, .15); -t = -0.5:.01:2; -axes(handles(1)); -plot(t,PSTH, 'Color', colo) -yticks([]) -xticks([]) -yl = ylim(); -c = rectangle('Position',[0,yl(1),1,diff(yl)],'FaceColor',[0.999, 0.999, .8],'LineStyle','none'); -uistack(c,'bottom') - -% load cellData/110216Ac19.mat -e = cellData.epochs(5); - -t = -0.5:.0001:1.9999; -axes(handles(2)); -plot(t, e.getData(), 'Color', colo) -xlabel('Time from light onset (sec)'); -yticks([]) - -hold on -yl = ylim(); -c = rectangle('Position',[0,yl(1),1,diff(yl)],'FaceColor',[0.999, 0.999, .8],'LineStyle','none'); -uistack(c,'bottom') - - -%% Compare parameterized light step values - -paramNames = {'polarity','delay', 'rise dur', 'hold dur', 'decay time const', 'decay baseline/peak'}; -paramColumns = dtab{:,{'LS_ON_params_ex','LS_ON_params_in'}}; -paramMatrix = []; -for exin = 1:2 - for p = 1:length(paramColumns) - par = paramColumns{p,exin}; - if isempty(par) - par = nan*ones(1,6); - end - paramMatrix(p,exin,:) = par; - end - - - figure;clf; - h = tight_subplot(3,2,.1); - for parami = 1:size(paramMatrix, 2) - - axes(h(parami)); - histogram(paramMatrix(cellTypeSelect('ON WFDS'),exin,parami),8) - hold on - histogram(paramMatrix(selectControl,exin,parami),8) - title(paramNames{parami}) - end -end - - -%% Compare delays - -figure; -delayToPeak = paramMatrix(:,:,2) + paramMatrix(:,:,3); -delayDifference = diff(delayToPeak')'; -histogram(delayToPeak(cellTypeSelect('ON WFDS'),1)-delayToPeak(cellTypeSelect('ON WFDS'),2), 10) -hold on -histogram(delayToPeak(selectControl,1)-delayToPeak(selectControl,2), 20) - -figure -histogram(delayDifference(cellTypeSelect('ON WFDS')),10) -hold on -histogram(delayDifference(selectControl),20) - -figure -hold on -plot(delayDifference(cellTypeSelect('ON WFDS')), dtab{cellTypeSelect('ON WFDS'),'DrifTex_DSI_sp'}, 'o') -plot(delayDifference(selectControl), dtab{selectControl,'DrifTex_DSI_sp'}, 'o') -xlabel('delay Ex to In (sec)') -ylabel('Texture DSI') -legend('WFDS ON','Control') -ylim([0,.35]) -movingDataSets = {'MB_1000_DSI_sp','MB_500_DSI_sp','DrifTex_DSI_sp'}; - -figure -h = tight_subplot(length(movingDataSets),1,.1, .1, .2); - -for mi = 1:length(movingDataSets) - axes(h(mi)) - scatter(abs(dtab{cellTypeSelect('ON WFDS'),'spatial_exin_offset'}), delayDifference(cellTypeSelect('ON WFDS')), 3000*dtab{cellTypeSelect('ON WFDS'),movingDataSets{mi}}.^2) - hold on - scatter(abs(dtab{selectControl,'spatial_exin_offset'}), delayDifference(selectControl), 3000*dtab{selectControl,movingDataSets{mi}}.^2) - - ylim([-.05,.1]) - xlabel('offset distance') - ylabel('delay difference') - legend('WFDS ON (DSI)','Control (DSI)') - title(movingDataSets{mi}, 'Interpreter','none'); -end - - -%% Find good example cells - -sel = ~cellfun(@isempty, dtab.SMS_spotSize_ca); -sel = sel & ~cellfun(@isempty, dtab.SMS_spotSize_exc); -names = cellNames(sel) - - -%% Plot RF offset ovals with angle arrows -figure(200);clf; -sel = ~isnan(dtab.spatial_ex_amplitude) & cellTypeSelect('ON WFDS'); -h = tight_subplot(4,3); - -cis = find(sel); -for ci = 1:sum(sel) - cel = dtab(cis(ci), :); - axes(h(ci)) - - hold on - ellipse(cel.spatial_ex_sigma2X, cel.spatial_ex_sigma2Y, -cel.spatial_ex_angle, cel.spatial_ex_centerX, cel.spatial_ex_centerY, 'blue'); - - ellipse(cel.spatial_in_sigma2X, cel.spatial_in_sigma2Y, -cel.spatial_in_angle, cel.spatial_in_centerX, cel.spatial_in_centerY, 'red'); - -% legend('Exc','Inh') - - plot(cel.spatial_ex_centerX, cel.spatial_ex_centerY, 'blue', 'MarkerSize', 20, 'Marker', '+') - plot(cel.spatial_in_centerX, cel.spatial_in_centerY, 'red', 'MarkerSize', 20, 'Marker', '+') - - % then, directions - start = ([cel.spatial_ex_centerX, cel.spatial_ex_centerY] + [cel.spatial_in_centerX, cel.spatial_in_centerY]) / 2; - - angleNames = {'imageAngle','MB_500_DSang_sp','MB_1000_DSang_sp','DrifTex_DSang_sp'}; - angleColors = {'r','b','g','k'}; - for ai = 1:length(angleNames) - ang = dtab{cis(ci), angleNames{ai}}; - if isnan(ang) - continue - end - offset = 5*[cos(deg2rad(ang)), sin(deg2rad(ang))]; - arrow(start, start + 10*offset,'Color',angleColors{ai}) - end - - hold off - set(gca,'box','off') - set(gca,'xcolor','w','ycolor','w','xtick',[],'ytick',[]) - title(cellNames{cis(ci)}) -end - -%% -figure(201) -boxplot(autocenterOffsetDistanceNormalized, cellTypeSelect('ON WFDS'), 'Labels',{'control','F-mini ON'}) -ylabel('Distance (norm)') -% title('magnitude of spatial offset (norm)') - -%% Is light SMS peak connected to DSI? (Sensitivity) -figure(202) -clf; - -yvar = 'best_DSI_sp'; -xvar = 'SMS_onSpikes_peakSpikes'; - -x = dtab{cellTypeSelect('ON WFDS'),xvar}; -y = dtab{cellTypeSelect('ON WFDS'),yvar}; -valid = ~(isnan(x)|isnan(y)); -x = x(valid); -y = y(valid); -[x,i] = sort(x); -y = y(i); - -plot(x,y,'o') -[p,S] = polyfit(x,y,1); -hold on -[yfit, delta] = polyval(p,x,S); - -Rsq = 1 - sum((y - yfit).^2)/sum((y - mean(y)).^2) - -plot(x, yfit, 'k'); -plot(x, yfit+delta,'--k'); -plot(x, yfit-delta,'--k'); -hold off -xlabel(xvar, 'Interpreter', 'none') -ylabel(yvar, 'Interpreter', 'none') - -%% Check for quality and discard outliers -% var = dtab{:, 'SMS_onSpikes_peakSpikes'}; -var = dtab{:, 'best_DSI_sp'}; - -figure(205) -histogram(var(cellTypeSelect('ON WFDS')), 10) -% threshold = prctile(var(cellTypeSelect('ON WFDS')), 90) -threshold = .6 - -cellNames(var >= threshold & cellTypeSelect('ON WFDS')) % | var > prctile(var, 90) - diff --git a/core/CellData.m b/core/CellData.m index 440300b..8684162 100755 --- a/core/CellData.m +++ b/core/CellData.m @@ -35,7 +35,6 @@ %Epoch attributes (protocol properties) %and data links %EpochDataGroups = info.Groups(1).Groups(2).Groups; - %EpochDataGroups = info.Groups(1).Groups(1).Groups(1).Groups(2).Groups; %search through all EpochGroups (not just first one!!!) %GWS fixed on 6/6/14 @@ -183,21 +182,18 @@ dataStd = std(M,1); end - function plotMeanData(obj, epochInd, subtractBaseline, lowPass, streamName, ax) - if nargin < 6 - ax = gca; - end + function plotMeanData(obj, epochInd, subtractBaseline, lowPass, streamName) if nargin < 5 streamName = 'Amplifier_Ch1'; end if nargin < 4 lowPass = []; end - if nargin < 3 + if nargin < 4 subtractBaseline = true; end - + ax = gca; sampleEpoch = obj.epochs(epochInd(1)); sampleRate = sampleEpoch.get('sampleRate'); stimLen = sampleEpoch.get('stimTime')*1E-3; %s @@ -323,17 +319,15 @@ function plotSpikeRaster(obj, epochInd, streamName) ylabel(ax, 'Trials'); end - function plotPSTH(obj, epochInd, binWidth, streamName, ax) - if nargin < 5 - ax = gca; - end + function plotPSTH(obj, epochInd, binWidth, streamName) if nargin < 4 streamName = 'Amplifier_Ch1'; end if nargin < 3 binWidth = 10; end - + + ax = gca; sampleEpoch = obj.epochs(epochInd(1)); stimLen = sampleEpoch.get('stimTime')*1E-3; %s [spCount, xvals] = obj.getPSTH(epochInd, binWidth, streamName); diff --git a/core/LabData.m b/core/LabData.m index ea62230..aec53a2 100755 --- a/core/LabData.m +++ b/core/LabData.m @@ -269,7 +269,6 @@ function analyzeCells(obj, cellNames) if ischar(cellNames) cellNames = {cellNames}; end - tic for i=1:length(cellNames) curCellName = cellNames{i}; disp(['Analyzing cell ' curCellName ': ' num2str(i) ' of ' num2str(length(cellNames))]); @@ -296,8 +295,6 @@ function analyzeCells(obj, cellNames) end end end - disp('Analysis complete') - toc end function resultTree = collectCells(obj, cellNames) diff --git a/core/loadAndSyncCellData.m b/core/loadAndSyncCellData.m index 9b64a70..742b1ec 100755 --- a/core/loadAndSyncCellData.m +++ b/core/loadAndSyncCellData.m @@ -1,7 +1,6 @@ function cellData = loadAndSyncCellData(cellDataName) global ANALYSIS_FOLDER; global SYNC_TO_SERVER; -global CELL_DATA_MASTER; cellData_local = []; cellData = []; do_local_to_server_copy = false; @@ -17,19 +16,11 @@ disp([cellDataName ': Local copy not found']); end -% Check to see if the file is recently changed -% localFileAge = (localModDate - now) * 86400; -% fprintf('Loaded file was modified %g sec ago', localFileAge) -% if localFileAge < 200 -% return -% end - if SYNC_TO_SERVER - if exist(CELL_DATA_MASTER, 'dir') == 7 %sever is connected and CellDataMaster folder is found + if exist([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster']) == 7 %sever is connected and CellDataMaster folder is found % disp('CellDataMaster found'); - cellDataStatusFileLocation = [CELL_DATA_MASTER 'CellDataStatus.txt']; try - fileinfo = dir([CELL_DATA_MASTER cellDataName '.mat']); + fileinfo = dir([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster' filesep cellDataName '.mat']); serverModDate = fileinfo.datenum; fprintf('Local file is %g sec newer than server file\n',(localModDate - serverModDate) * 86400) @@ -49,7 +40,7 @@ end end else - disp(['Unable to connect to ' CELL_DATA_MASTER]); + disp(['Unable to connect to ' filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster']); disp([cellDataName ': Local copy being loaded without sync']); end @@ -62,7 +53,7 @@ time_elapsed = toc; file_opened = false; while time_elapsed < FILE_IO_TIMEOUT - fid = fopen(cellDataStatusFileLocation, 'r+'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'r+'); if fid>0 file_opened = true; break; @@ -71,7 +62,7 @@ end if ~file_opened - disp(['Unable to open CellDataStatus.txt at' cellDataStatusFileLocation]); + disp('Unable to open CellDataStatus.txt'); return; end @@ -102,7 +93,7 @@ time_elapsed = toc; fclose(fid); while time_elapsed < BUSY_STATUS_TIMEOUT - fid = fopen(cellDataStatusFileLocation, 'r'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'r'); M = textscan(fid, '%s%s%s%u', 'Delimiter', '\t', 'HeaderLines', 1); fnames = M{1}; dates = M{2}; @@ -131,7 +122,7 @@ if curStatus %file is busy disp(['File is busy: ' cellDataName ' not updated!']); else - fid = fopen(cellDataStatusFileLocation, 'w'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'w'); %write busy flag before operation if new_entry fnames{ind} = cellDataName; @@ -151,14 +142,14 @@ %do the operation if do_local_to_server_copy disp('Doing do_local_to_server_copy'); - save([CELL_DATA_MASTER cellDataName '.mat'], 'cellData'); + save([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster' filesep cellDataName '.mat'], 'cellData'); elseif do_server_to_local_copy disp('Doing do_server_to_local_copy'); - copyfile([CELL_DATA_MASTER cellDataName '.mat'], [ANALYSIS_FOLDER 'cellData' filesep cellDataName '.mat']); + copyfile([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster' filesep cellDataName '.mat'], [ANALYSIS_FOLDER 'cellData' filesep cellDataName '.mat']); elseif do_server_to_local_update disp('Doing do_server_to_local_update'); copyfile([ANALYSIS_FOLDER 'cellData' filesep cellDataName '.mat'], [ANALYSIS_FOLDER 'cellData_localCopies' filesep cellDataName '.mat']); - copyfile([CELL_DATA_MASTER cellDataName '.mat'], [ANALYSIS_FOLDER 'cellData' filesep cellDataName '.mat']); + copyfile([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster' filesep cellDataName '.mat'], [ANALYSIS_FOLDER 'cellData' filesep cellDataName '.mat']); end %load updated cellData @@ -167,7 +158,7 @@ %reset busy status to 0 status(ind) = 0; %print file - fid = fopen(cellDataStatusFileLocation, 'w'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'w'); fprintf(fid,'%s\t%s\t%s\t%s\n','Filename', 'CheckInDate', 'CheckedInBy', 'BusyStatus'); L = length(fnames); for i=1:L diff --git a/core/saveAndSyncCellData.m b/core/saveAndSyncCellData.m index 2ad39e7..c8e4b37 100755 --- a/core/saveAndSyncCellData.m +++ b/core/saveAndSyncCellData.m @@ -1,16 +1,14 @@ function [] = saveAndSyncCellData(cellData) global ANALYSIS_FOLDER; -global CELL_DATA_MASTER; global SYNC_TO_SERVER; do_sync = true; -cellDataStatusFileLocation = [CELL_DATA_MASTER 'CellDataStatus.txt']; % Determine server mod time -if exist(CELL_DATA_MASTER, 'dir') == 7 %sever is connected and CellDataMaster folder is found +if exist([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster']) == 7 %sever is connected and CellDataMaster folder is found disp('CellDataMaster found'); try - fileinfo = dir([CELL_DATA_MASTER cellData.savedFileName '.mat']); + fileinfo = dir([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster' filesep cellData.savedFileName '.mat']); serverModDate = fileinfo.datenum; catch serverModDate = 0; @@ -51,7 +49,7 @@ time_elapsed = toc; file_opened = false; while time_elapsed < FILE_IO_TIMEOUT - fid = fopen(cellDataStatusFileLocation, 'r+'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'r+'); if fid>0 file_opened = true; break; @@ -60,7 +58,7 @@ end if ~file_opened - disp(['Unable to open CellDataStatus.txt at' cellDataStatusFileLocation]); + disp('Unable to open CellDataStatus.txt'); return; end @@ -89,7 +87,7 @@ time_elapsed = toc; fclose(fid); while time_elapsed < BUSY_STATUS_TIMEOUT - fid = fopen(cellDataStatusFileLocation, 'r'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'r'); M = textscan(fid, '%s%s%s%u', 'Delimiter', '\t', 'HeaderLines', 1); fnames = M{1}; dates = M{2}; @@ -117,7 +115,7 @@ if curStatus %file is busy disp(['File is busy: ' cellData.savedFileName ' not updated!']); else - fid = fopen(cellDataStatusFileLocation, 'w'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'w'); %write busy flag before copying cellData fnames{ind} = cellData.savedFileName; dates{ind} = datestr(now); @@ -134,7 +132,7 @@ %do the copy disp([cellData.savedFileName ': Copying local file to server']); - save([CELL_DATA_MASTER cellData.savedFileName '.mat'], 'cellData'); + save([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster' filesep cellData.savedFileName '.mat'], 'cellData'); % pause(0.5); %resave local version so modification date is later % disp([cellData.savedFileName ': Local resave']); @@ -143,7 +141,7 @@ %reset busy status to 0 status(ind) = 0; %print file - fid = fopen(cellDataStatusFileLocation, 'w'); + fid = fopen('/Volumes/SchwartzLab/CellDataStatus.txt', 'w'); fprintf(fid,'%s\t%s\t%s\t%s\n','Filename', 'CheckInDate', 'CheckedInBy', 'BusyStatus'); L = length(fnames); for i=1:L diff --git a/imageAnalysis/caImagingAnalysis.m b/imageAnalysis/caImagingAnalysis.m deleted file mode 100644 index 5ef81e4..0000000 --- a/imageAnalysis/caImagingAnalysis.m +++ /dev/null @@ -1,66 +0,0 @@ -function [xPoints, yPoints, signalMat, deltaFoverF, dendDist] = caImagingAnalysis(f_name, thres, pixels, baselineFrames) - -info = imfinfo(f_name); -Nframes = numel(info); -w = info(1).Width; -h = info(1).Height; -cellImageMat = zeros(h,w,Nframes); - -for i=1:Nframes - curImage = imread(f_name, i); - background = imopen(curImage,strel('disk',5)); - curImage = curImage - background; - cellImageMat(:,:,i) = curImage; - -end - -meanImage = mean(cellImageMat, 3); -cellImageMask = meanImage > thres; -cellImageMask = bwareaopen(cellImageMask, 50); -figure; -imagesc(meanImage); -disp('Draw a line along the middle of the ROI. Double click to finish'); -[xpts, ypts] = getline(gcf); -if xpts(1) < w/2 - allX = 1:w; -else - allX = w:-1:1; -end -allY = interp1(xpts, ypts, allX); - -[X,Y] = meshgrid(1:w,1:h); - -%nearPoints = zeros(h,w,w); -z=1; -for i=1:w - if ~isnan(allY(i)) - x = allX(i); - y = allY(i); - dist_2 = sum(bsxfun(@minus, [X(:), Y(:)], [x, y]) .^ 2, 2); - dist_2(cellImageMask(sub2ind([h, w], Y(:), X(:))) == 0) = Inf; - [~, ind] = sort(dist_2); - selectedInd = ind(1:pixels); - - dist_2(selectedInd(pixels)); - if dist_2(selectedInd(pixels)) < Inf - nearPoints = zeros(h,w); - [xNear, yNear] = ind2sub([h, w], selectedInd); - nearPoints(xNear, yNear) = 1; -% imagesc(nearPoints); -% pause; - xPoints(z) = x; - yPoints(z) = y; - signalMat(z,:) = squeeze(mean(mean(cellImageMat(xNear, yNear, :)))); - bg = mean(signalMat(z,1:baselineFrames)); - deltaFoverF(z) = (mean(signalMat(z,baselineFrames+1:end)) - bg) / bg; - z=z+1; - end - end -end - -refPointX = xPoints(1); -refPointY = yPoints(1); - -dendDist = sqrt((xPoints - refPointX).^2 + (yPoints - refPointY).^2); - - diff --git a/imageAnalysis/orderPointsByDistance.m b/imageAnalysis/orderPointsByDistance.m deleted file mode 100644 index 39bd42c..0000000 --- a/imageAnalysis/orderPointsByDistance.m +++ /dev/null @@ -1,62 +0,0 @@ -image_fname = '010517Ac3_mask.tif'; -info = imfinfo(image_fname); -for i=1:numel(info) - cellMask_full(:,:,i) = imresize(imread(image_fname, i), 0.2071602); -end -[maskPointsX, maskPointsY, maskPointsZ] = ind2sub(size(cellMask_full), find(cellMask_full>0)); -maskPointsZ = maskPointsZ * .15; - -cellMask = squeeze(max(cellMask_full, [], 3) > 0); - -A = dlmread('010517Ac3_PSD_masked_puncta.xls', '\t', 1, 0); -allX = A(:,12); -allY = A(:,13); -allZ = A(:,14); -allX = allX * 0.2071602; -allY = allY * 0.2071602; -allZ = allZ * 0.15; - -L = length(allX); -D = ones(L,L) * nan; - -for i=1:L - for j=i+1:L - D(i,j) = sqrt((allX(j) - allX(i))^2 + (allY(j) - allY(i))^2 + (allZ(j) - allZ(i))^2); - end -end - -[minVal, minInd] = min(D); - -distVals = zeros(L, 1); -centerPoints = zeros(L, 3); -for i=1:L - if minVal(i) < 20 - distVals(i) = minVal(i); - centerPoints(i, 1) = mean([allX(i), allX(minInd(i))]); - centerPoints(i, 2) = mean([allY(i), allY(minInd(i))]); - centerPoints(i, 3) = mean([allZ(i), allZ(minInd(i))]); - else - distVals(i) = nan; - centerPoints(i, :) = [nan nan nan]; - end -end - -ind = find(isnan(distVals)); -distVals = distVals(setdiff(1:L, ind)); -centerPoints = centerPoints(setdiff(1:L, ind), :); - -% L = length(distVals);Vq = interp2(X,Y,V,Xq,Yq) r -% for i=1:L -% -% end -% A -V = griddata(centerPoints(:,1),centerPoints(:,2),centerPoints(:,3),1./distVals,maskPointsY,maskPointsX,maskPointsZ); - -cellMask = cellMask * nan; -for i=1:length(maskPointsX) - if ~isnan(V(i)) - cellMask(maskPointsX(i),maskPointsY(i)) = V(i); - else - cellMask(maskPointsX(i),maskPointsY(i)) = nanmean(V); - end -end \ No newline at end of file diff --git a/imageAnalysis/punctaLinearDensity.m b/imageAnalysis/punctaLinearDensity.m deleted file mode 100644 index 2b13542..0000000 --- a/imageAnalysis/punctaLinearDensity.m +++ /dev/null @@ -1,76 +0,0 @@ -image_fname = 'FusedBinaryPSDMask.tif'; -punctaPoints_fname = 'punctaPoints.mat'; -micronsPerPixelXY = 0.1132913; -micronsPerPixelZ = 0.15; - -info = imfinfo(image_fname); -for i=1:numel(info) - cellMask_full(:,:,i) = imresize(imread(image_fname, i), micronsPerPixelXY); -end -[maskPointsX, maskPointsY, maskPointsZ] = ind2sub(size(cellMask_full), find(cellMask_full>0)); -maskPointsZ = maskPointsZ * micronsPerPixelZ; - -cellMask = squeeze(max(cellMask_full, [], 3) > 0); - -% A = dlmread('010517Ac3_PSD_masked_puncta.xls', '\t', 1, 0); -% allX = A(:,12); -% allY = A(:,13); -% allZ = A(:,14); - -load(punctaPoints_fname,'COM'); -allX = COM(:,1); -allY = COM(:,2); -allZ = COM(:,3); - -allX = allX * micronsPerPixelXY; -allY = allY * micronsPerPixelXY; -allZ = allZ * micronsPerPixelZ; - -L = length(allX); -D = ones(L,L) * nan; - -for i=1:L - for j=i+1:L - D(i,j) = sqrt((allX(j) - allX(i))^2 + (allY(j) - allY(i))^2 + (allZ(j) - allZ(i))^2); - end -end - -[minVal, minInd] = min(D); - -distVals = zeros(L, 1); -centerPoints = zeros(L, 3); -for i=1:L - if minVal(i) < 20 - distVals(i) = minVal(i); - centerPoints(i, 1) = mean([allX(i), allX(minInd(i))]); - centerPoints(i, 2) = mean([allY(i), allY(minInd(i))]); - centerPoints(i, 3) = mean([allZ(i), allZ(minInd(i))]); - else - distVals(i) = nan; - centerPoints(i, :) = [nan nan nan]; - end -end - -ind = find(isnan(distVals)); -distVals = distVals(setdiff(1:L, ind)); -centerPoints = centerPoints(setdiff(1:L, ind), :); - -% L = length(distVals);Vq = interp2(X,Y,V,Xq,Yq) r -% for i=1:L -% -% end -% A -V = griddata(centerPoints(:,1),centerPoints(:,2),centerPoints(:,3),1./distVals,maskPointsY,maskPointsX,maskPointsZ); - -densityMap = cellMask * nan; -for i=1:length(maskPointsX) - if ~isnan(V(i)) - densityMap(maskPointsX(i),maskPointsY(i)) = V(i); - else - densityMap(maskPointsX(i),maskPointsY(i)) = 0; - %nanmean(V); - end -end - -imageFilter=fspecial('gaussian',50,6); -densityMap_filtered = nanconv(densityMap,imageFilter,'nanout'); diff --git a/imageAnalysis/punctaMaskFinder.m b/imageAnalysis/punctaMaskFinder.m deleted file mode 100644 index ac08afd..0000000 --- a/imageAnalysis/punctaMaskFinder.m +++ /dev/null @@ -1,65 +0,0 @@ -%punctaMaskFinder(f_name, thres, pixels, baselineFrames) -f_name_puncta = 'TouchingPSDPuncta_sizeFiltered.tif'; -f_name_NB = 'FusedBinaryPSDMask.tif'; -fname_stats = 'PunctaTableTouching.txt'; -overlapThreshold = 0.1; - -info = imfinfo(f_name_puncta); -Nframes = numel(info); -w = info(1).Width; -h = info(1).Height; -punctaImageMat = zeros(h,w,Nframes); -cellImageMat = zeros(h,w,Nframes); - -%load images into matrix -for i=1:Nframes - curImage = imread(f_name_puncta, i); - punctaImageMat(:,:,i) = curImage; - curImage = imread(f_name_NB, i); - cellImageMat(:,:,i) = curImage; -end - -punctaImageMat_binary = punctaImageMat > 0; - -[labelVals, Nobj] = bwlabeln(punctaImageMat_binary); -Nobj -fractionOverlap = zeros(1, Nobj); -closestPunctaInd = zeros(1, Nobj); - - -%load punta COM locations -A = dlmread(fname_stats, '\t', 1, 0); -allX = A(:,12); -allY = A(:,13); -allZ = A(:,14); - -COM = zeros(Nobj, 3); -D = zeros(1,Nobj); -temp = regionprops(punctaImageMat_binary, 'Centroid'); -for i=1:Nobj - COM(i,:) = temp(i).Centroid; - for j=1:Nobj - D(j) = sqrt(sum(([allX(j), allY(j), allZ(j)] - COM(i,:)).^2)); - end - [~, closestPunctaInd(i)] = min(D); -end - -%D = [allX, allY, allZ] - COM; - -%find fraction overlap -for i=1:Nobj - i - maskPixInd = find(labelVals == i); - maskPixels = length(maskPixInd); - overlapPixels = length(find(labelVals == i & cellImageMat > 0)); - fractionOverlap(i) = overlapPixels ./ maskPixels; -end -countedPunctaInd = fractionOverlap>overlapThreshold; -COM = COM(countedPunctaInd, :); - -countedPuncta = closestPunctaInd(fractionOverlap>overlapThreshold); -Xpos = allX(countedPunctaInd); -Ypos = allY(countedPunctaInd); - - - diff --git a/imageAnalysis/volumeColocAnalysis.m b/imageAnalysis/volumeColocAnalysis.m deleted file mode 100644 index 6e451ab..0000000 --- a/imageAnalysis/volumeColocAnalysis.m +++ /dev/null @@ -1,110 +0,0 @@ -function [pixelAvg, pixelAvg90, pixelAvg180, pixelAvg270, withinVals, vals90, vals180, vals270] = volumeColocAnalysis(image_fname) -Nchannels = 3; -cellChannel = 1; -quantChannel = 2; -searchArea = 20; %pixels - -imageData = bfopen(image_fname); -rawImageSequence = imageData{1,1}; -cellImageSeq = rawImageSequence(cellChannel:Nchannels:end, 1); -quantImageSeq = rawImageSequence(quantChannel:Nchannels:end, 1); - -Nframes = length(cellImageSeq); -[pixX, pixY] = size(cellImageSeq{1}); -cellImageMat = zeros(pixX, pixY, Nframes); -cellImageMask = zeros(pixX, pixY, Nframes); -quantImageMat = zeros(pixX, pixY, Nframes); -quantImageMat180 = zeros(pixX, pixY, Nframes); - -if pixX == pixY - quantImageMat90 = zeros(pixY, pixX, Nframes); - quantImageMat270 = zeros(pixY, pixX, Nframes); -end -thresLevel = zeros(1, Nframes); - -for i=1:Nframes - cellImageMat(:,:,i) = cellImageSeq{i}; - quantImageMat(:,:,i) = quantImageSeq{i}; - quantImageMat180(:,:,i) = imrotate(quantImageSeq{i}, 180); - - if pixX == pixY - quantImageMat90(:,:,i) = imrotate(quantImageSeq{i}, 90); - quantImageMat270(:,:,i) = imrotate(quantImageSeq{i}, 270); - end - - thresLevel(i) = graythresh(squeeze(cellImageMat(:,:,i))); - %thresLevel(i) = 1; - cellImageMask(:,:,i) = im2bw(cellImageMat(:,:,i), thresLevel(i)); - %cellImageMask(:,:,i) = cellImageMat(:,:,i) > 1500; -end -temp = quantImageMat .* cellImageMask; -withinVals = temp(:); -withinValMean = mean(temp(:)); - - -temp = quantImageMat180 .* cellImageMask; -vals180 = temp(:); -withinVal180Mean = mean(temp(:)); - - -if pixX == pixY - temp = quantImageMat90 .* cellImageMask; - vals90 = temp(:); - withinVal90Mean = mean(temp(:)); - - temp = quantImageMat270 .* cellImageMask; - vals270 = temp(:); - withinVal270Mean = mean(temp(:)); -end - -if pixX == pixY - valsControl = [vals90; vals180; vals270]; -else - valsControl = vals180; -end - -%pixelTriggeredAverage part -withinInd = find(cellImageMask==1); - -L = length(withinInd); -pixelAvg = zeros(searchArea+1, searchArea+1); -pixelAvg180 = zeros(searchArea+1, searchArea+1); - -if pixX == pixY - pixelAvg90 = zeros(searchArea+1, searchArea+1); - pixelAvg270 = zeros(searchArea+1, searchArea+1); -end - - -z = 0; -%L -%pause; -for i=1:L - % i - [x, y, f] = ind2sub([pixX, pixY, Nframes], withinInd(i)); - if x > round(searchArea/2) && x < pixX - round(searchArea/2) && y > round(searchArea/2) && y < pixY - round(searchArea/2); - pixelAvg = pixelAvg + quantImageMat(x-round(searchArea/2):x+round(searchArea/2), y-round(searchArea/2):y+round(searchArea/2), f); - pixelAvg180 = pixelAvg180 + quantImageMat180(x-round(searchArea/2):x+round(searchArea/2), y-round(searchArea/2):y+round(searchArea/2), f); - - if pixX == pixY - pixelAvg90 = pixelAvg90 + quantImageMat90(x-round(searchArea/2):x+round(searchArea/2), y-round(searchArea/2):y+round(searchArea/2), f); - pixelAvg270 = pixelAvg270 + quantImageMat270(x-round(searchArea/2):x+round(searchArea/2), y-round(searchArea/2):y+round(searchArea/2), f); - end - - z=z+1; - end -end -pixelAvg = pixelAvg./z; -pixelAvg180 = pixelAvg180./z; - -if pixX == pixY - pixelAvg90 = pixelAvg90./z; - pixelAvg270 = pixelAvg270./z; -else - pixelAvg90 = []; - pixelAvg270 = []; - vals90 = []; - vals270 = []; -end - - diff --git a/shapeModel/exploreEICombination.m b/shapeModel/exploreEICombination.m deleted file mode 100644 index e34fbfa..0000000 --- a/shapeModel/exploreEICombination.m +++ /dev/null @@ -1,34 +0,0 @@ -clf -x = []; -y = []; -for ci = 1:size(dtab,1) - if ~strcmp(dtab{ci, 'cellType'}, 'ON WFDS') - continue - end - - - ex = dtab{ci, 'SMS_charge_ex'}{1}; - in = dtab{ci, 'SMS_charge_inh'}{1}; - sp = dtab{ci, 'SMS_onSpikes'}{1}; - - if isempty(ex) || isempty(in) || isempty(sp) - continue - end - if length(ex) ~= length(sp) - continue - end - - wc = ex(3:10) + in(3:10)/20; - ca = sp(3:10); - x = [x; wc]; - y = [y; ca]; - - -end -plot(x, y, 'o') -xlabel('wc') -ylabel('sp') -p = polyfit(x,y,3); -k = polyval(p, sort(x)); -hold on -plot(sort(x),k) \ No newline at end of file diff --git a/shapeModel/extractMovingBarResponses.m b/shapeModel/extractMovingBarResponses.m index 4c12d6e..7a5c463 100644 --- a/shapeModel/extractMovingBarResponses.m +++ b/shapeModel/extractMovingBarResponses.m @@ -9,12 +9,10 @@ tEnd = 2.0; barOrEdge = 1; -c_responses = {}; % ha = tight_subplot(12, 4); -% vi: 1 ex, 2 in, 3 spike rate over time, 4 flat line spike count -for vi = 1:3 +for vi = 1:4; if strcmp(cellName, '060216Ac2') if vi == 1 % ex startEpoch = 343; @@ -91,17 +89,12 @@ if vi < 3 response = epoch.getData('Amplifier_Ch1'); else - spikes = epoch.getSpikes() / 10000; - spikes(spikes > tEnd) = []; - if vi == 3 -% spikeRate = zeros(size(response)); -% spikeRate(spikes) = 1.0; - tbins = 0:1/10000:tEnd; - tbins = [tbins, inf]; - spikeRate = histcounts(spikes, tbins); - response = spikeRate; -% response = filtfilt(hann(10000 / 10), 1, spikeRate); % 10 ms (100 samples) window filter - elseif vi == 4 + spikes = epoch.getSpikes(); + if vi < 4 + spikeRate = zeros(size(response)); + spikeRate(spikes) = 1.0; + response = filtfilt(hann(10000 / 10), 1, spikeRate); % 10 ms (100 samples) window filter + else response = ones(length(response),1) * length(spikes); end end @@ -128,7 +121,7 @@ epochIndices = find(epochAngles == c_angles(ai)); mn = mean(responses(epochIndices,:), 1); -% mn = smooth(mn, 30); + mn = smooth(mn, 30); mn = mn(1:10000*tEnd+1); baseline = mean(mn(1:0.2*10000)); mn = mn - baseline; diff --git a/shapeModel/lightStepResponseParamFit.m b/shapeModel/lightStepResponseParamFit.m deleted file mode 100644 index 5a8a793..0000000 --- a/shapeModel/lightStepResponseParamFit.m +++ /dev/null @@ -1,50 +0,0 @@ -% solves parameters for fitting light step responses -% eid = 101; -% stepResponse = cellData.epochs(eid).getData('Amplifier_Ch1'); - -% function lightStepResponseParamFit(stepResponse, voltage, - -% stepResponse = meanData'; -voltage = -60; -preTimeSec = cellData.epochs(eid).get('preTime') / 1000; -stepResponse = stepResponse - mean(stepResponse(1:(preTimeSec * 10000))); -stepResponse = stepResponse(1:10000 * 1.5); -stepResponse = stepResponse ./ prctile(abs(stepResponse), 99); -stepResponse = stepResponse ./ sign(voltage); -stepResponse = stepResponse(preTimeSec * 10000 : end); -r = resample(stepResponse, round(1/sim_timeStep), 10000); - - - -% delay, rise dur, hold dur, decay time constant, baseline to peak ratio -x0 = [.05, .01, .02, .2, 0]; -fToMin = @(p) mean(power(abs(makeParametricResponse(p, sim_timeStep, length(r)) - r), 2)); - - -figure(10);clf; -hold on -plot(r) -plot(makeParametricResponse(x0, sim_timeStep, length(r))) - -p = x0; -for i = 1:5 - [p, f] = fminsearch(fToMin, p); -end - - -plot(makeParametricResponse(p, sim_timeStep, length(r))) -hold off -legend('signal','initial','final') - -function d = makeParametricResponse(p, sim_timeStep, len) - - delay = zeros(1, round(p(1) / sim_timeStep)); - rise = linspace(0, 1, round(p(2) / sim_timeStep)); - holds = ones(1, round(p(3) / sim_timeStep)); - decay = (1-p(5))*exp(-1 * (sim_timeStep:sim_timeStep:10) / p(4)) + p(5); - - sig = horzcat(delay, rise, holds, decay); -% d = diff(sig); - d = sig(1:len)'; - -end \ No newline at end of file diff --git a/shapeModel/runShapeModel.m b/shapeModel/runShapeModel.m index b9380e3..f69287c 100644 --- a/shapeModel/runShapeModel.m +++ b/shapeModel/runShapeModel.m @@ -9,8 +9,7 @@ useRealRf = 0; useRealFilters = 0; -useSubunits = 0; -useOffFilters = 0; +useSubunits = 1; % cellName = '033116Ac2'; % nice RF with edges and bars, but missing bars spikes and inhibitory temporal align % acName = '263'; @@ -27,7 +26,7 @@ calcDsi = @(angles, values) abs(sum(exp(sqrt(-1) * angles) .* values) / sum(values)); -plotSpatialGraphs = 1; +plotSpatialGraphs = 0; plotStimulus = 0; plotSubunitCurrents = 0; plotOutputCurrents = 1; @@ -55,15 +54,15 @@ -%% Big parameter loop around overall parameters - +%% disp('Running full simulation'); -paramColumnNames = {'spatial offset', 'ex delay', }; -col_rfOffset = 1; -col_barSpeed = 2; -col_filterDelay = 1; +%% Big parameter loop around 12 angles and simulation core + +paramColumnNames = {'positionOffset'}; +col_positionOffset = 1; +col_barSpeed = 1; % paramValues = {0; % 10; @@ -74,46 +73,18 @@ % 975; % 1365}; - -% paramValues = [.1, 20]; - -paramValues = [0; - 2; -% 8; - 16; -% 24; - 35; - 52; - 75]; +paramValues = {1000}; % barspeed + - -% paramValues = [.04; -% .05; -% .06; -% .07; -% .08]; - - -% p1 = [.04,.07,.1]; -% p2 = [2,12,32]; -% -% paramValues = []; -% -% for i1 = 1:length(p1) -% for i2 = 1:length(p2) -% paramValues(end+1,1:2) = [p1(i1),p2(i2)]; -% end -% end - [numParamSets,numParams] = size(paramValues); dsiByParamSet = []; valuesByParamSet = []; -tic + for paramSetIndex = 1:numParamSets - fprintf('Param Set %d: %s\n', paramSetIndex, mat2str(paramValues(paramSetIndex,:))); + fprintf('Param Set %d: %s\n', paramSetIndex, num2str(paramValues{paramSetIndex,:})); %% Setup @@ -135,44 +106,6 @@ end -disp('Model run complete') -toc - -%% display DSI over parameters -if numParamSets >= 3 - figure(901);clf; - - if numParams == 1 - d1 = linspace(min(paramValues(:,1)), max(paramValues(:,1)), 10); - m = interp1(paramValues(:,1), dsiByParamSet, d1); - plot(d1, m) - - %% Plot WFDS cells - hold on - plot(abs(dtab{selectWfdsOn,'spatial_exin_offset'}), dtab{selectWfdsOn,'best_DSI_sp'}, '.', 'MarkerSize', 20) - plot(abs(dtab{selectWfdsOff,'spatial_exin_offset'}), dtab{selectWfdsOff,'best_DSI_sp'}, '.', 'MarkerSize', 20) - plot(abs(dtab{selectControl,'spatial_exin_offset'}), dtab{selectControl,'best_DSI_sp'}, '.', 'MarkerSize', 20) - hold off - legend('Model','WFDS ON','WFDS OFF','Control') - xlabel(paramColumnNames{1}) - ylabel('DSI') - - elseif numParams == 2 - d1 = linspace(min(paramValues(:,1)), max(paramValues(:,1)), 10); - d2 = linspace(min(paramValues(:,2)), max(paramValues(:,2)), 10); - - [d1q,d2q] = meshgrid(d1, d2); - c = griddata(paramValues(:,1), paramValues(:,2), dsiByParamSet, d1q, d2q); - surface(d1q, d2q, zeros(size(d1q)), c) - hold on -% plot(paramValues(:,1), paramValues(:,2), '.', 'MarkerSize', 40) - hold off - xlabel(paramColumnNames{1}) - ylabel(paramColumnNames{2}) - colorbar - end -end - %% process output nonlinearity % speeds = cell2mat(paramValues)'; diff --git a/shapeModel/shapeModelAnalyzeOutput.m b/shapeModel/shapeModelAnalyzeOutput.m index 52a5c10..3cd8a35 100644 --- a/shapeModel/shapeModelAnalyzeOutput.m +++ b/shapeModel/shapeModelAnalyzeOutput.m @@ -11,13 +11,12 @@ out_valsByOptions = []; plot_timeLims = [0.0, sim_endTime]; -timeOffsetSim = -.01; -timeOffsetSpikes = -.3; -ephysScale = .1; +timeOffsetSim = -0.21; +timeOffsetSpikes = -.35; +ephysScale = 1; simScale = [1, .5; 1, .5] * 1000; % scaling the sim relative to ephys -combineScaleCurrents = [3, 3; 1, 1]; % voltages; ooi -combineScaleSpikes = .1; -additiveOffset = .5; % add to overall output current +combineScaleCurrents = [2, 2; 1, 1]; % voltages, ooi +combineScaleSpikes = 1; % displayScale = [5,2.2]; plotYLimsScale = 1; fitAnalysisLimits = [.2, 1.5]; @@ -33,7 +32,7 @@ outputSignals = []; outputLabels = {}; - ang = stim_directions(optionIndex); +% ang = stim_directions(optionIndex); % Output scale sim_responseSubunitsCombinedScaled = sim_responseSubunitsCombinedByOption{optionIndex}; for vi = 1:e_numVoltages @@ -78,56 +77,43 @@ outputLabels{end+1} = 'comb_s'; % ephys responses (ex, in, spikes) - displayEphysResponses = false; - if displayEphysResponses - Esel = T > plot_timeLims(1) & T < plot_timeLims(2); - simShift = timeOffsetSim / sim_timeStep; - cell_responses = []; - - for vi = 1:3 %3 %enables spikes - mn = ephysScale * c_responses{vi, c_angles == ang}.mean; - - if vi <= 2 - scale = combineScaleCurrents(vi,oi); - else - scale = combineScaleSpikes; - end - mn = scale * resample(mn, round(1/sim_timeStep), 10000); - cell_responses(vi,:) = mn; - rcell = cell_responses(vi,Esel); - if simShift >= 0 - outputSignals(end+1,:) = rcell(simShift:end); - else - outputSignals(end+1,:) = [zeros(1,-simShift), rcell(1:end+2*simShift+1)]; - end - l = {'ex_e','in_e','spike_e'}; - outputLabels{end+1} = l{vi}; - % - % if vi < 3 - % plot(T(Esel), mn(Esel)) - % else - % plot(T(Esel) + timeOffsetSpikes, mn(Esel)); - % end - - - end - end + Esel = T > plot_timeLims(1) & T < plot_timeLims(2); + simShift = timeOffsetSim / sim_timeStep; + cell_responses = []; - -% ephys combined values - displayEphysCombinedValues = false; - if displayEphysCombinedValues - cell_responsesCombined = sum(cell_responses(1:2,:)); - rcell = cell_responsesCombined(Esel); - if simShift >= 0 - outputSignals(end+1,:) = rcell(simShift:end); %#ok<*SAGROW> - else - outputSignals(end+1,:) = [zeros(1,-simShift), rcell(1:end+2*simShift+1)]; - end - outputLabels{end+1} = 'comb_e'; - end - -% % % extract values for comparison plot +% for vi = 1:3 %3 %enables spikes +% mn = ephysScale * c_responses{vi, c_angles == ang}.mean; +% +% mn = combineScale(vi) * resample(mn, round(1/sim_timeStep), 10000); +% cell_responses(vi,:) = mn; +% rcell = cell_responses(vi,Esel); +% if simShift >= 0 +% outputSignals(end+1,:) = rcell(simShift:end); +% else +% outputSignals(end+1,:) = [zeros(1,-simShift), rcell(1:end+2*simShift+1)]; +% end +% l = {'ex_e','in_e','spike_e'}; +% outputLabels{end+1} = l{vi}; +% +% % if vi < 3 +% % plot(T(Esel), mn(Esel)) +% % else +% % plot(T(Esel) + timeOffsetSpikes, mn(Esel)); +% % end +% +% +% end + % ephys combined values +% cell_responsesCombined = sum(cell_responses(1:2,:)); +% rcell = cell_responsesCombined(Esel); +% if simShift >= 0 +% outputSignals(end+1,:) = rcell(simShift:end); %#ok<*SAGROW> +% else +% outputSignals(end+1,:) = [zeros(1,-simShift), rcell(1:end+2*simShift+1)]; +% end +% outputLabels{end+1} = 'comb_e'; + + % extract values for comparison plot % out_valsByOptions(optionIndex, 2) = -1*sum(cell_responsesCombined(cell_responsesCombined < 0)) / sim_dims(1); % out_valsByOptions(optionIndex, 3) = -1*sum(cell_responses(3,:)) / sim_dims(1); @@ -141,7 +127,7 @@ if plotCellResponses % then plot all the signals together - plotSelect = logical([1,0,1,0,1,0,0,0,0]); + plotSelect = logical([1,1,1,1,1]); plot(Tsim, outputSignals(plotSelect,:)'); legend(outputLabels(plotSelect),'Location','Best'); xlim(plot_timeLims); @@ -221,8 +207,7 @@ % nonlinOutput = polyfit(out_valsByOptions(:,1), out_valsByOptions(:,3),1); % out_valsByOptions(:,4) = polyval(nonlinOutput, out_valsByOptions(:,1)); - ordering = [5];%,8,9]; - dataSetToExport = 5; % this is the one for the overall output comparison + ordering = [5]; % ordering = 1; for ti = ordering angles = deg2rad(stim_directions)'; @@ -231,22 +216,17 @@ signals = outputSignalsByOption{oi}; values(oi,1) = -sum(signals(ti, signals(ti,:) < 0)) * sim_timeStep; end - values = values + additiveOffset; % outputStruct.(sprintf('byang_%s',outputLabels{ti})) = values; a = [angles; angles(1)]; v = [values; values(1)]; - v = v / mean(v); polarplot(a, v) hold on - dsi = abs(sum(exp(sqrt(-1) * angles) .* values) / sum(values)); - if dataSetToExport == ti - dsiByParamSet(paramSetIndex,1) = dsi; - valuesByParamSet(paramSetIndex,:) = values; - - end + dsi = abs(sum(exp(sqrt(-1) * angles) .* values) / sum(values)) + dsiByParamSet(paramSetIndex,1) = dsi; + valuesByParamSet(paramSetIndex,:) = values; end hold off diff --git a/shapeModel/shapeModelParameterSetup.m b/shapeModel/shapeModelParameterSetup.m index 33edeba..60b7e98 100644 --- a/shapeModel/shapeModelParameterSetup.m +++ b/shapeModel/shapeModelParameterSetup.m @@ -1,6 +1,6 @@ % shapeModelSetup -sim_endTime = 2.5; +sim_endTime = 5.0; sim_timeStep = 0.005; sim_spaceResolution = 3; % um per point s_sidelength = 350;%max(cell_rfPositions); @@ -12,9 +12,7 @@ c_subunit2SigmaWidth_surround = [80 80; 120 120]; c_subunitSurroundRatio = [0.15 0.15; 0.0 0.0]; -% paramValues(paramSetIndex,col_rfOffset) -% positionOffsetByVoltageDim = [6, 8; 0, 0]; -positionOffsetByVoltageDim = [paramValues(paramSetIndex,col_rfOffset), 0; 0, 0]; +positionOffsetByVoltage = [13,0]; % generate RF map for EX and IN % import completed maps @@ -78,7 +76,7 @@ % add null corners to ground the spatial map at edges if useRealRf positions = e_positions{vi, ii}; - positions = bsxfun(@plus, positions, [positionOffsetByVoltageDim(vi,1),positionOffsetByVoltageDim(vi,2)]); + positions = bsxfun(@plus, positions, [0,positionOffsetByVoltage(vi)]); vals = e_vals{vi,ii,:}; % positions = vertcat(positions, [X(1),Y(1);X(end),Y(1);X(end),Y(end);X(1),Y(end)]); % vals = vertcat(vals, [0,0,0,0]'); @@ -86,9 +84,8 @@ 'linear','none'); m = F(mapX, mapY) * sign(e_voltages(vi)); else - % Simple gaussian RF approximation - d = sqrt((mapY-positionOffsetByVoltageDim(vi,2)).^2 + 2*(mapX-positionOffsetByVoltageDim(vi,1)).^2); - m = exp(-d.^2 / 60^2); + d = sqrt((mapY-positionOffsetByVoltage(vi)).^2 + mapX.^2); + m = -20 + 100*exp(-d.^2 / 80^2); end m(isnan(m)) = 0; diff --git a/shapeModel/shapeModelParameterizedFilters.m b/shapeModel/shapeModelParameterizedFilters.m index 01a3c24..8d56185 100644 --- a/shapeModel/shapeModelParameterizedFilters.m +++ b/shapeModel/shapeModelParameterizedFilters.m @@ -1,65 +1,51 @@ -% polarity, delay, rise dur, hold dur, decay time constant, baseline to peak ratio +% polarity, delay, rise dur, hold dur, decay time constant filtParams = cell(2); % ON EX -% filtParams{1,1} = [-1, .065, .016, 0, .03]; % 060216Ac2 -filtParams{1,1} = [-1, .175, .05, 0, .08, 0];% 010716Ac1 - -% paramValues(paramSetIndex,col_filterDelay) +filtParams{1,1} = [-1, .065, .016, 0, .03]; % ON IN -% filtParams{2,1} = [1, .057, .08, .13, .1, .4]; % 060216Ac2 -filtParams{2,1} = [1, .14, .08, .08, .3, 0]; % 010716Ac1 - +filtParams{2,1} = [1, .057, .03, .051, .055]; % OFF EX -filtParams{1,2} = [-1, .065, .016, 0, .03, 0]; +filtParams{1,2} = [-1, .065, .016, 0, .03]; % OFF IN -filtParams{2,2} = [1, .057, .03, .051, .055, 0]; +filtParams{2,2} = [1, .057, .03, .051, .055]; filters = cell(2); -plotFilters = false; -if plotFilters - clf - figure(55); - ha = tight_subplot(2,2); -end +% clf +% figure(55); +% ha = tight_subplot(2,2); for vi = 1:2 for oi = 1:2 - if ~useOffFilters && oi == 2 - filters{vi,oi} = 0; - continue - end - p = filtParams{vi,oi}; delay = zeros(1, round(p(2) / sim_timeStep)); rise = linspace(0, 1, round(p(3) / sim_timeStep)); holds = ones(1, round(p(4) / sim_timeStep)); - decay = (1-p(6))*exp(-1 * (sim_timeStep:sim_timeStep:2) / p(5)) + p(6); + decay = exp(-1 * (sim_timeStep:sim_timeStep:.3) / p(5)); sig = horzcat(delay, rise, holds, decay) * p(1); -% sig(end+1) = 0; + sig(end+1) = 0; d = diff(sig); filters{vi,oi} = d; - if plotFilters - axes(ha((oi - 1) * 2 + vi)); - t = (1:length(sig)) * sim_timeStep; - plot(t, sig); - hold on - t = (1:length(lightResponses{vi,oi})) / 10000 - .5; - r = lightResponses{vi,oi}; - r = r - mean(r(1:2500)); - r = r / prctile(abs(r(1:10000)), 98); - plot(t, r) - hold off - end + +% axes(ha((oi - 1) * 2 + vi)); +% t = (1:length(sig)) * sim_timeStep; +% plot(t, sig); +% hold on +% t = (1:length(lightResponses{vi,oi})) * .001; +% r = lightResponses{vi,oi}; +% r = r - mean(r(1:20)); +% r = r / max(abs(r)); +% plot(t, r) +% hold off end end diff --git a/shapeModel/shapeModelStimSetup.m b/shapeModel/shapeModelStimSetup.m index 5c62956..e26096e 100644 --- a/shapeModel/shapeModelStimSetup.m +++ b/shapeModel/shapeModelStimSetup.m @@ -1,15 +1,16 @@ -stim_mode = 'movingBar'; -numAngles = 12; -stim_directions = linspace(0,360,numAngles+1); -stim_directions(end) = []; -stim_numOptions = length(stim_directions); - -stim_barSpeed = 500;%paramValues(paramSetIndex,col_barSpeed); -stim_barLength = 500; -stim_barWidth = 150; -stim_moveTime = sim_endTime + 1.0; -stim_intensity = 0.5; +% stim_mode = 'movingBar'; +% numAngles = 12; +% stim_directions = linspace(0,360,numAngles+1); +% stim_directions(end) = []; +% % stim_directions = [210]; +% stim_numOptions = length(stim_directions); +% +% stim_barSpeed = paramValues{paramSetIndex,col_barSpeed}; +% stim_barLength = 500; +% stim_barWidth = 150; +% stim_moveTime = sim_endTime + 1.0; +% stim_intensity = 0.5; % SMS % stim_mode = 'flashedSpot'; @@ -27,20 +28,20 @@ % stim_intensity = 0.5; % stim_spotPosition = [0,0]; -% stim_mode = 'driftingTexture'; -% numAngles = 9; -% stim_directions = linspace(0,360,numAngles+1); -% stim_directions(end) = []; -% stim_numOptions = length(stim_directions); -% -% stim_texSpeed = 500; -% stim_moveTime = sim_endTime + 1.0; -% stim_meanLevel = 0.5; -% stim_uniformDistribution = 1; -% stim_resScaleFactor = 2; -% stim_randomSeed = 1; -% stim_textureScale = 30; -% stim_movementDelay = 0.5; +stim_mode = 'driftingTexture'; +numAngles = 9; +stim_directions = linspace(0,360,numAngles+1); +stim_directions(end) = []; +stim_numOptions = length(stim_directions); + +stim_texSpeed = 500; +stim_moveTime = sim_endTime + 1.0; +stim_meanLevel = 0.5; +stim_uniformDistribution = 1; +stim_resScaleFactor = 2; +stim_randomSeed = 1; +stim_textureScale = 60; +stim_movementDelay = 0.5; stim_lightMatrix_byOption = {}; diff --git a/transcriptomeAnalysys/concatenateDataSets.m b/transcriptomeAnalysys/concatenateDataSets.m deleted file mode 100644 index e03ab4e..0000000 --- a/transcriptomeAnalysys/concatenateDataSets.m +++ /dev/null @@ -1,19 +0,0 @@ -function [cellIDs_all, cellType_all, D_all, eyeVec_all, geneCounts_all, xPos_all, yPos_all, geneNames] = concatenateDataSets(varargin) -cellIDs_all = []; -cellType_all = []; -D_all = []; -eyeVec_all = []; -geneCounts_all = []; -xPos_all = []; -yPos_all = []; -for i=1:nargin - setName = varargin{i}; - load(setName); - cellIDs_all = [cellIDs_all, cellIDs]; - cellType_all = [cellType_all, cellType]; - eyeVec_all = [eyeVec_all, eyeVec]; - xPos_all = [xPos_all, xPos]; - yPos_all = [yPos_all, yPos]; - geneCounts_all = [geneCounts_all, geneCounts]; - D_all = [D_all, D]; -end \ No newline at end of file diff --git a/transcriptomeAnalysys/fullSelectiveExpressionMatrix.m b/transcriptomeAnalysys/fullSelectiveExpressionMatrix.m deleted file mode 100644 index ddd823d..0000000 --- a/transcriptomeAnalysys/fullSelectiveExpressionMatrix.m +++ /dev/null @@ -1,36 +0,0 @@ -function [D_full, uniqueTypes_sorted, NofEach_sorted, allGeneNames] = fullSelectiveExpressionMatrix(D, cellTypes, geneNames, Ngenes, method) -uniqueTypes = unique(cellTypes); - -Ntypes = length(uniqueTypes); -NofEach = zeros(1,Ntypes); -%sort by most prevalent -for i=1:Ntypes - NofEach(i) = length(find(strcmp(uniqueTypes{i}, cellTypes))); -end -[NofEach_sorted, ind] = sort(NofEach, 'descend'); -uniqueTypes_sorted = uniqueTypes(ind); - -Ntestable = length(find(NofEach>2)); - -%sort by type -ind = []; -for i=1:Ntypes - ind = [ind, find(strcmp(uniqueTypes_sorted{i}, cellTypes))]; -end -%ind -D_sorted = D(:,ind); -cellTypes = cellTypes(ind); - -%make full matrix -D_full = zeros(Ngenes*Ntestable,length(cellTypes)); -allGeneNames = []; -curInd = 1; -for i=1:Ntypes - if NofEach_sorted(i) > 2 - [~, ~, ~, curD, ~, geneNames_sorted] = ... - selectiveExpressionMatrix(D_sorted, cellTypes, geneNames, uniqueTypes_sorted{i}, Ngenes, method); - D_full(curInd:curInd+Ngenes-1,:) = curD; - allGeneNames = [allGeneNames; geneNames_sorted]; - curInd = curInd+Ngenes; - end -end \ No newline at end of file diff --git a/transcriptomeAnalysys/readGenomicsData.m b/transcriptomeAnalysys/readGenomicsData.m deleted file mode 100644 index 71eed9a..0000000 --- a/transcriptomeAnalysys/readGenomicsData.m +++ /dev/null @@ -1,33 +0,0 @@ -function [cellIDs, eyeVec, xPos, yPos, cellType, geneNames, geneCounts, D] = readGenomicsData(filename, geneCountThreshold) -A = readtable(filename, 'ReadVariableNames', false, 'Delimiter', '\t'); -cellIDs = A{1,2:end}; -% eyeVec = A{2,2:end}; -% xPos = A{3,2:end}; -% yPos = A{4,2:end}; -% cellType = A{5,2:end}; - -cellType = A{2,2:end}; -eyeVec = A{3,2:end}; -xPos = A{4,2:end}; -yPos = A{5,2:end}; - - -geneNames = A{6:end,1}; -D = str2double(A{6:end,2:end}); -D_thres = D>2; - -geneCounts = sum(D_thres,1); - -goodInd = find(geneCounts > geneCountThreshold); -disp([num2str(length(goodInd)) ' of ' num2str(length(geneCounts)) ' cells passed threshold of ' num2str(geneCountThreshold) ' genes.']); - -cellIDs = cellIDs(goodInd); -eyeVec = eyeVec(goodInd); -xPos = xPos(goodInd); -yPos = yPos(goodInd); -cellType = cellType(goodInd); -D = D(:, goodInd); -geneCounts = geneCounts(goodInd); - - - diff --git a/transcriptomeAnalysys/selectiveExpressionMatrix.m b/transcriptomeAnalysys/selectiveExpressionMatrix.m deleted file mode 100644 index c85a818..0000000 --- a/transcriptomeAnalysys/selectiveExpressionMatrix.m +++ /dev/null @@ -1,63 +0,0 @@ -function [D_sorted, D_target, D_others, D_origOrder, indexVals_sorted, geneNames_sorted, targetInd, othersInd] = selectiveExpressionMatrix(D, cellTypes, geneNames, selection, Ngenes, method) -if ischar(selection) - selectedType = selection; - targetInd = find(strcmp(selectedType, cellTypes)); - disp([num2str(length(targetInd)) ' cells of type: ' selectedType]); - othersInd = setdiff(1:length(cellTypes), targetInd); -else - targetInd = selection; - disp([num2str(length(targetInd)) ' cells selected.']); - othersInd = setdiff(1:length(cellTypes), targetInd); -end - - -thresVal = 10; -N = length(geneNames); -indexVals = zeros(N,1); -switch method - case 'log-ratio' - D(D<2) = 1; - logD = log10(D); - for i=1:N - targetMed = median(logD(i,targetInd)); - otherMed = median(logD(i,othersInd)); - indexVals(i) = targetMed - otherMed; - end - - case 'threshold' - D_thres = D>thresVal; - for i=1:N - targetFrac = sum(D_thres(i,targetInd))./length(targetInd); - otherFrac = sum(D_thres(i,othersInd))./length(targetInd); - indexVals(i) = targetFrac - otherFrac; - end - - case 'p-value' - D(D<10) = 1; - logD = log10(D); - for i=1:N - targetVals = logD(i,targetInd); - otherVals = logD(i,othersInd); - [~, indexVals(i)] = ttest2(targetVals, otherVals, 'tail', 'right'); - end -end - -[indexVals_sorted, ind] = sort(indexVals, 'ascend'); -geneNames_sorted = geneNames(ind); - -geneNames_sorted = geneNames_sorted(1:Ngenes); -D(D<3) = 0; -D_origOrder = D(ind(1:Ngenes), :); -D_target = D(ind(1:Ngenes), targetInd); -D_others = D(ind(1:Ngenes), othersInd); -D_sorted = [D_target, D_others]; - - - -%method is one of the following options: -% threshold -% log-ratio -% p-value - - - diff --git a/transcriptomeAnalysys/testGene.m b/transcriptomeAnalysys/testGene.m deleted file mode 100644 index b1f9272..0000000 --- a/transcriptomeAnalysys/testGene.m +++ /dev/null @@ -1,8 +0,0 @@ -function [targetCounts, othersCounts, targetInd, othersInd] = testGene(D, geneNames, cellTypes, targetGene, selectedType) -targetInd = find(strcmp(selectedType, cellTypes)); -disp([num2str(length(targetInd)) ' cells of type: ' selectedType]); -othersInd = setdiff(1:length(cellTypes), targetInd); - -geneInd = find(strcmp(targetGene, geneNames)); -targetCounts = D(geneInd, targetInd); -othersCounts = D(geneInd, othersInd); diff --git a/utilities/LIF.m b/utilities/LIF.m index 4ac2f77..9eec1ba 100755 --- a/utilities/LIF.m +++ b/utilities/LIF.m @@ -1,4 +1,3 @@ - % Integrate and fire %DEFINE PARAMETERS @@ -7,9 +6,9 @@ t_end = 2000; %total time of run [ms] t_StimStart = 0; %time to start injecting current [ms] t_StimEnd = 1000; %time to end injecting current [ms] -E_L = -62; %resting membrane potential [mV] -V_th = -56; %spike threshold [mV] -V_reset = -70; %value to reset voltage to after a spike [mV] +E_L = -60; %resting membrane potential [mV] +V_th = -58; %spike threshold [mV] +V_reset = -65; %value to reset voltage to after a spike [mV] V_spike = 20; %value to draw a spike to, when cell spikes [mV] R_m = 500; %membrane resistance [MOhm] tau_mem = 1; %membrane time constant [ms] @@ -115,4 +114,4 @@ figure; plot(timeAxis_PSTH./1000,PSTH); xlabel('Time (ms)'); -ylabel('Spike rate (Hz)'); \ No newline at end of file +ylabel('Spike rate (Hz)'); diff --git a/utilities/Suppression.m b/utilities/Suppression.m deleted file mode 100644 index a4a6c8b..0000000 --- a/utilities/Suppression.m +++ /dev/null @@ -1,16 +0,0 @@ -Response = nodeData.spikeCount_stimInterval_grndBlSubt.mean_c; -SpotSize = nodeData.spotSize; - -LargeSpotI = find(abs(SpotSize - 1200)<50); -LargeSpotR = Response(LargeSpotI); -BestSpotR = max(Response); - -Supressed = (BestSpotR - LargeSpotR)/BestSpotR; - -Names(i) = {nodeData.cellName} -Data(i) = Supressed - -i = i + 1; - - -%Run at beggining Data = [] Names = {} i=1 diff --git a/utilities/addDsiOsiVarTitle.m b/utilities/addDsiOsiVarTitle.m deleted file mode 100644 index 667df53..0000000 --- a/utilities/addDsiOsiVarTitle.m +++ /dev/null @@ -1,10 +0,0 @@ -function addDsiOsiVarTitle(rootData, paramName) - DSI = rootData.(sprintf('%s_DSI', paramName)); - DSang = rootData.(sprintf('%s_DSang', paramName)); - OSI = rootData.(sprintf('%s_OSI', paramName)); - OSang = rootData.(sprintf('%s_OSang', paramName)); - DVar = rootData.(sprintf('%s_DVar', paramName)); - - s = sprintf('DSI: %1.2f @ %3.0f� | OSI: %1.2f @ %3.0f� | Variance: %1.2f', DSI, DSang, OSI, OSang, DVar); - title(s); -end \ No newline at end of file diff --git a/utilities/allParamsAcrossCells.m b/utilities/allParamsAcrossCells.m index a9dbf85..f936e03 100755 --- a/utilities/allParamsAcrossCells.m +++ b/utilities/allParamsAcrossCells.m @@ -42,43 +42,16 @@ leafInd = analysisTree.getchildren(analysisClassInd(nodeInd)); %Where responses are stored. %numLeafs = length(leafInd); %ASSUMING =1 curLeaf = analysisTree.get(leafInd); - - -% splitParamToUse = nan; -% switch analysisClass -% case 'DriftingGratingsAnalysis' -% splitParamToUse = 'spatialFreq'; % use to specify a multiple branching analysis's final leaf -% end -% -% if ~isnan(splitParamToUse) % step down tree to get to the data -% while ~strcmp(splitParamToUse, curAnalysisNode.get('splitParam')) -% analysisClassInd(nodeInd) = curAnalysisNode.getchildren(analysisClassInd(nodeInd)); -% curAnalysisNode = analysisTree.get(analysisClassInd(nodeInd)); -% end -% end - - XparamValuesName = nan; - switch analysisClass case {'MovingBarAnalysis', 'BarsMultiAngleAnalysis'} - XparamValuesName = 'barAngle'; + XparamValues = curAnalysisNode.barAngle; case 'SpotsMultiSizeAnalysis' - XparamValuesName = 'spotSize'; + XparamValues = curAnalysisNode.spotSize; case 'DriftingGratingsAnalysis' - XparamValuesName = 'gratingAngle'; + XparamValues = curAnalysisNode.gratingAngle; case 'DriftingTextureAnalysis' - XparamValuesName = 'textureAngle'; - end - - if ~isnan(XparamValuesName) - while ~isfield(curAnalysisNode, XparamValuesName) - children = analysisTree.getchildren(analysisClassInd(nodeInd)); - analysisClassInd(nodeInd) = children(1); - curAnalysisNode = analysisTree.get(analysisClassInd(nodeInd)); - end - - XparamValues = curAnalysisNode.(XparamValuesName); - end + XparamValues = curAnalysisNode.textureAngle; + end; for paramInd = 1:numParam paramIsStruct = 0; @@ -95,7 +68,7 @@ if ~isempty(strfind(YparamName,'_c')) %assuming using mean_c or median_c YparamSEM = curAnalysisNode.(YparamStructName).SEM_c; else - YparamSEM = curAnalysisNode.(YparamStructName).SEM; %assuming using mean or median + YparamSEM = curAnalysisNode.(YparamStructName).SEM; %suuming using mean or median end; else YparamSEM = zeros(1,length(YparamValues)); diff --git a/utilities/arrow.m b/utilities/arrow.m deleted file mode 100644 index 5854d63..0000000 --- a/utilities/arrow.m +++ /dev/null @@ -1,1461 +0,0 @@ -function [h,yy,zz] = arrow(varargin) -% ARROW Draw a line with an arrowhead. -% -% ARROW(Start,Stop) draws a line with an arrow from Start to Stop (points -% should be vectors of length 2 or 3, or matrices with 2 or 3 -% columns), and returns the graphics handle of the arrow(s). -% -% ARROW uses the mouse (click-drag) to create an arrow. -% -% ARROW DEMO & ARROW DEMO2 show 3-D & 2-D demos of the capabilities of ARROW. -% -% ARROW may be called with a normal argument list or a property-based list. -% ARROW(Start,Stop,Length,BaseAngle,TipAngle,Width,Page,CrossDir) is -% the full normal argument list, where all but the Start and Stop -% points are optional. If you need to specify a later argument (e.g., -% Page) but want default values of earlier ones (e.g., TipAngle), -% pass an empty matrix for the earlier ones (e.g., TipAngle=[]). -% -% ARROW('Property1',PropVal1,'Property2',PropVal2,...) creates arrows with the -% given properties, using default values for any unspecified or given as -% 'default' or NaN. Some properties used for line and patch objects are -% used in a modified fashion, others are passed directly to LINE, PATCH, -% or SET. For a detailed properties explanation, call ARROW PROPERTIES. -% -% Start The starting points. B -% Stop The end points. /|\ ^ -% Length Length of the arrowhead in pixels. /|||\ | -% BaseAngle Base angle in degrees (ADE). //|||\\ L| -% TipAngle Tip angle in degrees (ABC). ///|||\\\ e| -% Width Width of the base in pixels. ////|||\\\\ n| -% Page Use hardcopy proportions. /////|D|\\\\\ g| -% CrossDir Vector || to arrowhead plane. //// ||| \\\\ t| -% NormalDir Vector out of arrowhead plane. /// ||| \\\ h| -% Ends Which end has an arrowhead. //<----->|| \\ | -% ObjectHandles Vector of handles to update. / base ||| \ V -% E angle||<-------->C -% ARROW(H,'Prop1',PropVal1,...), where H is a |||tipangle -% vector of handles to previously-created arrows ||| -% and/or line objects, will update the previously- ||| -% created arrows according to the current view -->|A|<-- width -% and any specified properties, and will convert -% two-point line objects to corresponding arrows. ARROW(H) will update -% the arrows if the current view has changed. Root, figure, or axes -% handles included in H are replaced by all descendant Arrow objects. -% -% A property list can follow any specified normal argument list, e.g., -% ARROW([1 2 3],[0 0 0],36,'BaseAngle',60) creates an arrow from (1,2,3) to -% the origin, with an arrowhead of length 36 pixels and 60-degree base angle. -% -% Normally, an ARROW is a PATCH object, so any valid PATCH property/value pairs -% can be passed, e.g., ARROW(Start,Stop,'EdgeColor','r','FaceColor','g'). -% ARROW will use LINE objects when requested by ARROW(...,'Type','line') or, -% using LINE property/value pairs, ARROW(Start,Stop,'Type','line','Color','b'). -% -% The basic arguments or properties can generally be vectorized to create -% multiple arrows with the same call. This is done by passing a property -% with one row per arrow, or, if all arrows are to have the same property -% value, just one row may be specified. -% -% You may want to execute AXIS(AXIS) before calling ARROW so it doesn't change -% the axes on you; ARROW determines the sizes of arrow components BEFORE the -% arrow is plotted, so if ARROW changes axis limits, arrows may be malformed. -% -% This version of ARROW uses features of MATLAB 6.x and is incompatible with -% earlier MATLAB versions (ARROW for MATLAB 4.2c is available separately); -% some problems with perspective plots still exist. - -% Copyright (c)1995-2016, Dr. Erik A. Johnson , 5/25/2016 -% http://www.usc.edu/civil_eng/johnsone/ - -% Revision history: -% 5/25/16 EAJ Add documentation of 'Type','line' -% Add documentation of how to set color -% Add 'Color' property (which sets both 'EdgeColor' and 'FaceColor' for patch objects) -% 5/24/16 EAJ Remove 'EraseMode' in HG2 -% 7/16/14 EAJ R2014b HandleGraphics2 compatibility -% 7/14/14 EAJ 5/20/13 patch extension didn't work right in HG2 -% so break the arrow along its length instead -% 5/20/13 EAJ Extend patch line one more segment so EPS/PDF printed versions -% have nice rounded tips when the LineWidth is wider -% 2/06/13 EAJ Add ShortenLength property to shorten length if arrow is short -% 1/24/13 EAJ Remove some old comments. -% 5/20/09 EAJ Fix view direction in (3D) demo. -% 6/26/08 EAJ Replace eval('trycmd','catchcmd') with try, trycmd; catch, -% catchcmd; end; -- break's MATLAB 5 compatibility. -% 8/26/03 EAJ Eliminate OpenGL attempted fix since it didn't fix anyway. -% 11/15/02 EAJ Accomodate how MATLAB 6.5 handles NaN and logicals -% 7/28/02 EAJ Tried (but failed) work-around for MATLAB 6.x / OpenGL bug -% if zero 'Width' or not double-ended -% 11/10/99 EAJ Add logical() to eliminate zero index problem in MATLAB 5.3. -% 11/10/99 EAJ Corrected warning if axis limits changed on multiple axes. -% 11/10/99 EAJ Update e-mail address. -% 2/10/99 EAJ Some documentation updating. -% 2/24/98 EAJ Fixed bug if Start~=Stop but both colinear with viewpoint. -% 8/14/97 EAJ Added workaround for MATLAB 5.1 scalar logical transpose bug. -% 7/21/97 EAJ Fixed a few misc bugs. -% 7/14/97 EAJ Make arrow([],'Prop',...) do nothing (no old handles) -% 6/23/97 EAJ MATLAB 5 compatible version, release. -% 5/27/97 EAJ Added Line Arrows back in. Corrected a few bugs. -% 5/26/97 EAJ Changed missing Start/Stop to mouse-selected arrows. -% 5/19/97 EAJ MATLAB 5 compatible version, beta. -% 4/13/97 EAJ MATLAB 5 compatible version, alpha. -% 1/31/97 EAJ Fixed bug with multiple arrows and unspecified Z coords. -% 12/05/96 EAJ Fixed one more bug with log plots and NormalDir specified -% 10/24/96 EAJ Fixed bug with log plots and NormalDir specified -% 11/13/95 EAJ Corrected handling for 'reverse' axis directions -% 10/06/95 EAJ Corrected occasional conflict with SUBPLOT -% 4/24/95 EAJ A major rewrite. -% Fall 94 EAJ Original code. - -% Things to be done: -% - in the arrow_clicks section, prompt by printing to the screen so that -% the user knows what's going on; also make sure the figure is brought -% to the front. -% - segment parsing, computing, and plotting into separate subfunctions -% - change computing from Xform to Camera paradigms -% + this will help especially with 3-D perspective plots -% + if the WarpToFill section works right, remove warning code -% + when perpsective works properly, remove perspective warning code -% - add cell property values and struct property name/values (like get/set) -% - get rid of NaN as the "default" data label -% + perhaps change userdata to a struct and don't include (or leave -% empty) the values specified as default; or use a cell containing -% an empty matrix for a default value -% - add functionality of GET to retrieve current values of ARROW properties -% -% New list of things to be done: -% - rewrite as a graphics or class object that updates itself in real time -% (but have a 'Static' or 'DoNotUpdate' property to avoid updating) - -% Permission is granted to distribute ARROW with the toolboxes for the book -% "Solving Solid Mechanics Problems with MATLAB 5", by F. Golnaraghi et al. -% (Prentice Hall, 1999). - -% Permission is granted to Dr. Josef Bigun to distribute ARROW with his -% software to reproduce the figures in his image analysis text. - -% global variable initialization -persistent ARROW_PERSP_WARN ARROW_STRETCH_WARN ARROW_AXLIMITS ARROW_AX -if isempty(ARROW_PERSP_WARN ), ARROW_PERSP_WARN =1; end; -if isempty(ARROW_STRETCH_WARN), ARROW_STRETCH_WARN=1; end; - -% Handle callbacks -if (nargin>0 & isstr(varargin{1}) & strcmp(lower(varargin{1}),'callback')), - arrow_callback(varargin{2:end}); return; -end; - -% Are we doing the demo? -c = sprintf('\n'); -if (nargin==1 & isstr(varargin{1})), - arg1 = lower(varargin{1}); - if strncmp(arg1,'prop',4), arrow_props; - elseif strncmp(arg1,'demo',4) - clf reset - demo_info = arrow_demo; - if ~strncmp(arg1,'demo2',5), - hh=arrow_demo3(demo_info); - else, - hh=arrow_demo2(demo_info); - end; - if (nargout>=1), h=hh; end; - elseif strncmp(arg1,'fixlimits',3), - arrow_fixlimits(ARROW_AX,ARROW_AXLIMITS); - ARROW_AXLIMITS=[]; ARROW_AX=[]; - elseif strncmp(arg1,'help',4), - disp(help(mfilename)); - else, - error([upper(mfilename) ' got an unknown single-argument string ''' deblank(arg1) '''.']); - end; - return; -end; - -% Check # of arguments -if (nargout>3), error([upper(mfilename) ' produces at most 3 output arguments.']); end; - -% find first property number -firstprop = nargin+1; -for k=1:length(varargin), if ~isnumeric(varargin{k}) && ~all(ishandle(varargin{k})), firstprop=k; break; end; end; %eaj 5/24/16 for k=1:length(varargin), if ~isnumeric(varargin{k}), firstprop=k; break; end; end; -lastnumeric = firstprop-1; - -% check property list -if (firstprop<=nargin), - for k=firstprop:2:nargin, - curarg = varargin{k}; - if ~isstr(curarg) | sum(size(curarg)>1)>1, - error([upper(mfilename) ' requires that a property name be a single string.']); - end; - end; - if (rem(nargin-firstprop,2)~=1), - error([upper(mfilename) ' requires that the property ''' ... - varargin{nargin} ''' be paired with a property value.']); - end; -end; - -% default output -if (nargout>0), h=[]; end; -if (nargout>1), yy=[]; end; -if (nargout>2), zz=[]; end; - -% set values to empty matrices -start = []; -stop = []; -len = []; -baseangle = []; -tipangle = []; -wid = []; -page = []; -crossdir = []; -ends = []; -shorten = []; -ax = []; -oldh = []; -ispatch = []; -defstart = [NaN NaN NaN]; -defstop = [NaN NaN NaN]; -deflen = 16; -defbaseangle = 90; -deftipangle = 16; -defwid = 0; -defpage = 0; -defcrossdir = [NaN NaN NaN]; -defends = 1; -defshorten = 0; -defoldh = []; -defispatch = 1; - -% The 'Tag' we'll put on our arrows -ArrowTag = 'Arrow'; - -% check for oldstyle arguments -if (firstprop==2), - % assume arg1 is a set of handles - oldh = varargin{1}(:); - if isempty(oldh), return; end; -elseif (firstprop>9), - error([upper(mfilename) ' takes at most 8 non-property arguments.']); -elseif (firstprop>2), - {start,stop,len,baseangle,tipangle,wid,page,crossdir}; - args = [varargin(1:firstprop-1) cell(1,length(ans)-(firstprop-1))]; - [start,stop,len,baseangle,tipangle,wid,page,crossdir] = deal(args{:}); -end; - -% parse property pairs -extraprops={}; -for k=firstprop:2:nargin, - prop = varargin{k}; - val = varargin{k+1}; - prop = [lower(prop(:)') ' ']; - if strncmp(prop,'start' ,5), start = val; - elseif strncmp(prop,'stop' ,4), stop = val; - elseif strncmp(prop,'len' ,3), len = val(:); - elseif strncmp(prop,'base' ,4), baseangle = val(:); - elseif strncmp(prop,'tip' ,3), tipangle = val(:); - elseif strncmp(prop,'wid' ,3), wid = val(:); - elseif strncmp(prop,'page' ,4), page = val; - elseif strncmp(prop,'cross' ,5), crossdir = val; - elseif strncmp(prop,'norm' ,4), if (isstr(val)), crossdir=val; else, crossdir=val*sqrt(-1); end; - elseif strncmp(prop,'end' ,3), ends = val; - elseif strncmp(prop,'shorten',5), shorten = val; - elseif strncmp(prop,'object' ,6), oldh = val(:); - elseif strncmp(prop,'handle' ,6), oldh = val(:); - elseif strncmp(prop,'type' ,4), ispatch = val; - elseif strncmp(prop,'userd' ,5), %ignore it - else, - % make sure it is a valid patch or line property - try - get(0,['DefaultPatch' varargin{k}]); - catch - errstr = lasterr; - try - get(0,['DefaultLine' varargin{k}]); - catch - errstr(1:max(find(errstr==char(13)|errstr==char(10)))) = ''; - error([upper(mfilename) ' got ' errstr]); - end - end; - extraprops={extraprops{:},varargin{k},val}; - end; -end; - -% Check if we got 'default' values -start = arrow_defcheck(start ,defstart ,'Start' ); -stop = arrow_defcheck(stop ,defstop ,'Stop' ); -len = arrow_defcheck(len ,deflen ,'Length' ); -baseangle = arrow_defcheck(baseangle,defbaseangle,'BaseAngle' ); -tipangle = arrow_defcheck(tipangle ,deftipangle ,'TipAngle' ); -wid = arrow_defcheck(wid ,defwid ,'Width' ); -crossdir = arrow_defcheck(crossdir ,defcrossdir ,'CrossDir' ); -page = arrow_defcheck(page ,defpage ,'Page' ); -ends = arrow_defcheck(ends ,defends ,'' ); -shorten = arrow_defcheck(shorten ,defshorten ,'' ); -oldh = arrow_defcheck(oldh ,[] ,'ObjectHandles'); -ispatch = arrow_defcheck(ispatch ,defispatch ,'' ); - -% check transpose on arguments -[m,n]=size(start ); if any(m==[2 3])&(n==1|n>3), start = start'; end; -[m,n]=size(stop ); if any(m==[2 3])&(n==1|n>3), stop = stop'; end; -[m,n]=size(crossdir); if any(m==[2 3])&(n==1|n>3), crossdir = crossdir'; end; - -% convert strings to numbers -if ~isempty(ends) & isstr(ends), - endsorig = ends; - [m,n] = size(ends); - col = lower([ends(:,1:min(3,n)) ones(m,max(0,3-n))*' ']); - ends = NaN*ones(m,1); - oo = ones(1,m); - ii=find(all(col'==['non']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*0; end; - ii=find(all(col'==['sto']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*1; end; - ii=find(all(col'==['sta']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*2; end; - ii=find(all(col'==['bot']'*oo)'); if ~isempty(ii), ends(ii)=ones(length(ii),1)*3; end; - if any(isnan(ends)), - ii = min(find(isnan(ends))); - error([upper(mfilename) ' does not recognize ''' deblank(endsorig(ii,:)) ''' as a valid ''Ends'' value.']); - end; -else, - ends = ends(:); -end; -if ~isempty(ispatch) & isstr(ispatch), - col = lower(ispatch(:,1)); - patchchar='p'; linechar='l'; defchar=' '; - mask = col~=patchchar & col~=linechar & col~=defchar; - if any(mask), - error([upper(mfilename) ' does not recognize ''' deblank(ispatch(min(find(mask)),:)) ''' as a valid ''Type'' value.']); - end; - ispatch = (col==patchchar)*1 + (col==linechar)*0 + (col==defchar)*defispatch; -else, - ispatch = ispatch(:); -end; -oldh = oldh(:); - -% check object handles -if ~all(ishandle(oldh)), error([upper(mfilename) ' got invalid object handles.']); end; - -% expand root, figure, and axes handles -if ~isempty(oldh), - ohtype = get(oldh,'Type'); - mask = strcmp(ohtype,'root') | strcmp(ohtype,'figure') | strcmp(ohtype,'axes'); - if any(mask), - oldh = num2cell(oldh); - for ii=find(mask)', - oldh(ii) = {findobj(oldh{ii},'Tag',ArrowTag)}; - end; - oldh = cat(1,oldh{:}); - if isempty(oldh), return; end; % no arrows to modify, so just leave - end; -end; - -% largest argument length -[mstart,junk]=size(start); [mstop,junk]=size(stop); [mcrossdir,junk]=size(crossdir); -argsizes = [length(oldh) mstart mstop ... - length(len) length(baseangle) length(tipangle) ... - length(wid) length(page) mcrossdir length(ends) length(shorten)]; -args=['length(ObjectHandle) '; ... - '#rows(Start) '; ... - '#rows(Stop) '; ... - 'length(Length) '; ... - 'length(BaseAngle) '; ... - 'length(TipAngle) '; ... - 'length(Width) '; ... - 'length(Page) '; ... - '#rows(CrossDir) '; ... - '#rows(Ends) '; ... - 'length(ShortenLength) ']; -if (any(imag(crossdir(:))~=0)), - args(9,:) = '#rows(NormalDir) '; -end; -if isempty(oldh), - narrows = max(argsizes); -else, - narrows = length(oldh); -end; -if (narrows<=0), narrows=1; end; - -% Check size of arguments -ii = find((argsizes~=0)&(argsizes~=1)&(argsizes~=narrows)); -if ~isempty(ii), - s = args(ii',:); - while ((size(s,2)>1)&((abs(s(:,size(s,2)))==0)|(abs(s(:,size(s,2)))==abs(' ')))), - s = s(:,1:size(s,2)-1); - end; - s = [ones(length(ii),1)*[upper(mfilename) ' requires that '] s ... - ones(length(ii),1)*[' equal the # of arrows (' num2str(narrows) ').' c]]; - s = s'; - s = s(:)'; - s = s(1:length(s)-1); - error(setstr(s)); -end; - -% check element length in Start, Stop, and CrossDir -if ~isempty(start), - [m,n] = size(start); - if (n==2), - start = [start NaN*ones(m,1)]; - elseif (n~=3), - error([upper(mfilename) ' requires 2- or 3-element Start points.']); - end; -end; -if ~isempty(stop), - [m,n] = size(stop); - if (n==2), - stop = [stop NaN*ones(m,1)]; - elseif (n~=3), - error([upper(mfilename) ' requires 2- or 3-element Stop points.']); - end; -end; -if ~isempty(crossdir), - [m,n] = size(crossdir); - if (n<3), - crossdir = [crossdir NaN*ones(m,3-n)]; - elseif (n~=3), - if (all(imag(crossdir(:))==0)), - error([upper(mfilename) ' requires 2- or 3-element CrossDir vectors.']); - else, - error([upper(mfilename) ' requires 2- or 3-element NormalDir vectors.']); - end; - end; -end; - -% fill empty arguments -if isempty(start ), start = [Inf Inf Inf]; end; -if isempty(stop ), stop = [Inf Inf Inf]; end; -if isempty(len ), len = Inf; end; -if isempty(baseangle ), baseangle = Inf; end; -if isempty(tipangle ), tipangle = Inf; end; -if isempty(wid ), wid = Inf; end; -if isempty(page ), page = Inf; end; -if isempty(crossdir ), crossdir = [Inf Inf Inf]; end; -if isempty(ends ), ends = Inf; end; -if isempty(shorten ), shorten = Inf; end; -if isempty(ispatch ), ispatch = Inf; end; - -% expand single-column arguments -o = ones(narrows,1); -if (size(start ,1)==1), start = o * start ; end; -if (size(stop ,1)==1), stop = o * stop ; end; -if (length(len )==1), len = o * len ; end; -if (length(baseangle )==1), baseangle = o * baseangle ; end; -if (length(tipangle )==1), tipangle = o * tipangle ; end; -if (length(wid )==1), wid = o * wid ; end; -if (length(page )==1), page = o * page ; end; -if (size(crossdir ,1)==1), crossdir = o * crossdir ; end; -if (length(ends )==1), ends = o * ends ; end; -if (length(shorten )==1), shorten = o * shorten ; end; -if (length(ispatch )==1), ispatch = o * ispatch ; end; -ax = repmat(gca,narrows,1); %eaj 7/16/14 ax=gca; if ~isnumeric(ax), ax=double(ax); end; ax=o*ax; - -% if we've got handles, get the defaults from the handles -if ~isempty(oldh), - for k=1:narrows, - oh = oldh(k); - ud = get(oh,'UserData'); - ax(k) = get(oh,'Parent'); %eaj 7/16/14 get(oh,'Parent'); if ~isnumeric(ans), double(ans); end; ax(k)=ans; - ohtype = get(oh,'Type'); - if strcmp(get(oh,'Tag'),ArrowTag), % if it's an arrow already - if isinf(ispatch(k)), ispatch(k)=strcmp(ohtype,'patch'); end; - % arrow UserData format: [start' stop' len base tip wid page crossdir' ends shorten] - start0 = ud(1:3); - stop0 = ud(4:6); - if (isinf(len(k))), len(k) = ud( 7); end; - if (isinf(baseangle(k))), baseangle(k) = ud( 8); end; - if (isinf(tipangle(k))), tipangle(k) = ud( 9); end; - if (isinf(wid(k))), wid(k) = ud(10); end; - if (isinf(page(k))), page(k) = ud(11); end; - if (isinf(crossdir(k,1))), crossdir(k,1) = ud(12); end; - if (isinf(crossdir(k,2))), crossdir(k,2) = ud(13); end; - if (isinf(crossdir(k,3))), crossdir(k,3) = ud(14); end; - if (isinf(ends(k))), ends(k) = ud(15); end; - if (isinf(shorten(k))), shorten(k) = ud(16); end; - elseif strcmp(ohtype,'line')|strcmp(ohtype,'patch'), % it's a non-arrow line or patch - convLineToPatch = 1; %set to make arrow patches when converting from lines. - if isinf(ispatch(k)), ispatch(k)=convLineToPatch|strcmp(ohtype,'patch'); end; - x=get(oh,'XData'); x=x(~isnan(x(:))); if isempty(x), x=NaN; end; - y=get(oh,'YData'); y=y(~isnan(y(:))); if isempty(y), y=NaN; end; - z=get(oh,'ZData'); z=z(~isnan(z(:))); if isempty(z), z=NaN; end; - start0 = [x(1) y(1) z(1) ]; - stop0 = [x(end) y(end) z(end)]; - else, - error([upper(mfilename) ' cannot convert ' ohtype ' objects.']); - end; - ii=find(isinf(start(k,:))); if ~isempty(ii), start(k,ii)=start0(ii); end; - ii=find(isinf(stop( k,:))); if ~isempty(ii), stop( k,ii)=stop0( ii); end; - end; -end; - -% convert Inf's to NaN's -start( isinf(start )) = NaN; -stop( isinf(stop )) = NaN; -len( isinf(len )) = NaN; -baseangle( isinf(baseangle)) = NaN; -tipangle( isinf(tipangle )) = NaN; -wid( isinf(wid )) = NaN; -page( isinf(page )) = NaN; -crossdir( isinf(crossdir )) = NaN; -ends( isinf(ends )) = NaN; -shorten( isinf(shorten )) = NaN; -ispatch( isinf(ispatch )) = NaN; - -% set up the UserData data (here so not corrupted by log10's and such) -ud = [start stop len baseangle tipangle wid page crossdir ends shorten]; - -% Set Page defaults -page = ~isnan(page) & trueornan(page); - -% Get axes limits, range, min; correct for aspect ratio and log scale -axm = zeros(3,narrows); -axr = zeros(3,narrows); -axrev = zeros(3,narrows); -ap = zeros(2,narrows); -xyzlog = zeros(3,narrows); -limmin = zeros(2,narrows); -limrange = zeros(2,narrows); -oldaxlims = zeros(6,narrows); -oneax = all(ax==ax(1)); -if (oneax), - T = zeros(4,4); - invT = zeros(4,4); -else, - T = zeros(16,narrows); - invT = zeros(16,narrows); -end; -axnotdone = true(size(ax)); -while (any(axnotdone)), - ii = find(axnotdone,1); - curax = ax(ii); - curpage = page(ii); - % get axes limits and aspect ratio - axl = [get(curax,'XLim'); get(curax,'YLim'); get(curax,'ZLim')]; - ax==curax; oldaxlims(:,ans)=repmat(reshape(axl',[],1),1,sum(ans)); - % get axes size in pixels (points) - u = get(curax,'Units'); - axposoldunits = get(curax,'Position'); - really_curpage = curpage & strcmp(u,'normalized'); - if (really_curpage), - curfig = get(curax,'Parent'); - pu = get(curfig,'PaperUnits'); - set(curfig,'PaperUnits','points'); - pp = get(curfig,'PaperPosition'); - set(curfig,'PaperUnits',pu); - set(curax,'Units','pixels'); - curapscreen = get(curax,'Position'); - set(curax,'Units','normalized'); - curap = pp.*get(curax,'Position'); - else, - set(curax,'Units','pixels'); - curapscreen = get(curax,'Position'); - curap = curapscreen; - end; - set(curax,'Units',u); - set(curax,'Position',axposoldunits); - % handle non-stretched axes position - str_stretch = { 'DataAspectRatioMode' ; ... - 'PlotBoxAspectRatioMode' ; ... - 'CameraViewAngleMode' }; - str_camera = { 'CameraPositionMode' ; ... - 'CameraTargetMode' ; ... - 'CameraViewAngleMode' ; ... - 'CameraUpVectorMode' }; - notstretched = strcmp(get(curax,str_stretch),'manual'); - manualcamera = strcmp(get(curax,str_camera),'manual'); - if ~arrow_WarpToFill(notstretched,manualcamera,curax), - % give a warning that this has not been thoroughly tested - if 0 & ARROW_STRETCH_WARN, - ARROW_STRETCH_WARN = 0; - strs = {str_stretch{1:2},str_camera{:}}; - strs = [char(ones(length(strs),1)*sprintf('\n ')) char(strs)]'; - warning([upper(mfilename) ' may not yet work quite right ' ... - 'if any of the following are ''manual'':' strs(:).']); - end; - % find the true pixel size of the actual axes - texttmp = text(axl(1,[1 2 2 1 1 2 2 1]), ... - axl(2,[1 1 2 2 1 1 2 2]), ... - axl(3,[1 1 1 1 2 2 2 2]),''); - set(texttmp,'Units','points'); - textpos = get(texttmp,'Position'); - delete(texttmp); - textpos = cat(1,textpos{:}); - textpos = max(textpos(:,1:2)) - min(textpos(:,1:2)); - % adjust the axes position - if (really_curpage), - % adjust to printed size - textpos = textpos * min(curap(3:4)./textpos); - curap = [curap(1:2)+(curap(3:4)-textpos)/2 textpos]; - else, - % adjust for pixel roundoff - textpos = textpos * min(curapscreen(3:4)./textpos); - curap = [curap(1:2)+(curap(3:4)-textpos)/2 textpos]; - end; - end; - if ARROW_PERSP_WARN & ~strcmp(get(curax,'Projection'),'orthographic'), - ARROW_PERSP_WARN = 0; - warning([upper(mfilename) ' does not yet work right for 3-D perspective projection.']); - end; - % adjust limits for log scale on axes - curxyzlog = strcmp(get(curax,{'XScale' 'YScale' 'ZScale'})','log'); - if (any(curxyzlog)), - ii = find([curxyzlog;curxyzlog]); - if (any(axl(ii)<=0)), - error([upper(mfilename) ' does not support non-positive limits on log-scaled axes.']); - else, - axl(ii) = log10(axl(ii)); - end; - end; - % correct for 'reverse' direction on axes; - curreverse = strcmp(get(curax,{'XDir' 'YDir' 'ZDir'})','reverse'); - ii = find(curreverse); - if ~isempty(ii), - axl(ii,[1 2])=-axl(ii,[2 1]); - end; - % compute the range of 2-D values - try, curT=get(curax,'Xform'); catch, num2cell(get(curax,'View')); curT=viewmtx(ans{:}); end; - lim = curT*[0 1 0 1 0 1 0 1;0 0 1 1 0 0 1 1;0 0 0 0 1 1 1 1;1 1 1 1 1 1 1 1]; - lim = lim(1:2,:)./([1;1]*lim(4,:)); - curlimmin = min(lim')'; - curlimrange = max(lim')' - curlimmin; - curinvT = inv(curT); - if (~oneax), - curT = curT.'; - curinvT = curinvT.'; - curT = curT(:); - curinvT = curinvT(:); - end; - % check which arrows to which cur corresponds - ii = find((ax==curax)&(page==curpage)); - oo = ones(1,length(ii)); - axr(:,ii) = diff(axl')' * oo; - axm(:,ii) = axl(:,1) * oo; - axrev(:,ii) = curreverse * oo; - ap(:,ii) = curap(3:4)' * oo; - xyzlog(:,ii) = curxyzlog * oo; - limmin(:,ii) = curlimmin * oo; - limrange(:,ii) = curlimrange * oo; - if (oneax), - T = curT; - invT = curinvT; - else, - T(:,ii) = curT * oo; - invT(:,ii) = curinvT * oo; - end; - axnotdone(ii) = zeros(1,length(ii)); -end; - -% correct for log scales -curxyzlog = xyzlog.'; -ii = find(curxyzlog(:)); -if ~isempty(ii), - start( ii) = real(log10(start( ii))); - stop( ii) = real(log10(stop( ii))); - if (all(imag(crossdir)==0)), % pulled (ii) subscript on crossdir, 12/5/96 eaj - crossdir(ii) = real(log10(crossdir(ii))); - end; -end; - -% correct for reverse directions -ii = find(axrev.'); -if ~isempty(ii), - start( ii) = -start( ii); - stop( ii) = -stop( ii); - crossdir(ii) = -crossdir(ii); -end; - -% transpose start/stop values -start = start.'; -stop = stop.'; - -% take care of defaults, page was done above -ii=find(isnan(start(:) )); if ~isempty(ii), start(ii) = axm(ii)+axr(ii)/2; end; -ii=find(isnan(stop(:) )); if ~isempty(ii), stop(ii) = axm(ii)+axr(ii)/2; end; -ii=find(isnan(crossdir(:) )); if ~isempty(ii), crossdir(ii) = zeros(length(ii),1); end; -ii=find(isnan(len )); if ~isempty(ii), len(ii) = ones(length(ii),1)*deflen; end; -ii=find(isnan(baseangle )); if ~isempty(ii), baseangle(ii) = ones(length(ii),1)*defbaseangle; end; -ii=find(isnan(tipangle )); if ~isempty(ii), tipangle(ii) = ones(length(ii),1)*deftipangle; end; -ii=find(isnan(wid )); if ~isempty(ii), wid(ii) = ones(length(ii),1)*defwid; end; -ii=find(isnan(ends )); if ~isempty(ii), ends(ii) = ones(length(ii),1)*defends; end; -ii=find(isnan(shorten )); if ~isempty(ii), shorten(ii) = ones(length(ii),1)*defshorten; end; - -% transpose rest of values -len = len.'; -baseangle = baseangle.'; -tipangle = tipangle.'; -wid = wid.'; -page = page.'; -crossdir = crossdir.'; -ends = ends.'; -shorten = shorten.'; -ax = ax.'; - -% given x, a 3xN matrix of points in 3-space; -% want to convert to X, the corresponding 4xN 2-space matrix -% -% tmp1=[(x-axm)./axr; ones(1,size(x,1))]; -% if (oneax), X=T*tmp1; -% else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T.*tmp1; -% tmp2=zeros(4,4*N); tmp2(:)=tmp1(:); -% X=zeros(4,N); X(:)=sum(tmp2)'; end; -% X = X ./ (ones(4,1)*X(4,:)); - -% for all points with start==stop, start=stop-(verysmallvalue)*(up-direction); -ii = find(all(start==stop)); -if ~isempty(ii), - % find an arrowdir vertical on screen and perpendicular to viewer - % transform to 2-D - tmp1 = [(stop(:,ii)-axm(:,ii))./axr(:,ii);ones(1,length(ii))]; - if (oneax), twoD=T*tmp1; - else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T(:,ii).*tmp1; - tmp2=zeros(4,4*length(ii)); tmp2(:)=tmp1(:); - twoD=zeros(4,length(ii)); twoD(:)=sum(tmp2)'; end; - twoD=twoD./(ones(4,1)*twoD(4,:)); - % move the start point down just slightly - tmp1 = twoD + [0;-1/1000;0;0]*(limrange(2,ii)./ap(2,ii)); - % transform back to 3-D - if (oneax), threeD=invT*tmp1; - else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=invT(:,ii).*tmp1; - tmp2=zeros(4,4*length(ii)); tmp2(:)=tmp1(:); - threeD=zeros(4,length(ii)); threeD(:)=sum(tmp2)'; end; - start(:,ii) = (threeD(1:3,:)./(ones(3,1)*threeD(4,:))).*axr(:,ii)+axm(:,ii); -end; - -% compute along-arrow points -% transform Start points - tmp1=[(start-axm)./axr;ones(1,narrows)]; - if (oneax), X0=T*tmp1; - else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T.*tmp1; - tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); - X0=zeros(4,narrows); X0(:)=sum(tmp2)'; end; - X0=X0./(ones(4,1)*X0(4,:)); -% transform Stop points - tmp1=[(stop-axm)./axr;ones(1,narrows)]; - if (oneax), Xf=T*tmp1; - else, tmp1=[tmp1;tmp1;tmp1;tmp1]; tmp1=T.*tmp1; - tmp2=zeros(4,4*narrows); tmp2(:)=tmp1(:); - Xf=zeros(4,narrows); Xf(:)=sum(tmp2)'; end; - Xf=Xf./(ones(4,1)*Xf(4,:)); -% compute pixel distance between points - D = sqrt(sum(((Xf(1:2,:)-X0(1:2,:)).*(ap./limrange)).^2)); - D = D + (D==0); %eaj new 2/24/98 -% shorten the length if requested % added 2/6/2013 - numends = (ends==1) + (ends==2) + 2*(ends==3); - mask = shorten & D0 - ii = find(strcmpi(extraprops(1:2:end),'color')); %eaj 5/25/16 - ispatch = strcmp(get(H,'Type'),'patch'); - %eaj start 5/25/16 - while ~isempty(ii) && any(ispatch) - if ii>1, set(H,extraprops{1:2*ii-2}); end; - c = extraprops{2*ii}; - extraprops(1:2*ii) = []; - ii(1) = []; - if all(ispatch) || ischar(c)&&size(c,1)==1 || isnumeric(c)&&isequal(size(c),[1 3]) - set(H,'EdgeColor',c,'FaceColor',c) - elseif iscell(c) && numel(c)~=numel(H) - set(H(ispatch),'EdgeColor',c(ispatch),'FaceColor',c(ispatch)); - set(H(~ispatch),'Color',c(~ispatch)); - elseif isnumeric(c) && isequal(size(c),[numel(H) 3]) - set(H(ispatch),'EdgeColor',num2cell(c(ispatch,:),2),'FaceColor',num2cell(c(ispatch,:),2)); - set(H(~ispatch),'Color',num2cell(c(~ispatch,:),2)); - else - warning('ignoring unknown or invalid ''Color'' specification'); - end - end - if ~isempty(extraprops) - %eaj end 5/25/16 - set(H,extraprops{:}); - end %eaj 5/25/16 - end - % handle choosing arrow Start and/or Stop locations if unspecified - [H,oldaxlims,errstr] = arrow_clicks(H,ud,x,y,z,ax,oldaxlims); - if ~isempty(errstr), error([upper(mfilename) ' got ' errstr]); end; - % set the output - if (nargout>0), h=H; end; - % make sure the axis limits did not change - if isempty(oldaxlims), - ARROW_AXLIMITS = []; - ARROW_AX = []; - else, - lims = get(ax(:),{'XLim','YLim','ZLim'})'; - lims = reshape(cat(2,lims{:}),6,size(lims,2)); - mask = arrow_is2DXY(ax(:)); - oldaxlims(5:6,mask) = lims(5:6,mask); - % store them for possible restoring - mask = any(oldaxlims~=lims,1); ARROW_AX=ax(mask); ARROW_AXLIMITS=oldaxlims(:,mask); - if any(mask), - warning(arrow_warnlimits(ARROW_AX,narrows)); - end; - end; -else, - % don't create the patch, just return the data - h=x; - yy=y; - zz=z; -end; - - - -function out = arrow_defcheck(in,def,prop) -% check if we got 'default' values - out = in; - if ~isstr(in), return; end; - if size(in,1)==1 & strncmp(lower(in),'def',3), - out = def; - elseif ~isempty(prop), - error([upper(mfilename) ' does not recognize ''' in(:)' ''' as a valid ''' prop ''' string.']); - end; - - - -function [H,oldaxlims,errstr] = arrow_clicks(H,ud,x,y,z,ax,oldaxlims) -% handle choosing arrow Start and/or Stop locations if necessary - errstr = ''; - if isempty(H)|isempty(ud)|isempty(x), return; end; - % determine which (if any) need Start and/or Stop - needStart = all(isnan(ud(:,1:3)'))'; - needStop = all(isnan(ud(:,4:6)'))'; - mask = any(needStart|needStop); - if ~any(mask), return; end; - ud(~mask,:)=[]; ax(:,~mask)=[]; - x(:,~mask)=[]; y(:,~mask)=[]; z(:,~mask)=[]; - % make them invisible for the time being - set(H,'Visible','off'); - % save the current axes and limits modes; set to manual for the time being - oldAx = gca; - limModes=get(ax(:),{'XLimMode','YLimMode','ZLimMode'}); - set(ax(:),{'XLimMode','YLimMode','ZLimMode'},{'manual','manual','manual'}); - % loop over each arrow that requires attention - jj = find(mask); - for ii=1:length(jj), - h = H(jj(ii)); - axes(ax(ii)); - % figure out correct call - if needStart(ii), prop='Start'; else, prop='Stop'; end; - [wasInterrupted,errstr] = arrow_click(needStart(ii)&needStop(ii),h,prop,ax(ii)); - % handle errors and control-C - if wasInterrupted, - delete(H(jj(ii:end))); - H(jj(ii:end))=[]; - oldaxlims(jj(ii:end),:)=[]; - break; - end; - end; - % restore the axes and limit modes - axes(oldAx); - set(ax(:),{'XLimMode','YLimMode','ZLimMode'},limModes); - -function [wasInterrupted,errstr] = arrow_click(lockStart,H,prop,ax) -% handle the clicks for one arrow - fig = get(ax,'Parent'); - % save some things - oldFigProps = {'Pointer','WindowButtonMotionFcn','WindowButtonUpFcn'}; - oldFigValue = get(fig,oldFigProps); - oldArrowProps = {'EraseMode'}; - if ~isnumeric(fig), oldArrowProps={}; end %eaj 5/24/16 % only use in HG2 - oldArrowValue = get(H,oldArrowProps); - if isnumeric(fig), %eaj 5/24/16 - set(H,'EraseMode','background'); %because 'xor' makes shaft invisible unless Width>1 -- only use in HG2 - end %eaj 5/24/16 - global ARROW_CLICK_H ARROW_CLICK_PROP ARROW_CLICK_AX ARROW_CLICK_USE_Z - ARROW_CLICK_H=H; ARROW_CLICK_PROP=prop; ARROW_CLICK_AX=ax; - ARROW_CLICK_USE_Z=~arrow_is2DXY(ax)|~arrow_planarkids(ax); - set(fig,'Pointer','crosshair'); - % set up the WindowButtonMotion so we can see the arrow while moving around - set(fig,'WindowButtonUpFcn','set(gcf,''WindowButtonUpFcn'','''')', ... - 'WindowButtonMotionFcn',''); - if ~lockStart, - set(H,'Visible','on'); - set(fig,'WindowButtonMotionFcn',[mfilename '(''callback'',''motion'');']); - end; - % wait for the button to be pressed - [wasKeyPress,wasInterrupted,errstr] = arrow_wfbdown(fig); - % if we wanted to click-drag, set the Start point - if lockStart & ~wasInterrupted, - pt = arrow_point(ARROW_CLICK_AX,ARROW_CLICK_USE_Z); - feval(mfilename,H,'Start',pt,'Stop',pt); - set(H,'Visible','on'); - ARROW_CLICK_PROP='Stop'; - set(fig,'WindowButtonMotionFcn',[mfilename '(''callback'',''motion'');']); - % wait for the mouse button to be released - try - waitfor(fig,'WindowButtonUpFcn',''); - catch - errstr = lasterr; - wasInterrupted = 1; - end; - end; - if ~wasInterrupted, feval(mfilename,'callback','motion'); end; - % restore some things - set(gcf,oldFigProps,oldFigValue); - set(H,oldArrowProps,oldArrowValue); - -function arrow_callback(varargin) -% handle redrawing callbacks - return - if nargin==0, return; end; - str = varargin{1}; - if ~isstr(str), error([upper(mfilename) ' got an invalid Callback command.']); end; - s = lower(str); - if strcmp(s,'motion'), - % motion callback - global ARROW_CLICK_H ARROW_CLICK_PROP ARROW_CLICK_AX ARROW_CLICK_USE_Z - feval(mfilename,ARROW_CLICK_H,ARROW_CLICK_PROP,arrow_point(ARROW_CLICK_AX,ARROW_CLICK_USE_Z)); - drawnow; - else, - error([upper(mfilename) ' does not recognize ''' str(:).' ''' as a valid Callback option.']); - end; - -function out = arrow_point(ax,use_z) -% return the point on the given axes - if nargin==0, ax=gca; end; - if nargin<2, use_z=~arrow_is2DXY(ax)|~arrow_planarkids(ax); end; - out = get(ax,'CurrentPoint'); - out = out(1,:); - if ~use_z, out=out(1:2); end; - -function [wasKeyPress,wasInterrupted,errstr] = arrow_wfbdown(fig) -% wait for button down ignoring object ButtonDownFcn's - if nargin==0, fig=gcf; end; - errstr = ''; - % save ButtonDownFcn values - objs = findobj(fig); - buttonDownFcns = get(objs,'ButtonDownFcn'); - mask=~strcmp(buttonDownFcns,''); objs=objs(mask); buttonDownFcns=buttonDownFcns(mask); - set(objs,'ButtonDownFcn',''); - % save other figure values - figProps = {'KeyPressFcn','WindowButtonDownFcn'}; - figValue = get(fig,figProps); - % do the real work - set(fig,'KeyPressFcn','set(gcf,''KeyPressFcn'','''',''WindowButtonDownFcn'','''');', ... - 'WindowButtonDownFcn','set(gcf,''WindowButtonDownFcn'','''')'); - lasterr(''); - try - waitfor(fig,'WindowButtonDownFcn',''); - wasInterrupted = 0; - catch - wasInterrupted = 1; - end - wasKeyPress = ~wasInterrupted & strcmp(get(fig,'KeyPressFcn'),''); - if wasInterrupted, errstr=lasterr; end; - % restore ButtonDownFcn and other figure values - set(objs,'ButtonDownFcn',buttonDownFcns); - set(fig,figProps,figValue); - - - -function [out,is2D] = arrow_is2DXY(ax) -% check if axes are 2-D X-Y plots - % may not work for modified camera angles, etc. - out = false(size(ax)); % 2-D X-Y plots - is2D = out; % any 2-D plots - views = get(ax(:),{'View'}); - views = cat(1,views{:}); - out(:) = abs(views(:,2))==90; - is2D(:) = out(:) | all(rem(views',90)==0)'; - -function out = arrow_planarkids(ax) -% check if axes descendents all have empty ZData (lines,patches,surfaces) - out = true(size(ax)); - allkids = get(ax(:),{'Children'}); - for k=1:length(allkids), - kids = get([findobj(allkids{k},'flat','Type','line') - findobj(allkids{k},'flat','Type','patch') - findobj(allkids{k},'flat','Type','surface')],{'ZData'}); - for j=1:length(kids), - if ~isempty(kids{j}), out(k)=logical(0); break; end; - end; - end; - - - -function arrow_fixlimits(ax,lims) -% reset the axis limits as necessary - if isempty(ax) || isempty(lims), disp([upper(mfilename) ' does not remember any axis limits to reset.']); end; - for k=1:numel(ax), - if any(get(ax(k),'XLim')~=lims(1:2,k)'), set(ax(k),'XLim',lims(1:2,k)'); end; - if any(get(ax(k),'YLim')~=lims(3:4,k)'), set(ax(k),'YLim',lims(3:4,k)'); end; - if any(get(ax(k),'ZLim')~=lims(5:6,k)'), set(ax(k),'ZLim',lims(5:6,k)'); end; - end; - - - -function out = arrow_WarpToFill(notstretched,manualcamera,curax) -% check if we are in "WarpToFill" mode. - out = strcmp(get(curax,'WarpToFill'),'on'); - % 'WarpToFill' is undocumented, so may need to replace this by - % out = ~( any(notstretched) & any(manualcamera) ); - - - -function out = arrow_warnlimits(ax,narrows) -% create a warning message if we've changed the axis limits - msg = ''; - switch (numel(ax)) - case 1, msg=''; - case 2, msg='on two axes '; - otherwise, msg='on several axes '; - end; - msg = [upper(mfilename) ' changed the axis limits ' msg ... - 'when adding the arrow']; - if (narrows>1), msg=[msg 's']; end; - out = [msg '.' sprintf('\n') ' Call ' upper(mfilename) ... - ' FIXLIMITS to reset them now.']; - - - -function arrow_copyprops(fm,to) -% copy line properties to patches - props = {'EraseMode','LineStyle','LineWidth','Marker','MarkerSize',... - 'MarkerEdgeColor','MarkerFaceColor','ButtonDownFcn', ... - 'Clipping','DeleteFcn','BusyAction','HandleVisibility', ... - 'Selected','SelectionHighlight','Visible'}; - if ~isnumeric(findobj('Type','root')), props(strcmp(props,'EraseMode'))=[]; end; %eaj 5/24/16 - lineprops = {'Color', props{:}}; - patchprops = {'EdgeColor',props{:}}; - patch2props = {'FaceColor',patchprops{:}}; - fmpatch = strcmp(get(fm,'Type'),'patch'); - topatch = strcmp(get(to,'Type'),'patch'); - set(to( fmpatch& topatch),patch2props,get(fm( fmpatch& topatch),patch2props)); %p->p - set(to(~fmpatch&~topatch),lineprops, get(fm(~fmpatch&~topatch),lineprops )); %l->l - set(to( fmpatch&~topatch),lineprops, get(fm( fmpatch&~topatch),patchprops )); %p->l - set(to(~fmpatch& topatch),patchprops, get(fm(~fmpatch& topatch),lineprops) ,'FaceColor','none'); %l->p - - - -function arrow_props -% display further help info about ARROW properties - c = sprintf('\n'); - disp([c ... - 'ARROW Properties: Default values are given in [square brackets], and other' c ... - ' acceptable equivalent property names are in (parenthesis).' c c ... - ' Start The starting points. For N arrows, B' c ... - ' this should be a Nx2 or Nx3 matrix. /|\ ^' c ... - ' Stop The end points. For N arrows, this /|||\ |' c ... - ' should be a Nx2 or Nx3 matrix. //|||\\ L|' c ... - ' Length Length of the arrowhead (in pixels on ///|||\\\ e|' c ... - ' screen, points on a page). [16] (Len) ////|||\\\\ n|' c ... - ' BaseAngle Angle (degrees) of the base angle /////|D|\\\\\ g|' c ... - ' ADE. For a simple stick arrow, use //// ||| \\\\ t|' c ... - ' BaseAngle=TipAngle. [90] (Base) /// ||| \\\ h|' c ... - ' TipAngle Angle (degrees) of tip angle ABC. //<----->|| \\ |' c ... - ' [16] (Tip) / base ||| \ V' c ... - ' Width Width of the base in pixels. Not E angle ||<-------->C' c ... - ' the ''LineWidth'' prop. [0] (Wid) |||tipangle' c ... - ' Page If provided, non-empty, and not NaN, |||' c ... - ' this causes ARROW to use hardcopy |||' c ... - ' rather than onscreen proportions. A' c ... - ' This is important if screen aspect --> <-- width' c ... - ' ratio and hardcopy aspect ratio are ----CrossDir---->' c ... - ' vastly different. []' c... - ' CrossDir A vector giving the direction towards which the fletches' c ... - ' on the arrow should go. [computed such that it is perpen-' c ... - ' dicular to both the arrow direction and the view direction' c ... - ' (i.e., as if it was pasted on a normal 2-D graph)] (Note' c ... - ' that CrossDir is a vector. Also note that if an axis is' c ... - ' plotted on a log scale, then the corresponding component' c ... - ' of CrossDir must also be set appropriately, i.e., to 1 for' c ... - ' no change in that direction, >1 for a positive change, >0' c ... - ' and <1 for negative change.)' c ... - ' NormalDir A vector normal to the fletch direction (CrossDir is then' c ... - ' computed by the vector cross product [Line]x[NormalDir]). []' c ... - ' (Note that NormalDir is a vector. Unlike CrossDir,' c ... - ' NormalDir is used as is regardless of log-scaled axes.)' c ... - ' Ends Set which end has an arrowhead. Valid values are ''none'',' c ... - ' ''stop'', ''start'', and ''both''. [''stop''] (End)' c... - ' ShortenLength Shorten length of arrowhead(s) if line is too short' c ... - ' ObjectHandles Vector of handles to previously-created arrows to be' c ... - ' updated or line objects to be converted to arrows.' c ... - ' [] (Object,Handle)' c ... - ' Type ''patch'' creates the arrow with a PATCH object (the default)' c ... - ' and ''line'' creates it with a LINE object [''patch''].' c ... - ' Color For patch arrows (the default), set both ''FaceColor'' and' c ... - ' ''EdgeColor'' to the given value. For line arrows, set' c ... - ' the ''Color'' property to the given value.' c ... - ]); - - - -function out = arrow_demo - % demo - % create the data - [x,y,z] = peaks; - [ddd,out.iii]=max(z(:)); - out.axlim = [min(x(:)) max(x(:)) min(y(:)) max(y(:)) min(z(:)) max(z(:))]; - - % modify it by inserting some NaN's - [m,n] = size(z); - m = floor(m/2); - n = floor(n/2); - z(1:m,1:n) = NaN*ones(m,n); - - % graph it - clf('reset'); - out.hs=surf(x,y,z); - out.x=x; out.y=y; out.z=z; - xlabel('x'); ylabel('y'); - -function h = arrow_demo3(in) - % set the view - axlim = in.axlim; - axis(axlim); - zlabel('z'); - %set(in.hs,'FaceColor','interp'); - view(3); % view(viewmtx(-37.5,30,20)); - title(['Demo of the capabilities of the ARROW function in 3-D']); - - % Normal blue arrow - h1 = feval(mfilename,[axlim(1) axlim(4) 4],[-.8 1.2 4], ... - 'EdgeColor','b','FaceColor','b'); - - % Normal white arrow, clipped by the surface - h2 = feval(mfilename,axlim([1 4 6]),[0 2 4]); - t=text(-2.4,2.7,7.7,'arrow clipped by surf'); - - % Baseangle<90 - h3 = feval(mfilename,[3 .125 3.5],[1.375 0.125 3.5],30,50); - t2=text(3.1,.125,3.5,'local maximum'); - - % Baseangle<90, fill and edge colors different - h4 = feval(mfilename,axlim(1:2:5)*.5,[0 0 0],36,60,25, ... - 'EdgeColor','b','FaceColor','c'); - t3=text(axlim(1)*.5,axlim(3)*.5,axlim(5)*.5-.75,'origin'); - set(t3,'HorizontalAlignment','center'); - - % Baseangle>90, black fill - h5 = feval(mfilename,[-2.9 2.9 3],[-1.3 .4 3.2],30,120,[],6, ... - 'EdgeColor','r','FaceColor','k','LineWidth',2); - - % Baseangle>90, no fill - h6 = feval(mfilename,[-2.9 2.9 1.3],[-1.3 .4 1.5],30,120,[],6, ... - 'EdgeColor','r','FaceColor','none','LineWidth',2); - - % Stick arrow - h7 = feval(mfilename,[-1.6 -1.65 -6.5],[0 -1.65 -6.5],[],16,16); - t4=text(-1.5,-1.65,-7.25,'global mininum'); - set(t4,'HorizontalAlignment','center'); - - % Normal, black fill - h8 = feval(mfilename,[-1.4 0 -7.2],[-1.4 0 -3],'FaceColor','k'); - t5=text(-1.5,0,-7.75,'local minimum'); - set(t5,'HorizontalAlignment','center'); - - % Gray fill, crossdir specified, 'LineStyle' -- - h9 = feval(mfilename,[-3 2.2 -6],[-3 2.2 -.05],36,[],27,6,[],[0 -1 0], ... - 'EdgeColor','k','FaceColor',.75*[1 1 1],'LineStyle','--'); - - % a series of normal arrows, linearly spaced, crossdir specified - h10y=(0:4)'/3; - h10 = feval(mfilename,[-3*ones(size(h10y)) h10y -6.5*ones(size(h10y))], ... - [-3*ones(size(h10y)) h10y -.05*ones(size(h10y))], ... - 12,[],[],[],[],[0 -1 0]); - - % a series of normal arrows, linearly spaced - h11x=(1:.33:2.8)'; - h11 = feval(mfilename,[h11x -3*ones(size(h11x)) 6.5*ones(size(h11x))], ... - [h11x -3*ones(size(h11x)) -.05*ones(size(h11x))]); - - % series of magenta arrows, radially oriented, crossdir specified - h12x=2; h12y=-3; h12z=axlim(5)/2; h12xr=1; h12zr=h12z; ir=.15;or=.81; - h12t=(0:11)'/6*pi; - h12 = feval(mfilename, ... - [h12x+h12xr*cos(h12t)*ir h12y*ones(size(h12t)) ... - h12z+h12zr*sin(h12t)*ir],[h12x+h12xr*cos(h12t)*or ... - h12y*ones(size(h12t)) h12z+h12zr*sin(h12t)*or], ... - 10,[],[],[],[], ... - [-h12xr*sin(h12t) zeros(size(h12t)) h12zr*cos(h12t)],... - 'FaceColor','none','EdgeColor','m'); - - % series of normal arrows, tangentially oriented, crossdir specified - or13=.91; h13t=(0:.5:12)'/6*pi; - locs = [h12x+h12xr*cos(h13t)*or13 h12y*ones(size(h13t)) h12z+h12zr*sin(h13t)*or13]; - h13 = feval(mfilename,locs(1:end-1,:),locs(2:end,:),6); - - % arrow with no line ==> oriented downwards - h14 = feval(mfilename,[3 3 .100001],[3 3 .1],30); - t6=text(3,3,3.6,'no line'); set(t6,'HorizontalAlignment','center'); - - % arrow with arrowheads at both ends - h15 = feval(mfilename,[-.5 -3 -3],[1 -3 -3],'Ends','both','FaceColor','g', ... - 'Length',20,'Width',3,'CrossDir',[0 0 1],'TipAngle',25); - - h=[h1;h2;h3;h4;h5;h6;h7;h8;h9;h10;h11;h12;h13;h14;h15]; - -function h = arrow_demo2(in) - axlim = in.axlim; - dolog = 1; - if (dolog), set(in.hs,'YData',10.^get(in.hs,'YData')); end; - shading('interp'); - view(2); - title(['Demo of the capabilities of the ARROW function in 2-D']); - hold on; [C,H]=contour(in.x,in.y,in.z,20,'-'); hold off; - for k=H', - set(k,'ZData',(axlim(6)+1)*ones(size(get(k,'XData'))),'Color','k'); - if (dolog), set(k,'YData',10.^get(k,'YData')); end; - end; - if (dolog), axis([axlim(1:2) 10.^axlim(3:4)]); set(gca,'YScale','log'); - else, axis(axlim(1:4)); end; - - % Normal blue arrow - start = [axlim(1) axlim(4) axlim(6)+2]; - stop = [in.x(in.iii) in.y(in.iii) axlim(6)+2]; - if (dolog), start(:,2)=10.^start(:,2); stop(:,2)=10.^stop(:,2); end; - h1 = feval(mfilename,start,stop,'EdgeColor','b','FaceColor','b'); - - % three arrows with varying fill, width, and baseangle - start = [-3 -3 10; -3 -1.5 10; -1.5 -3 10]; - stop = [-.03 -.03 10; -.03 -1.5 10; -1.5 -.03 10]; - if (dolog), start(:,2)=10.^start(:,2); stop(:,2)=10.^stop(:,2); end; - h2 = feval(mfilename,start,stop,24,[90;60;120],[],[0;0;4],'Ends',str2mat('both','stop','stop')); - set(h2(2),'EdgeColor',[0 .35 0],'FaceColor',[0 .85 .85]); - set(h2(3),'EdgeColor','r','FaceColor',[1 .5 1]); - h=[h1;h2]; - -function out = trueornan(x) -if isempty(x), - out=x; -else, - out = isnan(x); - out(~out) = x(~out); -end; diff --git a/utilities/checkoutCellDataForProject.m b/utilities/checkoutCellDataForProject.m index 9757996..f8c0d49 100755 --- a/utilities/checkoutCellDataForProject.m +++ b/utilities/checkoutCellDataForProject.m @@ -1,7 +1,7 @@ function [] = checkoutCellDataForProject global ANALYSIS_FOLDER; projFolder = uigetdir([ANALYSIS_FOLDER 'Projects' filesep], 'Choose project folder'); -global CELL_DATA_MASTER +cellData_folder = uigetdir([],'Choose cellData folder from which to copy data'); fid = fopen([projFolder filesep 'cellNames.txt'], 'r'); if fid < 0 @@ -12,8 +12,6 @@ cellNames = temp{1}; fclose(fid); -fprintf('Checking for %g files\n', length(cellNames)); - for i=1:length(cellNames) cellDataNames = cellNameToCellDataNames(cellNames{i}); for j=1:length(cellDataNames) @@ -21,14 +19,12 @@ if exist([ANALYSIS_FOLDER 'cellData' filesep cellData_fname], 'file') %already have the file %do nothing else - if exist([CELL_DATA_MASTER cellData_fname], 'file') + if exist([cellData_folder filesep cellData_fname], 'file') disp(['Copying ' cellData_fname]); - st = ['!cp -p ' [CELL_DATA_MASTER cellData_fname] ' ' ANALYSIS_FOLDER 'cellData' filesep]; - eval(st); + eval(['!cp -r ' [cellData_folder filesep cellData_fname] ' ' ANALYSIS_FOLDER 'cellData' filesep]); else - disp([CELL_DATA_MASTER cellData_fname ' not found']); + disp([cellData_folder filesep cellData_fname ' not found']); end end end -end -disp('Done'); \ No newline at end of file +end \ No newline at end of file diff --git a/utilities/checkoutRawDataForProject.m b/utilities/checkoutRawDataForProject.m index 97eff12..88ab4ba 100755 --- a/utilities/checkoutRawDataForProject.m +++ b/utilities/checkoutRawDataForProject.m @@ -14,8 +14,6 @@ cellNames = temp{1}; fclose(fid); -fprintf('Checking for %g files\n', length(cellNames)); - for i=1:length(cellNames) cellDataNames = cellNameToCellDataNames(cellNames{i}); for j=1:length(cellDataNames) @@ -41,5 +39,4 @@ end end end -end -disp('Done'); \ No newline at end of file +end \ No newline at end of file diff --git a/utilities/correctAngles.m b/utilities/correctAngles.m index bc88245..cc424a2 100644 --- a/utilities/correctAngles.m +++ b/utilities/correctAngles.m @@ -43,7 +43,7 @@ angleName = 'barAngle'; angleOffset = 0; - case 'Drifting Texture' + case 'Drifting Texture'; angleName = 'textureAngle'; angleOffset = 0; diff --git a/utilities/correctAnglesForCell.m b/utilities/correctAnglesForCell.m deleted file mode 100644 index 3700f30..0000000 --- a/utilities/correctAnglesForCell.m +++ /dev/null @@ -1,17 +0,0 @@ -function correctAnglesForCell(cname) - global CELL_DATA_FOLDER - fprintf('processing cellData %s\n', cname) - fname = fullfile(CELL_DATA_FOLDER, [cname, '.mat']); - load(fname) - - - cellData = correctAngles(cellData, cname); - if cellData == 1 - return - end - - %% Save cellData - disp('saving cell data'); - save(fname, 'cellData'); - -end \ No newline at end of file diff --git a/utilities/doSingleAnalysis.m b/utilities/doSingleAnalysis.m index d3e7072..44c20c4 100755 --- a/utilities/doSingleAnalysis.m +++ b/utilities/doSingleAnalysis.m @@ -1,23 +1,19 @@ -function resultTree = doSingleAnalysis(cellName, analysisClassName, cellFilter, epochFilter, cellData, analysisTable) -global PREFERENCE_FILES_FOLDER - -if nargin < 3 - cellFilter = []; -end +function resultTree = doSingleAnalysis(cellName, analysisClassName, cellFilter, epochFilter) if nargin < 4 epochFilter = []; end -% cell data is loaded below - -if nargin < 6 -%Open DataSetsAnalyses.txt file that defines the mapping between data set -%names and analysis classes - fid = fopen([PREFERENCE_FILES_FOLDER 'DataSetAnalyses.txt'], 'r'); - analysisTable = textscan(fid, '%s\t%s'); - fclose(fid); +if nargin < 3 + cellFilter = []; end +global ANALYSIS_FOLDER +global PREFERENCE_FILES_FOLDER +%Open DataSetsAnalyses.txt file that defines the mapping between data set +%names and analysis classes +fid = fopen([PREFERENCE_FILES_FOLDER 'DataSetAnalyses.txt'], 'r'); +analysisTable = textscan(fid, '%s\t%s'); +fclose(fid); %find correct row in this table Nanalyses = length(analysisTable{1}); @@ -53,11 +49,9 @@ nodeData.device = params_deviceOnly.deviceName; resultTree = resultTree.set(1, nodeData); -%load cellData if needed -if nargin < 5 - cellData = loadAndSyncCellData(cellName); -end - +%load cellData +cellData = loadAndSyncCellData(cellName); +%load([ANALYSIS_FOLDER 'cellData' filesep cellName]); dataSetKeys = cellData.savedDataSets.keys; %run cell filter diff --git a/utilities/extractVectorOverSplitParamFromSingleCellTree.m b/utilities/extractVectorOverSplitParamFromSingleCellTree.m deleted file mode 100644 index 4a8dc4a..0000000 --- a/utilities/extractVectorOverSplitParamFromSingleCellTree.m +++ /dev/null @@ -1,38 +0,0 @@ -function data = extractVectorOverSplitParamFromSingleCellTree(T, paramNames) -% T is analysis tree -% dataByCell is numCells x 2+numParams array: cellName, splitParam, responseValue1, responseValue2, ... - - -sT = T.subtree(2); -leafNodes = sT.findleaves; -data = {}; - -paramNames_typed = {}; -for paramIndex = 1:length(paramNames) - curNode = sT.get(leafNodes(1)); - paramStruct = curNode.(paramNames{paramIndex}); - paramType = paramStruct.type; - paramUnits = paramStruct.units; - if strcmp(paramType, 'byEpoch') - if strcmp(paramUnits, 's') - paramNames_typed{paramIndex,1} = [paramNames{paramIndex} '_median']; - else - paramNames_typed{paramIndex,1} = [paramNames{paramIndex} '_mean']; - end - else - paramNames_typed{paramIndex,1} = [paramNames{paramIndex} '_value']; - end -end - - -for paramIndex = 1:length(paramNames) - splitValues = zeros(length(leafNodes), 1); - dataValues = splitValues; - for j=1:length(leafNodes) - curNode = sT.get(leafNodes(j)); - splitValues(j) = curNode.splitValue; - dataValues(j) = curNode.(paramNames_typed{paramIndex}); - end - data(1,1) = {splitValues}; - data(1,1 + paramIndex) = {dataValues}; -end diff --git a/utilities/filterProjectByCellQuality.m b/utilities/filterProjectByCellQuality.m deleted file mode 100644 index 172c1bd..0000000 --- a/utilities/filterProjectByCellQuality.m +++ /dev/null @@ -1,44 +0,0 @@ -function goodCells = filterProjectByCellQuality(qrSet) - - infilename = [uigetdir('', 'input file location') filesep 'cellNames.txt']; - outfolder = uigetdir('', 'output file location'); - fid = fopen(infilename); - fline = 'temp'; - cellNames = {}; - while ~isempty(fline) - fline = fgetl(fid); - if isempty(fline) || (isscalar(fline) && fline < 0) - break; - end - if strfind(fline,',') - continue; - end - cellNames{end+1,1} = fline; - end - fclose(fid); - - fprintf('Checking %g cells\n', length(cellNames)); - - global CELL_DATA_FOLDER; - goodCells = {}; - for ci = 1:length(cellNames) - infilename = [CELL_DATA_FOLDER filesep cellNames{ci} '.mat']; - load(infilename); - map = cellData.tags; - if isKey(map, 'QualityRating') - qr = str2double(map('QualityRating')); - if any(qr == qrSet) - fprintf('Found good cell %g %s with quality rating %g\n', length(goodCells)+1, cellNames{ci}, qr); - goodCells{end+1,1} = cellNames{ci}; - end - end - end - - fid = fopen([outfolder filesep 'cellNames.txt'],'w'); - for i = 1:length(goodCells) - fprintf(fid, [goodCells{i} '\n']); - end - fclose(fid); - fprintf('Wrote cell names to %s\n',[outfolder filesep 'cellNames.txt']); - -end \ No newline at end of file diff --git a/utilities/getSustainedThresCross.m b/utilities/getSustainedThresCross.m old mode 100755 new mode 100644 index b5f39ed..3ce83ca --- a/utilities/getSustainedThresCross.m +++ b/utilities/getSustainedThresCross.m @@ -1,12 +1,15 @@ -function susCrossInd = getSustainedThresCross(V,th) -%Adam 9/22/15 +function susCrossInd = getSustainedThresCross(V) +%Adam 9/22/15, change 2/13/16 +% % % definition of "maximum" +Vsort = sort(V,'descend'); +Vmax = median(Vsort(1:10)); +th = 0.5*Vmax; +upperTh = 0.8*Vmax; +maxInd = find(V>=upperTh); - -[MaxV, MaxVind] = max(V); zeroInd = find(V == 0); -maxInd = find(V == MaxV); susCrossInd = []; @@ -22,7 +25,7 @@ if ~isempty(nextZeros) nextZero = nextZeros(1); end; - nextMaxima = maxInd(maxInd>Ind(indOfInd)); + nextMaxima = maxInd(maxInd>=Ind(indOfInd)); if ~isempty(nextMaxima) nextMax = nextMaxima(1); end; @@ -31,14 +34,9 @@ susCrossInd = [susCrossInd, Ind(indOfInd)]; end; end; - %if nextMax is empty - then don't include, - %unless it's the case below + %if nextMax is empty - then don't include end; -%If no such crossing was found, then the only crossings found are also maxima -%Commenting this out is an option, which will give more NaNs but maybe fewer outliers -if isempty(susCrossInd) - susCrossInd = MaxVind; -end; + diff --git a/utilities/makePositionVectors.m b/utilities/makePositionVectors.m old mode 100755 new mode 100644 index cfb616f..28c8a58 --- a/utilities/makePositionVectors.m +++ b/utilities/makePositionVectors.m @@ -15,8 +15,8 @@ for k=1:i %calculate vector end points - x_vect(k,1) = x(k) + (200*cos(ang(k))); - x_vect(k,2) = x(k) - (200*cos(ang(k))); + x_vect(k,1) = -x(k) + (200*cos(ang(k))); + x_vect(k,2) = -x(k) - (200*cos(ang(k))); y_vect(k,1) = y(k) + (200*sin(ang(k))); y_vect(k,2) = y(k) - (200*sin(ang(k))); end @@ -40,6 +40,6 @@ disp('Error: Abcissae and Ordinates must be of equal length!'); end - %x_vect = x_vect.'; - %y_vect = y_vect.'; + x_vect = x_vect.'; + y_vect = y_vect.'; end \ No newline at end of file diff --git a/utilities/makeTempFolderForExperiment.m b/utilities/makeTempFolderForExperiment.m index 1a29114..000ef09 100755 --- a/utilities/makeTempFolderForExperiment.m +++ b/utilities/makeTempFolderForExperiment.m @@ -1,10 +1,9 @@ function projectFolder = makeTempFolderForExperiment(expName) global ANALYSIS_FOLDER; -global CELL_DATA_FOLDER; projectFolder = [ANALYSIS_FOLDER 'Projects' filesep expName '_temp']; eval(['!rm -rf ' projectFolder]); eval(['!mkdir ' projectFolder]); -cellNames = ls([CELL_DATA_FOLDER expName '*.mat']); +cellNames = ls([ANALYSIS_FOLDER 'cellData' filesep expName '*.mat']); if ispc cellNames = cellstr(cellNames); else diff --git a/utilities/nanconv.m b/utilities/nanconv.m deleted file mode 100644 index 5dbc32b..0000000 --- a/utilities/nanconv.m +++ /dev/null @@ -1,114 +0,0 @@ -function c = nanconv(a, k, varargin) -% NANCONV Convolution in 1D or 2D ignoring NaNs. -% C = NANCONV(A, K) convolves A and K, correcting for any NaN values -% in the input vector A. The result is the same size as A (as though you -% called 'conv' or 'conv2' with the 'same' shape). -% -% C = NANCONV(A, K, 'param1', 'param2', ...) specifies one or more of the following: -% 'edge' - Apply edge correction to the output. -% 'noedge' - Do not apply edge correction to the output (default). -% 'nanout' - The result C should have NaNs in the same places as A. -% 'nonanout' - The result C should have ignored NaNs removed (default). -% Even with this option, C will have NaN values where the -% number of consecutive NaNs is too large to ignore. -% '2d' - Treat the input vectors as 2D matrices (default). -% '1d' - Treat the input vectors as 1D vectors. -% This option only matters if 'a' or 'k' is a row vector, -% and the other is a column vector. Otherwise, this -% option has no effect. -% -% NANCONV works by running 'conv2' either two or three times. The first -% time is run on the original input signals A and K, except all the -% NaN values in A are replaced with zeros. The 'same' input argument is -% used so the output is the same size as A. The second convolution is -% done between a matrix the same size as A, except with zeros wherever -% there is a NaN value in A, and ones everywhere else. The output from -% the first convolution is normalized by the output from the second -% convolution. This corrects for missing (NaN) values in A, but it has -% the side effect of correcting for edge effects due to the assumption of -% zero padding during convolution. When the optional 'noedge' parameter -% is included, the convolution is run a third time, this time on a matrix -% of all ones the same size as A. The output from this third convolution -% is used to restore the edge effects. The 'noedge' parameter is enabled -% by default so that the output from 'nanconv' is identical to the output -% from 'conv2' when the input argument A has no NaN values. -% -% See also conv, conv2 -% -% AUTHOR: Benjamin Kraus (bkraus@bu.edu, ben@benkraus.com) -% Copyright (c) 2013, Benjamin Kraus -% $Id: nanconv.m 4861 2013-05-27 03:16:22Z bkraus $ - -% Process input arguments -for arg = 1:nargin-2 - switch lower(varargin{arg}) - case 'edge'; edge = true; % Apply edge correction - case 'noedge'; edge = false; % Do not apply edge correction - case {'same','full','valid'}; shape = varargin{arg}; % Specify shape - case 'nanout'; nanout = true; % Include original NaNs in the output. - case 'nonanout'; nanout = false; % Do not include NaNs in the output. - case {'2d','is2d'}; is1D = false; % Treat the input as 2D - case {'1d','is1d'}; is1D = true; % Treat the input as 1D - end -end - -% Apply default options when necessary. -if(exist('edge','var')~=1); edge = false; end -if(exist('nanout','var')~=1); nanout = false; end -if(exist('is1D','var')~=1); is1D = false; end -if(exist('shape','var')~=1); shape = 'same'; -elseif(~strcmp(shape,'same')) - error([mfilename ':NotImplemented'],'Shape ''%s'' not implemented',shape); -end - -% Get the size of 'a' for use later. -sza = size(a); - -% If 1D, then convert them both to columns. -% This modification only matters if 'a' or 'k' is a row vector, and the -% other is a column vector. Otherwise, this argument has no effect. -if(is1D); - if(~isvector(a) || ~isvector(k)) - error('MATLAB:conv:AorBNotVector','A and B must be vectors.'); - end - a = a(:); k = k(:); -end - -% Flat function for comparison. -o = ones(size(a)); - -% Flat function with NaNs for comparison. -on = ones(size(a)); - -% Find all the NaNs in the input. -n = isnan(a); - -% Replace NaNs with zero, both in 'a' and 'on'. -a(n) = 0; -on(n) = 0; - -% Check that the filter does not have NaNs. -if(any(isnan(k))); - error([mfilename ':NaNinFilter'],'Filter (k) contains NaN values.'); -end - -% Calculate what a 'flat' function looks like after convolution. -if(any(n(:)) || edge) - flat = conv2(on,k,shape); -else flat = o; -end - -% The line above will automatically include a correction for edge effects, -% so remove that correction if the user does not want it. -if(any(n(:)) && ~edge); flat = flat./conv2(o,k,shape); end - -% Do the actual convolution -c = conv2(a,k,shape)./flat; - -% If requested, replace output values with NaNs corresponding to input. -if(nanout); c(n) = NaN; end - -% If 1D, convert back to the original shape. -if(is1D && sza(1) == 1); c = c.'; end - -end \ No newline at end of file diff --git a/utilities/normtoMaxCellAvg.m b/utilities/normtoMaxCellAvg.m old mode 100755 new mode 100644 index faf10ab..d971e08 --- a/utilities/normtoMaxCellAvg.m +++ b/utilities/normtoMaxCellAvg.m @@ -8,8 +8,8 @@ normResp = zeros(row,col); for i=1:row normResp(i,:) = Data(i,:)./max(Data(i,:)); %normalize to max - j = find(normResp(i,:)==1); %find preferred stimulus - normResp(i,:) = circshift(normResp(i,:),-min(j)+7,2); %shift max to middle + %j = find(normResp(i,:)==1); %find preferred stimulus + %normResp(i,:) = circshift(normResp(i,:),-min(j)+7,2); %shift max to middle end respMean = transpose(mean(normResp,1)); respErr = transpose(std(normResp,1)/sqrt(row)); diff --git a/utilities/paramOverlapMany2D.m b/utilities/paramOverlapMany2D.m deleted file mode 100755 index 92a7490..0000000 --- a/utilities/paramOverlapMany2D.m +++ /dev/null @@ -1,138 +0,0 @@ -function scatterPlotInfo = paramOverlapMany2D(analysisTree, paramList, cellTypeList) -%1/23/2015. Version 2 -%"main cell type" will be the first type on the list of celltypes passed down to -%this function. - -global TYPOLOGY_FILES_FOLDER; -pathname = TYPOLOGY_FILES_FOLDER; - -%paramList: Greg's format is [L1 L2 L3] = getParameterListByType(nodeData); -%Adam's format is L = adaptParamList(nodeData). -%Here use Adam's. - - - - - -[cellTypeList, numOfCells, cellNamesByType, paramList, paramByType] = getParamDataFromAnalysisTree(analysisTree, paramList, cellTypeList); - -mainCellType = cellTypeList{1}; -otherCellTypes = cellTypeList(2:end); -paramForMainCellType = paramByType{1}; -paramForOtherTypes = paramByType(2:end); -numOtherTypes = length(otherCellTypes); -numParams = length(paramList); -% Make matrices with only the scalar parameters -% Deal with vector parameters later... - -for I = 1:(size(paramForMainCellType,1) * size(paramForMainCellType,2)) - %Shouldn't be any empty parameter values (but there are...) - if isempty(paramForMainCellType{I}) - paramForMainCellType{I} = NaN; - end; -end; - -paramForMainCellTypeMAT = cell2mat(paramForMainCellType); -paramForOtherTypesMATS = cell(numOtherTypes,1); -for otherTypeInd = 1:numOtherTypes - - for I = 1:(size(paramForOtherTypes{otherTypeInd},1) * size(paramForOtherTypes{otherTypeInd},2)) - %Shouldn't be any empty parameter values (but there are...) - if isempty(paramForOtherTypes{otherTypeInd}{I}) - paramForOtherTypes{otherTypeInd}{I} = NaN; - end; - end; - - paramForOtherTypesMATS{otherTypeInd} = cell2mat(paramForOtherTypes{otherTypeInd}); -end; -% % % - - - -% %save -% mainCellType(strfind(mainCellType,' ')) = ''; -% mainCellType(strfind(mainCellType,'/')) = ''; -% mainCellType(strfind(mainCellType,'-')) = ''; -% -% D = datestr(date); -% D(D == '-') = ''; -% filename = ['overlapMany2D_',mainCellType,'_',D]; -% fullfilename = [pathname, filename,'.mat']; -% save(fullfilename, 'paramList', 'mainCellType', 'cellNamesMainType','paramForMainCellType','otherCellTypes','cellNamesOtherTypes','paramForOtherTypes'); - - -%Make 2D plots. -numParameterPairs = numParams.*(numParams-1)./2; -paramPairCount = 0; -scatterPlotInfo = cell(numParameterPairs,1); -%figure; - -for paramInd1 = 1:numParams-1 - MmainParam1 = paramForMainCellTypeMAT(paramInd1,:); - %MmainParam1 = MmainParam1(~isnan(MmainParam1) & ~(MmainParam1==inf)); - for otherTypeInd = 1:numOtherTypes - M2 = paramForOtherTypesMATS{otherTypeInd}(paramInd1,:); - %M2 = M2(~isnan(M2) & ~(M2==inf)); - M_otherParam1{otherTypeInd} = M2; - end; - - for paramInd2 = paramInd1+1:numParams - MmainParam2 = paramForMainCellTypeMAT(paramInd2,:); - %MmainParam2 = MmainParam2(~isnan(MmainParam2) & ~(MmainParam2==inf)); - for otherTypeInd = 1:numOtherTypes - M2 = paramForOtherTypesMATS{otherTypeInd}(paramInd2,:); - %M2 = M2(~isnan(M2) & ~(M2==inf)); - M_otherParam2{otherTypeInd} = M2; - end; - - if ~all(isnan(MmainParam1)| MmainParam1==inf) && ~all(isnan(MmainParam2)| MmainParam2==inf) - paramPairCount = paramPairCount+1; - if mod(paramPairCount,4) == 1 - figure; - end; - subplotFigure(paramPairCount, numParameterPairs, 4); - - scatter(MmainParam1, MmainParam2, 'DisplayName', mainCellType, 'MarkerFaceColor',[1 0 0],... - 'MarkerEdgeColor',[1 0 0]); - hold on; - for otherTypeInd = 1:numOtherTypes - if ~all(isnan(M_otherParam1{otherTypeInd})| M_otherParam1{otherTypeInd}==inf) && ~all(isnan(M_otherParam2{otherTypeInd})| M_otherParam2{otherTypeInd}==inf) - scatter(M_otherParam1{otherTypeInd}, M_otherParam2{otherTypeInd}, 'DisplayName', otherCellTypes{otherTypeInd}); - title([paramList{paramInd1},' vs ', paramList{paramInd2}]); - end; - end; - hold off; - - % % export scatter plot info (S holds info of a single plot) - S.Xvectors = [MmainParam1; M_otherParam1']'; - S.Yvectors = [MmainParam2; M_otherParam2']'; - S.plotTitle = [paramList{paramInd1},' vs ', paramList{paramInd2}]; - S.plotLegend = cellTypeList; - S.numberOfCells = numOfCells; - - S.cellNamesByType = cellNamesByType; - - paramXdataByType = cell(1+numOtherTypes, 1); - paramYdataByType = cell(1+numOtherTypes, 1); - - for cellTypeInd = 1:numOtherTypes+1 - paramXdataByType{cellTypeInd} = [paramByType{cellTypeInd}{paramInd1,:}]; - paramYdataByType{cellTypeInd} = [paramByType{cellTypeInd}{paramInd2,:}]; - end; - S.paramXdataByType = paramXdataByType; - S.paramYdataByType = paramYdataByType; - - scatterPlotInfo{paramPairCount} = S; - % % % - end; - end; -end; - -% Create legend -legend1 = legend('show'); -set(legend1,'FontSize',12); - -end - - - diff --git a/utilities/paramOverlapMany2Dnew.m b/utilities/paramOverlapMany2Dnew.m index ade8acc..2d2211f 100755 --- a/utilities/paramOverlapMany2Dnew.m +++ b/utilities/paramOverlapMany2Dnew.m @@ -92,7 +92,7 @@ if mod(paramPairCount,1) == 0 figure; end; - %subplotFigure(paramPairCount, numParameterPairs, 1,1); + subplotFigure(paramPairCount, numParameterPairs, 1,1); scatter(MmainParam1, MmainParam2, 'DisplayName', mainCellType, 'MarkerFaceColor',[1 0 0],... 'MarkerEdgeColor',[1 0 0]); diff --git a/utilities/parseRawDataFiles.m b/utilities/parseRawDataFiles.m index b4b18ef..b3a75a6 100755 --- a/utilities/parseRawDataFiles.m +++ b/utilities/parseRawDataFiles.m @@ -1,8 +1,10 @@ function parseRawDataFiles(expDate) global RAW_DATA_FOLDER; -global CELL_DATA_FOLDER; -D_raw = dir(RAW_DATA_FOLDER); -D_cell = dir(CELL_DATA_FOLDER); +global ANALYSIS_FOLDER; +rawDataDir = RAW_DATA_FOLDER; +cellDataDir = [ANALYSIS_FOLDER 'cellData' filesep]; +D_raw = dir(rawDataDir); +D_cell = dir(cellDataDir); allCellDataNames = {}; z = 1; @@ -26,17 +28,17 @@ function parseRawDataFiles(expDate) end if writeOK tic; - disp(['parsing file ' curCellName]); - fname = [RAW_DATA_FOLDER curCellName '.h5']; + disp(['parsing file' curCellName]); + fname = [rawDataDir curCellName '.h5']; if h5readatt(fname, '/', 'version') == 2 disp('Parsing cells in Symphony 2 file') cells = symphony2Mapper(fname); - arrayfun(@(cellData) save([CELL_DATA_FOLDER cellData.savedFileName], 'cellData'), cells); + arrayfun(@(cellData) save([cellDataDir cellData.savedFileName], 'cellData'), cells); disp(['Elapsed time: ' num2str(toc) ' seconds']); else cellData = CellData(fname); - save([CELL_DATA_FOLDER curCellName], 'cellData'); + save([cellDataDir curCellName], 'cellData'); disp(['Elapsed time: ' num2str(toc) ' seconds']); end end diff --git a/utilities/splitProjectsBy.m b/utilities/splitProjectsBy.m index 356f7d7..cb8b160 100755 --- a/utilities/splitProjectsBy.m +++ b/utilities/splitProjectsBy.m @@ -8,15 +8,13 @@ %dataSet prefixes, and optional fourth argument of epoch filters for each data %set global ANALYSIS_FOLDER; -global CELL_DATA_MASTER; -if ~(exist(CELL_DATA_MASTER, 'dir') == 7) - disp(['Could not connect to CellDataMaster at ' CELL_DATA_MASTER]); - return; +if exist([filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster']) == 7 + cellDataMasterFolder = [filesep 'Volumes' filesep 'SchwartzLab' filesep 'CellDataMaster']; else - cellDataMasterFolder = CELL_DATA_MASTER; + disp('Could not connect to CellDataMaster'); + return; end - if nargin==1 splitKey = varargin{1}; @@ -55,7 +53,7 @@ L = length(cellDataBaseNames); projMap = containers.Map; -if strcmp(splitKey, 'expDate') +if strcmp(splitKey, 'expDate'); for i=1:L disp(['Cell ' num2str(i) ' of ' num2str(L)]); if ~isempty(cellDataBaseNames{i}) @@ -68,7 +66,7 @@ end end end -elseif strcmp(splitKey, 'hasDataSet') +elseif strcmp(splitKey, 'hasDataSet'); for i=1:L disp(['Cell ' num2str(i) ' of ' num2str(L)]); if ~isempty(cellDataBaseNames{i}) @@ -86,7 +84,7 @@ end end end -elseif strcmp(splitKey, 'cellTypeWithDataSets') +elseif strcmp(splitKey, 'cellTypeWithDataSets'); for i=1:L disp(['Cell ' num2str(i) ' of ' num2str(L)]); if ~isempty(cellDataBaseNames{i}) @@ -134,7 +132,7 @@ end end end -elseif strcmp(splitKey, 'cellType') %cell type +elseif strcmp(splitKey, 'cellType'); %cell type for i=1:L disp(['Cell ' num2str(i) ' of ' num2str(L)]); if ~isempty(cellDataBaseNames{i}) diff --git a/utilities/symphony2Mapper.m b/utilities/symphony2Mapper.m index 5721dbd..f03443d 100644 --- a/utilities/symphony2Mapper.m +++ b/utilities/symphony2Mapper.m @@ -17,13 +17,9 @@ info = h5info(fname); epochsByCellMap = getEpochsByCellLabel(fname, info.Groups(1).Groups(2).Groups); - sourceLinks = info.Groups(1).Groups(5).Links; - sourceTree = tree(); - for i = 1 : numel(sourceLinks) - sourceTree = sourceTree.graft(1, buildSourceTree(sourceLinks(i).Value{:}, fname)); - end - + sourceTree = buildSourceTree(info.Groups(1).Groups(5).Links.Value{:}, fname); numberOfCells = numel(epochsByCellMap.keys); + cells = CellData.empty(numberOfCells, 0); labels = epochsByCellMap.keys; @@ -150,13 +146,7 @@ else source = epochGroup.Links(2).Value{:}; end - try - label = h5readatt(fname, source, 'label'); - catch - % if there is any problem check links. - source = epochGroup.Links(2).Value{:}; - label = h5readatt(fname, source, 'label'); - end + label = h5readatt(fname, source, 'label'); end function map = buildAttributes(h5group, fname, map) @@ -211,21 +201,16 @@ function map = getSourceAttributes(sourceTree, label, map) - id = find(sourceTree.treefun(@(node) ~isempty(node) && strcmp(node('label'), label))); + id = find(sourceTree.treefun(@(node) strcmp(node('label'), label))); while id > 0 currentMap = sourceTree.get(id); - id = sourceTree.getparent(id); - - if isempty(currentMap) - continue; - end - keys = currentMap.keys; for i = 1 : numel(keys) k = keys{i}; map = addToMap(map, k, currentMap(k)); end + id = sourceTree.getparent(id); end end