4. 繰り返し方法を工夫しよう―傾きの対比と同化

4.1. この章の実験の概要

この章では、傾きの対比の実験を題材として、実験を実施する度に条件ファイルを変更したり、繰り返しを多重に用いることによってやや複雑な計画の実験を実現したりする方法を学びます。

さっそく実験の内容を確認しましょう。 図4.1 に縞模様の刺激が描かれていますが、このように正弦波上に明るさが変化する縞模様の刺激をグレーティングと呼びます。今回の実験では、大小2個の円形のグレーティング刺激を実験に使用します。スクリーン中央に 図4.1 のように二つの刺激の中心が一致するように重ねます。グレーティングの模様がスクリーンの垂直方向にぴったり一致しているのを0度の方向として、大きいグレーティング刺激の向きを反時計回り、または時計回りに20度傾けます。そして小さいグレーティング刺激の向きを0度±5度の範囲で変化させて、小さいグレーティング刺激が0度より反時計回り、時計回りのどちらに傾いているかを実験参加者に判断させます。「小さい方のグレーティング刺激」などといちいち書くのは面倒ですので、小さい方のグレーティング刺激を「テスト刺激」、大きい方のグレーティング刺激を「コンテクスト刺激」と呼ぶことにしましょう。コンテクスト刺激がテスト刺激の傾きの知覚にどのような影響を与えるかを調べるのが実験の目的です。

実験の作成を始める前に刺激の大きさや反応方法などの詳細を決める必要がありますが、それ以前にこの刺激は前章までに学んだ知識で作成できそうにありません。PsychoPy Builderにはこの刺激を描くためにぴったりなGratingコンポーネントというコンポーネントが用意されているので、まずはその使い方を学びましょう。

_images/simul-contrast.png

図4.1 この章の実験。実験参加者は、テスト刺激の縞が垂直方向より反時計回りに傾いているか、時計回りに傾いているかを判断します。テスト刺激の周囲のコンテクスト刺激が判断に与える影響を明らかにするのが目的です。

4.2. Gratingコンポーネント

Gratingコンポーネントは、簡単に言うと縞模様の視覚刺激を描くためのコンポーネントです。視知覚の研究においては基本刺激とでも言うべき重要な刺激ですし、視覚認知の研究でもまた頻繁に用いられます。 [開始][終了] で刺激の有効な時間を指定したり、 [位置 [x, y] $] で位置を指定したりするなど、大半のプロパティはPolygonコンポーネントやTextコンポーネントと共通です。GratingコンポーネントがPolygonおよびTextコンポーネントと大きく異なるのは「テクスチャ」タブです。本節ではこのタブの項目について解説します( [テクスチャ] は複雑なので「 4.11.1:Gratingコンポーネントの [テクスチャ] プロパティについて 」で詳しく取り上げます)。

図4.2[マスク][位相 (周期に対する比) $][空間周波数 $] を変化させるとどのような刺激が提示されるかを示したものです。 [マスク] は刺激を切り抜くプロパティで、None、circle、gaussを指定することができます。空白にしておくと長方形の刺激が描画され、circleにすると楕円状に切り抜かれた刺激が描画されます。gaussは2次元Gauss関数の値に従ってコントラストが変調された縞模様を描きます。Gauss関数と言われてもピンと来ない方は正規分布の密度関数を思い出してください。正規分布の密度関数はGauss関数の一種であり、「Gauss関数の値に従ってコントラストが変調される」とはあの正規分布の密度関数のように中心から周辺に向かってなだらかに縞模様の薄れていくということです。正弦波を正規分布で変調した刺激はGaborパッチと呼ばれ、視知覚の実験では非常によく用いられます。

続いて [空間周波数 $] ですが、この値を大きくすると縞模様の密度が高くなります。より厳密な表現を用いれば、空間周波数(spatial frequency)とは一定の空間範囲に描かれる模様の繰り返し回数のことです。 [空間の単位] がcmとdegの場合には、刺激の幅1.0に含まれる縞模様の数に対応します。例えば刺激の幅が5.0cmで [空間周波数 $] が0.4ならば5.0×0.4=2.0、つまり刺激には2周期分の縞模様が描かれます( 図4.2 中段左)。 [空間の単位] がnormとheightの場合は、刺激に描かれる縞模様の数に直接対応します。つまり、 [空間周波数 $] が2.0なら刺激の幅の値がいくらであろうと常に2周期分の縞が描かれます。 [空間の単位] がpixの場合は複雑で、「 [空間周波数 $] の値×刺激の幅」の周期分の縞が描かれます。刺激の幅が200pixであれば、 [空間周波数 $] に0.01を指定すれば200×0.01で2周期分の縞になります。

[位相 (周期に対する比) $] は、縞模様の位相を指定するパラメータです。Gratingコンポーネントは初期設定では刺激の中心で明るさが最大になるように縞模様が描かれますが、位相を指定すると明るさが最大になる位置をずらすことができます。単位は1周期に対する比であり、0.5ずらすとちょうど明暗が反転します( 図4.2 下段の左端と右端)。

_images/grating-samples.png

図4.2 Gratingコンポーネントのプロパティのうち、 [マスク] (上段)、 [空間周波数 $] (中段)、 [位相 (周期に対する比) $] を変化させた例。いずれも [サイズ [w, h] $] は[5.0,5.0]で、 [単位] はcmを指定しています。

