Skip to content

Commit

Permalink
updated streaming in CellExplorer, other minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
petersenpeter committed Jun 29, 2023
1 parent fb6f5ae commit 30b721e
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 90 deletions.
6 changes: 6 additions & 0 deletions CellExplorer.m
Original file line number Diff line number Diff line change
Expand Up @@ -11264,6 +11264,9 @@ function reInitializeSession(~,~)
customPlotOptions = {};
else
customPlotOptions = what('customPlots');
if size(customPlotOptions,1)>1
customPlotOptions = customPlotOptions(1);
end
customPlotOptions = cellfun(@(X) X(1:end-2),customPlotOptions.m,'UniformOutput', false);
customPlotOptions(strcmpi(customPlotOptions,'template')) = [];
end
Expand Down Expand Up @@ -11360,6 +11363,9 @@ function reInitializeSession(~,~)
spikesPlots = {};
else
customSpikePlotOptions = what('customSpikesPlots');
if size(customSpikePlotOptions,1)>1
customSpikePlotOptions = customSpikePlotOptions(1);
end
customSpikePlotOptions = cellfun(@(X) X(1:end-2),customSpikePlotOptions.m,'UniformOutput', false);
customSpikePlotOptions(strcmpi(customSpikePlotOptions,'spikes_template')) = [];
spikesPlots = {};
Expand Down
182 changes: 100 additions & 82 deletions NeuroScope2.m
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ function NeuroScope2(varargin)
% Plotting data
plotData;

if UI.t0 == UI.t_total-UI.settings.windowDuration
UI.streamingText = text(UI.plot_axis1,UI.settings.windowDuration/2,1,'End of file','FontWeight', 'Bold','VerticalAlignment', 'top','HorizontalAlignment','center','color',UI.settings.primaryColor,'HitTest','off');
end

% Updating epoch axes
if ishandle(epoch_plotElements.t0)
delete(epoch_plotElements.t0)
Expand Down Expand Up @@ -346,9 +350,13 @@ function NeuroScope2(varargin)
UI.menu.display.channelOrder.option(4) = uimenu(UI.menu.display.channelOrder.topMenu,menuLabel,'Descending channel order',menuSelectedFcn,@setChannelOrder);
UI.menu.display.channelOrder.option(UI.settings.channelOrder).Checked = 'on';

UI.menu.display.colorgroups.topMenu = uimenu(UI.menu.display.topMenu,menuLabel,'Color groups');
UI.menu.display.colorgroups.option(1) = uimenu(UI.menu.display.colorgroups.topMenu,menuLabel,'By electrode groups',menuSelectedFcn,@setColorGroups);
UI.menu.display.colorgroups.option(2) = uimenu(UI.menu.display.colorgroups.topMenu,menuLabel,'By channel order',menuSelectedFcn,@setColorGroups);
UI.menu.display.colorgroups.option(3) = uimenu(UI.menu.display.colorgroups.topMenu,menuLabel,'By custom-sized channel groups',menuSelectedFcn,@setColorGroups);
UI.menu.display.colorgroups.option(UI.settings.colorByChannels).Checked = 'on';

UI.menu.display.colormap = uimenu(UI.menu.display.topMenu,menuLabel,'Color maps');
UI.menu.display.colorByChannels = uimenu(UI.menu.display.colormap,menuLabel,'Color ephys traces by channel order',menuSelectedFcn,@colorByChannels);
UI.menu.display.colorByChannels2 = uimenu(UI.menu.display.colormap,menuLabel,'Color ephys traces in channel groups',menuSelectedFcn,@colorByChannels2);
UI.menu.display.changeColormap = uimenu(UI.menu.display.colormap,menuLabel,'Change colormap of ephys traces',menuSelectedFcn,@changeColormap);
UI.menu.display.changeSpikesColormap = uimenu(UI.menu.display.colormap,menuLabel,'Change colormap of spikes',menuSelectedFcn,@changeSpikesColormap);
UI.menu.display.changeBackgroundColor = uimenu(UI.menu.display.colormap,menuLabel,'Change background color & primary color',menuSelectedFcn,@changeBackgroundColor);
Expand All @@ -368,7 +376,9 @@ function NeuroScope2(varargin)

% Analysis
UI.menu.analysis.topMenu = uimenu(UI.fig,menuLabel,'Analysis');
initAnalysisToolsMenu
try
initAnalysisToolsMenu
end
UI.menu.analysis.summaryFigure = uimenu(UI.menu.analysis.topMenu,menuLabel,'Summary figure',menuSelectedFcn,@summaryFigure,'Separator','on');

