Ejemplo n.º 1
0
class Controller:
    REFRESH_INTERVAL = 300 #ms
    def __init__(self, session):
        self.app = wx.App(False) 

        self.session = session

        self.view = View(None, name=self.session.subj.name, n_lick_show=self.session.lr.ACCUM_SIZE)

        # bindings
        self.view.start_button.Bind(wx.EVT_BUTTON, self.run_session)
        self.view.pause_button.Bind(wx.EVT_BUTTON, self.pause_session)
        self.view.rewardl_but.Bind(wx.EVT_BUTTON, lambda evt, temp=self.session.L: self.give_reward(evt, temp))
        self.view.rewardr_but.Bind(wx.EVT_BUTTON, lambda evt, temp=self.session.R: self.give_reward(evt, temp))
        self.view.puffl_but.Bind(wx.EVT_BUTTON, lambda evt, temp=self.session.L: self.give_puff(evt, temp))
        self.view.puffr_but.Bind(wx.EVT_BUTTON, lambda evt, temp=self.session.R: self.give_puff(evt, temp))

        self.view.Bind(wx.EVT_CLOSE, self.on_close)
        self.view.Show()
    def run(self):
        self.trial_n = self.session.trial_idx
        self.update_vals()
        self.app.MainLoop()
    
    def give_reward(self, evt, side):
        self.session.spout.go(side)
    def give_puff(self, evt, side):
        self.session.stimulator.go(side, dur=self.session.stim_duration)
    def pretty_time(self, t):
        if t<60:
            return '%0.0f s'%t
        else:
            return '%0.0f m, %0.0f s'%(np.floor(t/60.),t%60.)
    def update_vals(self):
        # values
        self.view.trial_n_widg.SetValue("%s (%s)"%(str(self.session.valid_trial_idx),str(self.session.trial_idx)))
        self.view.session_runtime_widg.SetValue(self.pretty_time(self.session.session_runtime))
        self.view.trial_runtime_widg.SetValue(self.pretty_time(self.session.trial_runtime))

        # plots
        self.view.set_lick_data(self.session.lr.get_accum())

        # movie
        self.view.panel_mov.set_frame(self.session.cam.get_current_frame(self.session.cam.cS))
        
        
        # trial
        trn = self.session.trial_idx
        if trn != self.trial_n and self.session.session_on:
            self.trial_n = trn
            if self.session.use_trials:
                self.view.set_trial_data(self.session.trials[self.trial_n], self.session.stim_phase_intro_duration, self.session.phase_durations[self.session.PHASE_DELAY], self.session.stim_phase_end_duration)
            self.view.set_perf_data(*self.session.get_cum_performance())
            self.view.rewarded_widg.SetValue(str(self.session.rewards_given))
            self.view.perc_widg.SetValue(' / '.join(['%0.2f [%i]'%(p,n) for p,n in zip(self.session.percentages[::-1], self.session.side_ns[::-1])]))
            self.view.bias_widg.SetValue(' / '.join(['%0.2f'%s for s in self.session.bias_correction_percentages[::-1]])+' [%i]'%self.session.bias_correction_window)
            self.view.pvalid_widg.SetValue('%0.2f'%self.session.perc_valid)
        # controls
        if self.session.session_complete or self.session.session_kill:
            self.view.start_button.Disable()

        # pauses
        if self.session.paused:
            self.view.pause_button.SetLabel('Unpause')
            self.view.pause_button.SetBackgroundColour((0,255,0))
            self.view.start_button.Disable()
        elif not self.session.paused:
            self.view.pause_button.SetLabel('Pause')
            self.view.pause_button.SetBackgroundColour((0,150,150))
            if self.session.session_on and not self.session.session_kill:
                self.view.start_button.Enable()
            
        self.update_timer = wx.CallLater(self.REFRESH_INTERVAL, self.update_vals)

    def run_session(self, evt):
        if not self.session.session_on:
            self.run_th = threading.Thread(target=self.session.run)
            self.run_th.start()
            self.view.start_button.SetLabel('End Session')
            self.view.start_button.SetBackgroundColour((255,0,0))
            self.view.pause_button.Enable()
        elif self.session.session_on:
            self.session.session_kill = True
            self.view.start_button.Disable()
            self.view.puffr_but.Disable()
            self.view.puffl_but.Disable()
            self.view.rewardr_but.Disable()
            self.view.rewardl_but.Disable()
            self.view.pause_button.Disable()
    def pause_session(self, evt):
        if not self.session.paused:
            self.session.paused += 1
            self.view.pause_button.SetLabel('Unpause')
            self.view.pause_button.SetBackgroundColour((0,255,0))
            self.view.start_button.Disable()
        elif self.session.paused:
            self.session.paused = max(self.session.paused-1,0)
            self.view.pause_button.SetLabel('Pause')
            self.view.pause_button.SetBackgroundColour((0,100,200))
            self.view.start_button.Enable()

    def on_close(self, evt):
        if self.session.session_on:
            dlg = wx.MessageDialog(self.view, message='End session before closing interface.', caption='Session is active.', style=wx.OK)
            res = dlg.ShowModal()
            dlg.Destroy()
        
        else:
            dlg = wx.MessageDialog(self.view, message="Some data may be lost.", caption="Exit Experiment?", style=wx.OK|wx.CANCEL)
            result = dlg.ShowModal()
            dlg.Destroy()
            if result == wx.ID_OK:
                self.update_timer.Stop()
                self.view.Destroy()