[テクスチャの解像度 $][補間] の効果を示したのが 図4.3 です。グレーティングコンポーネントを大きく拡大した図が描かれていますが、まず左側の二つをご覧ください。上が [テクスチャの解像度 $] が初期値の128、下が512の時の結果です。512の時の結果と比べると、128の時には刺激の境界も縞模様もぼけています。この「ぼけ」は、PsychoPyがグレーティングを描くときには内部で縞模様の画像データ(テクスチャ)を作成し、それを [サイズ [w, h] $] で指定された大きさに拡大するために生じます。 [テクスチャの解像度 $] はテクスチャの解像度を指定するプロパティで、128であれば128×128ピクセル、512であれば512×512ピクセルのテクスチャを生成します。値が高い方が大きく拡大した時のぼけが小さく済みますが、その代わりにPCのグラフィック描画機能に負担をかけます。小さなグレーティング刺激を多数描画する場合は、描画の負担を小さくするために [テクスチャの解像度 $] を低く設定するべきです。逆に今回の実験のように大きなグレーティング刺激をせいぜい2、3個描画する場合は高い値を設定するとよいでしょう。描画負担は使用しているPCのグラフィック性能に大きく依存しますので、グラフィック性能が高いPCであれば512に設定して多数のグレーティングを描いても問題は生じません。

[補間] は、グレーティングを拡大した時の補間方法を指定します。補間方法と言われてもピンと来ないかもしれませんが、 図4.3 右の二つの拡大図を比べてください。上は刺激の境界がぼやけていますが、下は境界がくっきりしていてカクカクしています。上が [補間] に「一次」を指定した例で、拡大した時に足りない色情報を周囲のピクセルと滑らかにつながるように補います。結果として、このように大きく拡大した場合はぼけが目立ってしまいます。一方「最近傍」を指定した場合は、元のテクスチャで最も近いピクセルの色を使用しますので、ぼけが生じない代わりにカクカクになってしまいます。滑らかにする方法は使用するPCのグラフィック機能によって異なりますので、自分が使用するPCでどちらの方がよい出力が得られるか各自で確認してください。

_images/resolution-interpolate.png

図4.3 Gratingコンポーネントの [テクスチャの解像度 $] および [補間] オプションの効果。

なお、「外観」タブの [前景色] はすでにTextコンポーネントで解説しましたが、Gratingコンポーネントの場合は縞模様を描画しますので少々複雑です。Gratingコンポーネントの色は、 [前景色] の値を [テクスチャ] で指定された波形に掛け算することによって決まります。つまり、 [テクスチャ] がsinで [前景色] の値が$[1,1,1]であれば-1から+1まで変化します。 [前景色] が$[0.5,0.5,0.5]であれば-0.5から+0.5まで変化します。$[-0.5,-0.5,-0.5]であれば、$[0.5,0.5,0.5]のときと同様に-0.5から+0.5まで変化しますが、負の値を掛け算していますので明暗が$[0.5,0.5,0.5]の時と反転します。 $[1,0,0]のようにRGB各成分の値が異なる場合も、それぞれの成分に波形が掛け算されます。$[1,0,0]の場合は$[-1,0,0]から$[1,0,0]まで変化するということです。 [前景色] にredやgreenといった色名が指定され場合は、PsychoPyの内部でこれらの色名をRGBに変換したうえで波形との掛け算が行われます。

ずいぶん脱線が長くなってしまいました。以上の解説を踏まえて、実験手続きの詳細を決定して実験を作成しましょう。

チェックリスト
  • Gratingコンポーネントを用いて長方形、または楕円形に縞模様が描かれた刺激を提示することができる。

  • Gratingコンポーネントで [空間の単位] がcm、deg、pix、norm、heightのいずれの場合においても、「幅xに対してy周期分の縞模様」を描けるように [空間周波数 $] の値を決定できる(x、yは正の数値)。

  • Gratingコンポーネントで描かれる縞模様を初期設定の状態からずらして描画することができる。

  • Gratingコンポーネントで描画処理の負担を軽くするためにテクスチャの解像度を下げることができる。

  • Gratingコンポーネントを大きく表示するときに画質を高めるためにテクスチャの解像度を上げることができる。

  • Gratingコンポーネントの色を指定したときに、何色の縞模様が描かれるのかをこたえることができる。

4.3. パラメータを決定しよう

それでは実験に用いる刺激のパラメータを決定しましょう。まず、テスト刺激とコンテクスト刺激の大きさと縞模様を 図4.4 のように設定することにします。 コンテクスト刺激の**[サイズ [w, h] $]** と [空間周波数 $] はそれぞれテスト刺激の3倍の値が設定されていて、同じ幅の縞が描かれるようにしてあります。いずれの刺激も [マスク] にcircleを指定して円形にします。 [前景色] はいずれも$[0.5, 0.5, 0.5]にしておきましょう。

_images/simul-param.png

図4.4 刺激のパラメータ

今回の実験で一番重要なパラメータはテスト刺激とコンテクスト刺激の方向です。すでに概要で述べたとおり、コンテクスト刺激には反時計回りに20度( [回転角度 $] =20)傾いたものと、時計回りに20度 [回転角度 $] =-20傾いたものの2種類を用います。それぞれのコンテクスト刺激に対して、-5度から1度間隔で5度までの計11種類のテスト刺激を組み合わせることにしましょう。それぞれの組み合わせに対して5回ずつ、無作為な順序に実験参加者に提示して、判断させることにします。試行数はコンテクスト刺激2種類×テスト刺激11種類×繰り返し5回=110試行です。

続いて 図4.5 に実験の手続きを示します。まず実験が始まったら、反応方法の教示をスクリーンに提示します。反応方法は、テスト刺激が時計回りに傾いているように見えたらカーソルキーの右、反時計回りに傾いているように見えたらカーソルキーの左を押すものとします。教示画面は各自で自由に作成していただいてよいと思いますが、刺激の例を示しながら反応するキーを示すとよいと思います。

