-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
<!DOCTYPE html> | ||
<head> | ||
<script src="https://unpkg.com/[email protected]"></script> | ||
<script src="https://unpkg.com/@jspsych/plugin-html-keyboard-response/dist/index.browser.js"></script> | ||
<script src="simulation_options.js"></script> | ||
<link rel="stylesheet" href="https://unpkg.com/[email protected]/css/jspsych.css"> | ||
<style> | ||
.stimulus { | ||
font-size: 48px; | ||
font-weight: bold; | ||
} | ||
|
||
.red { | ||
color: red; | ||
} | ||
|
||
.green { | ||
color: green; | ||
} | ||
|
||
.blue { | ||
color: blue; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
</body> | ||
<script> | ||
const jsPsych = initJsPsych(); | ||
|
||
const instructions = { | ||
type: jsPsychHtmlKeyboardResponse, | ||
stimulus: `<p>You'll see a word on the screen like this:</p> | ||
<p class="stimulus red">GREEN</p> | ||
<p>Press R if the color of the word is red, G if it is green, and B if it is blue.</p> | ||
<p>For this trial, you would press R because the color of the word is red.</p> | ||
<p>Press R to continue.</p>`, | ||
choices: ['r'] | ||
} | ||
|
||
const ready = { | ||
type: jsPsychHtmlKeyboardResponse, | ||
stimulus: `<p>There are 48 trials.</p><p>Press R, G, or B to begin.</p>`, | ||
choices: ['r', 'g', 'b'] | ||
} | ||
|
||
const fixation = { | ||
type: jsPsychHtmlKeyboardResponse, | ||
stimulus: `<p class="stimulus">+</p>`, | ||
choices: "NO_KEYS", | ||
trial_duration: 250, | ||
} | ||
|
||
const stroop_trial = { | ||
type: jsPsychHtmlKeyboardResponse, | ||
stimulus: () => { | ||
return `<p class="stimulus ${jsPsych.timelineVariable('color')}">${jsPsych.timelineVariable('word')}</p>` | ||
}, | ||
choices: ['r','g','b'], | ||
data: { | ||
color: jsPsych.timelineVariable('color'), | ||
word: jsPsych.timelineVariable('word'), | ||
stroop_type: jsPsych.timelineVariable('stroop_type'), | ||
}, | ||
simulation_options: jsPsych.timelineVariable('stroop_type'), | ||
on_finish: (data) => { | ||
data.correct = data.response == data.color.substring(0,1); | ||
} | ||
} | ||
|
||
const stroop_test = { | ||
timeline: [fixation, stroop_trial], | ||
timeline_variables: [ | ||
{color: 'red', word: 'RED', stroop_type: 'congruent'}, | ||
{color: 'green', word: 'GREEN', stroop_type: 'congruent'}, | ||
{color: 'blue', word: 'BLUE', stroop_type: 'congruent'}, | ||
{color: 'red', word: 'RED', stroop_type: 'congruent'}, | ||
{color: 'green', word: 'GREEN', stroop_type: 'congruent'}, | ||
{color: 'blue', word: 'BLUE', stroop_type: 'congruent'}, | ||
{color: 'green', word: 'RED', stroop_type: 'incongruent'}, | ||
{color: 'blue', word: 'RED', stroop_type: 'incongruent'}, | ||
{color: 'red', word: 'GREEN', stroop_type: 'incongruent'}, | ||
{color: 'blue', word: 'GREEN', stroop_type: 'incongruent'}, | ||
{color: 'red', word: 'BLUE', stroop_type: 'incongruent'}, | ||
{color: 'green', word: 'BLUE', stroop_type: 'incongruent'}, | ||
], | ||
randomize_order: true, | ||
repetitions: 4, | ||
} | ||
|
||
const done = { | ||
type: jsPsychHtmlKeyboardResponse, | ||
stimulus: ()=>{ | ||
|
||
const data = jsPsych.data.get() | ||
const congruent_trials = data.filter({stroop_type: 'congruent'}); | ||
const incongruent_trials = data.filter({stroop_type: 'incongruent'}); | ||
|
||
const avg_rt_congruent = congruent_trials | ||
.filter({correct: true}) | ||
.select('rt') | ||
.mean(); | ||
|
||
const avg_rt_incongruent = incongruent_trials | ||
.filter({correct: true}) | ||
.select('rt') | ||
.mean(); | ||
|
||
const correct_percent_congruent = congruent_trials | ||
.filter({correct: true}) | ||
.count() / congruent_trials.count() * 100; | ||
|
||
const correct_percent_incongruent = incongruent_trials | ||
.filter({correct: true}) | ||
.count() / incongruent_trials.count() * 100; | ||
|
||
return `<p>Done!</p> | ||
<p>Your average response time for congruent trials was: ${Math.round(avg_rt_congruent)} ms (${Math.round(correct_percent_congruent)}% correct)</p> | ||
<p>Your average response time for incongruent trials was: ${Math.round(avg_rt_incongruent)} ms (${Math.round(correct_percent_incongruent)}% correct)</p>` | ||
}, | ||
choices: "NO_KEYS", | ||
simulation_options: { | ||
simulate: false | ||
} | ||
} | ||
|
||
const timeline = [instructions, ready, stroop_test, done] | ||
|
||
const simulation_options = create_simulation_options(jsPsych); | ||
|
||
jsPsych.simulate(timeline, "data-only", simulation_options); | ||
|
||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
const congruent_rt_mu = 500; | ||
const congruent_rt_sd = 100; | ||
const congruent_rt_tau = 1 / 100; | ||
const congruent_p_correct = 0.9; | ||
|
||
const incongruent_rt_mu = 600; | ||
const incongruent_rt_sd = 100; | ||
const incongruent_rt_tau = 1 / 100; | ||
const incongruent_p_correct = 0.7; | ||
|
||
const p_speedy_subject = 0.1; | ||
|
||
const speedy_rt_mu = 100; | ||
const speedy_rt_sd = 20; | ||
const speedy_rt_tau = 1 / 20; | ||
|
||
function create_simulation_options(jsPsych) { | ||
const simulation_options = { | ||
congruent: {}, | ||
incongruent: {}, | ||
}; | ||
if (Math.random() > p_speedy_subject) { | ||
simulation_options.congruent.data = { | ||
response: () => { | ||
const correct_response = jsPsych | ||
.timelineVariable("color") | ||
.substring(0, 1); | ||
const incorrect_response = jsPsych.randomization.shuffle( | ||
["r", "g", "b"].filter((x) => x !== correct_response) | ||
)[0]; | ||
if (Math.random() < congruent_p_correct) { | ||
return correct_response; | ||
} else { | ||
return incorrect_response; | ||
} | ||
}, | ||
rt: () => { | ||
return jsPsych.randomization.sampleExGaussian( | ||
congruent_rt_mu, | ||
congruent_rt_sd, | ||
congruent_rt_tau, | ||
true | ||
); | ||
}, | ||
}; | ||
|
||
simulation_options.incongruent.data = { | ||
response: () => { | ||
const correct_response = jsPsych | ||
.timelineVariable("color") | ||
.substring(0, 1); | ||
const incorrect_response = jsPsych.randomization.shuffle( | ||
["r", "g", "b"].filter((x) => x !== correct_response) | ||
)[0]; | ||
if (Math.random() < incongruent_p_correct) { | ||
return correct_response; | ||
} else { | ||
return incorrect_response; | ||
} | ||
}, | ||
rt: () => { | ||
return jsPsych.randomization.sampleExGaussian( | ||
incongruent_rt_mu, | ||
incongruent_rt_sd, | ||
incongruent_rt_tau, | ||
true | ||
); | ||
}, | ||
}; | ||
} else { | ||
simulation_options.congruent.data = { | ||
rt: () => { | ||
return jsPsych.randomization.sampleExGaussian( | ||
speedy_rt_mu, | ||
speedy_rt_sd, | ||
speedy_rt_tau, | ||
true | ||
); | ||
}, | ||
}; | ||
simulation_options.incongruent.data = { | ||
rt: () => { | ||
return jsPsych.randomization.sampleExGaussian( | ||
speedy_rt_mu, | ||
speedy_rt_sd, | ||
speedy_rt_tau, | ||
true | ||
); | ||
}, | ||
}; | ||
} | ||
|
||
return simulation_options; | ||
} |