diff --git a/three-back.psyexp b/three-back.psyexp new file mode 100644 index 0000000000000000000000000000000000000000..64a6a3c375e6b27d4212784a2a9ab663b645808d --- /dev/null +++ b/three-back.psyexp @@ -0,0 +1,77 @@ +<?xml version="1.0" ?> +<PsychoPy2experiment encoding="utf-8" version="3.2.0"> + <Settings> + <Param name="Audio latency priority" updates="None" val="use prefs" valType="str"/> + <Param name="Audio lib" updates="None" val="use prefs" valType="str"/> + <Param name="Completed URL" updates="None" val="" valType="str"/> + <Param name="Data filename" updates="None" val="u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])" valType="code"/> + <Param name="Enable Escape" updates="None" val="True" valType="bool"/> + <Param name="Experiment info" updates="None" val="{'participant': '', 'session': '001'}" valType="code"/> + <Param name="Force stereo" updates="None" val="True" valType="bool"/> + <Param name="Full-screen window" updates="None" val="False" valType="bool"/> + <Param name="HTML path" updates="None" val="html" valType="str"/> + <Param name="Incomplete URL" updates="None" val="" valType="str"/> + <Param name="JS libs" updates="None" val="packaged" valType="str"/> + <Param name="Monitor" updates="None" val="Alienware Laptop Monitor" valType="str"/> + <Param name="Save csv file" updates="None" val="False" valType="bool"/> + <Param name="Save excel file" updates="None" val="False" valType="bool"/> + <Param name="Save log file" updates="None" val="True" valType="bool"/> + <Param name="Save psydat file" updates="None" val="True" valType="bool"/> + <Param name="Save wide csv file" updates="None" val="True" valType="bool"/> + <Param name="Screen" updates="None" val="1" valType="num"/> + <Param name="Show info dlg" updates="None" val="True" valType="bool"/> + <Param name="Show mouse" updates="None" val="False" valType="bool"/> + <Param name="Units" updates="None" val="deg" valType="str"/> + <Param name="Use version" updates="None" val="" valType="str"/> + <Param name="Window size (pixels)" updates="None" val="[1600, 900]" valType="code"/> + <Param name="blendMode" updates="None" val="avg" valType="str"/> + <Param name="color" updates="None" val="$[-1,-1,-1]" valType="str"/> + <Param name="colorSpace" updates="None" val="rgb" valType="str"/> + <Param name="expName" updates="None" val="three-back" valType="str"/> + <Param name="exportHTML" updates="None" val="on Sync" valType="str"/> + <Param name="logging level" updates="None" val="exp" valType="code"/> + </Settings> + <Routines> + <Routine name="trial"> + <TextComponent name="letter"> + <Param name="color" updates="constant" val="white" valType="str"/> + <Param name="colorSpace" updates="constant" val="rgb" valType="str"/> + <Param name="disabled" updates="None" val="False" valType="bool"/> + <Param name="durationEstim" updates="None" val="" valType="code"/> + <Param name="flip" updates="constant" val="" valType="str"/> + <Param name="font" updates="constant" val="Arial" valType="str"/> + <Param name="languageStyle" updates="None" val="LTR" valType="str"/> + <Param name="letterHeight" updates="constant" val="2.5" valType="code"/> + <Param name="name" updates="None" val="letter" valType="code"/> + <Param name="opacity" updates="constant" val="1" valType="code"/> + <Param name="ori" updates="constant" val="0" valType="code"/> + <Param name="pos" updates="constant" val="(0, 0)" valType="code"/> + <Param name="saveStartStop" updates="None" val="True" valType="bool"/> + <Param name="startEstim" updates="None" val="" valType="code"/> + <Param name="startType" updates="None" val="time (s)" valType="str"/> + <Param name="startVal" updates="None" val="2" valType="code"/> + <Param name="stopType" updates="None" val="duration (s)" valType="str"/> + <Param name="stopVal" updates="constant" val="0.03" valType="code"/> + <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/> + <Param name="text" updates="set every repeat" val="a" valType="str"/> + <Param name="units" updates="None" val="from exp settings" valType="str"/> + <Param name="wrapWidth" updates="constant" val="" valType="code"/> + </TextComponent> + </Routine> + </Routines> + <Flow> + <LoopInitiator loopType="TrialHandler" name="trials"> + <Param name="Selected rows" updates="None" val="" valType="str"/> + <Param name="conditions" updates="None" val="None" valType="str"/> + <Param name="conditionsFile" updates="None" val="" valType="str"/> + <Param name="endPoints" updates="None" val="[0, 1]" valType="num"/> + <Param name="isTrials" updates="None" val="True" valType="bool"/> + <Param name="loopType" updates="None" val="random" valType="str"/> + <Param name="nReps" updates="None" val="20" valType="code"/> + <Param name="name" updates="None" val="trials" valType="code"/> + <Param name="random seed" updates="None" val="" valType="code"/> + </LoopInitiator> + <Routine name="trial"/> + <LoopTerminator name="trials"/> + </Flow> +</PsychoPy2experiment> diff --git a/three-back_lastrun.py b/three-back_lastrun.py new file mode 100644 index 0000000000000000000000000000000000000000..ac5c32cd2a4eece8ccd02be3ddc358eec2e22f5d --- /dev/null +++ b/three-back_lastrun.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +This experiment was created using PsychoPy3 Experiment Builder (v3.2.0), + on November 04, 2019, at 11:23 +If you publish work using this script the most relevant publication is: + + Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019) + PsychoPy2: Experiments in behavior made easy Behav Res 51: 195. + https://doi.org/10.3758/s13428-018-01193-y + +""" + +from __future__ import absolute_import, division + +from psychopy import locale_setup +from psychopy import prefs +from psychopy import sound, gui, visual, core, data, event, logging, clock +from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED, + STOPPED, FINISHED, PRESSED, RELEASED, FOREVER) + +import numpy as np # whole numpy lib is available, prepend 'np.' +from numpy import (sin, cos, tan, log, log10, pi, average, + sqrt, std, deg2rad, rad2deg, linspace, asarray) +from numpy.random import random, randint, normal, shuffle +import os # handy system and path functions +import sys # to get file system encoding + +from psychopy.hardware import keyboard + +# Ensure that relative paths start from the same directory as this script +_thisDir = os.path.dirname(os.path.abspath(__file__)) +os.chdir(_thisDir) + +# Store info about the experiment session +psychopyVersion = '3.2.0' +expName = 'three-back' # from the Builder filename that created this script +expInfo = {'participant': '', 'session': '001'} +dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName) +if dlg.OK == False: + core.quit() # user pressed cancel +expInfo['date'] = data.getDateStr() # add a simple timestamp +expInfo['expName'] = expName +expInfo['psychopyVersion'] = psychopyVersion + +# 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='D:\\Projects\\three-back\\three-back_lastrun.py', + 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 +frameTolerance = 0.001 # how close to onset before 'same' frame + +# Start Code - component code to be run before the window creation + +# Setup the Window +win = visual.Window( + size=[1600, 900], fullscr=False, screen=0, + winType='pyglet', allowGUI=True, allowStencil=False, + monitor='Alienware Laptop Monitor', color=[-1,-1,-1], colorSpace='rgb', + blendMode='avg', useFBO=True, + units='deg') +# store frame rate of monitor if we can measure it +expInfo['frameRate'] = win.getActualFrameRate() +if expInfo['frameRate'] != None: + frameDur = 1.0 / round(expInfo['frameRate']) +else: + frameDur = 1.0 / 60.0 # could not measure, so guess + +# create a default keyboard (e.g. to check for escape) +defaultKeyboard = keyboard.Keyboard() + +# Initialize components for Routine "trial" +trialClock = core.Clock() +letter = visual.TextStim(win=win, name='letter', + text='default text', + font='Arial', + pos=(0, 0), height=2.5, wrapWidth=None, ori=0, + color='white', colorSpace='rgb', opacity=1, + languageStyle='LTR', + depth=0.0); + +# Create some handy timers +globalClock = core.Clock() # to track the time since experiment started +routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine + +# set up handler to look after randomisation of conditions etc +trials = data.TrialHandler(nReps=20, method='random', + extraInfo=expInfo, originPath=-1, + trialList=[None], + seed=None, name='trials') +thisExp.addLoop(trials) # add the loop to the experiment +thisTrial = trials.trialList[0] # so we can initialise stimuli with some values +# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb) +if thisTrial != None: + for paramName in thisTrial: + exec('{} = thisTrial[paramName]'.format(paramName)) + +for thisTrial in trials: + currentLoop = trials + # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb) + if thisTrial != None: + for paramName in thisTrial: + exec('{} = thisTrial[paramName]'.format(paramName)) + + # ------Prepare to start Routine "trial"------- + routineTimer.add(2.030000) + # update component parameters for each repeat + letter.setText('a') + # keep track of which components have finished + trialComponents = [letter] + for thisComponent in trialComponents: + thisComponent.tStart = None + thisComponent.tStop = None + thisComponent.tStartRefresh = None + thisComponent.tStopRefresh = None + if hasattr(thisComponent, 'status'): + thisComponent.status = NOT_STARTED + # reset timers + t = 0 + _timeToFirstFrame = win.getFutureFlipTime(clock="now") + trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip + frameN = -1 + continueRoutine = True + + # -------Run Routine "trial"------- + while continueRoutine and routineTimer.getTime() > 0: + # get current time + t = trialClock.getTime() + tThisFlip = win.getFutureFlipTime(clock=trialClock) + tThisFlipGlobal = win.getFutureFlipTime(clock=None) + frameN = frameN + 1 # number of completed frames (so 0 is the first frame) + # update/draw components on each frame + + # *letter* updates + if letter.status == NOT_STARTED and tThisFlip >= 2-frameTolerance: + # keep track of start time/frame for later + letter.frameNStart = frameN # exact frame index + letter.tStart = t # local t and not account for scr refresh + letter.tStartRefresh = tThisFlipGlobal # on global time + win.timeOnFlip(letter, 'tStartRefresh') # time at next scr refresh + letter.setAutoDraw(True) + if letter.status == STARTED: + # is it time to stop? (based on global clock, using actual start) + if tThisFlipGlobal > letter.tStartRefresh + 0.03-frameTolerance: + # keep track of stop time/frame for later + letter.tStop = t # not accounting for scr refresh + letter.frameNStop = frameN # exact frame index + win.timeOnFlip(letter, 'tStopRefresh') # time at next scr refresh + letter.setAutoDraw(False) + + # check for quit (typically the Esc key) + if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): + core.quit() + + # check if all components have finished + if not continueRoutine: # a component has requested a forced-end of Routine + break + continueRoutine = False # will revert to True if at least one component still running + for thisComponent in trialComponents: + if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: + continueRoutine = True + break # at least one component has not yet finished + + # refresh the screen + if continueRoutine: # don't flip if this routine is over or we'll get a blank screen + win.flip() + + # -------Ending Routine "trial"------- + for thisComponent in trialComponents: + if hasattr(thisComponent, "setAutoDraw"): + thisComponent.setAutoDraw(False) + trials.addData('letter.started', letter.tStartRefresh) + trials.addData('letter.stopped', letter.tStopRefresh) + thisExp.nextEntry() + +# completed 20 repeats of 'trials' + + +# Flip one final time so any remaining win.callOnFlip() +# and win.timeOnFlip() tasks get executed before quitting +win.flip() + +# 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 +win.close() +core.quit()