教示画面でカーソルキーの左右いずれかを押すと実験が始まります。各試行はまず0.5秒間の空白のスクリーンから始まり、続けて刺激を提示します。実験参加者がカーソルキーの左右いずれかを押して反応するまで刺激を提示し続け、キーが押されたら直ちに次の試行に進みます。全試行終了すれば実験は終了です。 図4.5 では示していませんが、最後に「実験は終了しました」などのメッセージを表示するのも良いでしょう。

_images/simul-contrast-procedure.png

図4.5 実験の手続き

以上が手続きです。いよいよ実験を作成しますが、第3章 の実験と比べて使用するコンポーネントが多いので便利なテクニックを紹介しながら作業を進めましょう。

4.4. コンポーネントのコピーを活用して実験を作成しよう

では、Builderを開いて作業を開始します。実験はexp04a.psyexpというファイル名で保存するものとします。 まずtrialルーチンで以下の作業をしてください。

  • trialルーチン
    • Gratingコンポーネントを1つ配置し、以下の設定をする。
      • 「基本」タブの [名前] をtestStimとし、[開始] を「時刻 (秒)」で0.5に、 [終了] を空白にする

      • 「外観」タブの [前景色] を$[0.5,0.5,0.5]にする。

      • 「テクスチャ」タブの [マスク] をcircleに、 [空間周波数 $] を5.0にする。 [テクスチャの解像度 $] を512にする。

      • 「レイアウト」タブの [サイズ [w, h] $] を[0.2,0.2]にする。 [回転角度 $] をtestDirにして、「繰り返し毎に更新」にする。

これでテスト刺激が完成しました。続いてコンテキスト刺激を作成しなければいけませんが、[名前][サイズ [w, h] $][回転角度 $] 以外はテスト刺激と設定が同じです。このような場合には、コンポーネントのコピー機能を使用すると作業が楽になります。

_images/copy-component.png

図4.6 コンポーネントのコピー

図4.6 にコピーの手順を示します。まず図の左上のように、コピーしたいコンポーネントにマウスカーソルを重ねて右クリックし、メニューから「コピー」を選択します。その後、コピーを作成したいルーチンを表示します。今はtrialルーチンに作成したいので、そのままで結構です。ルーチンの余白部分でマウスを右クリックすると、「貼り付け(testStim)」というメニューが表示されます(図の中段左)。選択すると図の右上のようにコンポーネントの名前をたずねるダイアログが表示されます。Builderでは同一の名前を持つコンポーネントを複数作ることができませんので、新しい名前をつけなければいけません。名前を空欄のままOKをクリックするとtestStim_2のように元のコンポーネントの名前の後ろに数字を添えた名前となりますが、ここはcontextStimという名前にしておきましょう。新しい名前を入力してOKをクリックすれば、図の中段右のようにコンポーネントのコピーが完了します。

なお、「貼り付け」のメニューを表示するために右クリックをする際に、配置済みの他のコンポーネント上で右クリックすると、図の下段のように削除や順番変更といった項目の中に「上に貼り付け()」「下に貼り付け()」という項目が表示されます(括弧内はコピー中のコンポーネント名)。これを利用すると、たくさんのコンポーネントを配置しているルーチンで、他のコンポーネントの順番を考慮して狙った位置に貼り付けることができます。複雑な実験を作るときにはとても便利なテクニックなので覚えておきましょう。

コンポーネントのコピーが終了したら、contextStimのパラメータを変更します。

  • trialルーチン
    • contextStimの [サイズ [w, h] $] を[0.6,0.6]に、 [空間周波数 $] を15.0にする。 [回転角度 $] をcontextDirにする。

    • contextStimの上にtestStimが表示されるようにコンポーネントの順番を並び替える。

これで刺激は完成です。あとは参加者の反応を計測するためにKeyboardコンポーネントを置いておきましょう。

  • trialルーチン
    • Keyboardコンポーネントをひとつ配置し、「基本」タブの [開始] を「時刻 (秒)」で0.5に、 [終了] を空白にする。「データ」タブの [検出するキー $] を'left', 'right'にする。 [正答を記録] をチェックして、 [正答] に$correctAnsと入力する。

続いて実験の開始時に表示する教示画面を作成します。 図4.1 のように時計回り、反時計回りの刺激の実例を表示するとわかりやすいでしょう。 図4.1 のような画面を作成するとなると、Gratingコンポーネントを4個配置しなければいけません。たった今覚えたコンポーネントのコピーを使えば楽ができますが、前章で紹介したルーチンのコピーを使うとさらに手順を省略できます。 図4.7 のようにtrialルーチンをinstructionという名前でコピーしましょう。

_images/copy-routine.png

図4.7 ルーチンのコピー。

コピー元のtrialsルーチンと同じコンポーネントが含まれていること、コンポーネントの名前には(名前が重複しないように)番号が自動的につけられていることを確認してください。これでかなり作業を楽することができました。後はinstructionルーチンで以下のように作業してください。

  • instructionルーチン

    • フローの先頭に挿入する (忘れがちなので注意!)。

    • contextStim_2の [名前] をleft_largeとし、 [開始] を「時刻 (秒)」で0.0にする。 [位置 [x, y] $] を[-0.4, 0.0]とする。 [回転角度 $] を20.0にし、「更新しない」にする。

    • testStim_2の [名前] をleft_smallとし、 [位置 [x, y] $] を[-0.4, 0.0]とする。 [回転角度 $] を-10.0にし、「更新しない」にする。 [開始] を「時刻 (秒)」で0.0にする。

    • left_largeをコピーして [名前] をright_largeにする。 [位置 [x, y] $] を[0.4, 0.0]とする。

    • left_smallをコピーして [名前] をright_smallにする。 [位置 [x, y] $] を[0.4, 0.0]、 [回転角度 $] を10.0にする。

    • left_largeの上にleft_small、right_largeの上にright_smallが描かれるように各コンポーネントが並んでいることを確認する。

