見出し画像

TouchDesignerで心理学実験システム.001:画面遷移を作る

0. はじめに

心理学実験、心理物理実験、認知実験やユーザースタディなどを行う研究活動において、あるタスクを所定の条件を変えながら繰り返し行い、実験参加者の行動データを記録して解析するような実験プログラムが必要になります。

そのプログラムを何で実装するか?は切実な問題です。既にチームが所属する機関で共通して使われている実装環境を用いる事が多いとは思いますし、実験プログラミング作成のためのすばらしい環境やフレームワークは数多くあります。(psychoPy, Psychtoolbox, OpenSesame..」)

実験に用いたい機材と実験プログラムを統合したり、プログラムの試作と修正を最速で進めたいとき、TouchDesignerで実験プログラム(システム)を実装したら今の所良かったので、現時点でいくつかまとめてみたいと思います。すでに、心理実験制作のデファクトスタンダードともいえるpsychoPyに敬意を込めて、勝手にpsychoTDと名付けています.

TouchDesigner

もともとは、実験プログラム実装用ではありませんが、1. リアルタイムグラフィック、インタラクティブインスタレーションなど、映像や音声のための高い時間制御要件に対応し、2. グラフィックレンダリング、信号処理、ネットワーク、(VRやKinectセンサ等も)外部機器制御への対応も早く、3. 内部においてpythonスクリプトの実行やC++のカスタムモジュールを実装することも可能であり高い拡張性があります。4. そして(慣れると)ノートベースでのプログラム作成の恩恵により試行錯誤が爆速で可能になります。この4点が大変魅力であり、実験環境構築としては未だ未開拓ではあるとは思いますが、大きなポテンシャルを持っていると思います。

 また、使用できる映像サイズが1280pixまでの制限や、ごく一部の機能制限を除いてはTouchDesignerは無料で使用ですることができます。その点でも、大変ありがたいです。

TouchDesigner自体の入門は、多くの素晴らしい講義資料・チュートリアルがあるので、そちらを見てからこの記事を見ると良いかもしれません。なので、その点では、この記事はTouchDesignerチョットワカル人が何故か心理実験等を作りたくなった場合のニッチにな資料になります。

今シリーズ記事では、分かりやすい視覚刺激課題を実際にTouchDesignerで組むのと、その内容をベースにした筆者が作成したモジュールの紹介をします。書いていたら長くなりそうだったので、シリーズにして(モチベーションが維持できる限り)不定期で更新していきます。

本記事は以前作成した記事のアップデート・拡充版になります。
https://qiita.com/shks/items/6ebdbbfdc64d8ae20897

題材:ストループ課題の制作

それでは、シンプルで体感しやすい事例としてストループ課題の認知実験のための視覚刺激を実際に制作していきます。ストループ効果(ストループ課題)とは、文字の意味と文字色のように同時に目にするふたつの情報が干渉しあう現象です。

画像2

例として、「赤・青・黄」の文字がそれぞれの文字の意味と一致した色で表示されている場合には問題なくすばやく(音読)読めます。一方で、「赤・青・黄」が文字の意味と、一致しない色で表示されている場合には脳内で情報が干渉して、素早く音読することができなくなります。こちらに、体験できるデモがあります。

このストループ効果を題材にして、文字と文字色が一致している場合と、不一致である場合の色判断の反応速度はどのにように変わるかを調べるTouchDesignerを用いて構築してみます。

実験パラダイム
実験では刺激(視覚・聴覚・触覚 etc..)とそれに対する被検者反応を取得して記録する。というループを繰り返し行い、統計的な解析のためのデータを取得します。その実験のループにあたるシーケンスは「実験パラダイム」と呼ばれ、タスクの説明や刺激の提示順序・時間やユーザー回答の時間など、綿密に設計することが求められます。ある現象に関する実験シーケンスを考える際に、例えばgoogle image searchで「*** paradigm」と検索すると雰囲気を掴む事ができますし、先行研究のパラダイム調査に役立ちます。
例えば、”Stroop paradigm" と検索すると下記のような結果です。

画像3

ストループ課題のパラダイムも各種ありますが、ここではpsychopyのdemoにあるパラダイムを参考に一部変更した以下のようなタスクを想定します。

画像4

実験タスクの流れ
- 準備画面、fixation cross (注視点)をそれぞれ1秒、0.5秒表示
- 視覚刺激が表示される(赤色で「GREEN」や、青色で「RED」と書かれていたりする)
- 視覚刺激が表示されている間に、キーボード入力で回答する。色が赤なら1,緑なら2、青ならば3
- 正解・不正解のフィードバックを表示
- 休憩
の繰りかえし

