Skip to content

Commit f1f802e

Browse files
committed
Made several updates associated with real-time SIFT classification,
including some bug fixes and optimizations.
1 parent f653130 commit f1f802e

36 files changed

+910
-229
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ userdata/
1717
LBPA40-atlas-2011-04-28/*
1818
LBPA40-atlas-2011-04-28/PDFGM/*
1919

20+
/.project

RELEASE NOTES.TXT

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ Minor New Features
237237
- added the ability to read private plugins from ~/.bcilab/code
238238
- added robust re-referencing
239239
- flt_standarize now uses regularization for sphering
240+
- vis_artifacts: can now also display event markers
241+
- eeg_checkset: optimized chanlocs processing
242+
- par_getworkers_ssh: added sanity checks, made shell command editable, added ability to auto-generate MATLAB command (default)
243+
and added ability to bring up its own GUI
244+
- env_startup now creates a few more directories in ~/.bcilab (including code/scripts and logs/workers)
245+
- env_acquire_cluster/env_release_cluster (and "Request Cluster Availability" button) now by default override BCILAB's
246+
current global setting of whether to run on the cluster and which worker pool to use, making routine cluster acquisition
247+
with the click of a button more convenient (given that the cluster acquire options are set up correctly in the config file
248+
or settings GUI)
249+
- flt_selchans: can now select the closest channels to the selected ones, if the desired channels are not in the data set
250+
- flt_iir: now does not need the Sigproc toolbox for online processing and runs with less overhead (removed dfilt dependency)
251+
- bci_batchtrain: now returns error messages produced during a cluster run, and allows more flexible wildcard syntax when
252+
listing data sets to process (using rdir() rather than dir()), such as /data/mystudy/**/*.set
253+
- hlp_serialize: now serializes gpuArray data (as double arrays)
240254

241255
Major Changes:
242256
- arg_tovals: now by default sets the arg_direct flag to false rather than true, meaning that some
@@ -281,7 +295,11 @@ Minor Changes:
281295
- flt_ica: if TransformData is checked, by default the .icaweights field is cleared afterwards (can be disabled by
282296
setting the ClearAfterTransform flag to false)
283297
- ParadigmSpectralmeans: now uses a FIR filter by default instead of IIR
284-
298+
- arg_guidialog: now by default hides arguments marked "guru" (can be toggled with the ShowGuru option)
299+
- flt_fir: normalize_response now off by default
300+
- bci_batchtrain: was previously running locally by default; now the default matches the current global setting
301+
- fit_eeg_distribution: now by default fits an ensemble of truncated distributions and returns a quantile thereof
302+
- flt_clean_windows: updated defaults in accordance with fit_eeg_distribution
285303

286304
Serious Fixes:
287305
- ml_calcloss: fixed calculation of FP and FN (Dan Roberts)
@@ -309,4 +327,7 @@ Minor Fixes:
309327
- ParadigmSpectralmeans: fixed an off-by-one error in frequency indexing (Dan Roberts)
310328
- flt_eog: fixed bug which disabled regression when removing EOG channels
311329
- utl_check_dataset: fixed a warning message
312-
330+
- onl_append: changed the order of stream field updates to work with new MATLAB versions
331+
- flt_movavg: fixed buffering bug when data had 0 samples
332+
- ParadigmFBCSP: used missing function when robust flag was set (cov_robust, now cov_blockgeom)
333+
- ParadigmSIFT: feature extraction now works for online processing

bcilab_config.m

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
% But to automatically acquire machines, you need to have a Linux .ssh identity set up so that
4949
% you can ssh into any of these machines without needing to type a password. Also, make sure that
5050
% these machines/ports are never accessible from the internet (except perhaps via SSH tunnels).
51-
parallel = {'engine', 'local', 'pool', {'localhost:23547', 'localhost:23548', 'localhost:23549', 'localhost:23550', 'localhost:23551', 'localhost:23552', 'localhost:23553', 'localhost:23554'}};
51+
parallel = {'engine','local', 'pool', {'localhost:23547', 'localhost:23548', 'localhost:23549', 'localhost:23550', 'localhost:23551', 'localhost:23552', 'localhost:23553', 'localhost:23554'}};
5252

5353
% this controls how likely BCILAB is to cache things on disk; since disk access may be slower than
5454
% recomputing the results again, this is the expected number of times you believe you'll need a
@@ -70,14 +70,9 @@
7070
% whether to show guru-level options in the GUI by default (this can be toggled while editing)
7171
show_guru = false;
7272

