Skip to content
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

NDI-matlab functionality: reading from ndi.element.timeseries objects, writing ndi.neuron objects #157

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
8 changes: 4 additions & 4 deletions +jrclust/+detect/@DetectController/detectOneRecording.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
end

% load raw samples
iSamplesRaw = hRec.readRawROI(obj.hCfg.siteMap, 1+loadOffset:loadOffset+nSamples);
iSamplesRaw = hRec.readRawROI(obj.hCfg.siteMap, 1+loadOffset:loadOffset+nSamples,obj.hCfg);

% convert samples to int16
iSamplesRaw = samplesToInt16(iSamplesRaw, obj.hCfg);
Expand All @@ -52,7 +52,7 @@
if iLoad < nLoads && obj.hCfg.nSamplesPad > 0
leftBound = loadOffset + nSamples + 1;
rightBound = leftBound + obj.hCfg.nSamplesPad - 1;
samplesPost = hRec.readRawROI(obj.hCfg.siteMap, leftBound:rightBound);
samplesPost = hRec.readRawROI(obj.hCfg.siteMap, leftBound:rightBound,obj.hCfg);
samplesPost = samplesToInt16(samplesPost, obj.hCfg);
else
samplesPost = [];
Expand Down Expand Up @@ -135,7 +135,7 @@
% if in import mode, only process loads where there are imported spikes.
if isempty(impTimes) || any(inInterval)
% load raw samples
iSamplesRaw = hRec.readRawROI(obj.hCfg.siteMap, 1+loadOffset:loadOffset+nSamples);
iSamplesRaw = hRec.readRawROI(obj.hCfg.siteMap, 1+loadOffset:loadOffset+nSamples,obj.hCfg);

% convert samples to int16
iSamplesRaw = samplesToInt16(iSamplesRaw, obj.hCfg);
Expand All @@ -144,7 +144,7 @@
if iLoad < nLoads && obj.hCfg.nSamplesPad > 0
leftBound = loadOffset + nSamples + 1;
rightBound = leftBound + obj.hCfg.nSamplesPad - 1;
samplesPost = hRec.readRawROI(obj.hCfg.siteMap, leftBound:rightBound);
samplesPost = hRec.readRawROI(obj.hCfg.siteMap, leftBound:rightBound,obj.hCfg);
samplesPost = samplesToInt16(samplesPost, obj.hCfg);
else
samplesPost = [];
Expand Down
4 changes: 2 additions & 2 deletions +jrclust/+detect/@DetectController/findSecondaryPeaks.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function [spikeSites2, spikeSites3] = findSecondaryPeaks(obj, spikeWindows, spikeSites)
%FINDSECONDARYPEAKS Find secondary peaks
% spikeWindows: nSamples x nSites x nSpikes
evtNeighbors = 2:obj.hCfg.nSitesEvt; % sites within merge radius, excluding ref sites
evtNeighbors = 2:obj.hCfg.nSitesEvt; % sites within merge radius, excluding ref sites
siteNeighbors2 = obj.hCfg.siteNeighbors(evtNeighbors, spikeSites);

spikeWindows2 = spikeWindows(:, evtNeighbors, :);
Expand All @@ -22,4 +22,4 @@
else
spikeSites3 = [];
end
end
end
104 changes: 104 additions & 0 deletions +jrclust/+detect/ndiRecording.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
classdef ndiRecording < jrclust.interfaces.RawRecording
%NDIRECORDING Model of an element in NDI
%% NDI-SPECIFIC PROPERTIES

properties (GetAccess=public,SetAccess=private)
S; % ndi.session.dir that holds the experimental session data
E; % the ndi.element object that holds the data
epoch_id; % the epoch ids that are included
nsamples; % the number of samples per epoch
t0_t1; % start and end times, in local device time, of each epoch
end;

%% LIFECYCLE
methods
function obj = ndiRecording(epochname, hCfg)
%NDIRECORDING Construct an instance of this class
% set object data type
obj = [email protected](epochname, hCfg);
% file not found error is not an error for ndi
obj.errMsg = '';
obj.isError = 0;
obj.S = ndi.session.dir(hCfg.ndiPath);
E = getelements(obj.S,'element.name',hCfg.ndiElementName,'element.reference',hCfg.ndiElementReference);
if iscell(E) & numel(E)==1,
obj.E = E{1};
else,
obj.isError = 1;
obj.errMsg = 'No such element found.';
return;
end;

try
obj.hCfg = hCfg;
catch ME
obj.errMsg = ME.message;
obj.isError = 1;
return;
end

et = epochtable(obj.E);

[parentdir,epoch_id] = fileparts(epochname);
match = find(strcmp(epoch_id,{et.epoch_id}));
if isempty(match),
obj.isError = 1;
obj.errMsg = ['No such epoch ' epoch_id '.'];
return;
end;
obj.epoch_id = et(match).epoch_id;
% find clock that is dev local time
foundMatch = 0;
for i=1:numel(et(match).epoch_clock),
if strcmp(et(match).epoch_clock{i}.type,'dev_local_time'),
foundMatch = i;
break;
end;
end;
if foundMatch,
obj.t0_t1 = et(match).t0_t1{foundMatch};
else,
error(['No clock type ''dev_local_time''.']);
end;
obj.nsamples = 1+diff(times2samples(obj.E,epoch_id,obj.t0_t1));
obj.dshape = [hCfg.nChans, obj.nsamples];
end % ndiRecording()

function openRaw(obj)
%OPENRAW Open the raw recording file for reading - does nothing for ndiRecording
obj.rawIsOpen = 1;
end
function closeRaw(obj)
%CLOSERAW Close the raw recording file for reading - does nothing for ndiRecording
obj.rawIsOpen = 0;
end

function roi = readRawROI(obj, rows, cols,hCfg)
%READRAWROI Get a region of interest by rows/cols from the raw file
t0t1 = samples2times(obj.E, obj.epoch_id, cols([1 end]));
roi = hCfg.ndiScale*readtimeseries(obj.E, obj.epoch_id, t0t1(1), t0t1(2));
roi = roi'; % switch to column-based samples
roi = single(roi(rows,:)); % if only a subset requested, return only the subset
end % readRawROI()


end % methods

%% GETTERS/SETTERS
methods
function set.S(obj, val)
if ~isa(val,'ndi.session.dir'),
error(['S must be of type ndi.session.dir']);
end;
obj.S = val;
end
function set.E(obj,val)
if ~isa(val,'ndi.element') & ~isa(val,'ndi.time.timeseries'),
error(['E must be an ndi.element and an ndi.time.timeseries']);
end;
obj.E = val;
end;

end
end

4 changes: 2 additions & 2 deletions +jrclust/+detect/newRecording.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
switch hCfg.recordingFormat
case 'Intan'
hRec = jrclust.detect.IntanRecording(rawPath, hCfg);

case 'ndi',
hRec = jrclust.detect.ndiRecording(rawPath, hCfg);
otherwise % SpikeGLX .bin/.dat
hRec = jrclust.detect.Recording(rawPath, hCfg);

end
end

Loading