Parameter Definitions

Good PXL programs are adaptable to different experimental questions. This is done by setting up a program's parameter file which ultimately defines which of the available parameters correspond to the independent, the dependent and the control variables of the experiment. This chapter describes the grammar of a PXL parameter file. The parameter file completely controls each experimental session. It defines the values of global experimental variables, specifies which of the variables may be local to a block or a single trial and gives the complete sequence of blocks and trials including the values of the local parameters.

The Parameter File Structure

Each parameter file has three sections: (1) the variable assignment section, (2) the block and trial argument definitions section and (3) the block and trial list section. Each section is introduced by a keyword: var, arg, and stimuli and the whole file is closed by the keyword end. Thus the over all structure of a parameter file looks like the following sequence:
   var
     dsptime = 300
     ...
     /* here are some more assignments */
     ...
   arg
     block(blockstate, training)
     trial(stimulus, response, dspstate)

   stimuli
     block(0, ON) {
       trial(100, ?, ?)
       trial(200, ?, ?)
       ...
       trial(400, ?, ?)
     }
     ...
     /* here may be some more blocks */
     ...
   end

Global Assignments

The variable assignment section is introduced by the keyword var. It contains global assignments to experimental variables. The values assigned in this section are global in the sense that they constitute defaults for any local copies of the respective variables.

Local Variables in Blocks and Trials

Nonglobal copies of a variable are created during run time by including the variable into the block or trial arguments list in the arguments section. This section is introduced by the keyword arg. It always contains two statements. One defines the block arguments and one defines the trial arguments. Creating a block or trial variable automatically creates a local copy of the respective variable at run time. However, it is up to the application to decide whether the global or the local copy of a variable's value is used at a certain point in time. Some applications may force certain variables to be trial or block variables. In this case the application will return a fatal error message if the user does not include the variable into the block or trial arguments list.

The List of Blocks and Trials

The list of block and trial arguments in the arg section is used to parse the block and trial calls in the stimuli section. Each value in the call of block or trial is assigned to the local copy of that variable having the same position in the arguments list as the respective value in the call. In the above example of a parameter file section of a block has two arguments, local copies of the variables blockstate and training. The block call in the example assigns the value 0 to the local copy of blockstate and the value ON to the local copy of training. A trial in this example creates three local variables: stimulus, response, and dspstate. The first call of a trial in the first block assigns the value 100 to stimulus. The local values of response and dspstate are not given in the parameter file, since they may not be set until the subject actually has responded. Thus we use a question mark ? as a placeholder for the values of response and dspstate in the call to trial.

Variables

The following sections give a detailed description of the PXL parameter definition language. We start out with the syntax and then look at the meaning of the special features of PXL's input grammar. The variables of an application are defined in the program code of the application. This includes the variable's name and its type. The first character of a variable name has to be a character or an underscore. The following characters may be letters, underscores, or digits. Variable names are case sensitive and may have arbitrary length. There are three types of variables: floating point, integer, and string variables. The variable assignment section may contain assignments of expression values to variables. An expression value that is assigned to a variable must have the same type as the variable. The type of a variable is defined in the program code and not visible in the definitions file. The following names are reserved keywords and must not be used as variable names: arg, B, block, end, FALSE, from, OFF, ON, startup, step, stimuli, T, trial, to, TRUE, and var.

Expressions

Expressions may be given in different ways. Simple expressions evaluate to a simple constant of type integer, floating point or string. A range expressions is a list of simple expressions with the same type. There are several ways to specify a range expression.

Simple Expressions

The most primitive simple expression is a constant. Integer constants are given as integer numbers like 3 or 3256. Floating point constants have to contain a decimal point like 1.2 or 512.0. Any numeric constant must have a digit or a period as its first character. Thus .2also is a legal floating point constant. String constants are given by enclosing a sequence of characters in double quotes like "This is a legal string constant". The standard C language escape sequences shown in Table escape may be used to embed nonprintable ASCII characters into a string constant.


Insert Table escape here.

Numeric constants may be used to build simple numeric expressions by using the binary operators +, -, *, and /. The unary operator - may be used to invert the sign of a numeric expression. Braces "(" and ")" may be used to group subexpressions. Type mixtures are not allowed within an expression. Here are some examples of legal simple numeric expressions: -1, 3 * 5 - 20, 1.5/2. Some named integer constants are known to any program: ON = 1, OFF = 0, TRUE = 1, and FALSE = 0.

Range Expressions

