Skip to content

Commit 88a81a2

Browse files
committed
Better handling of ExpDefs; Documentation updates
1 parent 80bc28b commit 88a81a2

File tree

10 files changed

+265
-166
lines changed

10 files changed

+265
-166
lines changed

+eui/SignalsTest.m

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
classdef (Sealed) SignalsTest < handle %& exp.SignalsExp
22
%SIGNALSTEST A GUI for testing SignalsExp experiment definitions
3+
% A GUI for running Signals Experiments, loading/saving parameters,
4+
% testing custom ExpPanels and live-plotting Signals. The wheel input
5+
% is simulated with mouse movements by default.
36
%
47
% Example:
5-
% PsychDebugWindowConfiguration
6-
% e = eui.SignalsTest
7-
%
8-
% TODO Document this class
8+
% PsychDebugWindowConfiguration % Transparent window
9+
% e = eui.SignalsTest('advancedChoiceWorld')
910
%
1011
% TODO This may be generalized for all Experiment classes!
11-
% See also: EXP.SIGNALSEXPTEST, EUI.MCONTROL
1212
%
13+
% See also: EXP.SIGNALSEXPTEST, EUI.MCONTROL
1314

14-
% can be set in GUI or command line to improve visualization
1515
properties
1616
% A struct of hardware objects to be used with the Experiment
1717
Hardware
@@ -50,7 +50,7 @@
5050
% The path of the last selected experiment function
5151
LastDir
5252
% The currently chosen Signals experiment definition
53-
ExpDef function_handle
53+
ExpDef
5454
% Dummy communicator for ExpPanel events. Our experiment object may
5555
% notify the ExpPanel through dummy events.
5656
DummyRemote srv.StimulusControl
@@ -64,9 +64,9 @@
6464
ParamProfileLabel
6565
% Handles for the ExpPanel and ParamEditor events
6666
Listeners
67-
6867
% The container for the running experiment panel
6968
ExpPanelBox
69+
% The timer for refreshing the ExpPanel
7070
RefreshTimer
7171
MainGrid % main 'uix.GridFlex' object
7272
ExpGrid % top 'uix.Grid' object; child of 'MainGrid'
@@ -92,9 +92,26 @@
9292
end
9393

9494
function obj = SignalsTest(expdef, rig)
95-
%SIGNALSTEST Creates a GUI for testing SignalsExp experiments
96-
% constructor method runs the 'buildUI' method to create the ExpTest
97-
% panel
95+
%EUI.SIGNALSTEST A GUI for testing Signals Experiments
96+
% A GUI for parameterizing and testing exp.SignalsExp Experiments.
97+
% Opens a stimulus window and optionally can live-plot Signals
98+
% updates or display updates in an ExpPanel. Experiments may be
99+
% paused by pressing the <esc> key.
100+
%
101+
% Inputs (optional):
102+
% expdef (char|function_handle): The experiment definition
103+
% function to run. May be a handle, char function name or a
104+
% full path. If empty the user is prompted to select a file.
105+
% rig (struct): A hardware structure to containing configuration
106+
% settings for the test experiment. If empty the mouse is used
107+
% as the primary input device.
108+
%
109+
% Example:
110+
% PsychDebugWindowConfiguration
111+
% e = eui.SignalsTest(@advancedChoiceWorld)
112+
% e.startStopExp(e.ExpRef) % Start experiment
113+
% data = e.startStopExp % Stop experiment and return block struct
114+
%
98115
InitializeMatlabOpenGL
99116
% Check paths file exists
100117
assert(exist('+dat/paths', 'file') == 2, ...
@@ -106,26 +123,28 @@
106123
if nargin > 0 % called with experiment function to run
107124
if ischar(expdef)
108125
% Check function exists
109-
% TODO bump down to warning
110126
assert(exist(expdef, 'file') == 2, ...
111127
'rigbox:eui:SignalsTest:fileNotFound',...
112128
'File function ''%s.m'' not found.', expdef)
113-
[obj.LastDir, expdefname] = fileparts(which(expdef));
114-
obj.ExpDef = fileFunction(obj.LastDir, expdefname);
129+
% Ensure we get the absolute path of the expdef
130+
[mpath, expdefname] = fileparts(expdef);
131+
if isempty(mpath), mpath = fileparts(which(expdef)); end
132+
obj.ExpDef = fullfile(mpath, [expdefname '.m']);
115133
else
116134
obj.ExpDef = expdef;
117135
expdefname = func2str(expdef);
136+
% If we can't resolve the function name, use generic title
137+
if isempty(expdefname), expdefname = 'Signals Test'; end
118138
end
119139
else
120140
% Prompt for experiment definition
121-
[mfile, mpath] = uigetfile(...
141+
[obj.ExpDef, mpath] = uigetfile(...
122142
'*.m', 'Select the experiment definition function', obj.LastDir);
123-
if mfile == 0
143+
if obj.ExpDef == 0
124144
return
125145
end
126146
obj.LastDir = mpath;
127-
[~, expdefname] = fileparts(mfile);
128-
obj.ExpDef = fileFunction(mpath, mfile);
147+
[~, expdefname] = fileparts(obj.ExpDef);
129148
end
130149

131150
obj.buildUI % Build the GUI
@@ -200,8 +219,24 @@ function paramProfileChanged(obj, src, ~)
200219
end
201220

202221
function setOptions(obj, ~, ~)
203-
% callback for 'Options' button: sets options for running the Exp Def:
204-
% 1) yes/no for live-plotting; 2) yes/no for saving a block file
222+
% SETOPTIONS callback for 'Options' button
223+
% Sets various parameters related to monitering the experiment.
224+
%
225+
% Options:
226+
% Plot Signals (off): Plot all events, input and output Signals
227+
% against time in a separate figure. Clicking on each subplot
228+
% will cycle through the plotting styles.
229+
% Show experiment panel (on): Instantiate an eui.SignalsExpPanel
230+
% for monitoring the experiment updates. The ExpPanelFun
231+
% parameter defines a custom ExpPanel function to display. NB:
232+
% Unlike in MC, the comments box is hidden.
233+
% View PTB window as single screen (off): When true, the default
234+
% setting of the window simulates a 4:3 aspect ratio screen.
235+
% Post new parameters on edit (off): When true, whenever a
236+
% parameter is edited while the experiment is running, the
237+
% parameter Signals immediately update.
238+
%
239+
% See also SIG.TEST.TIMEPLOT, EUI.SIGNALSEXPPANEL
205240