これで刺激は完成です。さらにテキストを追加しましょう。

  • instructionルーチン

    • Textコンポーネントを1個配置して、 [名前] をTextInstとする。
      • [文字列] に「カーソルキーの左右いずれかを押すと始まります」等のメッセージを入力する。画面の大きさに応じて文を短くするなり改行するなりするとよい。

      • [文字の高さ $] を0.04にする(各自のPC画面の大きさに応じて調節すると良い)。

      • [位置 [x, y] $] に[0, -0.4]と入力する。

    • TextInstをコピーしてtextCCの名前で貼り付ける。
      • [位置 [x, y] $] に[-0.4, -0.35]、 [文字列] に「反時計回り」と入力する。

    • TextInstをコピーしてtextCの名前で貼り付ける。
      • TextCの [位置 [x, y] $] に[0.4, -0.35]、 [文字列] に「時計回り」と入力する。

最後にKeyboardコンポーネントの調整をします。

  • instructionルーチン

    • 配置済みのKeyboardコンポーネント(標準ではkey_resp_2という名前になっているはず)の [記録] を「なし」にして、 [正答を記録] のチェックを外す。 [開始] を「時刻 (秒)」で0.0にする。

あとはループを挿入して、条件ファイルを作成しましょう。

  • trialsループ(作成する)

    • trialルーチンのみを繰り返すように挿入する。

    • [繰り返し回数 $] が5(初期値)になっていることを確認する。

    • [繰り返し条件] にexp04_20.xlsxと入力する。

  • exp04_20.xlsx (条件ファイル)

    • testDir、contextDir、correctAnsの3パラメータを設定する。

    • 実験手続きの説明を満たすようにtestDirに11種類の、contextDirに2種類の値を入力する。

    • すべての行のcorrectAnsにrightを入力する。

さて、これで各ブロックの手続きは完成です。最後の項目「すべての行のcorrectAnsにrightを入力する」に注目してください。テスト刺激が時計回りに傾いている時にカーソルキーの右を押すのですから、testDirが正の値の時のみrightが正答のはずです。しかし、この実験では敢えてすべての試行の正答をrightとした方が楽にデータ処理できるのです。次節でこの点について補足します。

4.5. 反応の記録方法を工夫しよう

この章の実験の手続きは、心理物理学的測定法のひとつである恒常法の手続きです。恒常法を用いた実験のデータ分析でよく用いられる方法が心理物理曲線の作成です。 図4.8 に今回の実験で得られる心理物理曲線の例を示します。横軸はテスト刺激の傾き、縦軸に時計回りに傾いているという反応の頻度です。物理的な刺激と反応が一致していれば、横軸の0度を境界として左側では縦軸の値は0.0、右側では1.0となりますが、グラフは0.0から1.0へなだらかに上昇する曲線を描いています。グラフが0.0から1.0へ変化する範囲が左右に寄っていれば、実験参加者の判断が全体的に偏っていたことがわかります。また、この範囲が左右に広がっていれば、反時計回りか時計回りかの判断が難しい課題であったことがわかります。

_images/psychometric-function.png

図4.8 心理物理曲線の例。横軸にテスト刺激の傾き、縦軸に時計回りに傾いているという反応の頻度をプロットしています。折れ線グラフはそれぞれコンテクスト刺激の傾きが-20度と20度の条件に対応しています。

心理物理曲線を描く時には、実験参加者の反応が刺激の物理的特性と一致していたか否かは関係がありません。ですから、PsychoPyで実験参加者の反応を記録する時に、両者が一致していたかを記録しても何の役にも立ちません。前節のように、「right(=時計回りに傾いている)」という反応をしていたかを記録するようにしておけば、正答率の値がそのまま心理物理曲線の縦軸の値として利用できます。分析の手間が大幅に省けます。便利なテクニックですので、ぜひ覚えておいてください。

チェックリスト
  • 恒常法の実験において、正答率がそのまま心理物理曲線の縦軸の値として使用できるように正答を定義できる。

4.6. 実験情報ダイアログで条件ファイルを指定しよう

この節からがいよいよこの章の本題です。exp04a.psyexpではコンテクスト刺激の傾きとして-20度と20度を用いましたが、これらの条件に加えて-70度と70度傾いた条件のデータも取りたいとします。さらに、-20度/20度のコンテクストを使う試行と、-70度/70度のコンテクスト刺激を使う試行はそれぞれまとめて実施することにします。つまり、実験を二つのブロックに分割し、一方のブロックではコンテクスト刺激はすべて-20度/20度、もう一方のブロックではすべて-70度/70度とします。

コンテクスト刺激の種類で実験をブロック化せず、全部無作為な順番で実施するのであれば、条件ファイルに-70度/70度の条件に対応する行を追加するだけで対応できます。しかし、ブロック化するのであればこの方法は使えません。一番簡単な方法は、-70度/70度条件に対応する新たな条件ファイル(exp04_70.xlsx)を作り、このexp04_70.xlsxを条件ファイルとして使用する実験をもう一個作成するというものでしょう。まあ別にこの方法で乗り切っても構わないのですが、せっかくですのでひとつの実験ファイルで二つの条件ファイルを切り替える方法を習得しましょう。

_images/add-expinfo-fields.png

図4.9 実験情報ダイアログに項目を追加する手順。

