-
Notifications
You must be signed in to change notification settings - Fork 0
Protocols
Example protocol files can be found in config/experiment_protocols. If you want to check the output of your .stim file, you can do so through StimControl through the top bar menu. Tools -> Check Stimulus will load a file and check the validity of each trial within the file. You can click through each trial to see a summary, which will include an error description if the trial is invalid, and plot it using the "Plot" button, or deselect the trials and click "Plot All" to see plots of every trial in the file.
The preview will appear as shown below. The top graph shows the structure of the parsed tree, and can be largely ignored unless something has gone seriously wrong. The bottom graph shows the estimated outputs as they should appear on the DAQ (with the exception of QST commands, which will appear as they will be output from the QST device, not as the triggers that will actually be output from the DAQ)

A protocol file has 3 sections, separated by a ~ operator on a new line:
You can add comments to a protocol file using the % operator. Comments in the trial information section will be displayed during the experiment.
The general section takes up the first non-comment line. It accepts the following arguments:
| Command | Explanation |
|---|---|
| nProtRunsX | number of times the protocol runs (including the first) - defaults to 1 |
| RandomiseX | how to randomise trials |
| dPauseX | time (ms) between trials in the protocol |
| nTrialRunsX | (optional) change the default number of times each stimulus line is run for each protocol |
| tPreX | (optional) change the default time to record before starting stimuli for each protocol |
| tPostOnsetX | (optional) change the default time to record after the stimulus onset for each protocol. tPost is also accepted with identical syntax, but only one should be defined. |
| PrePauseX | (optional) whether to preload trials at the start of dPause, and to pause before the start of trial 1 (useful for, e.g. setting a baseline temperature for a serial device) |
| Intro | Stimulus Blocks | Sequential Execution | Oddballs |
Each line in this section is a trial, which comprises a series of stimulus blocks. These should be treated like function calls, where the functions are defined in Stimulus definitions.
Stimulus blocks have relationships with one another defined by their connectors, and can be separated and nested using brackets. Stimulus blocks should only ever contain a single relationship (either & (simultaneous), > (sequential), or ^.X (oddball), with additional relationships | and |> permitted for oddballs). Relationships within nested blocks, however, are permitted. For example,
(StimA & (StimB > StimC))
is a valid paradigm, but
(StimA & StimB > StimC)
is not.
Once per trial, you can optionally define the following:
| Command | Explanation |
|---|---|
| nTrialRunsX | (optional) number of times this trial is run for each protocol |
| tPreX | (optional) number of ms to record before stimulus onset |
| tPostOnsetX | (optional) number of ms to record after stimulus onset. tPostX is accepted as equivalent. |
A stimulus block is a group of stimuli, and can be used to construct more complex stimulation protocols. In each stimulus block, the following keywords can be defined exactly once:
| Command | Explanation |
|---|---|
| repDelXXXX | Delay between repeats in ms. Default 0. |
| startDelXXXX | Start delay from stimulus t=0 |
| nStimsX | Number of times the stimulus / stim block is run within a trial. Default 1. -1 will make the stimulus repeat until the end of tPost. |
To construct a set of stimuli that occur simultaneously, use the & operator.
e.g. StimA & StimB nStims2 repDel1000
StimA |*__|*_
StimB |**_|**
(note that the repeat delay happens after the conclusion of the longest stim,
and by default does not occur at the end of the trial)
To build more complex patterns of stimuli, use bracket notation. Functions in brackets are built independently from the middle out.
e.g. (StimA nStims3 repDel1000)(StimB & StimC nStims2 repDel1000)
StimA |*_|*_|*
StimB |**_|**_
StimC |*__|*__
(note that because B and C are within the same bracket block, they have the same t=0 for repeats)
To build a sequence of stimuli, use the > operator
e.g. (StimA nStims2 repDel1000) > StimB
StimA |*_|*___
StimB |____|**
or
(StimA nStims2 repDel1000) > (StimB startDel1000)
StimA |*_|*___
StimB |____|_**
(note the startDel operator in the second example)
To construct an oddball trial, use the ^.X operator, which will swap out the first stimulus for the second stimulus X% of the time.
e.g. StimA ^.5 StimB nStims4
StimA|*___|*___
StimB|_|**__|**
gives 4 total stims, defaulting to StimA and swapping it out for StimB after every 1 occurrence.
You can swap in a random selection from a list of stimulus blocks using the | operator, or swap them in sequence using the |> operator
e.g. StimA ^.5 (StimB|StimC) nStims4 repDel1000
StimA|*__|*__
StimB|_|*____
StimC|_____|*
e.g. StimA ^.5 (StimB|>StimC) nStims4 repDel1000
StimA|*__|*__
StimB|_____|*
StimC|_|*____
Oddball stimulus blocks accept the following additional arguments:
| Command | Explanation |
|---|---|
| OddDistrX | distribution method (0=even, 1=random, 2=semirandom) |
| OddMinDistX | (OddDistr3 only) minimum occurrences of baseline between oddball swaps. |
Stimuli are each defined on their own line, and are defined using the syntax:
StimulusName(type)[TargetDevice1, TargetDevice2, ...]: param1 param2 param3
Where:
- StimulusName maps to a StimBlock defined in section 2
- TargetDevice(s) map to device ProtocolIDs
- type is one of:
- And params are defined per type as in the following sections.
Defining a function in this section and not using it is permitted, and will not change the way StimControl interacts with the file. Note however that the longer the file, the longer it will take to parse.
Please Note StimulusNames should be unique. If the protocol file uses any StimulusGroup functionality, names should not contain other names (e.g. if one stimulus is called Light and another is BlueLight, Light should be renamed to AllLight or similar). StimulusGroups work on a pure text replacement basis, and the logic for them is functional but not robust. Having BlueLight and Light defined may lead to unexpected behaviour - the program may try to parse Blue(LightStimGroup) and throw errors where syntax is otherwise valid.
When defaults are given, defining the parameter is optional. By default, stimuli begin after tPre (i.e. at tOnset). Any stimulus can also be given the parameter AcquisitionTrigger, which will make the stimulus start at the beginning of tPre, rather than the beginning of tPostOnset.
Note also that X and x represent digits. X (uppercase) represents an arbitrary number of digits, while x (lowercase) denotes a single digit, and indicates that a precise number of digits is required in the parameter. Decimals are not currently supported.
Recall also that stimulus repeats, delays, and linking with other stimuli are done within Stimulus Blocks. You may also use StimulusGroups to accomplish this for better readability.
| Parameter | Meaning |
|---|---|
| DurX | Pulse duration (ms) -1 = until end of stim |
| PulseAmpX | Pulse amplitude (V) |
| RampOnDurX | Pulse onset ramping dur (ms). Default 0 |
| RampOffDurX | Pulse offset ramping dur (ms). Default 0 |
| BaseAmpX | Amplitude to pulse from (V). Default 0 |
| Parameter | Meaning |
|---|---|
| File:FileName | Name of the file to read. Files should comprise a comma-separated list of values. |
| InterpX | Whether to interpolate values (1=true 0=false). Default 0. |
| DurX | Duration (ms) -1 = until end of available duration. |
| If InterpX is set to 0 and the number of values in the file is not equal to the number of ticks in the set duration, the stimulus will be cut off at the end of the set duration |
| Parameter | Meaning |
|---|---|
| DurX | duration (ms) -1=until end of stim |
| FromEndX | effectively whether to reverse this stimulus within its block. 0=false, 1=true. Default 0. |
| FromEndX is intended for use with 'acquisition end' triggers. |
| Parameter | Meaning |
|---|---|
| PWX | Pulse width (ms). Default 50% of period. |
| FreqX | Frequency (Hz) |
| DurX | Signal duration (ms) -1 = until end of available duration. |
| Parameter | Meaning |
|---|---|
| DurX | duration (ms) -1=until end of stim |
| Outputs 0 for the duration. |
| Parameter | Meaning |
|---|---|
| DurX | duration (ms) -1 = until end of available duration. |
| DistrX | distribution type (1=uniform, 2=normal) |
| MinAmpX | minimum amplitude (V) |
| MaxAmpX | maximum amplitude (V) |
| Parameter | Meaning |
|---|---|
| DurX | pulse duration (ms) |
| FreqX | pulse frequency (ms) |
| StimNumX | stimulation number |
| AmpX | Max amplitude. |
| RampX | Signal ramp. Default 20 |
| nStimsX | number of stims |
| Note that piezo is a legacy implementation of analog pulse with sensible | |
| defaults. In general, AnalogPulse should be used instead. |
| Parameter | Meaning |
|---|---|
| DCX | Duty cycle (%) |
| FreqX | Pulse frequency (Hz) |
| DurX | Signal duration (ms) -1 = until end of available duration. |
| RampOnDurX | Duration of any up ramp (ms). Takes place within Dur. Default 0 |
| RampOffDurX | Duration of any down ramp (ms) Takes place within Dur. Default 0 |
| Parameter | Meaning |
|---|---|
| Nxxx | Set neutral temperature in 1/10 °C (xxx = 200-400) |
| Sxxxxx | Enable/disable area 1 to 5 (x=0: disable, x=1: enable) |
| Cxxx | Set stimulation temperature in 1/10 °C (s=0: all areas or s=1-5, xxx=100-600) |
| Vxxxx | Set stimulation speed in 1/10 °C/s (s=0: all areas or s=1-5, xxxx=0001-9999) |
| Dxxxx | Set stimulation duration in ms (s=0: all areas or s=1-5, xxxx=0001-9999) |
| Txxx | Set trigger number (xxx = 001-255) |
| Ix | Enable/disable Integral term (x=0: disable, x=1: enable) |
| DurX | Stimulation duration, if different from Dxxxx (for buffering) |
NB. GPIO-based digital triggers are generated automatically if the connected data acquistion card has an output channel defined for the target device(s)
| Parameter | Meaning |
|---|---|
| DurX | stimulation duration -1=until end of available duration. |
| xxx | Any valid serial command for the device |
| NB. GPIO-based digital triggers are generated automatically if the connected data acquistion card has an output channel defined for the target device(s). | |
| Currently, generic serial devices are not implemented. |
| Parameter | Meaning |
|---|---|
| AmpX | Peak-peak amplitude (V) |
| FreqX | Frequency (Hz) |
| DurX | Signal duration (ms) -1 = until end of available duration. |
| PhaseX | Phase shift (deg). Default 0. |
| VerticalShiftX | Amplitude constant. Default 0. |
| Parameter | Meaning |
|---|---|
| DurX | Signal duration (ms) -1=until end of stim |
| FreqX | Signal frequency (Hz) |
| MaxAmpX | Max amplitude (V) |
| MinAmpX | Min amplitude (V) |
| DCX | Signal duty cycle (percent) |
A special case used for grouping other stimuli into a single function for readability.
Targets should be set to 'none', and parameters should follow Stimulus Block syntax.
PLEASE NOTE
- All StimulusGroups must be defined after all comprising stimuli have been defined. Failing to do this will throw an error.
- If the protocol file uses any StimulusGroup functionality, names should not contain other names (e.g. if one stimulus is called
Lightand another isBlueLight,Lightshould be renamed toAllLightor similar). StimulusGroups work on a pure text replacement basis, and the logic for them is functional but not robust. Having BlueLight and Light defined may lead to unexpected behaviour.
I've done sort of the bare minimum for legacy compatibility: hardcoding a wrapper function that takes the old (p, g) data structure and outputs it in the format of the new data structure. If you're running into issues with, for example, legacy protocol files outputting to the wrong channels, you may want to go in and edit ConvertToStimControlParameters in common/readQSTParameters so targetDevices in each new struct is accurate to what you want per the component-protocol map (see Config Files for more on this).
Add comments to your protocol using the percent (%) symbol. Comment lines can appear anywhere in a protocol file. If you append a comments to the end of a parameter line, it will be assigned to the respective stimulus (and show up in the QSTcontrol GUI). Blank lines will be ignored.
The first line in a protocol file can be used to set general parameters:
- nProtRepXXX number of iterations across the whole protocol (default: 1)
- randomizeX randomize sequenze (0 = off, 1 = randomize, 2 = pseudo; default: off)
- dPauseXXX duration of the pause between stimuli (in seconds; default: 5 seconds)
The thermode is adressed according to QST syntax:
- Nxxx set neutral temperature in 1/10 °C (xxx = 200-400)
- Sxxxxx enable/disable area 1 to 5 (x=0: disable, x=1: enable)
- Csxxx set stimulation temperature in 1/10 °C (s=0: all areas or s=1-5, xxx=100-600)
- Vsxxxx set stimulation speed in 1/10 °C/s (s=0: all areas or s=1-5, xxxx=0001-9999)
- Dsxxxx set stimulation Duration in ms (s=0: all areas or s=1-5, xxxx=0001-9999)
- Txxx set Trigger number (xxx = 001-255)
- Ix enable/disable Integral term (x=0: disable, x=1: enable)
Additional parameters control the vibration motors (omit to disable):
- VibDurX set vibration Duration in ms
- VibAmpX set vibration intensity in 1/10V (X=15-33)
Append 'A' or 'B' to any of these parameters do address a specific thermode (otherwise, the parameter is valid for both thermodes).
- tPreX recording duration before stimulus onset (s)
- tPostX recording duration after stimulus onset (s)
- nRepX number of stimulus repetitions