206241
[~,~,w] = distribute(pick(groot, 'ScreenSize'));
207242
% getnicedialoglocation_for_newid([300 250], 'pixels')
@@ -215,7 +250,7 @@ function setOptions(obj, ~, ~)
215250
'TooltipString', 'Display an experiment panel', ...
216251
'String', 'Show experiment panel', 'Value', logical(obj.ShowExpPanel));
217252
SingleScreenCheck = uicontrol('Parent', dCheckBox, 'Style', 'checkbox',...
218-
'String', 'View PTB Window as Single Screen', ...
253+
'String', 'View PTB window as single screen', ...
219254
'TooltipString', 'Simuluate a single screen monitor', ...
220255
'Value', logical(obj.SingleScreen), 'Enable', 'off');
221256
parslist = obj.Listeners(arrayfun(@(o)isa(o.Source{1}, 'eui.ParamEditor'), obj.Listeners));
@@ -279,8 +314,17 @@ function setOptions(obj, ~, ~)
279314
end
280315

281316
function startStopExp(obj, varargin)
282-
% callback for 'Start/Stop' button:
283-
% stops experiment if running, and starts experiment if not running
317+
% STARTSTOPEXP Callback for 'Start/Stop' button
318+
% Stops experiment if running, and starts experiment if not
319+
% running. Inputs passed to exp.SignalsExp/run or
320+
% exp.SignalsExp/quit depending on the state.
321+
%
322+
% Input:
323+
% expRef | immediately : When IsRunning == false, the experiment
324+
% reference string. Otherwise, a flag for whether to abort the
325+
% experiment.
326+
%
327+
% See also EXP.SIGNALSEXP/RUN, EXP.SIGNALSEXP/QUIT
284328

285329
if obj.IsRunning
286330
% Stop experiment
@@ -471,11 +515,7 @@ function init(obj)
471515
obj.Hardware.stimWindow.open();
472516
end
473517
p = obj.ParamEditor.Parameters.Struct;
474-
if strcmp(func2str(obj.ExpDef), 'fileFunction/call')
475-
p.defFunction = fullfile(obj.LastDir, [obj.Parent.Name, '.m']);
476-
else
477-
p.defFunction = obj.ExpDef;
478-
end
518+
p.defFunction = obj.ExpDef;
479519
delete(obj.Experiment) % delete previous experiment
480520
obj.Experiment = exp.test.Signals(p, obj.Hardware, true); % create new SignalsExp object
481521

@@ -567,7 +607,8 @@ function setExpDef(obj)
567607
% gets and sets signals expDef
568608
[mfile, mpath] = uigetfile('*.m', 'Select Exp Def', obj.LastDir);
569609
if ~mfile, return; end
570-
obj.ExpDef = fileFunction(mpath, mfile);
610+
obj.ExpDef = fullfile(mpath, mfile);
611+
obj.LastDir = mpath;
571612
obj.Parent.Name = mfile(1:end-2);
572613
obj.loadParameters('<defaults>');
573614
end
@@ -632,11 +673,7 @@ function saveParamProfile(obj)
632673
if doSave % Going ahead with save
633674
p = obj.ParamEditor.Parameters.Struct;
634675
% Restore defFunction parameter
635-
if strcmp(func2str(obj.ExpDef), 'fileFunction/call')
636-
p.defFunction = fullfile(obj.LastDir, [obj.Parent.Name, '.m']);
637-
else
638-
p.defFunction = obj.ExpDef;
639-
end
676+
p.defFunction = obj.ExpDef;
640677
dat.saveParamProfile('custom', validName, p); % Save
641678
%add the profile to the control options
642679
profiles = obj.ParameterSets.Option;

docs/html/ParamEditor.PNG

26 KB
Loading

docs/html/expPanel.PNG

18.5 KB
Loading

0 commit comments

Comments
 (0)