Beispiel #1
0
    def test_quest(self):
        conditions = data.importConditions(
            os.path.join(fixturesPath, 'multiStairConds.xlsx'))
        stairs = data.MultiStairHandler(stairType='quest',
                                        conditions=conditions,
                                        method='random',
                                        nTrials=20,
                                        name='QuestStairs',
                                        autoLog=False)
        exp = data.ExperimentHandler(name='testExp',
                                     savePickle=True,
                                     saveWideText=True,
                                     dataFileName=os.path.join(
                                         self.temp_dir,
                                         'multiQuestExperiment'),
                                     autoLog=False)
        rng = np.random.RandomState(seed=self.random_seed)

        exp.addLoop(stairs)
        for intensity, condition in stairs:
            # make data that will cause different stairs to finish different
            # times
            if rng.rand() > condition['startVal']:
                corr = 1
            else:
                corr = 0
            stairs.addData(corr)

        stairs.saveAsExcel(os.path.join(self.temp_dir, 'multiQuestOut'))

        # contains more info
        stairs.saveAsPickle(os.path.join(self.temp_dir, 'multiQuestOut'))
        exp.close()
Beispiel #2
0
    def test_QuestPlus(self):
        import sys
        if not (sys.version_info.major == 3 and sys.version_info.minor >= 6):
            pytest.skip('QUEST+ only works on Python 3.6+')

        conditions = data.importConditions(
            os.path.join(fixturesPath, 'multiStairQuestPlus.xlsx'))
        stairs = data.MultiStairHandler(stairType='questplus',
                                        conditions=conditions,
                                        method='random',
                                        nTrials=20,
                                        name='QuestPlusStairs',
                                        autoLog=False)
        exp = data.ExperimentHandler(name='testExp',
                                     savePickle=True,
                                     saveWideText=True,
                                     dataFileName=os.path.join(
                                         self.temp_dir,
                                         'multiQuestPlusExperiment'),
                                     autoLog=False)
        rng = np.random.RandomState(seed=self.random_seed)
        exp.addLoop(stairs)

        for intensity, condition in stairs:
            response = np.random.choice(['Correct', 'Incorrect'])
            stairs.addResponse(response)

        stairs.saveAsExcel(os.path.join(self.temp_dir, 'multiQuestPlusOut'))

        # contains more info
        stairs.saveAsPickle(os.path.join(self.temp_dir, 'multiQuestPlusOut'))
        exp.close()
 def test_simple(self):
     conditions = data.importConditions(
         pjoin(fixturesPath, 'multiStairConds.xlsx'))
     stairs = data.MultiStairHandler(stairType='simple',
                                     conditions=conditions,
                                     method='random',
                                     nTrials=20,
                                     name='simpleStairs',
                                     autoLog=False)
     exp = data.ExperimentHandler(name='testExp',
                                  savePickle=True,
                                  saveWideText=True,
                                  dataFileName=pjoin(
                                      self.temp_dir,
                                      'multiStairExperiment'),
                                  autoLog=False)
     exp.addLoop(stairs)
     for intensity, condition in stairs:
         #make data that will cause different stairs to finish different times
         if random() > condition['startVal']:
             corr = 1
         else:
             corr = 0
         stairs.addData(corr)
     stairs.saveAsExcel(pjoin(self.temp_dir, 'multiStairOut'))
     stairs.saveAsPickle(pjoin(self.temp_dir,
                               'multiStairOut'))  #contains more info
Beispiel #4
0
def test_invalid_method():
    conditions = data.importConditions(os.path.join(fixturesPath,
                                                    'multiStairConds.xlsx'))

    kwargs = dict(method='foobar', stairType='simple',
                  conditions=conditions, nTrials=5)

    with pytest.raises(ValueError):
        data.MultiStairHandler(**kwargs)
Beispiel #5
0
 def testQuest(self):
     conditions = data.importConditions(
         pjoin(TESTSDATA_PATH, 'multiStairConds.xlsx'))
     stairs = data.MultiStairHandler(stairType='quest', conditions=conditions,
                 method='random', nTrials=5)
     for intensity,condition in stairs:
         #make data that will cause different stairs to finish different times
         if random()>condition['startVal']:
             corr=1
         else:corr=0
         stairs.addData(corr)
     stairs.saveAsExcel(pjoin(self.temp_dir, 'multiQuestOut'))
     stairs.saveAsPickle(pjoin(self.temp_dir, 'multiQuestOut'))#contains more info
Beispiel #6
0
def test_fullRandom():
    conditions = data.importConditions(os.path.join(fixturesPath,
                                                    'multiStairConds.xlsx'))

    seed = 11
    first_pass = ['medium', 'low', 'medium']

    kwargs = dict(method='fullRandom', randomSeed=seed, stairType='simple',
                  conditions=conditions, nTrials=5)

    multistairs = data.MultiStairHandler(**kwargs)

    for staircase_idx, staircase in enumerate(multistairs.thisPassRemaining):
        assert staircase.condition['label'] == first_pass[staircase_idx]
Beispiel #7
0
def test_different_seeds():
    conditions = data.importConditions(os.path.join(fixturesPath,
                                                    'multiStairConds.xlsx'))

    seeds = [7, 11]
    first_pass = [['high', 'medium', 'low'],
                  ['low', 'high', 'medium']]

    kwargs = dict(method='random', stairType='simple',
                  conditions=conditions, nTrials=5)

    for seed_idx, seed in enumerate(seeds):
        multistairs = data.MultiStairHandler(randomSeed=seed, **kwargs)

        for staircase_idx, staircase in enumerate(multistairs.thisPassRemaining):
            assert staircase.condition['label'] == first_pass[seed_idx][staircase_idx]
Beispiel #8
0
 def test_multiStairQuest(self):
     nTrials = 5
     conditions = [{
         'label': 'stim_01',
         'startVal': 0.3,
         'startValSd': 0.8,
         'minVal': 0,
         'maxVal': 1,
         'pThreshold': 0.5,
         'gamma': 0.01,
         'delta': 0.01,
         'grain': 0.01
     }, {
         'label': 'stim_02',
         'startVal': 0.3,
         'startValSd': 0.8,
         'minVal': 0,
         'maxVal': 1,
         'pThreshold': 0.5,
         'gamma': 0.01,
         'delta': 0.01,
         'grain': 0.01
     }, {
         'label': 'stim_03',
         'startVal': 0.3,
         'startValSd': 0.8,
         'minVal': 0,
         'maxVal': 1,
         'pThreshold': 0.5,
         'gamma': 0.01,
         'delta': 0.01,
         'grain': 0.01
     }]
     multiStairHandler = data.MultiStairHandler(stairType='quest',
                                                method='sequential',
                                                conditions=conditions,
                                                nTrials=nTrials)
     responsesToMake = makeBasicResponseCycles()
     expectedLevels = [
         0.3,
         0.26922321258393306,
         0.24699865727320078,
         0.265989972738,
         0.282954436975,
     ]
     expectedLevels = np.repeat(expectedLevels, len(conditions))
     self.doTrials(multiStairHandler, responsesToMake, expectedLevels)
Beispiel #9
0
        thisComponent.setAutoDraw(False)
# check responses
if endInstructions.keys in ['', [], None]:  # No response was made
    endInstructions.keys = None
thisExp.addData('endInstructions.keys', endInstructions.keys)
if endInstructions.keys != None:  # we had a response
    thisExp.addData('endInstructions.rt', endInstructions.rt)
thisExp.nextEntry()
# the Routine "instructions" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()

# set up handler to look after randomisation of trials etc
conditions = data.importConditions('stairDefinitions.xlsx')
trials = data.MultiStairHandler(stairType='QUEST',
                                name='trials',
                                nTrials=40,
                                conditions=conditions,
                                originPath=-1)
thisExp.addLoop(trials)  # add the loop to the experiment
# initialise values for first condition
level = trials._nextIntensity  # initialise some vals  # Yiming: I assume the level is contrast
condition = trials.currentStaircase.condition

for level, condition in trials:
    currentLoop = trials
    # abbreviate parameter names if possible (e.g. rgb=condition.rgb)
    for paramName in condition:
        exec(paramName + '= condition[paramName]')

    # ------Prepare to start Routine "trial"-------
    t = 0
