0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PsychoPyで円を描くように刺激を動かす。複数回のキー押し。キーを押したときの刺激の位置を記録。

Last updated at Posted at 2019-11-14

この記事では、PsychoPyを使って、円を描くように刺激を動かす方法を解説します。
実験の参加者は、刺激が動いていあいだ、何度でもキーを押せることにします。
そして、キーを押したときの刺激の位置を記録します。
刺激は5秒間呈示されると消えるものとします。

今回のプログラムは、Builderだけでは作れない(作りにくい)例です。Codeコンポーネントを使いますが、それでもまだ作りにくく、Coderを使用します。(注: CodeコンポーネントとCoderは別物です)

刺激(今回の例では青い正方形とします)は、注視点を中心とした円周上を動きます。
stim_circle1.jpg

この例では、簡単な三角関数を使います。以下の図の意味が分からないときは、三角関数についてまずは復習してください。
半径がrの円を正方形が移動するとき、正方形の座標は (x, y) = (r * cos(θ), r * sin(θ)) となります。

stim_circle2.jpg

以下の図を参考にして、code, polygon, keyboardの3つのコンポーネントを配置してください。
スクリーンショット 2019-11-14 10.58.23.png

polygonコンポーネント

変更箇所は次の通りです。
スクリーンショット 2019-11-14 11.02.31.png

色を青にするには「高度」タブを開きます。手動で、$[-1, -1, 1] と打ち込んでもよいですが、数字が書いてある場所を右クリックすると色を選択することができます。
スクリーンショット 2019-11-14 11.02.35.png

keyboardコンポーネント

変更箇所は次の通りです。

スクリーンショット 2019-11-14 11.06.27.png

今回の実験では、何回もキー入力ができるので「Routineを終了」のチェックを外し、記録を「全てのキー」とします。

Codeコンポーネント

「フレーム毎」のタブを開き、次のコードを入力します。

radius = 5 # deg
angle_deg_sec = 45 # deg/sec
current_deg = angle_deg_sec * t
polygon.pos = (radius * cos(deg2rad(current_deg)), radius * sin(deg2rad(current_deg)))

円の半径(radius)を視角5度(degree)としています。刺激が動く速度(angle_deg_sec)は45度/秒です。つまり、1秒で45度進みます。

tは、PsychoPyが準備している変数で、Routineの開始時からの時間(秒)になります。

距離(今回の例では移動角度) = 速度 x 時間

という関係を思い出してくださいね。
polygon.pos =の行で、polygonの座標を決定しています。
以上の作業をフレーム毎、つまり、画面が書き換わるタイミングごとに実行されるようにします。

ここまでの作業はBuilderで可能です。プログラムを実行してみてください。青い正方形が円上を移動するはずです。

Coderを使って、キーが押されたときの刺激の位置を記録しよう

まずはBuilderで実行して、刺激が移動しているあいだに、3回ほどスペースキーを押してみてください。
その後、dataフォルダにある csvファイルを開いてください。
スクリーンショット 2019-11-14 11.22.40.png

上の図のようにスペースキーが3回押されて、それぞれの反応時間が記録されていることが分かります。
これらのデータと同じように、スペースキーが押されたときの刺激の位置を記録してみましょう。
刺激の位置は(x, y)の座標ですが、説明を簡略化するため、角度(θ)を記録することにします。角度が分かれば、(x, y)の座標も計算可能です。

Coderを開くには、下の図の赤枠をクリックします。
スクリーンショット 2019-11-14 10.58.23.png

重要な注意点です。 Coderで変更したあとにBuilderで変更を加えると、Coderの変更が上書きされてしまうため、まずはファイルを別名で保存するようにしましょう。

key_resp.keyskey_resp.rtのように記録したいので、これらが記述されているところを見つけ出します。なお、ここからの作業は、Coderよりも、Visual Studio CodeAtomなどのテキストエディタを使うほうが便利だと思います。

# update component parameters for each repeat
key_resp.keys = []
key_resp.rt = []

この箇所を見つけてください。これはデータを記録するためのリストを作るためのコードです。初期化とも言います。
角度のデータを保存するため、初期化のコードを追加してみましょう。

# update component parameters for each repeat
key_resp.keys = []
key_resp.rt = []
key_resp.angle = []

次に、以下のコードを探してください。

key_resp.keys.append(theseKeys.name)  # storing all keys
key_resp.rt.append(theseKeys.rt)

これはキーを押すたびに実行される箇所で、どのキーが押されたか、そしてその反応時間を保存しています。ここで角度のデータも同じように保存しましょう。
保存したい角度のデータは、current_degになります。どうしてcurrent_degを保存するのか分からないときは、上で説明したCodeコンポーネントのところを読み返してみてください。

次のように追記します。注意点として、インデントを上の2行とそろえてください。Pythonではインデントが重要な意味を持ちます。

key_resp.keys.append(theseKeys.name)  # storing all keys
key_resp.rt.append(theseKeys.rt)
key_resp.angle.append(current_deg)

最後に、以下のコードを探してください。

thisExp.addData('key_resp.keys',key_resp.keys)
if key_resp.keys != None:  # we had a response
    thisExp.addData('key_resp.rt', key_resp.rt)

Routineの終了時に、すべてのキーの情報と、その反応時間をCSVファイルに保存しています。2行目にif文がありますが、これは「キーが一度でも押されていたら」という意味です。一度もキーが押されないこともあり得るのでこのような書き方になっています。

一度でもキーが押されていたら、反応時間と一緒に、角度が保存されるようにしましょう。

thisExp.addData('key_resp.keys',key_resp.keys)
if key_resp.keys != None:  # we had a response
    thisExp.addData('key_resp.rt', key_resp.rt)
    thisExp.addData('key_resp.angle', key_resp.angle)

以上で変更は終わりです。

実行するときは、Builderの実行ボタンではなく、Coderの実行ボタンを押します。
角度のデータが保存されていることを確認してください。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?