% BuzLabDB
Expand Down Expand Up @@ -846,7 +856,7 @@ function NeuroScope2(varargin)
% Showing detected spikes in a spike-waveform-PCA plot inset
if UI.settings.detectSpikes && ~isempty(UI.channelOrder) && UI.settings.showDetectedSpikesPCAspace
plotSpikesPCAspace(raster,UI.settings.primaryColor,true)
end
end

if ~isempty(UI.legend)
text(1/400,0.005,UI.legend,'FontWeight', 'Bold','BackgroundColor',UI.settings.textBackground,'VerticalAlignment', 'bottom','Units','normalized','HorizontalAlignment','left','HitTest','off','Interpreter','tex')
Expand Down Expand Up @@ -1035,7 +1045,12 @@ function addLegend(text_string,clr)
plotCSD
end

if UI.settings.colorByChannels
if UI.settings.colorByChannels == 1
electrodeGroupsToPlot = UI.settings.electrodeGroupsToPlot;
channelsList = UI.channels;
colorsList = colors;

elseif UI.settings.colorByChannels == 2
channelsList2 = UI.channelOrder;
channelsList = {};
temp = rem(0:numel(channelsList2)-1,UI.settings.nColorGroups)+1;
Expand All @@ -1052,7 +1067,7 @@ function addLegend(text_string,clr)
colors(1:2:end,:) = colors(1:2:end,:)-0.08*(9-UI.settings.greyScaleTraces);
end
colorsList = colors;
elseif UI.settings.colorByChannels2
elseif UI.settings.colorByChannels == 3
channelsList2 = UI.channelOrder;
channelsList = {};
nElectrodes = ceil(numel(channelsList2)/UI.settings.nColorGroups);
Expand All @@ -1069,10 +1084,6 @@ function addLegend(text_string,clr)
colors(1:2:end,:) = colors(1:2:end,:)-0.08*(9-UI.settings.greyScaleTraces);
end
colorsList = colors;
else
electrodeGroupsToPlot = UI.settings.electrodeGroupsToPlot;
channelsList = UI.channels;
colorsList = colors;
end

if UI.settings.plotStyle == 1
Expand Down Expand Up @@ -3008,29 +3019,37 @@ function HelpDialog(~,~)
else
UI.settings.playAudioFirst = false;
end
streamToc = 0;
streamToc_extra = 0;

while UI.settings.stream
streamTic = tic;
UI.t0 = UI.t0+UI.settings.replayRefreshInterval*UI.settings.windowDuration;
if streamToc > UI.settings.windowDuration*UI.settings.replayRefreshInterval
replayRefreshInterval = 1;
else
replayRefreshInterval = UI.settings.replayRefreshInterval;
end

UI.t0 = UI.t0+replayRefreshInterval*UI.settings.windowDuration;
UI.t0 = max([0,min([UI.t0,UI.t_total-UI.settings.windowDuration])]);
if ~ishandle(UI.fig) || (UI.fid.ephys == -1 && UI.settings.plotStyle ~= 4)
return
end

% playAudioWithTrace
if UI.settings.audioPlay && n_streaming == 0
samples = 1:round(replayRefreshInterval*ephys.nSamples);
deviceWriter(UI.settings.audioGain*ephys.traces(samples,UI.settings.audioChannels));
end

if UI.settings.playAudioFirst
load_ephys_data
end

% playAudioWithTrace
if UI.settings.audioPlay
streamTicAudio = tic;

if n_streaming == 0
streamTicAudio_t0 = tic;
samples = 1:round(UI.settings.replayRefreshInterval*ephys.nSamples);
deviceWriter(UI.settings.audioGain*ephys.traces(samples,107));
end
samples = round(UI.settings.replayRefreshInterval*ephys.nSamples)+1:ephys.nSamples;
deviceWriter(UI.settings.audioGain*ephys.traces(samples,107));
samples = 1:round(replayRefreshInterval*ephys.nSamples);
deviceWriter(UI.settings.audioGain*ephys.traces(samples,UI.settings.audioChannels));
UI.settings.deviceWriterActive = true;
n_streaming = n_streaming+1;
end
Expand All @@ -3044,37 +3063,43 @@ function HelpDialog(~,~)
% Updating UI text and slider
UI.elements.lower.time.String = num2str(UI.t0);
setTimeText(UI.t0)
UI.streamingText = text(UI.plot_axis1,UI.settings.windowDuration/2,1,'Streaming','FontWeight', 'Bold','VerticalAlignment', 'top','HorizontalAlignment','center','color',UI.settings.primaryColor,'HitTest','off');
UI.streamingText = text(UI.plot_axis1,UI.settings.windowDuration/2,1,['Streaming: ', num2str(UI.settings.windowDuration*replayRefreshInterval),' sec intervals'],'FontWeight', 'Bold','VerticalAlignment', 'top','HorizontalAlignment','center','color',UI.settings.primaryColor,'HitTest','off');

