- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2023-01-06T14:37:31+09:00","default:riseki","riseki")
**&color(#000080){ランダムな位置に刺激を提示したい}; [#y99f7a04]
認知心理学の実験課題では,試行ごとに刺激をランダムに変化させたいことがあります。
たとえば,視覚探索課題で試行ごとに刺激の位置をランダムに変えたいなどです。
このような場合,PsychoPyのGUI機能だけでプログラムを作るのには限界があります。
しかし,だからといって全面的にプログラム言語を使って(Coderを使って)プログラムを書き直す必要はありません。
GUI機能(Builder)のCodeコンポーネントを使って,ごく部分的にコードを書けばよいのです。
**&color(#000080){サンプルの概要}; [#pf663e10]
まず,サンプルのファイルをダウンロードしてください。
下のアイコンを右クリックして「対象をファイルに保存」を選んでください。
または,保存のポップアップから「ファイルを保存する」を選んでください。
プログラムはPsychoPy v.1.83.04で作成しています。
&ref(RandomPosition.psyexp);
今回のサンプルは,3つのドット刺激を1秒間提示するだけというごく簡単なものです。
それぞれPolygonコンポーネントで円を描画しています。
各ドットはサンプルを動かしたときに区別しやすいよう別々の色に設定しています。
&ref(disp1.png,,,40%);
&ref(disp2.png,,,40%);
trialルーチンの一番上にCodeコンポーネントを設定しています。
このCodeコンポーネントの中に刺激の位置をランダムに決めるためのコードを書くことにします。
今回は,試行ごとに位置を変えたいので“Routine開始時”のタブを開いて,ここにコードを書きます。
このサンプルでは,trialという名前のルーチンがそのまま実験試行1回分に対応しているので,試行ごとに変える=Routine開始のたびに変えるとなるからです。
&ref(disp3.png,,,60%);
このサンプルでは,最初にrandomというライブラリを読み込んでいます。
これは,あとで使う乱数化のための関数を呼び出せるようにする操作です。
なお,この”import random”はRoutine開始のたびでなく実験の際に一回だけ呼び出せば十分なので,この行は”実験開始時”のタブに記述するほうが適切です。
しかし,コードが複数のタブにまたがると見づらいのでこのサンプルでは同じタブに記述しています。
実際に実験プログラムを作成する際にはそれぞれのタブに書き分けてください。
今回は,5×5の仮想グリッド(格子)を作って各交点を中心に刺激を配置することにしました。
画面上に完全にランダムに刺激を配置しようとすると,刺激同士が重なったり,刺激の一部が画面からはみ出してしまうということが起こります。
いったんランダムに配置してから逐一刺激の重なりがないか,はみ出しているものがないかチェックするという方法も考えられますが,これはなかなか面倒です。
仮想グリッドを使えば,この点を簡単に処理できます。
気をつけるのは,隣り合った刺激が重ならないように十分に距離を空けること,四隅に刺激を配置したときにもはみ出さないようにグリッド自体の配置も設定することです。
加えて,今回のサンプルでは,ジッターもかけています。
前述のようにグリッドの交点上にのみ刺激を配置した場合,縦や横,あるいは斜めにきれいに刺激が整列して見えることがあるため,実験の目的によっては好ましくない効果が生じることがあります(縦一列にまとまった刺激群はばらばらに提示された刺激群よりも処理しやすいなど)。
そこで,いったんグリッド上の交点に配置を決めた後で,その位置を縦横にランダムに少しずつずらすという方法によってこれに対処することがあります(よく“ジッターをかける”と呼ばれる操作です)。
今回のサンプルでは,縦軸と横軸の両方向に-0.4~0.4の範囲でランダムに位置をずらす設定にしました(単位はcmです)。
ジッターが必要ない場合はこのパラメータを0にすればグリッドの交点ぴったりの位置にのみ刺激が提示されるように変更できます。
サンプルのプログラムを実行すると,ランダムに位置を変えながら3つのドットが1秒間提示されるという試行が5回くり返されます。
**&color(#000080){カスタマイズの方針}; [#b38db011]
自分の求める実験プログラムにこの方法を適用するには,サンプルのコードを適宜書き換える必要があるでしょう。
グリッドは画面中央を中心として配置されています。
xsize,ysizeの値を変えることで5×5以外の任意のサイズにグリッドを変更できます。
また,unitx,unityの値でグリッド間の間隔を設定しています。
このあたりは実際に提示したい刺激のサイズと使用するモニターの解像度やサイズとの関係をもとに調整する必要があるでしょう。
ジッターのサイズ(JitSizeで設定)についても同様です。
stimListには,刺激として提示するコンポーネントの変数名をすべて挙げてください。
今回のサンプルでは,各Polygonコンポーネントの名前を並べています(文字変数を宣言しているのではなく,すでに存在する変数を参照しているので,''で囲んでいないことに注意してください)。
もちろん,Polygonコンポーネント以外を使うこともできます。
Textコンポーネントを使って文字列を提示したり,imageコンポーネントを使ってひとつひとつの刺激を画像にすることもできるでしょう(ただし,画像を使う場合については,[[PsychoPyで試行ごとにランダムな位置に刺激提示2]]も参考にしてください)。
outListは,上のようにして決めたランダムな配置を出力ファイルに記録する際に使う変数です。
他と重複のない変数名であれば何でもかまいませんが,どの刺激の位置を記録したものか,あとでわかるような名前をつけるのがよいと思います。
今回のサンプルでは,刺激の個数を3個に限定しています。
しかし,条件によって刺激の個数を変えたい場合もあるでしょう。
そのような場合には,予め最大数の刺激を用意しておき,不要な刺激は画面内に表示させないという方法があります。
たとえば,刺激が4個の条件と8個の条件をランダムに実施したいとします。
このような場合,ルーチンにはまず8個の刺激を設定しておきます。
そして,どの刺激についても提示位置を画面外に設定します(32 x 20のディスプレイなのに[40, 30]と指定するなど)。
一方,実際の刺激の提示位置はCodeコンポーネントで決定するわけですが,このとき,条件によっていくつの刺激に新しい提示位置を設定するかを操作すればよいわけです。
サンプルではstimListに挙がっているすべての刺激に位置の設定を行うことになっていますが,この部分を条件によって変更すれば,一部の刺激は仮想グリッド内の位置に提示されますが,残りは画面外のまま,すなわち,見かけ上は提示されない状態にできると思います。
2つめのfor文のlen(stimList)の部分を条件によってif文で切り替えるか,stimList及びoutList自体をif文によって切り替えるといった形にするといった方法があるでしょう。
今回のサンプルを応用すれば,刺激の提示位置だけでなく,色や形などを何通りかの候補から試行ごとにランダムに選んで決めるといったこともできるはずです。
いろいろと工夫する際の参考になればと思います。