Some physiological measurements require more human inspection and interaction to be good enough for additional analyses (e.g. in a GSR peak-to-peak analysis). This function allows to visualize parts of a measurement (e.g. GSR data channel) as single curves (e.g. 15-second windows following onsets).
The physiological data must be available as a one of the supported object types, ACQ or NTT. It is fairly simple to store any channel data in a new NTT object, if necessary:
% load data from a MAT file load HPS1344_session1_GSR.mat; % create new NTT ntt = xff('new:ntt'); % store data from mat file in ntt ntt.Data = data;
Usually, it is best to first resample the data and then filter the channel which is to be examined (potentially into a new channel):
% data is loaded in object gsr % this resamples all channels, applying cubic/gaussian resampling % for channel 1 and simple re-indexing for channels 2 through 9 gsr.Resample(100, struct('cubic', [true, false(1, 8)])); % this filters channel 1 into a new channel (10) % all parameters are default, the post-filtering cut-off is set to 0.2s gsr.Filter(1, struct('dest', 10, 'post', 0.2));
plotcurves - plot different curves and select those of interest FORMAT: [sel, varc, spot, sets] = plotcurves(obj [, opts]]); Input fields: obj xff object with plotable data or SxC double data opts optional settings .cuediff difference between cue and onset (only useful if fixed interval!; default: -2) .curves Cx2 cell array with names and a 1x3 double array containing [channelnumber, onset, offset] - for curves in a set, the mean/std. error is computed - onset and offset are given in seconds .dchannel data channel (for onset detection, default: 1) .dfilt detection filter length (in seconds, default: 0.5) .dminlat minimum detection latency (after one point, def: 0.5) .freq data sampling frequency (if not in object, def: 100) .ochannel onset channel number (will add curves, default: []) .odchannel original data channel (allows to filter effect) .onsets Ox1 onset vector in seconds .owin 1x2 onset window in seconds (default: [-2, 18]) .sets Sx2 cell array with names and lists of curve indices .spot Sx1 cell array with Cx1 X or Cx2 x/y time-points .spotnames Sx1 cell array with strings .spottype Sx1 cell array with either of 'cue', {'free'}, 'max', 'min', 'minmax', 'onset' .var 1xV struct with fields .calc either of 'dx', {'dy'}, 'mean', 'std', 'var', 'x', 'y' .name variable name .spot 1x1 or 1x2 index into S .trans apply additional transformation to each value, one of {'none'}, 'log', 'log+1', 'sqrt' Output fields: sel selection (Cx1 boolean array) varc computed variables spot updated spots sets updates sets (new indices) Note: where appropriate, the options are taken from obj.RunTimeVars if not specified in the call!
This function has its own GUI. Once called (with appropriate parameters), the following dialog will open:
The dialog has the following controls:
Additionally the following keyboard commands are supported (when no UI control has the focus!):
SHIFT
+ cursor up/down/left/right → move plot window along X/Y axis (0.1 of window size)'d
' key → decrease zoom (de-magnify)'f
' key → toggle force-to-curve checkbox'i
' / 'o
' keys → toggle whether this curve (onset) is included (i) or omitted (o) from averages'm
' key → increase zoom (magnify)'p
' key → places a currently highlighted marker at a peak (max or min, depending on data)'r
' key → reset axes limits (to initial curve setting)'u
' key → toggle use-curve checkboxThe curve/spot plot has the following mouse-based functions:
d
or r
keys)Operating the dialog is straight forward:
u
key if the box is checked)
After all curves have been inspected/worked on, simply click on Accept curves and variables
or close the dialog (no difference in behavior).
The most basic usage is by simply creating as many onsets as required and defining some basic spots:
% data is in object gsr and already preprocessed % onsets are in variable onsets, data in channel 1 curves = cell(numel(onsets), 2); for cc = 1:numel(onsets) curves{cc, 1} = sprintf('Onset %d, t=%.4f', cc, onsets(cc)); curves{cc, 2} = [1, onsets(cc) - 2, onsets(cc) + 20]; end % we define three spots of interest: % - onset (time of stimulus), % - delay of response (minimum before peak), % - and peak of response (amplitude) spotnames = {'onset', 'delay', 'peak'}; spottype = {'onset', 'min', 'max'}; % the spots are simply defined as the onsets (and added values) spots = {onsets, onsets + 3, onsets + 7}; % then we define some variables of interest: % - Latency (defined as x-diff between onset and delay) % - Response time (defined as x-diff between delay and peak) % - Base amplitude (defined as y-value at delay) % - Peak amplitude (defined as y-value at peak) % - Peak-to-peak response amplitude (defined as y-diff between delay and peak) % additionally, we define that for the response amplitude, the log+1 transform % should be applied after we're done vars = struct( ... 'name', {'Latency', 'Resp. time', 'Base ampl.', 'Peak ampl.', 'Resp. ampl.'}, ... 'calc', {'dx', 'dx', 'y', 'y', 'dy'}, ... 'spot', {[1,2], [2,3], [2], [3], [2,3]}, ... 'trans', {'none', 'none', 'none', 'none', 'log+1'}); % options: % - data is now in channel 10 (filtered!) % - original data is in channel 1 (pre-filter) % - variables and spots as defined pcopts = struct( ... 'var', vars, ... 'spot', {spot}, ... 'spotnames', {spotnames}, ... 'spottype', {spottype}); % now we call plotcurves plotcurves(gsr, pcopts);
If the data contains onset/stimulus information, the plotcurves function has implemented functionality to detect peaks (min/max):
% data is in object gsr and already preprocessed % for this example we define four (!) spots of interest: % - cue (time of stimulus minus 2 secs) % - onset (time of stimulus), % - delay of response (minimum before peak), % - and peak of response (amplitude) spotnames = {'cue', 'onset', 'delay', 'peak'}; spottype = {'cue', 'onset', 'min', 'max'}; % the spot values are set to empty arrays with size 0x2! % this tells plotcurves to autodetect... spot = {zeros(0,2), zeros(0,2), zeros(0,2), zeros(0, 2)}; % then we define the variables of interest: % NOTE: since we have a CUE spot, all spot indices shift by one! % - Latency (defined as x-diff between onset and delay) % - Response time (defined as x-diff between delay and peak) % - Base amplitude (defined as y-value at delay) % - Peak amplitude (defined as y-value at peak) % - Peak-to-peak response amplitude (defined as y-diff between delay and peak) % additionally, we define that for the response amplitude, the log+1 transform % should be applied after we're done vars = struct( ... 'name', {'Latency', 'Resp. time', 'Base ampl.', 'Peak ampl.', 'Resp. ampl.'}, ... 'calc', {'dx', 'dx', 'y', 'y', 'dy'}, ... 'spot', {[2, 3], [3, 4], [3], [4], [3, 4]}, ... 'trans', {'none', 'none', 'none', 'none', 'log+1'}); % re-using the variables definition from above, options: % - data is now in channel 10 (filtered!) % - original data is in channel 1 (pre-filter) % - onsets are coded in channel 8 (0Volts nothing, 5 Volts boxes) % - cue onffset is 2 seconds % - thus, the window is increased! [-4, 20] % - variables and spots as defined pcopts = struct( ... 'dchannel', 10, ... 'odchannel', 1, ... 'ochannel', 8, ... 'cuediff', 2, ... 'owin', [-4, 20],... 'var', vars, ... 'spot', {spot}, ... 'spotnames', {spotnames}, ... 'spottype', {spottype}); % now we call plotcurves plotcurves(gsr, pcopts);
The function outputs the following variables:
In addition to this, the final options and configuration (when the dialog was closed) is stored in the gsr object under .RunTimeVars.plotcurves
.