-
Notifications
You must be signed in to change notification settings - Fork 732
/
Copy pathft_preamble_init.m
183 lines (172 loc) · 7.82 KB
/
ft_preamble_init.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
% FT_PREAMBLE_INIT is a helper script that is used at the start of all FieldTrip main
% functions. It checks whether the user specified at lease one input arguments (i.e.
% the cfg) or shows the help of the calling function. It merges the global defaults
% with the cfg. It checks whether the output file already exists and whether it is OK
% to overwrite it. It tracks the function call.
%
% Use as
% ft_preamble init
%
% See also FT_PREAMBLE, FT_POSTAMBLE, FT_TRACKUSAGE
% Copyright (C) 2011-2016, Robert Oostenveld, DCCN
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
% FieldTrip is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% FieldTrip is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$
% disabled for now, see further down
global ft_default
% Which high-level FieldTrip function is lowest on the stack, and which is
% highest? Lowest could e.g. be ft_selectdata called by another FieldTrip
% function, highest should always be the top-level FieldTrip function that
% was explicitly called by the user. These are used further down below,
% e.g. in the reproducescript functionality.
% (Note that we prepend random strings to local variables in pre- and
% postambles to avoid contaminating the caller's namespace.)
FjmoT6aA_stack = dbstack('-completenames');
% FjmoT6aA_stack(1) is this script
% FjmoT6aA_stack(2) is the calling ft_postamble function
% FjmoT6aA_stack(3) is the lowest FieldTrip function on the stack, the one currently being evaluated
% the highest FieldTrip function on the stack is given by the highest n
% such that FjmoT6aA_stack(n).path begins with the FieldTrip path
FjmoT6aA_lowest_ft = FjmoT6aA_stack(3).name;
FjmoT6aA_highest_ft = FjmoT6aA_stack(3).name;
[FjmoT6aA_ft_ver, FjmoT6aA_ft_path] = ft_version;
for FjmoT6aA_k = 3:numel(FjmoT6aA_stack)
if startsWith(FjmoT6aA_stack(FjmoT6aA_k).file, FjmoT6aA_ft_path)
FjmoT6aA_highest_ft = FjmoT6aA_stack(FjmoT6aA_k).name;
else
% we are operating under the assumption here that a private FieldTrip
% function (i.e. one whose name does not start with "ft_") never calls
% another high-level FieldTrip function.
break;
end
end
% check whether we are currently in a top-level user-called FT function
% (note that checking of names only probably is not sufficient, as recursion
% could occur)
FjmoT6aA_current_ft_toplevel = strcmp(FjmoT6aA_lowest_ft, FjmoT6aA_highest_ft) && ...
(FjmoT6aA_k == 4 || numel(FjmoT6aA_stack) == 3);
if ft_nargin==0
help(FjmoT6aA_lowest_ft);
% throw the error as if it happened in the original function
msg.message = 'This function requires one or multiple input arguments, please refer to the documentation above';
msg.identifier = '';
msg.stack = FjmoT6aA_stack;
error(msg);
end % if nargin
% check if there are fieldnames in the cfg that suggest as if the user
% erroneously inputted a data argument
checkdatafields = isfield(cfg, {'cfg' 'label' 'dimord' 'trialinfo' 'avg' 'powspctrm'});
if any(checkdatafields)
help(FjmoT6aA_lowest_ft);
% throw the error as if it happened in the original function
msg.message = 'It seems as if the first input argument is a FieldTrip data structure, while a cfg is expected';
msg.identifier = '';
msg.stack = FjmoT6aA_stack;
error(msg);
end
% convert automatically from cell-array to structure
if iscell(cfg)
cfg = ft_keyval2cfg(cfg);
end
% check that it is an struct or empty numeric array
assert(isstruct(cfg) || (isnumeric(cfg) && isempty(cfg)), 'The configuration must be a structure or empty');
% this script requires some options that can be user-specified, but otherwise are obtained from ft_default
% merge the default options into the configuration, except the preamble field which is used for passing arguments
cfg = mergestruct(cfg, ft_default);
% determine whether function execution should be aborted or continued
if isfield(cfg, 'outputfile') && ~isempty(cfg.outputfile)
assert(any(strcmp(fieldnames(cfg), 'outputfilepresent')), 'cfg.outputfilepresent is a required option, please see FT_DEFAULTS');
% check whether the output file already exists
if ischar(cfg.outputfile)
chiL7fee_outputfile = {cfg.outputfile};
else
chiL7fee_outputfile = cfg.outputfile;
end
for i=1:numel(chiL7fee_outputfile)
[p, f, x] = fileparts(chiL7fee_outputfile{i});
if isempty(p)
% the relative path was speciield
chiL7fee_outputfile{i} = fullfile(pwd, chiL7fee_outputfile{i});
else
% the absolute path was specified
chiL7fee_outputfile{i} = chiL7fee_outputfile{i};
end
if ~exist(chiL7fee_outputfile{i}, 'file')
ft_abort = false;
else
% the output file exists, determine how to deal with it
switch cfg.outputfilepresent
case 'keep'
if ft_nargout>0
% continue executing the parent function
ft_warning('output file %s is already present, but you also requested an output argument: continuing function execution', chiL7fee_outputfile{i});
ft_abort = false;
else
% stop executing the parent function
ft_warning('output file %s is already present: aborting function execution', chiL7fee_outputfile{i});
ft_abort = true;
end
case 'overwrite'
ft_warning('output file %s is already present: it will be overwritten', chiL7fee_outputfile{i});
ft_abort = false;
case 'error'
ft_error('output file %s is already present', chiL7fee_outputfile{i});
otherwise
ft_error('invalid option for cfg.outputfilepresent');
end % case
end
end % for each of the output files
else
% there is no reason to abort execution
ft_abort = false;
end % if chiL7fee_outputfile{i}
if isfield(cfg, 'reproducescript') && ~isempty(cfg.reproducescript)
% the reproducescript code should only be executed in a top-level FT function
if ~FjmoT6aA_current_ft_toplevel
% we are in a FT function that was called by another FT function
cfg = rmfield(cfg, 'reproducescript');
else
% we are in a top-level FT function
if ~isfolder(cfg.reproducescript)
mkdir(cfg.reproducescript);
end
% user-specified cfg.inputfile or cfg.outputfile are not compatible
% with cfg.reproducescript functionality, throw error to make them
% mutually exclusive
if (isfield(cfg, 'inputfile') && ~isempty(cfg.inputfile)) || ...
(isfield(cfg, 'outputfile') && ~isempty(cfg.outputfile))
ft_error('cfg.reproducescript cannot be used together with a user-specified cfg.inputfile or cfg.outputfile');
end
% this variable is used in loadvar, savevar and savefig
Fief7bee_reproducescript = cfg.reproducescript;
cfg = rmfield(cfg, 'reproducescript');
% pause one second to ensure that subsequent file names (which contain the time stamp) are unique
pause(1);
end
end
if false
% this is currently generating too much data and therefore disabled
if isfield(cfg, 'trackusage') && ~(isequal(cfg.trackusage, false) || isequal(cfg.trackusage, 'no') || isequal(cfg.trackusage, 'off'))
% track the usage of the calling function
stack = dbstack('-completenames');
% stack(1) is this script
% stack(2) is the calling ft_postamble function
% stack(3) is the main FieldTrip function that we are interested in
ft_trackusage('function call', 'function', stack(3).name);
end % if trackusage
end