使用する条件ファイル名をはじめ、実験のパラメータを実験開始時に指定するには実験情報ダイアログを使用します。初期状態では実験情報ダイアログにはsessionとparticipantの2項目しかありませんが、実験設定ダイアログから項目を追加することができます。 図4.9 は実験情報ダイアログに項目を追加する手順を示しています。exp04a.psyexpを開いて設定ダイアログを開いてみましょう。 [実験情報ダイアログを表示] のチェックを外している人はチェックしなおしておいてください。初期状態では実験設定ダイアログの [実験情報ダイアログ] にsessionとparticipantという項目が表示されていて、その右側に[+]、[-]が書かれたボタンが表示されています。[+]ボタンを押すと、その行の下に新しい行が追加されます。[-]を押すと、その行が削除されます。participantとsessionのどちらの行の下に追加しても、動作には違いがありません。

では、[+]を押して新しい行を追加して、「フィールド」にcndFileName、「初期値」にexp04_.xlxsと入力してください。入力したら実験を実行してみましょう。すると、 図4.9 の一番下の図のように実験情報ダイアログにcndFileNameという項目が追加されていて、exp04_.xlsxという文字列が最初から入力されているはずです。「フィールド」は実験情報ダイアログに表示する項目の名前、「初期値」はその項目に最初から入力されている文字列(初期値)に対応しています。participantのように「初期値」が空白の場合は、実験情報ダイアログでも空白になります。

実験情報ダイアログの項目名は、条件ファイルのパラメータ名と異なり、空白文字(スペース)や#、$といった記号を含むことができます。日本語の文字列でも指定できますが、表示が乱れることがありますのであまりお勧めしません。項目が実験情報ダイアログに表示される順番は、従来のバージョンではPsychoPyが自動的に決定されてしまって自由に指定できなかったのですが、現在のバージョンでは実験設定ダイアログで入力した通りの順番となります(2020.2.6で確認)。

実験情報ダイアログで入力した値は、条件ファイルに記述されたパラメータのようにBuilder内部で参照することができます。ただし、条件ファイルの場合とは書き方が異なっていて、expInfo['パラメータ名']という具合に書きます。この書き方の意味を理解するためにはPythonの文法を理解する必要がありますので、ここではとりあえず「こう書くんだ」と覚えておいてください。

それでは、実験情報ダイアログを利用して「ひとつの実験ファイルで二つの条件ファイルを切り替える」という問題に挑戦してみましょう。先ほどのcndFileNameという項目をexp04a.psyexpに追加した状態から作業を続けます。trialsループのプロパティを開いて、 [繰り返し条件] を$expInfo['cndFileName']に変更してください。 [繰り返し条件] には$が付いていないので、条件ファイルからパラメータを読む時と同様に$を付けないといけない点に注意してください( 図4.10 )。これで、実験実行時に実験情報ダイアログのcndFileNameの項目に入力された名前の条件ファイルを開くようになりました。実験をexp04b.psyexpの名前で保存しておきます。

_images/set-conditionfile-from-expinfo.png

図4.10 [繰り返し条件] に実験情報ダイアログの項目を指定します。先頭の$と項目名の前後の'を忘れないように注意してください。

続いて、Builderをいったん離れてコンテクスト刺激が-70度/70度傾いている条件の条件ファイルを作成しましょう。これは単にexp04_20.xlsxを開いて、contextDirの列の-20を-70に、20を70に書き換えて別名で保存するだけです。ここではexp04_70.xlsxという名前で保存しておきましょう。元のexp04_20.xlsxも引き続き使用しますので、上書き保存しないように注意してください。exp04_20.xlsx、exp04_70.xlsxの両方ともexp04b.psyexpと同じフォルダに置いてください。

以上で実行時に条件ファイルを切り替えられる実験の作成は終了です。PsychoPyに戻ってexp04b.psyexpを実行しましょう。実験情報ダイアログのcndFileNameにexp04_20.xlsxと入力すれば、-20度/20度、exp04_70.xlsxと入力すれば-70度/70度の条件の試行が始まります。最初からexp04_.xlsxという文字列が入力されているので、_の後に20または70と入力するだけでよいはずです。ぜひ、-70度/70度の実験を最後まで行って、-20度/20度の実験結果と比較してみてください。

チェックリスト
  • 実験情報ダイアログの項目を追加、削除することができる。

  • 実験情報ダイアログの項目の初期値を設定することができる。

  • 実験情報ダイアログの項目名から、その値を利用するためのBuilder内における表記に変換することができる。

  • 条件ファイル名を実験情報ダイアログの項目から取り出してループのプロパティに設定することができる。

4.7. 実験情報ダイアログで項目を選択できるようにしよう

前節で実験情報ダイアログを使って条件ファイルを切り替えできるようになりましたが、実際に使用してみた感想はいかがでしょうか? 確かに便利なのですが、条件ファイル名を入力するのが面倒ではないでしょうか。今回の例のように入力する内容がいくつかの決まったパターンしかない場合、いちいちキーボードから入力するのではなくドロップダウンメニューから選択できるようにする機能がBuilderには用意されています。

_images/expinfo-dropdown-menu.png

図4.11 実験情報ダイアログの項目を選択式にする

さっそく使ってみましょう。exp04b.psyexpを開いて設定ダイアログを開き、先ほど編集した [実験情報ダイアログ] のcndFileNameの項目を以下のように変更します。[ ]や' '、,などの記号に注意して入力してください。

['exp04_20.xlsx', 'exp04_70.xlsx']

入力できたら実験を実行してみましょう。 図4.11 に示すように、cndFileNameの項目がexp04_20.xlsxとexp04_70.xlsxのどちらかを選べるようになりました。この形式をドロップダウンメニューと呼びます。これで条件ファイルの切り替えが少し楽になったのではないでしょうか。

