diff --git a/rds_task.psyexp b/rds_task.psyexp
index 60c83e0c41f1ddc6dc338f5f639135163d9dbd13..41cefdacda4e8fcecad4d24168ea156e6edf663d 100644
--- a/rds_task.psyexp
+++ b/rds_task.psyexp
@@ -8,7 +8,7 @@
     <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="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"/>
@@ -23,7 +23,7 @@
     <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="[1920, 1080]" valType="code"/>
+    <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="$[0,0,0]" valType="str"/>
     <Param name="colorSpace" updates="None" val="rgb" valType="str"/>
@@ -33,6 +33,21 @@
   </Settings>
   <Routines>
     <Routine name="trial">
+      <CodeComponent name="sequence">
+        <Param name="Begin Experiment" updates="constant" val="MINLEVEL=0&amp;#10;MAXLEVEL=9" valType="extendedCode"/>
+        <Param name="Begin JS Experiment" updates="constant" val="" valType="extendedCode"/>
+        <Param name="Begin JS Routine" updates="constant" val="" valType="extendedCode"/>
+        <Param name="Begin Routine" updates="constant" val="sequence=np.random.randint(0,10,MAXLEVEL-level+1)&amp;#10;stair.addOtherData('digits.stimulus', sequence)" valType="extendedCode"/>
+        <Param name="Code Type" updates="None" val="Py" valType="str"/>
+        <Param name="Each Frame" updates="constant" val="" valType="extendedCode"/>
+        <Param name="Each JS Frame" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End Experiment" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End JS Experiment" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End JS Routine" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End Routine" updates="constant" val="resp.corr = [int(k) for k in resp.keys] == list(np.flip(sequence))&amp;#10;stair.addResponse(resp.corr)&amp;#10;stair.addOtherData('resp.keys', resp.keys)" valType="extendedCode"/>
+        <Param name="disabled" updates="None" val="False" valType="bool"/>
+        <Param name="name" updates="None" val="sequence" valType="code"/>
+      </CodeComponent>
       <TextComponent name="digits">
         <Param name="color" updates="constant" val="white" valType="str"/>
         <Param name="colorSpace" updates="constant" val="rgb" valType="str"/>
@@ -49,14 +64,32 @@
         <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="1" valType="code"/>
+        <Param name="startVal" updates="None" val="0" valType="code"/>
         <Param name="stopType" updates="None" val="duration (s)" valType="str"/>
         <Param name="stopVal" updates="constant" val="1.0" valType="code"/>
         <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/>
-        <Param name="text" updates="constant" val="3" valType="str"/>
+        <Param name="text" updates="set every repeat" val="$str(sequence)[1:-1]" valType="str"/>
         <Param name="units" updates="None" val="from exp settings" valType="str"/>
-        <Param name="wrapWidth" updates="constant" val="" valType="code"/>
+        <Param name="wrapWidth" updates="constant" val="30" valType="code"/>
       </TextComponent>
+      <KeyboardComponent name="resp">
+        <Param name="allowedKeys" updates="constant" val="'0','1','2','3','4','5','6','7','8','9'" valType="code"/>
+        <Param name="correctAns" updates="constant" val="" valType="str"/>
+        <Param name="disabled" updates="None" val="False" valType="bool"/>
+        <Param name="discard previous" updates="constant" val="True" valType="bool"/>
+        <Param name="durationEstim" updates="None" val="" valType="code"/>
+        <Param name="forceEndRoutine" updates="constant" val="False" valType="bool"/>
+        <Param name="name" updates="None" val="resp" 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="0" valType="code"/>
+        <Param name="stopType" updates="None" val="duration (s)" valType="str"/>
+        <Param name="stopVal" updates="constant" val="2" valType="code"/>
+        <Param name="store" updates="constant" val="all keys" valType="str"/>
+        <Param name="storeCorrect" updates="constant" val="False" valType="bool"/>
+        <Param name="syncScreenRefresh" updates="constant" val="True" valType="bool"/>
+      </KeyboardComponent>
     </Routine>
     <Routine name="Instruction">
       <TextComponent name="instruction">