1. 画面遷移の作成

プログラム実装の観点から見ると、ある決まったシーケンスで画面遷移を設計することになります。それでは、実際に作成していきましょう。
まず、画面(テクスチャ)を生成するためには、TOP(Texture Operator)を使用します。ここでは、インストラクション画面、Fixation画面も含めて、textTOPで作成します。
後ほど、実験条件に応じて内容が変わる画面も仮に作成しておきます。

画像5

該当するTOPを作成したら、それらをswitchTOPにつなぎます。switchTOPindexパラメータを指定することで接続したTOPのどれを選択するかが変わるので、このindexパラメータを0, 1, 2,,,と指定時間毎に変化させることで画面遷移を実現できます。

画像6

次に、0, 1, 2,,とindex パラメータを経過時間に応じて変化させます。

それぞれの画面状態の時間は異なるので、そのようなタイマーを実現するために、timerCHOPsegment機能を用います。tableDATを用意、図のようなシーケンスの開始時間(start) と画面保持時間(duration)、そしてその状態の名前を記載します。(状態の名前は後で分かりやすいようにするため)
その用意したtableDATのオブジェクト名(ここでは、timer_table)を、timerCHOPSegment DATに入れることで、タイマーが複数セグメント(ここでは各画面遷移)を持ったタイマーになります。segmentが指定されている場合、timerCHOPのparameterでstartを押すとsegment 0から開始し、最後のセグメントまで順番にそれぞれのセグメントで指定されたタイミングで次のセグメントへ切り替わっていきます。

画像7

ここで、timerCHOPparameterのOutputsを図のようにすると、現在のセグメント、セグメント内の進行状況、全体の経過時間などをtimer CHOPの出力として観察することができます。

(補足)
TimerCHOPの右下にある下矢印のボタンをクリックすることで、callbackのスクリプトを記述することができます。例えば、「segment 4に入ったら観測データを記録して、ファイルに保存する」「あるセグメントに入ったら、外部装置にシリアルを送る、OSCメッセージを送信する」等、シーケンスの進行に応じた挙動をスクリプトで記述できます。これは後々使います。
def onSegmentEnter(timerOp, segment, interrupt):
   print('TimerCHOP Entering segment', segment)
   return
細かい話ですが、後述の selectCHOPで取り出した、segment 値の変化をexcuteChop DATvalueChangeでトリガーするように実装することもできますが、実行順序はTimerCHOPのcallbackのほうが先で、かつ環境によっては、2-8ms程度の時間が生じてしまいます。 よって、segmentに入ったら直ちに実行させたい関数や機能はTimerCHOPcallbackから直接実行したほうが良いです。

このtimerCHOPが出力したsegment値をつかって先程用意したswitchTOPの選択index更新すれば良いので、timerCHOPからの出力をselect CHOPにつないで’segment’のみにします。オペレーターの名前segment_indexにしておきます。

画像8

switchTOPindexを、segment_indexオペレーターのsegmentの値への参照にします。これで、timerCHOPの[start]を押すと指定した時間長さごとに画面遷移する部分を作る事ができました。

画像9

ここで、プログラム的に同じシーケンスを止めることなく延々とループする場合には、timerCHOPOn DoneRe-Startにしておくと、最後のsegmentが終了したタイミングで、最初のsegmentから自動的に連続再生されます。実験1ループ(トライアル)毎に開始タイミングを指定したい場合には、On DoneDo nothingにしておいて、timer CHOP パラメータのStartを後ほど別のスクリプトからトリガーすることにします。

画像10

ここまでで、(テスト刺激映像は固定映像で、OK/NGのフィードバックも被検者入力を反映しませんが)画面遷移の雛形ができました。

Progress Indicator

なお筆者はトライアルの進行状況を視覚的に確認しながら実験を観察したい事が多く、シーケンスの可視化のためもモジュールを作って使っています。テーブル情報と進行状況のchopデータをつなぐとシーケンスが表示されるようになっています。このままセットで使えます。

画像11

ソースコードはコチラ

次は、仮に置いておいた視覚刺激のパターンを作る部分を制作していきます。

Qiitaとnoteどちらが書きやすいかテストも込めてQiitaでも同じ内容記載してみます。


この記事が気に入ったらサポートをしてみませんか?