示例#1
0
def test3():
    """
    Abandoned!!!
    """
    # _, color = ColorPicker(unit='deg').newcolor(theta=90)
    color = ColorPicker().Crgb

    newR = np.array([color[0] - 1.0, color[1],
                     color[2]])  # should be visible on 8-bit display
    newG = np.array([color[0], color[1] + 1.0, color[2]])
    newB = np.array([color[0], color[1], color[2] + 1.0])

    testR = np.array([color[0] - 0.5, color[1],
                      color[2]])  # should be only visible on 10-bit display
    testG = np.array([color[0], color[1] + 0.5, color[2]])
    testB = np.array([color[0], color[1], color[2] + 0.5])

    allcolor = np.stack([newR, newG, newB, testR, testG, testB])
    convertrgb = allcolor / 255 * 2 - 1  # convert from [0, 255] to [-1, 1]
    convert1023 = allcolor / 255 * 1023

    Crgb = list(ColorPicker().Crgb / 255 * 2 - 1)

    win = visual.Window(fullscr=True, color=Crgb, colorSpace='rgb',
                        unit='pix')  # need bpc=(bit, bit, bit), depthBits=bit?
    size = 0.3

    for idx in range(3):
        colorRect = visual.Rect(win,
                                width=size,
                                height=size,
                                pos=[-0.3, (idx - 1) * 0.3],
                                fillColor=color / 255 * 2 - 1,
                                lineColor=Crgb)

        newRect = visual.Rect(win,
                              width=size,
                              height=size,
                              pos=[0.3, (idx - 1) * 0.3],
                              fillColor=convertrgb[idx],
                              lineColor=Crgb)

        testRect = visual.Rect(win,
                               width=size,
                               height=size,
                               pos=[0, (idx - 1) * 0.3],
                               fillColor=convertrgb[idx + 3],
                               lineColor=Crgb)

        colorRect.draw()
        newRect.draw()
        testRect.draw()

    win.flip()
    if event.waitKeys():
        win.close()
        return
示例#2
0
def test4():
    """
    Abandoned!!!
    Temporal changes of colors: should be only visible on 10-bit display
    """
    from psychopy.hardware import keyboard
    import time

    Crgb = ColorPicker().Crgb

    _, color = ColorPicker(unit='deg').newcolor(theta=90)

    testR = np.array([color[0] - 0.5, color[1],
                      color[2]])  # should be only visible on 10-bit display
    testG = np.array([color[0], color[1] + 0.5, color[2]])
    testB = np.array([color[0], color[1], color[2] + 0.5])

    allcolor = np.stack([color, testR, testG, testB])

    kb = keyboard.Keyboard()

    win = visual.Window(unit='pix',
                        size=[800, 800],
                        allowGUI=True,
                        fullscr=True,
                        colorSpace="rgb255",
                        color=Crgb)
    while True:
        nowcolor = allcolor[int(np.random.choice(4, 1, replace=False))]

        rect = visual.Rect(win,
                           width=0.5,
                           height=0.5,
                           pos=[0, 0],
                           fillColorSpace='rgb255',
                           lineColorSpace='rgb255',
                           lineColor=list(Crgb))
        rect.fillColor = nowcolor

        text = visual.TextStim(win,
                               text=str(nowcolor),
                               pos=[0, -0.8],
                               height=0.05)
        win.mouseVisible = False

        rect.draw()
        text.draw()
        win.flip()

        kb.clock.reset()
        if kb.getKeys():  # press any key to quit
            core.quit()
        else:
            time.sleep(1)  # change every 3 sec
 def rand_color(self, theta, sigma, npatch):  # generate color noise
     noise = np.random.normal(theta, sigma, npatch)
     color = [
         ColorPicker.newcolor(theta, self.param['dlum']) for n in noise
     ]
     sml, rgb = zip(*color)
     return sml, rgb
    def __init__(self, subject, par_file, cfg_file, res_dir, priors_file_path):
        self.subject = subject
        self.idx = time.strftime("%Y%m%dT%H%M",
                                 time.localtime())  # add the current date
        if not res_dir:
            res_dir = 'data/'
        self.res_dir = res_dir
        self.priors_file_path = priors_file_path
        self.cfg_file = cfg_file
        self.cfg = config_tools.read_yml(cfg_file)
        self.par_file = par_file

        self.param = config_tools.read_yml(par_file)

        self.patch_nmb = self.cfg['patch_nmb']
        self.trial_nmb = self.cfg['trial_nmb']
        self.trial_dur = self.cfg['trial_dur']
        self.depthBits = self.cfg['depthBits']

        self.ColorPicker = ColorPicker(c=self.param['c'],
                                       sscale=self.param['sscale'],
                                       unit='deg',
                                       depthBits=self.depthBits,
                                       subject=self.subject)
        self.ColorSpace = self.ColorPicker.colorSpace

        hue_list_path = 'config/colorlist/' + self.subject
        if not os.path.exists(hue_list_path):
            self.ColorPicker.gencolorlist(0.2)
        self.hue_list = hue_list_path + '/hue-list-10bit-res0.2-sub-' + self.subject + '.npy'

        self.Csml = self.ColorPicker.Csml
        self.Crgb = self.ColorPicker.Crgb
        self.mon = monitors.Monitor(name=self.cfg['monitor']['name'],
                                    width=self.cfg['monitor']['width'],
                                    distance=self.cfg['monitor']['distance'])
        self.mon.setSizePix((self.cfg['monitor']['size']))
        self.win = visual.Window(monitor=self.mon,
                                 unit='deg',
                                 colorSpace=self.ColorSpace,
                                 color=self.Crgb,
                                 allowGUI=True,
                                 fullscr=True,
                                 bpc=(self.depthBits, self.depthBits,
                                      self.depthBits),
                                 depthBits=self.depthBits)
