2015-01-09 8 views
0

Matlab에서 약간의 경험이 있지만 PsychoPy를 처음 사용하게되었습니다.PsychoPy Coder : 프레임을 기준으로 이미지 지속 시간을 정의하십시오.

지금은 키보드 응답이있을 때까지 두 이미지를 계속 전환하고 싶습니다. 각 이미지는 100ms 동안 화면에 정확히 있어야하며이 경우 (로그 파일 등)를 확인할 수 있어야합니다.

win.flip() 후 core.wait (.084)를 사용하면 약 100ms의 60Hz 화면에서 올바르게 정렬됩니다. 각 플립의 프레임을 win.logOnFlip()과 함께 로그 파일에 기록하여 확인하고 있습니다.

그러나 나는 프레임의 관점에서 이미지의 지속 시간을 정의하는 방법 만 알고있을 수 있다고 생각합니다. .

함수 core.wait()는 프레임이 아니라 초 단위로 시간이 걸립니다.

6 프레임에 대해 각 이미지의 표시 방법 (및 확인 방법)에 대한 정보를 알려 주시면 매우 감사드립니다. 사전에

감사 톤

최저

세바스찬 여기

내 코드 :

import os       # for file/folder operations 
from psychopy import visual, event, core, gui, data, logging 

# Ensure that relative paths start from the same directory as this script 
_thisDir = os.path.dirname(os.path.abspath(__file__)) 
os.chdir(_thisDir) 

# screen size in pixels 
scrsize = (600,400)     

# gather info participant 
exp_name = 'MyFirstPsychoPy' 
exp_info = { 
     'participant': '', 
     } 
dlg = gui.DlgFromDict(dictionary=exp_info, title=exp_name) 

# if user pressed cancel quit 
if dlg.OK == False: 
    core.quit() 

# Get date and time 
exp_info['date'] = data.getDateStr() 
exp_info['exp_name'] = exp_name 

#save a log file for detail verbose info 
filename = _thisDir + os.sep + 'data/%s_%s_%s' %(exp_info['participant'], exp_name, exp_info['date']) 
# print filename #to see if path correct 
logFile = logging.LogFile(filename+'.log', level=logging.DEBUG) 
logging.console.setLevel(logging.WARNING) # outputs to the screen, not a file 


# Create a window small window 
win = visual.Window(size=scrsize, color='white', units='pix', fullscr=False) 

# or go full screen 
#win = visual.Window([1280,1024], fullscr=True, allowGUI=False, waitBlanking=True) 

# this is supposed to record all frames 
win.setRecordFrameIntervals(True) 

# show instructions until spacebar 
start_message = visual.TextStim(win, 
          text="hello. you will see mondrians. press space to respond.", 
          color='red', height=20) 
event.clearEvents() 
keys = event.getKeys(keyList=['space', 'escape']) #allow only space and escape keys 
while len(keys) == 0: 
    start_message.draw() 
    win.flip() 

    keys = event.getKeys(keyList=['space', 'escape']) 
    if len(keys)>0: 
     break 

print keys #show on output screen 
keys = event.clearEvents() # empty keys 
keys = event.getKeys(keyList=['space', 'escape']) 


# define 2 pictures 
bitmap1 = visual.ImageStim(win, 'Mondrians/Mask_1.bmp', size=scrsize) 
bitmap2 = visual.ImageStim(win, 'Mondrians/Mask_2.bmp', size=scrsize) 
bitmap = bitmap1 


# Initialize clock to register response time 
rt_clock = core.Clock() 
rt_clock.reset() # set rt clock to 0 


# show alternating pics until response 
frameN = 0 
while len(keys) == 0:  

    if bitmap == bitmap1: 
     bitmap = bitmap2 
    else: 
     bitmap = bitmap1 

    bitmap.draw() 

    win.logOnFlip(msg='frame=%i' %frameN, level=logging.DEBUG) #record the time of win.flip() in the log file 
    win.flip() # show image 
    frameN = frameN + 1 

    core.wait(.084) # wait 100 ms 


    keys = event.getKeys(keyList=['space', 'escape']) #record resp 

    # if response stop 
    if len(keys)>0: 
     rt = rt_clock.getTime() 
     break  

