-
Notifications
You must be signed in to change notification settings - Fork 11
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
758 pspm_expand_epochs #786
Changes from 1 commit
aba66fe
0285c10
d4bd1ec
cd43295
a4b6010
3113615
50cced7
fd8dce6
59c2d8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
function [sts, ep_exp] = pspm_expand_epochs(epoches, expansion, options) | ||
|
||
% fn passt nicht zu missing epochs | ||
% [sts, channel_index] = pspm_expand_epochs( {data_fn, channel}, expansion , options) | ||
% [sts, output_file] = pspm_expand_epochs( missing_epochs_fn, expansion , options) | ||
% [sts, expanded_epochs] = pspm_expand_epochs( missing_epochs, expansion , options) % | ||
% options.mode = 'datafile' | ||
% 'missing_ep_file' | ||
% 'missing_ep' | ||
|
||
global settings | ||
if isempty(settings) | ||
pspm_init; | ||
end | ||
|
||
sts = -1; | ||
|
||
if nargin < 3 | ||
warning('ID:invalid_input', 'Not enough input arguments'); | ||
return; | ||
end | ||
|
||
switch options.mode | ||
% missing epochs | ||
case 'missing_ep' | ||
% Directly expand the given epochs | ||
[sts, ep_exp] = expand(epoches, expansion); | ||
return; | ||
|
||
% missing epoches file | ||
case 'missing_ep_file' | ||
% Load missing epochs from file | ||
data = load(epoches); % Load the file without specifying a variable | ||
dominikbach marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
% Assuming the file contains a variable called 'epochs', access it | ||
% Right name? | ||
if isfield(data, 'epochs') | ||
missing_epochs = data.epochs; | ||
else | ||
error('File does not contain variable ''epochs''.'); | ||
return; | ||
end | ||
|
||
if isempty(missing_epochs) | ||
error('Failed to load missing epochs from file.'); | ||
return; | ||
end | ||
|
||
% Expand the loaded epochs | ||
[sts, ep_exp] = expand(missing_epochs, expansion); | ||
if sts == -1 | ||
error('Failed to expand epochs.'); | ||
end | ||
|
||
% Save expanded missing epoch to a new file with 'e' prefix | ||
[pathstr, name, ext] = fileparts(epoches); | ||
output_file = fullfile(pathstr, ['e' name ext]); | ||
save(output_file, 'ep_exp'); % should i save it as epoch??? | ||
disp(['Expanded epochs saved to: ', output_file]); | ||
|
||
sts = 0; | ||
return; | ||
|
||
|
||
case 'datafile' % rename!! | ||
|
||
% Load channel data | ||
datafile = epoches{1}; | ||
channel = epoches{2}; | ||
[lsts, ~, data] = pspm_load_data(datafile, channel); | ||
if lsts == -1 | ||
error('Failed to load data from file.'); | ||
end | ||
|
||
channel_data = data{1}; | ||
sr = channel_data.header.sr; | ||
|
||
% Find NaN indices | ||
nan_indices = isnan(channel_data.data); | ||
|
||
% Convert NaN indices to epochs | ||
nan_epochs = pspm_logical2epochs(nan_indices, sr); | ||
|
||
% Expand the epochs | ||
[sts, ep_exp] = expand(nan_epochs, expansion); | ||
if sts == -1 | ||
error('Failed to expand epochs.'); | ||
end | ||
|
||
% Convert expanded epochs back to logical indices | ||
expanded_indices = pspm_epochs2logical(ep_exp, numel(channel_data.data), sr); | ||
|
||
% Set data to NaN at expanded indices | ||
channel_data.data(expanded_indices) = NaN; | ||
|
||
% Save the data back to the file | ||
[sts, out] = pspm_write_channel(datafile, {channel_data}, 'replace'); % add to options 'newfile'? | ||
varargout{2} = 23 % channel_data.data; | ||
return; | ||
|
||
|
||
otherwise | ||
error('Unknown mode in options.'); | ||
return; | ||
end | ||
|
||
end | ||
|
||
|
||
function [sts, ep_exp] = expand(ep, expansion) | ||
% Helper function to expand epochs by the specified pre and post times | ||
% and merge overlapping epochs. | ||
% Also ensures that no epoch starts before time 0. | ||
|
||
% Initialize status | ||
sts = -1; | ||
|
||
% Check if epochs matrix and expansion vector are valid | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is needed for all modes of the function, I would check it in the beginning of the main function, before anything is loaded from file (faster and easier to read). |
||
if isempty(ep) || numel(expansion) ~= 2 | ||
error('Invalid input to expand function.'); | ||
return; | ||
end | ||
|
||
% Expand epochs | ||
pre = expansion(1); | ||
post = expansion(2); | ||
expanded_epochs_temp = [ep(:,1) - pre, ep(:,2) + post]; | ||
|
||
% | ||
% Ensure that the start of any epoch is not negative | ||
4gwe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
expanded_epochs_temp(expanded_epochs_temp(:,1) < 0, 1) = 0; % or <1??? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably we should put this code into pspm_get_epochs (if the functionality does not exist there already), because it is needed in several functions. then just call [sts, epochs] = pspm_get_timing('epochs', epochs) |
||
|
||
% Merge overlapping epochs | ||
ep_exp = expanded_epochs_temp(1, :); % Start with the first epoch | ||
for i = 2:size(expanded_epochs_temp, 1) | ||
% If the current epoch overlaps with the previous, merge them | ||
if ep_exp(end, 2) >= expanded_epochs_temp(i, 1) | ||
ep_exp(end, 2) = max(ep_exp(end, 2), expanded_epochs_temp(i, 2)); | ||
else | ||
% Otherwise, add the current epoch as a new row | ||
ep_exp = [ep_exp; expanded_epochs_temp(i, :)]; | ||
end | ||
end | ||
|
||
% Success | ||
sts = 0; | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,14 +12,17 @@ | |
% be in seconds. This parameter is passed to pspm_get_timing(). | ||
% * timeunits: timeunits of the epochfile. | ||
% ┌───options | ||
% └─.channel_action: | ||
% └─.channel_action: [pre, post] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is the channel action changed? |
||
% ['add'/'replace'] Defines whether new channels should be added or | ||
% corresponding channels should be replaced. The default value is 'add'. | ||
% .expand_epochs: | ||
% Expand epochs by 0.5 seconds before and after | ||
% ● Output | ||
% * channel_index: index of channel containing the processed data | ||
% ● History | ||
% Introduced in PsPM 4.0 | ||
% Written in 2016 by Tobias Moser (University of Zurich) | ||
% Maintained in 2024 by Bernhard Agoué von Raußendorf | ||
|
||
global settings | ||
if isempty(settings) | ||
|
@@ -36,7 +39,7 @@ | |
elseif nargin < 4 | ||
options = struct(); | ||
end | ||
options = pspm_options(options, 'remove_epochs'); | ||
options = pspm_options(options, 'remove_epochs'); % change!!! [0,0] | ||
if options.invalid | ||
return | ||
end | ||
|
@@ -51,6 +54,26 @@ | |
return; | ||
end | ||
|
||
|
||
|
||
expansion = options.expand_epochs; | ||
|
||
if numel(expansion) ~= 2 | ||
error('Expansion must be a 2-element vector [pre, post].'); | ||
end | ||
% Expand the epochs | ||
|
||
[sts, ep_exp] = pspm_expand_epochs(ep, expansion, 'missing_ep'); | ||
if psts == -1 | ||
return; | ||
end | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
n_ep = size(ep, 1); | ||
n_data = numel(data); | ||
for i_data = 1:n_data | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest using the
varargin
syntax.