Skip to content

Commit

Permalink
Bugfix: Reading CTF events from STIM channel (for coherence tutorial)
Browse files Browse the repository at this point in the history
  • Loading branch information
ftadel committed Jun 16, 2021
1 parent c562dd8 commit 9329fa0
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
2 changes: 1 addition & 1 deletion doc/license.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<body alink="#fff000" link="#fff000" vlink="#fff000">
<h4><span style="font-family: Arial Black; color: #ffffff;"><strong>THERE IS NO UNDO BUTTON - SET UP A BACKUP OF YOUR DATABASE</strong></span></h4>
<HR>
<!-- LICENCE_START -->Version: 3.210614 (14-Jun-2021)<br>
<!-- LICENCE_START -->Version: 3.210616 (16-Jun-2021)<br>
<span style="font-style: italic;">COPYRIGHT &copy; 2000-2020
USC &amp; McGill University.<br>
</span>
Expand Down
2 changes: 1 addition & 1 deletion doc/version.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
% Brainstorm
% v. 3.210614 (14-Jun-2021)
% v. 3.210616 (16-Jun-2021)
67 changes: 60 additions & 7 deletions toolbox/process/functions/process_evt_read.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2012-2020
% Authors: Francois Tadel, 2012-2021

eval(macro_method);
end
Expand Down Expand Up @@ -108,8 +108,25 @@
end

% ===== DETECTION =====
events = Compute(sFile, ChannelMat, StimChan, EventsTrackMode, isAcceptZero, MinDuration);

% CTF: Read separately upper and lower bytes
if ismember(sFile.format, {'CTF', 'CTF-CONTINUOUS'})
% Detect separately events on the upper and lower bytes of the STIM channel
eventsU = Compute(sFile, ChannelMat, [StimChan '__U'], EventsTrackMode, isAcceptZero, MinDuration);
eventsL = Compute(sFile, ChannelMat, [StimChan '__L'], EventsTrackMode, isAcceptZero, MinDuration);
% If there are events on both: add marker U/L
if ~isempty(eventsU) && ~isempty(eventsL)
for iEvt = 1:length(eventsU)
eventsU(iEvt).label = ['U', eventsU(iEvt).label];
end
for iEvt = 1:length(eventsL)
eventsL(iEvt).label = ['L', eventsL(iEvt).label];
end
end
events = [eventsL, eventsU];
else
events = Compute(sFile, ChannelMat, StimChan, EventsTrackMode, isAcceptZero, MinDuration);
end

% ===== SAVE RESULT =====
% Only save changes if something was change
if ~isempty(events)
Expand Down Expand Up @@ -192,7 +209,20 @@
return
end
end
end
end
% CTF: Select only upper or lower bytes
isCtfUp = 0;
isCtfLow = 0;
if ismember(sFile.format, {'CTF', 'CTF-CONTINUOUS'}) && (length(StimChan) > 3)
if strcmp(StimChan(end-2:end), '__U')
isCtfUp = 1;
StimChan = StimChan(1:end-3);
elseif strcmp(StimChan(end-2:end), '__L')
isCtfLow = 1;
StimChan = StimChan(1:end-3);
end
end
trigshift = fix(sFile.prop.sfreq * 9/1200);

% ===== ASK READ MODE =====
if strcmpi(EventsTrackMode, 'ask')
Expand Down Expand Up @@ -250,9 +280,32 @@
samplesBlock(2) = min(samplesBlock(2), samplesBounds(2));
% Read block of data
[tracks, times] = in_fread(sFile, ChannelMat, 1, samplesBlock, iChannels);
% Convert events values to uint16
tracks = reshape(double(typecast(int16(tracks(:)), 'uint16')), size(tracks));


% === BLOCK EDITED 16-JUN-2021 ===
% Round values
tracks = fix(tracks);
% CTF: Read separately Upper and Lower bytes
if ismember(sFile.format, {'CTF', 'CTF-CONTINUOUS'})
% Events are read as int32, while they are actually uint32: fix negative values
tracks(tracks<0) = tracks(tracks<0) + 2^32;
% Keep only upper or lower bytes
if isCtfUp
tracks = fix(tracks / 2^16);
elseif isCtfLow
tracks = double(bitand(uint32(tracks), 2^16-1));
end
% Determine the precise timing of the triggers (from FieldTrip's read_ctf_trigger)
upflank = [0 (diff(tracks)>0 & tracks(1:(end-1))==0)];
tracks = upflank(1:(end-trigshift)).*tracks((1+trigshift):end);
% Other formats
else
% Old code: Might be useless and/or detrimental to the reading of the events
% tracks = reshape(double(typecast(int16(tracks(:)), 'uint16')), size(tracks));
% Use the same fix as for CTF files
tracks(tracks<0) = tracks(tracks<0) + 2^32;
end
% =================================

% === ADD INITIAL STATE ===
% Add the initial status of the tracks
if isempty(trackPrev)
Expand Down

0 comments on commit 9329fa0

Please sign in to comment.