nafc

Classes:

Nafc([stage_block, stim, reward, …])

A Two-alternative forced choice task.

Nafc_Gap([noise_amplitude])

A Mild variation of Nafc that starts continuous white noise that plays continuously while the task is active.

Nafc_Gap_Laser(laser_probability, …)

Gap detection task with ability to control lasers via TTL logic for optogenetics

class Nafc(stage_block=None, stim=None, reward=50, req_reward=False, punish_stim=False, punish_dur=100, correction=False, correction_pct=50.0, bias_mode=False, bias_threshold=20, current_trial=0, stim_light=True, **kwargs)[source]

Bases: autopilot.tasks.task.Task

A Two-alternative forced choice task.

(can’t have number as first character of class.)

Stages

  • request - compute stimulus, set request trigger in center port.

  • discrim - respond to input, set reward/punishment triggers on target/distractor ports

  • reinforcement - deliver reward/punishment, end trial.

Variables
  • target ("L", "R") – Correct response

  • distractor ("L", "R") – Incorrect response

  • stim – Current stimulus

  • response ("L", "R") – Response to discriminand

  • correct (0, 1) – Current trial was correct/incorrect

  • correction_trial (bool) – If using correction trials, last trial was a correction trial

  • trial_counter (itertools.count) – Which trial are we on?

  • discrim_playing (bool) – Is the stimulus playing?

  • bailed (0, 1) – Subject answered before stimulus was finished playing.

  • current_stage (int) – As each stage is reached, update for asynchronous event reference

Parameters
  • stage_block (threading.Event) – Signal when task stages complete.

  • stim (dict) –

    Stimuli like:

    "sounds": {
        "L": [{"type": "Tone", ...}],
        "R": [{"type": "Tone", ...}]
    }
    
  • reward (float) – duration of solenoid open in ms

  • req_reward (bool) – Whether to give a water reward in the center port for requesting trials

  • punish_stim (bool) – Do a white noise punishment stimulus

  • punish_dur (float) – Duration of white noise in ms

  • correction (bool) – Should we do correction trials?

  • correction_pct (float) – (0-1), What proportion of trials should randomly be correction trials?

  • bias_mode (False, “thresholded_linear”) – False, or some bias correction type (see managers.Bias_Correction )

  • bias_threshold (float) – If using a bias correction mode, what threshold should bias be corrected for?

  • current_trial (int) – If starting at nonzero trial number, which?

  • stim_light (bool) – Should the LED be turned blue while the stimulus is playing?

  • **kwargs

Attributes:

STAGE_NAMES

PARAMS

PLOT

HARDWARE

Classes:

TrialData()

Methods:

request(*args, **kwargs)

Stage 0: compute stimulus, set request trigger in center port.

discrim(*args, **kwargs)

Stage 1: respond to input, set reward/punishment triggers on target/distractor ports

reinforcement(*args, **kwargs)

Stage 2 - deliver reward/punishment, end trial.

punish()

Flash lights, play punishment sound if set

respond(pin)

Set self.response

stim_start()

mark discrim_playing = true

stim_end()

called by stimulus callback

flash_leds()

flash lights for punish_dir

STAGE_NAMES = ['request', 'discrim', 'reinforcement']
PARAMS = OrderedDict([   ('reward', {'tag': 'Reward Duration (ms)', 'type': 'int'}),                 ('req_reward', {'tag': 'Request Rewards', 'type': 'bool'}),                 (   'punish_stim',                     {'tag': 'White Noise Punishment', 'type': 'bool'}),                 (   'punish_dur',                     {'tag': 'Punishment Duration (ms)', 'type': 'int'}),                 ('correction', {'tag': 'Correction Trials', 'type': 'bool'}),                 (   'correction_pct',                     {   'depends': {'correction': True},                         'tag': '% Correction Trials',                         'type': 'int'}),                 (   'bias_mode',                     {   'tag': 'Bias Correction Mode',                         'type': 'list',                         'values': {   'None': 0,                                       'Proportional': 1,                                       'Thresholded Proportional': 2}}),                 (   'bias_threshold',                     {   'depends': {'bias_mode': 2},                         'tag': 'Bias Correction Threshold (%)',                         'type': 'int'}),                 ('stim', {'tag': 'Sounds', 'type': 'sounds'})])
PLOT = {   'chance_bar': True,     'data': {'correct': 'rollmean', 'response': 'segment', 'target': 'point'},     'roll_window': 50}
class TrialData