さて、動作を確認したところで、この機能を使うためのポイントを確認しておきましょう。 [実験情報ダイアログ] の項目の「初期値」が以下の条件を満たすとき、その項目はドロップダウンメニューと解釈されます(上級者向け:厳密には「初期値」に記入されている内容がPythonのlistオブジェクトとして解釈可能であることが条件)。

  1. メニューの各項目が ' ' または " " で囲まれていて、かつ , で区切られている。

  2. 1.の内容が [] で囲まれている。 [ の前や ] の後ろには文字があってはいけない。

1番目の条件は、Keyboardコンポーネントの [検出するキー $] で'left', 'right'という具合にキー名を ' ' または " " で囲ってカンマ区切りで並べたとの同じように書くということです。いろいろな値を追加して練習してみてください。

チェックリスト
  • 実験情報ダイアログの項目をドロップダウンメニューにできる。

4.8. 多重繰り返しを活用しよう

今回の実験のようにある要因(ここではコンテクスト刺激の傾き角度)で試行がブロック化されている場合、一人の実験参加者が両方のブロックへ参加する実験計画を用いることもあれば(参加者内計画)、一人の実験参加者はいずれか一方のブロックしか参加しない計画を用いることもあります(参加者間計画)。前節の実験情報ダイアログで実験条件を指定する方法は、参加者内計画でも参加者間計画でも柔軟に対応できますが、実験者がいちいち条件ファイル名を設定しないといけないので面倒です。面倒なだけならいいのですが、条件ファイル名を間違えてしまうかもしれません。参加者内計画の場合、一方の条件を実行したら次のブロックは必ず残りの一方の条件です。Builderに自動的に二つの条件ファイルを読み込んで実行させるように、exp04b.psyexpを改造してみましょう。

_images/set-conditionfile-for-nested-loop.png

図4.12 読み込む条件ファイルを変更しながら繰り返すことによって、-20度/20度と-70度/70度の条件を連続して実行する実験を作成します。

図4.12 に改造の方針を示します。exp04b.psyexpを使う場合は、 図4.12 の上の図のように、条件ファイル名を変更しながら2回exp04b.psyexpを実行しなければいけません。これは、今まで作ってきた実験における「刺激の色や傾きを変更しながら刺激提示を繰り返す」という作業とよく似ています。ということは、刺激の色や傾きを条件ファイルから読み込んで代入しながら繰り返すことができたように、 図4.12 下のようにすれば条件ファイルの名前を別の条件ファイルから読み込んで代入しながら繰り返すことができるはずです。

_images/add-outer-loop.png

図4.13 多重に繰り返しを挿入します。

さっそく改造してみましょう。Builderでexp04b.psyexpを開いて、念のため別名で保存しておきましょう(exp04c.psyexpとします)。そして、 図4.13 のようにblocksというループを挿入してください。Blocksループの始点はinstructionルーチンの後ろでも構わないのですが、後ろに挿入してしまうと1回目のtrialsループが終わった直後に2回目のtrialsループが始まってしまうため、実験参加者に対する予告なしにいきなり-20度/20度条件と-70度/70度条件が切り替わってしまいます。instructionルーチンをbolorksループに含むようにしておけば、条件が切り替わる前に教示画面が再び表示されますので、切り替わりがわかりやすいでしょう。さらにわかりやすくするためには、trialルーチンの前にこれから始まる条件を表示するためのルーチンを挿入すると良いでしょうが、これは練習問題とします。bocksループのプロパティでは、 [繰り返し回数 $] を1に設定して、 [繰り返し条件] にexp04blocks.xlsxと入力しておきます。 [Loopの種類] はrandomのままでよいでしょう。これで新しいループの追加は完了です。

続いて、blocksループのための条件ファイル、exp04blocks.xlsxを用意しましょう。この条件ファイルでは 図4.14 左上のようにexp04_20.xlsxとexp04_70.xlsxの二つの値を持つcndFileNameというパラメータを設定します。続いてtrialsループでcndFileNameに基づいて条件ファイルを読み込むように設定するために、trialsループの [繰り返し条件] を$cndFileNameに変更します( 図4.14 右上)。実験情報ダイアログで条件ファイル名を入力する必要はなくなったので、実験設定ダイアログを開いて実験情報ダイアログからcndFileNameの行を削除しておきましょう( 図4.14 下)。

_images/set-conditionfile-automatically.png

図4.14 blocksループを使って条件ファイルを切り替えるようにtrialsループなどを修正します。

以上で改造は終了です。exp04c.psyexpを実行して、自動的に-20度/20度条件と-70度/70度条件が続けて実行されることを確認してください。blocksループの [Loopの種類] をrandomのままにしたので、-20度/20度条件と-70度/70度条件のどちらが先に実行されるかは毎回無作為に決定される点に注意してください。

なお、ループのプロパティには [試行を繰り返す] という項目がありますが、この項目は多重繰り返しを使ったときのデータ保存形式に関係があります。詳しくは「 4.11.2:ループの [試行を繰り返す] プロパティについて 」を参照してください。

チェックリスト
  • 多重繰り返しを挿入できる。

  • 多重繰り返しの内側のループで条件ファイル名を外側のループの条件ファイルから読み込んで設定することができる。

4.9. 複雑な実験を作るときにちょっと役立つテクニック

本章の実験とは関係ありませんが、多重繰り返しを応用すると、複雑な実験の一部分だけを実行することができます。複雑な実験を作成する際に知っておくと便利なので、ここで紹介しておきましょう。 図4.15 上段は教示などをを含む複雑なフローを持つ実験の例です。この実験の終盤にあるtestというルーチンに問題があって、少し修正したとしましょう。修正がうまくいったか実際に実行して確認したいところですが、testルーチンにたどり着くまでにはpracticesやtrialsといったループをすべて実行する必要があります。これらのループ内でおこなわれる課題によっては、数十分かかってしまうかも知れません。

