diff --git a/rMtS_multiblock.py b/rMtS_multiblock.py index 57c04c423be9993b89a735a76c09b4aa02f7ea91..8d08862d892e3d9aa14f0c4dbdece31294044736 100644 --- a/rMtS_multiblock.py +++ b/rMtS_multiblock.py @@ -42,6 +42,7 @@ if __name__ == '__main__': ('sample retention time','[1.5, 1.5]'), # delay after sample ('match type', ['single','multi']), # match type ("single" - ~Alekseichuk or "multi" - ~Berger) ('match number',1), # number of matches per sample + ('dedicated response period "?"', False), ('scanner mode', False), # Is it inside the scanner ('stimulation', False), # Run tES ('trigger port', ['none']+listSerial()), @@ -81,7 +82,9 @@ if __name__ == '__main__': matchDuration = 1 responseJitterRange = [0, 0] # jitter between events - responseDuration = 0 # maximum duration of response on top of matchDuration, 0 for no "?" + responseDuration = 1 # maximum duration of response on top of matchDuration + if not(expInfo['dedicated response period "?"']): # , 0 for no "?" + responseDuration = 0 stimRamp = 3 # stimulation rampup and rampdown @@ -98,7 +101,7 @@ if __name__ == '__main__': sampleDuration+ array(matchJitterRange).mean()+ nMatch*( - sampleDuration + + matchDuration + array(responseJitterRange).mean()+ responseDuration ) @@ -163,7 +166,7 @@ if __name__ == '__main__': else: infoStr = [ "You will perform a visual-spatial match-to-sample test, which is commonly used to assess spatial working memory.\n\nThe test takes about {:.1f} minute(s) and consists of {} trials. In each trial, first, you will see a sample stimulus: {} dots within a grid. This is followed by a mask stimulus, which is the same grid filled with grey dots.\n\nPress 'Yes' to continue.".format(tTot, nConditionBlock*nTrialBlock*nSample, sampleNum), - "Then, after shorter or longer delay, you will be presented with {} set(s) of test. The tests include a test stimulus, appearance of a single dot\n\nYou will have {:.1f} second(s) to press 'Yes' or 'No' indicating whether the location of the dot in the test stimulus matches any of those in the sample stimulus.\n\nPress 'Yes' when ready to start.".format(nMatch,responseDuration) + "Then, after shorter or longer delay, you will be presented with {} set(s) of test. The tests include a test stimulus, appearance of a single dot\n\nYou will have {:.1f} second(s) to press 'Yes' or 'No' indicating whether the location of the dot in the test stimulus matches any of those in the sample stimulus.\n\nPress 'Yes' when ready to start.".format(nMatch,matchDuration) ] infoImg = [ @@ -451,7 +454,7 @@ if __name__ == '__main__': elementTex=None, elementMask="circle", colors=colour, colorSpace='rgb', autoLog=False) recallForm.status == NOT_STARTED - while trialClock.getTime() < (jitter + sampleDuration): + while trialClock.getTime() < (jitter + matchDuration): # get current time t = trialClock.getTime() frameN = frameN + 1 # number of completed frames (so 0 is the first frame) @@ -479,6 +482,8 @@ if __name__ == '__main__': recallForm.status = STARTED win.logOnFlip(level=logging.EXP, msg='Match - STARTED - ' + array2string(thisMatch['match'])) if doTrigger: trigger.send(TRIGGER['testBase']+loopMatch.thisTrialN+1) + if responseDuration == 0: + SSO.wait_for_button(no_block=True) if fullForm.status == STARTED: fullForm.draw() @@ -487,44 +492,45 @@ if __name__ == '__main__': recallForm.draw() win.flip() - interimClock.reset((jitter + sampleDuration) - trialClock.getTime()) + interimClock.reset((jitter + matchDuration) - trialClock.getTime()) if recallForm.status == STARTED: recallForm.status = STOPPED win.logOnFlip(level=logging.EXP, msg='Match - STOPPED') - # Response - trialClock.reset(-interimClock.getTime()) - jitter = thisMatch['onsetResponse'] - - responseStim.status = NOT_STARTED - SSO.reset_buttons() - - while trialClock.getTime() < (jitter + responseDuration): - # get current time - t = trialClock.getTime() - frameN = frameN + 1 # number of completed frames (so 0 is the first frame) + # Response + if responseDuration > 0: + trialClock.reset(-interimClock.getTime()) + jitter = thisMatch['onsetResponse'] - # update/draw components on each frame - gridForm.draw() + responseStim.status = NOT_STARTED + SSO.reset_buttons() - # *sampleForm* updates - if t >= jitter and responseStim.status == NOT_STARTED: - # keep track of start time/frame for later - responseStim.tStart = t - responseStim.frameNStart = frameN # exact frame index - responseStim.setAutoDraw(True) - win.logOnFlip(level=logging.EXP, msg='Response - STARTED') - if doTrigger: trigger.send(TRIGGER['responseBase']+loopMatch.thisTrialN+1) - SSO.wait_for_button(no_block=True) + while trialClock.getTime() < (jitter + responseDuration): + # get current time + t = trialClock.getTime() + frameN = frameN + 1 # number of completed frames (so 0 is the first frame) - win.flip() - interimClock.reset((jitter + responseDuration)-trialClock.getTime()) - - if responseStim.status == STARTED: - responseStim.status = STOPPED - responseStim.setAutoDraw(False) - win.logOnFlip(level=logging.EXP, msg='Response - STOPPED') + # update/draw components on each frame + gridForm.draw() + + # *sampleForm* updates + if t >= jitter and responseStim.status == NOT_STARTED: + # keep track of start time/frame for later + responseStim.tStart = t + responseStim.frameNStart = frameN # exact frame index + responseStim.setAutoDraw(True) + win.logOnFlip(level=logging.EXP, msg='Response - STARTED') + if doTrigger: trigger.send(TRIGGER['responseBase']+loopMatch.thisTrialN+1) + SSO.wait_for_button(no_block=True) + + win.flip() + interimClock.reset((jitter + responseDuration)-trialClock.getTime()) + + if responseStim.status == STARTED: + responseStim.status = STOPPED + responseStim.setAutoDraw(False) + win.logOnFlip(level=logging.EXP, msg='Response - STOPPED') if len(SSO.buttonpresses): # no - SSO.buttonpresses[-1][0] = bNo; yes - SSO.buttonpresses[-1][0] = bYes logging.log(level=logging.EXP, msg='Button - {:.3f} - {}'.format(SSO.buttonpresses[-1][1],SSO.buttonpresses[-1][0]))