Bases: tables.description.IsDescription

Attributes:

columns

laser

laser_duration

laser_duty_cycle

laser_freq

columns = {   'DC_timestamp': StringCol(itemsize=26, shape=(), dflt=b'', pos=None),     'RQ_timestamp': StringCol(itemsize=26, shape=(), dflt=b'', pos=None),     'bailed': Int32Col(shape=(), dflt=0, pos=None),     'correct': Int32Col(shape=(), dflt=0, pos=None),     'correction': Int32Col(shape=(), dflt=0, pos=None),     'response': StringCol(itemsize=1, shape=(), dflt=b'', pos=None),     'target': StringCol(itemsize=1, shape=(), dflt=b'', pos=None),     'trial_num': Int32Col(shape=(), dflt=0, pos=None)}
laser = Int32Col(shape=(), dflt=0, pos=None)
laser_duration = Float32Col(shape=(), dflt=0.0, pos=None)
laser_duty_cycle = Float32Col(shape=(), dflt=0.0, pos=None)
laser_freq = Float32Col(shape=(), dflt=0.0, pos=None)
HARDWARE = {   'LEDS': {   'C': <class 'autopilot.hardware.gpio.LED_RGB'>,                 'L': <class 'autopilot.hardware.gpio.LED_RGB'>,                 'R': <class 'autopilot.hardware.gpio.LED_RGB'>,                 'TOP': <class 'autopilot.hardware.gpio.Digital_Out'>},     'POKES': {   'C': <class 'autopilot.hardware.gpio.Digital_In'>,                  'L': <class 'autopilot.hardware.gpio.Digital_In'>,                  'R': <class 'autopilot.hardware.gpio.Digital_In'>},     'PORTS': {   'C': <class 'autopilot.hardware.gpio.Solenoid'>,                  'L': <class 'autopilot.hardware.gpio.Solenoid'>,                  'R': <class 'autopilot.hardware.gpio.Solenoid'>}}
request(*args, **kwargs)[source]

Stage 0: compute stimulus, set request trigger in center port.

Returns

With fields:

{
'target': self.target,
'trial_num' : self.current_trial,
'correction': self.correction_trial,
'type': stimulus type,
**stim.PARAMS
}

Return type

data (dict)

discrim(*args, **kwargs)[source]

Stage 1: respond to input, set reward/punishment triggers on target/distractor ports

Returns

With fields::

{ ‘RQ_timestamp’: datetime.datetime.now().isoformat(), ‘trial_num’: self.current_trial, }

Return type

data (dict)

reinforcement(*args, **kwargs)[source]

Stage 2 - deliver reward/punishment, end trial.

Returns

With fields:

 {
'DC_timestamp': datetime.datetime.now().isoformat(),
'response': self.response,
'correct': self.correct,
'bailed': self.bailed,
'trial_num': self.current_trial,
'TRIAL_END': True
}

Return type

data (dict)

punish()[source]

Flash lights, play punishment sound if set

respond(pin)[source]

Set self.response

Parameters

pin – Pin to set response to

stim_start()[source]

mark discrim_playing = true

stim_end()[source]

called by stimulus callback

set outside lights blue

flash_leds()[source]

flash lights for punish_dir

class Nafc_Gap(noise_amplitude=0.01, **kwargs)[source]

Bases: autopilot.tasks.nafc.Nafc

A Mild variation of Nafc that starts continuous white noise that plays continuously while the task is active.

Parameters
  • noise_amplitude (float) – Multiplier used to scale amplitude of continuous noise

  • **kwargs – passed to Nafc

Attributes:

PARAMS

Methods:

end()

Stop the task, ending the continuous white noise.

