-
Notifications
You must be signed in to change notification settings - Fork 0
Protocols
Example protocol files can be found in config/experiment_protocols.
Dev notes:
NB default behaviour for tPre / tPost - Maybe by default throw an error if tPost is shorter than stim length and have some override behaviour?
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 |
| tPostX | (optional) change the default time to record after the first stimulus for each protocol |
| 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 the next section.
By default, all stimuli happen simultaneously, with the same start time. You can change this behaviour using stimulus blocks, the syntax for which is outlined below.
Settings for recording devices are defined in the protocol map, but can be redefined in this file if needed (e.g. you want a camera's acquisition to coincide with a flashing light). NB as far as I know DAQ cards can't be programmed to respond to inputs while generating buffered data. You can't write a light to respond to a camera's output line - you'll need a microcontroller or for both the camera and the light to be triggered by the DAQ
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 |
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. |
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. |
| Overview | Inline Definitions | Serial | PWM | | Digital Triggers | Sine Waves | Pulses | Noise | | Arbitrary I/O | Square Waves | Connected Signals | Buffer Signals |
Specific stimuli are defined here. Depending on the stimulus type, as defined by the prefix of the stimulus, different parameters will be available for use. Definitions shown below.
Define a stimulus function using the following syntax:
StimulusName[TargetDevice1, TargetDevice2, ...](type): param1 param2 param3
When defaults are given, defining the parameter is optional. By default, stimuli begin at the beginning of tPost. Any stimulus can also be given the parameter AcquisitionTrue, which will make the stimulus start at the beginning of tPre, rather than the beginning of tPost.
Stimuli can also be defined inline using the @ operator, as below:
@[StimulusName(type):param1 param2 param3]
or, using the & operator:
@[StimulusName1 & StimulusName2(type):param1 param2 param3]
| Command | Explanation |
|---|---|
| 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) |
| Trigger:StimName | Connected trigger. Defaults to the DigitalTrigger in the stimulus block, if singular and defined, else a trigger at t=0 |
| XXX | any other valid serial command for the target hardware |
Commands are loaded prior to t=0 triggers.
| Command | Explanation |
|---|---|
| DCXXX | Duty cycle (%) |
| FreqXXX | Pulse frequency (Hz) |
| DurXXX | PWM duration (ms) |
| upRampDurXXX | Duration of any up ramp (ms). Takes place within Dur. Default 0 |
| downRampDurXXX | Duration of any down ramp (ms) Takes place within Dur. Default 0 |
A digital trigger with the following parameters:
| Command | Explanation |
|---|---|
| PWXXX | Pulse width (ms) |
| FreqXXX | Pulse frequency (Hz). 0 = single trigger |
| DurXXX | Trigger duration (ms) (exclusive with n - do not define both!) |
| nXXX | Number of triggers (exclusive with Dur - do not define both!). If n=2 and freq=0, sends a trigger at the start and end of tPost |
An analog sine wave with the following parameters:
| Command | Explanation |
|---|---|
| AmpXXX | Peak amplitude (V) |
| FreqXXX | Sinewave frequency (Hz) |
| DurXXX | Duration (ms) |
| upRampDurXXX | Duration of any up ramping for amplitude (ms). Takes place within Dur. Default 0 |
| downRampDurXXX | Duration of any down ramping for amplitude (ms). Takes place within Dur. Default 0 |
A digital or analog pulse
| Command | Explanation |
|---|---|
| DurXXX | Pulse duration (ms) |
| AmpXXX | (analog only) Amplitude (V) |
| upRampDurXXX | (analog only) Duration of any up ramping for amplitude (ms). Takes place within Dur. Default 0 |
| downRampDurXXX | (analog only) Duration of any down ramping for amplitude (ms). Takes place within Dur. Default 0 |
Analog noise
| Command | Explanation |
|---|---|
| MaxXXX | Maximum noise amplitude (V) |
| MinXXX | Minimum noise amplitude (V) |
| DurXXX | Pulse duration (ms) |
| Dist:XXX | Distribution of amplitudes. Default Norm. Supported: Norm, Uniform |
| Base:StimName | Base analog signal. Defaults to a constant signal of 0v. When defined, the signal output is the base signal plus the defined noise |
An arbitrary digital or analog signal. File contents should match the signal type - digital signals should contain only 1 or 0, and analog signals should be in V.
| Command | Explanation |
|---|---|
| full_path_to_txt_file_1000Hz.csv | File should contain a comma-separated sequence of desired values, and the end of the filename should be '_XHz' where X is the sample rate of the values. |
An analog square wave
| Command | Explanation |
|---|---|
| FreqXXX | Signal frequency (Hz) |
| MaxXXX | Maximum amplitude (V). Default 10 |
| MinXXX | Minimum amplitude (V). Default 0 |
| StartValX | Start value. 1=max amplitude, 0=minimum amplitude. Default 1 |
A constant digital or analog signal.
| Command | Explanation |
|---|---|
| LenX | time (ms) to output val on the desired channel(s) |
| ValX | (optional) value to hold on the desired channel(s) (default 0. ValPrev will hold whatever the previous output was) |
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