73-
% custom options to control how workers are acquired; parameters to par_getworkers_* (rarely used)
74-
acquire_options = {};
75-
76-
77-
78-
79-
80-
73+
% custom options to control how workers are acquired; parameters to par_getworkers_*
74+
% these options are editable in the cluster settings dialog and are used when calling env_acquire_cluster (or clicking the "request cluster availability" button)
75+
acquire_options = {'Hostnames',{'localhost'},'ShutdownTimeout',300};
8176

8277

8378

code/arguments/arg_guidialog.m

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
% function must declare its arguments via arg_define. In addition, only a Subset of the function's
77
% specified arguments can be displayed.
88
%
9+
% If this function is called with no arguments from within a function that uses arg_define it brings
10+
% up a dialog for the function's defined arguments, with values assigned based on the function's
11+
% inputs (contents of in varargin) and returns an argument struct if the dialog was confirmed with a
12+
% click on OK, and an empty value otherwise. The calling function can exit on empty, or otherwise
13+
% resume with entered parameters.
14+
%
915
% In:
1016
% Function : the function for which to display arguments
1117
%
@@ -22,11 +28,15 @@
2228
%
2329
% 'Invoke' : whether to invoke the function directly; in this case, the output
2430
% arguments are those of the function (default: true, unless called in
25-
% the form g = arg_guidialog; e.g., from within some function)
31+
% the form g = arg_guidialog; from within some function)
32+
%
33+
% 'ShowGuru' : whether to show parameters marked as guru-level. (default: according
34+
% to env_startup setting)
2635
%
2736
% Out:
28-
% Parameters : either a struct that is a valid input to the Function or the outputs of the function
29-
% when Invoke is set to true (possibly multiple outputs)
37+
% Parameters : If Invoke was set to true, this is either the results of the function call or empty
38+
% (if the dialog was cancelled). If Invoke was set to false, this is either a struct
39+
% that is a valid input to the Function, or an empty value if cancel was clicked.
3040
%
3141
% Examples:
3242
% % bring up a configuration dialog for the given function
@@ -41,6 +51,15 @@
4151
% % bring up a dialog, and invoke the function with the selected settings after the user clicks OK
4252
% settings = arg_guidialog(@myfunction,'Invoke',true)
4353
%
54+
% % from within a function
55+
% args = arg_define(varargin, ...);
56+
% if nargin < 1
57+
% % optionally allow the user to enter arguments via a GUI
58+
% args = arg_guidialog;
59+
% % user clicked cancel?
60+
% if isempty(args), return; end
61+
% end
62+
%
4463
% See also:
4564
% arg_guidialog_ex, arg_guipanel, arg_define
4665
%
@@ -61,14 +80,22 @@
6180
% write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
6281
% USA
6382

83+
global tracking;
84+
6485
if ~exist('func','var')
65-
% called with no arguments, from inside a function: open function dialog
86+
% called with no arguments, from inside a function: open function dialog
6687
func = hlp_getcaller;
6788
varargin = {'Parameters',evalin('caller','varargin'),'Invoke',nargout==0};
6889
end
6990

7091
% parse arguments...
71-
hlp_varargin2struct(varargin,{'params','Parameters','parameters'},{}, {'subset','Subset'},{}, {'dialogtitle','title','Title'}, [char(func) '()'], {'buttons','Buttons'},[],{'invoke','Invoke'},true);
92+
hlp_varargin2struct(varargin, ...
93+
{'params','Parameters','parameters'},{}, ...
94+
{'subset','Subset'},{}, ...
95+
{'dialogtitle','title','Title'}, [char(func) '()'], ...
96+
{'buttons','Buttons'},[], ...
97+
{'invoke','Invoke'},true, ...
98+
{'show_guru','ShowGuru'},tracking.gui.show_guru);
7299
oldparams = params;
73100

74101
% obtain the argument specification for the function
@@ -83,7 +110,7 @@
83110
subset(1) = [];
84111
subset = allnames(~ismember(allnames,[subset 'arg_direct']));
85112
end
86-
[spec,subset] = obtain_items(rawspec,subset);
113+
[spec,subset] = obtain_items(rawspec,subset,'',show_guru);
87114

88115
% create an inputgui() dialog...
89116
geometry = repmat({[0.6 0.35]},1,length(spec)+length(buttons)/2);
@@ -95,7 +122,7 @@
95122
s = spec{k};
96123
if isempty(s)
97124
uilist(end+1:end+2) = {{} {}};
98-
else
125+
else
99126
if isempty(s.help)
100127
error(['Cannot display the argument ' subset{k} ' because it contains no description.']);
101128
else
@@ -138,6 +165,7 @@
138165
end
139166
end
140167