PARAMS = OrderedDict([   ('reward', {'tag': 'Reward Duration (ms)', 'type': 'int'}),                 ('req_reward', {'tag': 'Request Rewards', 'type': 'bool'}),                 (   'punish_dur',                     {'tag': 'Punishment Duration (ms)', 'type': 'int'}),                 ('correction', {'tag': 'Correction Trials', 'type': 'bool'}),                 (   'correction_pct',                     {   'depends': {'correction': True},                         'tag': '% Correction Trials',                         'type': 'int'}),                 (   'bias_mode',                     {   'tag': 'Bias Correction Mode',                         'type': 'list',                         'values': {   'None': 0,                                       'Proportional': 1,                                       'Thresholded Proportional': 2}}),                 (   'bias_threshold',                     {   'depends': {'bias_mode': 2},                         'tag': 'Bias Correction Threshold (%)',                         'type': 'int'}),                 ('stim', {'tag': 'Sounds', 'type': 'sounds'}),                 (   'noise_amplitude',                     {   'tag': 'Amplitude of continuous white noise',                         'type': 'float'})])
end()[source]

Stop the task, ending the continuous white noise.

class Nafc_Gap_Laser(laser_probability: float, laser_mode: str, laser_freq: Union[str, list], laser_duty_cycle: Union[str, list], laser_durations: Union[str, list], arena_led_mode: str = 'ON', **kwargs)[source]

Bases: autopilot.tasks.nafc.Nafc_Gap

Gap detection task with ability to control lasers via TTL logic for optogenetics