Simple expressions may be used to build range expressions that contain a list of simple expressions. Ranges may be defined by enclosing a list of simple expressions in brackets: [1, 4, 5, 7] is a range expression of type integer. Strings may also be used to create range expressions: ["Tomorrow", "Today", "Yesterday"] is a range expression of type string. Numeric ranges may also be specified by using the keywords from, to, and step. Thus the ranges [1, 3, 5, 7] and from 1 to 7 step 2 are identical. The step size is optional and if it is missing is assumed to be equal to 1 in integer ranges or equal to 1.0 in floating point ranges. Here are some examples for numeric ranges:
    from 0.0 to 12.0 step 12.0/(7.0 - 1.0)
    from 100 to 0 step - 10
    from 4.0/2.0 to 8.0/2.0.
The last example is equivalent to [2.0, 3.0, 4.0].

The question mark ? has a special meaning. It must not be used in assignments but may be used in actual block and trial argument lists to indicate that the value of the corresponding variable is to be taken from a previous assignment or a program default. The question mark may also be used as a place holder for those variables in trial and block argument lists that are set during the execution of the experiment or the computation of the results.

Assignments

Constant expressions may be assigned to variables. The equals sign = is used for assignments:
   dsptime = 800
sets the variable dsptime to the value 800. In this case dsptime has to be an integer variable. Assigning an expression to a variable of a different type is not allowed, since no type conversion is done. Ranges of the respective type may also be assigned to variables:
   dspcount = [1, 2, 3, 4, 5]
assigns the range [1, 2, 3, 4, 5] to the variable dspcount. It is not allowed to assign the question mark ? to a variable. An alternative way to do the above assignment is to say
   dspcount = from 1 to 5
since both ways to specify a range are equivalent.

As mentioned in the introduction to this chapter, calling a block or a trial in the stimulus section of the input file constitutes an implicit assignment of an expression value to a local variable (call by value). Thus any expression that may be assigned to a variable may also be used as an argument at the same variable's position in the argument list of a block or a trial. In addition to that, actual calls of block or trial may also contain the question mark. The implied meaning of the question mark in an actual argument list is that the variable's local copy will be set to the global copy's value at run time. Thus although the empty question mark's type is unknown, no variable may ever have an unknown type of value, but always has a default value with the appropriate type. The default values usually are determined by the application's program code.

Run Time Expansions

In many experiments the single trials are very similar. It may be necessary to use several variables to exactly describe one single trial, but there may be groups of trials that differ only by a single variable's value. Often trials have to be repeated identically to get relative frequencies of some responses. In these cases it would be very unconvenient to explicitly specify each single trial in the parameter file. Thus PXL provides some shorthand notation for trials that differ only by the value of a small number of variables. The most important means for shorthand notations of this type are the range expressions that lead to an expansion at run time.

Range Expansions

Suppose we have the following trial definition:
   trial(horizontal, vertical, response)
In each trial there is a horizontal line of length horizontal and a vertical line of length vertical. The subject's task is to chose the one that seems to be the longer one of the two. Now suppose we want to use a constant psychometric method to find the horizontal line length that is equivalent to a certain vertical line length. We might say
   trial(80, 100, ?)
   trial(82, 100, ?)
   ...
   trial(96, 100, ?)
to create a list of trials with a constant vertical line length and different values for the horizontal line length. The same list of trials may be created by using a range expression for the local values of horizontal:
   trial(from 80 to 96 step 2, 100, ?)
or equivalently saying
   trial([80, 82, 84, 86, 88, 90, 92, 94, 96], 100, ?)
Thus the run time effect of a range expression in an actual trial argument list is to create a list of trials, one for each range element, such that the range valued variable gets this range element as a value. The other variables get their values from the actual values in the argument list. If there are more than one range expressions in a trial arguments list, then all possible combinations of the range values are created and put into trials. Thus
   trial([80, 84, 88], [100, 104], ?)
is equivalent to writing
   trial(80, 100, ?)
   trial(84, 100, ?)
   trial(88, 100, ?)
   trial(80, 104, ?)
   trial(84, 104, ?)
   trial(88, 104, ?)
Range expressions in a block's actual arguments list are not expanded, neither are range expressions expanded that are assigned to global variables in the var section of a parameter file. However, if a global variable is assigned a range expression and the same variable is in a trial whose actual value is the question mark, then the local copy inherits the global value and thus is expanded.

Trial Copies

Range expressions may be used to create trial lists that differ in at least one variable's value. Very often we need multiple copies of trials that are identical in all independent stimulus variables. Such copies may be created in PXL by using the trial or block multiplication factors dfactor and bfactor. Setting dfactor to a value different from 1 makes PXL create dfactor copies of each trial. These copies are linked into a block's trial list such that they simply replace each original trial list element. Thus writing
   ...
   dfactor = 3
   ...
   ...
   trial(80, 100, ?)
   ...