Beispiel #10
0
 G['S']['goNogoStim'] = [None] # Container=[None]
 # nextfliptasks=[]
 G['S']['tooSoonTime'] = tooSoonTime
 
     
 # set up the staircase handler according specifications in Aron & Poldrack, 2009
 # ""Cortical and Subcortical Contributions to Stop Signal Response Inhibition: 
 # Role of the Subthalamic Nucleus""
 # 
 conditions = [
     {'label':'staircase1', 'startVal':100, 'stepSizes':50, 'nTrials':10, 'nUp':1, 'nDown':1, 'applyInitialRule':False, 'stepType':'lin'},
     {'label':'staircase2', 'startVal':150, 'stepSizes':50, 'nTrials':10, 'nUp':1, 'nDown':1, 'applyInitialRule':False, 'stepType':'lin'},
     {'label':'staircase3', 'startVal':200, 'stepSizes':50, 'nTrials':10, 'nUp':1, 'nDown':1, 'applyInitialRule':False, 'stepType':'lin'},
     {'label':'staircase4', 'startVal':250, 'stepSizes':50, 'nTrials':10, 'nUp':1, 'nDown':1, 'applyInitialRule':False, 'stepType':'lin'}
 ]
 G['S']['myMultiStairs'] = data.MultiStairHandler(stairType='simple', method='random', conditions=conditions, nTrials=40)
 
 
 # Obtain the Go Nogo Timing Parameters
 # for stop-signal task: read in the critucal timings from one of my 500 
 # OPTIMAL GLM Design specifications:
 tmp_rand_number = random.randint(1,501)
 #with open('efl/param_%d.txt' % (tmp_rand_number )) as f:
 #    matrix=[[float(s) for s in re.findall(r'-?\d+\.?\d*', line)] for line in f]
 with open('efl/tmpFile.txt','rb') as f:
     matrix=pickle.load(f)
 
 
 SSnumber, SSstopgo, ISIwaitTime, tmp1, tmp2, LeftOrRight = zip(*matrix)
 
 G['S']['SSnumber']=SSnumber