laser_freq, laser_duty_cycle, and laser_durations can be passed either as an integer (actually typically a string because of the way the value is pulled from the protocol wizard), or as a list – the product of values for all three are generated and presented equiprobably (eg. if laser_freq = 20, laser_duty_cycle=[0.1, 0.2, 0.3], laser_durations = [1, 2, 4, 8] were passed, then 1*3*4=12 different laser conditions would be possible.

Note

Subclasses like these will be made obsolete with the completion of stimulus managers

Parameters
  • laser_probability (float) – if trial satisfies laser_mode, probability that laser will be

  • laser_mode (‘L’, ‘R’, or ‘Both’) – Selects whether the laser is to be presented when target is 'L', 'R' or Either.

  • laser_freq (str, list) – Single value or list of possible laser frequencies in Hz

  • laser_duty_cycle (str, list) – Single value or list of possible duty cycles from 0-1

  • laser_durations (str, list) – Single value or list of possible laser durations (total time laser is on) in ms

  • arena_led_mode (‘ON’, ‘STIM’) – Whether the overhead LED should always be ‘ON’, or whether it should be illuminated for the duration of the longest stimulus at every request

Variables

laser_conditions (tuple) –

tuple of dicts of laser conditions, of format:

{

’freq’: laser frequency, ‘duty_cycle’: laser duty cycle, ‘duration’: laser duration, ‘script_id’: script ID for the series used by the laser Digital Out object, }

Attributes:

PARAMS

HARDWARE

Classes:

TrialData()

Methods:

init_lasers()

Given laser_freq, laser_duty_cycle, laser_durations , create series with Digital_Out.store_series() and populate laser_conditions

request(*args, **kwargs)

Call the superclass request method, and then compute laser presentation logic.

set_leds([color_dict])

Set the color of all LEDs at once.

PARAMS = OrderedDict([   ('reward', {'tag': 'Reward Duration (ms)', 'type': 'int'}),                 ('req_reward', {'tag': 'Request Rewards', 'type': 'bool'}),                 (   'punish_dur',                     {'tag': 'Punishment Duration (ms)', 'type': 'int'}),                 ('correction', {'tag': 'Correction Trials', 'type': 'bool'}),                 (   'correction_pct',                     {   'depends': {'correction': True},                         'tag': '% Correction Trials',                         'type': 'int'}),                 (   'bias_mode',                     {   'tag': 'Bias Correction Mode',                         'type': 'list',                         'values': {   'None': 0,                                       'Proportional': 1,                                       'Thresholded Proportional': 2}}),                 (   'bias_threshold',                     {   'depends': {'bias_mode': 2},                         'tag': 'Bias Correction Threshold (%)',                         'type': 'int'}),                 ('stim', {'tag': 'Sounds', 'type': 'sounds'}),                 (   'noise_amplitude',                     {   'tag': 'Amplitude of continuous white noise',                         'type': 'float'}),                 (   'laser_probability',                     {   'tag': 'Probability (of trials whose targets match '                                'laser_mode) of laser being turned on (0-1)',                         'type': 'float'}),                 (   'laser_mode',                     {   'tag': 'Laser Mode, laser will be possible when target '                                '== ?',                         'type': 'list',                         'values': {'Both': 2, 'L': 0, 'R': 1}}),                 (   'laser_freq',                     {   'tag': 'Laser Pulse Frequency (Hz), list-like [20, 30]',                         'type': 'str'}),                 (   'laser_duty_cycle',                     {   'tag': 'Laser Duty Cycle (0-1), list-like [0.1, 0.2]',                         'type': 'str'}),                 (   'laser_durations',                     {   'tag': 'Laser durations (ms), list-like [10, 20]. if '                                'blank, use durations from stimuli',                         'type': 'str'}),                 (   'arena_led_mode',                     {   'tag': 'Arena LED Mode: always ON vs. on for longest '                                'stim duration during requests',                         'type': 'list',                         'values': {'ON': 0, 'STIM': 1}})])
HARDWARE = {   'LASERS': {'LR': <class 'autopilot.hardware.gpio.Digital_Out'>},     'LEDS': {   'C': <class 'autopilot.hardware.gpio.LED_RGB'>,                 'L': <class 'autopilot.hardware.gpio.LED_RGB'>,                 'R': <class 'autopilot.hardware.gpio.LED_RGB'>,                 'TOP': <class 'autopilot.hardware.gpio.Digital_Out'>},     'POKES': {   'C': <class 'autopilot.hardware.gpio.Digital_In'>,                  'L': <class 'autopilot.hardware.gpio.Digital_In'>,                  'R': <class 'autopilot.hardware.gpio.Digital_In'>},     'PORTS': {   'C': <class 'autopilot.hardware.gpio.Solenoid'>,                  'L': <class 'autopilot.hardware.gpio.Solenoid'>,                  'R': <class 'autopilot.hardware.gpio.Solenoid'>}}
class TrialData

Bases: tables.description.IsDescription

Attributes:

columns

laser

laser_duration

laser_duty_cycle

laser_freq

columns = {   'DC_timestamp': StringCol(itemsize=26, shape=(), dflt=b'', pos=None),     'RQ_timestamp': StringCol(itemsize=26, shape=(), dflt=b'', pos=None),     'bailed': Int32Col(shape=(), dflt=0, pos=None),     'correct': Int32Col(shape=(), dflt=0, pos=None),     'correction': Int32Col(shape=(), dflt=0, pos=None),     'response': StringCol(itemsize=1, shape=(), dflt=b'', pos=None),     'target': StringCol(itemsize=1, shape=(), dflt=b'', pos=None),     'trial_num': Int32Col(shape=(), dflt=0, pos=None)}
laser = Int32Col(shape=(), dflt=0, pos=None)
laser_duration = Float32Col(shape=(), dflt=0.0, pos=None)
laser_duty_cycle = Float32Col(shape=(), dflt=0.0, pos=None)
laser_freq = Float32Col(shape=(), dflt=0.0, pos=None)
init_lasers()[source]

Given laser_freq, laser_duty_cycle, laser_durations , create series with Digital_Out.store_series() and populate laser_conditions

request(*args, **kwargs)[source]

Call the superclass request method, and then compute laser presentation logic.

If target == laser_mode, spin for a laser trial depending on laser_probability.

If we present a laser on this trial, we randomly draw from laser_conditions and call the appropriate script.

set_leds(color_dict=None)[source]

Set the color of all LEDs at once.

Override base method to exclude TOP led

Parameters

color_dict (dict) – If None, turn LEDs off, otherwise like:

{‘pin’: [R,G,B], ‘pin2: [R,G,B]}