示例#5
0
def run_scrsaver(depthBits):
    mon = monitors.Monitor(name='VIEWPixx LITE', width=38, distance=57)
    mon.setSizePix((1920, 1200))
    mon.save()  # if the monitor info is not saved

    win = visual.Window(fullscr=True,
                        mouseVisible=False,
                        bpc=(depthBits, depthBits, depthBits),
                        depthBits=depthBits,
                        monitor=mon)
    kb = keyboard.Keyboard()

    if depthBits == 8:
        colorSpace = 'rgb255'
    elif depthBits == 10:
        colorSpace = 'rgb'
    else:
        raise ValueError("Invalid color depth!")

    while True:
        num = np.random.randint(5, high=10)
        rect = visual.ElementArrayStim(win,
                                       units='norm',
                                       nElements=num**2,
                                       elementMask=None,
                                       elementTex=None,
                                       sizes=(2 / num, 2 / num),
                                       colorSpace=colorSpace)
        rect.xys = [(x, y)
                    for x in np.linspace(-1, 1, num, endpoint=False) + 1 / num
                    for y in np.linspace(-1, 1, num, endpoint=False) + 1 / num]

        rect.colors = [
            ColorPicker(depthBits=depthBits, unit='deg').newcolor(x)[1]
            for x in np.random.randint(0, high=360, size=num**2)
        ]
        rect.draw()
        win.mouseVisible = False
        win.flip()

        kb.clock.reset()
        if kb.getKeys():  # press any key to quit
            core.quit()
        else:
            time.sleep(3)  # change every 3 sec