@@ -72,7 +105,7 @@
         <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="saveStartStop" updates="None" val="False" 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="0.0" valType="code"/>
@@ -87,36 +120,40 @@
         <Param name="allowedKeys" updates="constant" val="'space'" valType="code"/>
         <Param name="correctAns" updates="constant" val="" valType="str"/>
         <Param name="disabled" updates="None" val="False" valType="bool"/>
-        <Param name="discard previous" updates="constant" val="True" valType="bool"/>
+        <Param name="discard previous" updates="constant" val="False" valType="bool"/>
         <Param name="durationEstim" updates="None" val="" valType="code"/>
         <Param name="forceEndRoutine" updates="constant" val="True" valType="bool"/>
         <Param name="name" updates="None" val="key_start" valType="code"/>
-        <Param name="saveStartStop" updates="None" val="True" valType="bool"/>
+        <Param name="saveStartStop" updates="None" val="False" 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="0.0" valType="code"/>
         <Param name="stopType" updates="None" val="duration (s)" valType="str"/>
         <Param name="stopVal" updates="constant" val="" valType="code"/>
-        <Param name="store" updates="constant" val="last key" valType="str"/>
+        <Param name="store" updates="constant" val="nothing" valType="str"/>
         <Param name="storeCorrect" updates="constant" val="False" valType="bool"/>
-        <Param name="syncScreenRefresh" updates="constant" val="True" valType="bool"/>
+        <Param name="syncScreenRefresh" updates="constant" val="False" valType="bool"/>
       </KeyboardComponent>
     </Routine>
   </Routines>
   <Flow>
     <Routine name="Instruction"/>
-    <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"/>
+    <LoopInitiator loopType="StairHandler" name="stair">
+      <Param name="N down" updates="None" val="1" valType="code"/>
+      <Param name="N reversals" updates="None" val="1" valType="code"/>
+      <Param name="N up" updates="None" val="1" valType="code"/>
       <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="sequential" valType="str"/>
+      <Param name="loopType" updates="None" val="staircase" valType="str"/>
+      <Param name="max value" updates="None" val="MAXLEVEL" valType="code"/>
+      <Param name="min value" updates="None" val="MINLEVEL" valType="code"/>
       <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"/>
+      <Param name="name" updates="None" val="stair" valType="code"/>
+      <Param name="start value" updates="None" val="MAXLEVEL-1" valType="code"/>
+      <Param name="step sizes" updates="None" val="[1]" valType="code"/>
+      <Param name="step type" updates="None" val="lin" valType="str"/>
     </LoopInitiator>
     <Routine name="trial"/>
-    <LoopTerminator name="trials"/>
+    <LoopTerminator name="stair"/>
   </Flow>
 </PsychoPy2experiment>