_images/zero-loop.png

図4.15 繰り返し0回のループを挿入すると、ループで囲んだ部分の実行を飛ばすことができます。

こういったときに役に立つのが「 [繰り返し回数 $] 0回のループ」です。 図4.15 下段のように、testループより前の部分をすっぽり包むループを追加して [繰り返し回数 $] 0を設定しましょう。 [Loopの種類] などはどれでも構いませんし、 [繰り返し条件] も空欄で構いません。 [名前] もなんでも結構です。これで実験を実行すると、0回のループで囲まれた部分は「0回実行する=全く実行されない」ので、すぐにtestルーチンが実行されます。確認が済んだら、0回のループを削除するだけで元の状態に戻ります。

なお、 図4.15 の例で「trialsループで囲まれている部分だけを飛ばしたい」場合は、新たにループを追加しなくてもtrailsループの [繰り返し回数] を0にするだけでOKです。0回ループは複雑な実験を作成するときに非常に便利なテクニックなので、覚えておいてください。

関連テクニックとして、「あるルーチンに含まれる一部のコンポーネントだけ実行したくない」場合についても触れておきます。これはちょっと具体例を挙げるのが難しいのですが、「実験を実行してみるとエラーで停止してしまうのだけれど、どのコンポーネントが原因なのかわからない」場合などに便利です。各コンポーネントのプロパティダイアログには「テスト」というタブがありますが、このタブにある [コンポーネントの無効化] という項目をチェックすると、あたかもこのコンポーネントが配置されていないかのように全く実行されなくなります( 図4.16 )。原因不明のエラーで困っている時に、あるコンポーネントを無効化して実行するとエラーが発生しないのなら、きっとそのコンポーネントがエラーに関与しているはずです。中級者から上級者向けの機能かも知れませんが、こんな機能があるということを頭の片隅に置いておくと役に立つかもしれません。

_images/disable-component.png

図4.16 「テスト」タブの [コンポーネントの無効化] をチェックするとコンポーネントを一時的に無効化できます。

4.10. 練習問題:条件ファイルを使う順番を指定できるようにしよう

exp04c.psyexpではblocksループの [Loopの種類] にrandomを指定したので、実行の度にどちらの条件が先に実行されるかが無作為に変化します。ところが、この章の実験のようにブロックの順序を実験参加者間で変更する場合は、各順番に同数の参加者が割り振られるようにバランスを取ることがよく行われます。つまり、実験参加者が20人いるとしたら、10人は-20度/20度条件を先に、残り10人は-70度/70度条件を先に行うようにするということです。実行順序を無作為に決定してしまうと、9人と11人といった具合にバランスが崩れてしまう可能性があります。確実にバランスが取れるようにするには、-20度/20度条件が先になるように書かれた条件ファイルと、-70度/70度条件が先になるように書かれた条件ファイルを用意して、どちらの条件ファイルを使用するかを実験情報ダイアログで指定するという方法があります。本章のまとめとして、exp04c.psyexpを改造してこの方法で実験参加者数のバランスを取ることができる実験を作成してください。さらに加えて、trialsループを開始する前に、これから行われるブロックについての情報を表示するルーチンも追加してください。

_images/practice-select-condition-order.png

図4.17 練習問題で作成する実験の流れ

文章だけではわかりにくいので、 図4.17 をご覧ください。まず、exp04c.psyexpをベースとして、実験情報ダイアログにブロックの順番を指定するための項目を設けてください。そしてこの項目に例えばexp04blocks.xlsxを指定したら-20度/20度条件から始まって、exp04blocks2.xlsxを指定したら-70度/70度条件から始まるようにしてください。そして、教示画面を表示した後に、これから始まるブロックが-20度/20度条件と-70度/70度条件のどちらなのかを示す画面を表示してください。最初のブロックが終了した後は、教示画面ではなくこれから始まるブロックを示す画面に戻るようにしてください。以上が練習問題です。

ちょっとこれだけでは難しいという方のために、 図4.18 にヒントを示します。条件ファイルでブロックの順番を指定するためのポイントは、blocksループの [Loopの種類] の値です。ブロックの順番を指定するための条件ファイルは、 図4.18 下のようなファイルと、2行目と3行目を入れ替えたファイルを用意すればよいでしょう。なぜこれでうまくいくかわからない方は、第3章[Loopの種類] の解説を読み直してください。健闘を祈ります。

_images/practice-select-condition-order-hint.png

図4.18 練習問題のヒント。

4.11. この章のトピックス

4.11.1. Gratingコンポーネントの [テクスチャ] プロパティについて

視知覚の研究でグレーティングと言うと一般的に正弦波状に明るさが変調された刺激を指すのですが、PsychoPyのGratingコンポーネントはより一般的な「同一のパターンが2次元に繰り返される刺激」を描く機能を持っています。 図4.19[テクスチャ] に指定できる値を示しています。sinは正弦波、sawは鋸波、sqrは矩形波、triは三角波を描きます。Noneを指定すると、 [前景色] で指定された色で塗りつぶします。これらの波は1次元、すなわち一方向にのみ明るさが変化しますが、sinXsinでは垂直方向と水平方向に変化する2次元の波を描きます。同様にsqrXsqr、gauss、radRamp、raisedCosといった波形を指定できます。垂直方向と水平方向の空間周波数を別々に指定するためには、 [空間周波数 $] に刺激の大きさを指定する時と同様の記法を用います。 図4.20 左上はsqrXsqrの波形に [空間周波数 $] として[2,3]、[3,2]を指定した時の出力を示しています(単位はheight)。図からわかるように、第1の値が水平方向、第2の値が垂直方向に対応しています。