168+
141169
% invoke the GUI, obtaining a list of output values...
142170
helptopic = char(func);
143171
try
@@ -149,6 +177,14 @@
149177
catch
150178
disp('Cannot deduce help topic.');
151179
end
180+
181+
% % strip geometry for guru arguments
182+
% if ~show_guru
183+
% tmpspec = [spec{:}];
184+
% geometry([tmpspec.guru]) = [];
185+
% geomvert([tmpspec.guru]) = [];
186+
% end
187+
152188
[outs,dummy,okpressed] = inputgui('geometry',geometry, 'uilist',uilist,'helpcom',['env_doc ' helptopic], 'title',dialogtitle,'geomvert',geomvert); %#ok<ASGLU>
153189

154190
if ~isempty(okpressed)
@@ -204,7 +240,7 @@
204240
end
205241

206242
% obtain a cell array of spec entries by name from the given specification
207-
function [items,ids] = obtain_items(rawspec,requested,prefix)
243+
function [items,ids] = obtain_items(rawspec,requested,prefix,show_guru)
208244
if ~exist('prefix','var')
209245
prefix = ''; end
210246
items = {};
@@ -241,7 +277,7 @@
241277
% special case: switch arguments are not spliced, but instead the argument that defines the
242278
% option popupmenu will be retained
243279
if ~isempty(items{k}) && ~isempty(items{k}.children) && (~iscellstr(items{k}.range) || isempty(requested))
244-
[subitems, subids] = obtain_items(items{k}.children,{},[ids{k} '.']);
280+
[subitems, subids] = obtain_items(items{k}.children,{},[ids{k} '.'],show_guru);
245281
if ~isempty(subitems)
246282
% and introduce blank rows around them
247283
items = [items(1:k-1) {{}} subitems {{}} items(k+1:end)];
@@ -251,7 +287,7 @@
251287
end
252288

253289
% remove items that cannot be displayed
254-
retain = cellfun(@(x)isempty(x)||x.displayable,items);
290+
retain = cellfun(@(x)isempty(x)||x.displayable&&(show_guru||~x.guru),items);
255291
items = items(retain);
256292
ids = ids(retain);
257293

code/environment/env_acquire_cluster.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
% invoke, but also impose default arguments (if unspecified)
3232
% by default, workers do not recruit (but only list) other workers, preventing a cascading effect
3333
try
34-
par_getworkers_ssh(arguments{:});
34+
tracking.parallel.pool = par_getworkers_ssh(arguments{:});
35+
tracking.parallel.engine = 'BLS';
36+
disp('Set default compute scheduler to BLS (parallel).');
3537
catch e
3638
disp('Could not acquire worker machines; traceback: ');
3739
env_handleerror(e);

code/environment/env_release_cluster.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@
1111
global tracking;
1212
% this will lead to the deletion of any involved heartbeat timer.
1313
tracking.cluster_requested = [];
14+
tracking.parallel.engine = 'local';
15+
disp('Set default compute scheduling to local.');

code/environment/env_startup.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,8 @@ function env_startup(varargin)
435435
% create directories in the user's .bcilab folder...
436436
home_basedir = [hlp_homedir filesep '.bcilab' filesep];
437437
home_codedirs = {['code' filesep 'filters'],['code' filesep 'dataset_editing'], ...
438-
['code' filesep 'machine_learning'], ['code' filesep 'paradigms']};
439-
home_miscdirs = {'models','approaches','code',['code' filesep 'dependencies'],'logs'};
438+
['code' filesep 'machine_learning'], ['code' filesep 'paradigms'], ['code' filesep 'scripts']};
439+
home_miscdirs = {'models','approaches','code',['code' filesep 'dependencies'],'logs',['logs' filesep 'workers']};
440440
for d = [home_codedirs home_miscdirs]
441441
try
442442
subdir = [home_basedir d{1}];

code/filters/flt_clean_windows.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
% Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
9797
% 2010-07-06
9898

99-
% flt_clean_windows_version<1.0> -- for the cache
99+
% flt_clean_windows_version<1.01> -- for the cache
100100

101101
if ~exp_beginfun('editing') return; end;
102102

