From 231a81ca6812d1f84431616bd27bd6f60cca73b3 Mon Sep 17 00:00:00 2001 From: ed kang Date: Sat, 9 Jan 2016 11:17:15 -0500 Subject: [PATCH 1/6] fixes to properties * fix properties that are not saving. --- +spoke/SpikeGrid.m | 51 +++++++++++++++++++++--------------- +spoke/SpikeGridController.m | 2 +- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/+spoke/SpikeGrid.m b/+spoke/SpikeGrid.m index 629d3b8..d5e34fc 100644 --- a/+spoke/SpikeGrid.m +++ b/+spoke/SpikeGrid.m @@ -93,7 +93,7 @@ %Spike waveform display properties spikeTimeWindow = [-1 2] * 1e-3; %2 element vector ([pre post]) indicating times, in seconds, to display before and after threshold crossing spikeAmpUnits = 'volts'; %One of {'volts' 'rmsMultiple'} indicating units to use for spike plot display. Value of 'rmsMultiple' only available if thresholdType='rmsMultiple' - %spikeAmpWindow = [-4000 4000]; + %spikeAmpWindow_ = [-4000 4000]; spikesPerPlot = 100; %Number of sweeps to display in each grid figure spikesPerPlotClearMode = 'all'; %One of {'all' 'oldest'} @@ -123,7 +123,7 @@ end properties (SetObservable, Dependent) - spikeAmpWindow; %2 element vector ([min max]) indicating voltage bounds or RMSMultiple (depending on thresholdType) for each spike plot + spikeAmpWindow_; %2 element vector ([min max]) indicating voltage bounds or RMSMultiple (depending on thresholdType) for each spike plot refreshPeriodMaxSpikeRate = inf; %Maximum spike rate (Hz) to detect/plot at each refresh period; spikes above this rate are discarded numAuxChans; %Number of auxiliary end @@ -155,6 +155,15 @@ properties (Hidden) maxBufSizeSeconds = 1; + + % The following are properties that were SetAccess=protected, but + % have been moved out of protected to allow config file saves with + % most. + refreshPeriodMaxNumSpikes = inf; %Maximum number of spikes to detect/plot during a given refresh period + + % The following are properties that back up dependent properties. + % This is for properties that need to be saved to disk. + spikeAmpWindow; % backs up property spikeAmpWindow_ end @@ -225,9 +234,7 @@ stimLastEventScanNumWindow; %1x2 array indicating start/end scan numbers for last stimulus trial stimEventCount_; %Struct var containing stimEventCount value for each of the stimEventTypes_ - - refreshPeriodMaxNumSpikes = inf; %Maximum number of spikes to detect/plot during a given refresh period - + bmarkReadTimeStats = zeros(3,1); %Array of [mean std n] bmarkPreProcessTimeStats = zeros(3,1);; %Array of [mean std n] bmarkPlotTimeStats = zeros(3,1);; %Array of [mean std n] @@ -301,7 +308,7 @@ obj.hThresholdLines = repmat({ones(numPadChans,1) * -1},2,1); obj.hSpikeLines = gobjects(numPadChans,1); - obj.spikeAmpWindow = [-aiRangeMax aiRangeMax]; + obj.spikeAmpWindow_ = [-aiRangeMax aiRangeMax]; obj.tabDisplayed = 1; obj.refreshRate = obj.refreshRate; %apply default value @@ -365,7 +372,7 @@ function ziniCreateGrids(obj) obj.hPanels.psth(i) = uipanel(obj.hFigs.psth,'Position',panelPosn); %Places axes in panel and configure - obj.hPlots(i) = axes('Parent',obj.hPanels.waveform(i),'Position',[0 0 1 1],'XLim',obj.spikeTimeWindow); %,'YLim',obj.spikeAmpWindow); + obj.hPlots(i) = axes('Parent',obj.hPanels.waveform(i),'Position',[0 0 1 1],'XLim',obj.spikeTimeWindow); %,'YLim',obj.spikeAmpWindow_); obj.hRasters(i) = axes('Parent',obj.hPanels.raster(i),'Position',[0 0 1 1],'XLim',obj.stimTimeWindow); obj.hPSTHs(i) = axes('Parent',obj.hPanels.psth(i),'Position',[0 0 1 1]); @@ -635,14 +642,14 @@ function ziniCreateGrids(obj) %Side-effects if ~strcmpi(oldVal,val) - %Adjust thresholdVal & spikeAmpWindow + %Adjust thresholdVal & spikeAmpWindow_ %TODO(?): A smarter adjustment based on the last-cached RMS values, somehow handlign the variety across channels switch val case 'volts' - obj.spikeAmpWindow = [-1 1] * obj.sglParamCache.niAiRangeMax; + obj.spikeAmpWindow_ = [-1 1] * obj.sglParamCache.niAiRangeMax; case 'rmsMultiple' - obj.spikeAmpWindow = [-2 10] * obj.thresholdVal; + obj.spikeAmpWindow_ = [-2 10] * obj.thresholdVal; end %Refresh threshold lines @@ -650,13 +657,13 @@ function ziniCreateGrids(obj) end end - - function val = get.spikeAmpWindow(obj) - val = get(obj.hPlots(1),'YLim'); + function val = get.spikeAmpWindow_(obj) + %val = get(obj.hPlots(1),'YLim'); + val = obj.spikeAmpWindow; end - function set.spikeAmpWindow(obj,val) - obj.validatePropArg('spikeAmpWindow',val); + function set.spikeAmpWindow_(obj,val) + obj.validatePropArg('spikeAmpWindow_',val); if strcmpi(obj.spikeAmpUnits,'volts'); aiRangeMax = obj.sglParamCache.niAiRangeMax; @@ -669,6 +676,8 @@ function ziniCreateGrids(obj) set(obj.hPlots,'YLim',val); + %Set real property + obj.spikeAmpWindow = val; end function set.spikeTimeWindow(obj,val) @@ -913,17 +922,17 @@ function ziniCreateGrids(obj) %Side Effects if ~strcmpi(oldVal,val) - %Adjust thresholdVal & spikeAmpWindow + %Adjust thresholdVal & spikeAmpWindow_ %TODO(?): A smarter adjustment based on the last-cached RMS values, somehow handlign the variety across channels switch val case 'volts' aiRangeMax = obj.sglParamCache.niAiRangeMax; obj.thresholdVal = .1 * aiRangeMax; - obj.spikeAmpWindow = [-1 1] * aiRangeMax; + obj.spikeAmpWindow_ = [-1 1] * aiRangeMax; case 'rmsMultiple' obj.thresholdVal = 5; - obj.spikeAmpWindow = [-2*obj.thresholdVal 10*obj.thresholdVal]; + obj.spikeAmpWindow_ = [-2*obj.thresholdVal 10*obj.thresholdVal]; end %Redraw threshold lines @@ -1164,7 +1173,7 @@ function saveConfigAs(obj,filename) end %Save model properties - obj.mdlSaveConfig(filename,'include',{'spikeAmpWindow' 'numAuxChans' 'gridFigPosition' 'psthFigPosition'}); + obj.mdlSaveConfig(filename,'include',{'spikeAmpWindow_' 'numAuxChans' 'gridFigPosition' 'psthFigPosition'}); %Save controller fig layout if ~isempty(obj.hController) @@ -2546,8 +2555,8 @@ function zprvClearPlots(obj,displaysToClear,reuseThreshold) s.thresholdRMSRefreshOnRetrigger = struct('Classes','binaryflex','Attributes','scalar'); s.spikeTimeWindow = struct('Attributes',{{'numel' 2 'finite'}}); -%s.spikeAmpWindow = struct('Attributes',{{'finite' '1d'}}); -s.spikeAmpWindow = struct('Attributes',{{'numel' 2 'finite'}}); +%s.spikeAmpWindow_ = struct('Attributes',{{'finite' '1d'}}); +s.spikeAmpWindow_ = struct('Attributes',{{'numel' 2 'finite'}}); s.spikeAmpUnits = struct('Options',{{'volts' 'rmsMultiple'}}); diff --git a/+spoke/SpikeGridController.m b/+spoke/SpikeGridController.m index ebf0e1f..71cc917 100644 --- a/+spoke/SpikeGridController.m +++ b/+spoke/SpikeGridController.m @@ -354,7 +354,7 @@ function stepThresholdVal(obj,direction) %frequently-adjusted property table bindings - s.spikeAmpWindow = struct('GuiIDs',{{'SpikeGrid','pcFreqAdjustProps'}},'PropControlData',struct('format','char')); + s.spikeAmpWindow_ = struct('GuiIDs',{{'SpikeGrid','pcFreqAdjustProps'}},'PropControlData',struct('format','char')); s.spikeTimeWindow = struct('GuiIDs',{{'SpikeGrid','pcFreqAdjustProps'}},'PropControlData',struct('format','char')); s.spikesPerPlot = struct('GuiIDs',{{'SpikeGrid','pcFreqAdjustProps'}},'PropControlData',struct('format','numeric')); From 2b3ff286268f82b74461ab990dda8d0b73d31ffa Mon Sep 17 00:00:00 2001 From: ed kang Date: Sat, 9 Jan 2016 11:28:12 -0500 Subject: [PATCH 2/6] fix to fix --- +spoke/SpikeGrid.m | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/+spoke/SpikeGrid.m b/+spoke/SpikeGrid.m index d5e34fc..775f108 100644 --- a/+spoke/SpikeGrid.m +++ b/+spoke/SpikeGrid.m @@ -115,7 +115,15 @@ psthTimerPeriod = inf; %Period, in seconds, at which plotPSTH() method is called automatically when displayMode='raster' channelSubset = inf; %Subset of channels to acquire from + + % The following are properties that were SetAccess=protected, but + % have been moved out of protected to allow config file saves with + % most. + refreshPeriodMaxNumSpikes = inf; %Maximum number of spikes to detect/plot during a given refresh period + % The following are properties that back up dependent properties. + % This is for properties that need to be saved to disk. + spikeAmpWindow; % backs up property spikeAmpWindow_ end properties (SetObservable, Transient) @@ -155,18 +163,8 @@ properties (Hidden) maxBufSizeSeconds = 1; - - % The following are properties that were SetAccess=protected, but - % have been moved out of protected to allow config file saves with - % most. - refreshPeriodMaxNumSpikes = inf; %Maximum number of spikes to detect/plot during a given refresh period - - % The following are properties that back up dependent properties. - % This is for properties that need to be saved to disk. - spikeAmpWindow; % backs up property spikeAmpWindow_ end - properties (Hidden,SetAccess=protected) hSGL; %Handle to SpikeGLX object sglParamCache; %cached SpikeGL parameters From 8aaea206479977afaa0e2e25c1a43d1f0591e013 Mon Sep 17 00:00:00 2001 From: ed kang Date: Sat, 9 Jan 2016 11:36:01 -0500 Subject: [PATCH 3/6] force recalc of dependent property --- +spoke/SpikeGrid.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/+spoke/SpikeGrid.m b/+spoke/SpikeGrid.m index 775f108..9a27986 100644 --- a/+spoke/SpikeGrid.m +++ b/+spoke/SpikeGrid.m @@ -575,6 +575,11 @@ function ziniCreateGrids(obj) obj.refreshPeriodMaxNumSpikes = ceil(val / obj.refreshRate); end + function set.refreshPeriodMaxNumSpikes(obj,val) + % force recalc of dependent property + obj.refreshPeriodMaxSpikeRate = obj.refreshPeriodMaxSpikeRate; + end + function val = get.refreshPeriodAvgScans(obj) val = round(get(obj.hTimer,'Period') * obj.sglParamCache.niSampRate); end @@ -678,6 +683,11 @@ function ziniCreateGrids(obj) obj.spikeAmpWindow = val; end + function set.spikeAmpWindow(obj,val) + %force recalc of dependent property + obj.spikeAmpWindow = obj.spikeAmpWindow; + end + function set.spikeTimeWindow(obj,val) obj.zprpAssertNotRunning('spikeTimeWindow'); obj.validatePropArg('spikeTimeWindow',val); From 855dd88d6691a3ff0c4a4f6ed9d0a342764b9ecc Mon Sep 17 00:00:00 2001 From: ed kang Date: Sat, 9 Jan 2016 13:26:38 -0500 Subject: [PATCH 4/6] prop reader fix for special case when single channel in SpikeGLX --- +spoke/SpikeGrid.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/+spoke/SpikeGrid.m b/+spoke/SpikeGrid.m index 9a27986..9b53bea 100644 --- a/+spoke/SpikeGrid.m +++ b/+spoke/SpikeGrid.m @@ -503,8 +503,8 @@ function ziniCreateGrids(obj) function val = get.numChans(obj) %val = obj.hSpoke.n_chan; - neuralChans = str2num(obj.sglParamCache.niMNChans1); %#ok - muxAnalogChans = str2num(obj.sglParamCache.niMAChans1); %#ok + neuralChans = str2num(char(obj.sglParamCache.niMNChans1)); %#ok + muxAnalogChans = str2num(char(obj.sglParamCache.niMAChans1)); %#ok val = obj.sglParamCache.niMuxFactor * (numel(neuralChans) + numel(muxAnalogChans)) + obj.numAuxChans; end From a42bd60a3c75c5feda0187a5457361c86dd582d1 Mon Sep 17 00:00:00 2001 From: ed kang Date: Sat, 9 Jan 2016 13:30:35 -0500 Subject: [PATCH 5/6] removed recursive set --- +spoke/SpikeGrid.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/+spoke/SpikeGrid.m b/+spoke/SpikeGrid.m index 9b53bea..cbd7595 100644 --- a/+spoke/SpikeGrid.m +++ b/+spoke/SpikeGrid.m @@ -577,7 +577,7 @@ function ziniCreateGrids(obj) function set.refreshPeriodMaxNumSpikes(obj,val) % force recalc of dependent property - obj.refreshPeriodMaxSpikeRate = obj.refreshPeriodMaxSpikeRate; + obj.refreshPeriodMaxNumSpikes = val; end function val = get.refreshPeriodAvgScans(obj) @@ -685,7 +685,7 @@ function ziniCreateGrids(obj) function set.spikeAmpWindow(obj,val) %force recalc of dependent property - obj.spikeAmpWindow = obj.spikeAmpWindow; + obj.spikeAmpWindow = val; end function set.spikeTimeWindow(obj,val) From 2f64a245c46bd0cb86b6c4a00e9d96b480bad9af Mon Sep 17 00:00:00 2001 From: ed kang Date: Sat, 9 Jan 2016 14:00:47 -0500 Subject: [PATCH 6/6] fixing props --- +spoke/SpikeGrid.m | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/+spoke/SpikeGrid.m b/+spoke/SpikeGrid.m index cbd7595..3518acd 100644 --- a/+spoke/SpikeGrid.m +++ b/+spoke/SpikeGrid.m @@ -119,7 +119,7 @@ % The following are properties that were SetAccess=protected, but % have been moved out of protected to allow config file saves with % most. - refreshPeriodMaxNumSpikes = inf; %Maximum number of spikes to detect/plot during a given refresh period + refreshPeriodMaxSpikeRate = inf; %Maximum spike rate (Hz) to detect/plot at each refresh period; spikes above this rate are discarded % The following are properties that back up dependent properties. % This is for properties that need to be saved to disk. @@ -132,7 +132,7 @@ properties (SetObservable, Dependent) spikeAmpWindow_; %2 element vector ([min max]) indicating voltage bounds or RMSMultiple (depending on thresholdType) for each spike plot - refreshPeriodMaxSpikeRate = inf; %Maximum spike rate (Hz) to detect/plot at each refresh period; spikes above this rate are discarded + refreshPeriodMaxNumSpikes = inf; %Maximum number of spikes to detect/plot during a given refresh period numAuxChans; %Number of auxiliary end @@ -565,19 +565,14 @@ function ziniCreateGrids(obj) val = ceil(numPadChans/obj.PLOTS_PER_TAB); end - function val = get.refreshPeriodMaxSpikeRate(obj) - val = obj.refreshPeriodMaxNumSpikes * obj.refreshRate; + function val = get.refreshPeriodMaxNumSpikes(obj) % DEPENDENT PROPERTY + val = obj.refreshPeriodMaxSpikeRate / obj.refreshRate; end - function set.refreshPeriodMaxSpikeRate(obj,val) + function set.refreshPeriodMaxSpikeRate(obj,val) % REAL DEAL obj.validatePropArg('refreshPeriodMaxSpikeRate',val); - - obj.refreshPeriodMaxNumSpikes = ceil(val / obj.refreshRate); - end - - function set.refreshPeriodMaxNumSpikes(obj,val) - % force recalc of dependent property - obj.refreshPeriodMaxNumSpikes = val; + lclVar = ceil(val / obj.refreshRate); + obj.refreshPeriodMaxSpikeRate = lclVar * obj.refreshRate; end function val = get.refreshPeriodAvgScans(obj)