Skip to content

Drop down stores and apply to all channels #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified neural_data_processing/SimpleSpikeDataProcessor.fig
Binary file not shown.
232 changes: 178 additions & 54 deletions neural_data_processing/SimpleSpikeDataProcessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

% Edit the above text to modify the response to help SimpleSpikeDataProcessor

% Last Modified by GUIDE v2.5 27-May-2019 17:41:12
% Last Modified by GUIDE v2.5 12-Aug-2019 11:16:45

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
Expand Down Expand Up @@ -74,7 +74,10 @@ function SimpleSpikeDataProcessor_OpeningFcn(hObject, eventdata, handles, vararg
handles.numsnips = 1000; % plot 1000 snips max

handles.data = [];
handles.store = 'spik';

handles.store = {'-- Select storage --'};

handles.all_channels_checkbox_value = get(handles.all_channels_checkbox,'Value');

% Update handles structure
guidata(hObject, handles);
Expand Down Expand Up @@ -111,20 +114,14 @@ function loadTDT_button_Callback(hObject, eventdata, handles)
% get block info
heads = TDTbin2mat(BLOCKPATH, 'HEADERS', 1);

% Find spikes store -- always 'spik'? make user specify that? use 'type' from TDTbin2mat to extract 'snips' only?
if ~isfield(heads.stores, handles.store)
warning('no ''spik'' store in specified file, sadly this is hardcoded in this function for now... sorry!');
return;
end

handles.chanlist = sort(unique(heads.stores.spik.chan));
handles.numchan = length(handles.chanlist);
handles.chan = handles.chanlist(1);
handles.stream_t0 = 0; % start at beginning of data (first 60 sec);

% read data from first channel
handles = read_chan(handles);
heads_fieldnames = fieldnames(heads.stores);

for i = 1:length(fieldnames(heads.stores))
handles.store{i+1,1} = heads_fieldnames{i,1};
end
% stream_snip = heads.stores
% handles.store = stream_snip(handles.store);
set(handles.list_popup,'String',string(handles.store));
end
end

Expand All @@ -136,7 +133,7 @@ function thresh_button_Callback(hObject, eventdata, handles)
update_snips(handles);

num_snips = size(handles.data.snips.Snip.data,1);
fprintf('Extracted %d snips\n',num_snips);
fprintf('Extracted %d snips from ch %d\n',num_snips,handles.chan);

% Update handles structure
guidata(hObject, handles);
Expand Down Expand Up @@ -222,32 +219,70 @@ function post_snip_wind_button_Callback(hObject, eventdata, handles)
guidata(hObject, handles);

function apply_all_button_Callback(hObject, eventdata, handles)
% thresholding
handles = extract_snips(handles);
num_snips = size(handles.data.snips.Snip.data,1);
fprintf('Extracted %d snips\n',num_snips);

% remove snips above reject line
rem_idx = find(any(abs(handles.data.snips.Snip.data') > handles.reject));

% remove snips when outside presnip window
rem_idx = [rem_idx find(any(abs(handles.data.snips.Snip.data(:,handles.presnipT(1):handles.presnipT(2)))' > handles.presnip))];

% remove snips when below postsnip threshold
rem_idx = [rem_idx find(any(handles.data.snips.Snip.data(:,handles.postsnipT(1):handles.postsnipT(2))' < handles.postsnip))];

% remove snips when outside postsnip window
rem_idx = [rem_idx find(any(abs(handles.data.snips.Snip.data(:,handles.postwindT(1):handles.postwindT(2)))' > handles.postwind))];

rem_idx = unique(rem_idx);

% actually remove all relevant snips
handles.data.snips.Snip.data(rem_idx,:) = [];
handles.data.snips.Snip.sortcode(rem_idx,:) = [];
handles.data.snips.Snip.ts(rem_idx,:) = [];

fprintf('Removed %d of %d snips\n',length(rem_idx),num_snips);
update_snips(handles);
if handles.all_channels_checkbox_value == 1
for i = 1:length(handles.chanlist)
handles.chan = handles.chanlist(i);
handles.stream_t0 = 0;
handles = read_chan(handles);

% thresholding
handles = extract_snips(handles);
num_snips = size(handles.data.snips.Snip.data,1);
fprintf('Extracted %d snips from ch %d\n',num_snips,handles.chan);

% remove snips above reject line
rem_idx = find(any(abs(handles.data.snips.Snip.data') > handles.reject));

% remove snips when outside presnip window
rem_idx = [rem_idx find(any(abs(handles.data.snips.Snip.data(:,handles.presnipT(1):handles.presnipT(2)))' > handles.presnip))];

% remove snips when below postsnip threshold
rem_idx = [rem_idx find(any(handles.data.snips.Snip.data(:,handles.postsnipT(1):handles.postsnipT(2))' < handles.postsnip))];

% remove snips when outside postsnip window
rem_idx = [rem_idx find(any(abs(handles.data.snips.Snip.data(:,handles.postwindT(1):handles.postwindT(2)))' > handles.postwind))];

rem_idx = unique(rem_idx);

% actually remove all relevant snips
handles.data.snips.Snip.data(rem_idx,:) = [];
handles.data.snips.Snip.sortcode(rem_idx,:) = [];
handles.data.snips.Snip.ts(rem_idx,:) = [];

fprintf('Removed %d of %d snips from ch %d\n',length(rem_idx),num_snips,handles.chan);
update_snips(handles);
save_chan(handles);
set(handles.all_channels_checkbox,'Value',0);
end
else
% thresholding
handles = extract_snips(handles);
num_snips = size(handles.data.snips.Snip.data,1);
fprintf('Extracted %d snips from ch %d\n',num_snips,handles.chan);

% remove snips above reject line
rem_idx = find(any(abs(handles.data.snips.Snip.data') > handles.reject));

% remove snips when outside presnip window
rem_idx = [rem_idx find(any(abs(handles.data.snips.Snip.data(:,handles.presnipT(1):handles.presnipT(2)))' > handles.presnip))];

% remove snips when below postsnip threshold
rem_idx = [rem_idx find(any(handles.data.snips.Snip.data(:,handles.postsnipT(1):handles.postsnipT(2))' < handles.postsnip))];

% remove snips when outside postsnip window
rem_idx = [rem_idx find(any(abs(handles.data.snips.Snip.data(:,handles.postwindT(1):handles.postwindT(2)))' > handles.postwind))];

rem_idx = unique(rem_idx);

% actually remove all relevant snips
handles.data.snips.Snip.data(rem_idx,:) = [];
handles.data.snips.Snip.sortcode(rem_idx,:) = [];
handles.data.snips.Snip.ts(rem_idx,:) = [];

fprintf('Removed %d of %d snips from ch %d\n',length(rem_idx),num_snips,handles.chan);
update_snips(handles);
end

% Update handles structure
guidata(hObject, handles);
Expand Down Expand Up @@ -293,8 +328,6 @@ function save_button_Callback(hObject, eventdata, handles)

end

function done_button_Callback(hObject, eventdata, handles)

function prev_chan_button_Callback(hObject, eventdata, handles)

% save snips from current channel
Expand Down Expand Up @@ -334,7 +367,7 @@ function update_stream(handles)
set(handles.figure1,'CurrentAxes',handles.stream_axes);

% select and plot relevant data and timeframe
yvals = handles.data.streams.(handles.store).data( handles.stream_timeframe >= handles.stream_t0 & handles.stream_timeframe < handles.stream_t0 + handles.stream_width);
yvals = handles.data.streams.(handles.list_choice).data( handles.stream_timeframe >= handles.stream_t0 & handles.stream_timeframe < handles.stream_t0 + handles.stream_width);
xvals = handles.stream_timeframe( handles.stream_timeframe >= handles.stream_t0 & handles.stream_timeframe < handles.stream_t0 + handles.stream_width);

cla(handles.stream_axes);
Expand Down Expand Up @@ -371,7 +404,7 @@ function update_snips(handles)
end
hold on; axis manual
xlim([handles.snips_timeframe(1) handles.snips_timeframe(end)]);
ylabel('uV'); xlabel('ms'); title(sprintf('first %d snips',numsnips));
ylabel('uV'); xlabel('ms'); title(sprintf('First %d snips',numsnips));

% if big artifacts, auto scale zooms out too much to see real data. Set a max yrange of +- 500 uV
yy = ylim; ylim([max(-500,yy(1)) min(500,yy(2))]);
Expand All @@ -397,22 +430,22 @@ function update_snips(handles)
function handles = read_chan(handles)

% read the specified data from our block into a Matlab structure
handles.data = TDTbin2mat(handles.blockpath_edit.String, 'STORE', handles.store, 'CHANNEL', handles.chan);
handles.data = TDTbin2mat(handles.blockpath_edit.String, 'STORE', handles.list_choice, 'CHANNEL', handles.chan);

% filter data 300-5000 Hz
handles.data = TDTdigitalfilter(handles.data, handles.store, [300 5000]);
handles.data = TDTdigitalfilter(handles.data, handles.list_choice, [300 5000]);

% convert to uV
handles.data.streams.(handles.store).data = handles.data.streams.(handles.store).data *1e6;
handles.data.streams.(handles.list_choice).data = handles.data.streams.(handles.list_choice).data *1e6;

handles.stream_timeframe = ((1:length(handles.data.streams.(handles.store).data))-1)/handles.data.streams.(handles.store).fs;
handles.stream_timeframe = ((1:length(handles.data.streams.(handles.list_choice).data))-1)/handles.data.streams.(handles.list_choice).fs;

% per TDTthresh:
%pre_wave = floor(NPTS/4)-1;
%post_wave = NPTS - pre_wave-1;
pre_wave = floor(handles.snip_width/4);
post_wave = handles.snip_width-pre_wave-1;
handles.snips_timeframe = (-pre_wave:post_wave)/handles.data.streams.(handles.store).fs*1e3; % in ms
handles.snips_timeframe = (-pre_wave:post_wave)/handles.data.streams.(handles.list_choice).fs*1e3; % in ms

% enable/disable buttons
if handles.chan == handles.chanlist(1)
Expand All @@ -426,15 +459,15 @@ function update_snips(handles)
handles.next_chan_button.Enable = 'on';
end

saved_snips = ~isempty(dir([handles.blockpath_edit.String filesep 'chandata' filesep 'ch' num2str(handles.chan) '_snips.mat']));
saved_snips = ~isempty(dir([handles.blockpath_edit.String filesep 'chandata' filesep 'ch' num2str(handles.chan) '_snips.mat']));

% load saved snips if already processed
if saved_snips
handles.data.snips.Snip = load([handles.blockpath_edit.String filesep 'chandata' filesep 'ch' num2str(handles.chan) '_snips.mat']);
else
handles = extract_snips(handles);
num_snips = size(handles.data.snips.Snip.data,1);
fprintf('Extracted %d snips\n',num_snips);
fprintf('Extracted %d snips from ch %d\n',num_snips,handles.chan);
end

snips_compat = length(handles.snips_timeframe) == size(handles.data.snips.Snip.data,2);
Expand All @@ -450,10 +483,10 @@ function update_snips(handles)
function handles = extract_snips(handles)

% extract snips using specified parameters
handles.data = TDTthresh(handles.data, handles.store, 'MODE', 'manual', 'THRESH', handles.thresh, 'NPTS', handles.snip_width, 'OVERLAP', 0,'VERBOSE',0);
handles.data = TDTthresh(handles.data, handles.list_choice, 'MODE', 'manual', 'THRESH', handles.thresh, 'NPTS', handles.snip_width, 'OVERLAP', 0,'VERBOSE',0);

%TDT thresh simply writes '1' in Snip.chan when only one channel at a time. We want that to reflect the real channel number
handles.data.snips.Snip.chan = handles.data.streams.(handles.store).channel;
handles.data.snips.Snip.chan = handles.data.streams.(handles.list_choice).channel;

function Snip = mergeSnips(s,Snip)
if isempty(Snip)
Expand Down Expand Up @@ -502,6 +535,7 @@ function thresh_edit_Callback(hObject, eventdata, handles)

% Update handles structure
guidata(hObject, handles);

function thresh_edit_CreateFcn(hObject, eventdata, handles)
% hObject handle to thresh_edit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
Expand All @@ -521,6 +555,7 @@ function reject_edit_Callback(hObject, eventdata, handles)

% Update handles structure
guidata(hObject, handles);

function reject_edit_CreateFcn(hObject, eventdata, handles)
% hObject handle to reject_edit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
Expand All @@ -540,6 +575,7 @@ function pre_snip_edit_Callback(hObject, eventdata, handles)

% Update handles structure
guidata(hObject, handles);

function pre_snip_edit_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
Expand Down Expand Up @@ -573,6 +609,7 @@ function post_snip_thresh_edit_Callback(hObject, eventdata, handles)

% Update handles structure
guidata(hObject, handles);

function post_snip_thresh_edit_CreateFcn(hObject, eventdata, handles)
% hObject handle to post_snip_thresh_edit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
Expand All @@ -595,3 +632,90 @@ function blockpath_edit_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in raw_data_radio.
function raw_data_radio_Callback(hObject, eventdata, handles)
% hObject handle to raw_data_radio (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of raw_data_radio


% --- Executes on button press in snips_only_radio.
function snips_only_radio_Callback(hObject, eventdata, handles)
% hObject handle to snips_only_radio (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of snips_only_radio


%% Added -VK 11/08/2019
% Adds popup menu with drop down list of available stores and load
% selected option

% --- Executes on selection change in list_popup.
function list_popup_Callback(hObject, eventdata, handles)
% hObject handle to list_popup (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns list_popup contents as cell array
% contents{get(hObject,'Value')} returns selected item from list_popup

list_contents = get(handles.list_popup,'String');
handles.list_choice = list_contents{get(handles.list_popup,'Value')};

heads = TDTbin2mat(handles.blockpath_edit.String, 'HEADERS', 1);

handles.chanlist = sort(unique(heads.stores.(handles.list_choice).chan));
handles.numchan = length(handles.chanlist);
handles.chan = handles.chanlist(1);
handles.stream_t0 = 0; % start at beginning of data (first 60 sec);

% read data from first channel
fprintf('Loading %s...\n', handles.list_choice)

try
handles = read_chan(handles);
catch
warning('Failed to load %s. Select a different storage.\n', handles.list_choice)
return
end

fprintf('%s loaded successfully.\n', handles.list_choice)

% Update handles structure
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function list_popup_CreateFcn(hObject, eventdata, handles)
% hObject handle to list_popup (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end

% Checkbox for applying settings to all channels
% --- Executes on button press in all_channels_checkbox.
function all_channels_checkbox_Callback(hObject, eventdata, handles)
% hObject handle to all_channels_checkbox (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of all_channels_checkbox

handles.all_channels_checkbox_value = get(handles.all_channels_checkbox,'Value');

% Update handles structure
guidata(hObject, handles);

%% End of code %%