def __init__(self,parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(nTrials=400,winsize=10)

         # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam('Time valve left',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveC'] = paramgui.NumericParam('Time valve center',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam('Time valve right',value=0.03,
                                                               units='s',group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')
        
        self.params['outcomeMode'] = paramgui.MenuParam('Outcome mode',
                                                        ['sides_direct','direct','on_next_correct',
                                                         'only_if_correct','simulated'],
                                                         value=3,group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam('Anti-bias mode',
                                                        ['off','repeat_mistake'],
                                                        value=0,group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTargetMean'] = paramgui.NumericParam('Mean delay to target',value=0.3,
                                                        units='s',group='Timing parameters')
        self.params['delayToTargetHalfRange'] = paramgui.NumericParam('+/-',value=0.05,
                                                        units='s',group='Timing parameters')
        self.params['delayToTarget'] = paramgui.NumericParam('Delay to target',value=0.3,
                                                        units='s',group='Timing parameters',
                                                        enabled=False,decimals=3)
        self.params['targetDuration'] = paramgui.NumericParam('Target duration',value=0.1,
                                                        units='s',group='Timing parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam('Reward availability',value=4,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeError'] = paramgui.NumericParam('Punishment (error)',value=0,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam('Punishment (early)',value=0,
                                                        units='s',group='Timing parameters')
        timingParams = self.params.layout_group('Timing parameters')

        self.params['trialsPerBlock'] = paramgui.NumericParam('Trials per block',value=300,
                                                              units='trials (0=no-switch)',
                                                              group='Switching parameters')
        self.params['currentBlock'] = paramgui.MenuParam('Current block',
                                                         ['mid_boundary','low_boundary','high_boundary'],
                                                         value=0,group='Switching parameters')
        switchingParams = self.params.layout_group('Switching parameters')


        self.params['psycurveMode'] = paramgui.MenuParam('PsyCurve Mode',
                                                         ['off','uniform'],
                                                         value=0,group='Psychometric parameters')
        psychometricParams = self.params.layout_group('Psychometric parameters')


        self.params['automationMode'] = paramgui.MenuParam('Automation Mode',
                                                           ['off','increase_delay'],
                                                           value=0,group='Automation')
        automationParams = self.params.layout_group('Automation')

        # 5000, 7000, 9800 (until 2014-03-19)
        self.params['highFreq'] = paramgui.NumericParam('High freq',value=16000,
                                                        units='Hz',group='Sound parameters')
        self.params['midFreq'] = paramgui.NumericParam('Middle freq',value=7000,
                                                        units='Hz',group='Sound parameters')
        self.params['lowFreq'] = paramgui.NumericParam('Low freq',value=3000,
                                                        units='Hz',group='Sound parameters')
        self.params['targetFrequency'] = paramgui.NumericParam('Target freq',value=0,
                                                        units='Hz',enabled=False,group='Sound parameters')
        self.params['targetIntensityMode'] = paramgui.MenuParam('Intensity mode',
                                                               ['fixed','randMinus20'],
                                                               value=1,group='Sound parameters')
        self.params['targetMaxIntensity'] = paramgui.NumericParam('Max intensity',value=60,
                                                        units='dB-SPL',group='Sound parameters')
        self.params['targetIntensity'] = paramgui.NumericParam('Intensity',value=0.0,units='dB-SPL',
                                                        enabled=False,group='Sound parameters')
        '''
        self.params['targetAmplitudeHigh'] = paramgui.NumericParam('AmplitudeHigh',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        self.params['targetAmplitudeMid'] = paramgui.NumericParam('AmplitudeMid',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        self.params['targetAmplitudeLow'] = paramgui.NumericParam('AmplitudeLow',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        '''                                                        
        self.params['targetAmplitude'] = paramgui.NumericParam('Target amplitude',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        self.params['punishSoundAmplitude'] = paramgui.NumericParam('Punish amplitude',value=0.01,
                                                              units='[0-1]',enabled=False,
                                                              group='Sound parameters')
        
        '''
        self.params['highFreq'] = paramgui.NumericParam('High freq',value=500,
                                                        units='Hz',group='Sound parameters')
        self.params['midFreq'] = paramgui.NumericParam('Middle freq',value=440,
                                                        units='Hz',group='Sound parameters')
        self.params['lowFreq'] = paramgui.NumericParam('Low freq',value=400,
                                                        units='Hz',group='Sound parameters')
        #4200, 9200, 20200
        '''
        soundParams = self.params.layout_group('Sound parameters')

        self.params['nValid'] = paramgui.NumericParam('N valid',value=0,
                                                      units='',enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',value=0,
                                                         units='',enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')


        # 
        self.params['experimenter'].set_value('santiago')
        self.params['subject'].set_value('test')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()
        
        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)
        
        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addStretch()
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addStretch()
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(switchingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(psychometricParams)
        layoutCol3.addStretch()

        layoutCol4.addWidget(automationParams)
        layoutCol3.addStretch()
        layoutCol4.addWidget(soundParams)
        layoutCol3.addStretch()
        layoutCol4.addWidget(reportParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000 # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left':0,'right':1}
        self.results['rewardSide'] = np.random.randint(2,size=maxNtrials)
        self.results.labels['choice'] = {'left':0,'right':1,'none':2}
        self.results['choice'] = np.empty(maxNtrials,dtype=int)
        self.results.labels['outcome'] = {'correct':1,'error':0,'invalid':2,
                                          'free':3,'nochoice':4,'aftererror':5,'aborted':6}
        self.results['outcome'] = np.empty(maxNtrials,dtype=int)
        # Saving as bool creates an 'enum' vector, so I'm saving as 'int'
        self.results['valid'] = np.zeros(maxNtrials,dtype='int8') # redundant but useful
        self.results['timeTrialStart'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials,dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials,dtype=float)


        # -- Define first block --
        import datetime
        if (datetime.datetime.now().day%2):
            self.params['currentBlock'].set_string('low_boundary')
        else:
            self.params['currentBlock'].set_string('high_boundary')

        # -- Load parameters from a file --
        self.params.from_file(paramfile,paramdictname)

        # -- Connect to sound server and define sounds --
        print 'Conecting to soundserver...'
        print '***** FIXME: HARDCODED TIME DELAY TO WAIT FOR SERIAL PORT! *****' ### DEBUG
        time.sleep(0.2)
        self.soundClient = soundclient.SoundClient()
        '''
        highFreq = self.params['highFreq'].get_value()
        lowFreq = self.params['lowFreq'].get_value()
        stimDur = self.params['targetDuration'].get_value()
        s1 = {'type':'tone', 'frequency':lowFreq, 'duration':stimDur, 'amplitude':0.01}
        s2 = {'type':'tone', 'frequency':highFreq, 'duration':stimDur, 'amplitude':0.01}
        self.soundClient.set_sound(1,s1)
        self.soundClient.set_sound(2,s2)
        '''

        punishSoundAmplitude = self.params['punishSoundAmplitude'].get_value()
        sNoise = {'type':'noise', 'duration':0.5, 'amplitude':punishSoundAmplitude}
        self.punishSoundID = 127
        self.soundClient.set_sound(self.punishSoundID,sNoise)
        self.soundClient.start()
Example #2
0
    def __init__(self,parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(nTrials=400,winsize=10)

         # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam('Time valve left',value=0.03,enabled=False,
                                                               units='s',group='Water delivery')
        self.params['baseWaterValveL'] = paramgui.NumericParam('Base time left',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['factorWaterValveL'] = paramgui.NumericParam('Factor left',value=1,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam('Time valve right',value=0.03,enabled=False,
                                                               units='s',group='Water delivery')
        self.params['baseWaterValveR'] = paramgui.NumericParam('Base time right',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['factorWaterValveR'] = paramgui.NumericParam('Factor right',value=1,
                                                               units='s',group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')

        self.params['outcomeMode'] = paramgui.MenuParam('Outcome mode',
                                                        ['sides_direct','direct','on_next_correct',
                                                         'only_if_correct','simulated'],
                                                         value=3,group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam('Anti-bias mode',
                                                        ['off','repeat_mistake'],
                                                        value=0,group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTargetMean'] = paramgui.NumericParam('Mean delay to target',value=0.04,
                                                        units='s',group='Timing parameters')
        self.params['delayToTargetHalfRange'] = paramgui.NumericParam('+/-',value=0.0,
                                                        units='s',group='Timing parameters')
        self.params['delayToTarget'] = paramgui.NumericParam('Delay to target',value=0.3,
                                                        units='s',group='Timing parameters',
                                                        enabled=False,decimals=3)
        self.params['targetDuration'] = paramgui.NumericParam('Target duration',value=0.5,
                                                        units='s',group='Timing parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam('Reward availability',value=4,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeError'] = paramgui.NumericParam('Punishment (error)',value=0,
                                                        units='s',group='Timing parameters')
        timingParams = self.params.layout_group('Timing parameters')

        self.params['automationMode'] = paramgui.MenuParam('Automation Mode',
                                                           ['off','increase_delay','same_left_right','same_right_left','left_right_left'],
                                                           value=0,group='Automation')
        automationParams = self.params.layout_group('Automation')
        
        
        self.params['threshMode'] = paramgui.MenuParam('Threshold Mode',
                                                         ['max_only','linear','exponential'],
                                                         value=0,group='Threshold detection parameters')
        # -- tone intensity refers to difference between tone and masking noise --
        self.params['minSNR'] = paramgui.NumericParam('Minimum signal to noise',value=2, decimals=1,
                                                        units='dB',group='Threshold detection parameters')
        self.params['maxSNR'] = paramgui.NumericParam('Maximum signal to noise',value=20,decimals=0,
                                                        units='dB',group='Threshold detection parameters')
        self.params['numSNRs'] = paramgui.NumericParam('Number of SNRs', value=2, decimals=0, units='dB', group='Threshold detection parameters')
        threshParams = self.params.layout_group('Threshold detection parameters')


        self.params['bandMode'] = paramgui.MenuParam('Bandwidth Mode', ['white_only', 'max_only', 'uniform'], value=0, group='Bandwidth parameters')
        self.params['minBand'] = paramgui.NumericParam('Minimum bandwidth',value=0.25,decimals=2,
                                                        units='octaves',group='Bandwidth parameters')
        self.params['maxBand'] = paramgui.NumericParam('Maximum bandwidth',value=4.0,decimals=2,
                                                        units='octaves',group='Bandwidth parameters')
        self.params['numBands'] = paramgui.NumericParam('Number of bandwidths',
                                                               value=5, decimals=0, group='Bandwidth parameters')
        self.params['includeWhite'] = paramgui.MenuParam('Include white noise?', ['yes', 'no'], value=0, group='Bandwidth parameters')
        bandParams = self.params.layout_group('Bandwidth parameters')
        
        self.params['noiseMode'] = paramgui.MenuParam('Masker amplitude mode', ['max_only', 'uniform'], value=1, group='Masker amplitude parameters')
        # -- power refers to average power of noise stimulus
        self.params['minNoiseAmp'] = paramgui.NumericParam('Minimum noise power',value=30,decimals=0,
                                                        units='dB',group='Masker amplitude parameters')
        self.params['maxNoiseAmp'] = paramgui.NumericParam('Maximum noise power',value=40,decimals=0,
                                                        units='dB',group='Masker amplitude parameters')
        self.params['numAmps'] = paramgui.NumericParam('Number of noise amplitudes',
                                                               value=2, decimals=0, group='Masker amplitude parameters')  
        noiseParams = self.params.layout_group('Masker amplitude parameters')  
            
        self.params['toneFreq'] = paramgui.NumericParam('Tone frequency',value=8000,
                                                        units='Hz',group='Sound parameters')
        self.params['modRate'] = paramgui.NumericParam('Modulation Rate',value=8,
                                                        units='Hz',group='Sound parameters')        
        soundParams = self.params.layout_group('Sound parameters')
        
        self.params['currentBand'] = paramgui.NumericParam('Trial bandwidth',value=0.0,decimals=2,
                                                        units='octaves', enabled=False, group='Current Trial')
        self.params['currentNoiseAmp'] = paramgui.NumericParam('Trial noise power',value=0.0,decimals=0,
                                                        units='dB', enabled=False, group='Current Trial')
        self.params['currentSNR'] = paramgui.NumericParam('Trial SNR',value=0.0,decimals=1,
                                                        units='dB', enabled=False, group='Current Trial')
        self.params['laserTrialType'] = paramgui.MenuParam('Laser trial type', 
                                                      ['no_laser','laser_onset1','laser_onset2',
                                                       'laser_onset3'], 
                                                      value=0, enabled=False, group='Current Trial')
        self.params['laserSide'] = paramgui.MenuParam('Laser side', ['none', 'left', 'right', 'bilateral'],
                                                      value=0, enabled=False, group='Current Trial')
        self.params['laserOnset'] = paramgui.NumericParam('Trial laser onset',value=0.0,decimals=1,
                                                        units='s', enabled=False, group='Current Trial')
        trialParams = self.params.layout_group('Current Trial')

        self.params['nValid'] = paramgui.NumericParam('N valid',value=0,
                                                      units='',enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',value=0,
                                                         units='',enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')

        # Photostim params
        self.params['laserDuration'] = paramgui.NumericParam('Laser duration',value=0.5,
                                                             units='s',group='Laser Stimulation')
        self.params['laserOnsetFromSoundOnset1'] = paramgui.NumericParam('Laser onset 1 (from sound)',value=-0.1,
                                                             units='s',group='Laser Stimulation')
        self.params['laserOnsetFromSoundOnset2'] = paramgui.NumericParam('Laser onset 2 (from sound)',value=0,
                                                             units='s',group='Laser Stimulation')
        self.params['laserOnsetFromSoundOnset3'] = paramgui.NumericParam('Laser onset 3 (from sound)',value=0.1,
                                                             units='s',group='Laser Stimulation')
        self.params['nOnsetsToUse'] = paramgui.MenuParam('Number of onsets to use', 
                                                         ['0','1','2','3'],
                                                         value=1, group='Laser Stimulation')
        # -- Percent trials each laser type. Remaining trials will be no laser.
        self.params['fractionTrialsLaser'] = paramgui.NumericParam('Fraction trials with laser',value=0.25,
                                                            units='',group='Laser Stimulation')

        self.params['stimMode'] = paramgui.MenuParam('Stimulation Mode',
                                                     ['unilateral_left','unilateral_right', 'bilateral', 'mixed_unilateral', 'mixed_all'],
                                                     value=2,group='Laser Stimulation')
        photostimParams = self.params.layout_group('Laser Stimulation')
        
        #
        self.params['experimenter'].set_value('santiago')
        self.params['subject'].set_value('test')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()

        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)

        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addStretch()
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addStretch()
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()
        layoutCol2.addWidget(automationParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(photostimParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(trialParams)
        layoutCol3.addStretch()
        
        layoutCol4.addWidget(soundParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(threshParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(bandParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(noiseParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(reportParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000 # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left':0,'right':1}
        self.results['rewardSide'] = np.random.randint(2,size=maxNtrials)
        self.results.labels['choice'] = {'left':0,'right':1,'none':2}
        self.results['choice'] = np.empty(maxNtrials,dtype=int)
        self.results.labels['outcome'] = {'correct':1,'error':0,'invalid':2,
                                          'free':3,'nochoice':4,'aftererror':5,'aborted':6}
        self.results['outcome'] = np.empty(maxNtrials,dtype=int)
        # Saving as bool creates an 'enum' vector, so I'm saving as 'int'
        self.results['valid'] = np.zeros(maxNtrials,dtype='int8') # redundant but useful
        self.results['timeTrialStart'] = np.empty(maxNtrials,dtype=float)
        self.results['timeTarget'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials,dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials,dtype=float)


        # -- Load parameters from a file --
        self.params.from_file(paramfile,paramdictname)

        # -- Connect to sound server and define sounds --
        print 'Conecting to soundserver...'
        print '***** FIXME: HARDCODED TIME DELAY TO WAIT FOR SERIAL PORT! *****' ### DEBUG
        time.sleep(0.2)
        self.soundClient = soundclient.SoundClient()
        self.soundClient.start()
        
        # -- Specify state matrix with extratimer --
        self.sm = statematrix.StateMatrix(inputs=rigsettings.INPUTS,
                                          outputs=rigsettings.OUTPUTS,
                                          readystate='ready_next_trial',
                                          extratimers=['laserTimer'])
Example #3
0
    def __init__(self,parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        self.name = 'lightDiscrim'

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(nTrials=400,winsize=10)

         # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam('Time valve left',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveC'] = paramgui.NumericParam('Time valve center',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam('Time valve right',value=0.03,
                                                               units='s',group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')
        
        self.params['outcomeMode'] = paramgui.MenuParam('Outcome mode',
                                                        ['sides_direct','direct','on_next_correct',
                                                         'only_if_correct','simulated', 'if_correct_leave_on'],
                                                         value=3,group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam('Anti-bias mode',
                                                        ['off','repeat_mistake'],
                                                        value=0,group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTargetMean'] = paramgui.NumericParam('Mean delay to target',value=0.2,
                                                        units='s',group='Timing parameters')
        self.params['delayToTargetHalfRange'] = paramgui.NumericParam('+/-',value=0.05,
                                                        units='s',group='Timing parameters')
        self.params['delayToTarget'] = paramgui.NumericParam('Delay to target',value=0.3,
                                                        units='s',group='Timing parameters',
                                                        enabled=False,decimals=3)
        self.params['targetDuration'] = paramgui.NumericParam('Target duration',value=0.2,
                                                        units='s',group='Timing parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam('Reward availability',value=4,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeError'] = paramgui.NumericParam('Punishment (error)',value=0,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam('Punishment (early)',value=0,
                                                        units='s',group='Timing parameters')
        timingParams = self.params.layout_group('Timing parameters')

        '''
        self.params['trialsPerBlock'] = paramgui.NumericParam('Trials per block',value=300,
                                                              units='trials (0=no-switch)',
                                                              group='Switching parameters')
        self.params['currentBlock'] = paramgui.MenuParam('Current block',
                                                         ['mid_boundary','low_boundary','high_boundary'],
                                                         value=0,group='Switching parameters')
        switchingParams = self.params.layout_group('Switching parameters')
        '''

        self.params['automationMode'] = paramgui.MenuParam('Automation Mode',
                                                           ['off','increase_delay'],
                                                           value=0,group='Automation')
        automationParams = self.params.layout_group('Automation')


        self.params['nValid'] = paramgui.NumericParam('N valid',value=0,
                                                      units='',enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',value=0,
                                                         units='',enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')


        # 
        self.params['experimenter'].set_value('santiago')
        self.params['subject'].set_value('test')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()
        
        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)
        
        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addStretch()
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addStretch()
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()
        #layoutCol3.addWidget(switchingParams)
        #layoutCol3.addStretch()
        #layoutCol3.addWidget(psychometricParams)
        #layoutCol3.addStretch()

        layoutCol3.addWidget(automationParams)
        layoutCol3.addStretch()
        #layoutCol4.addWidget(soundParams)
        #layoutCol3.addStretch()
        layoutCol3.addWidget(reportParams)
        layoutCol3.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000 # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left':0,'right':1}
        self.results['rewardSide'] = np.random.randint(2,size=maxNtrials)
        self.results.labels['choice'] = {'left':0,'right':1,'none':2}
        self.results['choice'] = np.empty(maxNtrials,dtype=int)
        self.results.labels['outcome'] = {'correct':1,'error':0,'invalid':2,
                                          'free':3,'nochoice':4,'aftererror':5,'aborted':6}
        self.results['outcome'] = np.empty(maxNtrials,dtype=int)
        # Saving as bool creates an 'enum' vector, so I'm saving as 'int'
        self.results['valid'] = np.zeros(maxNtrials,dtype='int8') # redundant but useful
        self.results['timeTrialStart'] = np.empty(maxNtrials,dtype=float)
        self.results['timeTarget'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials,dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials,dtype=float)

        '''
        # -- Define first block --
        import datetime
        if (datetime.datetime.now().day%2):
            self.params['currentBlock'].set_string('low_boundary')
        else:
            self.params['currentBlock'].set_string('high_boundary')
        '''

        # -- Load parameters from a file --
        self.params.from_file(paramfile,paramdictname)
    def __init__(self,parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(nTrials=400,winsize=10)

         # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam('Time valve left',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveC'] = paramgui.NumericParam('Time valve center',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam('Time valve right',value=0.03,
                                                               units='s',group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')

        self.params['outcomeMode'] = paramgui.MenuParam('Outcome mode',
                                                        ['sides_direct','direct','on_next_correct',
                                                         'only_if_correct','simulated'],
                                                         value=3,group='Choice parameters')
        self.params['allowEarlyWithdrawal'] = paramgui.MenuParam('Allow early withdraw',
                                                                 ['off','on'], enabled=False,
                                                                 value=1, group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam('Anti-bias mode',
                                                        ['off','repeat_mistake'],
                                                        value=0,group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTargetMean'] = paramgui.NumericParam('Mean delay to target',value=0.3,
                                                        units='s',group='Timing parameters')
        self.params['delayToTargetHalfRange'] = paramgui.NumericParam('+/-',value=0.05,
                                                        units='s',group='Timing parameters')
        self.params['delayToTarget'] = paramgui.NumericParam('Delay to target',value=0.3,
                                                        units='s',group='Timing parameters',
                                                        enabled=False,decimals=3)
        self.params['targetDuration'] = paramgui.NumericParam('Target duration',value=0.1,
                                                        units='s',group='Timing parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam('Reward availability',value=4,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeError'] = paramgui.NumericParam('Punishment (error)',value=0,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam('Punishment (early)',value=0,
                                                        units='s',group='Timing parameters')
        timingParams = self.params.layout_group('Timing parameters')

        '''
        self.params['trialsPerBlock'] = paramgui.NumericParam('Trials per block',value=300,
                                                              units='trials (0=no-switch)',
                                                              group='Switching parameters')
        self.params['currentBlock'] = paramgui.MenuParam('Current block',
                                                         ['mid_boundary','low_boundary','high_boundary'],
                                                         value=0,group='Switching parameters')
        switchingParams = self.params.layout_group('Switching parameters')
        '''

        self.params['psycurveMode'] = paramgui.MenuParam('PsyCurve Mode',
                                                         ['off','uniform','extreme80pc'],
                                                         value=0,group='Psychometric parameters')
        #self.params['psycurveNfreq'] = paramgui.NumericParam('N frequencies',value=8,decimals=0,
        #                                                     group='Psychometric parameters')
        psychometricParams = self.params.layout_group('Psychometric parameters')


        self.params['relevantFeature'] = paramgui.MenuParam('Relevant feature',
                                                         ['spectral','temporal'],
                                                         value=0,group='Categorization parameters')
        self.params['soundActionMode'] = paramgui.MenuParam('Sound-action mode',
                                                            ['low_left','high_left'],
                                                            value=0,group='Categorization parameters')
        categorizationParams = self.params.layout_group('Categorization parameters')

        self.params['automationMode'] = paramgui.MenuParam('Automation Mode',
                                                           ['off','increase_delay'],
                                                           value=0,group='Automation')
        automationParams = self.params.layout_group('Automation')


        # -- In this version the laser is set to last as long as the target --
        self.params['laserMode'] = paramgui.MenuParam('Laser mode',
                                                      ['none','bilateral'],
                                                      value=0, group='Photostimulation parameters')
        self.params['laserTrial'] = paramgui.MenuParam('Laser trial', ['no','yes'],
                                                       value=0, enabled=False,
                                                       group='Photostimulation parameters')
        self.params['laserOnset'] = paramgui.NumericParam('Laser onset (from sound)',value=0.0,
                                                          enabled=False,
                                                          units='s',group='Photostimulation parameters')
        self.params['laserDuration'] = paramgui.NumericParam('Laser duration',value=0.4, enabled=True,
                                                             units='s',group='Photostimulation parameters')
        # -- Percent trials with laser. Remaining trials will be no laser.
        self.params['fractionLaserTrials'] = paramgui.NumericParam('Fraction trials with laser',value=0.25,
                                                            units='',group='Photostimulation parameters')
        photostimParams = self.params.layout_group('Photostimulation parameters')
        

        
        # 5000, 7000, 9800 (until 2014-03-19)
        '''
        self.params['highFreq'] = paramgui.NumericParam('High freq',value=5000,
                                                        units='Hz',group='Sound parameters')
        self.params['lowFreq'] = paramgui.NumericParam('Low freq',value=3000,
                                                        units='Hz',group='Sound parameters')
        self.params['targetFrequency'] = paramgui.NumericParam('Target freq',value=0,decimals=0,
                                                               units='Hz',enabled=False,group='Sound parameters')
        '''
        self.params['targetFrequency'] = paramgui.NumericParam('Target percentage',value=0,decimals=0,
                                                               units='percentage',enabled=False,group='Sound parameters')
        self.params['targetIntensityMode'] = paramgui.MenuParam('Intensity mode',
                                                                ['fixed','randMinus20'],
                                                                value=0,group='Sound parameters')
        # This intensity corresponds to the intensity of each component of the chord
        self.params['targetMaxIntensity'] = paramgui.NumericParam('Max intensity',value=70,
                                                                  units='dB-SPL',group='Sound parameters')
        self.params['targetIntensity'] = paramgui.NumericParam('Intensity',value=0.0,units='dB-SPL',
                                                               enabled=False,group='Sound parameters')
        self.params['targetAmplitude'] = paramgui.NumericParam('Target amplitude',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        self.params['punishSoundIntensity'] = paramgui.NumericParam('Punish intensity',value=50,
                                                              units='dB-SPL',enabled=True,
                                                              group='Sound parameters')
        self.params['punishSoundAmplitude'] = paramgui.NumericParam('Punish amplitude',value=0.01,
                                                              units='[0-1]',enabled=False,
                                                              group='Sound parameters')
        soundParams = self.params.layout_group('Sound parameters')

        self.params['nValid'] = paramgui.NumericParam('N valid',value=0,
                                                      units='',enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',value=0,
                                                         units='',enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')

        #
        self.params['experimenter'].set_value('santiago')
        self.params['subject'].set_value('test')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()

        layoutMain.addLayout(layoutTop)
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)

        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addStretch()
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addStretch()
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(psychometricParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(categorizationParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(automationParams)
        layoutCol3.addStretch()
        
        layoutCol4.addWidget(photostimParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(soundParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(reportParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000 # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left':0,'right':1}
        self.results['rewardSide'] = np.random.randint(2,size=maxNtrials)
        self.results.labels['choice'] = {'left':0,'right':1,'none':2}
        self.results['choice'] = np.empty(maxNtrials,dtype=int)
        self.results.labels['outcome'] = {'correct':1,'error':0,'invalid':2,
                                          'free':3,'nochoice':4,'aftererror':5,'aborted':6}
        self.results['outcome'] = np.empty(maxNtrials,dtype=int)
        # Saving outcome as bool creates an 'enum' vector, so I'm saving as 'int'
        self.results['valid'] = np.zeros(maxNtrials,dtype='int8') # redundant but useful
        self.results['timeTrialStart'] = np.empty(maxNtrials,dtype=float)
        self.results['timeTarget'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials,dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials,dtype=float)

        # -- Load parameters from a file --
        self.params.from_file(paramfile,paramdictname)

        # -- Load speaker calibration --
        self.spkCal = speakercalibration.Calibration(rigsettings.SPEAKER_CALIBRATION_CHORD)
        self.spkNoiseCal = speakercalibration.NoiseCalibration(rigsettings.SPEAKER_CALIBRATION_NOISE)

        # -- Connect to sound server and define sounds --
        print('Conecting to soundserver (waiting for 200ms) ...')
        time.sleep(0.2)
        self.soundClient = soundclient.SoundClient()
        self.soundClient.start()

        # -- Prepare sounds --
        self.punishSoundID = 100
        #self.targetSoundID = {'leftSpectral':1, 'rightSpectral':2,
        #                      'leftTemporal':3, 'rightTemporal':4}
        self.targetSoundID = {'spectral000':1, 'spectral020':2, 'spectral040':3,
                              'spectral060':4, 'spectral080':5, 'spectral100':6,
                              'temporal000':11, 'temporal020':12, 'temporal040':13,
                              'temporal060':14, 'temporal080':15, 'temporal100':16}
        self.currentSoundID = None

        # -- Specify state matrix with extratimer --
        self.sm = statematrix.StateMatrix(inputs=rigsettings.INPUTS,
                                          outputs=rigsettings.OUTPUTS,
                                          readystate='readyForNextTrial',
                                          extratimers=['laserTimer'])
    def __init__(self,parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(nTrials=400,winsize=10)

         # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam('Time valve left',value=0.02,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveC'] = paramgui.NumericParam('Time valve center',value=0.02,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam('Time valve right',value=0.02,
                                                               units='s',group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')
        
        ###['sides direct','direct','on next correct','only if correct'],
        ###['sidesDirect','direct','onNextCorrect','onlyIforrect'],
        self.params['outcomeMode'] = paramgui.MenuParam('Outcome mode',
                                                        ['sides_direct','direct',
                                                         'on_next_correct','only_if_correct'],
                                                        value=3,group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam('Anti-bias mode',
                                                        ['off','repeat_mistake'],
                                                        value=1,group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTarget'] = paramgui.NumericParam('Delay to Target',value=0.1,
                                                        units='s',group='Timing Parameters')
        self.params['targetDuration'] = paramgui.NumericParam('Target Duration',value=0.1,
                                                        units='s',group='Timing Parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam('Reward Availability',value=4,
                                                        units='s',group='Timing Parameters')
        self.params['punishTimeError'] = paramgui.NumericParam('Punishment (error)',value=0,
                                                        units='s',group='Timing Parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam('Punishment (early)',value=0,
                                                        units='s',group='Timing Parameters')
        timingParams = self.params.layout_group('Timing Parameters')

        self.params['nValid'] = paramgui.NumericParam('N valid',value=0,
                                                      units='',enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',value=0,
                                                         units='',enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()
        
        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)
        
        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()

        layoutCol4.addWidget(reportParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000 # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left':0,'right':1}
        self.results['rewardSide'] = np.random.randint(2,size=maxNtrials)
        self.results.labels['choice'] = {'left':0,'right':1,'none':2}
        self.results['choice'] = np.empty(maxNtrials,dtype=int)
        self.results.labels['outcome'] = {'correct':1,'error':0,'invalid':2,
                                          'free':3,'nochoice':4,'aftererror':5,'aborted':6}
        self.results['outcome'] = np.empty(maxNtrials,dtype=int)
        self.results['timeTrialStart'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials,dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials,dtype=float)

        # -- Load parameters from a file --
        self.params.from_file(paramfile,paramdictname)
    def __init__(self, parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(
            nTrials=400, winsize=10)

        # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam(
            'Time valve left', value=0.03, units='s', group='Water delivery')
        self.params['timeWaterValveC'] = paramgui.NumericParam(
            'Time valve center', value=0.03, units='s', group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam(
            'Time valve right', value=0.03, units='s', group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')

        self.params['outcomeMode'] = paramgui.MenuParam(
            'Outcome mode', [
                'sides_direct', 'direct', 'on_next_correct', 'only_if_correct',
                'simulated'
            ],
            value=3,
            group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam(
            'Anti-bias mode', ['off', 'repeat_mistake'],
            value=0,
            group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTargetMean'] = paramgui.NumericParam(
            'Mean delay to target',
            value=0.3,
            units='s',
            group='Timing parameters')
        self.params['delayToTargetHalfRange'] = paramgui.NumericParam(
            '+/-', value=0.05, units='s', group='Timing parameters')
        self.params['delayToTarget'] = paramgui.NumericParam(
            'Delay to target',
            value=0.3,
            units='s',
            group='Timing parameters',
            enabled=False,
            decimals=3)
        self.params['targetDuration'] = paramgui.NumericParam(
            'Target duration', value=0.1, units='s', group='Timing parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam(
            'Reward availability',
            value=4,
            units='s',
            group='Timing parameters')
        self.params['punishTimeError'] = paramgui.NumericParam(
            'Punishment (error)',
            value=0,
            units='s',
            group='Timing parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam(
            'Punishment (early)',
            value=0,
            units='s',
            group='Timing parameters')
        timingParams = self.params.layout_group('Timing parameters')

        self.params['trialsPerBlock'] = paramgui.NumericParam(
            'Trials per block',
            value=300,
            units='trials (0=no-switch)',
            group='Switching parameters')
        self.params['currentBlock'] = paramgui.MenuParam(
            'Current block', ['mid_boundary', 'low_boundary', 'high_boundary'],
            value=0,
            group='Switching parameters')
        switchingParams = self.params.layout_group('Switching parameters')

        self.params['psycurveMode'] = paramgui.MenuParam(
            'PsyCurve Mode', ['off', 'uniform'],
            value=0,
            group='Psychometric parameters')
        self.params['psycurveNfreq'] = paramgui.NumericParam(
            'N frequencies',
            value=8,
            decimals=0,
            group='Psychometric parameters')
        psychometricParams = self.params.layout_group(
            'Psychometric parameters')

        self.params['automationMode'] = paramgui.MenuParam(
            'Automation Mode', ['off', 'increase_delay'],
            value=0,
            group='Automation')
        automationParams = self.params.layout_group('Automation')

        # 5000, 7000, 9800 (until 2014-03-19)
        self.params['highFreq'] = paramgui.NumericParam(
            'High freq', value=16000, units='Hz', group='Sound parameters')
        self.params['midFreq'] = paramgui.NumericParam(
            'Middle freq', value=7000, units='Hz', group='Sound parameters')
        self.params['lowFreq'] = paramgui.NumericParam(
            'Low freq', value=3000, units='Hz', group='Sound parameters')
        self.params['targetFrequency'] = paramgui.NumericParam(
            'Target freq',
            value=0,
            decimals=0,
            units='Hz',
            enabled=False,
            group='Sound parameters')
        self.params['targetIntensityMode'] = paramgui.MenuParam(
            'Intensity mode', ['fixed', 'randMinus20'],
            value=1,
            group='Sound parameters')
        self.params['targetMaxIntensity'] = paramgui.NumericParam(
            'Max intensity',
            value=60,
            units='dB-SPL',
            group='Sound parameters')
        self.params['targetIntensity'] = paramgui.NumericParam(
            'Intensity',
            value=0.0,
            units='dB-SPL',
            enabled=False,
            group='Sound parameters')
        '''
        self.params['targetAmplitudeHigh'] = paramgui.NumericParam('AmplitudeHigh',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        self.params['targetAmplitudeMid'] = paramgui.NumericParam('AmplitudeMid',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        self.params['targetAmplitudeLow'] = paramgui.NumericParam('AmplitudeLow',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        '''
        self.params['targetAmplitude'] = paramgui.NumericParam(
            'Target amplitude',
            value=0.0,
            units='[0-1]',
            enabled=False,
            decimals=4,
            group='Sound parameters')
        self.params['punishSoundAmplitude'] = paramgui.NumericParam(
            'Punish amplitude',
            value=0.01,
            units='[0-1]',
            enabled=False,
            group='Sound parameters')
        '''
        self.params['highFreq'] = paramgui.NumericParam('High freq',value=500,
                                                        units='Hz',group='Sound parameters')
        self.params['midFreq'] = paramgui.NumericParam('Middle freq',value=440,
                                                        units='Hz',group='Sound parameters')
        self.params['lowFreq'] = paramgui.NumericParam('Low freq',value=400,
                                                        units='Hz',group='Sound parameters')
        #4200, 9200, 20200
        '''
        soundParams = self.params.layout_group('Sound parameters')

        self.params['nValid'] = paramgui.NumericParam('N valid',
                                                      value=0,
                                                      units='',
                                                      enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',
                                                         value=0,
                                                         units='',
                                                         enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')

        #
        self.params['experimenter'].set_value('santiago')
        self.params['subject'].set_value('test')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()

        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)

        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addStretch()
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addStretch()
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(switchingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(psychometricParams)
        layoutCol3.addStretch()

        layoutCol4.addWidget(automationParams)
        layoutCol3.addStretch()
        layoutCol4.addWidget(soundParams)
        layoutCol3.addStretch()
        layoutCol4.addWidget(reportParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000  # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left': 0, 'right': 1}
        self.results['rewardSide'] = np.random.randint(2, size=maxNtrials)
        self.results.labels['choice'] = {'left': 0, 'right': 1, 'none': 2}
        self.results['choice'] = np.empty(maxNtrials, dtype=int)
        self.results.labels['outcome'] = {
            'correct': 1,
            'error': 0,
            'invalid': 2,
            'free': 3,
            'nochoice': 4,
            'aftererror': 5,
            'aborted': 6
        }
        self.results['outcome'] = np.empty(maxNtrials, dtype=int)
        # Saving as bool creates an 'enum' vector, so I'm saving as 'int'
        self.results['valid'] = np.zeros(maxNtrials,
                                         dtype='int8')  # redundant but useful
        self.results['timeTrialStart'] = np.empty(maxNtrials, dtype=float)
        self.results['timeTarget'] = np.empty(maxNtrials, dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials, dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials, dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials, dtype=float)

        # -- Define first block --
        import datetime
        if (datetime.datetime.now().day % 2):
            self.params['currentBlock'].set_string('low_boundary')
        else:
            self.params['currentBlock'].set_string('high_boundary')

        # -- Load parameters from a file --
        self.params.from_file(paramfile, paramdictname)

        # -- Connect to sound server and define sounds --
        print 'Conecting to soundserver...'
        print '***** XFIXME: HARDCODED TIME DELAY TO WAIT FOR SERIAL PORT! *****'  ### DEBUG
        time.sleep(0.2)
        self.soundClient = soundclient.SoundClient()
        '''
        highFreq = self.params['highFreq'].get_value()
        lowFreq = self.params['lowFreq'].get_value()
        stimDur = self.params['targetDuration'].get_value()
        s1 = {'type':'tone', 'frequency':lowFreq, 'duration':stimDur, 'amplitude':0.01}
        s2 = {'type':'tone', 'frequency':highFreq, 'duration':stimDur, 'amplitude':0.01}
        self.soundClient.set_sound(1,s1)
        self.soundClient.set_sound(2,s2)
        '''

        punishSoundAmplitude = self.params['punishSoundAmplitude'].get_value()
        sNoise = {
            'type': 'noise',
            'duration': 0.5,
            'amplitude': punishSoundAmplitude
        }
        self.punishSoundID = 127
        self.soundClient.set_sound(self.punishSoundID, sNoise)
        self.soundClient.start()
    def __init__(self, parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(
            nTrials=400, winsize=10)

        # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam(
            'Time valve left', value=0.02, units='s', group='Water delivery')
        self.params['timeWaterValveC'] = paramgui.NumericParam(
            'Time valve center', value=0.02, units='s', group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam(
            'Time valve right', value=0.02, units='s', group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')

        ###['sides direct','direct','on next correct','only if correct'],
        ###['sidesDirect','direct','onNextCorrect','onlyIforrect'],
        self.params['outcomeMode'] = paramgui.MenuParam(
            'Outcome mode',
            ['sides_direct', 'direct', 'on_next_correct', 'only_if_correct'],
            value=3,
            group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam(
            'Anti-bias mode', ['off', 'repeat_mistake'],
            value=1,
            group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTarget'] = paramgui.NumericParam(
            'Delay to Target', value=0.1, units='s', group='Timing Parameters')
        self.params['targetDuration'] = paramgui.NumericParam(
            'Target Duration', value=0.1, units='s', group='Timing Parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam(
            'Reward Availability',
            value=4,
            units='s',
            group='Timing Parameters')
        self.params['punishTimeError'] = paramgui.NumericParam(
            'Punishment (error)',
            value=0,
            units='s',
            group='Timing Parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam(
            'Punishment (early)',
            value=0,
            units='s',
            group='Timing Parameters')
        timingParams = self.params.layout_group('Timing Parameters')

        self.params['nValid'] = paramgui.NumericParam('N valid',
                                                      value=0,
                                                      units='',
                                                      enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',
                                                         value=0,
                                                         units='',
                                                         enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()

        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)

        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()

        layoutCol4.addWidget(reportParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000  # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left': 0, 'right': 1}
        self.results['rewardSide'] = np.random.randint(2, size=maxNtrials)
        self.results.labels['choice'] = {'left': 0, 'right': 1, 'none': 2}
        self.results['choice'] = np.empty(maxNtrials, dtype=int)
        self.results.labels['outcome'] = {
            'correct': 1,
            'error': 0,
            'invalid': 2,
            'free': 3,
            'nochoice': 4,
            'aftererror': 5,
            'aborted': 6
        }
        self.results['outcome'] = np.empty(maxNtrials, dtype=int)
        self.results['timeTrialStart'] = np.empty(maxNtrials, dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials, dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials, dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials, dtype=float)

        # -- Load parameters from a file --
        self.params.from_file(paramfile, paramdictname)
Example #8
0
    def __init__(self, parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(
            nTrials=400, winsize=10)

        # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam(
            'Time valve left',
            value=0.03,
            enabled=False,
            units='s',
            group='Water delivery')
        self.params['baseWaterValveL'] = paramgui.NumericParam(
            'Base time left', value=0.03, units='s', group='Water delivery')
        self.params['factorWaterValveL'] = paramgui.NumericParam(
            'Factor left', value=1, units='s', group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam(
            'Time valve right',
            value=0.03,
            enabled=False,
            units='s',
            group='Water delivery')
        self.params['baseWaterValveR'] = paramgui.NumericParam(
            'Base time right', value=0.03, units='s', group='Water delivery')
        self.params['factorWaterValveR'] = paramgui.NumericParam(
            'Factor right', value=1, units='s', group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')

        self.params['outcomeMode'] = paramgui.MenuParam(
            'Outcome mode', [
                'sides_direct', 'direct', 'on_next_correct', 'only_if_correct',
                'simulated'
            ],
            value=3,
            group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam(
            'Anti-bias mode', ['off', 'repeat_mistake'],
            value=0,
            group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTargetMean'] = paramgui.NumericParam(
            'Mean delay to target',
            value=0.04,
            units='s',
            group='Timing parameters')
        self.params['delayToTargetHalfRange'] = paramgui.NumericParam(
            '+/-', value=0.0, units='s', group='Timing parameters')
        self.params['delayToTarget'] = paramgui.NumericParam(
            'Delay to target',
            value=0.3,
            units='s',
            group='Timing parameters',
            enabled=False,
            decimals=3)
        self.params['targetDuration'] = paramgui.NumericParam(
            'Target duration', value=0.5, units='s', group='Timing parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam(
            'Reward availability',
            value=4,
            units='s',
            group='Timing parameters')
        self.params['punishTimeError'] = paramgui.NumericParam(
            'Punishment (error)',
            value=0,
            units='s',
            group='Timing parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam(
            'Punishment (early)',
            value=0,
            units='s',
            group='Timing parameters')
        timingParams = self.params.layout_group('Timing parameters')

        self.params['automationMode'] = paramgui.MenuParam('Automation Mode', [
            'off', 'increase_delay', 'same_left_right', 'same_right_left',
            'left_right_left'
        ],
                                                           value=0,
                                                           group='Automation')
        automationParams = self.params.layout_group('Automation')

        self.params['threshMode'] = paramgui.MenuParam(
            'Threshold Mode', ['max_only', 'linear', 'exponential'],
            value=0,
            group='Threshold detection parameters')
        # -- tone intensity refers to difference between tone and masking noise --
        self.params['minSNR'] = paramgui.NumericParam(
            'Minimum signal to noise',
            value=2,
            decimals=1,
            units='dB',
            group='Threshold detection parameters')
        self.params['maxSNR'] = paramgui.NumericParam(
            'Maximum signal to noise',
            value=20,
            decimals=0,
            units='dB',
            group='Threshold detection parameters')
        self.params['numSNRs'] = paramgui.NumericParam(
            'Number of SNRs',
            value=2,
            decimals=0,
            units='dB',
            group='Threshold detection parameters')
        threshParams = self.params.layout_group(
            'Threshold detection parameters')

        self.params['bandMode'] = paramgui.MenuParam(
            'Bandwidth Mode', ['white_only', 'max_only', 'uniform'],
            value=0,
            group='Bandwidth parameters')
        self.params['minBand'] = paramgui.NumericParam(
            'Minimum bandwidth',
            value=0.25,
            decimals=2,
            units='octaves',
            group='Bandwidth parameters')
        self.params['maxBand'] = paramgui.NumericParam(
            'Maximum bandwidth',
            value=4.0,
            decimals=2,
            units='octaves',
            group='Bandwidth parameters')
        self.params['numBands'] = paramgui.NumericParam(
            'Number of bandwidths',
            value=5,
            decimals=0,
            group='Bandwidth parameters')
        self.params['includeWhite'] = paramgui.MenuParam(
            'Include white noise?', ['yes', 'no'],
            value=0,
            group='Bandwidth parameters')
        bandParams = self.params.layout_group('Bandwidth parameters')

        self.params['noiseMode'] = paramgui.MenuParam(
            'Masker amplitude mode', ['max_only', 'uniform'],
            value=1,
            group='Masker amplitude parameters')
        # -- power refers to average power of noise stimulus
        self.params['minNoiseAmp'] = paramgui.NumericParam(
            'Minimum noise power',
            value=30,
            decimals=0,
            units='dB',
            group='Masker amplitude parameters')
        self.params['maxNoiseAmp'] = paramgui.NumericParam(
            'Maximum noise power',
            value=40,
            decimals=0,
            units='dB',
            group='Masker amplitude parameters')
        self.params['numAmps'] = paramgui.NumericParam(
            'Number of noise amplitudes',
            value=2,
            decimals=0,
            group='Masker amplitude parameters')
        noiseParams = self.params.layout_group('Masker amplitude parameters')

        self.params['toneFreq'] = paramgui.NumericParam(
            'Tone frequency', value=8000, units='Hz', group='Sound parameters')
        self.params['modRate'] = paramgui.NumericParam(
            'Modulation Rate', value=8, units='Hz', group='Sound parameters')
        self.params['punishSoundAmplitude'] = paramgui.NumericParam(
            'Punish amplitude',
            value=0.01,
            units='[0-1]',
            enabled=True,
            group='Sound parameters')
        soundParams = self.params.layout_group('Sound parameters')

        self.params['currentBand'] = paramgui.NumericParam(
            'Trial bandwidth',
            value=0.0,
            decimals=2,
            units='octaves',
            enabled=False,
            group='Current Trial')
        self.params['currentNoiseAmp'] = paramgui.NumericParam(
            'Trial noise power',
            value=0.0,
            decimals=0,
            units='dB',
            enabled=False,
            group='Current Trial')
        self.params['currentSNR'] = paramgui.NumericParam(
            'Trial SNR',
            value=0.0,
            decimals=1,
            units='dB',
            enabled=False,
            group='Current Trial')
        trialParams = self.params.layout_group('Current Trial')

        self.params['nValid'] = paramgui.NumericParam('N valid',
                                                      value=0,
                                                      units='',
                                                      enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',
                                                         value=0,
                                                         units='',
                                                         enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')

        #
        self.params['experimenter'].set_value('santiago')
        self.params['subject'].set_value('test')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()

        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)

        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addStretch()
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addStretch()
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(automationParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(trialParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(reportParams)
        layoutCol3.addStretch()

        layoutCol4.addWidget(soundParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(threshParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(bandParams)
        layoutCol4.addStretch()
        layoutCol4.addWidget(noiseParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000  # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left': 0, 'right': 1}
        self.results['rewardSide'] = np.random.randint(2, size=maxNtrials)
        self.results.labels['choice'] = {'left': 0, 'right': 1, 'none': 2}
        self.results['choice'] = np.empty(maxNtrials, dtype=int)
        self.results.labels['outcome'] = {
            'correct': 1,
            'error': 0,
            'invalid': 2,
            'free': 3,
            'nochoice': 4,
            'aftererror': 5,
            'aborted': 6
        }
        self.results['outcome'] = np.empty(maxNtrials, dtype=int)
        # Saving as bool creates an 'enum' vector, so I'm saving as 'int'
        self.results['valid'] = np.zeros(maxNtrials,
                                         dtype='int8')  # redundant but useful
        self.results['timeTrialStart'] = np.empty(maxNtrials, dtype=float)
        self.results['timeTarget'] = np.empty(maxNtrials, dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials, dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials, dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials, dtype=float)

        # -- Load parameters from a file --
        self.params.from_file(paramfile, paramdictname)

        # -- Connect to sound server and define sounds --
        print 'Conecting to soundserver...'
        print '***** FIXME: HARDCODED TIME DELAY TO WAIT FOR SERIAL PORT! *****'  ### DEBUG
        time.sleep(0.2)
        self.soundClient = soundclient.SoundClient()
        self.punishSoundID = 127
        self.soundClient.start()
    def __init__(self,parent=None, paramfile=None, paramdictname=None):
        super(Paradigm, self).__init__(parent)

        # -- Performance dynamics plot --
        performancedynamicsplot.set_pg_colors(self)
        self.myPerformancePlot = performancedynamicsplot.PerformanceDynamicsPlot(nTrials=400,winsize=10)

         # -- Add parameters --
        self.params['timeWaterValveL'] = paramgui.NumericParam('Time valve left',value=0.03,enabled=False,
                                                               units='s',group='Water delivery')
        self.params['baseWaterValveL'] = paramgui.NumericParam('Base time left',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['factorWaterValveL'] = paramgui.NumericParam('Factor left',value=1,
                                                               units='s',group='Water delivery')
        self.params['timeWaterValveR'] = paramgui.NumericParam('Time valve right',value=0.03,enabled=False,
                                                               units='s',group='Water delivery')
        self.params['baseWaterValveR'] = paramgui.NumericParam('Base time right',value=0.03,
                                                               units='s',group='Water delivery')
        self.params['factorWaterValveR'] = paramgui.NumericParam('Factor right',value=1,
                                                               units='s',group='Water delivery')
        waterDelivery = self.params.layout_group('Water delivery')

        self.params['outcomeMode'] = paramgui.MenuParam('Outcome mode',
                                                        ['sides_direct','direct','on_next_correct',
                                                         'only_if_correct','simulated'],
                                                         value=3,group='Choice parameters')
        self.params['antibiasMode'] = paramgui.MenuParam('Anti-bias mode',
                                                        ['off','repeat_mistake'],
                                                        value=0,group='Choice parameters')
        choiceParams = self.params.layout_group('Choice parameters')

        self.params['delayToTargetMean'] = paramgui.NumericParam('Mean delay to target',value=0.04,
                                                        units='s',group='Timing parameters')
        self.params['delayToTargetHalfRange'] = paramgui.NumericParam('+/-',value=0.0,
                                                        units='s',group='Timing parameters')
        self.params['delayToTarget'] = paramgui.NumericParam('Delay to target',value=0.3,
                                                        units='s',group='Timing parameters',
                                                        enabled=False,decimals=3)
        self.params['targetDuration'] = paramgui.NumericParam('Target duration',value=0.5,
                                                        units='s',group='Timing parameters')
        self.params['rewardAvailability'] = paramgui.NumericParam('Reward availability',value=4,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeError'] = paramgui.NumericParam('Punishment (error)',value=0,
                                                        units='s',group='Timing parameters')
        self.params['punishTimeEarly'] = paramgui.NumericParam('Punishment (early)',value=0,
                                                        units='s',group='Timing parameters')
        timingParams = self.params.layout_group('Timing parameters')

        self.params['trialsPerBlock'] = paramgui.NumericParam('Trials per block',value=200,
                                                              units='trials (0=no-switch)',
                                                              group='Switching parameters')
        self.params['currentBlock'] = paramgui.MenuParam('Current block',
                                                         ['same_reward','more_left','more_right','more_both'],
                                                         value=0,group='Switching parameters')
        switchingParams = self.params.layout_group('Switching parameters')


        self.params['psycurveMode'] = paramgui.MenuParam('PsyCurve Mode',
                                                         ['off','uniform'],
                                                         value=0,group='Psychometric parameters')
        self.params['psycurveNfreq'] = paramgui.NumericParam('N frequencies',value=8,decimals=0,
                                                             group='Psychometric parameters')
        psychometricParams = self.params.layout_group('Psychometric parameters')


        self.params['laserMode'] = paramgui.MenuParam('Laser Mode',
                                                      ['none', 'random'],
                                                      value=0, group='Laser parameters')
        self.params['laserProbability'] = paramgui.NumericParam('Laser probability',
                                                                value=0.25, group='Laser parameters')
        self.params['laserDuration'] = paramgui.NumericParam('Laser duration', value=0.5,
                                                             group='Laser parameters')
        self.params['laserOn'] = paramgui.NumericParam('Laser On', value=0,
                                                       enabled=False, group='Laser parameters')
        laserParams = self.params.layout_group('Laser parameters')

        self.params['automationMode'] = paramgui.MenuParam('Automation Mode',
                                                           ['off','increase_delay','same_left_right','same_right_left','left_right_left'],
                                                           value=0,group='Automation')
        automationParams = self.params.layout_group('Automation')

        # 5000, 7000, 9800 (until 2014-03-19)
        self.params['highSoundFreq'] = paramgui.NumericParam('High sound freq',value=16000,
                                                        units='Hz',group='Sound parameters')
        self.params['lowSoundFreq'] = paramgui.NumericParam('Low sound freq',value=5000,
                                                        units='Hz',group='Sound parameters')
        self.params['highModFreq'] = paramgui.NumericParam('High mod freq',value=32,
                                                        units='Hz',group='Sound parameters')
        self.params['lowModFreq'] = paramgui.NumericParam('Low mod freq',value=8,
                                                        units='Hz',group='Sound parameters')
        self.params['targetFrequency'] = paramgui.NumericParam('Target freq',value=0,decimals=0,
                                                        units='Hz',enabled=False,group='Sound parameters')
        self.params['targetIntensityMode'] = paramgui.MenuParam('Intensity mode',
                                                               ['fixed','randMinus20'],
                                                               value=0,group='Sound parameters')
        self.params['soundTypeMode'] = paramgui.MenuParam('Sound mode',
                                                          ['amp_mod','tones', 'chords', 'mixed_tones', 'mixed_chords'],
                                                          value=0,group='Sound parameters')
        self.params['soundType'] = paramgui.MenuParam('Sound type',
                                                      ['amp_mod','tones', 'chords'],
                                                      value=0,group='Sound parameters')
        # This intensity corresponds to the intensity of each component of the chord
        self.params['targetMaxIntensity'] = paramgui.NumericParam('Max intensity',value=50,
                                                        units='dB-SPL',group='Sound parameters')
        self.params['targetIntensity'] = paramgui.NumericParam('Intensity',value=0.0,units='dB-SPL',
                                                        enabled=False,group='Sound parameters')
        self.params['targetAmplitude'] = paramgui.NumericParam('Target amplitude',value=0.0,units='[0-1]',
                                                        enabled=False,decimals=4,group='Sound parameters')
        self.params['punishSoundAmplitude'] = paramgui.NumericParam('Punish amplitude',value=0.01,
                                                              units='[0-1]',enabled=True,
                                                              group='Sound parameters')
        soundParams = self.params.layout_group('Sound parameters')

        self.params['nValid'] = paramgui.NumericParam('N valid',value=0,
                                                      units='',enabled=False,
                                                      group='Report')
        self.params['nRewarded'] = paramgui.NumericParam('N rewarded',value=0,
                                                         units='',enabled=False,
                                                         group='Report')
        reportParams = self.params.layout_group('Report')


        #
        self.params['experimenter'].set_value('santiago')
        self.params['subject'].set_value('test')

        # -- Add graphical widgets to main window --
        self.centralWidget = QtGui.QWidget()
        layoutMain = QtGui.QVBoxLayout()
        layoutTop = QtGui.QVBoxLayout()
        layoutBottom = QtGui.QHBoxLayout()
        layoutCol1 = QtGui.QVBoxLayout()
        layoutCol2 = QtGui.QVBoxLayout()
        layoutCol3 = QtGui.QVBoxLayout()
        layoutCol4 = QtGui.QVBoxLayout()

        layoutMain.addLayout(layoutTop)
        #layoutMain.addStretch()
        layoutMain.addSpacing(0)
        layoutMain.addLayout(layoutBottom)

        layoutTop.addWidget(self.mySidesPlot)
        layoutTop.addWidget(self.myPerformancePlot)

        layoutBottom.addLayout(layoutCol1)
        layoutBottom.addLayout(layoutCol2)
        layoutBottom.addLayout(layoutCol3)
        layoutBottom.addLayout(layoutCol4)

        layoutCol1.addWidget(self.saveData)
        layoutCol1.addWidget(self.sessionInfo)
        layoutCol1.addWidget(self.dispatcherView)

        layoutCol2.addWidget(self.manualControl)
        layoutCol2.addStretch()
        layoutCol2.addWidget(waterDelivery)
        layoutCol2.addStretch()
        layoutCol2.addWidget(choiceParams)
        layoutCol2.addStretch()

        layoutCol3.addWidget(timingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(switchingParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(psychometricParams)
        layoutCol3.addStretch()
        layoutCol3.addWidget(laserParams)
        layoutCol3.addStretch()

        layoutCol4.addWidget(automationParams)
        layoutCol3.addStretch()
        layoutCol4.addWidget(soundParams)
        layoutCol3.addStretch()
        layoutCol4.addWidget(reportParams)
        layoutCol4.addStretch()

        self.centralWidget.setLayout(layoutMain)
        self.setCentralWidget(self.centralWidget)

        # -- Add variables for storing results --
        maxNtrials = 4000 # Preallocating space for each vector makes things easier
        self.results = arraycontainer.Container()
        self.results.labels['rewardSide'] = {'left':0,'right':1}
        self.results['rewardSide'] = np.random.randint(2,size=maxNtrials)
        self.results.labels['choice'] = {'left':0,'right':1,'none':2}
        self.results['choice'] = np.empty(maxNtrials,dtype=int)
        self.results.labels['outcome'] = {'correct':1,'error':0,'invalid':2,
                                          'free':3,'nochoice':4,'aftererror':5,'aborted':6}
        self.results['outcome'] = np.empty(maxNtrials,dtype=int)
        # Saving as bool creates an 'enum' vector, so I'm saving as 'int'
        self.results['valid'] = np.zeros(maxNtrials,dtype='int8') # redundant but useful
        self.results['timeTrialStart'] = np.empty(maxNtrials,dtype=float)
        self.results['timeTarget'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterIn'] = np.empty(maxNtrials,dtype=float)
        self.results['timeCenterOut'] = np.empty(maxNtrials,dtype=float)
        self.results['timeSideIn'] = np.empty(maxNtrials,dtype=float)


        # -- Load parameters from a file --
        self.params.from_file(paramfile,paramdictname)

        # -- Connect to sound server and define sounds --
        print 'Conecting to soundserver...'
        print '***** FIXME: HARDCODED TIME DELAY TO WAIT FOR SERIAL PORT! *****' ### DEBUG
        time.sleep(0.2)
        self.soundClient = soundclient.SoundClient()
        '''
        highFreq = self.params['highFreq'].get_value()
        lowFreq = self.params['lowFreq'].get_value()
        stimDur = self.params['targetDuration'].get_value()
        s1 = {'type':'tone', 'frequency':lowFreq, 'duration':stimDur, 'amplitude':0.01}
        s2 = {'type':'tone', 'frequency':highFreq, 'duration':stimDur, 'amplitude':0.01}
        self.soundClient.set_sound(1,s1)
        self.soundClient.set_sound(2,s2)
        '''

        '''
        # This code was moved to the method prepare_punish_sound()
        punishSoundAmplitude = self.params['punishSoundAmplitude'].get_value()
        sNoise = {'type':'noise', 'duration':0.5, 'amplitude':punishSoundAmplitude}
        self.punishSoundID = 127
        self.soundClient.set_sound(self.punishSoundID,sNoise)
        '''
        self.punishSoundID = 127
        self.soundClient.start()

        # -- Specify state matrix with extratimer --


        if rigsettings.OUTPUTS.has_key('stim1') and rigsettings.OUTPUTS.has_key('stim2'):
            self.laserPin = ['stim1', 'stim2']
        else:
            self.laserPin = ['centerLED'] # Use center LED during emulation

        self.sm = statematrix.StateMatrix(inputs=rigsettings.INPUTS,
                                          outputs=rigsettings.OUTPUTS,
                                          readystate='readyForNextTrial',
                                          extratimers=['laserTimer', 'rewardAvailabilityTimer'])