Skip to content

Protocols

Michelle Sands edited this page Oct 7, 2025 · 31 revisions

Protocol Files

Dev notes: 
I think I'm just going to code a legacy adaptor rather than trying to integrate it into this system. Detect whether a protocol file is using the old or new syntax, then use that. OR just make a thing that converts old files to the new format.
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.

General

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 (seconds) 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

Trial Information

| Intro | Stimulus Blocks | Sequential Execution | Oddballs |

Each line in this block is a trial, which comprises a series of stimuli. Stimulus names have three parts:

  • the name, which maps directly to the protocol map;
  • the optional sub-identifier, which can be used to isolate behaviour for devices of the same type; and
  • the index, which is used to differentiate between stimuli for the same device over trials.

Camera, CameraA, Camera1, and CameraA1 can all be used, with different outcomes in targeted devices. When no sub-identifier is provided, all active devices of the given type are targeted.

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) change the number of times this trial is run for each protocol

Stimulus Blocks

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)

The '>' Operator

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)

Oddballs

To construct an oddball trial, use the oddX notation, which takes the following params in square brackets:

  • Default stimulus
  • Stimulus to swap in (can be a single stimulus block, or multiple stimuli separated by | or > )
e.g. Odd1[StimA, StimB] nStims4
StimA|*___|*___
StimB|_|**__|**
    gives 4 total stims, defaulting to StimA and swapping it out for StimB after every 1 occurrence.

You can randomise how many stimuli to swap out with odd using Odd1>5, which will swap StimA out after between 1 and 5 occurrences, inclusive.

e.g. Odd1[StimA, StimB] StimC nStims3
StimA|*___|*
StimB|_|**__
StimC|*|*_|*
    note that t=0 for each stim remains synchronised, even when the oddball leads to stimuli of different lengths.

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. Odd1[StimA, (StimB|StimC)] nStims4 repDel1000 
StimA|*__|*__
StimB|_|*____
StimC|_____|*


e.g. Odd1[StimA, (StimC|>StimB)] nStims4 repDel1000
StimA|*__|*__
StimB|_____|*
StimC|_|*____

Stimulus Info

| 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. Note that capitalisation consistency is vital for stimulus subtypes (e.g. CameraA, not Cameraa or cameraa)

Define a stimulus function using the following syntax: StimulusName(type): param1 param2 param3

You can set multiple hardware devices to be connected to the same stimulus using the & operator:

StimulusName1 & StimulusName2(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.

Inline Definitions

Stimuli can also be defined inline using curly braces, as below: {StimulusName(type):param1 param2 param3}

or, using the & operator: {StimulusName1 & StimulusName2(type):param1 param2 param3}

Supported types and parameters:

Serial (includes thermodes)

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.

PWM

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

Trigger

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

Sine

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

Pulse

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

Noise

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

Arbitrary

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.

SquareWave

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

Connected

Command Explanation
XXX name of target for connected triggering
Del When to send the trigger

Buffer

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)

#Legacy Protocol Files

Clone this wiki locally