Beispiel #11
0
def startExperiment():
    try:
        expInfo, stairInfo, outputfile, monitorInfo = setupExperiment()
        win = open_window(monitorInfo)
        show_instructions(win, "Press spacebar to start experiment, doing " +
                          str(expInfo['TrainingTrials']) + " training trials")

        # We instanciate 4 staircases, we must decide the starting values for each of them
        # The speed value is the speedValue in the for loop of staircases and is measured in [cm/s]
        # The staircase will terminate when nTrials AND nReversals have been exceeded.
        # If stepSizes was an array and has been exceeded before nTrials is
        # exceeded then the staircase will continue to reverse

        # Convert the string of steps to a list of floats to feed to every
        # staircase
        stepSizes = [float(x)
                     for x in stairInfo['StepSizes'].replace('[', '').replace(']', '').split(',')]

        # Convert the initial velocities of the staircases
        SpeedBiRight = [float(x)
                        for x in stairInfo['SpeedBiRight'].replace('[', '').replace(']', '').split(',')]
        SpeedBiLeft = [float(x)
                       for x in stairInfo['SpeedBiLeft'].replace('[', '').replace(']', '').split(',')]
        SpeedUniRight = [float(x)
                         for x in stairInfo['SpeedUniRight'].replace('[', '').replace(']', '').split(',')]
        SpeedUniLeft = [float(x)
                        for x in stairInfo['SpeedUniLeft'].replace('[', '').replace(']', '').split(',')]

        conditionsBilateral = [
            {'label': 'Bilateral-Right_0',
             'Side': 'Right',
             'startVal': SpeedBiRight[0],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpBiRight'],
             'nDown':stairInfo['nDownBiRight'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             },

            {'label': 'Bilateral-Left_0',
             'Side': 'Left',
             'startVal': SpeedBiLeft[0],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpBiLeft'],
             'nDown':stairInfo['nDownBiLeft'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             },

            {'label': 'Bilateral-Right_1',
             'Side': 'Right',
             'startVal': SpeedBiRight[1],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpBiRight'],
             'nDown':stairInfo['nDownBiRight'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             },

            {'label': 'Bilateral-Left_1',
             'Side': 'Left',
             'startVal': SpeedBiLeft[1],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpBiLeft'],
             'nDown':stairInfo['nDownBiLeft'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             }
        ]
        ########## CONDITIONS UNILATERAL ##########
        conditionsUnilateral = [
            {'label': 'Unilateral-Right_0',
             'Side': 'Right',
             'startVal': SpeedUniRight[0],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpUniRight'],
             'nDown':stairInfo['nDownUniRight'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             },

            {'label': 'Unilateral-Left_0',
             'Side': 'Left',
             'startVal': SpeedUniLeft[0],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpUniLeft'],
             'nDown':stairInfo['nDownUniLeft'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             },

            {'label': 'Unilateral-Right_1',
             'Side': 'Right',
             'startVal': SpeedUniRight[1],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpUniRight'],
             'nDown':stairInfo['nDownUniRight'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             },

            {'label': 'Unilateral-Left_1',
             'Side': 'Left',
             'startVal': SpeedUniLeft[1],
             'method':'2AFC',
             'stepType':stairInfo['StepType'],
             'stepSizes':stepSizes,
             'nUp':stairInfo['nUpUniLeft'],
             'nDown':stairInfo['nDownUniLeft'],
             'nTrials':stairInfo['MinTrials'],
             'nReversals':stairInfo['MinReversals'],
             'minVal':0
             }
        ]

        conditions = None
        if expInfo['Block'] == 'Unilateral':
            conditions = conditionsUnilateral
        if expInfo['Block'] == 'Bilateral':
            conditions = conditionsBilateral
        if expInfo['Block'] == 'Uni+Bi':
            conditions = conditionsUnilateral + conditionsBilateral
        from psychopy import data
        stairs = data.MultiStairHandler(
            conditions=conditions, nTrials=2, method=stairInfo['Selection'])

        if (monitorInfo['RunSpeedTest']):
            from common.draw_test_square import draw_test_square
            draw_test_square(win)
        # Do some training trials with no variation in speed
        for i in range(0, int(expInfo['TrainingTrials'])):
            speedValue = 1.25 * (i + 1)
            trackingTrial(win, expInfo, speedValue, conditions[randrange(0, 2)])

        show_instructions(
            win, "Finished training trials, press spacebar to begin")
        velocityConditions = {}
        velocityConditions['Left'] = []
        velocityConditions['Right'] = []
        # Start of the trial loop
        # We save the last speed used for every side of stimulus presentation
        nTrial = 0
        import copy
        # Has to initialize the first trial
        speedValue, thisCondition = stairs.next()
        nCatchTrials = 0
        nValidTrials = 0
        dfrows = [] # Collects all trials included catch trials
        print thisCondition
        while True: # Using while True is the correct way to insert catch trials
            velocityConditions[thisCondition['Side']].append(speedValue)
            # print thisCondition['Side'], speedValue
            # Catch trial presentato al 25% di probabilita
            if np.random.rand() < 0.25 and nTrial > 2:
                nCatchTrials += 1
                catchCondition = copy.deepcopy(thisCondition)
                if thisCondition['Side'] == 'Left':
                    catchCondition['Side'] = 'Left'
                    catchSpeedValue = velocityConditions['Right'][-1]
                else:
                    catchCondition['Side'] = 'Right'
                    catchSpeedValue = velocityConditions['Left'][-1]
                catchResp = trackingTrial(win, expInfo, catchSpeedValue, catchCondition, simulation=expInfo['SimulationMode'], isCatchTrial=0) #doesn't print message
                dfrows.append({'label':catchCondition['label'], 'Side':catchCondition['Side'], 'CatchCondition':1, 'Speed':speedValue, 'Response':int(not catchResp)})
            else:
                thisResp = trackingTrial(win, expInfo, speedValue, thisCondition, simulation=expInfo['SimulationMode'],isCatchTrial=0)
                dfrows.append({'label':thisCondition['label'], 'Side':thisCondition['Side'], 'CatchCondition':0, 'Speed':speedValue, 'Response':int(not thisResp)})
                if thisResp is not None:
                    stairs.addResponse(int(not thisResp))
                    nValidTrials += 1
                    try:
                        speedValue, thisCondition = stairs.next()
                    except StopIteration:
                        break
                else:
                    raise
            # Increase the trial counter and save the temporary results
            nTrial = nTrial + 1
            stairs.saveAsText(outputfile)
            stairs.saveAsPickle(outputfile)
            df = pd.DataFrame(dfrows) # this holds all trials in raw mode
        stairs.saveAsExcel(outputfile)
        experiment_finished(win)
        df.to_excel(outputfile+'_trials_summary.xlsx')
    except:
        # If the experiments stops before a default response is inserted
        stairs.addResponse(0)
        stairs.saveAsExcel(outputfile)
        df.to_excel(outputfile+'_trials_summary.xlsx')
        win.close()
        raise
def startExperiment():
    try:
        expInfo, stairInfo, outputfile, monitorInfo = setupExperiment()
        win = open_window(monitorInfo)
        show_instructions(
            win, "Press spacebar to start experiment, doing " +
            str(expInfo['TrainingTrials']) + " training trials")

        # We instanciate 4 staircases, we must decide the starting values for each of them
        # The speed value is the speedValue in the for loop of staircases and is measured in [cm/s]
        # The staircase will terminate when nTrials AND nReversals have been exceeded.
        # If stepSizes was an array and has been exceeded before nTrials is
        # exceeded then the staircase will continue to reverse

        # Convert the string of steps to a list of floats to feed to every
        # staircase
        stepSizes = [
            float(x) for x in stairInfo['StepSizes'].replace('[', '').replace(
                ']', '').split(',')
        ]

        # Convert the initial velocities of the staircases
        SpeedBiRight = [
            float(x)
            for x in stairInfo['SpeedBiRight'].replace('[', '').replace(
                ']', '').split(',')
        ]
        SpeedBiLeft = [
            float(x)
            for x in stairInfo['SpeedBiLeft'].replace('[', '').replace(
                ']', '').split(',')
        ]
        SpeedUniRight = [
            float(x)
            for x in stairInfo['SpeedUniRight'].replace('[', '').replace(
                ']', '').split(',')
        ]
        SpeedUniLeft = [
            float(x)
            for x in stairInfo['SpeedUniLeft'].replace('[', '').replace(
                ']', '').split(',')
        ]

        conditionsBilateral = [{
            'label': 'Bilateral-Right_0',
            'Side': 'Right',
            'startVal': SpeedBiRight[0],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpBiRight'],
            'nDown': stairInfo['nDownBiRight'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }, {
            'label': 'Bilateral-Left_0',
            'Side': 'Left',
            'startVal': SpeedBiLeft[0],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpBiLeft'],
            'nDown': stairInfo['nDownBiLeft'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }, {
            'label': 'Bilateral-Right_1',
            'Side': 'Right',
            'startVal': SpeedBiRight[1],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpBiRight'],
            'nDown': stairInfo['nDownBiRight'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }, {
            'label': 'Bilateral-Left_1',
            'Side': 'Left',
            'startVal': SpeedBiLeft[1],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpBiLeft'],
            'nDown': stairInfo['nDownBiLeft'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }]
        ########## CONDITIONS UNILATERAL ##########
        conditionsUnilateral = [{
            'label': 'Unilateral-Right_0',
            'Side': 'Right',
            'startVal': SpeedUniRight[0],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpUniRight'],
            'nDown': stairInfo['nDownUniRight'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }, {
            'label': 'Unilateral-Left_0',
            'Side': 'Left',
            'startVal': SpeedUniLeft[0],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpUniLeft'],
            'nDown': stairInfo['nDownUniLeft'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }, {
            'label': 'Unilateral-Right_1',
            'Side': 'Right',
            'startVal': SpeedUniRight[1],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpUniRight'],
            'nDown': stairInfo['nDownUniRight'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }, {
            'label': 'Unilateral-Left_1',
            'Side': 'Left',
            'startVal': SpeedUniLeft[1],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpUniLeft'],
            'nDown': stairInfo['nDownUniLeft'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': 0
        }]

        conditions = None
        if expInfo['Block'] == 'Unilateral':
            conditions = conditionsUnilateral
        if expInfo['Block'] == 'Bilateral':
            conditions = conditionsBilateral
        if expInfo['Block'] == 'Uni+Bi':
            conditions = conditionsUnilateral + conditionsBilateral
        from psychopy import data
        stairs = data.MultiStairHandler(conditions=conditions,
                                        nTrials=2,
                                        method=stairInfo['Selection'])

        if (monitorInfo['RunSpeedTest']):
            from common.draw_test_square import draw_test_square
            draw_test_square(win)
        # Do some training trials with no variation in speed
        for i in range(0, int(expInfo['TrainingTrials'])):
            speedValue = 1.25 * (i + 1)
            trackingTrial(win, expInfo, speedValue, conditions[randrange(0,
                                                                         2)])

        show_instructions(win,
                          "Finished training trials, press spacebar to begin")
        velocityConditions = {}
        velocityConditions['Left'] = []
        velocityConditions['Right'] = []
        # Start of the trial loop
        # We save the last speed used for every side of stimulus presentation
        nTrial = 0
        import copy
        for speedValue, thisCondition in stairs:
            velocityConditions[thisCondition['Side']].append(speedValue)
            # print thisCondition['Side'], speedValue
            # Catch trial presentato al 25% di probabilita
            if np.random.rand() < 0.25 and nTrial > 2:
                catchCondition = copy.deepcopy(thisCondition)
                if thisCondition['Side'] == 'Left':
                    catchCondition['Side'] = 'Left'
                    # print "Using speed value", velocityConditions['Right'][-1], " instead of ", speedValue
                    # get the last speed used element
                    speedValue = velocityConditions['Right'][-1]
                else:
                    catchCondition['Side'] = 'Right'
                    # print "Using speed value", velocityConditions['Left'][-1], " instead of ", speedValue
                    # get the last speed used element
                    speedValue = velocityConditions['Left'][-1]
                # print "0.25 catch trial, showing ", catchCondition['Side'], "
                # instead of ", thisCondition['Side']
                trackingTrial(win, expInfo, speedValue, catchCondition,
                              expInfo['SimulationMode'])
            # Catch trial lanciato quando una delle due staircase finita
            # e che randomizza il lato di presentazione
            elif np.random.rand() < 0.5:
                catchCondition = copy.deepcopy(thisCondition)
                if thisCondition['Side'] == 'Left':
                    catchCondition['Side'] = 'Right'
                else:
                    catchCondition['Side'] = 'Left'
                # print "0.5 catch trial, showing ", catchCondition['Side'], "
                # instead of ", thisCondition['Side']
                trackingTrial(win, expInfo, speedValue, catchCondition,
                              expInfo['SimulationMode'])
            else:
                thisResp = trackingTrial(win, expInfo, speedValue,
                                         thisCondition,
                                         expInfo['SimulationMode'])
                if thisResp is not None:
                    # print speedValue, thisCondition, nTrial
                    stairs.addData(not thisResp)
                else:
                    raise
            nTrial = nTrial + 1
            stairs.saveAsText(outputfile)
        # Finally save the results of the experiment
        stairs.saveAsText(outputfile)
        # stairs.saveAsExcel(outputfile)
        stairs.saveAsPickle(outputfile)
        experiment_finished(win)
    except:
        stairs.saveAsText(outputfile)
        # stairs.saveAsExcel(outputfile)
        stairs.saveAsPickle(outputfile)
        win.close()
        raise
Beispiel #13
0
    'TF': 4
}, {
    'label': 'practice',
    'startVal': 1,
    'startValSd': 0.1,
    'pThreshold': .82,
    'max_contr': .95,
    'minVal': 0,
    'maxVal': 1,
    'stim_diam_degs': 3.5,
    'SF': 10,
    'TF': 4
}]
loop_practice = data.MultiStairHandler(stairType='QUEST',
                                       name='loop_practice',
                                       nTrials=2,
                                       conditions=conditions,
                                       originPath=-1)
thisExp.addLoop(loop_practice)  # add the loop to the experiment
# initialise values for first condition
level = loop_practice._nextIntensity  # initialise some vals
condition = loop_practice.currentStaircase.condition
trial_n = 0

for level, condition in loop_practice:
    trial_n += 1
    currentLoop = loop_practice
    # abbreviate parameter names if possible (e.g. rgb=condition.rgb)
    for paramName in condition:
        exec(paramName + '= condition[paramName]')
Beispiel #14
0
def experiment_module(p, win):

    ########################
    #### Instructions ####
    ########################
    update_rule_names(p)
    if p.step_num == 0:
        for txt in p.instruct_text['intro']:
            message = visual.TextStim(win,
                                      height=p.text_height,
                                      text=dedent(txt))
            message.draw()
            win.flip()
            keys = event.waitKeys(keyList=['space'])

    else:
        for txt in p.instruct_text['break_txt']:
            txt = txt.replace('COMPLETED', str(p.step_num))
            txt = txt.replace('TOTAL', str(p.num_blocks))

            message = visual.TextStim(win, text=dedent(txt))
            message.draw()
            win.flip()
            keys = event.waitKeys(keyList=['space'])

    ########################
    #### Visual Objects ####
    ########################

    #colors
    p.dot_colors = p.lch_to_rgb(p)

    #dotstims init
    dotstims, cue = init_stims(p, win)

    #get fixation cross and feedback info
    fixation, feedback_text = get_basic_objects(win, p)

    ############################
    #### Set up Staircasing ####
    ############################

    conditions = [
        # {'label':'easy', 'startVal': 0.6, 'stepSizes' : .01, 'stepType': 'lin', 'minVal': .51, 'maxVal': 1, 'nUp': 1, 'nDown': 5, 'nReversals': 15},
        {
            'label': 'hard',
            'startVal': p.coherence[p.rule],
            'stepSizes': .01,
            'stepType': 'lin',
            'minVal': p.min_value[p.rule],
            'maxVal': 1,
            'nUp': 1,
            'nDown': 1,
            'nReversals': p.n_reversals
        },
    ]
    stairs = data.MultiStairHandler(conditions=conditions, nTrials=10)

    ########################
    #### Run Experiment ####
    ########################

    #start timer
    clock = core.Clock()

    #draw fixation
    draw_stim(win, fixation, 1 * win.framerate)

    p.resp = []
    p.rt = []
    p.choice_times = []
    p.feedback_times = []
    p.correct = []
    p.incorrect = []  #only for switch
    p.bank = 0
    win.recordFrameIntervals = True
    num_correct = 0
    num_errors = 0

    other_dimensions = [x for x in ['color', 'shape', 'motion'] if x != p.rule]

    for intensity, staircase in stairs:

        ############################
        ###dot stim/choice period###
        ############################

        p.coherence[p.rule] = intensity

        #initialize dots
        dotstims, cue = init_stims(p, win)

        #set up response key and rt recording
        rt_clock = clock.getTime()
        p.choice_times.append(rt_clock)
        correct = True

        #color, motion and shape for this trial
        trial_features = {}
        for other_dim in other_dimensions:
            trial_features[other_dim] = np.random.choice(
                p.rule_features[other_dim])

        #get motion rule and correct response
        act_resp = list(zip(p.rule_features[p.rule], ['1', '2']))
        np.random.shuffle(act_resp)
        trial_features[p.rule], correct_resp = act_resp[0]

        #present trial
        keys = present_dots_record_keypress(p, win, dotstims, cue, clock,
                                            trial_features['color'],
                                            trial_features['shape'],
                                            trial_features['motion'], p.rule)

        #record keypress
        if not keys:
            resp = np.NaN
            p.resp.append(resp)
            p.rt.append(np.NaN)
        else:
            resp = keys[0][0]
            p.resp.append(resp)
            p.rt.append(keys[0][1] - rt_clock)

        #####################
        ###feedback period###
        #####################

        #show feedback
        nframes = p.feedback_dur * win.framerate

        if np.isnan(p.rt[-1]):
            correct = False
            draw_error(win, nframes, p.too_slow_color)

        elif str(resp) != str(correct_resp):
            correct = False
            draw_error(win, nframes, p.fixation_color)

        if not correct:
            num_errors += 1

        p.correct.append(correct)

        ##update staircase handler
        stairs.addResponse(int(correct))
        stairs.addOtherData('rt', p.rt[-1])
        stairs.addOtherData('color', trial_features['color'])
        stairs.addOtherData('shape', trial_features['shape'])
        stairs.addOtherData('motion', trial_features['motion'])

        ################
        ###iti period###
        ################

        draw_stim(win, fixation, p.iti * win.framerate)

    print_reversal = min(p.n_reversals, 6)

    print('mean reversal', p.rule,
          np.mean(stairs.staircases[0].reversalIntensities[-print_reversal:]))
    print('std reversal', p.rule,
          np.std(stairs.staircases[0].reversalIntensities[-print_reversal:]))
    print('mean_rt', np.nanmean(p.rt))
    print('\nOverall, %i frames were dropped.\n' % win.nDroppedFrames)

    #save data
    out_f = op.join(
        p.outdir,
        p.sub + '_psychophys_run' + str(p.run) + '_' + p.rule + '.pkl')
    while op.exists(out_f):
        out_f = out_f[:-4] + '+' + '.pkl'

    with open(out_f, 'wb') as output:
        pickle.dump(p, output, pickle.HIGHEST_PROTOCOL)

    # save data as multiple formats
    filename = op.join(p.outdir,
                       p.sub + '_run' + str(p.run) + '_staircase_' + p.rule)
    stairs.saveAsExcel(filename)  # easy to browse
    stairs.saveAsPickle(filename)
Beispiel #15
0
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# check responses
if key_resp_3.keys in ['', [], None]:  # No response was made
    key_resp_3.keys = None
# store data for thisExp (ExperimentHandler)
thisExp.addData('key_resp_3.keys', key_resp_3.keys)
if key_resp_3.keys != None:  # we had a response
    thisExp.addData('key_resp_3.rt', key_resp_3.rt)
thisExp.nextEntry()

# set up handler to look after randomisation of trials etc
conditions = data.importConditions('staircaseflo_2.xlsx')
trials_2 = data.MultiStairHandler(stairType='simple',
                                  name='trials_2',
                                  nTrials=5,
                                  conditions=conditions,
                                  originPath=None)
thisExp.addLoop(trials_2)  # add the loop to the experiment
# initialise values for first condition
level = trials_2._nextIntensity  # initialise some vals
condition = trials_2.currentStaircase.condition

for level, condition in trials_2:
    currentLoop = trials_2
    # abbreviate parameter names if possible (e.g. rgb=condition.rgb)
    for paramName in condition.keys():
        exec(paramName + '= condition[paramName]')

    #------Prepare to start Routine "ISI_2"-------
    t = 0
Beispiel #16
0
    def run_quest_procedure(self, n_trials=10, start=20, start_sd=10, maxvalue=40, beta=3.5, delta=0.01, gamma=0.01, grain=0.01):

        print("RUNNING QUEST\n" \
              "-------------\n")

        startVal=start
        startValSd=start_sd
        pThreshold=0.75
        nTrials=n_trials
        minVal=0
        maxVal=maxvalue
        beta=beta
        delta=delta
        gamma=gamma
        grain=grain
        method='quantile'
        
        conditions = {
            'startVal': startVal, 'startValSd': startValSd,
            'minVal': 0, 'maxVal': maxVal, 'pThreshold': 0.75, 'gamma': gamma, 'delta': delta,
            'grain': grain, 'method': method, 'nTrials': n_trials,
        }
        self.conditions = [
            dict({'label': 'staircase_1'}.items() + conditions.items()),
            dict({'label': 'staircase_2'}.items() + conditions.items()),
        ]
        self.quest = data.MultiStairHandler(stairType='quest', method='random', conditions=self.conditions)
        t1 = self.quest.staircases[0].mean()
        t2 = self.quest.staircases[1].mean()
        sd1 = self.quest.staircases[0].sd()
        sd2 = self.quest.staircases[1].sd()
        beta1 = contrib.quest.QuestObject.beta(self.quest.staircases[0])
        beta1 = contrib.quest.QuestObject.beta(self.quest.staircases[1])
        
        t_mean = (t1 + t2) / 2
        beta_mean = (beta1 + beta2) / 2 

        fit = data.FitWeibull(t_mean, beta_mean, sems=1/n_trials)

        for n, stim_level in enumerate(self.quest):

            print("Calibration trial {0} / {1}\n" \
                  "Stimulation level = {2}\n" \
                  "-----------------------------".format(n + 1, n_trials, stim_level))

            response = None

            # Repeat if subject doesn't respond
            while response == None:
                trial = ConditioningTrial(self, n, True, max_voltage=stim_level)
                response = trial.run()

            # Add the response
            if response:
                print("Stimulation detected")
            else:
                print("Stimulation not detected")

            if n >= self.config['quest_settings']['n_ignored']:
                self.quest.addResponse(int(response))
                p0 = fit.inverse(0)
                p25 = fit.inverse(.25)
                p50 = fit.inverse(.50)
                p75 = fit.inverse(.75)
                print("1% detection probability level = {0}\n"
                      "25% detection probability level = {1}\n"
                      "50% detection probability level = {2}\n"
                      "75% detection probability level = {3}\n".format(self.quest.quantile(0.01), self.quest.quantile(.25), self.quest.quantile(.5), self.quest.quantile(.75)))


        return p0, p25, p50, p75
Beispiel #17
0
def startExperiment():
    """
    Begin the experiment
    1. Set experimental parameters
    2. Open the window and take measurements of the refresh rate
    3. Start some training trials if needed
    4. Start the interleaved staircase experiment
    5. Save the result
    """
    try:
        expInfo, stairInfo, outputfile, monitorInfo = setupExperiment()
    except:
        raise
    try:
        win = open_window(monitorInfo)
        show_instructions(
            win, "Press spacebar to start experiment, doing " +
            str(expInfo['TrainingTrials']) + " training trials")

        # Convert the string of steps to a list of floats to feed to every
        # staircase
        stepSizes = [
            float(x) for x in stairInfo['StepSizes'].replace('[', '').replace(
                ']', '').split(',')
        ]

        expConditions = [{
            'label': 'Right',
            'startVal': stairInfo['FlickerFreqRight'],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpRight'],
            'nDown': stairInfo['nDownRight'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': min(stepSizes)
        }, {
            'label': 'Left',
            'startVal': stairInfo['FlickerFreqLeft'],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpLeft'],
            'nDown': stairInfo['nDownLeft'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': min(stepSizes)
        }]
        from psychopy import data
        stairs = data.MultiStairHandler(conditions=expConditions,
                                        nTrials=1,
                                        method=stairInfo['Selection'])

        if (monitorInfo['RunSpeedTest']):
            from common.draw_test_square import draw_test_square
            draw_test_square(win)

        # Do some training trials with no variation in speed
        for i in range(0, int(expInfo['TrainingTrials'])):
            flickerTrial(win,
                         expInfo,
                         flickerFreq=1,
                         side='Left',
                         useOddBall=True)

        show_instructions(win,
                          "Finished training trials, press spacebar to begin")
        for flickerFreq, thisCondition in stairs:
            thisResp = flickerTrial(win,
                                    expInfo,
                                    flickerFreq,
                                    side=thisCondition['label'],
                                    useOddBall=True)
            if thisResp is not None:
                stairs.addData(not thisResp)
            stairs.saveAsText(outputfile)

        stairs.saveAsText(outputfile)
        stairs.saveAsPickle(outputfile)
        stairs.saveAsExcel(outputfile)
        experiment_finished(win)
    except:
        stairs.saveAsText(outputfile)
        stairs.saveAsPickle(outputfile)
        stairs.saveAsExcel(outputfile)
        win.close()
        raise
    def test_multiStairQuestSequentialIdenticalConditions(self):
        """
        Identical parameters passed to both QuestHandlers, and identical
        simulated responses provided.

        We use the exact same settings as in
        TestQuestHandler.test_QuestHandler().

        """
        # These are the parameters for the QuestHandlers.
        nTrials = 10  # This is going to yield 10 trials per staircase.
        startVal, minVal, maxVal = 50, 0, 100
        range = maxVal - minVal
        startValSd = 50
        grain = 0.01
        pThreshold = 0.82
        beta, gamma, delta = 3.5, 0.5, 0.01
        stopInterval = None
        method = 'quantile'

        # These parameters are shared between the two staircases. The only
        # thing we will need to add is individual labels, which will
        # happen below.
        conditions = {
            'startVal': startVal,
            'startValSd': startValSd,
            'minVal': minVal,
            'maxVal': maxVal,
            'range': range,
            'pThreshold': pThreshold,
            'gamma': gamma,
            'delta': delta,
            'grain': grain,
            'method': method,
            'nTrials': nTrials,
            'stopInterval': stopInterval
        }

        self.conditions = [
            dict(
                list({'label': 'staircase_0'}.items()) +
                list(conditions.items())),
            dict(
                list({'label': 'staircase_1'}.items()) +
                list(conditions.items())),
        ]

        self.stairs = data.MultiStairHandler(stairType='quest',
                                             method='linear',
                                             conditions=self.conditions)

        # Responses for only one staircase. We will duplicate this below.
        responses = makeBasicResponseCycles(cycles=3,
                                            nCorrect=2,
                                            nIncorrect=2,
                                            length=10)
        self.responses = np.repeat(responses, 2)

        # Same procedure as with the responses: This lists the responses
        # for one of the staircases, and will be duplicated below.
        intensities = [
            50, 45.139710407074872, 37.291086503930742, 58.297413127139947,
            80.182967131096547, 75.295251409003527, 71.57627192423783,
            79.881680484036906, 90.712313302815517, 88.265808957695796
        ]
        self.intensities = np.repeat(intensities, 2)

        mean = 86.0772169427
        mode = 80.11
        quantile = 86.3849031085

        self.simulate()
        self.checkSimulationResults()

        assert np.allclose(self.stairs.staircases[0].mean(), mean)
        assert np.allclose(self.stairs.staircases[0].mode(), mode)
        assert np.allclose(self.stairs.staircases[0].quantile(), quantile)

        assert (self.stairs.staircases[0].intensities ==
                self.stairs.staircases[1].intensities)

        assert (
            self.stairs.staircases[0].data == self.stairs.staircases[1].data)
Beispiel #19
0
    'maxVal': 1,
    'nUp': 1,
    'nDown': 2,
    'stepSizes': steps
}, {
    'label': 'high',
    'startVal': 0.65,
    'stepType': 'lin',
    'minVal': 0.01,
    'maxVal': 1,
    'nUp': 1,
    'nDown': 2,
    'stepSizes': steps
}]

stairs = data.MultiStairHandler(conditions=conditions, nTrials=120)

instruction.draw()
win.flip()
event.waitKeys(keyList=['space'])

instruction.setText(instr2)
instruction.draw()
win.flip()
event.waitKeys(keyList=['space'])

trial = 0
for thisIncrement in stairs:  #will step through the staircase
    trial += 1

    if trial == 121:
    def run_session(self):

        path = os.path.join(self.res_dir, self.subject)
        if not os.path.exists(path):
            os.makedirs(path)

        # welcome
        msg = visual.TextStim(self.win,
                              'Welcome!' + '\n' +
                              ' Press any key to start this session :)',
                              color='black',
                              units='deg',
                              pos=(0, 0),
                              height=0.8)
        msg.draw()
        self.win.mouseVisible = False
        self.win.flip()
        event.waitKeys()

        # read staircase parameters
        conditions = [
            dict({'stimulus': key}, **value)
            for key, value in self.param.items() if key.startswith('stimulus')
        ]

        if conditions[0]['stairType'] == 'simple':
            stairs = data.MultiStairHandler(stairType='simple',
                                            conditions=conditions,
                                            nTrials=self.trial_nmb,
                                            method='sequential')
        elif conditions[0]['stairType'] == 'quest':
            stairs = []
            for cond in conditions:
                if self.priors_file_path:
                    prior_file = self.priors_file_path + cond[
                        'label'] + '.psydat'
                    print(prior_file)
                    prior_handler = misc.fromFile(prior_file)
                else:
                    prior_handler = None
                cur_handler = data.QuestHandler(cond['startVal'],
                                                cond['startValSd'],
                                                pThreshold=cond['pThreshold'],
                                                nTrials=self.trial_nmb,
                                                minVal=cond['min_val'],
                                                maxVal=cond['max_val'],
                                                staircase=prior_handler,
                                                extraInfo=cond)
                stairs.append(cur_handler)
        elif conditions[0]['stairType'] == 'psi':
            stairs = []
            for cond in conditions:
                if self.priors_file_path:
                    prior_file = self.priors_file_path + cond['label'] + '.npy'
                else:
                    prior_file = None
                print(prior_file)
                cur_handler = data.PsiHandler(nTrials=self.trial_nmb,
                                              intensRange=[1, 10],
                                              alphaRange=[1, 10],
                                              betaRange=[0.01, 10],
                                              intensPrecision=0.1,
                                              alphaPrecision=0.1,
                                              betaPrecision=0.01,
                                              delta=0.01,
                                              extraInfo=cond,
                                              prior=prior_file,
                                              fromFile=(prior_file
                                                        is not None))
                stairs.append(cur_handler)

        # write configuration files
        xpp = config_tools.WriteXpp(self.subject, self.idx)
        xpp_file = xpp.head(self.cfg_file, self.par_file)
        config_tools.write_xrl(self.subject,
                               cfg_file=self.cfg_file,
                               par_file=self.par_file,
                               xpp_file=xpp_file)

        xlsname = path + '/' + self.idx + self.param[
            'noise_condition'] + '.xlsx'
        """ running staircase """

        if isinstance(stairs, data.MultiStairHandler):
            # start running the staircase using the MultiStairHandler for the up-down method
            count = 0

            for rot, cond in stairs:
                count += 1
                judge, thiskey, trial_time = self.run_trial(rot, cond, count)

                # check whether the theta is valid - if not, the rotation given by staircase should be corrected by
                # realizable values
                valid_theta = np.round(np.load(self.hue_list), decimals=1)

                disp_standard = self.take_closest(
                    valid_theta, cond['standard'])  # theta actually displayed
                stair_test = cond['standard'] + stairs._nextIntensity * (-1)**(
                    cond['label'].endswith('m'))  # theta for staircase
                if stair_test < 0:
                    stair_test += 360
                disp_test = self.take_closest(valid_theta, stair_test)
                disp_intensity = abs(disp_test - disp_standard)
                if disp_intensity > 300:
                    disp_intensity = 360 - (disp_test + disp_standard)
                stairs.addResponse(judge, disp_intensity)

                xpp.task(count, cond, rot, float(disp_intensity), judge,
                         trial_time)

                event.waitKeys(keyList=[
                    thiskey
                ])  # press the response key again to start the next trial

            config_tools.write_xrl(self.subject, xls_file=xlsname)
            stairs.saveAsExcel(xlsname)  # save results
            psydat_file_path = os.path.join(
                path, "psydat", self.idx + self.param['condition'] +
                '.psydat')  # save the handler into a psydat-file
            misc.toFile(psydat_file_path, stairs)

        elif isinstance(stairs, list):
            # start running the staircase using custom interleaving stairs for the quest and psi methods
            count = 0
            rot_all = []
            rot_all_disp = []
            judge_all = []
            estimates = {s.extraInfo['label']: [] for s in stairs}

            for trial_n in range(self.trial_nmb):
                for handler_idx, cur_handler in enumerate(stairs):
                    count += 1
                    rot = next(cur_handler)

                    if len(rot_all) <= handler_idx:
                        rot_all.append([])
                    rot_all[handler_idx].append(rot)
                    cond = cur_handler.extraInfo
                    judge, thiskey, trial_time = self.run_trial(
                        rot, cond, count)

                    if len(judge_all) <= handler_idx:
                        judge_all.append([])
                    judge_all[handler_idx].append(judge)
                    # cur_handler.addResponse(judge)  # to the next trial

                    valid_theta = np.round(np.load(self.hue_list), decimals=1)
                    disp_standard = self.take_closest(
                        valid_theta,
                        cond['standard'])  # theta actually displayed
                    stair_test = cond[
                        'standard'] + cur_handler._nextIntensity * (-1)**(
                            cond['label'].endswith('m'))  # theta for staircase
                    if stair_test < 0:
                        stair_test += 360
                    disp_test = self.take_closest(valid_theta, stair_test)
                    disp_intensity = abs(disp_test - disp_standard)
                    if disp_intensity > 300:
                        disp_intensity = 360 - (disp_test + disp_standard)
                    cur_handler.addResponse(judge, disp_intensity)

                    if len(rot_all_disp
                           ) <= handler_idx:  # add displayed intensities
                        rot_all_disp.append([])
                    rot_all_disp[handler_idx].append(disp_intensity)

                    print('stair test: ' + str(stair_test) + ', ' +
                          'disp_test:' + str(disp_test))

                    if isinstance(cur_handler, data.PsiHandler):
                        estimates[cur_handler.extraInfo['label']].append([
                            cur_handler.estimateLambda()[0],  # location
                            cur_handler.estimateLambda768()[1],  # slope
                            cur_handler.estimateThreshold(0.75)
                        ])
                    elif isinstance(cur_handler, data.QuestHandler):
                        estimates[cur_handler.extraInfo['label']].append([
                            cur_handler.mean(),
                            cur_handler.mode(),
                            cur_handler.quantile(0.5)
                        ])

                    xpp.task(count, cond, rot, disp_intensity, judge,
                             trial_time)
                    event.waitKeys(keyList=[
                        thiskey
                    ])  # press the response key again to start the next trial

            config_tools.write_xrl(self.subject, xls_file=xlsname)

            # save results in xls-file
            workbook = xlsxwriter.Workbook(xlsname)
            for handler_idx, cur_handler in enumerate(stairs):
                worksheet = workbook.add_worksheet(
                    cur_handler.extraInfo['label'])
                worksheet.write('A1', 'Reversal Intensities')
                worksheet.write('B1', 'Reversal Indices')
                worksheet.write('C1', 'All Intensities')
                worksheet.write('D1', 'All Responses')
                for i in range(len(rot_all[handler_idx])):
                    # worksheet.write('C' + str(i + 2), rot_all[handler_idx][i])
                    worksheet.write('C' + str(i + 2),
                                    rot_all_disp[handler_idx][i])
                    worksheet.write('D' + str(i + 2),
                                    judge_all[handler_idx][i])
            workbook.close()

            # print resulting parameters and estimates for each step
            res_file_path = os.path.join(path, self.idx + '_estimates.csv')
            res_writer = csv.writer(open(res_file_path, 'w'))
            for res_stim, res_vals in estimates.items():
                for res_val_id, res_val in enumerate(res_vals):
                    res_writer.writerow([
                        res_stim, res_val_id, res_val[0], res_val[1],
                        res_val[2]
                    ])

            # save each handler into a psydat-file and save posterior into a numpy-file
            for cur_handler in stairs:
                file_name = os.path.join(
                    path, self.idx + self.param['noise_condition'] +
                    cur_handler.extraInfo['label'])
                misc.toFile(file_name + '.psydat', cur_handler)
                if isinstance(cur_handler, data.PsiHandler):
                    cur_handler.savePosterior(file_name + '.npy')
Beispiel #21
0
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()

# -------Ending Routine "instruct"-------
for thisComponent in instructComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "instruct" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()

# set up handler to look after randomisation of trials etc
conditions = data.importConditions('2Nb-stimuls-5.xlsx')
trials = data.MultiStairHandler(stairType='simple',
                                name='trials',
                                nTrials=1,
                                conditions=conditions,
                                originPath=-1)
thisExp.addLoop(trials)  # add the loop to the experiment
# initialise values for first condition
level = trials._nextIntensity  # initialise some vals
condition = trials.currentStaircase.condition

for level, condition in trials:
    currentLoop = trials
    # abbreviate parameter names if possible (e.g. rgb=condition.rgb)
    for paramName in condition:
        exec(paramName + '= condition[paramName]')

    # ------Prepare to start Routine "trial"-------
    t = 0
Beispiel #22
0
def startExperiment():
    try:
        expInfo, stairInfo, outputfile, monitorInfo = setupExperiment()
        win = open_window(monitorInfo, measureFPS=False)
        win.measuredFPS = 59.95
        show_instructions(
            win, "Press spacebar to start experiment, doing " +
            str(expInfo['TrainingTrials']) + " training trials")

        # Convert the string of steps to a list of floats to feed to every
        # staircase
        stepSizes = [
            float(x) for x in stairInfo['StepSizes'].replace('[', '').replace(
                ']', '').split(',')
        ]

        expConditions = [{
            'label': 'Right',
            'startVal': stairInfo['ContrastRight'],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpRight'],
            'nDown': stairInfo['nDownRight'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': min(stepSizes),
            'maxVal': 1
        }, {
            'label': 'Left',
            'startVal': stairInfo['ContrastLeft'],
            'method': '2AFC',
            'stepType': stairInfo['StepType'],
            'stepSizes': stepSizes,
            'nUp': stairInfo['nUpLeft'],
            'nDown': stairInfo['nDownLeft'],
            'nTrials': stairInfo['MinTrials'],
            'nReversals': stairInfo['MinReversals'],
            'minVal': min(stepSizes),
            'maxVal': 1
        }]

        print "Minimum value for staircase = ", min(stepSizes)
        from psychopy import data
        stairs = data.MultiStairHandler(conditions=expConditions,
                                        nTrials=1,
                                        method=stairInfo['Selection'])

        if (monitorInfo['RunSpeedTest']):
            from common.draw_test_square import draw_test_square
            draw_test_square(win)

        # Do some training trials with no variation in speed
        for i in np.linspace(0.0, 2.0, expInfo['TrainingTrials']):
            contrastTrial(win,
                          expInfo,
                          contrastValue=i,
                          side='Left',
                          useSameStimuli=randrange(0, 2))

        show_instructions(win,
                          "Finished training trials, press spacebar to begin")

        for contrast, thisCondition in stairs:
            sameStimuli = randrange(0, 100) < 25  # To present 4 equal stimuli
            thisResp = contrastTrial(win,
                                     expInfo,
                                     contrastValue=contrast,
                                     side=thisCondition['label'],
                                     useSameStimuli=sameStimuli)
            if thisResp is not None:
                stairs.addData(not thisResp)
            else:
                print "skipped"
            # save data as multiple formats for every trial
            stairs.saveAsText(outputfile)

        stairs.saveAsText(outputfile)
        stairs.saveAsPickle(outputfile)
        stairs.saveAsExcel(outputfile)
        experiment_finished(win)
    except:
        win.close()
        raise
    def run_session(self):

        path = os.path.join(self.res_dir, self.subject)
        if not os.path.exists(path):
            os.makedirs(path)
        psydat_path = os.path.join(path, 'psydat')
        if not os.path.exists(psydat_path):
            os.makedirs(psydat_path)

        # welcome
        msg = visual.TextStim(self.win,
                              'Welcome!' + '\n' +
                              ' Press any key to start this session :)',
                              color='black',
                              units='deg',
                              pos=(0, 0),
                              height=0.8)
        msg.draw()
        self.win.mouseVisible = False
        self.win.flip()
        event.waitKeys()

        # read staircase parameters
        conditions = [
            dict({'stimulus': key}, **value)
            for key, value in self.param.items() if key.startswith('stimulus')
        ]

        if conditions[0]['stairType'] == 'simple':
            stairs = data.MultiStairHandler(stairType='simple',
                                            conditions=conditions,
                                            nTrials=self.trial_nmb,
                                            method='sequential')
        elif conditions[0]['stairType'] == 'quest':
            stairs = []
            for cond in conditions:
                if self.priors_file_path:
                    prior_file = self.priors_file_path + cond[
                        'label'] + '.psydat'
                    print(prior_file)
                    prior_handler = misc.fromFile(prior_file)
                else:
                    prior_handler = None
                cur_handler = data.QuestHandler(cond['startVal'],
                                                cond['startValSd'],
                                                pThreshold=cond['pThreshold'],
                                                nTrials=self.trial_nmb,
                                                minVal=cond['min_val'],
                                                maxVal=cond['max_val'],
                                                staircase=prior_handler,
                                                extraInfo=cond,
                                                grain=0.02)
                stairs.append(cur_handler)
        elif conditions[0]['stairType'] == 'psi':
            stairs = []
            for cond in conditions:
                if self.priors_file_path:
                    prior_file = self.priors_file_path + cond['label'] + '.npy'
                else:
                    prior_file = None
                print(prior_file)
                cur_handler = data.PsiHandler(nTrials=self.trial_nmb,
                                              intensRange=[1, 10],
                                              alphaRange=[1, 10],
                                              betaRange=[0.01, 10],
                                              intensPrecision=0.1,
                                              alphaPrecision=0.1,
                                              betaPrecision=0.01,
                                              delta=0.01,
                                              extraInfo=cond,
                                              prior=prior_file,
                                              fromFile=(prior_file
                                                        is not None))
                stairs.append(cur_handler)

        # write configuration files
        xpp = config_tools.WriteXpp(self.subject, self.idx)
        xpp_file = xpp.head(self.cfg_file, self.par_file)
        config_tools.write_xrl(self.subject,
                               cfg_file=self.cfg_file,
                               par_file=self.par_file,
                               xpp_file=xpp_file)

        xlsname = path + '/' + self.idx + self.param[
            'noise_condition'] + '.xlsx'
        """ running staircase """

        if isinstance(stairs, data.MultiStairHandler):
            # start running the staircase using the MultiStairHandler for the up-down method
            count = 0

            for rot, cond in stairs:
                count += 1
                direction = (-1)**(cond['label'].endswith('m')
                                   )  # direction as -1 if for minus stim
                rot = rot * direction  # rotation for this trial
                judge, react_time, trial_time_start = self.run_trial(
                    rot, cond, cond['std'], count)

                # check whether the theta is valid - if not, the rotation given by staircase should be corrected by
                # realizable values
                valid_theta = np.round(np.load(self.hue_list), decimals=1)

                disp_standard = self.take_closest(
                    valid_theta, cond['standard'])  # theta actually displayed
                stair_test = cond[
                    'standard'] + stairs._nextIntensity * direction
                if stair_test < 0:
                    stair_test += 360
                disp_test = self.take_closest(valid_theta, stair_test)
                disp_intensity = disp_test - disp_standard
                if disp_intensity > 300:
                    disp_intensity = (disp_test + disp_standard) - 360
                stairs.addResponse(judge, abs(disp_intensity))

                xpp.task(count, cond, rot, float(disp_intensity), judge,
                         react_time, trial_time_start)

                if 'escape' in event.waitKeys():
                    config_tools.write_xrl(self.subject,
                                           break_info='userbreak')
                    core.quit()

            config_tools.write_xrl(self.subject, xls_file=xlsname)
            stairs.saveAsExcel(xlsname)  # save results
            misc.toFile(
                os.path.join(
                    psydat_path,
                    self.idx + self.param['noise_condition'] + '.psydat'),
                stairs)

        elif isinstance(stairs, list):
            # start running the staircase using custom interleaving stairs for the quest and psi methods
            count = 0
            rot_all = []
            rot_all_disp = []
            judge_all = []
            estimates = {s.extraInfo['label']: [] for s in stairs}

            for trial_n in range(self.trial_nmb):
                for handler_idx, cur_handler in enumerate(stairs):
                    count += 1
                    direction = (-1)**(
                        cur_handler.extraInfo['label'].endswith('m')
                    )  # direction as -1 if for minus stim

                    if cur_handler._nextIntensity >= 10.0:
                        sys.exit(
                            "Hue difference is out of range! Please enlarge the testing range or take more training!"
                        )

                    rot = cur_handler._nextIntensity * direction  # rotation for this trial
                    if trial_n >= 5:  # avoid repeating an intensity more than 3 times
                        last_rots = [
                            np.round(r, decimals=1) for r in [
                                rot_all_disp[handler_idx][trial_n - 1],
                                rot_all_disp[handler_idx][trial_n - 2],
                                rot_all_disp[handler_idx][trial_n - 3]
                            ]
                        ]
                        last_resp = [
                            judge_all[handler_idx][trial_n - 1],
                            judge_all[handler_idx][trial_n - 2],
                            judge_all[handler_idx][trial_n - 3]
                        ]
                        if last_rots[0] == last_rots[1] == last_rots[2] \
                                and last_resp[0] == last_resp[1] == last_resp[2]:
                            if cur_handler._nextIntensity > 0.5:
                                rot = (cur_handler._nextIntensity -
                                       0.5) * direction
                                print('Intensity decreases by 0.5!')
                            if cur_handler._nextIntensity <= 0.5:
                                rot = (cur_handler._nextIntensity +
                                       0.5) * direction
                                print('Intensity increases by 0.5!')
                    cond = cur_handler.extraInfo
                    judge, react_time, trial_time_start = self.run_trial(
                        rot, cond, cond['std'], count)

                    if len(rot_all) <= handler_idx:
                        rot_all.append([])
                    rot_all[handler_idx].append(rot)

                    if len(judge_all) <= handler_idx:
                        judge_all.append([])
                    judge_all[handler_idx].append(judge)

                    valid_theta = np.round(np.load(self.hue_list), decimals=1)
                    disp_standard = self.take_closest(valid_theta,
                                                      cond['standard'])
                    stair_test = cond[
                        'standard'] + rot  # calculated test hue for this trial
                    if stair_test < 0:
                        stair_test += 360
                    disp_test = self.take_closest(
                        valid_theta,
                        stair_test)  # actual displayed test hue for this trial

                    disp_intensity = disp_test - disp_standard  # actual displayed hue difference
                    if disp_intensity > 300:
                        disp_intensity = (disp_test + disp_standard) - 360

                    cur_handler.addResponse(
                        judge, abs(disp_intensity)
                    )  # only positive number is accepted by addResponse

                    if len(rot_all_disp
                           ) <= handler_idx:  # add displayed intensities
                        rot_all_disp.append([])
                    rot_all_disp[handler_idx].append(disp_intensity)

                    if isinstance(cur_handler, data.PsiHandler):
                        estimates[cur_handler.extraInfo['label']].append([
                            cur_handler.estimateLambda()[0],  # location
                            cur_handler.estimateLambda768()[1],  # slope
                            cur_handler.estimateThreshold(0.75)
                        ])
                    elif isinstance(cur_handler, data.QuestHandler):
                        estimates[cur_handler.extraInfo['label']].append([
                            cur_handler.mean(),
                            cur_handler.mode(),
                            cur_handler.quantile(0.5)
                        ])

                    xpp.task(count, cond, rot, disp_intensity, judge,
                             react_time, trial_time_start)

                    if 'escape' in event.waitKeys():
                        config_tools.write_xrl(self.subject,
                                               break_info='userbreak')
                        core.quit()

            config_tools.write_xrl(self.subject, xls_file=xlsname)

            # save results in xls-file
            workbook = xlsxwriter.Workbook(xlsname)
            for handler_idx, cur_handler in enumerate(stairs):
                worksheet = workbook.add_worksheet(
                    cur_handler.extraInfo['label'])
                worksheet.write('A1', 'Reversal Intensities')
                worksheet.write('B1', 'Reversal Indices')
                worksheet.write('C1', 'All Intensities')
                worksheet.write('D1', 'All Responses')
                for i in range(len(rot_all[handler_idx])):
                    # worksheet.write('C' + str(i + 2), rot_all[handler_idx][i])
                    worksheet.write('C' + str(i + 2),
                                    rot_all_disp[handler_idx][i])
                    worksheet.write('D' + str(i + 2),
                                    judge_all[handler_idx][i])
            workbook.close()

            # print resulting parameters and estimates for each step
            res_file_path = os.path.join(path, self.idx + '_estimates.csv')
            res_writer = csv.writer(open(res_file_path, 'w'))
            for res_stim, res_vals in estimates.items():
                for res_val_id, res_val in enumerate(res_vals):
                    res_writer.writerow([
                        res_stim, res_val_id, res_val[0], res_val[1],
                        res_val[2]
                    ])

            # save each handler into a psydat-file and save posterior into a numpy-file
            for cur_handler in stairs:
                file_name = os.path.join(
                    psydat_path, self.idx + self.param['noise_condition'] +
                    cur_handler.extraInfo['label'])
                misc.toFile(file_name + '.psydat', cur_handler)
                if isinstance(cur_handler, data.PsiHandler):
                    cur_handler.savePosterior(file_name + '.npy')
Beispiel #24
0
        thisComponent.setAutoDraw(False)
# check responses
if key_resp_3.keys in ['', [], None]:  # No response was made
    key_resp_3.keys = None
# store data for thisExp (ExperimentHandler)
thisExp.addData('key_resp_3.keys', key_resp_3.keys)
if key_resp_3.keys != None:  # we had a response
    thisExp.addData('key_resp_3.rt', key_resp_3.rt)
thisExp.nextEntry()

# set up handler to look after randomisation of trials etc
conditions = data.importConditions('staircaseflo_2.xlsx')
trials_2 = data.MultiStairHandler(
    stairType='simple',
    name='trials_2',
    nTrials=5,
    conditions=conditions,
    originPath=
    u'/Users/jason/Dropbox/SteffenerColumbia/Scripts/ExperimentalStimuli/Johannes/staircaseEXP.psyexp'
)
thisExp.addLoop(trials_2)  # add the loop to the experiment
# initialise values for first condition
level = trials_2._nextIntensity  # initialise some vals
condition = trials_2.currentStaircase.condition

for level, condition in trials_2:
    currentLoop = trials_2
    # abbreviate parameter names if possible (e.g. rgb=condition.rgb)
    for paramName in condition.keys():
        exec(paramName + '= condition[paramName]')

    #------Prepare to start Routine "ISI_2"-------
Beispiel #25
0
show_practice_trial()
show_practice_trial()
show_practice_trial()
show_practice_trial()

instructions6.draw()
win.flip()
event.waitKeys()

# Start staircase
current_run=0
total_run=range(4)
for current_run in total_run:
    # create the staircase handler
    if params.staircase_style == 'QUEST':
        staircase = data.MultiStairHandler(stairType='QUEST', conditions=params.conditions_QUEST,  nTrials=params.staircase_ntrials)
    else:
        staircase = data.MultiStairHandler(stairType='simple', conditions=params.conditions_simple, nTrials=params.staircase_ntrials)
    print('Created staircase: %s' % params.staircase_style)
    n_trials = 0
    for this_stim_secs, this_condition in staircase:
        frame_n=0
        # Print trial number, condition info to console
        n_trials += 1
        print('trial:', str(n_trials), 'condition: ' + this_condition['label'] + " | " + 'stim_secs: ' + str(this_stim_secs))
        
        # Initialize grating parameters for this condition
        this_max_contrast = this_condition['max_contr']
        this_grating_degree = this_condition['grating_deg']
        this_tf = this_condition['tf']
        this_spf = this_condition['spf']
Beispiel #26
0
                  lineWidth=0,
                  size=.75,
                  pos=(0, 0))

message1 = visual.TextStim(win, pos=[0, +3], text='Hit a key when ready.')
message2 = visual.TextStim(
    win,
    pos=[0, -3],
    text=
    "When the white box appears, press LEFT arrow to identify a horizontal grating or the UP arrow to identify a vertical grating."
)

# create the staircase handler
if params.stair_case_style == 'quest':
    staircase = data.MultiStairHandler(stairType='quest',
                                       conditions=params.conditions_QUEST,
                                       nTrials=50)
else:
    staircase = data.MultiStairHandler(stairType='simple',
                                       conditions=params.conditions_simple,
                                       nTrials=50)

#-----------------------------------------------------------------------------------------------------------
# Start experiment
#-----------------------------------------------------------------------------------------------------------

# display instructions and wait
message1.draw()
message2.draw()
fixation.draw()
win.flip()