11classdef (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
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
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'
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 , ...
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 ;
0 commit comments