def genMask(size, dir): # Store coordinates of the edges of the screen. Top right, bottom right, # bottom left, top left coords = [[300, 300], [300, -300], [-300, -300], [-300, 300]] if dir == 0: # Right (0°) # Reduce the x coordinates for the right of the mask to the center + the # distance needed to cover the characters at the center of the screen coords[0][0] = 0 + ((size * 0.75) * 2) coords[1][0] = 0 + ((size * 0.75) * 2) elif dir == 1: # Down (270°) # Reduce the y coordinates for the bottom of the mask to the center - the # distance needed to cover the characters at the center of the screen coords[0][1] = 0 - ((size * 0.85) * 2) coords[3][1] = 0 - ((size * 0.85) * 2) elif dir == 2: # Left (180°) # Reduce the x coordinates for the left of the mask to the center + the # distance needed to cover the characters at the center of the screen coords[2][0] = 0 - ((size * 0.75) * 2) coords[3][0] = 0 - ((size * 0.75) * 2) elif dir == 3: # Up (90°) # Reduce the y coordinates for the top of the mask to the center + the # distance needed to cover the characters at the center of the screen coords[0][1] = 0 + ((size * 0.85) * 1.5) coords[3][1] = 0 + ((size * 0.85) * 1.5) # Convert the coords to a list of tuples verts = list(map(tuple, coords)) # Generate a grey shape with the coordinates as vertices mask = ShapeStim(win, vertices=verts, fillColor='grey', size=.5,\ lineColor='grey') # Display the mask shape mask.draw()
def ChoiceConfidenceTrial(TopImage, BottomImage, Clock, Screen, tStim, bStim, expData, presTime, waitTime): """ForcedChoiceTrial plays one trial of a forced choice paradigm given time and stimuli and returns the keypresses of the individual""" first = [(-1, -1), (-1, -1)] #set the argument images to the matching image object TopImage.setImage(tStim) BottomImage.setImage(bStim) #fixation cross fx = ShapeStim(Screen, vertices='cross', size=1, pos=(0, 0), lineColor='red', fillColor='red') expData.addData("tStim", os.path.basename(tStim)) expData.addData("bStim", os.path.basename(bStim)) #draw the fixation cross to the screen fx.draw() Screen.flip() #reset clock for counting and reaction times Clock.reset() #fixation cross wait, make consistent at 1 second for now core.wait(1, 1) #draw the stimuli to the screen's buffer TopImage.draw(Screen) BottomImage.draw(Screen) #present the stimuli simultaneously by flipping the buffer Screen.flip() #reset the clock on next cpu tick to allow for stimulus duration Clock.reset() #Wait for the given amount of time in arg 4, still listen for keypresses though core.wait(presTime, presTime) q = visual.TextStim(Screen, text="Which image was clearer? Top/Bottom?") #draw to the buffer q.draw() #flip screen back to blank. This is the response screen Screen.flip() #reset clock for counting and reaction times Clock.reset() core.wait(waitTime, waitTime) #pull the input from the participant's trial and return it #if event.getKeys(None, False, Clock) != 0: first = event.getKeys(None, False, Clock) #return pressed Keys return (first)
def FixationCue(): RectC_Cue = ShapeStim( win=expwin, units="deg", lineWidth=10, lineColor=[-1, -1, -1], fillColor=None, vertices=[[-1.25, 1.25], [-1.25, -1.25], [1.25, -1.25], [1.25, 1.25]], ) RectC_Cue.draw() CrossLineH.draw() CrossLineV.draw() RectR.draw() RectL.draw()
def Line2(): TargetLine2_1 = ShapeStim(win=expwin, units="deg", lineWidth=2, lineColor=[-1, -1, -1], vertices=Line_Shape2[0][0], closeShape=False, pos=theLoc2) TargetLine2_2 = ShapeStim(win=expwin, units="deg", lineWidth=2, lineColor=[-1, -1, -1], vertices=Line_Shape2[0][1], closeShape=False, pos=theLoc2) TargetLine2_1.draw() TargetLine2_2.draw() CenterBox() RectR.draw() RectL.draw()
def CueDisplay(): #此处暂时设定i值为0。正式实验流程再进行调整 CueRect_L = ShapeStim(win=expwin, units="deg", lineWidth=CueLine1[0], lineColor=[-1, -1, -1], fillColor=None, vertices=[[-1.25, 1.25], [-1.25, -1.25], [1.25, -1.25], [1.25, 1.25]], pos=RectL_pos) CueRect_R = ShapeStim(win=expwin, units="deg", lineWidth=CueLine2[0], lineColor=[-1, -1, -1], fillColor=None, vertices=[[-1.25, 1.25], [-1.25, -1.25], [1.25, -1.25], [1.25, 1.25]], pos=RectR_pos) CueRect_L.draw() CenterBox() CueRect_R.draw()
starLocations = [(0, 0)] elif trial['visible_card'] == 2: starLocations = [(0, 0.2), (0, -0.2)] else: # visible_card is 3 starLocations = [(0, .35), (0, 0), (0, -.35)] starVertices = [makeStar(coords, .25) for coords in starLocations] for star in starVertices: starStim = ShapeStim(w, vertices=star, fillColor='green', lineWidth=2, lineColor='white') starStim.draw() w.flip() rt = core.Clock() keys = event.waitKeys(keyList=['z', 'm'], timeStamped=rt) trialData = trial.copy() trialData['key'] = keys[0][0] trialData['rt'] = keys[0][1] trialData['response'] = 'keep' if trialData['key'] == 'z' else 'switch' trialData['reward'] = trialData['hidden_card'] if trialData[ 'response'] == 'switch' else trialData['visible_card'] lastReward = trialData['reward'] totalScore += trialData['reward'] responses.append(trialData)
(-66, 99), (-89, 93), (-76, 108), (-64, 105), (-52, 96), (-64, 116), (-53, 120), (-53, 130), (-83, 158), (-95, 163), (-102, 130), (-116, 113), (-105, 133), (-105, 166), (-96, 172), (-95, 169), (-93, 175), (-94, 181), (-94, 206), (-66, 227), (-66, 215), (-66, 202), (-67, 188), (-89, 173), (-94, 164), (-81, 158), (-67, 171), (-55, 141), (-50, 143), (-52, 161), (-50, 181), (-43, 186), (-30, 186), (-38, 197), (-26, 230)] coast = ShapeStim(win, vertices=coastVert, fillColor='darkgray', lineColor=None, size=.0007, pos=(.4, .2)) while not event.getKeys(): donut.draw() coast.draw() star7.setOri(1, '-') # rotate star7.setSize(star7.ori % 360 / 360) # shrink star7.draw() thing.setOri(-star7.ori / 7) # rotate slowly thing.draw() arrow.draw() lineA.draw() # dynamic vertices: selfxVert[0] = star7.size / 5 selfxVert[3] = star7.size / 5 * (0, .9) selfx.vertices = selfxVert # can be slow with many vertices selfx.draw() win.flip()
thing = ShapeStim(win, vertices=thingVert, fillColor='blue', lineWidth=0, opacity=.3, size=.7) # `donut` has a true hole, using two loops of vertices: donutVert = [[(-.2,-.2),(-.2,.2),(.2,.2),(.2,-.2)], [(-.15,-.15),(-.15,.15),(.15,.15),(.15,-.15)]] donut = ShapeStim(win, vertices=donutVert, fillColor='orange', lineWidth=0, size=.75, pos=(-.2,-.25)) # lines are ok; use closeShape=False lineAVert = [(0,0),(.1,.1),(.1,.2),(.1,.1),(.1,-.1),(0,.1)] lineA = ShapeStim(win, vertices=lineAVert, closeShape=False, lineWidth=2, pos=(-.4,.2), ori=180) # a complex shape, many vertices: coastVert = [(-23,230),(-3,223),(32,233),(43,230),(46,236),(34,240),(31,248),(31,267),(45,260),(52,266),(43,274),(47,279),(53,268),(65,282),(65,273),(56,266),(59,265),(53,261),(47,237),(43,230),(39,225),(43,219),(39,209),(29,206),(12,189),(9,183),(-2,183),(18,179),(-2,165),(10,169),(2,162),(29,177),(40,169),(74,170),(80,169),(86,153),(77,145),(76,132),(61,107),(61,100),(33,86),(51,91),(57,84),(27,63),(36,63),(51,70),(71,60),(87,42),(100,4),(97,-9),(125,-28),(139,-46),(138,-56),(148,-73),(118,-66),(149,-82),(157,-98),(157,-106),(151,-109),(148,-114),(154,-120),(158,-120),(159,-111),(168,-110),(188,-114),(205,-131),(203,-144),(200,-160),(188,-170),(164,-180),(179,-180),(179,-188),(157,-193),(172,-196),(165,-197),(176,-202),(193,-200),(193,-211),(181,-217),(180,-229),(172,-220),(155,-234),(139,-227),(118,-233),(99,-227),(94,-232),(91,-237),(101,-243),(106,-242),(107,-237),(103,-232),(94,-238),(90,-233),(81,-233),(81,-240),(61,-243),(50,-234),(27,-240),(21,-262),(15,-262),(15,-260),(-2,-253),(-13,-256),(-26,-264),(-26,-272),(-31,-275),(-31,-269),(-38,-267),(-41,-268),(-46,-271),(-46,-267),(-41,-262),(-28,-257),(-8,-226),(-8,-219),(1,-219),(3,-210),(25,-205),(30,-210),(35,-210),(35,-204),(29,-205),(29,-200),(15,-185),(0,-191),(0,-187),(3,-183),(-4,-180),(-24,-187),(-32,-178),(-29,-178),(-29,-174),(-35,-174),(-26,-164),(4,-149),(8,-139),(6,-118),(3,-117),(-4,-118),(-5,-122),(-16,-122),(-11,-115),(-2,-107),(-2,-100),(-11,-93),(-11,-85),(0,-84),(7,-93),(14,-88),(32,-89),(40,-96),(39,-85),(47,-90),(41,-79),(42,-55),(48,-53),(44,-41),(35,-48),(22,-21),(23,-3),(15,0),(4,-6),(-5,0),(-3,-14),(-20,-2),(-20,-16),(-31,2),(-13,36),(-18,48),(-18,65),(-21,50),(-35,65),(-25,76),(-39,64),(-37,56),(-37,44),(-28,30),(-26,37),(-32,49),(-39,45),(-39,29),(-52,25),(-47,32),(-45,50),(-45,65),(-54,57),(-61,43),(-69,43),(-73,50),(-73,57),(-72,57),(-71,57),(-68,57),(-66,57),(-64,57),(-62,57),(-62,58),(-60,58),(-59,59),(-58,59),(-58,66),(-47,76),(-46,71),(-44,80),(-44,89),(-29,120),(-48,99),(-48,91),(-59,87),(-71,87),(-63,92),(-66,99),(-89,93),(-76,108),(-64,105),(-52,96),(-64,116),(-53,120),(-53,130),(-83,158),(-95,163),(-102,130),(-116,113),(-105,133),(-105,166),(-96,172),(-95,169),(-93,175),(-94,181),(-94,206),(-66,227),(-66,215),(-66,202),(-67,188),(-89,173),(-94,164),(-81,158),(-67,171),(-55,141),(-50,143),(-52,161),(-50,181),(-43,186),(-30,186),(-38,197),(-26,230)] coast = ShapeStim(win, vertices=coastVert, fillColor='darkgray', lineColor=None, size=.0007, pos=(.4,.2)) while not event.getKeys(): donut.draw() coast.draw() star7.setOri(1,'-') # rotate star7.setSize(star7.ori % 360 / 360) # shrink star7.draw() thing.setOri(-star7.ori/7) # rotate slowly thing.draw() arrow.draw() lineA.draw() # dynamic vertices: selfxVert[0] = star7.size/5 selfxVert[3] = star7.size/5 * (0,.9) selfx.vertices = selfxVert # can be slow with many vertices selfx.draw() win.flip()
def main(fCue, fStim, fInterval, fTest, fPause, tPerBlock, stimType, targChange, trialType, cue, numTrials, blocks): fCue = fCue fStim = fStim fTest = fTest fPause = fPause tPerBlock = tPerBlock stimType = stimType targChange = targChange trialType = trialType cue = cue numTrials = numTrials # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)).decode( sys.getfilesystemencoding()) os.chdir(_thisDir) # Store info about the experiment session expName = 'Change Detection.py' expInfo = {'session': '001', 'participant': ''} dlg = gui.DlgFromDict(dictionary=expInfo, title=expName) if dlg.OK == False: core.quit() # user pressed cancel expInfo['date'] = data.getDateStr() # add a simple timestamp expInfo['expName'] = expName # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc filename = _thisDir + os.sep + u'data/%s_%s_%s' % ( expInfo['participant'], expName, expInfo['date']) # An ExperimentHandler isn't essential but helps with data saving thisExp = data.ExperimentHandler(name=expName, version='', extraInfo=expInfo, runtimeInfo=None, originPath=None, savePickle=True, saveWideText=True, dataFileName=filename) # save a log file for detail verbose info logFile = logging.LogFile(filename + '.log', level=logging.EXP) logging.console.setLevel( logging.WARNING) # this outputs to the screen, not a file endExpNow = False # flag for 'escape' or other condition => quit the exp win = visual.Window(size=[1600, 900], units='height', fullscr=True) # KEYBOARD STUFF # Start iohub process. The iohub process can be accessed using `io`. io = launchHubServer() # A `keyboard` variable is used to access the iohub Keyboard device. keyboard = io.devices.keyboard events = keyboard.getKeys() # INITIALIZE # trialN : number of trial # trialResp : their response on each trial # correctResp : if their response was correct # responseTime : the amount of time it took for them to respond on each trial m = 0 trialN = [-1 for x in range(numTrials)] trialResp = [9 for x in range(numTrials)] correctResp = [9 for x in range(numTrials)] responseTime = [0 for x in range(numTrials)] pauseTime = [0 for x in range(blocks)] respChar = [['r', 'i'], ['f', 'j']] # Which stim to display # true if rectangles, false if cubes rectangles = not stimType # STIMULI pauseText = visual.TextStim(win, text="Press the Spacebar to Continue", font=u'Arial', pos=(0, 0), height=0.1, wrapWidth=None, ori=0, color=u'white', colorSpace='rgb', opacity=1, depth=0.0) fixation = visual.Line(win, start=(-.025, 0), end=(.025, 0), lineColor='black', lineWidth=4) fixation2 = visual.Line(win, start=(0, -.025), end=(0, 0.025), lineColor='black', lineWidth=4) arrowLeft = ShapeStim(win, vertices=[(.03, .04), (-.03, .04), (-.03, .05), (-.05, .04), (-.03, .03), (-.03, .04)], lineColor='black', fillColor='black', lineWidth=3) arrowRight = ShapeStim(win, vertices=[(-.03, .04), (.03, .04), (.03, .05), (.05, .04), (.03, .03), (.03, .04)], lineColor='black', fillColor='black', lineWidth=3) for t in range(numTrials): trialTime = time.time() if (t % tPerBlock == 0) & (t > 1): event.clearEvents(eventType='keyboard') waiting = [] tStart = time.time() while not 'space' in waiting: waiting = event.getKeys(keyList=['space']) pauseText.draw() win.flip() pauseTime = time.time() - tStart thisExp.addData('pauseTime', pauseTime) trialN[t] = t + 1 # STIM PRESENTATION randTrial = random.randint(1, 100) # THIS IS 1920 X 1080 VERSION stimName = 'stimType%d_trialType%d_cue%d_order%d (%d)_resized.png' % ( stimType, trialType[t], cue[t], 0, randTrial) stimDir = '%d%d%d_resized/' % (stimType, trialType[t], cue[t]) + stimName # presents cue for frameN in range(fCue + 1): fixation.draw() fixation2.draw() if cue[t]: arrowRight.draw() else: arrowLeft.draw() win.flip() # presents stim for frameN in range(fStim + 1): stim = visual.ImageStim(win, image=stimDir) stim.draw() win.flip() # presents interval for frameN in range(fInterval + 1): fixation.draw() fixation2.draw() win.flip() # presents test array if targChange[t]: stimName = 'stimType%d_trialType%d_cue%d_order%d (%d).png' % ( stimType, trialType[t], cue[t], 1, randTrial) stimDir = '%d%d%d/' % (stimType, trialType[t], cue[t]) + stimName stim = visual.ImageStim(win, image=stimDir) startT = time.time() for frameN in range(fTest + 1): theseKeys = event.getKeys(keyList=['r', 'f', 'i', 'j']) if len(theseKeys) > 0: # at least one key was pressed trialResp[t] = theseKeys[-1] # just the last key pressed responseTime[t] = time.time() - startT stim.draw() win.flip() # presents interval for frameN in range(fPause + 1): fixation.draw() fixation2.draw() win.flip() if cue[t]: if targChange[t]: if trialResp[t] == 'i': correctResp[t] = 1 else: correctResp[t] = 0 else: if trialResp[t] == 'j': correctResp[t] = 1 else: correctResp[t] = 0 else: if targChange[t]: if trialResp[t] == 'r': correctResp[t] = 1 else: correctResp[t] = 0 else: if trialResp[t] == 'f': correctResp[t] = 1 else: correctResp[t] = 0 # OUTPUT thisExp.addData('stimType', stimType) thisExp.addData('trialType', trialType[t]) thisExp.addData('targChange', targChange[t]) thisExp.addData('cue', cue[t]) thisExp.addData('startTime', trialTime) thisExp.addData('responseTime', responseTime[t]) thisExp.addData('trialKeyPress', trialResp[t]) thisExp.addData('correctResponse', correctResp[t]) thisExp.addData('trialNumber', trialN[t]) thisExp.addData('stimulusHandle', stimName) thisExp.nextEntry() # these shouldn't be strictly necessary (should auto-save) thisExp.saveAsWideText(filename + '.csv') thisExp.saveAsPickle(filename) logging.flush() # make sure everything is closed down thisExp.abort() # or data files will save again on exit origLUT = numpy.round(win.backend._origGammaRamp * 65535.0).astype("uint16") origLUT = origLUT.byteswap() / 255.0 win.backend._origGammaRamp = origLUT win.close() core.quit()
def ChoiceConfidenceTrial(TopImage, BottomImage, flicker, Clock, Screen, tStim, bStim, expData, presTime, waitTime): """ForcedChoiceTrial plays one trial of a forced choice paradigm given time and stimuli and returns the keypresses of the individual""" first = [(-1, -1), (-1, -1)] #set the argument images to the matching image object TopImage.setImage(tStim) BottomImage.setImage(bStim) #fixation cross fx = ShapeStim(Screen, vertices='cross', size=1, pos=(0, 0), lineColor='red', fillColor='red') expData.addData("tStim", os.path.basename(tStim)) expData.addData("bStim", os.path.basename(bStim)) #draw the fixation cross to the screen fx.draw() Screen.flip() #reset clock for counting and reaction times Clock.reset() #fixation cross wait, make consistent at 1 second for now core.wait(1, 1) #draw the stimuli to the screen's buffer #4 hz flicker begin #if top image is flickered for i in range(2): xdiff = random.uniform(-.25, .25) ydiff = random.uniform(-.25, .25) if flicker == 0: BottomImage.pos = (0, -8) TopImage.pos = (0, 8) elif flicker == 1: #flicker == 1, bottom image needs to be flickered #present the stimuli simultaneously by flipping the buffer #Screen.flip() BottomImage.pos = (0 + xdiff, -8 + ydiff) elif flicker == 2: #present the stimuli simultaneously by flipping the buffer #Screen.flip() TopImage.pos = (0 + xdiff, 8 + ydiff) #reset the clock on next cpu tick to allow for stimulus duration else: #flicker == 3: #Screen.flip() TopImage.pos = (0 + xdiff, 8 + ydiff) BottomImage.pos = (0 + xdiff, -8 + ydiff) #Wait for the 1/3 given amount of time in arg 4, still listen for keypresses though TopImage.draw(Screen) BottomImage.draw(Screen) Screen.flip() Clock.reset() core.wait(presTime / 10, presTime / 10) BottomImage.pos = (0, -8) TopImage.pos = (0, 8) TopImage.draw(Screen) BottomImage.draw(Screen) Screen.flip() core.wait(2 * presTime / 3, 2 * presTime / 3) q = visual.TextStim(Screen, text="Which image was clearer? Top/Bottom?") #draw to the buffer q.draw() #flip screen back to blank. This is the response screen Screen.flip() #reset clock for counting and reaction times Clock.reset() core.wait(waitTime, waitTime) #pull the input from the participant's trial and return it #if event.getKeys(None, False, Clock) != 0: first = event.getKeys(None, False, Clock) #return pressed Keys return (first)
stim1_left = word2_left stim2_right = word1_right stim2_left = word1_left # show blank screen for 500 ms for frameN in range(int(round(params['ISI2'] * params['frameRate']))): win.update() # show fixation point for 500 ms for frameN in range(int(round(params['fp'] * params['frameRate']))): fixation.draw() win.update() # show first word for 300 ms for frameN in range(int(round(params['duration'] * params['frameRate']))): stim1_right.draw() stim1_left.draw() square1.draw() square2.draw() line.draw() win.update() # show mask for 200 ms for frameN in range(int(round(params['ISI1'] * params['frameRate']))): mask.draw() win.update() # show mask + cue for 200 ms for frameN in range(int(round(params['ISI1'] * params['frameRate']))): mask.draw() cue.draw() win.update() # show second word thisResponse = None clockRT.reset()
class MDTO(object): def __init__(self, logfile, imgDir, screenType, expVariant, trialDuration, ISI, trialsPer, selfPaced, practiceTrials, inputButtons, pauseButton): self.logfile = logfile self.expVariant = expVariant self.trialDuration = trialDuration self.selfPaced = selfPaced self.ISI = ISI self.trialsPer = trialsPer self.imgDir = imgDir self.leftOvers = [] self.splitLures = self.SplitLures() self.splitSingles = self.SplitSingles() self.runPracticeTrials = practiceTrials self.leftButton = inputButtons[0] self.rightButton = inputButtons[1] self.pauseButton = pauseButton if (screenType == 'Windowed'): screenSelect = False elif (screenType == 'Fullscreen'): screenSelect = True self.window = Window(fullscr=screenSelect, units='pix', color='White', allowGUI=False) self.imageWidth = self.window.size[1] / 3 #Define the black box that appears in the lower left, to signal EEG rW = 110 #Width rH = 60 #Height rectVertices = [[rW, -rH], [-rW, -rH], [-rW, rH], [rW, rH]] rectCenter = [(-self.window.size[0] / 2 + rW), (-self.window.size[1] / 2) + rH] self.blackBox = ShapeStim(self.window, fillColor='black', units='pix', fillColorSpace='rgb', vertices=rectVertices, closeShape=True, interpolate=True, pos=rectCenter) self.rangeITI = numpy.arange(1, 1.4, .001) self.clock = Clock() #Initialize scorelist for 4 categories|| [correct,incorrect,response] self.scoreList = [] for i in range(0, 4): self.scoreList.append([0, 0, 0]) def GrabFileType(self, fileList, exts): """Takes an inputted list, as well as extension, and returns a list with the elements in the original list that have the desired extension. fileList: The list of files to search through ext: string containing the extension type, e.g. ".jpg", ".png" return: a new list, containing files only of ext type """ fileListofType = [] for aFile in fileList: for ext in exts: ftLen = len(ext) if (aFile[-ftLen:] == ext): fileListofType.append(aFile) break return fileListofType def SplitLures(self): """Creates and returns a list of image lures. Lures are taken from both the lure high and lure low directory, and an equal amount of each are put into the list. Each element in the returned list has 2 elements: [imgA,imgB] and a number, pertaining to the difficulty of the lure, i.e. the degree of apparent difference between the two images. Return: a list, each element being: [[imgA,imgB], lureNum] """ dirFiles = os.listdir(self.imgDir) imgTypes = ['.jpg', '.jpeg', '.JPG'] allImgs = self.GrabFileType(dirFiles, imgTypes) allImgs = [img for img in allImgs if "PR" not in img] lureLowImgs = [] lureHighImgs = [] for img in allImgs: if (img[5] == "1"): lureHighImgs.append(img) elif (img[5] == "2"): lureLowImgs.append(img) #Sort images by name lureHighImgs.sort() lureLowImgs.sort() #Return a list of lures as a list w/: [[imgA,imgB],lureType] def LureListGroup(imgList): lureList = [] for i in range(0, int(len(imgList) / 2)): imgA = imgList[i * 2] imgB = imgList[(i * 2) + 1] highSet = [imgA, imgB] lureList.append(highSet) return lureList #Create list of lures with embedded structure, then shuffle lureHighList = LureListGroup(lureHighImgs) lureLowList = LureListGroup(lureLowImgs) random.shuffle(lureHighList) random.shuffle(lureLowList) #Put number (num of trials) of list items from both lists into list selectedList = [] for i in range(0, self.trialsPer): selectedList.append(lureHighList[i]) selectedList.append(lureLowList[i]) #Unused "leftover" A images will be used as singles #Probably want to use other method while seeded rand unimplemented #OK for now for i in range(self.trialsPer + 1, len(lureHighList)): try: self.leftOvers.append(lureHighList[i][0]) except IndexError: pass try: self.leftOvers.append(lureLowList[i][0]) except IndexError: pass random.shuffle(selectedList) return selectedList def SplitSingles(self): """Creates and returns a list of image "singles". Each item in the list is an image, followed by either "sF" (single Foil) or "sR" (single repeat), indicating if it is to be shown once or twice. return: list composed of [imageFileName, type] type: "sR" or "sF" """ singles = self.leftOvers targetsFoils = [] for i in range(0, self.trialsPer * 2): if (i % 2 == 0): targetsFoils.append([singles[i], "sR"]) else: targetsFoils.append([singles[i], "sF"]) random.shuffle(targetsFoils) return targetsFoils def Pause(self): """Pauses the task, and displays a message waiting for a spacebar input from the user before continuing to proceed. """ pauseMsg = "Experiment Paused\n\nPress '{}' to continue".format( self.pauseButton) pauseText = TextStim(self.window, text=pauseMsg, color='Black', height=40) pauseText.draw(self.window) self.window.flip() waitKeys(keyList=[self.pauseButton]) clearEvents() def ScaleImage(self, image, maxSize=350): """Scales the size of the image to fit as largely as it can within the window of the defined maxSize, while preserving its aspect ratio. image: the filename of the image to be scaled maxSize: maximum size, in pixels of image return: maximum scaling of image """ im = Image.open(image) larger = im.size[0] if (im.size[0] < im.size[1]): larger = im.size[1] scale = larger / maxSize scaledSize = (im.size[0] / scale, im.size[1] / scale) return scaledSize def RunTrialECog(self, image, phase): """Runs a particular trial for an ECog (Electrocorticography) based task. An ECog trial runs as follows: display the image along with the black box for <trial duration> amount of time, clear the screen for <ISI> amount of time, then asking for and getting subject input for <ITI> amount of time. image: the stimuli to display on screen phase: 0 (Study Phase) - prompts user "Indoor / Outdoor" 1 (Test Phase) - prompts user "Old / New" return: [keyPress, reactionTime] """ theImage = ImageStim(self.window) #Set the full path of the image, based on the image's lure type if (image[0][5] == "3"): image = (self.imgSnglDir + '%s' % (image[0])) elif ((image[0][5] == "1") or (image[0][5] == "2")): image = (self.lureHighDir + '%s' % (image[0])) elif ((image[0][5] == "4") or (image[0][5] == "5")): image = (self.lureLowDir + '%s' % (image[0])) theImage.setImage(image) imageSize = self.ScaleImage(image, self.imageWidth) theImage.setSize(imageSize) ecogISI = 0.5 posLeftText = (-(self.window.size[0] / 8), 0) posRightText = ((self.window.size[0] / 8), 0) if (phase == 0): ecogTrialDur = 2.0 leftMsg = "Indoor\n\n 1" rightMsg = "Outdoor\n\n 2" else: ecogTrialDur = 1.0 leftMsg = "Old\n\n 1" rightMsg = "New\n\n 2" theImage.draw(self.window) self.blackBox.draw(self.window) self.window.flip() wait(ecogTrialDur, ecogTrialDur) self.window.flip() wait(ecogISI, ecogISI) textLeft = TextStim(self.window, text=leftMsg, pos=posLeftText, color='Black', height=50) textRight = TextStim(self.window, text=rightMsg, pos=posRightText, color='Black', height=50) textLeft.draw(self.window) textRight.draw(self.window) self.window.flip() clearEvents() self.clock.reset() keyPresses = waitKeys(keyList=['1', '2', 'space', 'escape'], timeStamped=self.clock, maxWait=1.5) self.window.flip() random.shuffle(self.rangeITI) wait(self.rangeITI[0], self.rangeITI[0]) if (not keyPresses): return '', 0 return keyPresses[0][0], keyPresses[0][1] def RunTrial(self, image): """Runs a particular trial, which includes displaying the image to the screen, and gathering the keypresses and their respective response times. image: the image (filename) to display returns: [keyPress, reaction time] """ theImage = ImageStim(self.window) imagePath = os.path.normpath(self.imgDir + "/%s" % (image)) theImage.setImage(imagePath) imageSize = self.ScaleImage(imagePath, self.imageWidth) theImage.setSize(imageSize) theImage.draw(self.window) self.window.flip() clearEvents() self.clock.reset() keyPresses = [] if (self.selfPaced == False): wait(self.trialDuration, self.trialDuration) keyPresses = getKeys(keyList=[ self.leftButton, self.rightButton, self.pauseButton, 'escape' ], timeStamped=self.clock) elif (self.selfPaced == True): keyPresses = waitKeys(keyList=[ self.leftButton, self.rightButton, self.pauseButton, 'escape' ], timeStamped=self.clock) self.window.flip() wait(self.ISI) if (not keyPresses): return '', 0 return keyPresses[0][0], keyPresses[0][1] def RunStudy(self): """Runs the first part of the MDT-O experiment, or the Study phase. In this phase, all target versions of the image pairs are shown, as well as half of the "singles" images. Keypresses and their repsective reaction times are recorded during this period, and no "right or wrong" answers are graded. """ ecog = False if self.expVariant != "ECog" else True studyPromptN = ( "Let's do the real test. \n\n Are the following objects indoor or outdoor? \n\n Press 'p' to continue" ) ''' studyPromptE = ("In the following phase, a sequence of images will be " "shown.\n\n-Press '1' if the image is of an indoor " "object.\n\n-Press '2' if the image is of an outdoor " "object.\n\n\nPress space to begin" ) ''' studyText = TextStim(self.window, studyPromptN, color='Black') if ecog: studyText = TextStim(self.window, studyPromptE, color='Black') studyText.draw(self.window) self.window.flip() continueKey = waitKeys(keyList=[self.pauseButton, 'escape']) if (continueKey[0] == 'escape'): self.logfile.write("\n\n\nStudy Not Run\n\n") return 0 self.logfile.write("\nBegin Study\n\n") logStudyFormat = '{:<7}{:<12s} {:<10s} {:<10s} {:<4s}\n'.format( 'Trial', 'Image', 'ImageType', 'Response', 'RT') self.logfile.write(logStudyFormat) #Create list for study: "A" pairs (targets), and repeat singles studyImgList = [] for pair in self.splitLures: studyImgList.append([pair[0], pair[0][5]]) for img in self.splitSingles: if (img[1] == "sR"): studyImgList.append(img) #Shuffle study list random.shuffle(studyImgList) #Run trial for each study image for i in range(0, len(studyImgList)): if not ecog: (response, RT) = self.RunTrial(studyImgList[i][0]) else: (response, RT) = self.RunTrialECog(studyImgList[i][0], 0) if (response == "escape"): self.logfile.write("\n\nStudy terminated early\n\n") return 0 elif (response == self.pauseButton): self.Pause() trialFormat = '{:<7}{:<17s}{:<10s}{:<6s}{:<4.3f}\n'.format( i + 1, studyImgList[i][0], studyImgList[i][1], response, RT) self.logfile.write(trialFormat) return 1 def RunTest(self): """Runs the second part of the MDT-O experiment, or the Test phase. In this phase, high and low "lures" are shown, as well as all of the "singles" shown in the study phase, as well as entirely new images known as "foils". All keypresses and their respective reaction times are recorded during this period. Additionally, a tally is kept of whether the subjects answer was wrong or right, with a separate score for "pair" answers. """ ecog = False if self.expVariant != "ECog" else True testPromptN = ( "In this phase, another sequence of images will be shown" "\n\nAre the objects old or new?\n\n Press 'p' to continue.") '''testPromptE = ("In this phase, another sequence of images will be shown." "\n\n-Press '1' if the image presented was also shown " "in the previous phase. (Old Image)\n\n-Press '2' if the" "image presented was not shown in the previous phase." " (New Image)\n\n\nPress space to begin" ) ''' testText = TextStim(self.window, text=testPromptN, color='Black') if ecog: testText = TextStim(self.window, text=testPromptE, color='Black') testText.draw(self.window) self.window.flip() continueKey = waitKeys(keyList=[self.pauseButton, 'escape']) if (continueKey[0] == 'escape'): self.logfile.write("\n\n\nTest Not Run\n\n") return 0 self.logfile.write("\nBegin Test\n\n") logTestFormat = '{:<7}{:<12}{:<11}{:<9}{:<10}{:<4}\n'.format( 'Trial', 'Image', 'ImageType', 'CorResp', 'Response', 'RT') self.logfile.write(logTestFormat) #Create trial list for test: B and C lures, and all singles testImgList = [] for pair in self.splitLures: testImgList.append([pair[1], pair[1][5]]) for img in self.splitSingles: testImgList.append(img) #Shuffle trial list random.shuffle(testImgList) #Run trial for each image in list, get responses for i in range(0, len(testImgList)): correct = self.rightButton trialType = testImgList[i][1] if (trialType == "sR"): correct = self.leftButton if not ecog: (response, RT) = self.RunTrial(testImgList[i][0]) else: (response, RT) = self.RunTrialECog(testImgList[i][0], 1) if (response == "escape"): self.logfile.write("\n\nTest terminated early\n\n") break elif (response == self.pauseButton): self.Pause() trialFormat = '{:<7}{:<15}{:<11}{:<9}{:<6}{:<4.3f}\n'.format( i + 1, testImgList[i][0], testImgList[i][1], correct, response, RT) self.logfile.write(trialFormat) #Tally scores of correct/responses if (response): if (trialType == "sR"): self.scoreList[0][2] += 1 if (response == correct): self.scoreList[0][0] += 1 else: self.scoreList[0][1] += 1 elif (trialType == "1"): self.scoreList[1][2] += 1 if (response == correct): self.scoreList[1][0] += 1 else: self.scoreList[1][1] += 1 elif (trialType == "2"): self.scoreList[2][2] += 1 if (response == correct): self.scoreList[2][0] += 1 else: self.scoreList[2][1] += 1 elif (trialType == "sF"): self.scoreList[3][2] += 1 if (response == correct): self.scoreList[3][0] += 1 else: self.scoreList[3][1] += 1 return 1 def ShowPromptAndWaitForSpace(self, prompt, keylist=['p', 'escape']): ''' Show the prompt on the screen and wait for space, or the keylist specified returns the key pressed ''' keylist = [self.pauseButton, 'escape'] text = TextStim(self.window, prompt, color='Black') text.draw(self.window) self.window.flip() continueKey = waitKeys(keyList=keylist) if len(continueKey) != 0 and continueKey[0] == 'escape': self.logfile.write("Terminated early.") self.logfile.close() sys.exit() return continueKey def RunSinglePractice(self, practiceBlock, images): ''' Read in the images we want, and run the practice block for this subject Run encoding and test, and write to the logs Return: float: ratio correct ''' imgPairs = [] for i in range(0, len(images) - 1, 2): if "foil" in images[i]: t = "sF" elif "target" in images[i]: t = "sR" elif "high" in images[i]: t = "2" elif "low" in images[i]: t = "1" imgPairs.append([images[i], images[i + 1], t]) ### Encoding self.ShowPromptAndWaitForSpace( " Outdoor or Indoor? ('{}' to continue)".format(self.pauseButton)) random.shuffle(imgPairs) self.logfile.write( "\nBegin Practice Encoding {}\n\n".format(practiceBlock)) logPracticeFormat = '{:<7}{:<17}{:<11}{:<9}{:<10}{:<4}\n'.format( 'Trial', 'Image', 'ImageType', 'CorResp', 'Response', 'RT') self.logfile.write(logPracticeFormat) # Run the trial for each encoding trial for i, trial in enumerate(imgPairs): imgA, imgB, trialType = trial if trialType != 'sF': response, RT = self.RunTrial(imgA) if (response == 'escape'): self.logfile.write( "\n\nPractice block terminated early\n\n") self.logfile.close() sys.exit() elif (response == self.pauseButton): self.Pause() trialFormat = '{:<7}{:<17}{:<11}{:<9}{:<6}{:<4.3f}\n'.format( i + 1, imgA, trialType, '', response, RT) self.logfile.write(trialFormat) ### Test self.ShowPromptAndWaitForSpace( " Old or new? ('{}' to continue)".format(self.pauseButton)) random.shuffle(imgPairs) self.logfile.write( "\nBegin Practice Test {}\n\n".format(practiceBlock)) self.logfile.write(logPracticeFormat) # Keep track of the total number they got correct totalCorrect = 0 for i, trial in enumerate(imgPairs): imgA, imgB, trialType = trial if trialType == 'sR' or trialType == 'sF': response, RT = self.RunTrial(imgA) else: response, RT = self.RunTrial(imgB) correct = self.leftButton if trialType == 'sR' else self.rightButton if response == correct: totalCorrect += 1 if (response == "escape"): self.logfile.write("\n\nPractice terminated early\n\n") return -1 elif (response == self.pauseButton): self.Pause() trialFormat = '{:<7}{:<17}{:<11}{:<9}{:<6}{:<4.3f}\n'.format( i + 1, imgA, trialType, correct, response, RT) self.logfile.write(trialFormat) # Return the percentage correct return totalCorrect / len(imgPairs) def RunPractice(self): ''' Runs three rounds of practice trials. If the participant gets a certain amount correct, they move on to the real test. ''' dirFiles = os.listdir(self.imgDir) practiceImages = [img for img in dirFiles if "PR" in img] # Run each practice session for i in range(3): practicePrompt = "Let's practice. ('{}' to continue)".format( self.pauseButton) self.ShowPromptAndWaitForSpace(practicePrompt) imagesThisPracticeSession = sorted([ img for img in practiceImages if "Set_{}".format(i + 1) in img ]) results = self.RunSinglePractice(i + 1, imagesThisPracticeSession) # If they get a certain percentage correct, then stop the practice self.ShowPromptAndWaitForSpace( "You got {}% correct! ('{}' to continue)".format( int(results * 100), self.pauseButton)) if results > .6: return def RunExp(self): """Run through an instance of the task, which includes the study and test phases. Also prints the exit message at the end, and closes the logfile if scores are not being written to it. return: (logfile, scorelist) if the test was run through. Assuming this happens, scores will be written to the logfile return: (-1,-1) if the task was quit prior to the completion of the study phase, meaning scores will not be writtent to the logfile """ #Print task ending message to the screen, and wait escape to be prssed def EndExp(): exitPrompt = ("This concludes the session. Thank you for " "participating!\n\nPress Esc to quit") exitText = TextStim(self.window, exitPrompt, color='Black') exitText.draw(self.window) self.window.flip() waitKeys(keyList=['escape']) self.window.close() # Show main welcome window welcomePrompt = "Thank you for participating in our study! Press '{}' to begin".format( self.pauseButton) self.ShowPromptAndWaitForSpace(welcomePrompt) # If run practice trials, then RunPractice if self.runPracticeTrials: self.RunPractice() #Run study, terminate if user exits early studyFinished = self.RunStudy() testFinished = self.RunTest() if (not studyFinished): EndExp() self.logfile.close() return (-1, -1) EndExp() return (self.logfile, self.scoreList)
def ChoiceConfidenceTrial(TopImage, BottomImage, flicker, Clock, Screen, tStim, bStim, expData, presTime, waitTime): """ForcedChoiceTrial plays one trial of a forced choice paradigm given time and stimuli and returns the keypresses of the individual""" first = ('NaN', 'NaN') #set the argument images to the matching image object TopImage.setImage(tStim) BottomImage.setImage(bStim) #fixation cross fx = ShapeStim(Screen, vertices= 'cross', size = 1, pos=(0, 0), lineColor = 'red', fillColor = 'red') expData.addData("tStim", os.path.basename(tStim)) expData.addData("bStim", os.path.basename(bStim)) #draw the fixation cross to the screen fx.draw() Screen.flip() #reset clock for counting and reaction times Clock.reset() #fixation cross wait, make consistent at 1 second for now core.wait(1, 1) #draw the stimuli to the screen's buffer #4 hz jitter begin #if top image is flickered for i in range(2): xdiff = random.uniform(-.25, .25) ydiff = random.uniform(-.25, .25) x1diff = random.uniform(-.25, .25) y1diff = random.uniform(-.25, .25) if flicker == 0: BottomImage.pos = (0, -8) TopImage.pos = (0, 8) elif flicker == 1: #flicker == 1, bottom image needs to be flickered #present the stimuli simultaneously by flipping the buffer #Screen.flip() BottomImage.pos = (0+xdiff, -8+ydiff) elif flicker == 2: #present the stimuli simultaneously by flipping the buffer #Screen.flip() TopImage.pos = (0+xdiff, 8+ydiff) #reset the clock on next cpu tick to allow for stimulus duration else: #flicker == 3: #Screen.flip() TopImage.pos = (0+x1diff, 8+y1diff) BottomImage.pos = (0+xdiff, -8+ydiff) #Wait for the 1/3 given amount of time in arg 4, still listen for keypresses though TopImage.draw(Screen) BottomImage.draw(Screen) Screen.flip() Clock.reset() core.wait(presTime/10, presTime/10) BottomImage.pos = (0, -8) TopImage.pos = (0, 8) TopImage.draw(Screen) BottomImage.draw(Screen) Screen.flip() core.wait(2*presTime/3, 2*presTime/3) q = visual.TextStim(Screen, text="Which image was clearer? Top/Bottom?") confScale = visual.RatingScale(Screen, choices=None, low=0, high=6, labels=("Top, Confident", "Top, Unsure", "Don't know", "Bottom, Unsure", "Bottom, Confident"), mouseOnly=True, showValue=True, acceptText='Ok', acceptKeys='return', scale=None) #draw to the buffer q.draw() confScale.draw() #flip screen back to blank. This is the response screen Screen.flip() #reset clock for counting and reaction times Clock.reset() core.wait(waitTime, waitTime) first = (confScale.getRating(), confScale.getRT()) #return pressed Keys return(first)
elif trial['visible_card'] == 3: starLocations = [(.12, .45), (0, .05), (-.12, -.35)] else: # visible_card is 4 starLocations = [(.12, .45), (-.12, .45), (-.12, -.35), (.12, -.35)] starVertices = [makeStar(coords, .25) for coords in starLocations] for star in starVertices: starStim = ShapeStim(w, vertices=star, fillColor='green', lineWidth=2, lineColor='white') starStim.draw() w.flip() rt = core.Clock() keys = event.waitKeys(keyList=['z', 'm'], timeStamped=rt) trialData = trial.copy() trialData['key'] = keys[0][0] trialData['rt'] = keys[0][1] trialData['response'] = 'keep' if trialData['key'] == 'z' else 'switch' trialData['reward'] = trialData['hidden_card'] if trialData[ 'response'] == 'switch' else trialData['visible_card'] lastReward = trialData['reward'] totalScore += trialData['reward'] responses.append(trialData)
vertices=SquareVert, fillColor=colour, lineWidth=0, size=5, pos=(0, 0)) # show fixation point for one second for frameN in range(int(round(params['fp'] * params['frameRate']))): fixation.draw() win.update() # show square thisResponse = None while thisResponse == None: clockRT.reset() square.draw() win.update() # collect response allKeys = event.waitKeys(timeStamped=clockRT) for keyTuple in allKeys: [thisKey, thisRT] = keyTuple for thisKey in allKeys: if thisKey[0] in ['escape']: core.quit() elif thisKey[0] in ['1', '2', '3', '4']: if int(thisKey[0]) == int(trials.thisTrial['color']): thisResponse = 1 accuracy = 1 corSnd.play() else:
right_market = np.random.randint(10, 50, 15) ######################################################################################## # A Trial: ######################################################################################## for i in range(15): # Number of trials if i == 0: intro_text.draw() # intro text win.flip() keypressed = event.waitKeys(timeStamped=False) win.flip() core.wait(0.5) trial = True while trial == True: # while loop to show static market performance grid your_fund.draw() # Neutral left market screen n_fund.draw() # Neutral right market screen y_f.draw() n_f.draw() left_market_numi = left_market[ i] # Identify what number to show for your market left_market_num = visual.TextStim(win, text=left_market_numi, pos=(-14, 7), height=textsize, wrapWidth=40, alignHoriz='center') left_market_num.draw() # Show your market number right_market_numi = right_market[ i] # Identify what number to show neighbour market right_market_num = visual.TextStim(win,
arrow3.setOri(0) arrow4.setOri(0) arrow5.setOri(0) # blank screen for 50 ms for frameN in range(int(round(params['ISI'] * params['frameRate']))): win.update() thisResponse = None while thisResponse == None: # stimulus # for frameN in range(int(round(params['duration']*params['frameRate']))): clockRT.reset() target.draw() arrow2.draw() arrow3.draw() arrow4.draw() arrow5.draw() win.update() # start collecting response allKeys = event.waitKeys(keyList=['escape', '1', '2'], timeStamped=clockRT) for keyTuple in allKeys: [thisKey, thisRT] = keyTuple for thisKey in allKeys: if thisKey[0] in ['escape']: core.quit() elif thisKey[0] in ['1', '2']: if int(thisKey[0]) == corresp:
# show instructions instructionsStim.draw() win.flip() # wait for any key waitKeys(maxWait=float('inf'), keyList=None, timeStamped=True) # 64 trials, randomly selected that are valid # 12 trials that are not valid validData = [] invalidData = [] shuffle(trialsPossible) for trial in trialsPossible: # show initial screen fixStim.draw() leftboxStim.draw() rightboxStim.draw() win.flip() wait(FIXATION_TIME) # show the cue fixStim.draw() leftboxStim.draw() rightboxStim.draw() shuffle(cues) currentCue = cues[0] if currentCue == 'cueleft': cueleftStim.draw()
# check for quit (typically the Esc key) if kb.getKeys(keyList=["escape"]): thisResp = 0 rt = 0 print("Saving data.") dataFile.write( '%i,%i,%i,%.3f,%i,%.3f\n' % (this_ori, this_spf, this_tf, this_max_contrast, thisResp, rt)) staircase.saveAsPickle( fileName) # special python data file to save all the info print("Exiting program.") core.quit() # clear screen get response donut.draw() win.flip() start_resp_time = clock.getTime() while thisResp is None: allKeys = event.waitKeys() rt = clock.getTime() - start_resp_time for thisKey in allKeys: if ((thisKey == 'left' and this_ori == 90) or (thisKey == 'up' and this_ori == 0)): thisResp = 1 # correct elif ((thisKey == 'left' and this_ori == 0) or (thisKey == 'up' and this_ori == 90)): thisResp = 0 # incorrect elif thisKey in ['q', 'escape']: test = False