見出し画像

TouchDesignerで心理学実験システム.005:実験結果を記録する


前回の記事の続きです。TouchDesignerで心理学実験・認知実験などを実装する方法をストループ課題を題材に説明していきます。

前回は、実験に対する反応をキーボードで取得し、結果表示を反映する部分を作りました。今回は、実験結果を記録し、他のソフトウエアで解析できるようにファイルに書き出しする部分を作ります。

画像1

今回取り扱う実験では1回のタスクにおいて、実験条件の情報と、実験参加者の反応結果の合わせて5つのデータを実験データとして記録します。

- letter : 視覚刺激の文字(実験条件)
- color : 視覚刺激の色(実験条件)
- answer : 実験参加者の回答(反応)
- isCorrect : 実験参加者の回答がOKかNGか(反応)
- reaction time : 実験参加者の回答時間(反応)

方針

前回のプログラムでは、それぞれの結果がTable DAT形式やCHOP形式になっているので、それらをまとめて、下記のようなテーブルデータにして、それらを実験タスク毎にデータを足していってファイルに保存する方針で作ります。

画像2

データの例:赤い文字(RED)で、「GREEN」と表示されているときに間違えて、「GREEN」と回答して、その際の反応時間は364.362 msecであった。

この形式のデータをタスク毎に追加し、下記のようにテーブルデータ作成・保存するような機能を作ります。

画像3

テーブルデータの整形

まず前回のプログラムに変更を加え、タスクのデータ用意します。
base_sequenceTableからは下記の情報がDATとして出力されています。
- letter : 視覚刺激の文字(実験条件)
- color : 視覚刺激の色(実験条件)

画像4

base_user_inputでは、
- answer : 実験参加者の回答(反応)
が1つのセルのテーブルデータとして出力されています。データの名前(answer)を加えたいので、merge CHOPで連結して、下記のようなテーブルデータにしておきます。

画像5


- base_user_inputからのreaction time : 実験参加者の回答時間(反応)
- base_feedbackからのis correct : 実験参加者の回答がOKかNGか(反応)はCHOPデータとして出力されているので、merge CHOPでまとめたあとに、Chop to DATでテーブルデータへ変換しておきます。

画像6

これらのテーブルデータをmerge DATでつなげて、1つのテーブルデータにまとめます。横方向に連結するには、merge DATのパラメータでHowAppend Columnsを指定します。

画像7

これで、記録したいデータの整形準備が完了しました。

テーブルデータのファイルへの保存

次に、このタスク毎にデータを記録する部分を作ります。ここでは、
- タスクの完了時(REST状態)になったら、上記で用意したデータ列を追加して保存
- Initが押されたときには、記録する
という挙動を実装します。

ここでも、空のbaseを用意してbase_dataSaverと名前をつけて中身を作っていきます。
3つのin(in DAT : テーブル入力用、in CHOP : 記録テーブル初期化用, in CHOP : テーブルデータ追加保存用)を用意して、それぞれ、nullオペレーターをつないでおきます。
さらに、記録用のテーブルデータとして、空のTableDATの名前をsaveTableとして作成しておきます。

画像8

2つのin CHOPをつないだそれぞれのnull CHOPChop Execute DATをリンクさせて、off to onのみをONにして、それぞれのスクリプトを下記のように書きます。

in_init側のChop Execute DAT

def onOffToOn(channel, sampleIndex, val, prev):
   #テーブル初期化
   op('saveTable').clear()
   
   #テーブルにnullの1行目(データのラベル部分のみを追加)
   saveTable = op('saveTable')
   newData = op('null1')
   saveTable.appendRow(newData.row(0))
   
   return

in_add側のChop Execute DAT

def onOffToOn(channel, sampleIndex, val, prev):

   #テーブルにnullの2行目(データ部分のみを追加)
   saveTable = op('saveTable')
   newData = op('null1')
   saveTable.appendRow(newData.row(1))
 
   #テーブルをtsv(タブ区切りテーブルファイル)として保存
   saveTable.save("saveTSV.tsv")   
   return

上の階層から、記録テーブル初期化用in CHOPに、Initボタンからトリガーを接続し、テーブルデータ追加in CHOPに新しいボタン(ここではaddBtnとする)をつなぎます。これで、Initを押すとテーブルが初期化され、Addボタンを押すとテーブルにデータが追加された上で、データが”saveTSV.tsv”に保存される。という挙動が実装できます。

画像9

このaddボタンを適切なタイミングで呼び出すようにします。ここでは、

