Blink¶
A very simple task: Blink an LED
Written by @mikewehr in the mike
branch: https://github.com/wehr-lab/autopilot/blob/mike/autopilot/tasks/blink.py
Demonstrates the basic structure of a task with one stage, described in the comments throughout the task.
See the main tutorial for more detail: https://docs.auto-pi-lot.com/en/latest/guide.task.html#
This page is rendered in the docs here in order to provide links to the mentioned objects/classes/etc., but this example was intended to be read as source code, as some comments will only be visible there.
Note
Currently, after completion, the task needs to be explicitly imported and added to tasks.TASK_LIST
,
this will be remedied shortly (see the registries
branch).
Classes:
|
Blink an LED. |
-
class
Blink
(stage_block=None, pulse_duration=100, pulse_interval=500, *args, **kwargs)[source]¶ Bases:
autopilot.tasks.task.Task
Blink an LED.
Note that we subclass the
tasks.Task
class (Blink(Task)
) to provide us with some methods useful for all Tasks.- Parameters
pulse_duration (int, float) – Duration the LED should be on, in ms
pulse_interval (int, float) – Duration the LED should be off, in ms
Attributes:
An (optional) list or tuple of names of methods that will be used as stages for the task.
A dictionary that specifies the parameters that control the operation of the task – each task presumably has some range of options that allow slight variations (eg. different stimuli, etc.) on a shared task structure. This dictionary specifies each
PARAM
as a human-readabletag
and atype
that is used by the gui to create an appropriate input object. For example::.Declare the hardware that will be used in the task. Each hardware object is specified with a
group
and anid
as nested dictionaries. These descriptions require a set of hardware parameters in the autopilotprefs.json
(typically generated byautopilot.setup.setup_autopilot
) with a matchinggroup
andid
structure. For example, an LED declared like this in theBlink.HARDWARE
attribute::.Some generator that returns the stage methods that define the operation of the task.
Some counter to keep track of the trial number
Classes:
This class declares the data that will be returned for each “trial” – or complete set of executed task stages.
Methods:
pulse
(*args, **kwargs)Turn an LED on and off according to
Blink.pulse_duration
andBlink.pulse_interval
-
STAGE_NAMES
= ['pulse']¶ An (optional) list or tuple of names of methods that will be used as stages for the task.
See
Blink.stages
for more information
-
PARAMS
= OrderedDict([ ( 'pulse_duration', {'tag': 'LED Pulse Duration (ms)', 'type': 'int'}), ( 'pulse_interval', {'tag': 'LED Pulse Interval (ms)', 'type': 'int'})])¶ A dictionary that specifies the parameters that control the operation of the task – each task presumably has some range of options that allow slight variations (eg. different stimuli, etc.) on a shared task structure. This dictionary specifies each
PARAM
as a human-readabletag
and atype
that is used by the gui to create an appropriate input object. For example:PARAMS['pulse_duration'] = {'tag': 'LED Pulse Duration (ms)', 'type': 'int'}
When instantiated, these params are passed to the
__init__
method.A
collections.OrderedDict
is used so that parameters can be presented in a predictable way to users.
-
class
TrialData
¶ Bases:
tables.description.IsDescription
This class declares the data that will be returned for each “trial” – or complete set of executed task stages. It is used by the
subject.Subject
object to make a data table with the correct data types. Declare each piece of data using a pytables Column descriptor (see https://www.pytables.org/usersguide/libref/declarative_classes.html#col-sub-classes for available data types, and the pytables guide: https://www.pytables.org/usersguide/tutorials.html for more information)For each trial, we’ll return two timestamps, the time we turned the LED on, the time we turned it off, and the trial number. Note that we use a 26-character
tables.StringCol
for the timestamps, which are given as an isoformatted string like'2021-02-16T18:11:35.752110'
Attributes:
-
columns
= { 'timestamp_off': StringCol(itemsize=26, shape=(), dflt=b'', pos=None), 'timestamp_on': StringCol(itemsize=26, shape=(), dflt=b'', pos=None), 'trial_num': Int32Col(shape=(), dflt=0, pos=None)}¶
-
-
HARDWARE
= {'LEDS': {'dLED': <class 'autopilot.hardware.gpio.Digital_Out'>}}¶ Declare the hardware that will be used in the task. Each hardware object is specified with a
group
and anid
as nested dictionaries. These descriptions require a set of hardware parameters in the autopilotprefs.json
(typically generated byautopilot.setup.setup_autopilot
) with a matchinggroup
andid
structure. For example, an LED declared like this in theBlink.HARDWARE
attribute:HARDWARE = {'LEDS': {'dLED': gpio.Digital_Out}}
requires an entry in
prefs.json
like this:"HARDWARE": {"LEDS": {"dLED": { "pin": 1, "polarity": 1 }}}
that will be used to instantiate the
hardware.gpio.Digital_Out
object, which is then available for use in the task like:self.hardware['LEDS']['dLED'].set(1)
-
stages
¶ Some generator that returns the stage methods that define the operation of the task.
To run a task, the
pilot.Pilot
object will call each stage function, which can return some dictionary of data (seeBlink.pulse()
) and wait until some flag (Blink.stage_block
) is set to compute the next stage. Since in this case we want to call the same method (Blink.pulse()
) over and over again, we use anitertools.cycle
object (if we have more than one stage to call in a cycle, we could provide them likeitertools.cycle([self.stage_method_1, self.stage_method_2])
. More complex tasks can define a custom generator for finer control over stage progression.
-
trial_counter
¶ Some counter to keep track of the trial number