class Exp:
    """
    Class for performing the experiment.
    """
    def __init__(self, subject, par_file, cfg_file, res_dir, priors_file_path):
        self.subject = subject
        self.idx = time.strftime("%Y%m%dT%H%M",
                                 time.localtime())  # add the current date
        if not res_dir:
            res_dir = 'data/'
        self.res_dir = res_dir
        self.priors_file_path = priors_file_path
        self.cfg_file = cfg_file
        self.cfg = config_tools.read_yml(cfg_file)
        self.par_file = par_file

        self.param = config_tools.read_yml(par_file)

        self.patch_nmb = self.cfg['patch_nmb']
        self.trial_nmb = self.cfg['trial_nmb']
        self.trial_dur = self.cfg['trial_dur']
        self.depthBits = self.cfg['depthBits']

        self.ColorPicker = ColorPicker(c=self.param['c'],
                                       sscale=self.param['sscale'],
                                       unit='deg',
                                       depthBits=self.depthBits,
                                       subject=self.subject)
        self.ColorSpace = self.ColorPicker.colorSpace

        hue_list_path = 'config/colorlist/' + self.subject
        if not os.path.exists(hue_list_path):
            self.ColorPicker.gencolorlist(0.2)
        self.hue_list = hue_list_path + '/hue-list-10bit-res0.2-sub-' + self.subject + '.npy'

        self.Csml = self.ColorPicker.Csml
        self.Crgb = self.ColorPicker.Crgb
        self.mon = monitors.Monitor(name=self.cfg['monitor']['name'],
                                    width=self.cfg['monitor']['width'],
                                    distance=self.cfg['monitor']['distance'])
        self.mon.setSizePix((self.cfg['monitor']['size']))
        self.win = visual.Window(monitor=self.mon,
                                 unit='deg',
                                 colorSpace=self.ColorSpace,
                                 color=self.Crgb,
                                 allowGUI=True,
                                 fullscr=True,
                                 bpc=(self.depthBits, self.depthBits,
                                      self.depthBits),
                                 depthBits=self.depthBits)

    """stimulus features"""

    def patch_ref(self, theta):  # reference patches
        ref = visual.Circle(win=self.win,
                            units='deg',
                            radius=self.cfg['ref_size'],
                            fillColorSpace=self.ColorSpace,
                            lineColorSpace=self.ColorSpace)
        ref.fillColor = self.ColorPicker.newcolor(theta, self.param['dlum'])[1]
        ref.lineColor = ref.fillColor
        return ref

    def patch_stim(self):  # standard and test stimuli
        patch = visual.ElementArrayStim(win=self.win,
                                        units='deg',
                                        fieldSize=self.cfg['field_size'],
                                        nElements=self.patch_nmb,
                                        elementMask='circle',
                                        elementTex=None,
                                        sizes=self.cfg['patch_size'],
                                        colorSpace=self.ColorSpace)
        return patch

    def patch_pos(self, xlim, ylim):  # position of standard and test stimuli
        n = int(np.sqrt(self.patch_nmb))
        pos = [[x, y] for x in np.linspace(xlim[0], xlim[1], n)
               for y in np.linspace(ylim[0], ylim[1], n)]
        return pos

    """color noise & noise conditions"""

    def rand_color(self, theta, sigma, npatch):  # generate color noise
        noise = np.random.normal(theta, sigma, npatch)
        color = [
            ColorPicker.newcolor(theta, self.param['dlum']) for n in noise
        ]
        sml, rgb = zip(*color)
        return sml, rgb

    def choose_con(self, standard, test):  # choose noise condition
        sColor = None
        tColor = None
        if self.param['noise_condition'] == 'L-L':  # low - low noise
            sColor = self.ColorPicker.newcolor(standard, self.param['dlum'])[1]
            tColor = self.ColorPicker.newcolor(test, self.param['dlum'])[1]

        elif self.param[
                'noise_condition'] == 'L-H':  # low - high noise: only test stimulus has high noise
            sColor = self.ColorPicker.newcolor(standard, self.param['dlum'])[1]

            tColor = self.rand_color(test, self.param['sigma'],
                                     self.patch_nmb)[1]

        elif self.param['noise_condition'] == 'H-H':  # high - high noise
            sColor = self.rand_color(standard, self.param['sigma'],
                                     self.patch_nmb)[1]
            tColor = self.rand_color(test, self.param['sigma'],
                                     self.patch_nmb)[1]

        else:
            print("No noise condition corresponds to the input!")

        return sColor, tColor

    """tool fucntion"""

    def take_closest(self, arr, val):
        """
        Assumes arr is sorted. Returns closest value to val (could be itself).
        If two numbers are equally close, return the smallest number.
        """
        pos = bisect_left(arr, val)
        if pos == 0:
            return arr[0]
        if pos == len(arr):
            return arr[-1]
        before = arr[pos - 1]
        after = arr[pos]
        if after - val < val - before:
            return after
        else:
            return before

    """main experiment"""

    def run_trial(self, rot, cond, count):
        # set two reference
        left = cond['leftRef']
        right = cond['rightRef']

        leftRef = self.patch_ref(left)
        leftRef.pos = self.cfg['leftRef.pos']
        rightRef = self.patch_ref(right)
        rightRef.pos = self.cfg['rightRef.pos']

        # set colors of two stimuli
        standard = cond['standard']  # standard should be fixed
        test = standard + rot

        sPatch = self.patch_stim()
        tPatch = self.patch_stim()
        sPatch.colors, tPatch.colors = self.choose_con(standard, test)

        # randomly assign patch positions: upper (+) or lower (-)
        patchpos = [self.cfg['standard.ylim'], self.cfg['test.ylim']]
        rndpos = patchpos.copy()
        np.random.shuffle(rndpos)

        sPatch.xys = self.patch_pos(self.cfg['standard.xlim'], rndpos[0])
        tPatch.xys = self.patch_pos(self.cfg['test.xlim'], rndpos[1])

        # fixation cross
        fix = visual.TextStim(self.win,
                              text="+",
                              units='deg',
                              pos=[0, 0],
                              height=0.4,
                              color='black',
                              colorSpace=self.ColorSpace)
        # number of trial
        num = visual.TextStim(self.win,
                              text="trial " + str(count),
                              units='deg',
                              pos=[12, -10],
                              height=0.4,
                              color='black',
                              colorSpace=self.ColorSpace)

        trial_time_start = time.time()
        # first present references for 0.5 sec
        fix.draw()
        num.draw()
        leftRef.draw()
        rightRef.draw()
        self.win.flip()
        core.wait(1.0)

        # then present the standard and the test stimuli as well for
        fix.draw()
        num.draw()
        leftRef.draw()
        rightRef.draw()
        sPatch.draw()
        tPatch.draw()
        self.win.flip()

        if self.trial_dur:
            # show stimuli for some time
            core.wait(self.trial_dur)

            # refresh the window, clear references and stimuli
            num.draw()
            self.win.flip()

        # get response
        judge = None

        while judge is None:
            allkeys = event.waitKeys()
            for key in allkeys:
                if (key == 'left' and rot * rndpos[0][0] > 0) or (
                        key == 'right' and rot * rndpos[0][0] < 0):
                    judge = 1  # correct
                    thiskey = key
                elif (key == 'left' and rot * rndpos[0][0] < 0) or (
                        key == 'right' and rot * rndpos[0][0] > 0):
                    judge = 0  # incorrect
                    thiskey = key
                elif key == 'escape':
                    breakinfo = 'userbreak'
                    # xrl.add_break(breakinfo)
                    config_tools.write_xrl(self.subject,
                                           break_info='userbreak')
                    core.quit()

        trial_time = time.time() - trial_time_start

        return judge, thiskey, trial_time

    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
                direction = (-1)**(cond['label'].endswith('m')
                                   )  # direction as -1 if for minus stim
                rot = rot * direction  # rotation for this trial
                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 * 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,
                         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
                    direction = (-1)**(
                        cur_handler.extraInfo['label'].endswith('m')
                    )  # direction as -1 if for minus stim
                    rot = next(
                        cur_handler) * direction  # rotation for this trial

                    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)

                    valid_theta = np.round(np.load(self.hue_list), decimals=1)
                    disp_standard = self.take_closest(valid_theta,
                                                      cond['standard'])
                    stair_test = cond[
                        'standard'] + direction * cur_handler._nextIntensity  # calculated test hue for this trial - although it is called nextIntensity
                    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, 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)

            # 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')
