Chapter 13

【サイモン課題】刺激の提示位置の変更

snishiyama
snishiyama
2021.09.24に更新

はじめに

本章では,サイモン課題の作成を通して,刺激の提示位置の変更方法について解説します。

サイモン課題とは

サイモン効果は,求められた反応と位置とが競合する場合に,競合しない場合と比べて反応が遅くなる効果です。例えば,左手のキーでの反応が求められた刺激が右側に提示されると,その刺激が左側に提示される場合と比べて反応が遅くなります。図付きの概要が十河先生のサイトにありました。詳しくは文献等を参照してください。

http://www.s12600.net/psy/python/ppb/html/chapter03.html

本シリーズのサイモン課題では,「L」「R」という 2 つの文字を刺激として用いることにします。参加者はLの提示に対して左手人差し指でfキーを,Rの提示に対して右手人差し指でjキーを押すこととします。

土台となるコードは以下の折りたたんでいる部分を参照してください。以降の説明の簡単のため,timeline_variables等は使っておらず,LRが 1 回ずつ提示されるコードを作成しています。サンプルコードを見る前にぜひ一度ご自身で作成してみてください。

刺激の提示位置が変更されないコード
simon.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="../jspsych-6.3.1/jspsych.js"></script>
    <script src="../jspsych-6.3.1/plugins/jspsych-html-keyboard-response.js"></script>
    <link rel="stylesheet" href="../jspsych-6.3.1/css/jspsych.css"></link>
  </head>
  <body></body>
  <script>
    var trial_L = {
      type: 'html-keyboard-response',
      stimulus: 'L',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    var trial_R = {
      type: 'html-keyboard-response',
      stimulus: 'R',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    jsPsych.init({
      timeline: [trial_L, trial_R],
    });
  </script>
</html>

刺激の提示位置を変更する

さて,さっそく刺激の提示位置を変更していきます。第 5 章でフォントサイズを変更した時と同じように,stimulusに html タグ利用します。フォントサイズの変更には<p>タグを使用しましたが,位置の変更には<div>タグを使用します。

var trial_L = {
  type: 'html-keyboard-response',
  stimulus: '<div style="position: absolute; left: 40%; top: 50%">L</div>',
  choices: ['f', 'j'],
  post_trial_gap: 500,
};

var trial_R = {
  type: 'html-keyboard-response',
  stimulus: '<div style="position: absolute; right: 40%; top: 50%">R</div>',
  choices: ['f', 'j'],
  post_trial_gap: 500,
};

いい感じに刺激を左右に提示することができたのではないでしょうか。フォントサイズの変更と同じように,タグのstyleを指定しています。指定している項目はそれぞれ以下のとおりです。

  • position: absolute: 絶対位置を用いる。ここでの絶対位置とは,ブラウザの上下左右の端を 0 とした位置のこと。
  • left: 40%: 左から 40%の位置(右端が 100%)
  • top: 50%: 上から 50%の位置(下端が 100%)

left, top以外にも,right, bottomも使用することができます。上の例でも,R を提示する際にはright: 40%と指定しています。また,位置の単位には%以外にもピクセルpxを用いることができます。基本的には%でいいでしょう。

positionについては他にもstatic, relative, fixedと指定することができます。詳しい説明は,google 先生に任せることにしますが,文字列の位置を変更する場合に限ってはabsoluteを使えばいいでしょう。

<div>タグについても google 先生を参照してください。

style を別で作っておく

位置の変更は<div>タグを使いつつ,style=...で指定すればよいことがわかりました。しかし,位置を指定したせいでstimulus:の部分がかなり読みにくくなってしまいました。例えば,どこが実際に提示したい刺激なのかパッとわかりにくいです。位置の指定のために,style の部分に様々な設定項目が並んでいるのが読みにくさ一因のような気がします。なんとか位置に関する設定を<div>タグの外側に書くことができれば,もう少し読みやすくなりそうです。

HTML では,<div style="...">で指定していたstyleを,<head>タグの部分で,名前をつけて用意しておくことができます。具体的には,以下のようにします。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="../jspsych-6.3.1/jspsych.js"></script>
    <script src="../jspsych-6.3.1/plugins/jspsych-html-keyboard-response.js"></script>
    <link rel="stylesheet" href="../jspsych-6.3.1/css/jspsych.css"></link>
    <style>
      .text_left {
        position: absolute;
        left: 40%;
        top: 50%;
      }
      .text_right {
        position: absolute;
        right: 40%;
        top: 50%;
      }
    </style>
  </head>
  <body></body>
  <script>
    var trial_L = {
      type: 'html-keyboard-response',
      stimulus: '<div class="text_left">L</div>',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    var trial_R = {
      type: 'html-keyboard-response',
      stimulus: '<div class="text_right">R</div>',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    jsPsych.init({
      timeline: [trial_L, trial_R],
    });
  </script>
</html>

ポイントは 2 点です。

  1. <head>の中に<style>というタグを新しく用意して,その中に<div style=...>で指定していた内容を書き写し,text_lefttext_rightという名前をつけています。
  2. stimulusのもともと<div style="設定項目">だった部分を,<div class="スタイル名">として,その名前のstyleを読み込んでいます。

2 で述べたように,事前に設定したスタイルをclass=スタイル名で読み込むように変更することで,stimulusの部分がかなり見やすくなりました。また,<style>タグ内でスタイルを作成する際には,;で改行して,設定項目を縦に並べることができるため,何をどのように設定しているのかについても見やすくなりました。

提示位置の確認

位置を変更することができましたが,筆者の拙い HTML の知識ではこれで正しいの不安になるところです。もともとstimulus:に文字列だけ指定していたときには,jsPsych が自動で画面中央に刺激を提示してくれていました。もし,先程の例での位置の指定方法に問題がないのであれば,stimulus:に文字だけ指定したときと上下の位置に違いはないはずです。trial_L, trial_Rのどちらか一方のstimulus:を文字列だけの指定に戻して,上下の位置が一致しているかどうかを確認してみましょう。コード例では R の提示位置の指定をなくしています。

コード例
check_position.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="../jspsych-6.3.1/jspsych.js"></script>
    <script src="../jspsych-6.3.1/plugins/jspsych-html-keyboard-response.js"></script>
    <link rel="stylesheet" href="../jspsych-6.3.1/css/jspsych.css"></link>
    <style>
      .text_left {
        position: absolute;
        left: 40%;
        top: 50%;
      }
      .text_right {
        position: absolute;
        right: 40%;
        top: 50%;
      }
    </style>
  </head>
  <body></body>
  <script>
    var trial_L = {
      type: 'html-keyboard-response',
      stimulus: '<div class="text_left">L</div>',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    var trial_R = {
      type: 'html-keyboard-response',
      stimulus: 'R',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    jsPsych.init({
      timeline: [trial_L, trial_R],
    });
  </script>
</html>

実際に確認してみると,上で紹介した方法で位置を調整した L が明らかに R よりも低い位置に提示されていることがわかります。すべての刺激に対して同じ指定方法top: 50%を用いれば,刺激間で上下の提示位置に差はないため,実験結果に影響はないと思われますが,jsPsych の「中央」からずれているのはすこし気持ちが悪いです。これを修正する方法を考えていきましょう。

何の位置が調整されているのか

positionでの位置指定がどのよう行われているのかを理解するために,簡単な実験をしてみましょう。2 つの刺激の内,一方の刺激は元の通りtop:50%で上から 50%の位置に提示されるようにし,もう一方の刺激はbottom: 50%で下から 50%の位置に提示されるようにしましょう。素朴にはどちらも同じ位置を指定しているように思われます。

コード例
change_position.html
<!DOCTYPE html>
<html>
  <head>
    <script src="../jspsych-6.3.1/jspsych.js"></script>
    <script src="../jspsych-6.3.1/plugins/jspsych-html-keyboard-response.js"></script>
    <link rel="stylesheet" href="../jspsych-6.3.1/css/jspsych.css"></link>
    <style>
      .text_left {
        position: absolute;
        left: 40%;
        top: 50%;
      }
      .text_right {
        position: absolute;
        right: 40%;
        bottom: 50%;
      }
    </style>
  </head>
  <body></body>
  <script>
    var trial_L = {
      type: 'html-keyboard-response',
      stimulus: '<div class="text_left">L</div>',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    var trial_R = {
      type: 'html-keyboard-response',
      stimulus: '<div class="text_right">R</div>',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    jsPsych.init({
      timeline: [trial_L, trial_R],
    });
  </script>
</html>

しかし,試してみると,異なる位置に刺激が提示されたと思います。なぜこのようなことが起こるのでしょうか。実は,topbottomで提示刺激(HTML の要素)のどの部分を上から・下から 50%の位置に持ってきているのかが異なります。

  • top: 50%は提示刺激の上端が上から 50%の位置に来るように調整します。
  • bottom: 50% は提示刺激の下端が下から 50%の位置に来るように調整します。

フォントのサイズ分だけ刺激の上端と下端の位置は異なるため,結果的に刺激は異なった位置に提示されることになります。さらに,topで指定しているのは刺激の上端の位置であるためtop: 50%と指定しても,刺激はウィンドウの縦方向のちょうど真ん中には提示されません。どうやらこれが jsPsych の標準の処理と違った結果になる原因なようです。

同じことがleftrightで横方向の位置を指定したときにも当てはまります。leftは刺激の左端,rightは刺激の右端の位置を調整します。そのため,left: 50%と指定しても,刺激はウィンドウの横方向のちょうど真ん中には提示されませんし,left: 50%, right: 50%ではそれぞれ異なった位置に刺激が提示されます。

この問題を避けて,top: 50%bottom: 50%left: 50%right: 50%)で刺激を縦(横)方向のちょうど真ん中に提示するには,刺激の中心が指定した位置に来るように調整すればよさそうです。

刺激の中心の位置を調整する

指定した位置に刺激の中心を持ってくる方法を考えていきましょう。例えば,これまでのようにtop: 50%, left: 40%とすると,刺激の左上端がブラウザの上端から 50%, 左端から 40%の位置に来ます。この位置に,刺激の中心を移動させたいのであれば,刺激の高さ(縦の長さ)の半分だけ上側に戻し,幅(横の長さ)の半分だけ左側に戻せばよいです。このページの「6. transform」にある図がわかりやすいです。

これを実現するには,style にtransform: translateY(-50%) translateX(-50%);を追加します。translateYは縦方向,translateXは横方向に対応しており,正の値を指定すると下(右)方向に移動し,負の値だと上(左)方向に移動します。

以下の例では,L を画面左側に提示し,R は jsPsych の標準の処理で画面中央に提示するようにしています。実行して,L と R の縦方向の提示位置がどうなっているのかを確認してみてください。

change_position_transform.html
<!DOCTYPE html>
  <html>
  <head>
    <script src="../jspsych-6.3.1/jspsych.js"></script>
    <script src="../jspsych-6.3.1/plugins/jspsych-html-keyboard-response.js"></script>
    <link rel="stylesheet" href="../jspsych-6.3.1/css/jspsych.css"></link>
    <style>
      .text_left {
        position: absolute;
        left: 40%;
        top: 50%;
        transform: translateY(-50%) translateX(-50%);
        -webkit-transform: translateY(-50%) translateX(-50%);
      }
      .text_right {
        position: absolute;
        right: 40%;
        top: 50%;
        transform: translateY(-50%) translateX(50%);
        -webkit-transform: translateY(-50%) translateX(50%);
      }
    </style>
  </head>
  <body></body>
  <script>
    var trial_L = {
      type: 'html-keyboard-response',
      stimulus: '<div class="text_left">L</div>',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    var trial_R = {
      type: 'html-keyboard-response',
      stimulus: 'R',
      choices: ['f', 'j'],
      post_trial_gap: 500,
    }

    jsPsych.init({
      timeline: [trial_L, trial_R],
    });
  </script>
</html>

どうでしょうか。L と R が同じ高さに表示されていたのではないでしょうか。text_leftleftを 50%に設定すると,L と R が全く同じ位置に提示されます。つまり,今回作成した位置の設定と,jsPsych が標準で処理してくれる位置の設定が同じであるということがわかります。ぜひ確認してみてください。

上の例では使用していませんが,text_rightを使うと,刺激の中心が画面の右側のちょうど 40%の位置に提示されます。また,text_righttransformtext_leftと見比べてみるとtranslateXの値の正負が異なっていますが,left:right:で指定した位置に刺激の中心を持ってくるという点では,どちらもこれで問題ありません。それぞれのtranslateXの正負を反転させたりしていろいろ試してみてください。

おわりに

本章では,提示位置の変更方法を紹介しました。ウェブブラウザを使用する jsPsych では,位置を変更するために HTML タグを触る必要があります。style の設定は<head>の部分で先に宣言しておくこともできます。この style をまとめて別ファイルをとして保存しているのがjspsych.cssです。このファイルには他にもたくさんの style が定義されています。眺めていると学ぶこともあるかもしれません。この本章を通じて,みなさんが自在に位置調整できるようになったことを願うばかりです。