General programming concepts in TrajTracker

TrajTracker uses some programming tools and concepts that go beyond what we may call "basic matlab programming skills". If you are not familiar with these, we hope the following may help.

Contents

Function handles

A function handle is a variable that represents a certain function. A handle to a function, say f(), can be passed as argument to another function, which would be able to call f() via that handle.

A common example to function handles is matlab's arrayfun():

a = 1:100;
b = arrayfun(@(x)x^2, a);

arrayfun() gets two arguments - a function handle and an array - and applies to function to each element in the array.

The TrajTracker toolbox uses function handles for several goals. For example, tt.util.filterTrials() get the experiment data of one or several subjects and returns a corresponding data structure in which some of the trials were filtered out. To specify which trials should be included and which should be filtered out, tt.util.filterTrials() gets a function handle for a filtering function that defines, per trial, whether to include it or not.

For this to work, filterTrials() should know how to call the filtering function you provide it. The way it works is that filterTrials() only accepts functions with a certain signature (= arguments and return value) - e.g., it can get a filtering function that gets a single argument (the trial) and returns a boolean value (true/false, indicating whether the trial should be included).

You can define function handles in two ways: by specifying a handle to an already-defined function, or by defining function inline. For example:

function include = includeOnlyOddTargets(trial)
    include = mod(trial.Target, 2) == 1;
end
%-- Refer to a predefined function
f = tt.util.filterTrials(mydataset, @includeOnlyOddTargets);
%-- Define a function inline
f = tt.util.filterTrials(mydataset, @(trial)mod(trial.Target, 2) == 1);

For more information on function handles, look here.

Classes

A class is an object containing several entries (fields), much similarly to a matlab struct. Still, there are some important differences between classes and |struct|s:

trialData.Custom.MyDynamicVariable = 3
filtered = experimentData.filterTrials(...arguments...)
a = struct('x', 1);
b = a;
b.new_field = 3;
disp(a.new_field);  % This will result in an error: new_field was added to b but not to a
a = NLOneTrialData(1, 1);
b = a;
b.TrialIndex = 5;
disp(a.TrialIndex);

To learn about matlab classes, look here

A shorter explanation with a simple example is here.