123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- # this file contains functions used in both the localiser task and main task
- import os
- from itertools import groupby
- import csv
- import codecs
- import numpy as np
- from random import randint
- from psychopy import visual
- import PIL
- # function to make noise images green
- def greenify_noise(im):
- im_arr = np.array(im, dtype=np.uint8)
- im_arr[:, :, [0, 2]] = 127
- targ = im_arr[:, :, 1] < 127
- im_arr[:, :, 0][targ] = im_arr[:, :, 1][targ]
- im_arr[:, :, 2][targ] = im_arr[:, :, 1][targ]
- im_gr = PIL.Image.fromarray(np.uint8(im_arr))
- return(im_gr)
- # function to append a trial's data (in dictionary format) to csv
- def write_csv(fileName, thisTrial):
- full_path = os.path.abspath(fileName)
- directory = os.path.dirname(full_path)
- if not os.path.exists(directory):
- os.makedirs(directory)
- if not os.path.isfile(full_path):
- with codecs.open(full_path, 'ab+', encoding='utf8') as f:
- csv.writer(f, delimiter=',').writerow(thisTrial.keys())
- csv.writer(f, delimiter=',').writerow(thisTrial.values())
- else:
- with codecs.open(full_path, 'ab+', encoding='utf8') as f:
- csv.writer(f, delimiter=',').writerow(thisTrial.values())
- # function to get the lengths of consecutive runs (useful for limiting number of consecutive trial types)
- def get_consec_lens(x):
- return [ len(list(v)) for k, v in groupby(list(x)) ]
- # functions for precise frame-wise timing
- def ms_2_flips(ms = 100, Hz = 60, round_func = np.round):
- return int(round_func(ms / (1/Hz*1000)))
- def display_n_flips(win, stim, n_flips = 10, port = None, trigg = None):
- for frame_n in range(n_flips):
- stim.draw()
- if frame_n == 0:
- if trigg is not None:
- win.callOnFlip(port.setData, data=trigg)
- win.flip()
- def display_x_ms(win, stim, ms = 100, Hz = 60, round_func = np.round, port = None, trigg = None):
- display_n_flips(win, stim, ms_2_flips(ms, Hz, round_func), port, trigg)
- def display_jitter_ms(win, stim, min_ms = 100, max_ms = 500, Hz = 60, round_func = np.round, port = None, trigg = None):
- flips_min = ms_2_flips(min_ms, Hz, round_func)
- flips_max = ms_2_flips(max_ms, Hz, round_func)
- n_flips = randint(flips_min, flips_max)
- display_n_flips(win, stim, n_flips, port, trigg)
- return(n_flips, n_flips*(1/Hz*1000))
- def display_list_n_flips(win, stim_list, n_flips = 10, port = None, trigg = None):
- for frame_n in range(n_flips):
- for stim_i in stim_list:
- stim_i.draw()
- if frame_n == 0:
- if trigg is not None:
- win.callOnFlip(port.setData, data=trigg)
- win.flip()
- def display_list_ms(win, stim_list, ms = 100, Hz = 60, round_func = np.round, port = None, trigg = None):
- display_list_n_flips(win, stim_list, ms_2_flips(ms, Hz, round_func), port, trigg)
- def display_list_jitter_ms(win, stim_list, min_ms = 100, max_ms = 500, Hz = 60, round_func = np.round, port = None, trigg = None):
- flips_min = ms_2_flips(min_ms, Hz, round_func)
- flips_max = ms_2_flips(max_ms, Hz, round_func)
- n_flips = randint(flips_min, flips_max)
- display_list_n_flips(win, stim_list, n_flips, port, trigg)
- return(n_flips, n_flips*(1/Hz*1000))
- # function that returns a list containing the objects in the Thaler et al. fixation point
- # can then draw the list contents in a loop
- def thaler_list_fix(win, units='deg', circlesColor=[1,1,1], circlesColorSpace='rgb', outerCircleDiameter=0.6, innerCircleDiameter=0.2, pos = (0, 0)):
- crossColor=win.color.tolist()
- crossColorSpace=win.colorSpace
-
- outerCircle = visual.Circle(win, units=units, pos=pos, radius=outerCircleDiameter/2, lineColor=circlesColor, fillColor=circlesColor, fillColorSpace=circlesColorSpace, lineColorSpace=circlesColorSpace)
- crossVertical = visual.Rect(win, units=units, pos=pos, height=outerCircleDiameter*1.1, width=innerCircleDiameter/2, lineColor=None, fillColor=crossColor, fillColorSpace=crossColorSpace, lineColorSpace=crossColorSpace)
- crossHorizontal = visual.Rect(win, units=units, pos=pos, height=innerCircleDiameter/2, width=outerCircleDiameter*1.1, lineColor=None, fillColor=crossColor, fillColorSpace=crossColorSpace, lineColorSpace=crossColorSpace)
- innerCircle = visual.Circle(win, units=units, pos=pos, radius=innerCircleDiameter/2, lineColor=circlesColor, fillColor=circlesColor, fillColorSpace=circlesColorSpace, lineColorSpace=circlesColorSpace)
- return [outerCircle, crossVertical, crossHorizontal, innerCircle]
|