示例#7
0
def test2():
    """
    Abandoned!!!
    """
    _, color = ColorPicker().newcolor(theta=90, unit='deg')

    newR = np.array([color[0] - 1.0, color[1],
                     color[2]])  # should be visible on 8-bit display
    newG = np.array([color[0], color[1] + 1.0, color[2]])
    newB = np.array([color[0], color[1], color[2] + 1.0])

    testR = np.array([color[0] - 0.5, color[1],
                      color[2]])  # should be only visible on 10-bit display
    testG = np.array([color[0], color[1] + 0.5, color[2]])
    testB = np.array([color[0], color[1], color[2] + 0.5])

    allcolor = np.stack([newR, newG, newB, testR, testG, testB])
    convertrgb = allcolor / 255 * 2 - 1  # convert from [0, 255] to [-1, 1]
    convert1023 = allcolor / 255 * 1023

    Crgb = list(ColorPicker().Crgb / 255 * 2 - 1)

    win = visual.Window(
        [1000, 1000], color=Crgb,
        colorSpace='rgb')  # need bpc=(bit, bit, bit), depthBits=bit?
    for idx in range(3):
        colorRect = visual.Rect(win,
                                width=0.2,
                                height=0.2,
                                pos=[-0.6, (idx - 1) * 0.5],
                                fillColor=color / 255 * 2 - 1,
                                lineColor=Crgb)
        colorText = visual.TextStim(win,
                                    text=str(np.round(color, decimals=2)),
                                    pos=[-0.6, (idx - 1) * 0.5 + 0.2],
                                    height=0.05)
        colorText1023 = visual.TextStim(win,
                                        text=str(
                                            np.round(color / 255 * 1023,
                                                     decimals=2)),
                                        pos=[-0.6, (idx - 1) * 0.5 + 0.3],
                                        height=0.05)

        newRect = visual.Rect(win,
                              width=0.2,
                              height=0.2,
                              pos=[0.6, (idx - 1) * 0.5],
                              fillColor=convertrgb[idx],
                              lineColor=Crgb)
        newText = visual.TextStim(win,
                                  text=str(np.round(allcolor[idx],
                                                    decimals=2)),
                                  pos=[0.6, (idx - 1) * 0.5 + 0.2],
                                  height=0.05)
        newText1023 = visual.TextStim(win,
                                      text=str(
                                          np.round(convert1023[idx],
                                                   decimals=2)),
                                      pos=[0.6, (idx - 1) * 0.5 + 0.3],
                                      height=0.05)

        testRect = visual.Rect(win,
                               width=0.2,
                               height=0.2,
                               pos=[0, (idx - 1) * 0.5],
                               fillColor=convertrgb[idx + 3],
                               lineColor=Crgb)
        testText = visual.TextStim(win,
                                   text=str(
                                       np.round(allcolor[idx + 3],
                                                decimals=2)),
                                   pos=[0, (idx - 1) * 0.5 + 0.2],
                                   height=0.05)
        testText1023 = visual.TextStim(win,
                                       text=str(
                                           np.round(convert1023[idx + 3],
                                                    decimals=2)),
                                       pos=[0, (idx - 1) * 0.5 + 0.3],
                                       height=0.05)

        colorRect.draw()
        colorText.draw()
        colorText1023.draw()

        newRect.draw()
        newText.draw()
        newText1023.draw()

        testRect.draw()
        testText.draw()
        testText1023.draw()

    win.flip()
    if event.waitKeys():
        win.close()
        return
