Ejemplo n.º 1
0
    def test_comparison_not_equal_after_iteration(self):
        if _travisTesting:
            pytest.skip()

        p1 = data.PsiHandler(nTrials=10,
                             intensRange=[0.1, 10],
                             alphaRange=[0.1, 10],
                             betaRange=[0.1, 3],
                             intensPrecision=0.1,
                             alphaPrecision=0.1,
                             betaPrecision=0.1,
                             delta=0.01)

        p2 = data.PsiHandler(nTrials=10,
                             intensRange=[0.1, 10],
                             alphaRange=[0.1, 10],
                             betaRange=[0.1, 3],
                             intensPrecision=0.1,
                             alphaPrecision=0.1,
                             betaPrecision=0.1,
                             delta=0.001)

        p1.__next__()
        p2.__next__()
        assert p1 != p2
Ejemplo n.º 2
0
    def test_comparison_not_equal(self):
        p1 = data.PsiHandler(nTrials=10, intensRange=[0.1, 10],
                             alphaRange=[0.1, 10], betaRange=[0.1, 3],
                             intensPrecision=0.1, alphaPrecision=0.1,
                             betaPrecision=0.1, delta=0.01)

        p2 = data.PsiHandler(nTrials=10, intensRange=[0.1, 10],
                             alphaRange=[0.1, 10], betaRange=[0.1, 3],
                             intensPrecision=0.1, alphaPrecision=0.1,
                             betaPrecision=0.1, delta=0.001)

        assert p1 != p2
Ejemplo n.º 3
0
    def test_comparison_equals_after_iteration(self):
        p1 = data.PsiHandler(nTrials=10, intensRange=[0.1, 10],
                             alphaRange=[0.1, 10], betaRange=[0.1, 3],
                             intensPrecision=0.1, alphaPrecision=0.1,
                             betaPrecision=0.1, delta=0.01)

        p2 = data.PsiHandler(nTrials=10, intensRange=[0.1, 10],
                             alphaRange=[0.1, 10], betaRange=[0.1, 3],
                             intensPrecision=0.1, alphaPrecision=0.1,
                             betaPrecision=0.1, delta=0.01)

        p1.__next__()
        p2.__next__()
        assert p1 == p2
Ejemplo n.º 4
0
    def test_json_dump(self):
        p = data.PsiHandler(nTrials=10, intensRange=[0.1, 10],
                            alphaRange=[0.1, 10], betaRange=[0.1, 3],
                            intensPrecision=1, alphaPrecision=1,
                            betaPrecision=0.5, delta=0.01)
        dump = p.saveAsJson()

        p.origin = ''
        assert p == json_tricks.np.loads(dump)
Ejemplo n.º 5
0
 def test_json_dump_to_file(self):
     _, path = mkstemp(dir=self.tmp_dir, suffix='.json')
     p = data.PsiHandler(nTrials=10,
                         intensRange=[0.1, 10],
                         alphaRange=[0.1, 10],
                         betaRange=[0.1, 3],
                         intensPrecision=1,
                         alphaPrecision=1,
                         betaPrecision=0.5,
                         delta=0.01)
     p.saveAsJson(fileName=path, fileCollisionMethod='overwrite')
Ejemplo n.º 6
0
    def test_json_dump_with_data(self):
        p = data.PsiHandler(nTrials=10, intensRange=[0.1, 10],
                            alphaRange=[0.1, 10], betaRange=[0.1, 3],
                            intensPrecision=1, alphaPrecision=1,
                            betaPrecision=0.5, delta=0.01)
        p.addResponse(1)
        p.addOtherData('foo', 'bar')
        dump = p.saveAsJson()

        p.origin = ''
        assert p == json_tricks.np.loads(dump)
Ejemplo n.º 7
0
    def test_comparison_equals(self):
        if _travisTesting:
            pytest.skip()

        p1 = data.PsiHandler(nTrials=10,
                             intensRange=[0.1, 10],
                             alphaRange=[0.1, 10],
                             betaRange=[0.1, 3],
                             intensPrecision=0.1,
                             alphaPrecision=0.1,
                             betaPrecision=0.1,
                             delta=0.01)

        p2 = data.PsiHandler(nTrials=10,
                             intensRange=[0.1, 10],
                             alphaRange=[0.1, 10],
                             betaRange=[0.1, 3],
                             intensPrecision=0.1,
                             alphaPrecision=0.1,
                             betaPrecision=0.1,
                             delta=0.01)

        assert p1 == p2
Ejemplo n.º 8
0
    def test_json_dump_and_reopen_file(self):
        p = data.PsiHandler(nTrials=10, intensRange=[0.1, 10],
                            alphaRange=[0.1, 10], betaRange=[0.1, 3],
                            intensPrecision=1, alphaPrecision=1,
                            betaPrecision=0.5, delta=0.01)
        p.addResponse(1)
        p.addOtherData('foo', 'bar')
        p.__next__()

        _, path = mkstemp(dir=self.tmp_dir, suffix='.json')
        p.saveAsJson(fileName=path, fileCollisionMethod='overwrite')
        p.origin = ''

        p_loaded = fromFile(path)
        assert p == p_loaded
Ejemplo n.º 9
0
    def test_json_dump_after_iteration(self):
        if _travisTesting:
            pytest.skip()

        p = data.PsiHandler(nTrials=10,
                            intensRange=[0.1, 10],
                            alphaRange=[0.1, 10],
                            betaRange=[0.1, 3],
                            intensPrecision=1,
                            alphaPrecision=1,
                            betaPrecision=0.5,
                            delta=0.01)
        p.__next__()
        dump = p.saveAsJson()

        p.origin = ''
        assert p == json_tricks.np.loads(dump)
Ejemplo n.º 10
0
    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')
    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')