[PYTHON] Erhalten Sie negative Reaktionszeit mit psychopy.event.getKeys ()

Einführung

In diesem Artikel werde ich, wie der Titel schon sagt, bei Verwendung von "psychopy.event.getKeys ()" einführen, dass Sie eine negative Reaktionszeit erhalten können, wenn ** Bedingungen erfüllt sind. Grundsätzlich ist die negative Reaktionszeit nicht das, was der Ersteller des Experiments wünscht. Ich hoffe, dass sie hilfreich ist, wenn Sie sie erhalten und sagen: "Ist es ein Fehler? Ich bin in Schwierigkeiten." Manchmal). Der Punkt ist, vergessen Sie nicht event.clearEvents (), wenn Sie keine negative Reaktionszeit wollen.

** (Aktualisiert 20191119) ** [win.flip () scheint wichtig zu sein](#winflip scheint auch wichtig zu sein 20191119 hinzugefügt) wurde hinzugefügt. Anscheinend ist es nicht einfach, eine negative Reaktionszeit zu bekommen.

Methode

Führen Sie nach dem Drücken der Taste ".reset ()" auf dem "core.Clock" -Objekt aus, um die Reaktionszeit zu messen (z. B. den Variablennamen "stopwatch") und "psychopoy.event.getKeys (timeStamped = stopwatch)". Sie erhalten eine negative Reaktionszeit. Schauen wir uns den Code an, der tatsächlich eine negative Reaktionszeit ergibt.

Codebeispiel 1

get-neg-rt_1.py


from psychopy import visual, core, event

win = visual.Window()
stopwatch = core.Clock()
stim = visual.TextStim(win)
l_letter = ['a','b','c']

for letter in l_letter:
    stim.setText(letter)
    stim.draw()
    win.flip()
    core.wait(2) #Geben Sie die Taste ein, während Sie den Stimulus präsentieren
    stopwatch.reset() #Uhr nach Tastendruck zurücksetzen
    resp = event.getKeys(timeStamped=stopwatch) #Tastatureingabe
    print(resp)

win.close()

#Ausgabebeispiel
# [['space', -0.17376430198783055], ['space', -0.16929624899057671]]
# [['space', -0.19804733199998736]]
# [['space', -0.19725568499416113]]

Wenn Sie core.wait () undstopwatch.reset ()umkehren, erhalten Sie keine negative Reaktionszeit (selbst wenn es sich um einen positiven Wert handelt, können Sie die Reaktion immer noch nicht richtig erhalten. So erhalten Sie sie richtig Wird in [diesem Artikel] vorgestellt (https://qiita.com/snishym/items/f343f24ca8c77ba1fb4a)). Ich glaube jedoch nicht, dass jemand solchen Code schreibt. Es sollte die Uhr vor oder unmittelbar nach der Präsentation des Stimulus zurücksetzen (dh vor core.wait ()). Das folgende Beispiel ist jedoch ein beschämender Fehler, den ich tatsächlich gemacht habe.

Codebeispiel 2

get-neg-rt_2.py


from psychopy import visual, core, event

win = visual.Window()
stopwatch = core.Clock()
stim = visual.TextStim(win)
l_letter = ['a','b','c']

for letter in l_letter:
    stim.setText(letter)
    resp = []
    # event.clearEvents()
    stopwatch.reset()
    for n_frame in range(120): # 120f(2 Sekunden bei einer Bildwiederholfrequenz von 60 Hz)
        stim.draw()
        win.flip()
        if not resp:
            resp = event.getKeys(timeStamped=stopwatch) #Tastatureingabe

    print(resp)

win.close()

#Ausgabebeispiel
# [['space', 0.8996025759843178]]
# [['space', -0.34911786299198866]]
# [['space', -1.4165731929824688], ['space', -0.6160959279804956]]

Dieser Code erhält wie der obige Code die Antwort, während der Stimulus 2 Sekunden lang präsentiert wird. Der Unterschied besteht darin, dass wir nur die erste Reaktion jedes Versuchs erfassen wollen. Wenn "resp = []" gesetzt ist, bevor der Stimulus präsentiert wird, und "resp" eine leere Liste bleibt, ist "nicht resp" "True" und "event.getKeys ()" wird ausgeführt. Wenn es eine Schlüsseleingabe gibt, wird "[[key, rt]]" "resp" zugewiesen, und in den nachfolgenden Schleifen wird "not resp" zu "False" und die Schlüsseleingabe wird nicht verarbeitet. Im Gegensatz zu Beispiel 1 wird stopwatch.reset () außerdem vor dem präsentierten Block ausgeführt, sodass es auf den ersten Blick kein Problem zu geben scheint (ich dachte, ich wäre nicht da). Wenn Sie die Taste jedoch mehrmals drücken, während Sie einen bestimmten Stimulus präsentieren, erhalten Sie eine negative Reaktionszeit, wie im Ausgabebeispiel gezeigt. Die Lösung besteht darin, "event.clearEvents ()" zu aktivieren, was im Code auskommentiert ist.

Warum passiert das?

Ich habe erst kürzlich bemerkt, dass (zumindest) Psychopy einen "Ereignispuffer" hat, der jeder Tasteneingabe (oder Maus-, Joystick-) Eingabe entspricht, und es scheint, dass die Eingabe dort gehalten wird. Dies geschieht auch, wenn core.wait () ausgeführt wird. Wenn Sie event.getKeys () ausführen, werden alle Eingaben abgerufen, die zu diesem Zeitpunkt im ** Tastatur ** -Bufffer gespeichert waren (offizielle Referenz (https://www.psychopy.org/api/event.html)). # psychopy.event.getKeys)). Und wenn "timeStamped" angegeben ist, beträgt die Differenz zwischen der im Puffer aufgezeichneten Zeit (Unix-Zeit) und der vom angegebenen "core.Clock" -Objekt ("Stoppuhr" im Codebeispiel) angegebenen Zeit " Es gibt den mit dem Timing von .reset () `neu berechneten Wert als 0 zurück. Dies gibt die Reaktionszeit. Aus diesen Gründen wird eine negative Reaktionszeit erhalten, wenn ".reset ()" zwischen der Schlüsseleingabe und "getKeys ()" wie in Beispiel 1 angeordnet ist, und wie in Beispiel 2 wird eine erhalten. Selbst wenn es so aussieht, als ob nur die Reaktion des Auges herausgenommen wird, werden die zweite und die nachfolgenden Reaktionen desselben Versuchs im Puffer gehalten, sodass sie von getKeys () der nächsten Schleife verarbeitet werden. Werden. Der Tastenanschlag selbst steht vor ".reset ()", daher ist die zurückgegebene Zeit negativ. Das in Beispiel 2 als Lösung dargestellte "clearEvents ()" entfernt die im Puffer enthaltene Eingabe. Wenn Sie dies kurz vor Beginn jedes Versuchs tun, haben die zweiten und nachfolgenden Reaktionen, die im vorherigen Versuch aufgetreten sind, keinen Einfluss auf den nächsten Versuch. Selbst wenn "getKeys ()" ausgeführt wird, verschwindet die bis zu diesem Punkt eingegebene Taste aus dem Puffer.

In Beispiel 1 könnten Sie einfach "core.wait ()" und ".reset ()" sortieren, aber das bedeutet nicht, dass es immer sicher ist, "core.wait ()" zu verwenden. Wie im folgenden Code gezeigt, erhalten Sie eine negative Reaktionszeit, wenn Sie zwischen den Versuchen ein Leerzeichen setzen und eine Taste mit diesem Leerzeichen drücken. Wiederum verhindert das Ausführen von "event.clearEvents ()" vor "core.wait ()" (oder "win.flip ()") negative Reaktionszeiten. In jedem Fall ist es wichtig, sich an event.clearEvents () zu erinnern.

get-neg-rt_3.py


from psychopy import visual, core, event

win = visual.Window()
stopwatch = core.Clock()
stim = visual.TextStim(win)
l_letter = ['a','b','c']

for letter in l_letter:
    # event.clearEvents()
    stim.setText(letter)
    stim.draw()
    win.flip()
    stopwatch.reset() #Uhr nach Tastendruck zurücksetzen
    core.wait(2) #Geben Sie die Taste ein, während Sie den Stimulus präsentieren
    resp = event.getKeys(timeStamped=stopwatch) #Tastatureingabe
    print(resp)
    # ITI
    win.flip()
    core.wait(1) #Wenn Sie hier die Taste drücken, erhalten Sie einen negativen Wert

win.close()

Übrigens ist event.waitKeys () so eingestellt, dass event.clearEvents () zur Laufzeit standardmäßig intern ausgeführt wird, sodass keine Angabe erforderlich ist ([Offizielle Referenz](https: /). /www.psychopy.org/api/event.html#psychopy.event.waitKeys)).

win.flip () scheint ebenfalls wichtig zu sein (20191119 postscript)

Nachdem ich verschiedene Dinge ausprobiert hatte, stellte ich fest, dass die Geschichte nicht so einfach war und dass "win.flip ()" auch die Berechnung der Reaktionszeit mit "getKeys ()" beeinflusste. Wenn Sie den folgenden Code ausführen, beträgt die Antwortzeit des Tastendrucks, der von der vorherigen Schleife übertragen wurde, weniger als 10 ms.

get-neg-rt_4.py


from psychopy import visual, core, event

win = visual.Window()
stopwatch = core.Clock()
stim = visual.TextStim(win)
l_letter = ['a','b','c']

for letter in l_letter:
    stim.setText(letter)
    resp = []
    # event.clearEvents()
    stopwatch.reset()
    stim.draw()
    win.flip()
    while stopwatch.getTime() < 2:
        if not resp:
            resp = event.getKeys(timeStamped=stopwatch) #Tastatureingabe

    print(resp)

win.close()

#Ausgabebeispiel
# [['down', 0.5086547629907727]]
# [['down', 0.0033315849723294377], ['down', 0.0070590279647149146]]
# [['down', 0.004310511983931065], ['down', 0.009222752996720374]]

Durch Eingabe der Schleife von "while stopwatch.getTime () <2" nach Präsentation des Stimulus wird der Vorgang des Erfassens der Reaktionszeit für 2 Sekunden fortgesetzt. Der Stimulus bleibt sichtbar, da der Bildschirm erst aktualisiert wird, wenn die "while" -Schleife endet und der nächste "win.flip ()" ausgeführt wird. Es sollte das gleiche sein wie im zweiten Beispiel, außer dass "stimul.draw ()" und "win.flip ()" nicht wiederholt werden, aber ich kann keine negative Reaktionszeit mehr erhalten. Als Reaktionszeit scheint es jedoch nicht angemessen zu sein. Wenn Sie "draw ()" und "flip ()" in die while-Schleife einfügen, erhalten Sie eine negative Reaktionszeit wie im zweiten Beispiel. Anscheinend wird das Timing der Schlüsseleingabe durch "win.flip ()" [^ 1] zurückgesetzt, und in diesem Beispiel wird "getKeys ()" unmittelbar danach ausgeführt, sodass ein Wert von etwa 10 ms erhalten wird. Scheint in der Lage zu sein. Der folgende Code ist die Grundlage für die Annahme, dass das Eingabe-Timing "neu" eingestellt ist, dh das Eingabe-Timing vor "win.flip ()" beibehalten wird.

[^ 1]: Es ist jedoch wahrscheinlich auf den Wert festgelegt, der durch das erste win.flip () aktualisiert wurde. Im zweiten Beispiel wird "win.flip ()" mit verbleibender Schlüsseleingabe im Ereignispuffer viele Male ausgeführt, aber eine solche negative Reaktionszeit wird erhalten. Ich bin mir nicht sicher, ob diese Vermutung richtig ist, da ich sie nicht überprüft habe.

get-multi-rt_4.py


from psychopy import visual, core, event

win = visual.Window()
stopwatch = core.Clock()
stim = visual.TextStim(win)
l_letter = ['a','b','c']

for letter in l_letter:
    stim.setText(letter)
    resp = []
    stopwatch.reset()
    stim.draw()
    win.flip()
    while stopwatch.getTime() < 2:
        resp += event.getKeys(timeStamped=stopwatch) #Tastatureingabe

    print(resp)

win.close()

In diesem Code wird wie im vorherigen Beispiel die Tasteneingabe 2 Sekunden lang erkannt, ohne den Bildschirm zu aktualisieren. Der Unterschied besteht jedoch darin, dass in einem Versuch mehrere Reaktionen akzeptiert werden. In diesem Fall wurde "win.flip ()" 2 Sekunden lang nicht ausgeführt, aber das Timing jeder Tasteneingabe scheint korrekt gemessen zu werden. Ich bin mir nicht sicher, warum die Verwendung von "win.flip ()" die im "Ereignispuffer" enthaltenen Informationen aktualisiert und dass die Aktualisierung wahrscheinlich nur einmal erfolgt. Wenn jemand es weiß, würde ich es begrüßen, wenn Sie mich unterrichten könnten. In jedem Fall empfehlen wir die Verwendung von "event.clearEvents ()", es sei denn, Sie benötigen ausdrücklich eine negative Reaktionszeit.

abschließend

In diesem Artikel haben wir den Fall vorgestellt, in dem psychopy.event.getKeys () eine negative Reaktionszeit zurückgibt. Es scheint, dass die negative Reaktionszeit ein Fehler war, der aus meinem Stolz und Stolz geboren wurde, dass es in Ordnung wäre, weil ich versucht habe, nur die erste Reaktion mit dem bedingten Ausdruck "wenn nicht resp." Zu erhalten. Ich habe das Gefühl, dass der Ereignispuffer überall erklärt wurde (Professor Togawas Buch?), Aber ich denke, es gab keinen Artikel, der ihn aus der Perspektive eines solchen Fehlers erklärte. In einigen Experimenten können auch negative Reaktionszeiten nützlich sein. In diesem Fall konsultieren Sie bitte Ihr eigenes experimentelles Verfahren und behandeln Sie win.flip () gut. event.clearEvents () ist das grundlegende "ki", um eine Reaktion zu erhalten. Vergiss nicht, wenn du dich daran gewöhnt hast.

Recommended Posts

Erhalten Sie negative Reaktionszeit mit psychopy.event.getKeys ()
Holen Sie sich die Standardausgabe in Echtzeit mit dem Python-Unterprozess
Beginnen Sie mit MicroPython
Holen Sie sich Tweets mit Tweepy
Holen Sie sich ein Date mit Python
Beginnen Sie mit Mezzanine
Python Aktuelle Zeit abrufen
Holen Sie sich YouTube Live-Chat-Felder in Echtzeit mit API
Holen Sie sich den Ländercode mit Python
Holen Sie sich die Tabelle dynamisch mit sqlalchemy
Fangen Sie mit Django an! ~ Tutorial ⑤ ~
Holen Sie sich Twitter-Timeline mit Python
Standardeingabe mit Zeitlimit
Beginnen Sie mit influxDB + Grafana
Holen Sie sich Youtube-Daten mit Python
Informationen erhalten Sie mit zabbix api
Fangen Sie mit Django an! ~ Tutorial ④ ~
Fangen Sie mit Django an! ~ Tutorial ⑥ ~
Messung der Ausführungszeit mit Python With
Holen Sie sich die Thread-ID mit Python
Beginnen Sie mit Python! ~ ② Grammatik ~
Holen Sie sich Bildfunktionen mit OpenCV
Holen Sie sich Lager mit Python
Holen Sie sich das Home-Verzeichnis mit Python
Holen Sie sich Tastaturereignis mit Python
Zeitsynchronisation (Windows) mit Python
Holen Sie sich Alembic-Informationen mit Python
Holen Sie sich ein Ranking mit Rakuten API