print keys, rt #show resp and rt on screen 

win.saveFrameIntervals(filename+'.log', clear=True) 

win.close() 
core.quit() 

답변

1

예, 더 나은 방법이있다! 표준 솔루션은 win.flip()이 다음 모니터 업데이트 때까지 코드 실행을 중단한다는 사실을 이용합니다. 따라서 win.flip()을 반복하면 루프 당 정확히 하나의 프레임이 제공됩니다.

clock = core.Clock() # to assess timing 
keepLooping = True 
while keepLooping: # continue until break 
    for thisBitmap in [bitmap1, bitmap2]: # alternate between images 
     if keepLooping: # do not show bitmap2 if a key was pressed on bitmap1 
      for frameN in range(6): # 100 ms 
       thisBitmap.draw() 
       print clock.getTime() 
       win.callOnFlip(clock.reset) # ... or use win.logOnFlip 
       win.flip() # inner loop is timed to this, as long as the rest of the code in here doesn't take longer than a frame. 

       keys = event.getKeys(keyList=['space', 'escape']) 
       if keys: # notice simplification. [] evaluates to False. 
        rt = rt_clock.getTime() 
        keepLooping = False 
        break 

... 그리고 나머지 : 그래서 두 응답이있을 때까지 imagesStims (bitmap1bitmap2) 사이를 전환합니다. 여기에 시간을 평가하기 위해 core.Clock()을 사용했지만 win.logOnFlip()은 그만큼 좋습니다. 원하는 출력의 종류에 따라 다릅니다.

event.getKeys()은 키를 누른 시간이 아니라이 줄이 실행 된 시간을 기록합니다. 따라서 약간의 지연이 추가됩니다. 따라서이 "프레임 고정 루프"에서 키 응답은 프레임 간격으로 이산화됩니다. 키보드 상태를 실제로 비동기 적으로 폴링하려면 (예 : RT 기록에서 + 16ms 오류가 발생하는 경우) iohub 모듈을 사용하십시오. 어쨌든 많은 키보드에는 고유 한 10-30 ms 대기 시간이 있으므로 모든 대기 시간을 제거 할 수는 없습니다.

+0

안녕하세요, Jonas, 정말 고맙습니다. 귀하의 제안에 따라 이미지가 100ms/6 프레임으로 표시됩니다. 불행하게도, 실험이 이제는 멈추지 않기 때문에 정확한 타이밍에 대해 확신하지 못합니다 (이미지가 앞뒤로 전환되면 스페이스 바를 사용하지 않아도 됨) 로그 파일이 작성되지 않습니다 (빈 로그 파일이 생성됩니다) . print clock.getTime()을 사용하여 출력 창에 인쇄 된 시간은 0.0002 범위이며 이해할 수 없습니다. 초가 아닌가? 그래서. 지금 뭐야? 다시 한번 감사드립니다. –

+0

로그 파일 없음 : 로그 파일이 아닌 콘솔에 플립 지속 시간을 출력하기로 선택했기 때문입니다. 파일을 원한다면 (''win.logOnFlip''을 사용하여) 접근법을 삽입하면됩니다. 플립 시간 : 예, ~ 0.0167이어야합니다. 컴퓨터가 모니터와 동기화되지 않을 수 있습니다. 컴퓨터에서 보여지는 프레임 지속 시간의 히스토그램을 제공하는 Coder -> Demos -> Timing -> timesByFrames.py를 실행 해보십시오. 약 0.01667로 좁혀 야합니다.그렇지 않은 경우 그래픽 카드 드라이버를 업그레이드하거나 다른 컴퓨터를 사용하십시오. –

+0

열쇠 등록 : 죄송합니다. 세 번의 반복 안에서 단 한번의 휴식이있었습니다. 응답을 업데이트하고 루핑을 계속할지 여부를 제어하는''keepLooping'' 변수를 만들었습니다. 매우 우아하지는 않지만 작동합니다 :-) –