_images/grating-texture-sample1.png

図4.19 Gratingコンポーネントの [テクスチャ] として指定できる値。これらの他に画像ファイル名を指定することができます。いずれも [空間の単位] はheightで [空間周波数 $] は3.0を指定しています。

_images/grating-texture-sample2.png

図4.20 [空間周波数 $] に2つの値を指定する例と(上段の左側2つ)、 [テクスチャ] に画像ファイルを指定する例(上段の右側2つ)、 [マスク] に画像ファイルを指定する例(下段)。

[テクスチャ] および [マスク] には、画像ファイルを指定することもできます。 図4.20 右上は、PsychoPyのアイコン画像を保存したicon.pngというファイルを [テクスチャ] に指定した例を示しています。 [テクスチャの解像度 $] の値が2の冪乗(64や128など)であったように、PsychoPy内部ではテクスチャは縦横の解像度が2の冪乗の正方形でなければいけません。それ以外の解像度の画像を指定するとPsychoPyが内部的に拡大縮小を行いますので、正確さを期する場合は最初から2の冪乗の正方形の画像ファイルを作成することが大切です。 [マスク] にモノクロの画像ファイルを指定すると、 [マスク] 画像のピクセルの明るさがテクスチャの透明度となります。文章では説明しにくいので 図4.20 下段をご覧ください。mask1.png、mask2.pngという2種類のモノクロ画像をマスクとして用意しました。 [マスク] にmask1.pngを、 [テクスチャ] に先ほどのicon.pngを指定した例が 図4.20 下段左から3番目です。mask1.pngの黒色の部分が透明になって、背景の灰色が見えています。透明になっていることがわかりやすいように、白色と青色のPolygonコンポーネントを背後に配置しています。 図4.20 下段の右端は、 [テクスチャ] をsinにして、 [マスク] にmask2.pngを指定した例を示しています。mask2.pngが黒色から白色に向かって滑らかに変化しているので、縞模様が滑らかに透明から不透明へと変化しています。

4.11.2. ループの [試行を繰り返す] プロパティについて

ループの [試行を繰り返す] プロパティは、実験設定ダイアログで「xlsx形式のデータを保存」または「CSV形式のデータを保存(summaries)」をチェックして出力されるデータファイルの形式を設定するものです。

「xlsx形式のデータを保存」をチェックしてexp04c.psyexpを実行することによって作成されるxlsxファイルの例を 図4.21 に示します。ただし、 [試行を繰り返す] はチェックしていないものとします。

_images/nestedloop-xlsx-output-not-checked.png

図4.21 多重ループを用いた実験によって作成されるxlsx記録ファイルの例( [試行を繰り返す] をチェックしない場合)。

表4.1 多重ループによって作成されるxlsx記録ファイルのシート名 (内側のループ名がtrialsの場合)

trials

最初に実行されたtrialsループ

trials1

2回目に実行されたtrialsループ

trialsN (Nは自然数)

N+1回目に実行されたtrialsループ

trialsとtrials1というシートが作成されていますが、これは 表4.1 に示すようにそれぞれtrialsループの1回目、2回目に対応しています。シートの内容を確認すると、 図4.21 の例の場合はtrialシートのcontextDirの列が20または-20なので、第1ブロックは-20度/20度条件であったことがわかります。同様に、trial1シートのcontextDirの列を確認すると大2ブロックは-70度/70度条件であったことがわかります。

今回の実験ではblocksループによるtrialsループの繰り返しは2回のみでしたが、仮にblocksループによる繰り返しが20回に及ぶ場合はtrials、trials1、…、trials19と20枚もシートが作成されます。あまりシート数が多くなるとExcel上での作業が大変ですので、繰り返し回数が多くなる場合は実験を分割することも検討すべきです。

続いてblocksループの [試行を繰り返す] をチェックした場合に出力されるxlsx記録ファイルの例を 図4.22 に示します。trials、trials1というシートができるのはチェックを外した場合と同じですが、それに加えてblocksというシートが含まれています。このシートには、blocksループの繰り返しにおいて、exp04blocks.xlsxから読み込んだ条件のどの行が使われたかが記録されています。別にこのシートが存在していてはいけないわけではないのですが、trials、trials1のシートから読み取ることができる情報しか含まれていないので、無駄なシートといえます。今回のようにblocksループが一番外側のループだったら1枚余分なシートが増えるだけですが、さらに外側にループが組まれている実験では何枚も無駄なシートが作成されてしまいます。このような場合は [試行を繰り返す] のチェックを外してシート数を抑えることが有効です。

_images/nestedloop-xlsx-output-checked.png

図4.22 多重ループを用いた実験によって作成されるxlsx記録ファイルの例( [試行を繰り返す] をチェックした場合)。

なお、外側のループ内にループに含まれないルーチンが存在していて、そのルーチンでの刺激や反応を記録する必要がある場合は、 [試行を繰り返す] のチェックを外してはいけません。具体的には、 図4.23 のtestルーチンのようなものがblocksループ内にある場合です。このような場合に blocksループの [試行を繰り返す] のチェックを外してしまうと、testルーチンで用いられた条件や、testルーチンにおける参加者の反応などが記録されません。チェックを外していいか自信がない場合、xlsx記録ファイルのシート数を気にしないのであれば [試行を繰り返す] のチェックはつけたままにしておくというのも一つの手だと思います。

_images/nestedloop-non-looped-routine.png

図4.23 [試行を繰り返す] のチェックを外してはいけない例