if UI.settings.audioPlay
streamToc = toc(streamTicAudio_t0);
streamToc2 = UI.settings.replayRefreshInterval*UI.settings.windowDuration-toc(streamTicAudio);
streaming_delay = UI.settings.windowDuration*UI.settings.replayRefreshInterval*n_streaming-streamToc;
% disp(['streamToc=',num2str(streamToc),' streamToc2=',num2str(streamToc2),' streaming_delay=',num2str(streaming_delay)]);
streaming_delay = min(max(streaming_delay,streamToc2),UI.settings.windowDuration);

pauseBins = ones(1,10) * streaming_delay*0.1;

drawnow
streamToc = toc(streamTic)-min([0,streamToc_extra]);

if UI.settings.windowDuration*replayRefreshInterval-streamToc > 0
pauseBins = ones(1,10) * 0.1 * (UI.settings.windowDuration*replayRefreshInterval-streamToc);
else
streamToc = toc(streamTic);
pauseBins = ones(1,10) * (UI.settings.replayRefreshInterval*0.1*(UI.settings.windowDuration-streamToc));
pauseBins(cumsum(pauseBins)-streamToc<0) = [];
end
pauseBins = [];
end

if ~isempty(pauseBins)
pauseBins(end) = pauseBins(1)-pauseBins(end);
for i = 1:numel(pauseBins)
if UI.settings.stream
pause(pauseBins(i))
end
end
end

if UI.t0 == UI.t_total-UI.settings.windowDuration
UI.settings.stream = false;
end

streamToc_extra = UI.settings.windowDuration*replayRefreshInterval-toc(streamTic);
end
UI.elements.lower.performance.String = '';
end
UI.settings.fileRead = 'bof';
if ishandle(UI.streamingText)
delete(UI.streamingText)
end

if UI.t0 == UI.t_total-UI.settings.windowDuration
UI.streamingText = text(UI.plot_axis1,UI.settings.windowDuration/2,1,'Streaming stopped: End of file','FontWeight', 'Bold','VerticalAlignment', 'top','HorizontalAlignment','center','color',UI.settings.primaryColor,'HitTest','off');
end

UI.buttons.play1.String = char(9654);
UI.buttons.play2.String = [char(9655) char(9654)];
if UI.settings.audioPlay
Expand Down Expand Up @@ -3126,7 +3151,7 @@ function initAudioDeviceWriter(~,~)
else
sr = data.session.extracellular.sr;
end
deviceWriter = audioDeviceWriter('SampleRate',sr);
deviceWriter = audioDeviceWriter('SampleRate',sr,'SupportVariableSizeInput',true);
SamplesPerFrame = round(UI.settings.replayRefreshInterval*sr);
NumChannels = numel(UI.settings.audioChannels);
setup(deviceWriter,zeros(SamplesPerFrame,NumChannels))
Expand Down Expand Up @@ -7017,9 +7042,16 @@ function changeSpikesColormap(~,~)
end
end

function colorByChannels(~,~)
UI.settings.colorByChannels = ~UI.settings.colorByChannels;
if UI.settings.colorByChannels
function setColorGroups(src,~)
UI.menu.display.colorgroups.option(1).Checked = 'off';
UI.menu.display.colorgroups.option(2).Checked = 'off';
UI.menu.display.colorgroups.option(3).Checked = 'off';

if src.Position == 1
UI.menu.display.colorgroups.option(1).Checked = 'on';
UI.settings.colorByChannels = 1;