@@ -111,8 +111,8 @@
111111
arg_sub({'fit_params','ParameterFitting','parameter_fitting'}, {}, { ...
112112
arg({'max_dropout_fraction','MaxDropoutFraction'}, 0.1, [], 'Maximum fraction that can have dropouts. This is the maximum fraction of time windows that may have arbitrarily low amplitude (e.g., due to the sensors being unplugged).'), ...
113113
arg({'min_clean_fraction','MinCleanFraction'}, 0.25, [], 'Minimum fraction that needs to be clean. This is the minimum fraction of time windows that need to contain essentially uncontaminated EEG.'), ...
114-
arg({'fit_quantiles','FitQuantiles'}, [0.022 0.6], [], 'Truncated Gaussian quantile. Quantile range [upper,lower] of the truncated Gaussian distribution that shall be fit to the EEG contents.','guru',true), ...
115-
arg({'step_sizes','StepSizes'}, [0.001 0.01], [], 'Grid search stepping. Step size of the grid search, in quantiles; separately for [lower,upper] edge of the truncated Gaussian. The lower edge has finer stepping because the clean data density is assumed to be lower there, so small changes in quantile amount to large changes in data space.','guru',true), ...
114+
arg({'fit_quantiles','FitQuantiles'}, [0.022*ones(21,1) (0.5:0.01:0.7)'], [], 'Truncated Gaussian quantile. Quantile range [upper,lower] of the truncated Gaussian distribution that shall be fit to the EEG contents.','guru',true), ...
115+
arg({'step_sizes','StepSizes'}, [0.01 0.01], [], 'Grid search stepping. Step size of the grid search, in quantiles; separately for [lower,upper] edge of the truncated Gaussian. The lower edge has finer stepping because the clean data density is assumed to be lower there, so small changes in quantile amount to large changes in data space.','guru',true), ...
116116
arg_deprecated({'num_bins','NumBins'},50,[],'This parameter is now auto-determined.') ...
117117
}, 'Parameter fitting details. Group of sub-arguments that govern how EEG distribution parameters should be fit.'), ...
118118
arg({'keep_metadata','KeepMetadata'}, true, [], 'Retain metadata of EEG set. Retaining meta data (events, ICA decomposition, etc.) is quite slow.'), ...

code/filters/flt_fir.m

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
% Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
107107
% 2010-04-17
108108

109-
% flt_fir_version<1.03> -- for the cache
109+
% flt_fir_version<1.04> -- for the cache
110110

111111
if ~exp_beginfun('filter') return; end
112112

@@ -122,7 +122,7 @@
122122
arg({'stopripple','StopbandRipple'}, -40, [-180 1], 'Maximum relative ripple amplitude in stop-band. Relative to nominal pass-band gain. Affects the filter length (i.e., delay). Assumed to be in db if negative, otherwise taken as a ratio.'), ...
123123
arg({'designrule','DesignRule'}, 'Frequency Sampling', {'Parks-McClellan','Window Method','Frequency Sampling'}, 'Filter design rule. Parks-McClellan minimizes the maximum error, the Window Method minimizes the square error, and Frequency Sampling constructs the filter via the Fourier transform without tuning (the latter requires no sigproc toolbox).'), ...
124124
arg({'chunk_length','ChunkLength'},50000,[], 'Maximum chunk length. Process the data in chunks of no larger than this (to avoid memory limitations).','guru',true), ...
125-
arg({'normalize_amplitude','NormalizeAmplitude'},true,[], 'Normalize amplitude. Normalizes the amplitude such that the maximum gain is as desired. This helps with the occasional erratic filter design result.','guru',true), ...
125+
arg({'normalize_amplitude','NormalizeAmplitude'},false,[], 'Normalize amplitude. Normalizes the amplitude such that the maximum gain is as desired. This helps with the occasional erratic filter design result.','guru',true), ...
126126
arg_nogui({'state','State'}));
127127

128128
if isempty(state)
@@ -227,7 +227,7 @@
227227

228228
[b,n] = deal(state.b,length(state.b));
229229
% process each known time series field
230-
for fld = {'data','srcpot','icaact'}
230+
for fld = utl_timeseries_fields(signal)
231231
field = fld{1};
232232
if isfield(signal,field) && ~isempty(signal.(field)) && ~isequal(signal.(field),1)
233233
if ~isfield(state,field)
@@ -277,9 +277,10 @@
277277
signal.etc.filter_delay = 0; end
278278

279279
if strcmp(ftype,'linear-phase')
280-
signal.etc.filter_delay = signal.etc.filter_delay + length(b)/2/signal.srate;
280+
signal.etc.filter_delay = signal.etc.filter_delay + (length(b)/2-1)/signal.srate;
281281
elseif strcmp(ftype,'minimum-phase')
282-
signal.etc.filter_delay = signal.etc.filter_delay + hlp_getresult(2,@max,b)/signal.srate;
282+
[dummy,maxidx] = max(b); %#ok<ASGLU>
283+
signal.etc.filter_delay = signal.etc.filter_delay + (maxidx-1)/signal.srate;
283284
end
284285

285286
exp_endfun;

0 commit comments

Comments
 (0)