pycontrol for self administration

71 views
Skip to first unread message

mao...@gmail.com

unread,
Mar 20, 2021, 1:51:08 PM3/20/21
to pyControl
Hi pycontrol community,

I am planing to  do food administration with pycontrol system.

The current idea is that mice poke and hold for 0.5s then LED on for 10s and deliver food with food dispenser. There is also 60s time out. During the time nose poke have no consequence.
I am also planing to do fixed ratio experiment, like fixed ratio 3, poke three times get 1 reward. 

Any idea about how to write task definition file.  
Also welcome if anyone can give any idea about the behavior parameter. For hold the poke for 0.5s, I want to avoid the wrong detection due to whisker movement. 

Thanks for your help in advance. 

thoma...@neuro.fchampalimaud.org

unread,
Mar 22, 2021, 6:45:16 AM3/22/21
to pyControl
Hi,

This type of task should be pretty straightforward to program with pyControl.  There is detailed information provided about programming tasks in the documentation here, and a high level overview in the manuscript here.  It is also useful to look at the example tasks, in particular I suggest looking at the button example here and the random ratio example here.  Once you have had a look at these, have a go at programming the task and if you get stuck then post the code you have here.

I don't think it will be difficult to get a mouse to hold for a duration of 0.5 seconds, though you would probably want to start with a shorted hold duration and gradually increase it across training. over a couple of days.

best,

Thomas

MM

unread,
Mar 24, 2021, 2:02:16 AM3/24/21
to pyControl
Hi Thomas,  Thanks for your reply and sorry for the naive questions. Here is my code below and attached. 
I used 5 timers and 3 timers at the same time. Do you think it is ok to use three timer at the same time?
And for the data log, should I mannully log the data, or the data will be automaticcally loged? Like here, left poke (active poke), right poke (inactive poke) and reward.

Thanks a lot for your time and help.

M

--------------------------------------------------------------------------------------------------------------------------------------------------------
from pyControl.utility import *
from devices import *

# Variables.

v.fixed_ratio = 3
v.nosepoking_duration = 500*ms
v.reward_duration = 1.5*second
v.cue_duration = 20*second
v.remove_duration = 60*second
v.inter_trial_interval = 0*second

v.poke_count = 0
v.n_rewards = 0
v.max_rewards = 40
v.session_duration = 1*hour


board = Breakout_1_2()  # Instantiate the breakout board object.

# Instantiate the poke objects.
left_poke   = Poke(port=board.port_1, rising_event='left_poke'  , falling_event='left_poke_out' )
right_poke  = Poke(port=board.port_2, rising_event='right_poke' , falling_event='right_poke_out')
Rew = Digital_output(board.port_3.POW_A)
Vaccum =  Digital_output(board.port_3.POW_B)


# States and events.

states = ['waiting_for_poke',
          'count_success_poke',
          'exit_poke',
          'reward',
          'inter_trial_interval']
          
events = ['left_poke',
          'left_poke_out',
          'success_poke_timer',
          'reward_timer',
          'cue_timer',
          'remove_timer',
          'session_timer']

initial_state = 'waiting_for_poke'

# Run start and stop behaviour.
def run_start(): 
    # Set session timer
    set_timer('session_timer', v.session_duration)  

def run_end():
    # Turn off all hardware outputs.  
    hw.off()

# State behaviour functions.

def waiting_for_poke(event):
    if event == 'left_poke':
       goto_state('count_success_poke')

def count_success_poke(event):
    if event == 'entry':
        set_timer('success_poke_timer', v.nosepoking_duration)
    elif event == 'left_poke_out':
        disarm_timer('success_poke_timer')
        goto_state('waiting_for_poke')
    elif event == 'success_poke_timer':
         v.poke_count += 1
         if v.poke_acount == v.fixed_ratio:
            v.poke_count = 0
            goto_state('reward')
         else:
            goto_state('exit_poke')

def exit_poke(event):
    if event == 'left_poke_out':
       goto_state('waiting_for_poke')

def reward(event):
    if event == 'entry':
        set_timer('reward_timer', v.reward_duration) 
        set_timer('cue_timer', v.cue_duration) 
        set_timer('remove_timer', v.remove_duration) 
        Rew.on()
        left_poke.LED.on()
        Vaccum.on()
        

    elif event == 'reward_timer':
        Rew.off()

    elif event == 'cue_timer':
        left_poke.LED.off()
    
    elif event == 'remove_timer':
        Vaccum.off()

        v.n_rewards += 1

        if v.n_rewards == v.max_rewards:
           stop_framework()

        else:
           goto_state('inter_trial_interval')

def inter_trial_interval(event):
    if event == 'entry':
       timed_goto_state('waiting_for_poke', v.inter_trial_interval)


def all_states(event):
    # When 'session_timer' event occurs stop framework to end session.
    if event == 'session_timer':
        stop_framework()
        



test.txt

thoma...@neuro.fchampalimaud.org

unread,
Mar 25, 2021, 6:36:34 AM3/25/21
to pyControl
Hi M,

I have not tested the code but it looks sensible. 

It is fine to have multiple timers running in parallel. 

pyControl will automatically log all state entries and externally generated events as long as they are specified in the task's events list.  You need to include the 'right_poke' and 'right_poke_out' events in the list to tell pyControl they are used in this task.   The reason for this is that normally hardware objects are instantiated in a seperate hardware definition file that is imported by the task (see here), so it is possible that hardware objects are defined in the hardwrae defintion that are not actually used in the current task.  Inputs whose events are not listed in the events list for the current task are inactive and not monitored by the framework.  Events generated by timers are not logged by default, but you can specify to log them using the argument output_event=True when you set them (see here).  

Also, I don't think you need the exit_poke state in your task, instead you could return straight to waiting_for_poke because the subject physically cannot poke back in without first exiting the poke.

best,

Thomas
Reply all
Reply to author
Forward
0 new messages