MWorks consists of a suite of three applications: the editor (MWEditor), the client (MWClient), and the server (MWServer).
The editor is used to construct an experiment via a graphical user interface. This is the tool the user will employ to build an experiment from scratch or to modify an existing experiment to fit their goal. The editor is only used to make/modify an experiment; it is not used at all during data collection.
The client provides a graphical user interface to control an experiment (load, run, stop, etc.), alter settings in the experiment (i.e. update the values of MWorks variables), and monitor/plot data flowing out of an experiment (i.e. show or plot the values of MWorks variables). This application need not run on the same machine as the MWServer instance that actually executes the experiment.
The server is the (pseudo) real-time core engine of MWorks. It has a minimal user interface, as it is intended to be controlled by the client. It accepts an experiment from a client instance, assembles the memory structures needed to execute that experiment (state-system, I/O, variables, stimuli, etc.), and executes the experiment, with a goal of keeping as close to real-time performance as possible (within the confines of the operating system).
These three applications are intended to be used as follows:
- Build or edit an experiment using MWEditor
- Use MWClient to tell MWServer to run the experiment. This can be done either on the same machine or remotely over a network interface.
- Use MWClient to watch data flow out of the experiment and control variables, save data files, etc.
After data collection is complete, the data files produced by MWorks can be analyzed offline using standard tools (e.g. Python, MATLAB).
Under the hood, here is what’s happening when the above steps are followed:
As you are using MWEditor, it is creating and editing an XML file that specifies all the experimental components and how they should interact. This XML file and the associated files (e.g. stimulus images) are stored together (they are the MWorks experiment).
When MWClient is invoked to load an experiment, it packages the experiment and sends it to an MWServer instance over a network interface. (MWServer may be running on the local machine or a remote machine.) At that time, MWServer parses the experiment (i.e. reads the XML file and interprets it), creates the memory structures needed to run the experiment, and waits.
When MWClient requests that the experiment be started (“run”), it sends a control event to MWServer. The server then starts executing the experiment and keeps running until either (1) the experiment completes or (2) it receives further instructions from the client (e.g. “stop”, “pause”, etc. requests from the user).
If the user would like to save data, he/she uses MWClient to request that. MWServer responds to that request and begins streaming a new data file to the specified location.
If the user would like to changes settings (MWorks variables) in an experiment, he/she uses one of the MWClient windows to make each such request to the server (e.g. simply by typing the desired value in the appropriate field of the MWClient windows). MWServer updates the MWorks variables to the requested values (all MWorks variable updates are automatically added to the data stream and thus saved in the data file), and the experiment continues to run, but now in the context of those new variable values.
Because they are common to many experiments, some MWorks variables have specific client windows to help make these requests (e.g. “reward”, “calibration”). However, there is nothing intrinsically special about these variables; at the level of MWServer, all variables work exactly the same way.
If the user would like to “see” the data flowing out of the experiment (e.g. eye position, behavioral performance, etc.), he/she uses one of the MWClient windows to plot the values of specified MWorks variables. Several standard windows already exist that allow flexibility in how the user has named his/her variables (e.g. the names of the user’s x and y eye position variables), but it is impossible to anticipate all windows that a user might want. To extend the options here, the user must either (1) use the MATLAB bridge (which allows plotting in user-defined MATLAB windows running on the local machine), or (2) build new MWClient plugin windows (which requires some facility with C++ and Cocoa).
Like all other components of an MWorks experiment, I/O devices are specified in the editor (i.e. their setup is part of the underlying XML file), instantiated by the server when the experiment is loaded, and started/stopped by calls specified by the user in the main body of the experiment. Input data (e.g. eye position signals) flow from the user specified input channel(s) of each I/O device into user-specified MWorks variables, which then flow to the data file and any “listening” client windows. Output data (e.g. reward pulse) flows from user-specified MWorks variables to the user-specified output channel(s) of each I/O device. MWorks currently supports several I/O devices, and supported I/O devices can be added easily by developers as plugins.