From db58baff5a8fc5bda546a7687f0dcfcb73c7f6cd Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Mon, 24 Nov 2025 16:10:03 +0000
Subject: [PATCH 1/4] Fix time calculation in axon_abf reader to handle gaps
Updated `ndr.reader.axon_abf.readchannels_epochsamples` to use `samples2times` for converting sample indices to time, ensuring correct handling of recordings with gaps (e.g., sweeps). Added special handling for the 'time' channel to avoid infinite recursion.
---
+ndr/+reader/axon_abf.m | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/+ndr/+reader/axon_abf.m b/+ndr/+reader/axon_abf.m
index 46de852..cc884a6 100755
--- a/+ndr/+reader/axon_abf.m
+++ b/+ndr/+reader/axon_abf.m
@@ -161,18 +161,21 @@
s1_ = 1;
end;
- sr = axon_abf_obj.get_samplerate_from_header(header, channel);
- sr_unique = unique(sr); % get all sample rates
- if numel(sr_unique)~=1,
- error(['Do not know how to handle different sampling rates across channels.']);
+ if strcmpi(channeltype{1},'time'),
+ % we want to avoid infinite recursion
+ t0t1 = axon_abf_obj.get_t0_t1_from_header(header);
+ T = t0t1{1};
+ else,
+ T = axon_abf_obj.samples2times(channeltype{1}, channel, epochstreams, epoch_select, [s0_ s1_]);
end;
- t0t1 = axon_abf_obj.get_t0_t1_from_header(header);
- T = ndr.time.fun.samples2times([s0_ s1_], t0t1{1}, sr_unique);
-
% in abfread, the reader reads up to s1 -1 instead of s1
data = ndr.format.axon.read_abf(filename,header,channeltype{1},channel,T(1),T(2));
+ if strcmpi(channeltype{1},'time'),
+ data = data(s0_:s1_);
+ end;
+
if numel(channel) == 1
data = data(:);
end
From a9c29b96d38130d47e67c0b1331d9c09399c9bb6 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 24 Nov 2025 16:12:24 +0000
Subject: [PATCH 2/4] Update GitHub badges
---
.github/badges/code_issues.svg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/badges/code_issues.svg b/.github/badges/code_issues.svg
index 40a2245..1bd6d59 100644
--- a/.github/badges/code_issues.svg
+++ b/.github/badges/code_issues.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From d199ac127ae2106d1b149a40e0fe4bfcd4701205 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Mon, 24 Nov 2025 16:24:54 +0000
Subject: [PATCH 3/4] Fix time calculation in axon_abf reader to handle gaps
and clean up syntax
Updated `ndr.reader.axon_abf.readchannels_epochsamples` to use `samples2times` for converting sample indices to time, ensuring correct handling of recordings with gaps (e.g., sweeps). Added special handling for the 'time' channel to avoid infinite recursion.
Additionally, removed unnecessary commas and semicolons throughout `ndr/reader/axon_abf.m` to reduce code warnings and improve readability.
---
+ndr/+reader/axon_abf.m | 58 +++++++++++++++++-----------------
.github/badges/code_issues.svg | 2 +-
2 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/+ndr/+reader/axon_abf.m b/+ndr/+reader/axon_abf.m
index cc884a6..b0433f0 100755
--- a/+ndr/+reader/axon_abf.m
+++ b/+ndr/+reader/axon_abf.m
@@ -79,10 +79,10 @@
channels(1) = struct('name','t1','type','time','time_channel',1);
- for i=1:numel(header.recChNames),
+ for i=1:numel(header.recChNames)
channels(end+1) = struct('name',['ai' int2str(i)],...
'type','analog_in', 'time_channel', 1);
- end;
+ end
end % ndr.reader.axon_abf.getchannelsepoch
function [datatype,p,datasize] = underlying_datatype(axon_abf_obj, epochstreams, epoch_select, channeltype, channel)
@@ -107,25 +107,25 @@
header = ndr.format.axon.read_abf_header(filename);
switch(channeltype)
- case {'analog_in','analog_out','auxiliary_in'},
+ case {'analog_in','analog_out','auxiliary_in'}
% For the abstract class, keep the data in doubles. This will always work but may not
% allow for optimal compression if not overridden
datasize = ndr.fun.bitDepth(header.lADCResolution);
datatype = ndr.fun.getDataTypeString(true,true,datasize);
p = [0 header.fADCRange/header.lADCResolution];
- case {'time'},
+ case {'time'}
datatype = 'float64';
datasize = 64;
p = [0 1];
- case {'digital_in','digital_out'},
+ case {'digital_in','digital_out'}
datatype = 'char';
datasize = 8;
p = [0 1];
- case {'eventmarktext','event','marker','text'},
+ case {'eventmarktext','event','marker','text'}
datatype = 'float64';
datasize = 64;
p = [0 1];
- otherwise,
+ otherwise
error(['Unknown channel type ' channeltype '.']);
end
end
@@ -148,33 +148,33 @@
[filename] = axon_abf_obj.filenamefromepochfiles(epochstreams);
header = ndr.format.axon.read_abf_header(filename);
- if ~iscell(channeltype),
+ if ~iscell(channeltype)
channeltype = repmat({channeltype},numel(channel),1);
- end;
+ end
maxSamples = header.lActualAcqLength / header.nADCNumChannels;
s0_ = max(1, s0);
- if isinf(s0_), % could be positive inf
+ if isinf(s0_) % could be positive inf
s0_ = maxSamples;
- end;
+ end
s1_ = min(maxSamples, s1);
- if isinf(s1_), % could be negative infinity
+ if isinf(s1_) % could be negative infinity
s1_ = 1;
- end;
+ end
- if strcmpi(channeltype{1},'time'),
+ if strcmpi(channeltype{1},'time')
% we want to avoid infinite recursion
t0t1 = axon_abf_obj.get_t0_t1_from_header(header);
T = t0t1{1};
- else,
+ else
T = axon_abf_obj.samples2times(channeltype{1}, channel, epochstreams, epoch_select, [s0_ s1_]);
- end;
+ end
% in abfread, the reader reads up to s1 -1 instead of s1
data = ndr.format.axon.read_abf(filename,header,channeltype{1},channel,T(1),T(2));
- if strcmpi(channeltype{1},'time'),
+ if strcmpi(channeltype{1},'time')
data = data(s0_:s1_);
- end;
+ end
if numel(channel) == 1
data = data(:);
@@ -194,9 +194,9 @@
% If CHANNELTYPE is a single string, then it is assumed that that
% CHANNELTYPE applies to every entry of CHANNEL.
%
- if epoch_select~=1,
+ if epoch_select~=1
error(['ABF files have 1 epoch per file.']);
- end;
+ end
filename = axon_abf_obj.filenamefromepochfiles(epochstreams);
@@ -216,12 +216,12 @@
[tf, matchstring, substring] = vlt.string.strcmp_substitution(s1,filename_array,'UseSubstituteString',0);
index = find(tf);
- if numel(index)==0,
+ if numel(index)==0
error(['Need at least 1 .abf file per epoch.']);
- else,
+ else
filename = filename_array{index(1)};
end
- end; % ndr.reader.axon_abf.filenamefromepochfiles
+ end % ndr.reader.axon_abf.filenamefromepochfiles
function channelstruct = daqchannels2internalchannels(ndr_reader_axon_abf_obj, channelprefix, channelnumber, epochstreams, epoch_select)
% DAQCHANNELS2INTERNALCHANNELS - convert a set of DAQ channel prefixes and channel numbers to an internal structure to pass to internal reading functions
@@ -262,7 +262,7 @@
channelstruct = vlt.data.emptystruct('internal_type','internal_number',...
'internal_channelname','ndr_type','samplerate');
- for i=1:numel(channels),
+ for i=1:numel(channels)
newentry.internal_type = channels(i).type;
[CHANNELNAMEPREFIX, numericchannel] = ndr.string.channelstring2channels(channels(i).name);
newentry.internal_number = numericchannel;
@@ -270,11 +270,11 @@
newentry.ndr_type = ndr.reader.base.mfdaq_type(newentry.internal_type);
newentry.samplerate = ndr_reader_axon_abf_obj.samplerate(epochstreams,epoch_select,...
CHANNELNAMEPREFIX, numericchannel);
- if any( (newentry.internal_number(:) == channelnumber) & strcmp(channelprefix,CHANNELNAMEPREFIX) ),
+ if any( (newentry.internal_number(:) == channelnumber) & strcmp(channelprefix,CHANNELNAMEPREFIX) )
channelstruct(end+1) = newentry;
- end;
- end;
- end; % daqchannels2internalchannels
+ end
+ end
+ end % daqchannels2internalchannels
function t = samples2times(axon_abf_obj, channeltype, channel, epochstreams, epoch_select, s)
% SAMPLES2TIMES - convert sample numbers to time
@@ -319,7 +319,7 @@
if isfield(header,'uFileStartDate')
dt = ndr.format.axon.abfTimeToDatetime(header.uFileStartDate,header.uFileStartTimeMS);
t0t1{2} = [datenum(dt) datenum(dt+seconds(t1))];
- end;
+ end
end
function sr = get_samplerate_from_header(header, channel)
diff --git a/.github/badges/code_issues.svg b/.github/badges/code_issues.svg
index 1bd6d59..40a2245 100644
--- a/.github/badges/code_issues.svg
+++ b/.github/badges/code_issues.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From dacd269d8555171aeb6953239b2bb9d8d0bb5465 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 24 Nov 2025 16:27:10 +0000
Subject: [PATCH 4/4] Update GitHub badges
---
.github/badges/code_issues.svg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/badges/code_issues.svg b/.github/badges/code_issues.svg
index 40a2245..3e3bca8 100644
--- a/.github/badges/code_issues.svg
+++ b/.github/badges/code_issues.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file