Esempio n. 1
0
    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()
Esempio n. 2
0
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):
        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')
from ScopeFoundry import Measurement
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
    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')
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")
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)
    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')
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])
    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()