示例#8
0
def test6_pyglet(bit):
    """
    Abandoned!!! Not dynamic yet!!!
    Same test as test6, but using pyglet directly instead of Psychopy
    """
    import pyglet
    from pyglet.gl import gl
    from psychopy.hardware import keyboard
    import time

    kb = keyboard.Keyboard()

    # colors
    def changegun(c, d):
        new = c.astype(float)
        new[0] = new[0] + d  # R
        new[1] = new[1] - d  # G
        new[2] = new[2] - d  # B
        return new

    Crgb = ColorPicker().Crgb
    color = Crgb.astype(int)

    newcolor1 = changegun(color, 1)
    newcolor2 = changegun(color, -1)

    color1_1 = [color, color, color, newcolor1, newcolor1,
                newcolor1]  # upper in condition 1
    color1_2 = [color, color, color, newcolor2, newcolor2,
                newcolor2]  # upper in condition 2

    color2_1 = [
        changegun(color, 0.),
        changegun(color, 0.2),
        changegun(color, 0.4),
        changegun(color, 0.6),
        changegun(color, 0.8),
        changegun(color, 1.0)
    ]

    color2_2 = [
        changegun(color, 0.),
        changegun(color, -0.2),
        changegun(color, -0.4),
        changegun(color, -0.6),
        changegun(color, -0.8),
        changegun(color, -1.0)
    ]

    # convert to [0, 1]

    Crgb = Crgb / (2**8 - 1)

    rgb1_1 = [x / (2**8 - 1) for x in color1_1]  # upper in condition 1
    rgb1_2 = [x / (2**8 - 1) for x in color1_2]  # upper in condition 2

    rgb2_1 = [x / (2**8 - 1) for x in color2_1]
    rgb2_2 = [x / (2**8 - 1) for x in color2_2]

    background = (Crgb[0], Crgb[1], Crgb[2], 1)  # RGB and alpha value

    # set up context and window
    # platform = pyglet.window.get_platform()
    # display = platform.get_default_display()
    # screen = display.get_default_screen()

    # template = pyglet.gl.Config(red_size=bit, green_size=bit, blue_size=bit)
    # config = screen.get_best_config(template)
    # context = config.create_context(None)

    # config = pyglet.gl.Config(red_size=bit, green_size=bit, blue_size=bit)
    config = pyglet.gl.Config(buffer_size=bit * 3)

    winsize = 1900
    window = pyglet.window.Window(caption='OpenGL',
                                  resizable=True,
                                  config=config,
                                  fullscreen=True)

    frameN = 0
    while True:
        if frameN % 2:
            rgb1 = rgb1_1
            rgb2 = rgb2_1
            color1 = color1_1
            color2 = color2_1
        else:
            rgb1 = rgb1_2
            rgb2 = rgb2_2
            color1 = color1_2
            color2 = color2_2

        @window.event
        def on_draw():
            # clears the background with the background color
            gl.glClearColor(*background)
            gl.glClear(gl.GL_COLOR_BUFFER_BIT)

            # draw in a loop
            boundary = winsize - 100
            gap = (winsize - boundary) / 2
            i_width = boundary / len(rgb1)
            i_height = boundary / 2

            # the first line
            for idx, rgb in enumerate(rgb1):
                gl.glColor3f(*rgb)

                gl.glBegin(
                    gl.GL_QUADS
                )  # start drawing a rectangle in counter-clockwise (CCW) order

                gl.glVertex2f(gap + idx * i_width,
                              gap + i_height)  # bottom left point
                gl.glVertex2f(gap + (idx + 1) * i_width,
                              gap + i_height)  # bottom right point
                gl.glVertex2f(gap + (idx + 1) * i_width,
                              gap + boundary)  # top right point
                gl.glVertex2f(gap + idx * i_width,
                              gap + boundary)  # top left point

                gl.glEnd()

                label = pyglet.text.Label(str(color1[idx]),
                                          font_size=7,
                                          x=gap + idx * i_width,
                                          y=gap + boundary + 20)
                label.draw()

            # # # the second line
            for idx, rgb in enumerate(rgb2):
                gl.glColor3f(*rgb)

                gl.glBegin(
                    gl.GL_QUADS
                )  # start drawing a rectangle in counter-clockwise (CCW) order

                gl.glVertex2f(gap + idx * i_width, gap)  # bottom left point
                gl.glVertex2f(gap + (idx + 1) * i_width,
                              gap)  # bottom right point
                gl.glVertex2f(gap + (idx + 1) * i_width,
                              gap + i_height)  # top right point
                gl.glVertex2f(gap + idx * i_width,
                              gap + i_height)  # top left point
                gl.glEnd()

                label = pyglet.text.Label(str(color2[idx]),
                                          font_size=7,
                                          x=gap + idx * i_width,
                                          y=gap - 20)
                label.draw()

        frameN += 1
        pyglet.app.run()

        kb.clock.reset()
        if kb.getKeys():  # press any key to quit
            core.quit()
        else:
            time.sleep(1)  # change every 1 sec