- タスクの完了時(REST状態)になったら、上記で用意したデータ列を追加して保存

を想定しているので、すでに作成している、timer1_callbacksの中に「segmentが4のときに、addBtnが押される」というスクリプトを書いておきます。これでaddBtnを押したときとおなじ挙動をスクリプトがら実行できます。

def onSegmentEnter(timerOp, segment, interrupt):
       if(segment == 2):
               op('base_user_input/startTimer').run()                
        #追加
       if(segment == 4):
               op('addBtn').click()
       return

なお、base_tableSaveOperator Viewerに、./saveTable と記載しておくと、現在のテーブルが確認できて便利です。

大事な補足

なお、今回はファイル名をすべて’saveTSV.tsv’にしましたが、実運用では実験データファイルを他の場所にバックアップする前に次の実験を行ったために、ファイルを上書きしていまい、実験結果を消失するというような事故が起きかねません。そのためには、Initしたときの時刻を文字列にしたファイル名をつけてデータを記録するなどの工夫をしたほうが良いでしょう。

Githubのサンプルには、上記の挙動に加えて、データ保存フォルダと実験者のIDを指定して、ファイルを保存するコンポーネントも置いておきますので、参考にしてください。

画像10

import datetime

#スクリプトの例
now = datetime.datetime.now()
nowstr = now.strftime('%m-%d-%H-%M-%S')
nameIDStr = me.parent().par.Savefilenamepre.eval()
me.parent().par.Filename = nowstr + '-' + nameIDStr + '.tsv'

記録したデータの解析

これ以降は、実験結果がtsvになっているので、エクセルなり、Rなり、pythonなりで実験結果の解析をすることになります。ここではそのごく一部としてjupyter notebookでtsvを読み込むところまで紹介しておきます。

psychoTD-005.ipynb


import pandas as pd

filePath= 'saveTSV.tsv'
df_testData = pd.read_table(filePath, header=0)

画像11

pandas(Pythonのデータ解析用のライブラリ)を使うことで、tsvは一行で読み込めるので、この後実験結果の解析はpandasや必要に応じて、numpy等を使って解析することになります。

Githubはこちら

まとめ

これ以降はTouchDesignerの話ではなくなってしまうので、まずはここまでで一旦まとめておきます。ほかPerformモードで実行したときに画面が表示されるよう更新したサンプルはGithubに置いておきますので参考にしてみてください。

実際、今回はわかりやすさを重視した組み方なので、実際はもうすこしシンプルに組めたり、実運用のためには修正するべき点はありますことをご了承ください。

(追記)さらに、心理統計や実験計画などは例えば下記の資料等が大変参考になります。

(追記)TouchDesignerを深める場合には第1回目の記事に記載したチュートリアルや講義資料が参考になります。

第1回から、ストループ課題を題材にTouchDesignerで心理学実験・認知実験などを実装する方法を紹介してきました。どうしても、心理学実験・認知実験を作成するためのソフトウエアpsychopy等よりも、初見的には複雑に見えてしまいます。しかし、今回のプログラムは一度組んでしまえば、流用することができますので、この後TouchDesignerの得意とした様々な機器や処理の組み合わせで実験を簡単に用意することができるのはと思います。

例として、
- Kinect関連のオペレーターを用いて体の動きを用いた実験
https://derivative.ca/UserGuide/Kinect_CHOP

- VRの3Dトラッカーデータを取得したり、VR上での実験を作成する
https://docs.derivative.ca/OpenVR

BlobTrack TOPや、python経由でopenCVを用いて画像処理を組み合わせた実験
https://docs.derivative.ca/OpenCV

SerialDAT経由でArduinoを連携した実験
https://docs.derivative.ca/Arduino

OSCTouchIn / TouchOUTを使用して、複数マシン間を接続したシステムでの実験
http://ted-kanakubo.com/touchdesigner-jp/?p=120

Multitouch DATを使ったマルチタッチ・タッチスクリーンを使用した実験
https://docs.derivative.ca/Multi_Touch_In_DAT

等々、様々な機器やライブラリを統合して制作できるTouchDesignerの利点を活かして、実験を構成できるのではないでしょうか。

TouchDesignerで心理学実験システムシリーズは一旦これで終わりますが、気が向いたら他のトピックについても更新、追加したいと思います。

おまけ

本稿の筆者もTouchDesignerを作品制作や実験システムを行っています。

2020年6月現在では一時的に休止していますが、筆者が所属しているラボでもTouchDesignerを用いたシステム構築や心理学実験に関するResearch Assistant・Internを時折募集しています。

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