elseif src.Position == 2
prompt = {'Number of color groups (1-50)'};
dlgtitle = 'Color groups';
definput = {num2str(UI.settings.nColorGroups)};
Expand All @@ -7031,22 +7063,11 @@ function colorByChannels(~,~)
if ~isempty(answer{1}) && rem(numeric_answer,1)==0 && numeric_answer > 0 && numeric_answer <= 50
UI.settings.nColorGroups = numeric_answer;
end
UI.menu.display.colorByChannels.Checked = 'on';
UI.menu.display.colorByChannels2.Checked = 'off';
UI.settings.colorByChannels2 = false;
else
UI.settings.colorByChannels = false;
UI.menu.display.colorByChannels.Checked = 'off';
UI.menu.display.colorgroups.option(src.Position).Checked = 'on';
UI.settings.colorByChannels = 2;
end
else
UI.menu.display.colorByChannels.Checked = 'off';
end
uiresume(UI.fig);
end

function colorByChannels2(~,~)
UI.settings.colorByChannels2 = ~UI.settings.colorByChannels2;
if UI.settings.colorByChannels2

elseif src.Position == 3
prompt = {'Number of channels per group (1-50)'};
dlgtitle = 'Color groups';
definput = {num2str(UI.settings.nColorGroups)};
Expand All @@ -7058,16 +7079,11 @@ function colorByChannels2(~,~)
if ~isempty(answer{1}) && rem(numeric_answer,1)==0 && numeric_answer > 0 && numeric_answer <= 50
UI.settings.nColorGroups = numeric_answer;
end
UI.menu.display.colorByChannels2.Checked = 'on';
UI.settings.colorByChannels = false;
UI.menu.display.colorByChannels.Checked = 'off';
else
UI.settings.colorByChannels2 = false;
UI.menu.display.colorByChannels2.Checked = 'off';
UI.menu.display.colorgroups.option(src.Position).Checked = 'on';
UI.settings.colorByChannels = 3;
end
else
UI.menu.display.colorByChannels2.Checked = 'off';
end
UI.menu.display.colorgroups.option(UI.settings.colorByChannels).Checked = 'on';
uiresume(UI.fig);
end

Expand Down Expand Up @@ -7207,31 +7223,33 @@ function MsgLog(message,priority)
% UI.popupmenu.log.String = [UI.popupmenu.log.String;message2];
% UI.popupmenu.log.Value = length(UI.popupmenu.log.String);
% end
if exist('priority','var')
dialog1.Interpreter = 'none';
dialog1.WindowStyle = 'modal';
if any(priority < 0)
disp(message2)
end
if any(priority == 1)
disp(message)
end
if any(priority == 2)
if UI.settings.allow_dialogs
msgbox(message,'NeuroScope2',dialog1);
else
try
if exist('priority','var')
dialog1.Interpreter = 'none';
dialog1.WindowStyle = 'modal';
if any(priority < 0)
disp(message2)
end
if any(priority == 1)
disp(message)
end
end
if any(priority == 3)
warning(message)
end
if any(priority == 4)
if UI.settings.allow_dialogs
warndlg(message,'NeuroScope2')
else
if any(priority == 2)
if UI.settings.allow_dialogs
msgbox(message,'NeuroScope2',dialog1);
else
disp(message)
end
end
if any(priority == 3)
warning(message)
end
if any(priority == 4)
if UI.settings.allow_dialogs
warndlg(message,'NeuroScope2')
else
warning(message)
end
end
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions ProcessCellMetrics.m
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,11 @@
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

customCalculationsOptions = what('customCalculations');
if size(customCalculationsOptions,1)>1
customCalculationsOptions = customCalculationsOptions(1);
end
customCalculationsOptions = cellfun(@(X) X(1:end-2),customCalculationsOptions.m,'UniformOutput', false);

customCalculationsOptions(strcmpi(customCalculationsOptions,'template')) = [];
for i = 1:length(customCalculationsOptions)
if any(contains(parameters.metrics,{customCalculationsOptions{i},'all'})) && ~any(contains(parameters.excludeMetrics,{customCalculationsOptions{i}}))
Expand Down
3 changes: 3 additions & 0 deletions calc_CellMetrics/gui_session.m
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@
classification_schema_value = 1;
else
classification_schema_list = what('celltype_classification');
if length(classification_schema_list)>1
classification_schema_list = classification_schema_list(1);
end
classification_schema_list = cellfun(@(X) X(1:end-2),classification_schema_list.m,'UniformOutput', false);

classification_schema_value = find(strcmp(parameters.preferences.putativeCellType.classification_schema,classification_schema_list));
Expand Down
Loading

0 comments on commit 30b721e

Please sign in to comment.