示例#9
0
def test5_pyglet(bit):
    """
    Same test as test5, but using pyglet directly instead of Psychopy
    TODO: adjust the size on VIEWPixx
    """
    import pyglet
    from pyglet.gl import gl

    # colors
    def changegun(c, d):
        new = c.astype(float)
        new[0] = new[0] + d  # R
        new[1] = new[1] - d  # G
        new[2] = new[2] - d  # B
        return new

    Crgb = ColorPicker().Crgb
    color = Crgb.astype(int)

    color1 = [
        color, color, color,
        changegun(color, 1.),
        changegun(color, 1.),
        changegun(color, 1.)
    ]

    color2 = [
        color,
        changegun(color, .2),
        changegun(color, .4),
        changegun(color, .6),
        changegun(color, .8),
        changegun(color, 1.)
    ]

    # convert to [0, 1]
    Crgb = Crgb / (2**8 - 1)
    rgb1 = [x / (2**8 - 1) for x in color1]
    rgb2 = [x / (2**8 - 1) for x in color2]

    background = (Crgb[0], Crgb[1], Crgb[2], 1)  # RGB and alpha value

    # set up context and window
    # config = pyglet.gl.Config(red_size=bit, gre""" rewrite the test5 with pyglet"""en_size=bit, blue_size=bit)
    config = pyglet.gl.Config(buffer_size=bit * 4)
    winsize = 1200
    window = pyglet.window.Window(caption='OpenGL',
                                  resizable=True,
                                  config=config,
                                  fullscreen=True)

    @window.event
    def on_draw():
        # clears the background with the background color
        gl.glClearColor(*background)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        # draw in a loop
        boundary = winsize - 200
        gap = (winsize - boundary) / 2
        i_width = boundary / len(rgb1)
        i_height = boundary / 2

        # the first line
        for idx, rgb in enumerate(rgb1):
            gl.glColor3f(*rgb)

            gl.glBegin(
                gl.GL_QUADS
            )  # start drawing a rectangle in counter-clockwise (CCW) order

            gl.glVertex2f(gap + idx * i_width,
                          gap + i_height)  # bottom left point
            gl.glVertex2f(gap + (idx + 1) * i_width,
                          gap + i_height)  # bottom right point
            gl.glVertex2f(gap + (idx + 1) * i_width,
                          gap + boundary)  # top right point
            gl.glVertex2f(gap + idx * i_width,
                          gap + boundary)  # top left point

            gl.glEnd()

            label = pyglet.text.Label(str(color1[idx]),
                                      font_size=10,
                                      x=gap + idx * i_width,
                                      y=gap + boundary + 20)
            label.draw()

        # # # the second line
        for idx, rgb in enumerate(rgb2):
            gl.glColor3f(*rgb)

            gl.glBegin(
                gl.GL_QUADS
            )  # start drawing a rectangle in counter-clockwise (CCW) order

            gl.glVertex2f(gap + idx * i_width, gap)  # bottom left point
            gl.glVertex2f(gap + (idx + 1) * i_width, gap)  # bottom right point
            gl.glVertex2f(gap + (idx + 1) * i_width,
                          gap + i_height)  # top right point
            gl.glVertex2f(gap + idx * i_width,
                          gap + i_height)  # top left point
            gl.glEnd()

            label = pyglet.text.Label(str(color2[idx]),
                                      font_size=10,
                                      x=gap + idx * i_width,
                                      y=gap - 20)
            label.draw()

    pyglet.app.run()
