class OdorGen(object): def __init__(self,odorindex): self.odorindex = odorindex def assign_odor(self): # initiate all the odor solenoids self.odors_DAQ = DAQSimpleDOTask('Dev2_SELECT/port0/line{}'.format(self.odorindex)) print('Odor {} has been properly assigned'.format(self.odorindex)) def set_rewardodor(self,index): reward_odor = self.odors_DAQ[index] print('reward odor is odor {}'.format(index)) return reward_odor def initiate(self): self.odors_DAQ.low() print('Odor initiation: status low') def close(self): self.odors_DAQ.close() print('Connection has been closed')
class NuneTraining(Measurement): # this is the name of the measurement that ScopeFoundry uses # when displaying your measurement and saving data related to it name = "nune_training" interrupt_subthread = QtCore.Signal(()) def setup(self): """ Runs once during App initialization. This is the place to load a user interface file, define settings, and set up data structures. """ # Define ui file to be used as a graphical interface # This file can be edited graphically with Qt Creator # sibling_path function allows python to find a file in the same folder # as this python module self.ui_filename = sibling_path(__file__, "ant_watch_plot.ui") #Load ui file and convert it to a live QWidget of the user interface self.ui = load_qt_ui_file(self.ui_filename) # Measurement Specific Settings # This setting allows the option to save data to an h5 data file during a run # All settings are automatically added to the Microscope user interface self.settings.New('save_h5', dtype=bool, initial=True) self.settings.New('save_video', dtype=bool, initial=False) # x and y is for transmitting signal # self.settings.New('x',dtype = float, initial = 32, ro = True, vmin = 0, vmax = 63.5) # self.settings.New('y',dtype = float, initial = 32, ro = True, vmin = 0, vmax = 63.5) # added by Nune self.settings.New('filename', dtype=str, initial='trial') self.settings.New('in_trial', dtype=bool, initial=False) self.settings.New('view_only', dtype=bool, initial=False) self.settings.New('lick_status', dtype=int, initial=0) self.settings.New('play_frequency', dtype=int, initial=0) # Define how often to update display during a run self.display_update_period = 0.04 # Convenient reference to the hardware used in the measurement self.wide_cam = self.app.hardware['wide_cam'] self.recorder = self.app.hardware['flirrec'] #setup experiment condition self.wide_cam.settings.frame_rate.update_value(8) self.wide_cam.read_from_hardware() def setup_figure(self): """ Runs once during App initialization, after setup() This is the place to make all graphical interface initializations, build plots, etc. """ # connect ui widgets to measurement/hardware settings or functions self.ui.start_pushButton.clicked.connect(self.start) self.ui.interrupt_pushButton.clicked.connect(self.interrupt) # Set up pyqtgraph graph_layout in the UI self.wide_cam_layout = pg.GraphicsLayoutWidget() self.ui.wide_cam_groupBox.layout().addWidget(self.wide_cam_layout) #create camera image graphs self.wide_cam_view = pg.ViewBox() self.wide_cam_layout.addItem(self.wide_cam_view) self.wide_cam_image = pg.ImageItem() self.wide_cam_view.addItem(self.wide_cam_image) #counter used for reducing refresh rate self.wide_disp_counter = 0 def update_display(self): """ Displays (plots) the numpy array self.buffer. This function runs repeatedly and automatically during the measurement run. its update frequency is defined by self.display_update_period """ # check availability of display queue of the wide camera if not hasattr(self, 'wide_disp_queue'): pass elif self.wide_disp_queue.empty(): pass else: try: wide_disp_image = self.wide_disp_queue.get() if type(wide_disp_image) == np.ndarray: if wide_disp_image.shape == ( self.wide_cam.settings.height.value(), self.wide_cam.settings.width.value()): try: self.wide_cam_image.setImage(wide_disp_image) except Exception as ex: print('Error: %s' % ex) except Exception as ex: print("Error: %s" % ex) def run(self): """ Runs when measurement is started. Runs in a separate thread from GUI. It should not update the graphical interface directly, and should only focus on data acquisition. """ # # first, create a data file # if self.settings['save_h5']: # # if enabled will create an HDF5 file with the plotted data # # first we create an H5 file (by default autosaved to app.settings['save_dir'] # # This stores all the hardware and app meta-data in the H5 file # self.h5file = h5_io.h5_base_file(app=self.app, measurement=self) # # # create a measurement H5 group (folder) within self.h5file # # This stores all the measurement meta-data in this group # self.h5_group = h5_io.h5_create_measurement_group(measurement=self, h5group=self.h5file) # # # create an h5 dataset to store the data # self.buffer_h5 = self.h5_group.create_dataset(name = 'buffer', # shape = self.buffer.shape, # dtype = self.buffer.dtype) # We use a try/finally block, so that if anything goes wrong during a measurement, # the finally block can clean things up, e.g. close the data file object. #self.wide_cam._dev.set_buffer_count(500) if self.settings.save_video.value(): save_dir = self.app.settings.save_dir.value() data_path = os.path.join(save_dir, self.app.settings.sample.value()) try: os.makedirs(data_path) except OSError: print( 'directory already exists, writing to existing directory') self.recorder.settings.path.update_value(data_path) #frame_rate = self.wide_cam.settings.frame_rate.value() #self.recorder.create_file('wide_mov',frame_rate) # # # create a subthread and connect it to the interrupt subthread signal # self.wide_disp_queue = queue.Queue(1000) # self.camera_thread = SubMeasurementQThread(self.camera_action) # self.interrupt_subthread.connect(self.camera_thread.interrupt) # #start camera # self.wide_cam.start() # # #start camera subthread # self.camera_thread.start() # initiate all the odor solenoids odor0 = DAQSimpleDOTask('Dev3/port0/line0') clean0 = DAQSimpleDOTask('Dev3/port0/line1') odor1 = DAQSimpleDOTask('Dev3/port0/line2') clean1 = DAQSimpleDOTask('Dev3/port0/line3') odor2 = DAQSimpleDOTask('Dev3/port0/line4') clean2 = DAQSimpleDOTask('Dev3/port0/line5') odor3 = DAQSimpleDOTask('Dev3/port0/line6') clean3 = DAQSimpleDOTask('Dev3/port0/line7') odor4 = DAQSimpleDOTask('Dev3/port1/line0') clean4 = DAQSimpleDOTask('Dev3/port1/line1') odor5 = DAQSimpleDOTask('Dev3/port1/line2') clean5 = DAQSimpleDOTask('Dev3/port1/line3') odor6 = DAQSimpleDOTask('Dev3/port1/line4') clean6 = DAQSimpleDOTask('Dev3/port1/line5') odor7 = DAQSimpleDOTask('Dev3/port1/line6') clean7 = DAQSimpleDOTask('Dev3/port1/line7') # # # D2-8 # reward_odor = odor5 # reward_odor_clean = clean5 # punish_odor = odor4 # punish_odor_clean = clean4 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd2-8_7-11-2019_odor_sound.xlsx' # #events_filename = 'test.xlsx' # # D2-9 # reward_odor = odor4 # reward_odor_clean = clean4 # punish_odor = odor5 # punish_odor_clean = clean5 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd2-9_7-11-2019_odor_sound.xlsx' # # # D2-10 # reward_odor = odor5 # reward_odor_clean = clean5 # punish_odor = odor4 # punish_odor_clean = clean4 # reward_sound = 2 # punish_sound = 1 # events_filename = 'd2-10_7-11-2019_odor_sound.xlsx' # D1-7 rewards: odor4, sound 1 # reward_odor = odor4 # reward_odor_clean = clean4 # punish_odor = odor5 # punish_odor_clean = clean5 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd1-7_7-12-2019_odor_sound.xlsx' # events_filename = 'test.xlsx' # # D1-12 rewards: odor5, sound 1 # reward_odor = odor5 # reward_odor_clean = clean5 # punish_odor = odor4 # punish_odor_clean = clean4 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd1-12_7-11-2019_odor_sound.xlsx' # D1-13 rewards: odor4, sound 2 # reward_odor = odor4 # reward_odor_clean = clean4 # punish_odor = odor5 # punish_odor_clean = clean5 # reward_sound = 2 # punish_sound = 1 # events_filename = 'd1-13_7-11-2019_odor_sound.xlsx' # D1-14 rewards: odor5, sound 2 reward_odor = odor5 reward_odor_clean = clean5 punish_odor = odor4 punish_odor_clean = clean4 reward_sound = 2 punish_sound = 1 events_filename = 'd1-14_7-11-2019_odor_sound.xlsx' odor0.low() odor1.low() odor2.low() odor3.low() odor4.low() odor5.low() odor6.low() odor7.low() clean0.low() clean1.low() clean2.low() clean3.high() clean4.high() clean5.high() clean6.high() clean7.high() odor0.close() odor1.close() odor2.close() odor3.close() odor6.close() odor7.close() clean0.close() clean1.close() clean2.close() clean3.close() clean6.close() clean7.close() LED = DAQSimpleDOTask('Dev3/port2/line2') LED.low() self.OdorOnCopy = DAQSimpleDOTask('Dev3/port2/line5') self.OdorOnCopy.low() waterR = DAQSimpleDOTask('Dev3/port2/line0') waterR.low() airpuff1 = DAQSimpleDOTask('Dev3/port2/line3') airpuff1.low() airpuff2 = DAQSimpleDOTask('Dev3/port2/line6') airpuff2.low() self.lickR = DAQSimpleDITask('Dev3/port2/line4') # EVENT CODES # video recording start / start trial = 101 # lick on = 11, lick off = 10 # right water on = 51, right water off = 50 # airpuff on = 81, off = 80 # reward odor on = 131, off = 130 # punish odor on = 141, off = 140 # reward sound on = 151, off = 150 # punish sound on = 161, off = 160 #create excel workbook self.wb = Workbook() self.ws = self.wb.active numtrials = 120 a = np.empty(int(numtrials / 4)) a.fill(2) b = np.empty(int(numtrials / 4)) b.fill(3) trialtypes = np.concatenate((np.ones( (int(numtrials / 4))), np.zeros((int(numtrials / 4))), a, b)) random.shuffle(trialtypes) print(trialtypes) # # arrays to randomize skipped trials for each trial type # num_to_skip = int((numtrials/5)*0.1) # skip0 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip0) # skip0 = np.concatenate((np.zeros(int(numtrials/10)),skip0)) # skip1 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip1) # skip1 = np.concatenate((np.zeros(int(numtrials/10)),skip1)) # skip2 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip2) # skip2 = np.concatenate((np.zeros(int(numtrials/10)),skip2)) # skip3 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip3) # skip3 = np.concatenate((np.zeros(int(numtrials/10)),skip3)) # counters for each trial type h = 0 i = 0 j = 0 k = 0 duration_rec_off = 6.5 duration_rec_on_before = 4 duration_odor_to_outcome = 1.3 duration_water_large = 0.2 duration_airpuff = 0.2 duration_rec_on_after = 8 sound_thread = SubMeasurementQThread(self.sound_action) self.interrupt_subthread.connect(sound_thread.interrupt) sound_thread.start() for t in range(0, numtrials): if bool(trialtypes[t]): self.settings.filename.update_value('reward_trial' + str(t)) else: self.settings.filename.update_value('punish_trial' + str(t)) self.recorder.create_file( self.settings.filename.value(), self.wide_cam.settings.frame_rate.value()) #print('turn on LED') LED.high() self.check_licking_1spout(1) #self.settings.save_video.update_value(True): print(t) self.settings.in_trial.update_value(True) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=101) self.check_licking_1spout(duration_rec_on_before) if trialtypes[t] == 0: print('odor reward trial ' + str(h)) print('opening odor port') reward_odor.high() self.OdorOnCopy.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=131) reward_odor_clean.low() self.check_licking_1spout(duration_odor_to_outcome) print('opening water valve') waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=51) self.check_licking_1spout(duration_water_large) print('closing odor port') reward_odor.low() self.OdorOnCopy.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=130) reward_odor_clean.high() waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=50) h += 1 self.wb.save(events_filename) elif trialtypes[t] == 1: print('punish odor trial ' + str(i)) print('opening odor port') punish_odor.high() self.OdorOnCopy.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=141) punish_odor_clean.low() self.check_licking_1spout(duration_odor_to_outcome) print('delivering airpuff') airpuff1.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=81) self.check_licking_1spout(duration_airpuff) print('closing odor port') punish_odor.low() self.OdorOnCopy.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=140) punish_odor_clean.high() airpuff1.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=80) i += 1 self.wb.save(events_filename) elif trialtypes[t] == 2: print('sound reward trial ' + str(j)) print('playing reward sound') self.settings.play_frequency.update_value(reward_sound) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=151) self.check_licking_1spout(duration_odor_to_outcome) print('opening water valve') waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=51) self.check_licking_1spout(duration_water_large) waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=50) j += 1 self.wb.save(events_filename) else: print('sound punish trial ' + str(k)) print('playing punish sound') self.settings.play_frequency.update_value(punish_sound) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=161) self.check_licking_1spout(duration_odor_to_outcome) print('delivering airpuff') airpuff1.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=81) self.check_licking_1spout(duration_airpuff) airpuff1.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=80) k += 1 self.wb.save(events_filename) self.check_licking_1spout(duration_rec_on_after) self.settings.in_trial.update_value(False) #self.settings.save_video.update_value(False): LED.low() self.wb.save(events_filename) self.check_licking_1spout(duration_rec_off) if self.interrupt_measurement_called: #tell subtherad to stop self.interrupt_subthread.emit() break reward_odor.close() reward_odor_clean.close() punish_odor.close() punish_odor_clean.close() waterR.close() waterR.close() airpuff1.close() airpuff2.close() LED.close() self.OdorOnCopy.close() print('FINISHED ASSOCIATION TRAINING') #sound_thread.stop() del sound_thread if self.settings.save_video.value(): self.recorder.close() def check_licking_1spout(self, interval): checkperiod = 0.02 timeout = time.time() + interval right_lick_last = 0 while time.time() < timeout: right_lick = self.lickR.read() if right_lick != right_lick_last: if right_lick: self.settings.lick_status.update_value(11) print('Lick') d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=11) else: self.settings.lick_status.update_value(10) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=10) else: self.settings.lick_status.update_value(0) right_lick_last = right_lick time.sleep(checkperiod) def sound_action(self): checkperiod = 0.02 time.sleep(checkperiod) if self.settings.play_frequency.value() == 1: self.settings.play_frequency.update_value(0) self.OdorOnCopy.high() winsound.Beep(5000, 1500) #winsound.PlaySound('highsoundstimulus.wav', winsound.SND_ALIAS) self.OdorOnCopy.low() elif self.settings.play_frequency.value() == 2: self.settings.play_frequency.update_value(0) self.OdorOnCopy.high() #winsound.PlaySound('lowsoundstimulus.wav', winsound.SND_ALIAS) winsound.Beep(12000, 1500) self.OdorOnCopy.low() # def camera_action(self): # ''' # format the image properly # ''' # try: # wide_image = self.wide_cam.read() # wide_image_data = self.wide_cam.to_numpy(wide_image) # self.wide_disp_queue.put(wide_image_data) # # if self.settings.save_video.value() and self.settings.in_trial.value() : # self.recorder.save_frame(self.settings.filename.value(),wide_image) # # except Exception as ex: # print('Error : %s' % ex)
def run(self): """ Runs when measurement is started. Runs in a separate thread from GUI. It should not update the graphical interface directly, and should only focus on data acquisition. """ # # first, create a data file # if self.settings['save_h5']: # # if enabled will create an HDF5 file with the plotted data # # first we create an H5 file (by default autosaved to app.settings['save_dir'] # # This stores all the hardware and app meta-data in the H5 file # self.h5file = h5_io.h5_base_file(app=self.app, measurement=self) # # # create a measurement H5 group (folder) within self.h5file # # This stores all the measurement meta-data in this group # self.h5_group = h5_io.h5_create_measurement_group(measurement=self, h5group=self.h5file) # # # create an h5 dataset to store the data # self.buffer_h5 = self.h5_group.create_dataset(name = 'buffer', # shape = self.buffer.shape, # dtype = self.buffer.dtype) # We use a try/finally block, so that if anything goes wrong during a measurement, # the finally block can clean things up, e.g. close the data file object. #self.wide_cam._dev.set_buffer_count(500) if self.settings.save_video.value(): save_dir = self.app.settings.save_dir.value() data_path = os.path.join(save_dir, self.app.settings.sample.value()) try: os.makedirs(data_path) except OSError: print( 'directory already exists, writing to existing directory') self.recorder.settings.path.update_value(data_path) #frame_rate = self.wide_cam.settings.frame_rate.value() #self.recorder.create_file('wide_mov',frame_rate) # # # create a subthread and connect it to the interrupt subthread signal # self.wide_disp_queue = queue.Queue(1000) # self.camera_thread = SubMeasurementQThread(self.camera_action) # self.interrupt_subthread.connect(self.camera_thread.interrupt) # #start camera # self.wide_cam.start() # # #start camera subthread # self.camera_thread.start() # initiate all the odor solenoids odor0 = DAQSimpleDOTask('Dev3/port0/line0') clean0 = DAQSimpleDOTask('Dev3/port0/line1') odor1 = DAQSimpleDOTask('Dev3/port0/line2') clean1 = DAQSimpleDOTask('Dev3/port0/line3') odor2 = DAQSimpleDOTask('Dev3/port0/line4') clean2 = DAQSimpleDOTask('Dev3/port0/line5') odor3 = DAQSimpleDOTask('Dev3/port0/line6') clean3 = DAQSimpleDOTask('Dev3/port0/line7') odor4 = DAQSimpleDOTask('Dev3/port1/line0') clean4 = DAQSimpleDOTask('Dev3/port1/line1') odor5 = DAQSimpleDOTask('Dev3/port1/line2') clean5 = DAQSimpleDOTask('Dev3/port1/line3') odor6 = DAQSimpleDOTask('Dev3/port1/line4') clean6 = DAQSimpleDOTask('Dev3/port1/line5') odor7 = DAQSimpleDOTask('Dev3/port1/line6') clean7 = DAQSimpleDOTask('Dev3/port1/line7') # # # D2-8 # reward_odor = odor5 # reward_odor_clean = clean5 # punish_odor = odor4 # punish_odor_clean = clean4 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd2-8_7-11-2019_odor_sound.xlsx' # #events_filename = 'test.xlsx' # # D2-9 # reward_odor = odor4 # reward_odor_clean = clean4 # punish_odor = odor5 # punish_odor_clean = clean5 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd2-9_7-11-2019_odor_sound.xlsx' # # # D2-10 # reward_odor = odor5 # reward_odor_clean = clean5 # punish_odor = odor4 # punish_odor_clean = clean4 # reward_sound = 2 # punish_sound = 1 # events_filename = 'd2-10_7-11-2019_odor_sound.xlsx' # D1-7 rewards: odor4, sound 1 # reward_odor = odor4 # reward_odor_clean = clean4 # punish_odor = odor5 # punish_odor_clean = clean5 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd1-7_7-12-2019_odor_sound.xlsx' # events_filename = 'test.xlsx' # # D1-12 rewards: odor5, sound 1 # reward_odor = odor5 # reward_odor_clean = clean5 # punish_odor = odor4 # punish_odor_clean = clean4 # reward_sound = 1 # punish_sound = 2 # events_filename = 'd1-12_7-11-2019_odor_sound.xlsx' # D1-13 rewards: odor4, sound 2 # reward_odor = odor4 # reward_odor_clean = clean4 # punish_odor = odor5 # punish_odor_clean = clean5 # reward_sound = 2 # punish_sound = 1 # events_filename = 'd1-13_7-11-2019_odor_sound.xlsx' # D1-14 rewards: odor5, sound 2 reward_odor = odor5 reward_odor_clean = clean5 punish_odor = odor4 punish_odor_clean = clean4 reward_sound = 2 punish_sound = 1 events_filename = 'd1-14_7-11-2019_odor_sound.xlsx' odor0.low() odor1.low() odor2.low() odor3.low() odor4.low() odor5.low() odor6.low() odor7.low() clean0.low() clean1.low() clean2.low() clean3.high() clean4.high() clean5.high() clean6.high() clean7.high() odor0.close() odor1.close() odor2.close() odor3.close() odor6.close() odor7.close() clean0.close() clean1.close() clean2.close() clean3.close() clean6.close() clean7.close() LED = DAQSimpleDOTask('Dev3/port2/line2') LED.low() self.OdorOnCopy = DAQSimpleDOTask('Dev3/port2/line5') self.OdorOnCopy.low() waterR = DAQSimpleDOTask('Dev3/port2/line0') waterR.low() airpuff1 = DAQSimpleDOTask('Dev3/port2/line3') airpuff1.low() airpuff2 = DAQSimpleDOTask('Dev3/port2/line6') airpuff2.low() self.lickR = DAQSimpleDITask('Dev3/port2/line4') # EVENT CODES # video recording start / start trial = 101 # lick on = 11, lick off = 10 # right water on = 51, right water off = 50 # airpuff on = 81, off = 80 # reward odor on = 131, off = 130 # punish odor on = 141, off = 140 # reward sound on = 151, off = 150 # punish sound on = 161, off = 160 #create excel workbook self.wb = Workbook() self.ws = self.wb.active numtrials = 120 a = np.empty(int(numtrials / 4)) a.fill(2) b = np.empty(int(numtrials / 4)) b.fill(3) trialtypes = np.concatenate((np.ones( (int(numtrials / 4))), np.zeros((int(numtrials / 4))), a, b)) random.shuffle(trialtypes) print(trialtypes) # # arrays to randomize skipped trials for each trial type # num_to_skip = int((numtrials/5)*0.1) # skip0 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip0) # skip0 = np.concatenate((np.zeros(int(numtrials/10)),skip0)) # skip1 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip1) # skip1 = np.concatenate((np.zeros(int(numtrials/10)),skip1)) # skip2 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip2) # skip2 = np.concatenate((np.zeros(int(numtrials/10)),skip2)) # skip3 = np.concatenate((np.zeros(int(numtrials/10)-num_to_skip),np.ones(num_to_skip))) # random.shuffle(skip3) # skip3 = np.concatenate((np.zeros(int(numtrials/10)),skip3)) # counters for each trial type h = 0 i = 0 j = 0 k = 0 duration_rec_off = 6.5 duration_rec_on_before = 4 duration_odor_to_outcome = 1.3 duration_water_large = 0.2 duration_airpuff = 0.2 duration_rec_on_after = 8 sound_thread = SubMeasurementQThread(self.sound_action) self.interrupt_subthread.connect(sound_thread.interrupt) sound_thread.start() for t in range(0, numtrials): if bool(trialtypes[t]): self.settings.filename.update_value('reward_trial' + str(t)) else: self.settings.filename.update_value('punish_trial' + str(t)) self.recorder.create_file( self.settings.filename.value(), self.wide_cam.settings.frame_rate.value()) #print('turn on LED') LED.high() self.check_licking_1spout(1) #self.settings.save_video.update_value(True): print(t) self.settings.in_trial.update_value(True) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=101) self.check_licking_1spout(duration_rec_on_before) if trialtypes[t] == 0: print('odor reward trial ' + str(h)) print('opening odor port') reward_odor.high() self.OdorOnCopy.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=131) reward_odor_clean.low() self.check_licking_1spout(duration_odor_to_outcome) print('opening water valve') waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=51) self.check_licking_1spout(duration_water_large) print('closing odor port') reward_odor.low() self.OdorOnCopy.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=130) reward_odor_clean.high() waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=50) h += 1 self.wb.save(events_filename) elif trialtypes[t] == 1: print('punish odor trial ' + str(i)) print('opening odor port') punish_odor.high() self.OdorOnCopy.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=141) punish_odor_clean.low() self.check_licking_1spout(duration_odor_to_outcome) print('delivering airpuff') airpuff1.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=81) self.check_licking_1spout(duration_airpuff) print('closing odor port') punish_odor.low() self.OdorOnCopy.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=140) punish_odor_clean.high() airpuff1.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=80) i += 1 self.wb.save(events_filename) elif trialtypes[t] == 2: print('sound reward trial ' + str(j)) print('playing reward sound') self.settings.play_frequency.update_value(reward_sound) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=151) self.check_licking_1spout(duration_odor_to_outcome) print('opening water valve') waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=51) self.check_licking_1spout(duration_water_large) waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=50) j += 1 self.wb.save(events_filename) else: print('sound punish trial ' + str(k)) print('playing punish sound') self.settings.play_frequency.update_value(punish_sound) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=161) self.check_licking_1spout(duration_odor_to_outcome) print('delivering airpuff') airpuff1.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=81) self.check_licking_1spout(duration_airpuff) airpuff1.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=80) k += 1 self.wb.save(events_filename) self.check_licking_1spout(duration_rec_on_after) self.settings.in_trial.update_value(False) #self.settings.save_video.update_value(False): LED.low() self.wb.save(events_filename) self.check_licking_1spout(duration_rec_off) if self.interrupt_measurement_called: #tell subtherad to stop self.interrupt_subthread.emit() break reward_odor.close() reward_odor_clean.close() punish_odor.close() punish_odor_clean.close() waterR.close() waterR.close() airpuff1.close() airpuff2.close() LED.close() self.OdorOnCopy.close() print('FINISHED ASSOCIATION TRAINING') #sound_thread.stop() del sound_thread if self.settings.save_video.value(): self.recorder.close()
from ScopeFoundry.measurement import MeasurementQThread from AntCamHW.daq_do.daq_do_dev import DAQSimpleDOTask from AntCamHW.daq_di.daq_di_dev import DAQSimpleDITask import time import cv2 # this test roughly consumes 5 ml water # water = DAQSimpleDOTask('Dev1/port0/line0') water = DAQSimpleDOTask('Dev2_SELECT/port0/line0') timeout = time.time() + 1200 count_drop = 0 lickR = DAQSimpleDITask('Dev2_SELECT/port1/line0') water.high() time.sleep(0.3) water.low() while time.time() < timeout and count_drop < 200: lick = lickR.read() if not lick: count_drop += 1 print(count_drop) time.sleep(5) water.high() time.sleep(0.06) water.low() #else: # continue time.sleep(0.01)
class SelinaTraining(Measurement): def __init__(self): # please change this according to mouse self.mouse = 'C32' #OT-GC-2 self.phase = 'cond' #'cond', 'deg','C-control' self.condition = 'Pav' self.numtrials = 200 self.list = [7, 6] self.events_path = "C:/Users/MurthyLab/Desktop/Selina_lab_computer_data/experiment_data_2020_3_{0}/{1}/".format( self.condition, self.mouse) self.events_filename = datetime.datetime.now().strftime( "%Y-%m-%d-%H-%M") + '{}.xlsx'.format(self.phase) self.reward_odor_index = [1, 0] #odor list index change according to mi if self.condition == 'Operant': self.operant = True self.licknum = 1 else: self.operant = False self.licknum = 0 # pre training self.p_go = 0.4 #0.5 self.p_reward_go = 0.75 self.p_no_go = 0.2 #0.2 self.p_empty = 0.4 #0.3 if self.phase == 'cond': self.p_reward_empty = 0 # 0.3 else: # 'deg','C-control' self.p_reward_empty = 0.75 self.counter = np.zeros(6) self.duration_rec_on_before = 1 self.duration_odor_on = 1 self.duration_odor_to_action = 0 self.duration_action_window = 2.5 self.duration_water_large = 0.06 #0.1 self.duration_rec_on_after = 2 self.duration_ITI = np.random.exponential(2, size=self.numtrials) self.waterline = 0 self.filename = self.events_path + self.events_filename def run(self): try: os.makedirs(self.events_path) except OSError: print("The directory %s existed" % self.events_path) else: print("Successfully created the directory %s " % self.events_path) logname = self.filename[0:-5] + '.log' logging.basicConfig(filename=logname, level=logging.DEBUG) logging.info(self.__dict__) odors_cue = OdorGen(self.list) odors_cue.assign_odor() self.reward_odor, self.non_reward_odor = odors_cue.set_rewardodor( index=self.reward_odor_index) odors_cue.initiate() # odors_cue.odors_DAQ[i] print('odor done') self.waterR = DAQSimpleDOTask('Dev2_SELECT/port0/line{}'.format( self.waterline)) self.waterR.low() # self.OdorOnCopy = DAQSimpleDOTask('Dev3/port2/line5') # self.OdorOnCopy.low() self.lickR = DAQSimpleDITask('Dev2_SELECT/port1/line0') print('water done') # EVENT CODES # video recording start / start trial = 101 # end trial = 100 # lick on = 11, lick off = 10 # contingency reward odor on = 131, off = 130, water on = 51, right water off = 50 # contingency no reward odor on = 141, off = 140, water on = 61, right water off = 60 # non-contingency reward odor on = 151, off = 150, water on = 71, right water off = 70 # non-contingency no reward odor on = 161, off = 160, water on = 81, right water off = 80 # create excel workbook self.wb = Workbook() self.ws = self.wb.active #generate trial type # generate trial type trialtypes = np.zeros(self.numtrials) for i in range(int(self.numtrials / 20)): train_go = np.zeros(int(round(20 * self.p_go * self.p_reward_go))) # code 0 train_nogo = np.ones(int(20 * self.p_no_go)) # code 1 temp_comb1 = np.concatenate((train_go, train_nogo)) train_empty = np.ones( int(20 * self.p_empty * (1 - self.p_reward_empty))) * 2 # code 2 train_go_omission = np.ones( int(round(20 * self.p_go * (1 - self.p_reward_go)))) * 3 # code 3 train_unpredwater = np.ones( int(20 * self.p_empty * self.p_reward_empty)) * 4 # code 4 temp_comb1 = np.concatenate((temp_comb1, train_empty)) temp_comb1 = np.concatenate((temp_comb1, train_unpredwater)) temp_comb2 = np.concatenate((temp_comb1, train_go_omission)) random.shuffle(temp_comb2) trialtypes[20 * i:20 * (i + 1)] = temp_comb2 self.trialstype = trialtypes print('================== Trial Types =================') print(trialtypes) for t in range(0, self.numtrials): print('================================================') print('trial number: ', t) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=101) #trial start d = self.ws.cell(row=self.ws.max_row, column=3, value='trial{}'.format(int( trialtypes[t]))) #trial type # code: 0--go w rward; 1--no go; 2--empty; 3--go w/o reward self.check_licking_1spout(self.duration_rec_on_before) # main training program self.run_trial_type(int(trialtypes[t])) self.check_licking_1spout(self.duration_rec_on_after) # self.settings.save_video.update_value(False): self.check_licking_1spout(self.duration_ITI[t]) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=100) #end self.wb.save(self.filename) odors_cue.initiate() odors_cue.close() self.waterR.low() self.waterR.close() print('FINISHED ASSOCIATION TRAINING') def check_licking_1spout(self, interval, check_action=False): checkperiod = 0.005 timeout = time.time() + interval reward_on = True # this is used for Pav or Operant right_lick_last = 0 count = 0 while time.time() < timeout: right_lick = self.lickR.read() if right_lick != right_lick_last: if right_lick: print('Lick') d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=11) # self.save_training() if check_action: count += 1 else: d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=10) else: pass right_lick_last = right_lick time.sleep(checkperiod) if check_action and count >= self.licknum: print('licking activate reward') elif check_action and count < self.licknum: print('not enough licking') reward_on = False return reward_on def run_trial_type(self, types): odor_on = False reward_on = False if types == 0: print('go trial ' + str(int(self.counter[types]))) odor_on = True # contingency odor comes is_go = True r_code = [131, 130] w_code = [51, 50] self.run_odor_module(odor_on, is_go, r_code) self.check_licking_1spout(self.duration_odor_to_action) reward_on = self.check_licking_1spout( self.duration_action_window, self.operant) ### can be a problem self.run_reward_module(reward_on, w_code) elif types == 1: print('no go trial ' + str(int(self.counter[types]))) odor_on = True is_go = False r_code = [141, 140] w_code = [61, 60] self.run_odor_module(odor_on, is_go, r_code) self.check_licking_1spout(self.duration_odor_to_action + self.duration_action_window) reward_on = False self.run_reward_module(reward_on, w_code) elif types == 2: print('empty trial ' + str(int(self.counter[types]))) # odor false: control odor comes w_code = [71, 70] # not used # self.run_odor_module(odor_on, r_code) self.check_licking_1spout(self.duration_odor_on) self.check_licking_1spout(self.duration_odor_to_action + self.duration_action_window) reward_on = False self.run_reward_module(reward_on, w_code) elif types == 3: print('go omission trial ' + str(int(self.counter[types]))) odor_on = True # contingency odor comes is_go = True r_code = [131, 130] w_code = [51, 50] self.run_odor_module(odor_on, is_go, r_code) self.check_licking_1spout(self.duration_odor_to_action + self.duration_action_window) self.run_reward_module(reward_on, w_code) elif types == 4: print('unpredicted water trial ' + str(int(self.counter[types]))) w_code = [51, 50] self.check_licking_1spout(self.duration_odor_on) self.check_licking_1spout(self.duration_odor_to_action) reward_on = self.check_licking_1spout(self.duration_action_window, self.operant) self.run_reward_module(reward_on, w_code) self.counter[types] += 1 self.wb.save(self.filename) def run_odor_module(self, odor_on, is_go, r_code): if odor_on: print('opening odor port') if is_go: self.reward_odor.high() else: self.non_reward_odor.high() # self.OdorOnCopy.high() # ??? d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[0]) # self.save_training() self.check_licking_1spout(self.duration_odor_on) print('closing odor port') if is_go: self.reward_odor.low() else: self.non_reward_odor.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[1]) else: self.check_licking_1spout(self.duration_odor_on) def run_reward_module(self, reward_on, w_code): if reward_on: # modify! give water if licks three times within 1 s print('opening water valve') self.waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[0]) self.check_licking_1spout( self.duration_water_large) # this parameter hasn't een defined print('closing water valve') self.waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[1]) else: self.check_licking_1spout(self.duration_water_large) # def camera_action(self): # ''' # format the image properly # ''' # try: # wide_image = self.wide_cam.read() # wide_image_data = self.wide_cam.to_numpy(wide_image) # self.wide_disp_queue.put(wide_image_data) # # if self.settings.save_video.value() and self.settings.in_trial.value() : # self.recorder.save_frame(self.settings.filename.value(),wide_image) # # except Exception as ex: # print('Error : %s' % ex) def save_training(self): with open(self.filename, 'wb') as output: pickle.dump(self, output, pickle.HIGHEST_PROTOCOL)
class SelinaTraining(Measurement): def __init__(self): self.events_path = "C:/Users/MurthyLab/Desktop/Selina/experiment_data/C12/" self.events_filename = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M") +'.hdf5' self.filename = self.events_path + self.events_filename self.waterline = 0 self.list = [7, 6, 5, 4] self.reward_odor_index = 0 #odor list index self.numtrials = 4 self.p_cont_noncont = 0.5 self.p_USwCS = 0.5 self.p_USwoCS = 0.5 self.counter = np.zeros(4) self.duration_rec_on_before = 2 self.duration_odor_on = 0.5 self.duration_odor_to_outcome = 1.5 self.duration_water_large = 0.02 self.duration_rec_on_after = 4 self.duration_ITI = np.random.poisson(lam=2, size=self.numtrials) def run(self): print('a ha') odors_cue = OdorGen(self.list) odors_cue.assign_odor() self.reward_odor = odors_cue.set_rewardodor(index=self.reward_odor_index) odors_cue.initiate() # odors_cue.odors_DAQ[i] print('odor done') self.waterR = DAQSimpleDOTask('Dev2_SELECT/port0/line{}'.format(self.waterline)) self.waterR.low() # self.OdorOnCopy = DAQSimpleDOTask('Dev3/port2/line5') # self.OdorOnCopy.low() self.lickR = DAQSimpleDITask('Dev2_SELECT/port1/line0') print('water done') # EVENT CODES # video recording start / start trial = 101 # lick on = 11, lick off = 10 # contingency reward odor on = 131, off = 130, water on = 51, right water off = 50 # contingency no reward odor on = 141, off = 140, water on = 61, right water off = 60 # non-contingency reward odor on = 151, off = 150, water on = 71, right water off = 70 # non-contingency no reward odor on = 161, off = 160, water on = 81, right water off = 80 # create excel workbook self.wb = Workbook() self.ws = self.wb.active print('book done') #generate trial type # generate trial type cont_reward = np.zeros(int(self.numtrials * self.p_cont_noncont * self.p_USwCS)) # code 0 cont_noreward = np.ones(int(self.numtrials * self.p_cont_noncont * (1 - self.p_USwCS))) # code 1 temp_comb1 = np.concatenate((cont_reward, cont_noreward)) noncont_reward = np.ones(int(self.numtrials * (1 - self.p_cont_noncont) * self.p_USwoCS)) * 2 # code 2 noncont_noreward = np.ones(int(self.numtrials * (1 - self.p_cont_noncont) * (1 - self.p_USwoCS))) * 3 # code 3 temp_comb2 = np.concatenate((noncont_noreward, noncont_reward)) trialtypes = np.concatenate((temp_comb1, temp_comb2)) random.shuffle(trialtypes) print('================== Trial Types =================') print(trialtypes) for t in range(0, self.numtrials): print('================================================') print('trial number: ', t) print() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=101) self.check_licking_1spout(self.duration_rec_on_before) # main training program self.run_trial_type(int(trialtypes[t])) self.check_licking_1spout(self.duration_rec_on_after) # self.settings.save_video.update_value(False): self.wb.save(self.events_path+'.xlsm') self.check_licking_1spout(self.duration_ITI[t]) odors_cue.initiate() odors_cue.close() self.waterR.low() self.waterR.close() print('FINISHED ASSOCIATION TRAINING') def check_licking_1spout(self, interval): checkperiod = 0.01 timeout = time.time() + interval right_lick_last = 0 while time.time() < timeout: right_lick = self.lickR.read() if right_lick != right_lick_last: if right_lick: print('Lick') d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=11) # self.save_training() else: d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=10) # self.save_training() else: pass right_lick_last = right_lick time.sleep(checkperiod) def run_trial_type(self,types): odor_on = False reward_on = False if types == 0: print('contingency reward trial ' + str(int(self.counter[types]))) print('opening odor port') odor_on = True reward_on = True r_code = [131, 130] w_code = [51, 50] self.run_odor_module(odor_on, r_code) self.check_licking_1spout(self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) elif types == 1: print('contingency no reward trial ' + str(int(self.counter[types]))) print('opening odor port') odor_on = True r_code = [141, 140] w_code = [61, 60] self.run_odor_module(odor_on, r_code) self.check_licking_1spout(self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) elif types == 2: print('non-contingency reward trial ' + str(int(self.counter[types]))) reward_on = True r_code = [151, 150] w_code = [71, 70] self.run_odor_module(odor_on, r_code) self.check_licking_1spout(self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) else: print('non-contingency no reward trial ' + str(int(self.counter[types]))) r_code = [161, 160] w_code = [71, 70] self.run_odor_module(odor_on, r_code) self.check_licking_1spout(self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) self.counter[types] += 1 self.wb.save(self.events_path+'.xlsm') def run_odor_module(self,odor_on, r_code): if odor_on: self.reward_odor.high() # self.OdorOnCopy.high() # ??? d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[0]) # self.save_training() time.sleep(self.duration_odor_on) print('closing odor port') self.reward_odor.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[1]) # self.save_training() else: d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[0]) # self.save_training() time.sleep(self.duration_odor_on) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[1]) # self.save_training() def run_reward_module(self ,reward_on, w_code): if reward_on: # modify! give water if licks three times within 1 s print('opening water valve') self.waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[0]) # self.save_training() self.check_licking_1spout(self.duration_water_large) # this parameter hasn't een defined print('closing water valve') self.waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[1]) # self.save_training() else: d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[0]) # self.save_training() time.sleep(self.duration_water_large) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[1]) # self.save_training() # def camera_action(self): # ''' # format the image properly # ''' # try: # wide_image = self.wide_cam.read() # wide_image_data = self.wide_cam.to_numpy(wide_image) # self.wide_disp_queue.put(wide_image_data) # # if self.settings.save_video.value() and self.settings.in_trial.value() : # self.recorder.save_frame(self.settings.filename.value(),wide_image) # # except Exception as ex: # print('Error : %s' % ex) def save_training(self): '''save object in hdf5 file format Args: filename: str path to the hdf5 file containing the saved object ''' if '.hdf5' in self.filename: save_dict_to_hdf5(self.__dict__, self.filename) else: raise Exception("Filename not supported")
clean0 = DAQSimpleDOTask('Dev3/port0/line1') odor1 = DAQSimpleDOTask('Dev3/port0/line2') clean1 = DAQSimpleDOTask('Dev3/port0/line3') odor2 = DAQSimpleDOTask('Dev3/port0/line4') clean2 = DAQSimpleDOTask('Dev3/port0/line5') odor3 = DAQSimpleDOTask('Dev3/port0/line6') clean3 = DAQSimpleDOTask('Dev3/port0/line7') odor4 = DAQSimpleDOTask('Dev3/port1/line0') clean4 = DAQSimpleDOTask('Dev3/port1/line1') odor5 = DAQSimpleDOTask('Dev3/port1/line2') clean5 = DAQSimpleDOTask('Dev3/port1/line3') odor6 = DAQSimpleDOTask('Dev3/port1/line4') clean6 = DAQSimpleDOTask('Dev3/port1/line5') odor7 = DAQSimpleDOTask('Dev3/port1/line6') clean7 = DAQSimpleDOTask('Dev3/port1/line7') odor0.low() odor1.low() odor2.low() odor3.low() odor6.low() odor7.low() clean0.low() clean1.low() clean2.low() clean3.low() clean6.low() clean7.low() # testing clean4.high() odor4.low()
class SelinaTraining(Measurement): def __init__(self): # please change this according to mouse self.mouse = 'C22' #OT-GC-2 self.phase = 'deg' self.condition = 'Pav' self.numtrials = 160 self.list = [7, 6] self.events_path = "C:/Users/MurthyLab/Desktop/Selina/experiment_data_2020_2_{0}/{1}/".format( self.condition, self.mouse) + datetime.datetime.now().strftime("%Y-%m-%d") + "/" self.events_filename = datetime.datetime.now().strftime( "%Y-%m-%d-%H-%M") + '{}.xlsx'.format(self.phase) self.reward_odor_index = [1, 0] #odor list index change according to mi if self.condition == 'Operant': self.operant = True self.licknum = 1 else: self.operant = False self.licknum = 0 #C22, C21 # self.p_conbynoncon = 0.5 # total water volumn should keep the same # self.p_reward_USwCS = 0.8 #self.p_conbynoncon*self.p_reward_USwCS + (1-self.p_conbynoncon)*self.p_USwoCs = p_pretraining_go # self.p_reward_USwoCS = 0.4 #C17, 19, 20, 18 self.p_conbynoncon = 0.5 # total water volumn should keep the same self.p_reward_USwCS = 0.8 # self.p_conbynoncon*self.p_reward_USwCS + (1-self.p_conbynoncon)*self.p_USwoCs = p_pretraining_go self.p_reward_USwoCS = 0.8 self.counter = np.zeros(4) self.duration_rec_on_before = 2.5 self.duration_odor_on = 1 self.duration_odor_to_action = 0 self.duration_action_window = 2.5 self.duration_water_large = 0.08 self.duration_rec_on_after = 3 self.duration_ITI = np.random.exponential(2, size=self.numtrials) self.waterline = 0 self.filename = self.events_path + self.events_filename def generate_trial(self): total_num = 20 #trial type distribution for every 20 trials are the same, the order is shuffled ## 0: trial type 1; 1: trial type 2; 2: trial type 3; 3: trial type 4 percent_1 = round((1 - self.p_conbynoncon) * self.p_reward_USwoCS, 2) #non-cont rewarded# percent_3 = round( (1 - self.p_conbynoncon) * (1 - self.p_reward_USwoCS), 2) # non-cont no reward percent_4 = round(self.p_conbynoncon * (1 - self.p_reward_USwCS), 2) # cont no reward #go omission percent_2 = round(1 - percent_1 - percent_3 - percent_4, 2) # cont reward #type 2 assert percent_2 >= 0, print("invalid ratio") sum_freq = percent_1 + percent_2 + percent_3 + percent_4 assert abs(sum_freq - 1) < 1e-3, print( "Sum of frequent ({}) not equal to 1".format(sum_freq)) num_1 = int(total_num * percent_1) num_3 = int(total_num * percent_3) num_4 = int(total_num * percent_4) num_2 = int(total_num * percent_2) print('Type0:non-contingency reward', num_1, '\nType1:contingency reward', 20 - num_1 - num_3 - num_4, '\nType2:non-contingency non reward', num_3, '\nType3:contingency non reward', num_4, ' \nin every 20 trials.') data = [0] * num_1 + [2] * num_3 + [1] * num_2 + [3] * num_4 trial_data = [] for token in range(int(self.numtrials / 20)): random.shuffle(data) trial_data += data return trial_data def run(self): try: os.makedirs(self.events_path) except OSError: print("The directory %s existed" % self.events_path) else: print("Successfully created the directory %s " % self.events_path) logname = self.filename[0:-5] + '.log' logging.basicConfig(filename=logname, level=logging.DEBUG) logging.info(self.__dict__) odors_cue = OdorGen(self.list) odors_cue.assign_odor() self.reward_odor, self.non_reward_odor = odors_cue.set_rewardodor( index=self.reward_odor_index) odors_cue.initiate() # odors_cue.odors_DAQ[i] print('odor done') self.waterR = DAQSimpleDOTask('Dev2_SELECT/port0/line{}'.format( self.waterline)) self.waterR.low() # self.OdorOnCopy = DAQSimpleDOTask('Dev3/port2/line5') # self.OdorOnCopy.low() self.lickR = DAQSimpleDITask('Dev2_SELECT/port1/line0') print('water done') # EVENT CODES # video recording start / start trial = 101 # end trial = 100 # lick on = 11, lick off = 10 # contingency reward odor on = 131, off = 130, water on = 51, right water off = 50 # contingency no reward odor on = 141, off = 140, water on = 61, right water off = 60 # non-contingency reward odor on = 151, off = 150, water on = 71, right water off = 70 # non-contingency no reward odor on = 161, off = 160, water on = 81, right water off = 80 # create excel workbook self.wb = Workbook() self.ws = self.wb.active #generate trial type # generate trial type trialtypes = self.generate_trial() self.trialtype = trialtypes print('================== Trial Types =================') print(trialtypes) for t in range(0, self.numtrials): print('================================================') print('trial number: ', t) print() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=101) if int(trialtypes[t]) == 0: trialcode = "noncontR" elif int(trialtypes[t]) == 1: trialcode = 'contR' elif int(trialtypes[t]) == 2: trialcode = "noncontNR" else: trialcode = 'contNR' d = self.ws.cell(row=self.ws.max_row, column=3, value='trial_{}'.format(trialcode)) #trial type self.check_licking_1spout(self.duration_rec_on_before) # main training program self.run_trial_type(int(trialtypes[t]), t) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=100) self.wb.save(self.filename) odors_cue.initiate() odors_cue.close() self.waterR.low() self.waterR.close() print('FINISHED ASSOCIATION TRAINING') def check_licking_1spout(self, interval, check_action=False): checkperiod = 0.01 timeout = time.time() + interval reward_on = True right_lick_last = 0 count = 0 while time.time() < timeout: right_lick = self.lickR.read() if right_lick != right_lick_last: if right_lick: print('Lick') d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=11) # self.save_training() if check_action: count += 1 else: d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=10) else: pass right_lick_last = right_lick time.sleep(checkperiod) if check_action and count >= self.licknum: print('licking activate reward') elif check_action and count < self.licknum: print('not enough licking') reward_on = False return reward_on def run_trial_type(self, types, t): odor_on = False reward_on = False if types == 0: print('non-contingency odor reward trial ' + str(int(self.counter[types]))) # contingency odor comes r_code = [151, 150] w_code = [51, 50] self.run_odor_module(odor_on, r_code) self.check_licking_1spout(self.duration_odor_to_action + self.duration_action_window) reward_on = True self.run_reward_module(reward_on, w_code) self.check_licking_1spout(self.duration_rec_on_after) self.check_licking_1spout(self.duration_ITI[t]) elif types == 1: print('contingency odor reward trial ' + str(int(self.counter[types]))) odor_on = True r_code = [131, 130] w_code = [51, 50] self.run_odor_module(odor_on, r_code) self.check_licking_1spout(self.duration_odor_to_action) reward_on = self.check_licking_1spout(self.duration_action_window, self.operant) self.run_reward_module(reward_on, w_code) self.check_licking_1spout(self.duration_rec_on_after) self.check_licking_1spout(self.duration_ITI[t]) elif types == 2: print(' non-contingency no reward trial ' + str(int(self.counter[types]))) # odor false: control odor comes w_code = [51, 50] self.check_licking_1spout(self.duration_odor_on) self.check_licking_1spout(self.duration_odor_to_action + self.duration_action_window) self.run_reward_module(reward_on, w_code) self.check_licking_1spout(self.duration_rec_on_after) self.check_licking_1spout(self.duration_ITI[t]) elif types == 3: print('contingency odor no reward trial ' + str(int(self.counter[types]))) odor_on = True r_code = [131, 130] w_code = [51, 50] self.run_odor_module(odor_on, r_code) self.check_licking_1spout( self.duration_odor_to_action) ### can be a problem self.check_licking_1spout(self.duration_action_window) self.run_reward_module(reward_on, w_code) self.check_licking_1spout(self.duration_rec_on_after) self.check_licking_1spout(self.duration_ITI[t]) self.counter[types] += 1 self.wb.save(self.filename) def run_odor_module(self, odor_on, r_code): if odor_on: print('opening odor port') self.reward_odor.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[0]) # self.save_training() self.check_licking_1spout(self.duration_odor_on) print('closing odor port') self.reward_odor.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[1]) else: self.check_licking_1spout(self.duration_odor_on) def run_reward_module(self, reward_on, w_code): if reward_on: # modify! give water if licks three times within 1 s print('opening water valve') self.waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[0]) self.check_licking_1spout( self.duration_water_large) # this parameter hasn't een defined print('closing water valve') self.waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[1]) else: self.check_licking_1spout(self.duration_water_large) # def camera_action(self): # ''' # format the image properly # ''' # try: # wide_image = self.wide_cam.read() # wide_image_data = self.wide_cam.to_numpy(wide_image) # self.wide_disp_queue.put(wide_image_data) # # if self.settings.save_video.value() and self.settings.in_trial.value() : # self.recorder.save_frame(self.settings.filename.value(),wide_image) # # except Exception as ex: # print('Error : %s' % ex) def save_training(self): with open(self.filename, 'wb') as output: pickle.dump(self, output, pickle.HIGHEST_PROTOCOL)
class SelinaTraining(Measurement): # this is the name of the measurement that ScopeFoundry uses # when displaying your measurement and saving data related to it name = "selina_training" interrupt_subthread = QtCore.Signal(()) # def __init__(self): # super().__init__() # # EVENT CODES # # video recording start / start trial = 101 # # lick on = 11, lick off = 10 # # right # # airpuff on = 81, off = 80 # # # contingency reward odor on = 131, off = 130, water on = 51, right water off = 50 # # contingency no reward odor on = 141, off = 140, water on = 61, right water off = 60 # # non-contingency reward odor on = 151, off = 150, water on = 71, right water off = 70 # # non-contingency no reward odor on = 161, off = 160, water on = 81, right water off = 80 # # self.events_filename = '2019-7-17-test.xlsx' # self.reward_odor_index = 0 # # self.duration_rec_off = 6.5 # self.duration_rec_on_before = 4 # change this to exponential decay # self.duration_odor_to_outcome = 1.3 # self.duration_water_large = 0.2 # self.duration_rec_on_after = 8 # self.duration_odor_on = 0.5 # # self.lines = [0, 1, 2, 3] # self.counter = np.zeros(len(self.lines)) # # self.numtrials = 200 # self.p_cont_noncont = 0.5 # self.p_USwCS = 0.5 # self.p_USwoCS = 0.5 def setup(self): """ Runs once during App initialization. This is the place to load a user interface file, define settings, and set up data structures. """ # Define ui file to be used as a graphical interface # This file can be edited graphically with Qt Creator # sibling_path function allows python to find a file in the same folder # as this python module self.ui_filename = sibling_path(__file__, "ant_watch_plot.ui") # Load ui file and convert it to a live QWidget of the user interface self.ui = load_qt_ui_file(self.ui_filename) # Measurement Specific Settings # This setting allows the option to save data to an h5 data file during a run # All settings are automatically added to the Microscope user interface self.settings.New('save_h5', dtype=bool, initial=True) self.settings.New('save_video', dtype=bool, initial=False) # x and y is for transmitting signal self.settings.New('x', dtype=float, initial=32, ro=True, vmin=0, vmax=63.5) self.settings.New('y', dtype=float, initial=32, ro=True, vmin=0, vmax=63.5) # added by Nune self.settings.New('filename', dtype=str, initial='trial') self.settings.New('in_trial', dtype=bool, initial=False) self.settings.New('view_only', dtype=bool, initial=False) self.settings.New('lick_status', dtype=int, initial=0) # added for Selina # connect lick indicator to settings self.settings.New('lick_on', dtype=bool, initial=False, ro=True) # change the lick indicator into blue light self.ui.right_lick_ind_checkBox.setStyleSheet( 'QCheckBox{color:blue;}QCheckBox::indicator:checked{image: url(./icons/c_b.png);}QCheckBox::indicator:unchecked{image: url(./icons/uc_b.png);}' ) # Define how often to update display during a run self.display_update_period = 0.01 # Convenient reference to the hardware used in the measurement self.wide_cam = self.app.hardware['HD Webcam C270'] # self.recorder = self.app.hardware['flirrec'] # setup experiment condition #self.wide_cam.settings.frame_rate.update_value(8) self.wide_cam.read_from_hardware() self.vc = cv2.VideoCapture(0) self.vc.set(cv2.CAP_FFMPEG, True) self.vc.set(cv2.CAP_PROP_FPS, 30) def setup_figure(self): """ Runs once during App initialization, after setup() This is the place to make all graphical interface initializations, build plots, etc. """ # connect ui widgets to measurement/hardware settings or functions self.ui.start_pushButton.clicked.connect(self.start) self.ui.interrupt_pushButton.clicked.connect(self.interrupt) # Set up pyqtgraph graph_layout in the UI self.wide_cam_layout = pg.GraphicsLayoutWidget() self.ui.wide_cam_groupBox.layout().addWidget(self.wide_cam_layout) # added by selina # Set up pyqtgraph graph_layout in the UI self.licking_layout = pg.GraphicsLayoutWidget() self.ui.plot_groupBox.layout().addWidget(self.licking_layout) # Create PlotItem object (a set of axes) self.plot = self.licking_layout.addPlot(title="Sine Wave Readout Plot") # Create PlotDataItem object ( a scatter plot on the axes ) self.optimize_plot_line = self.plot.plot([0]) # create camera image graphs self.wide_cam_view = pg.ViewBox() # rval, frame = self.vc.read() self.wide_cam_layout.addItem(self.wide_cam_view) self.wide_cam_image = pg.ImageItem() self.wide_cam_view.addItem(self.wide_cam_image) # counter used for reducing refresh rate self.wide_disp_counter = 0 # connect setting to user interface self.settings.lick_on.connect_to_widget(self.ui.lick_checkBox) def update_display(self): """ Displays (plots) the numpy array self.buffer. This function runs repeatedly and automatically during the measurement run. its update frequency is defined by self.display_update_period """ # check availability of display queue of the wide camera try: ret, frame = self.vc.read() self.wide_cam_image.setImage( np.flipud(np.fliplr(frame[:, :, 2::-1].transpose(1, 0, 2)))) except Exception as ex: print("Error: %s" % ex) def run(self): """ Runs when measurement is started. Runs in a separate thread from GUI. It should not update the graphical interface directly, and should only focus on data acquisition. """ # # first, create a data file # if self.settings['save_h5']: # # if enabled will create an HDF5 file with the plotted data # # first we create an H5 file (by default autosaved to app.settings['save_dir'] # # This stores all the hardware and app meta-data in the H5 file # self.h5file = h5_io.h5_base_file(app=self.app, measurement=self) # # # create a measurement H5 group (folder) within self.h5file # # This stores all the measurement meta-data in this group # self.h5_group = h5_io.h5_create_measurement_group(measurement=self, h5group=self.h5file) # # # create an h5 dataset to store the data # self.buffer_h5 = self.h5_group.create_dataset(name = 'buffer', # shape = self.buffer.shape, # dtype = self.buffer.dtype) # We use a try/finally block, so that if anything goes wrong during a measurement, # the finally block can clean things up, e.g. close the data file object. # self.wide_cam._dev.set_buffer_count(500) # if self.settings.save_video.value(): # save_dir = self.app.settings.save_dir.value() # data_path = os.path.join(save_dir, self.app.settings.sample.value()) # try: # os.makedirs(data_path) # except OSError: # print('directory already exists, writing to existing directory') # # self.recorder.settings.path.update_value(data_path) # frame_rate = self.wide_cam.settings.frame_rate.value() # self.recorder.create_file('wide_mov',frame_rate) # # # create a subthread and connect it to the interrupt subthread signal # self.wide_disp_queue = queue.Queue(1000) # self.camera_thread = SubMeasurementQThread(self.camera_action) # self.interrupt_subthread.connect(self.camera_thread.interrupt) # #start camera # self.wide_cam.start() # # #start camera subthread # self.camera_thread.start() self.events_filename = '2019-7-17-test.xlsx' self.reward_odor_index = 0 self.duration_rec_off = 6.5 self.duration_rec_on_before = 4 # change this to exponential decay self.duration_odor_to_outcome = 1.3 self.duration_water_large = 0.2 self.duration_rec_on_after = 8 self.duration_odor_on = 0.5 self.lines = [0, 1, 2, 3] self.counter = np.zeros(4) self.numtrials = 200 self.p_cont_noncont = 0.5 self.p_USwCS = 0.5 self.p_USwoCS = 0.5 odors_cue = OdorGen(self.lines) odors_cue.assign_odor() self.reward_odor = odors_cue.set_rewardodor( index=self.reward_odor_index) odors_cue.initiate() # odors_cue.odors_DAQ[i] print('odor ready') self.waterR = DAQSimpleDOTask('Dev1/port0/line2') self.waterR.low() # self.OdorOnCopy = DAQSimpleDOTask('Dev3/port2/line5') # self.OdorOnCopy.low() self.lickR = DAQSimpleDITask('Dev2_SELECT/port1/line0') print('water ready') # create excel workbook self.wb = Workbook() self.ws = self.wb.active print('book ready') #generate trial type cont_reward = np.zeros( int(self.numtrials * self.p_cont_noncont * self.p_USwCS)) # code 0 cont_noreward = np.ones( int(self.numtrials * self.p_cont_noncont * (1 - self.p_USwCS))) # code 1 temp_comb1 = np.concatenate((cont_reward, cont_noreward)) noncont_reward = np.ones( int(self.numtrials * (1 - self.p_cont_noncont) * self.p_USwoCS)) * 2 # code 2 noncont_noreward = np.ones( int(self.numtrials * (1 - self.p_cont_noncont) * (1 - self.p_USwoCS))) * 3 # code 3 temp_comb2 = np.concatenate((noncont_noreward, noncont_reward)) trialtypes = np.concatenate((temp_comb1, temp_comb2)) random.shuffle(trialtypes) print('================== Trial Types =================') print(trialtypes) for t in range(0, self.numtrials): print('================================================') print('trial number: ', t) print() self.settings.in_trial.update_value(True) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=101) # check lisking self.check_licking_1spout(self.duration_rec_on_before) # main training program self.run_trial_type(int(trialtypes[t])) # check licking self.check_licking_1spout(self.duration_rec_on_after) self.settings.in_trial.update_value(False) # self.settings.save_video.update_value(False): self.wb.save(self.events_filename) self.check_licking_1spout(self.duration_rec_off) if self.interrupt_measurement_called: # tell subtherad to stop self.interrupt_subthread.emit() break odors_cue.initiate() odors_cue.close() self.waterR.low() self.waterR.close() print('FINISHED ASSOCIATION TRAINING') if self.settings.save_video.value: self.recorder.close() def check_licking_1spout(self, interval): checkperiod = 0.01 timeout = time.time() + interval right_lick_last = 0 while time.time() < timeout: right_lick = self.lickR.read() if right_lick != right_lick_last: if right_lick: self.settings.lick_status.update_value(11) print('Lick') d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=11) self.settings.lick_on.update_value(True) else: self.settings.lick_status.update_value(10) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=10) self.settings.lick_on.update_value(False) else: self.settings.lick_status.update_value(0) right_lick_last = right_lick time.sleep(checkperiod) def run_trial_type(self, types): odor_on = False reward_on = False if types == 0: print('contingency reward trial ' + str(int(self.counter[types]))) print('opening odor port') odor_on = True reward_on = True r_code = [131, 130] w_code = [51, 50] self.run_odor_module(odor_on, r_code) self.check_licking_1spout( self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) elif types == 1: print('contingency no reward trial ' + str(int(self.counter[types]))) print('opening odor port') odor_on = True r_code = [141, 140] w_code = [61, 60] self.run_odor_module(odor_on, r_code) self.check_licking_1spout( self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) elif types == 2: print('non-contingency reward trial ' + str(int(self.counter[types]))) reward_on = True r_code = [151, 150] w_code = [71, 70] self.run_odor_module(odor_on, r_code) self.check_licking_1spout( self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) else: print('non-contingency no reward trial ' + str(int(self.counter[types]))) r_code = [161, 160] w_code = [71, 70] self.run_odor_module(odor_on, r_code) self.check_licking_1spout( self.duration_odor_to_outcome) ### can be a problem self.run_reward_module(reward_on, w_code) self.counter[types] += 1 self.wb.save(self.events_filename) def run_odor_module(self, odor_on, r_code): if odor_on: self.reward_odor.high() # self.OdorOnCopy.high() # ??? d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[0]) time.sleep(self.duration_odor_on) print('closing odor port') self.reward_odor.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[1]) else: d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[0]) time.sleep(self.duration_odor_on) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=r_code[1]) def run_reward_module(self, reward_on, w_code): if reward_on: # modify! give water if licks three times within 1 s print('opening water valve') self.waterR.high() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[0]) self.check_licking_1spout( self.duration_water_large) # this parameter hasn't een defined print('closing water valve') self.waterR.low() d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[1]) else: d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[0]) time.sleep(self.duration_water_large) d = self.ws.cell(row=(self.ws.max_row + 1), column=1, value=time.clock()) d = self.ws.cell(row=self.ws.max_row, column=2, value=w_code[1])