diff --git a/rds_task.py b/rds_task.py
new file mode 100644
index 0000000000000000000000000000000000000000..b55782594c23692f96efde9a4d789b56070f741e
--- /dev/null
+++ b/rds_task.py
@@ -0,0 +1,342 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+This experiment was created using PsychoPy3 Experiment Builder (v3.2.0),
+    on November 13, 2019, at 18:38
+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 = 'rds_task'  # 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\\reverse-digit-span-task\\rds_task.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='testMonitor', color=[0,0,0], 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 "Instruction"
+InstructionClock = core.Clock()
+instruction = visual.TextStim(win=win, name='instruction',
+    text='Press SPACE to start',
+    font='Arial',
+    pos=(0, 0), height=2.5, wrapWidth=None, ori=0, 
+    color='white', colorSpace='rgb', opacity=1, 
+    languageStyle='LTR',
+    depth=0.0);
+key_start = keyboard.Keyboard()
+
+# Initialize components for Routine "trial"
+trialClock = core.Clock()
+MINLEVEL=0
+MAXLEVEL=9
+digits = visual.TextStim(win=win, name='digits',
+    text='default text',
+    font='Arial',
+    pos=(0, 0), height=2.5, wrapWidth=30, ori=0, 
+    color='white', colorSpace='rgb', opacity=1, 
+    languageStyle='LTR',
+    depth=-1.0);
+resp = keyboard.Keyboard()
+
+# 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 
+
+# ------Prepare to start Routine "Instruction"-------
+# update component parameters for each repeat
+key_start.keys = []
+key_start.rt = []
+# keep track of which components have finished
+InstructionComponents = [instruction, key_start]
+for thisComponent in InstructionComponents:
+    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")
+InstructionClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
+frameN = -1
+continueRoutine = True
+
+# -------Run Routine "Instruction"-------
+while continueRoutine:
+    # get current time
+    t = InstructionClock.getTime()
+    tThisFlip = win.getFutureFlipTime(clock=InstructionClock)
+    tThisFlipGlobal = win.getFutureFlipTime(clock=None)
+    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
+    # update/draw components on each frame
+    
+    # *instruction* updates
+    if instruction.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
+        # keep track of start time/frame for later
+        instruction.frameNStart = frameN  # exact frame index
+        instruction.tStart = t  # local t and not account for scr refresh
+        instruction.tStartRefresh = tThisFlipGlobal  # on global time
+        win.timeOnFlip(instruction, 'tStartRefresh')  # time at next scr refresh
+        instruction.setAutoDraw(True)
+    if instruction.status == STARTED:
+        if bool(False):
+            # keep track of stop time/frame for later
+            instruction.tStop = t  # not accounting for scr refresh
+            instruction.frameNStop = frameN  # exact frame index
+            win.timeOnFlip(instruction, 'tStopRefresh')  # time at next scr refresh
+            instruction.setAutoDraw(False)
+    
+    # *key_start* updates
+    if key_start.status == NOT_STARTED and t >= 0.0-frameTolerance:
+        # keep track of start time/frame for later
+        key_start.frameNStart = frameN  # exact frame index
+        key_start.tStart = t  # local t and not account for scr refresh
+        key_start.tStartRefresh = tThisFlipGlobal  # on global time
+        win.timeOnFlip(key_start, 'tStartRefresh')  # time at next scr refresh
+        key_start.status = STARTED
+        # keyboard checking is just starting
+    if key_start.status == STARTED:
+        theseKeys = key_start.getKeys(keyList=['space'], waitRelease=False)
+        if len(theseKeys):
+            theseKeys = theseKeys[0]  # at least one key was pressed
+            
+            # check for quit:
+            if "escape" == theseKeys:
+                endExpNow = True
+            # a response ends the routine
+            continueRoutine = 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 InstructionComponents:
+        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 "Instruction"-------
+for thisComponent in InstructionComponents:
+    if hasattr(thisComponent, "setAutoDraw"):
+        thisComponent.setAutoDraw(False)
+# the Routine "Instruction" was not non-slip safe, so reset the non-slip timer
+routineTimer.reset()
+
+# --------Prepare to start Staircase "stair" --------
+# set up handler to look after next chosen value etc
+stair = data.StairHandler(startVal=MAXLEVEL-1, extraInfo=expInfo,
+    stepSizes=[1], stepType='lin',
+    nReversals=1, nTrials=20, 
+    nUp=1, nDown=1,
+    minVal=MINLEVEL, maxVal=MAXLEVEL,
+    originPath=-1, name='stair')
+thisExp.addLoop(stair)  # add the loop to the experiment
+level = thisStair = MAXLEVEL-1  # initialise some vals
+
+for thisStair in stair:
+    currentLoop = stair
+    level = thisStair
+    
+    # ------Prepare to start Routine "trial"-------
+    routineTimer.add(2.000000)
+    # update component parameters for each repeat
+    sequence=np.random.randint(0,10,MAXLEVEL-level+1)
+    stair.addOtherData('digits.stimulus', sequence)
+    digits.setText(str(sequence)[1:-1])
+    resp.keys = []
+    resp.rt = []
+    # keep track of which components have finished
+    trialComponents = [digits, resp]
+    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
+        
+        # *digits* updates
+        if digits.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
+            # keep track of start time/frame for later
+            digits.frameNStart = frameN  # exact frame index
+            digits.tStart = t  # local t and not account for scr refresh
+            digits.tStartRefresh = tThisFlipGlobal  # on global time
+            win.timeOnFlip(digits, 'tStartRefresh')  # time at next scr refresh
+            digits.setAutoDraw(True)
+        if digits.status == STARTED:
+            # is it time to stop? (based on global clock, using actual start)
+            if tThisFlipGlobal > digits.tStartRefresh + 1.0-frameTolerance:
+                # keep track of stop time/frame for later
+                digits.tStop = t  # not accounting for scr refresh
+                digits.frameNStop = frameN  # exact frame index
+                win.timeOnFlip(digits, 'tStopRefresh')  # time at next scr refresh
+                digits.setAutoDraw(False)
+        
+        # *resp* updates
+        waitOnFlip = False
+        if resp.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
+            # keep track of start time/frame for later
+            resp.frameNStart = frameN  # exact frame index
+            resp.tStart = t  # local t and not account for scr refresh
+            resp.tStartRefresh = tThisFlipGlobal  # on global time
+            win.timeOnFlip(resp, 'tStartRefresh')  # time at next scr refresh
+            resp.status = STARTED
+            # keyboard checking is just starting
+            waitOnFlip = True
+            win.callOnFlip(resp.clock.reset)  # t=0 on next screen flip
+            win.callOnFlip(resp.clearEvents, eventType='keyboard')  # clear events on next screen flip
+        if resp.status == STARTED:
+            # is it time to stop? (based on global clock, using actual start)
+            if tThisFlipGlobal > resp.tStartRefresh + 2-frameTolerance:
+                # keep track of stop time/frame for later
+                resp.tStop = t  # not accounting for scr refresh
+                resp.frameNStop = frameN  # exact frame index
+                win.timeOnFlip(resp, 'tStopRefresh')  # time at next scr refresh
+                resp.status = FINISHED
+        if resp.status == STARTED and not waitOnFlip:
+            theseKeys = resp.getKeys(keyList=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], waitRelease=False)
+            if len(theseKeys):
+                theseKeys = theseKeys[0]  # at least one key was pressed
+                
+                # check for quit:
+                if "escape" == theseKeys:
+                    endExpNow = True
+                resp.keys.append(theseKeys.name)  # storing all keys
+                resp.rt.append(theseKeys.rt)
+        
+        # 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)
+    resp.corr = [int(k) for k in resp.keys] == list(np.flip(sequence))
+    stair.addResponse(resp.corr)
+    stair.addOtherData('resp.keys', resp.keys)
+    stair.addOtherData('digits.started', digits.tStartRefresh)
+    stair.addOtherData('digits.stopped', digits.tStopRefresh)
+    # check responses
+    if resp.keys in ['', [], None]:  # No response was made
+        resp.keys = None
+    stair.addOtherData('resp.started', resp.tStartRefresh)
+    stair.addOtherData('resp.stopped', resp.tStopRefresh)
+    thisExp.nextEntry()
+    
+# staircase completed
+
+
+# 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()
diff --git a/rds_task_lastrun.py b/rds_task_lastrun.py
index fa539d41dbbaaec3a562cc66543a4f7ab79cdcf5..49813a75f848143c9fb6eae618c0a63218853894 100644
--- a/rds_task_lastrun.py
+++ b/rds_task_lastrun.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 """
 This experiment was created using PsychoPy3 Experiment Builder (v3.2.0),
-    on November 04, 2019, at 16:17
+    on November 13, 2019, at 18:35
 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) 
@@ -63,8 +63,8 @@ frameTolerance = 0.001  # how close to onset before 'same' frame
 
 # Setup the Window
 win = visual.Window(
-    size=[1920, 1080], fullscr=True, screen=0, 
-    winType='pyglet', allowGUI=False, allowStencil=False,
+    size=[1600, 900], fullscr=False, screen=0, 
+    winType='pyglet', allowGUI=True, allowStencil=False,
     monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
     blendMode='avg', useFBO=True, 
     units='deg')
@@ -91,13 +91,16 @@ key_start = keyboard.Keyboard()
 
 # Initialize components for Routine "trial"
 trialClock = core.Clock()
+MINLEVEL=0
+MAXLEVEL=9
 digits = visual.TextStim(win=win, name='digits',
-    text='3',
+    text='default text',
     font='Arial',
-    pos=(0, 0), height=2.5, wrapWidth=None, ori=0, 
+    pos=(0, 0), height=2.5, wrapWidth=30, ori=0, 
     color='white', colorSpace='rgb', opacity=1, 
     languageStyle='LTR',
-    depth=0.0);
+    depth=-1.0);
+resp = keyboard.Keyboard()
 
 # Create some handy timers
 globalClock = core.Clock()  # to track the time since experiment started
@@ -149,8 +152,7 @@ while continueRoutine:
             instruction.setAutoDraw(False)
     
     # *key_start* updates
-    waitOnFlip = False
-    if key_start.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
+    if key_start.status == NOT_STARTED and t >= 0.0-frameTolerance:
         # keep track of start time/frame for later
         key_start.frameNStart = frameN  # exact frame index
         key_start.tStart = t  # local t and not account for scr refresh
@@ -158,10 +160,7 @@ while continueRoutine:
         win.timeOnFlip(key_start, 'tStartRefresh')  # time at next scr refresh
         key_start.status = STARTED
         # keyboard checking is just starting
-        waitOnFlip = True
-        win.callOnFlip(key_start.clock.reset)  # t=0 on next screen flip
-        win.callOnFlip(key_start.clearEvents, eventType='keyboard')  # clear events on next screen flip
-    if key_start.status == STARTED and not waitOnFlip:
+    if key_start.status == STARTED:
         theseKeys = key_start.getKeys(keyList=['space'], waitRelease=False)
         if len(theseKeys):
             theseKeys = theseKeys[0]  # at least one key was pressed
@@ -169,8 +168,6 @@ while continueRoutine:
             # check for quit:
             if "escape" == theseKeys:
                 endExpNow = True
-            key_start.keys = theseKeys.name  # just the last key pressed
-            key_start.rt = theseKeys.rt
             # a response ends the routine
             continueRoutine = False
     
@@ -195,44 +192,34 @@ while continueRoutine:
 for thisComponent in InstructionComponents:
     if hasattr(thisComponent, "setAutoDraw"):
         thisComponent.setAutoDraw(False)
-thisExp.addData('instruction.started', instruction.tStartRefresh)
-thisExp.addData('instruction.stopped', instruction.tStopRefresh)
-# check responses
-if key_start.keys in ['', [], None]:  # No response was made
-    key_start.keys = None
-thisExp.addData('key_start.keys',key_start.keys)
-if key_start.keys != None:  # we had a response
-    thisExp.addData('key_start.rt', key_start.rt)
-thisExp.addData('key_start.started', key_start.tStartRefresh)
-thisExp.addData('key_start.stopped', key_start.tStopRefresh)
-thisExp.nextEntry()
 # the Routine "Instruction" was not non-slip safe, so reset the non-slip timer
 routineTimer.reset()
 
-# set up handler to look after randomisation of conditions etc
-trials = data.TrialHandler(nReps=20, method='sequential', 
-    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))
+# --------Prepare to start Staircase "stair" --------
+# set up handler to look after next chosen value etc
+stair = data.StairHandler(startVal=MAXLEVEL-1, extraInfo=expInfo,
+    stepSizes=[1], stepType='lin',
+    nReversals=1, nTrials=20, 
+    nUp=1, nDown=1,
+    minVal=MINLEVEL, maxVal=MAXLEVEL,
+    originPath=-1, name='stair')
+thisExp.addLoop(stair)  # add the loop to the experiment
+level = thisStair = MAXLEVEL-1  # initialise some vals
 
-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))
+for thisStair in stair:
+    currentLoop = stair
+    level = thisStair
     
     # ------Prepare to start Routine "trial"-------
     routineTimer.add(2.000000)
     # update component parameters for each repeat
+    sequence=np.random.randint(0,10,MAXLEVEL-level+1)
+    stair.addOtherData('digits.stimulus', sequence)
+    digits.setText(str(sequence)[1:-1])
+    resp.keys = []
+    resp.rt = []
     # keep track of which components have finished
-    trialComponents = [digits]
+    trialComponents = [digits, resp]
     for thisComponent in trialComponents:
         thisComponent.tStart = None
         thisComponent.tStop = None
@@ -257,7 +244,7 @@ for thisTrial in trials:
         # update/draw components on each frame
         
         # *digits* updates
-        if digits.status == NOT_STARTED and tThisFlip >= 1-frameTolerance:
+        if digits.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
             # keep track of start time/frame for later
             digits.frameNStart = frameN  # exact frame index
             digits.tStart = t  # local t and not account for scr refresh
@@ -273,6 +260,38 @@ for thisTrial in trials:
                 win.timeOnFlip(digits, 'tStopRefresh')  # time at next scr refresh
                 digits.setAutoDraw(False)
         
+        # *resp* updates
+        waitOnFlip = False
+        if resp.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
+            # keep track of start time/frame for later
+            resp.frameNStart = frameN  # exact frame index
+            resp.tStart = t  # local t and not account for scr refresh
+            resp.tStartRefresh = tThisFlipGlobal  # on global time
+            win.timeOnFlip(resp, 'tStartRefresh')  # time at next scr refresh
+            resp.status = STARTED
+            # keyboard checking is just starting
+            waitOnFlip = True
+            win.callOnFlip(resp.clock.reset)  # t=0 on next screen flip
+            win.callOnFlip(resp.clearEvents, eventType='keyboard')  # clear events on next screen flip
+        if resp.status == STARTED:
+            # is it time to stop? (based on global clock, using actual start)
+            if tThisFlipGlobal > resp.tStartRefresh + 2-frameTolerance:
+                # keep track of stop time/frame for later
+                resp.tStop = t  # not accounting for scr refresh
+                resp.frameNStop = frameN  # exact frame index
+                win.timeOnFlip(resp, 'tStopRefresh')  # time at next scr refresh
+                resp.status = FINISHED
+        if resp.status == STARTED and not waitOnFlip:
+            theseKeys = resp.getKeys(keyList=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], waitRelease=False)
+            if len(theseKeys):
+                theseKeys = theseKeys[0]  # at least one key was pressed
+                
+                # check for quit:
+                if "escape" == theseKeys:
+                    endExpNow = True
+                resp.keys.append(theseKeys.name)  # storing all keys
+                resp.rt.append(theseKeys.rt)
+        
         # check for quit (typically the Esc key)
         if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
             core.quit()
@@ -294,11 +313,19 @@ for thisTrial in trials:
     for thisComponent in trialComponents:
         if hasattr(thisComponent, "setAutoDraw"):
             thisComponent.setAutoDraw(False)
-    trials.addData('digits.started', digits.tStartRefresh)
-    trials.addData('digits.stopped', digits.tStopRefresh)
+    resp.corr = [int(k) for k in resp.keys] == list(np.flip(sequence))
+    stair.addResponse(resp.corr)
+    stair.addOtherData('resp.keys', resp.keys)
+    stair.addOtherData('digits.started', digits.tStartRefresh)
+    stair.addOtherData('digits.stopped', digits.tStopRefresh)
+    # check responses
+    if resp.keys in ['', [], None]:  # No response was made
+        resp.keys = None
+    stair.addOtherData('resp.started', resp.tStartRefresh)
+    stair.addOtherData('resp.stopped', resp.tStopRefresh)
     thisExp.nextEntry()
     
-# completed 20 repeats of 'trials'
+# staircase completed
 
 
 # Flip one final time so any remaining win.callOnFlip()