示例#10
0
def test6(bit, diff=1):
    """
    Dynamic version of test5.

    :param bit: 8 or 10
    :param diff: difference in RGB255 scale
    :return:
    """
    from psychopy.hardware import keyboard
    import time
    # mon = monitors.Monitor(name='VIEWPixx LITE', width=38, distance=57)
    #

    color = ColorPicker().Crgb
    color = color.astype(int)

    def changegun(c, d):
        new = c.astype(float)
        new[0] = new[0] + d  # R
        new[1] = new[1] - d  # G
        new[2] = new[2] - d  # B
        return new

    newcolor1 = changegun(color, diff)
    newcolor2 = changegun(color, -diff)

    color1_1 = [color, color, color, newcolor1, newcolor1,
                newcolor1]  # upper in condition 1
    color1_2 = [color, color, color, newcolor2, newcolor2,
                newcolor2]  # upper in condition 2

    color2_1 = [
        changegun(color, 0.),
        changegun(color, 0.2),
        changegun(color, 0.4),
        changegun(color, 0.6),
        changegun(color, 0.8),
        changegun(color, 1.0)
    ]

    color2_2 = [
        changegun(color, 0.),
        changegun(color, -0.2),
        changegun(color, -0.4),
        changegun(color, -0.6),
        changegun(color, -0.8),
        changegun(color, -1.0)
    ]

    # convert to [-1, 1]
    Crgb = ColorPicker().Crgb / (2**8 - 1) * 2 - 1

    rgb1_1 = [x / (2**8 - 1) * 2 - 1 for x in color1_1]  # upper in condition 1
    rgb1_2 = [x / (2**8 - 1) * 2 - 1 for x in color1_2]  # upper in condition 2

    rgb2_1 = [x / (2**8 - 1) * 2 - 1 for x in color2_1]
    rgb2_2 = [x / (2**8 - 1) * 2 - 1 for x in color2_2]

    win = visual.Window(fullscr=True,
                        color=Crgb,
                        colorSpace='rgb',
                        bpc=(bit, bit, bit),
                        depthBits=bit,
                        units='norm')
    kb = keyboard.Keyboard()

    boundary = 0.8
    num = len(color1_1)

    colorbar1 = visual.ElementArrayStim(win,
                                        units='norm',
                                        nElements=num,
                                        elementMask=None,
                                        elementTex=None,
                                        sizes=(boundary * 2 / num,
                                               boundary / 2),
                                        colorSpace='rgb')
    colorbar2 = visual.ElementArrayStim(win,
                                        units='norm',
                                        nElements=num,
                                        elementMask=None,
                                        elementTex=None,
                                        sizes=(boundary * 2 / num,
                                               boundary / 2),
                                        colorSpace='rgb')

    colorbar1.xys = [
        (x, boundary / 4)
        for x in np.linspace(-boundary, boundary, num, endpoint=False) +
        boundary / num
    ]
    colorbar2.xys = [
        (x, -boundary / 4)
        for x in np.linspace(-boundary, boundary, num, endpoint=False) +
        boundary / num
    ]

    frameN = 0
    while True:
        if frameN % 2:
            rgb1 = rgb1_1
            rgb2 = rgb2_1
            color1 = color1_1
            color2 = color2_1
        else:
            rgb1 = rgb1_2
            rgb2 = rgb2_2
            color1 = color1_2
            color2 = color2_2

        colorbar1.colors = rgb1
        colorbar2.colors = rgb2

        colorbar1.draw()
        colorbar2.draw()

        for idx, x in enumerate(
                np.linspace(-boundary, boundary, num, endpoint=False) +
                boundary / num):
            text1 = visual.TextStim(
                win, text=str(color1[idx]), pos=(x, 0.7),
                height=0.028)  # position set in weird way but works
            text2 = visual.TextStim(win,
                                    text=str(color2[idx]),
                                    pos=(x, -0.7),
                                    height=0.028)
            text1.draw()
            text2.draw()

        win.flip()
        frameN += 1

        kb.clock.reset()
        if kb.getKeys():  # press any key to quit
            core.quit()
        else:
            time.sleep(1)  # change every 1 sec
