% POP_SAVESET - save one or more EEG dataset structures
%
% Usage:
% >> pop_saveset( EEG ); % use an interactive pop-up window
% >> EEG = pop_saveset( EEG, 'key', 'val', ...); % no pop-up
%
% Inputs:
% EEG - EEG dataset structure. May only contain one dataset.
%
% Optional inputs:
% 'filename' - [string] name of the file to save to
% 'filepath' - [string] path of the file to save to
% 'check' - ['on'|'off'] perform extended syntax check. Default 'off'.
% 'savemode' - ['resave'|'onefile'|'twofiles'] 'resave' resave the
% current dataset using the filename and path stored
% in the dataset; 'onefile' saves the full EEG
% structure in a Matlab '.set' file, 'twofiles' saves
% the structure without the data in a Matlab '.set' file
% and the transposed data in a binary float '.fdt' file.
% By default the option from the eeg_options.m file is
% used.
% 'version' - ['6'|'7'|'7.3'] save Matlab file as version 6, 7, or
% '7.3' (default; as defined in eeg_option file).
%
% Outputs:
% EEG - saved dataset (after extensive syntax checks)
% ALLEEG - saved datasets (after extensive syntax checks)
%
% Note: An individual dataset should be saved with a '.set' file extension
%
% Author: Arnaud Delorme, CNL / Salk Institute, 2001
%
% See also: POP_LOADSET, EEGLAB
% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.
% 01-25-02 reformated help & license -ad
function [EEG, com] = pop_saveset( EEG, varargin)
com = '';
if nargin < 1
help pop_saveset;
return;
end
if isempty(EEG) , error('Cannot save empty datasets'); end
if length(EEG) == 1 && isequal(EEG.data, 'in set file')
EEGTMP = pop_loadset(fullfile(EEG.filepath, EEG.filename));
EEG.data = EEGTMP.data;
end
% empty filename (resave file)
emptyfilename = 0;
if nargin > 1
if isempty(varargin{1}) && isempty(EEG.filename), emptyfilename = 1; end
if strcmpi(varargin{1},'savemode')
if length(EEG) == 1
if isempty(EEG(1).filename), varargin{2} = ''; emptyfilename = 1; end
else
if any(cellfun(@isempty, { EEG.filename }))
error('Cannot resave files who have not been saved previously');
end
end
end
end
if nargin < 2 || emptyfilename
if length(EEG) >1, error('For reasons of consistency, this function does not save multiple datasets any more'); end
% pop up window to ask for file
[filename, filepath] = uiputfile2('*.set', 'Save dataset with .set extension -- pop_saveset()');
if ~ischar(filename), return; end
drawnow;
options = { 'filename' filename 'filepath' filepath };
else
% account for old calling format
% ------------------------------
if isempty(strmatch( lower(varargin{1}), { 'filename' 'filepath' 'savemode' 'check' }))
options = { 'filename' varargin{1} };
if nargin > 2
options = { options{:} 'filepath' varargin{2} };
end
else
options = varargin;
end
end
% decode input parameters
% -----------------------
eeglab_options;
defaultSave = fastif(option_saveversion6, '6', '7.3');
g = finputcheck(options, { 'filename' 'string' [] '';
'filepath' 'string' [] '';
'version' 'string' { '6','7','7.3' } defaultSave;
'check' 'string' { 'on','off' } 'off';
'savemode' 'string' { 'resave','onefile','twofiles','' } '' });
if ischar(g), error(g); end
% current filename without the .set
% ---------------------------------
if emptyfilename == 1, g.savemode = ''; end
[g.filepath, filenamenoext, ext] = fileparts( fullfile(g.filepath, g.filename) ); ext = '.set';
g.filename = [ filenamenoext ext ];
% performing extended syntax check
% --------------------------------
if strcmpi(g.check, 'on')
fprintf('Pop_saveset: Performing extended dataset syntax check...\n');
EEG = eeg_checkset(EEG, 'eventconsistency');
EEG = eeg_checkset(EEG);
else
EEG = eeg_checkset(EEG);
end
% check for change in saving mode
% -------------------------------
if length(EEG) == 1
if strcmpi(g.savemode, 'resave') && isfield(EEG, 'datfile') && ~isempty(EEG.datfile) && ~option_savetwofiles
disp('Note that your memory options for saving datasets does not correspond')
disp('to the format of the datasets on disk (ignoring memory options)')
elseif strcmpi(g.savemode, 'resave') && ~isfield(EEG, 'datfile') && option_savetwofiles
disp('Note that your memory options for saving datasets does not correspond')
disp('to the format of the datasets on disk (ignoring memory options)')
end
end
% default saving option
% ---------------------
save_as_dat_file = 0;
data_on_disk = 0;
if strcmpi(g.savemode, 'resave')
% process multiple datasets
% -------------------------
% check if called from EEGLAB
% if this is not the case, resave the file anyway
calledFromEEGLABFlag = true;
try
db = dbstack;
eeglabp = fileparts(which('eeglab.m'));
if length(db) > 1
if isempty(strfind(which(db(2).file), eeglabp))
calledFromEEGLABFlag = false;
end
end
catch
end
if length(EEG) > 1
for index = 1:length(EEG)
if strcmpi( EEG(index).saved, 'yes') && calledFromEEGLABFlag
disp('Dataset has not been modified; No need to resave it.');
else
pop_saveset(EEG(index), 'savemode', 'resave');
EEG(index).saved = 'yes';
end
end
if nargout > 1
com = sprintf('EEG = pop_saveset( EEG, %s);', vararg2str(options));
end
return;
end
if strcmpi( EEG.saved, 'yes') && calledFromEEGLABFlag
disp('Dataset has not been modified; No need to resave it.');
return;
end
g.filename = EEG.filename;
g.filepath = EEG.filepath;
if isfield(EEG, 'datfile')
if ~isempty(EEG.datfile)
save_as_dat_file = 1;
end
end
if ischar(EEG.data) && ~save_as_dat_file % data in .set file
TMP = pop_loadset(EEG.filename, EEG.filepath);
EEG.data = TMP.data;
data_on_disk = 1;
end
else
if length(EEG) >1, error('For reasons of consistency, this function does not save multiple datasets any more'); end
if ~strcmpi(EEG.filename, g.filename) || ~strcmpi(EEG.filepath, g.filepath)
EEG.datfile = '';
end
EEG.filename = g.filename;
EEG.filepath = g.filepath;
if isempty(g.savemode)
if option_savematlab, g.savemode = 'onefile';
else g.savemode = 'twofiles';
end
end
if strcmpi(g.savemode, 'twofiles')
save_as_dat_file = 1;
EEG.datfile = [ filenamenoext '.fdt' ];
option_savetwofiles = true; % BUG: Missing, thus it will save data in .set file as well as fdt
end
end
% Saving data as float and Matlab
% -------------------------------
tmpica = EEG.icaact;
EEG.icaact = [];
if ~ischar(EEG.data)
if ~strcmpi(class(EEG.data), 'memmapdata') && ~strcmpi(class(EEG.data), 'mmo') && ~strcmpi(class(EEG.data), 'single')
tmpdata = single(reshape(EEG.data, EEG.nbchan, EEG.pnts*EEG.trials));
else
tmpdata = EEG.data;
end
no_resave_dat = 'no';
else
no_resave_dat = 'yes';
end
v = version;
try,
fprintf('Saving dataset...\n');
EEG.saved = 'yes';
if save_as_dat_file
if ~ischar(EEG.data)
EEG.data = EEG.datfile;
tmpdata = floatwrite( tmpdata, fullfile(EEG.filepath, EEG.data), 'ieee-le');
end
end
% reload daata before saving if necessary
tmpdata2 = [];
if ~option_savetwofiles && ischar(EEG.data)
tmpdata2 = EEG.data;
EEG.data = eeg_getdatact(EEG);
EEG.datfile = [];
end
try
if option_saveasstruct
if strcmpi(g.version, '6')
warning('')
try
save(fullfile(EEG.filepath, EEG.filename), '-v6', '-mat', '-struct', 'EEG');
[~,b] = lastwarn;
catch
b = 'MATLAB:save:sizeTooBigForMATFile';
end
if strcmpi(b, 'MATLAB:save:sizeTooBigForMATFile')
disp('Re-saving file using the 7.3 format that can handle large variables')
save(fullfile(EEG.filepath, EEG.filename), '-v7.3', '-mat', '-struct', 'EEG');
end
elseif strcmpi(g.version, '7')
save(fullfile(EEG.filepath, EEG.filename), '-v7', '-mat', '-struct', 'EEG');
else
save(fullfile(EEG.filepath, EEG.filename), '-v7.3', '-mat', '-struct', 'EEG');
end
else
if strcmpi(g.version, '6')
save(fullfile(EEG.filepath, EEG.filename), '-v6', '-mat', 'EEG');
elseif strcmpi(g.version, '7')
save(fullfile(EEG.filepath, EEG.filename), '-v7', '-mat', 'EEG');
else
save(fullfile(EEG.filepath, EEG.filename), '-v7.3', '-mat', 'EEG');
end
end
catch
disp('Cannot save in v6 format (Unicode characters?), using default (possible x20 slow down)');
save(fullfile(EEG.filepath, EEG.filename), '-mat', 'EEG');
end
% put back the EEG structure field as they were
if ~isempty(tmpdata2)
EEG.data = tmpdata2;
end
if save_as_dat_file && strcmpi( no_resave_dat, 'no' )
EEG.data = tmpdata;
end
catch
rethrow(lasterror);
end
% try to delete old .fdt or .dat files
% ------------------------------------
tmpfilename = fullfile(EEG.filepath, [ filenamenoext '.dat' ]);
if exist(tmpfilename) == 2
disp('Deleting old .dat file format detected on disk (now replaced by .fdt file)');
try,
delete(tmpfilename);
disp('Delete successful.');
EEG.datfile = [];
catch, disp('Error while attempting to remove file');
end
end
if save_as_dat_file == 0
tmpfilename = fullfile(EEG.filepath, [ filenamenoext '.fdt' ]);
if exist(tmpfilename) == 2
disp('Old .fdt file detected on disk, deleting file since the Matlab file now contains all the data');
try
delete(tmpfilename);
disp('Delete successful.');
EEG.datfile = [];
catch, disp('Error while attempting to remove file');
end
end
end
% recovering variables
% --------------------
EEG.icaact = tmpica;
if data_on_disk
EEG.data = 'in set file';
end
if isnumeric(EEG.data) && v(1) < 7
EEG.data = double(reshape(tmpdata, EEG.nbchan, EEG.pnts, EEG.trials));
end
EEG.saved = 'justloaded';
if nargout > 1
com = sprintf('EEG = pop_saveset( EEG, %s);', vararg2str(options));
end
return;
function num = popask( text )
ButtonName=questdlg2( text, ...
'Confirmation', 'Cancel', 'Yes','Yes');
switch lower(ButtonName),
case 'cancel', num = 0;
case 'yes', num = 1;
end