Background
To start EPHUS, one must invoke a startup file at the MATLAB command line. The file is a MATLAB function file (i.e., .m extension), located in the current directory or somewhere on the user's MATLAB path. Every user/rig requires a customized startup file.
The best way to create this file is to modify one of the supplied example files, which are constantly maintained on this site. The examples cover all of the major applications of EPHUS known to the developers at the present time. Startup files contain both configuration and application information. The vast majority of users only need to adjust the configuration information, which resides in clearly demarcated sections at the beginning of the startup file.
This guide steps through a typical startup file, which follows the most current conventions. For completeness, both the configuration and application sections are described. Only power-users, however, should modify the application sections, and limited support can be provided for such uses.
The 'Specimen'
Time to dissect!
Download the specimen ('gephus.m')
Download the specimen ('gephus.m')
The Ventral View (Configuration)
All the parts of the startup file that the typical user must interact with – the configuration sections – are conveniently located at the top of the file.
The Head
Here's the beginning of our startup file 'specimen':
function gephus %% STARTUP BOILERPLATE %Set up a wait bar to show the progress. wb = waitbarWithCancel(0, 'Starting ephus...', 'Name', 'Loading software...'); pos = get(wb, 'Position'); pos(2) = pos(2) - pos(4); set(wb, 'Position', pos);
This section contains the function declaration, where the name of the startup file should be supplied – in this case, 'gephus'. For user-specific startup files, this should be modified to match the custom-named file (although MATLAB ignores this, and employs the filename as the function name, regardless).
The next section (%%Startup Boilerplate) should not be modified, as the name implies. This section contains the code that is common to all startup files.
The double-parenthesis(%%) signifies a MATLAB M-file cell. They are used throughout the startup file to help clearly demarcate the different file sections, when viewed in the MATLAB editor.
Device/Channel Configuration
This section contains the configuration information for each of the devices & channels connected to this installation of EPHUS:
%% DEVICE/CHANNEL CONFIGURATION %Amplifier objects for ephys patch{1} = multi_clamp('text_file_location', 'C:\MATLAB6p1\work\Physiology\MClamp700BChannel1.txt', 'scaledOutputBoardID', 1, 'scaledOutputChannelID', 0, ... 'vComBoardID', 1, 'vComChannelID', 0, 'channel', 1, 'name', '700B-1'); patch{2} = multi_clamp('text_file_location', 'C:\MATLAB6p1\work\Physiology\MClamp700BChannel2.txt', 'scaledOutputBoardID', 1, 'scaledOutputChannelID', 4, ... 'vComBoardID', 1, 'vComChannelID', 1, 'channel', 2, 'name', '700B-2'); %Acquirer channels acqChannelNames = {'photodiode1'}; acqBoardIDs = [2]; acqChanIDs = [0]; %Stimulator channels stimChannelNames = {'pockelsCell' 'shutter0' 'xMirror' 'yMirror' 'shutter1' 'ao5' 'ao6' 'ao7'}; stimBoardIDs = [3 3 3 3 3 3 3 3]; stimChanIDs = [0 1 2 3 4 5 6 7];
Devices
EPHUS programs sometimes employ specialized devices, which are implemented as MATLAB objects. In this case, for instance, the ephys program employs amplifier objects. All objects require a constructor in order to be created – this is a function which must be called and typically consists of several arguments initializing the particular object's properties. In EPHUS, all devices must be 'constructed' upon startup, and presumed to exist 'forever' (until EPHUS is closed).
In this case, the multi_clamp function calls create a particular type of amplifier – this refers to the MultiClamp 700B patch-clamp amplifier from Axon Instruments. The multi_clamp object definition is a 'class' (or, technically, a 'subclass') of amplifier. Another amplifier class that could be (but isn't) constructed here, is an axopatch200B, referring to the Axopatch 200B instrument, also from Axon Instruments.
The Device Constructors page documents the syntax for the various devices presently supported by EPHUS, such as the MultiClamp 700B and Axopatch 200B.
Channels
EPHUS contains two programs – acquirer and stimulator – which are included in virtually every EPHUS deployment. These programs allow a number of National Instruments A/D, D/A, and buffered digital output channels to be user-defined and controlled. As with devices, the channels must be configured on EPHUS startup, and persist until EPHUS is closed (it is presumed that users are not re-connecting signals during an experiment!).
For A/D channels, handled by the acquirer, three variables must be entered: acqChannelNames, acqBoardIDs, acqChanIDs. The variable acqChannelNames is a MATLAB cell array, while acqBoardIDs and acqChanIDs are numeric arrays of integers. Each of the arrays is a 'row vector' of the same length.
- acqChannelNames: A cell array of strings specifying descriptive names for each of the A/D channels.
- acqBoardIDs: An array of integers specifying the numeric indices of the National Instruments (NI) boards associated with each of the named channels in acqChannelNames. The Board IDs are defined in the NI Measurement and Automation Explorer program included with the DAQmx driver. The NI convention is that boards are named 'Dev#', i.e. 'Dev1', 'Dev2', etc. EPHUS presumes this convention is followed, and the BoardID refers to the number following 'Dev'.
- acqChanIDs: An array of integers specifying the A/D channel indices corresponding to each of the named channels in acqChannelNames. Different boards have differing numbers of supported A/D indices. Channel indices for NI begin with 0.
The D/A channels are specified to initialize the stimulator in a similar fashion, with the variables stimChannelNames, stimBoardIDs, and stimChanIDs.
The ability to add digital stimulator channels is currently being tested. These allow the 'correlated DIO' lines (lines contained buffered data scheduled for timed playback) feature available on some NI boards to be employed for outputting digital pulse train signals. This can help reduce the required number of D/A channels. This will be documented once this feature has been fully tested
Configuration Variables
The next section contains configuration variables that can/should be modified by the user. In our sample file, we see:
%% CONFIGURATION VARIABLES triggerOrigin = '/dev1/port0/line0'; %Specifies the digital line terminal on which the trigger pulse is output at the start of each acquisition triggerDest = 'PFI0'; %Specifies the digital line terminal on which the trigger pulse is received. On /every/ board, this must be connected to the triggerOrigin terminal xsgStartDirectory = 'C:\Data\'; %Default directory in which to save data files pockelsOn=1; %Logical value specifying whether Pockels Cell is in fact attached/active on %Size, in microns, of the camera FOV (a camera application is required by the mapper program) xVideoScaleFactor = 2625; yVideoScaleFactor = 1980; %% *************************END OF CONFIGURATION***************************************
The number and names of the configuration variables in a startup file will depend on the particular application (as determined by the application sections below). Generally, they should be well-documented via MATLAB comments as seen here.
Some variables appear in virtually all EPHUS deployments. For instance, triggerOrigin and triggerDest are used in all cases to specify, respectively, the digital line on which the trigger pulse for each acquisition is output and the terminal on which each board expects to receive this trigger signal, ensuring all boards begin acquisition at the same moment.
The end of this section is marked as the 'END OF CONFIGURATION'. That's all that most users need to stomach.
The Dorsal View (Application)
For those with a strong stomach, let's look at the 'other side' of the startup file – the application sections.
The application sections are only intended for modification by developers and power-users. This documentation is provided for informational purposes only.
The application sections of the startup file are less bound to convention, and hence are more likely to not be completely and/or correctly described by this documentation.
Timing/Clock Setup
This section initializes daqjob objects used by the various programs and handles the configuration of trigger and clock functions on the DAQ boards. This section makes use of daqjob, and in some cases nimex, class method calls.
For this file, we can see that the only task required is to configure the start trigger input and output lines:
%% TIMING/CLOCK SETUP %Set up the triggering. acqJob = daqjob('acquisition'); scopeJob = daqjob('scope'); setTriggerOrigin(acqJob, triggerOrigin); setTriggerOrigin(scopeJob, triggerOrigin); setTriggerDestination(acqJob, triggerDest); setTriggerDestination(scopeJob, triggerDest);
Program Startup
This section starts each of the EPHUS programs needed for this particular application. In addition, the programs are sometimes configured further following their initialization.
Here, we can see the programs which are opened by this startup file:
%% PROGRAM STARTUP if waitbarUpdate(0.0, wb, 'Starting experimentSavingGui...'); return; end xsg = openprogram(progmanager,{'xsg', 'experimentSavingGui'}); setLocalBatch(progmanager, xsg, 'directory',xsgStartDirectory); if waitbarUpdate(0.1, wb, 'Starting ephys...'); return; end ep = openprogram(progmanager,'ephys',patch); if waitbarUpdate(0.16, wb, 'Starting ephysScopeAccessory...'); return; end openprogram(progmanager,'ephysScopeAccessory',patch); if waitbarUpdate(0.24, wb, 'Starting stimulator...'); return; end stim = openprogram(progmanager, 'stimulator'); stim_addChannels(stim,stimChannelNames,stimBoardIDs,stimChanIDs); if waitbarUpdate(0.32, wb, 'Starting acquirer...');return;end acq = openprogram(progmanager,'acquirer'); acq_addChannels(acq,acqChannelNames,acqBoardIDs,acqChanIDs); if waitbarUpdate(0.48, wb, 'Starting pulseJacker...');return;end openprogram(progmanager, 'pulseJacker',{ep,stim}); if waitbarUpdate(0.52, wb, 'Starting userFcns...');return;end openprogram(progmanager, 'userFcns'); if waitbarUpdate(0.56, wb, 'Starting autonotes...');return;end openprogram(progmanager, 'autonotes'); if waitbarUpdate(0.60, wb, 'Starting headerGui...');return;end openprogram(progmanager, 'headerGUI'); if waitbarUpdate(0.64, wb, 'Starting HotSwitch...');return;end openprogram(progmanager,{'hotswitch', 'hotswitch', 'hotswitch', 'hs_config', 'hs_config'}); if waitbarUpdate(.68, wb, 'Starting photodiode configuration...');return;end pdiodeConfig = openprogram(progmanager, {'photodiode' 'photodiodeConfiguration'},'photodiode1'); end if waitbarUpdate(0.76, wb, 'Starting mapper...');return;end if pockelsOn mapper = openprogram(progmanager, 'mapper','xMirror','yMirror','pockelsCell','shutter0',pdiodeConfig); else %Don't associate either Pockels or Photodiode channel with mapper, if Pockels is not used mapper = openprogram(progmanager, 'mapper','xMirror','yMirror','','shutter0'); end setLocalBatch(progmanager, mapper, 'xVideoScaleFactor', xVideoScaleFactor, 'yVideoScaleFactor', xVideoScaleFactor);
'Constructing' programs with openprogram()
Each of the programs is opened by invoking openprogram(), which is a method of the Program Manager (@progmanager) class that is central to EPHUS.
The syntax for openprogram() is:
hProg = openprogram(progmanager,programName OR programInfo,constructorArg1, constructorArg2, ...)
Let's step through the arguments:
- hProg: An instance of a @program object, which can be regarded as a handle to the program.
- progmanager: The (singleton) @progmanager object – this can be obtained by simply calling the progmanager() function as shown here
- programName: For typical programs, this argument is used, specifying the name of the program to start. The program names are those in the <EPHUS>\Programs directory of the installation. The program's figure will have the same title as the name.
- programInfo: A cell array can be supplied instead of a simple string. This can be used for two purposes.
- A two-element cell array can be used to display the program GUI with a different title than the program name. Note that the alias 'xsg' is supplied before the actual program in the array.
- For programs which contain multiple GUIs (noted as such in EPHUS Programs), the cell array programInfo option must be used. For legacy reasons, both the first and second elements should be the program's alias, while the third element should be the actual program name (i.e. the M-file in <EPHUS>\Programs). Thereafter, elements are added in pairs; the first is the sub-gui's alias and the second is the sub-gui's actual name (an M filename found in the same directory as the main program M file).
- constructorArg#: Many programs have required (and/or optional) arguments that must be (or are typically) supplied upon invoking the program. These can be considered the constructor arguments of the program (the programs can be considered as class definitions, though they're technically not). The required arguments for each program are documented in EPHUS Programs.
For our current example, most calls to openprogram() employ the simple programName argument, but the programInfo cell array argument is employed for the experimentSavingGUI and the hotswitch programs. For the experimentSavingGui, the alias 'xsg' is specified for the program. For the hotswitch program, the main GUI/program as well as its reqired sub-gui, 'hs_config', is launched. In this case, both the main and sub-GUI use the same title as their corresponding M files – hence the names are repeated in the cell array.
Several programs in our example require 'constructor' arguments. One example is the mapper. As documented in EPHUS Programs, the mapper requires that the names of channels be provided corresponding to the X Mirror, Y Mirror, Pockels Cell, and shutter signals that it controls. These channels must have been designated for addition to the stimulator in the Channel/Device Configuration section. The Pockels Cell control can be deactivated by entering a blank channel name. The mapper constructor also takes an optional argument, which must be a program 'handle' for an instance of the photodiodeConfiguration program. That program itself is associated with an acquirer channel for the photodiode signal.
The 'constructor' for every program is the genericStartFcn() function that is contained within every program's main M file (i.e. the file with the name as the program).
Setting program properties
The 'constructor' arguments provide the necessary (or highly typical) information required to initialize a program in a manner consistent with the configuration information supplied in the startup file. Occasionally, it may be useful to configure additional properties of the program upon startup. The names of properties for given programs can be found by inspecting the makeGlobalCellArray() function found within each program's main M file. To set the values of these properties, one uses the setLocal() and setLocalBatch() methods of the Program Manager. The syntax for the latter is:
setLocalBatch(progmanager,programHandle,'Property Name 1',Property Value 1, 'Property Name 2', Property Value 2, ...)
As with openprogram(), the function progmanager() should simply be supplied for the first argument. The second argument, the programHandle refers to the object variable returned by openprogram(). Where setLocal() and setLocalBatch() are required, the handle returned by openprogram() must be saved to a local variable of the startup file.
Subsequent arguments are property/value pairs. The valid type(s) (i.e. numeric, string, etc) for each property can be determined from inspecting the makeGlobalCellArray() function of each program's main M file, and should be adhered to. The setLocal() function functions identically to the setLocalBatch() function, but only allows one property/value pair to be specified.
Most of the configurable properties of programs can be set via the program's GUI and then stored by saving the program's configuration. Thus, few properties are ever set via the startup file. Nonetheless, the ability to set program properties textually via the startup file is an important facility. For example, some program properties are infrequently changed; in this case, adding GUI control of the property would add unnecessary clutter. Another case is when implementing/testing new features. It may make sense to activate/configure the feature by setting newly created properties in the text file, without affecting the program's GUI(s).
In our example, the default XSG save directory is set via the experimentSavingGui's 'directory' property, and simply passes through the xsgSaveDirectory variable set in the Configuration Variables section of the startup file described above. The same is true of the 'x/yVideoScaleFactor' properties for the mapper. Each of these properties is not apt to change frequently for a given user/rig, and are hence set here in the startup file.
Adding and removing programs
Startup files designed for different EPHUS applications will employ different sets of programs. In many cases, one can simply remove (or add) programs from the list in the Program Startup section. Caution is required, however, because some programs assume that other programs have been started. For instance, the mapper assumes the stimulator has been started. In some cases, a program may requires program handles as a constructor argument; here, the pulseJacker is bound to the previously created ephys and stimulator program handles.
Generally, model startup files conservatively assume that all possible programs for an application will be used. This will cause several program windows to launch. However the user can close unneeded windows and save a configuration set accordingly to hide them. Thus, modification of the startup file is not really necessary.
UserFcn Bindings
In this section, various user functions (also referred to as 'callbacks') are 'registered' to respond to events generated by programs:
%% USERFCN BINDINGS
if waitbarUpdate(0.84, wb, 'Setting up default (built-in) userFcns...');return;end
userFcnCBM = getUserFcnCBM;
fprintf(1, 'Default UserFcn mappings:\n');
%userFcns for LSPS/mapping customization
addCallback(userFcnCBM, 'xsg:NewCell', @mapper_newCell_userFcn, 'userFcns_mapper_newCell_userFcn','verbose');
addCallback(userFcnCBM, 'ephys:SamplesAcquired', @mapper_userFcn_ephysSamplesAcquired_display, 'userFcns_mapper_userFcn_ephysSamplesAcquired_display','verbose');
addCallback(userFcnCBM, 'ephys:SamplesAcquired', @mapper_userFcn_ephysSamplesAcquired_updateMirrorPosition, 'userFcns_mapper_userFcn_ephysSamplesAcquired_updateMirrorPosition','verbose');
addCallback(userFcnCBM, 'mapper:MapStart', @mapper_userFcn_mapStart_display, 'userFcns_mapper_userFcn_mapStart_display','verbose');
addCallback(userFcnCBM, 'mapper:MapStop', @mapper_userFcn_mapStop_display, 'userFcns_mapper_userFcn_mapStop_display','verbose');
addCallback(userFcnCBM, 'mapper:MouseStart', @mapper_userFcn_mouseStart_updateMirrorPosition, 'userFcns_mapper_userFcn_mouseStart_updateMirrorPosition','verbose');
addCallback(userFcnCBM, 'mapper:PreGrabVideo', @loadImage4Mapper, 'userFcns_loadImage4Mapper','verbose');
addCallback(userFcnCBM, 'mapper:PostGrabVideo', @unloadImage4Mapper, 'userFcns_unloadImage4Mapper','verbose');
fprintf(1, '----------------------------\n');
Bindings of events to user functions (callbacks) are maintained by a data object called a callbackmanager. EPHUS maintains a single callbackmanager for user function bindings – the 'UserFcnCBM'. This section of the startup file is reserved for registering 'user' functions which have in fact been created by developers. The user functions developed can contain critical functionality for particular programs. For example, the mapper_userFcn_ephysSamplesAcquired function, developed as a part of the mapper, is associated with an ephys program event ('SamplesAcquired').
These developer-specified 'user' functions will appear in the userFcns GUI, alongside any 'true' user functions developed by the user for the purpose of customizing EPHUS. Such user function bindings can be stored as part of the userFcns configuration, without requiring modification of the startup file.
The Tail
As with the beginning, the final section contains code common to all EPHUS startup files and should not be modified. In particular, upon opening & initialization of all the programs, the user is prompted to load their desired configuration set folder:
%% ENDING BOILERPLATE
%Load a configuration (if requested).
if waitbarUpdate(0.88, wb, 'Loading configuration...');return;end
loadConfigurations(progmanager);
fprintf(1, '\nLoading Completed.\n\n');
delete(wb); %Kill the waitbar.
fprintf(1, '\n\n----------------------------------\n----------------------------------\n\n\n\n\n\n\n\n');
Final Comments
Let's summarize what we've learned during this 'laboratory':
- Startup file contain a mixture of configuration and application information.
- Most users should select an appropriate model startup file for their application, and modify only the configuration sections as needed for their particular rig/use.
The combination of configuration and application information into scripts that are executed is a common approach for adapatable programming. An example of this is LabView. In LabView, 'VI' files generally contain information about the hardware to use as well as the functions to perform with them. They may also contain constants that are not exposed to the VI's 'front panel'. Combinations of hardware/functionality/constants are generally distributed as model VIs; model EPHUS startup files are similar. In EPHUS, the program GUIs represent the 'front panel' and are quite flexible in that GUI settings can be captured into 'configuration sets' which are saved. Unlike LabView, EPHUS is not designed as a user programming environment, so that the application sections of startup files are not typically modified.
Finally, it is stressed that users should pay attention to the latest version that model startup files have been tested with (which will always be noted). As the underlying EPHUS code evolves, occasionally startup files may not function properly with newer versions. Startup file models will be regularly updated to be current, but may lag EPHUS updates for some applications.