示例#11
0
def test5(bit, diff=1):
    """
    Show static 6 x 2 colored patches:
        - 1st row with 1-bit step in RGB255
        - 2nd row with 0.2-bit step -- should be distinguishable on 10-bit

    :param bit: 8 or 10
    :param diff: difference in RGB255 scale
    :return:
    """

    color = ColorPicker().Crgb
    color = color.astype(int)

    def changegun(c, d):
        new = c.astype(float)
        new[0] = new[0] + d  # R
        new[1] = new[1] - d  # G
        new[2] = new[2] - d  # B
        return new

    newcolor = changegun(color, diff)

    color1 = [color, color, color, newcolor, newcolor, newcolor]  # upper row

    color2 = [
        changegun(color, 0.),
        changegun(color, 0.2),
        changegun(color, 0.4),
        changegun(color, 0.6),
        changegun(color, 0.8),
        changegun(color, 1.0)
    ]  # lower row

    # convert to [-1, 1]
    Crgb = ColorPicker().Crgb / (2**8 - 1) * 2 - 1
    rgb1 = [x / (2**8 - 1) * 2 - 1 for x in color1]
    rgb2 = [x / (2**8 - 1) * 2 - 1 for x in color2]

    win = visual.Window(fullscr=True,
                        color=Crgb,
                        colorSpace='rgb',
                        bpc=(bit, bit, bit),
                        depthBits=bit)

    boundary = 0.8
    num = len(color1)

    colorbar1 = visual.ElementArrayStim(win,
                                        units='norm',
                                        nElements=num,
                                        elementMask=None,
                                        elementTex=None,
                                        sizes=(boundary * 2 / num,
                                               boundary / 2),
                                        colorSpace='rgb')
    colorbar2 = visual.ElementArrayStim(win,
                                        units='norm',
                                        nElements=num,
                                        elementMask=None,
                                        elementTex=None,
                                        sizes=(boundary * 2 / num,
                                               boundary / 2),
                                        colorSpace='rgb')

    colorbar1.xys = [
        (x, boundary / 4)
        for x in np.linspace(-boundary, boundary, num, endpoint=False) +
        boundary / num
    ]
    colorbar2.xys = [
        (x, -boundary / 4)
        for x in np.linspace(-boundary, boundary, num, endpoint=False) +
        boundary / num
    ]

    colorbar1.colors = rgb1

    colorbar2.colors = rgb2
    print(colorbar2.colors)

    colorbar1.draw()
    colorbar2.draw()

    for idx, x in enumerate(
            np.linspace(-boundary, boundary, num, endpoint=False) +
            boundary / num):
        text1 = visual.TextStim(
            win, text=str(color1[idx]), pos=(x, 0.7),
            height=0.028)  # position set in weird way but works
        text2 = visual.TextStim(win,
                                text=str(color2[idx]),
                                pos=(x, -0.7),
                                height=0.028)
        text1.draw()
        text2.draw()

    win.flip()
    if event.waitKeys():
        win.close()
        return
示例#12
0
def test1(bit):
    """
    Abandoned!!!

    for test1(8), color should change every 3 steps;
    for test1(10), color should change every step
    """
    # visual.backends.getBackend(win=self,
    #                     bpc=bpc,
    #                     depthBits=depthBits,
    #                     stencilBits=stencilBits,
    #                     *args, **kwargs)

    # bpc:
    #   array_like or int Bits per color for the back buffer.
    #   Valid values depend on the output color depth of the display.
    #   By default, it is assumed the display has 8 - bits per color(8, 8, 8)
    # depthBits:
    #   int, Back buffer depth bits. Default is 8.
    # stencilBits:
    #   int Back buffer stencil bits. Default is 8.

    rlist = np.linspace(0.5, 0.6, 100,
                        endpoint=True)  # each step is 0.001 in [0, 1] scale;
    # so we expect color changes every step for 10-bit (1/1023 = 0.0009), but changes every 3 steps for 8-bit (1/255 = 0.0039)

    glist = np.linspace(0.4, 0.5, 100, endpoint=True)
    blist = np.linspace(0.8, 0.9, 100, endpoint=True)
    rgb = np.squeeze(np.dstack((rlist, glist, blist)))

    colorspace = None
    Crgb = ColorPicker().Crgb / 255

    if bit == 10:
        colorspace = 'rgb'
        rgb = rgb * 2 - 1  # converted to [-1, 1]
        Crgb = Crgb * 2 - 1
    elif bit == 8:
        colorspace = 'rgb255'
        rgb = rgb * 255  # converted to [0, 255]
        Crgb = Crgb * 255

    win = visual.Window([600, 600],
                        color=list(Crgb),
                        colorSpace=colorspace,
                        bpc=(bit, bit, bit),
                        depthBits=bit)
    text = visual.TextStim(win,
                           text=str(bit) + ' bit',
                           pos=[-0.7, 0.95],
                           height=0.03)
    text.draw()

    num = 40

    selrgb = rgb[0:num]
    boundary = 0.8

    colorbar = visual.ElementArrayStim(win,
                                       units='norm',
                                       nElements=num,
                                       elementMask=None,
                                       elementTex=None,
                                       sizes=(boundary * 2 / num, boundary),
                                       colorSpace=colorspace)
    colorbar.xys = [
        (x, 0) for x in np.linspace(-boundary, boundary, num, endpoint=False) +
        boundary / num
    ]

    colorbar.colors = selrgb

    colorbar.draw()

    win.flip()
    if event.waitKeys():
        win.close()
        return