is equivalent to (but shorter than) writing
   ...
   dfactor = 1
   ...
   ...
   trial(80, 100, ?)
   trial(80, 100, ?)
   trial(80, 100, ?)
   ...
The variable dfactor may be a block variable too. In this case the number of copies created may be different in each block whereas a global value of dfactor affects all trials in the file.

Block Copies

The variable bfactor may be used to create multiple copies of a complete block. There is, however, an additional feature for multiple block copies that makes them more useful than simple copies would be. If bfactor is different from 1, then bfactor copies of each block are created. These blocks initially have the same argument values. During run time, however, after one of these block copies has been executed, its current block arguments are copied into the block arguments of the next copy. Thus suppose there is a block variable called blockstate and there are several copies of each block to be executed. The variable blockstate may be changed during the execution of a block's trials. After execution the next block gets the new value of blockstate as an argument, since the argument list of the executed block is copied forward into the block waiting to be executed. This block may look at blockstate before starting execution and decide on some special actions using the current value of blockstate. This allows for a data dependent behavior of the next block, depending on the data of previous block copies. Special behavior like this, however, has to be supported by the application. The sample application pal in Chapter pal makes use of the block multiplication feature to create multiple copies of a learning list and to use a response dependent stopping rule.

Randomization

The sequence of trials in the parameter file generally defines the sequence that is used for the trials at run time. Many psychological experiments require a randomized sequence. Randomization of a block's trial list may be enabled in PXL by setting the experimental variable randomize to ON:
   randomize = ON
This creates a randomized sequence of all trials within a block and is the default behavior of most PXL programs. Set
   randomize = OFF
in order to prevent a program from randomizing the trial list. Blocks may never be randomized and trials of different blocks never are mixed.

Multiple Sessions

Usually experiments have to run over more than a single session with one and the same subject. Since the complete experiment is to be described in a single parameter file, we need a mechanism to tell the program that a subject has finished only parts of the parameter file. This mechanism is provided by several experimental variables. firstblock is the number of the first block that has to be displayed during a session and lastblock is the number of the last block to be displayed. The maximum number of blocks to be displayed during a session is given by maxblocks. Suppose we have a parameter file that contains six blocks of trials. We want to make three sessions with two blocks during each session. In this case we set

   firstblock = 1
   maxblocks = 2
   contfile = ON
This will result in two blocks a session. The first block of the first session will be block 1. After the first session the program will create a new parameter file that contains the remaining blocks of the original parameter file. This is controlled by the variable contfile. If contfile is ON, a new parameter file will be created containing all blocks that have not yet been displayed. firstblock will again be equal to 1 in the new file, but the first block of the new parameter file will be the third block of the original parameter file. All experimental variables will also be defined in the new parameter file, having the same value as in the original file. contfile = OFF, which is the default, will prevent PXL from creating the continuation file.

Now suppose the subject is ready to run the second session. The PXL program is to be run simply by using almost the same command line used for the first session. This is because the continuation file will get the subject's name using the file extension x. So if the program is started with

   exp john
the continuation file will get john.x as its name. Thus the only difference between the first and any following run is that only the first run my use the option -f for explicitely specifying the parameter file. Each time a PXL program is started it looks at the subject's name and checks the current directory whether there exists a file having the subject name as its root and x as its extension. If such a file exists, then the program will take it as its parameter file for the current session. If such a file does not exist, which is the case for a subject's first session, then the program takes its own command name, appends xand looks for a parameter file which has the resulting name. Thus the default for the above mentioned command line is to look for a parameter file named exp.x.

All this can be overridden by giving an explicit parameter file name using the command line option. Thus the command line

   exp -f par.x john
will force the program exp to use the file par.x as a parameter file, ignoring any other existing files in the current directory.

There is a source for potential confusion in the fact that PXL programs use a default subject name if none is given in the command line. Suppose you have set contfile to ON in your parameter file and you are just testing different parameter values. So you tend to run your program without giving a subject's name. In this case the program will use vp as a subject name. Now if you run the program and there are more blocks in the file than maxblocks requests, there will be a continuation file named vp.x after the run. Now you change your original parameter file and rerun the program. However there will be no change in the behavior of the program, since the parameter file used will be vp.x not your original file. So if you are testing parameter values set contfile to OFF, or make sure that no file named vp.x exists in the current directory.


Back to table of contents


Author: Hans Irtel

irtel@psychologie.uni-mannheim.de