docs updates; better RT tutorial

This commit is contained in:
Josh de Leeuw 2017-01-12 14:44:03 -05:00
parent f40214066b
commit a4ad32af66
5 changed files with 911 additions and 481 deletions

View File

@ -29,7 +29,7 @@ To actually create and run this simple example, complete the [hello world tutori
## Multiple trials
Scaling up to multiple trials is easy. Just create an object for each trial, and add each object to the array.
Scaling up to multiple trials is straightforward. Just create an object for each trial, and add each object to the timeline array.
```javascript
// with lots of trials, it might be easier to add the trials
@ -93,9 +93,9 @@ Timelines can be nested any number of times.
## Timeline variables
A common pattern in behavioral experiments is to repeat the same procedure many times with different stimuli. One shortcut to implement this pattern is with the approach described in the previous section, but this only works if all the trials use the same plugin type. Timeline variables are a more general solution. With timeline variables, you define the procedure once (as a timeline), and specify a set of parameters and their values for each iteration through the timeline.
A common pattern in behavioral experiments is to repeat the same procedure many times with different stimuli. A procedure might be a single trial, but it also might be a series of trials. One shortcut to implement this pattern is with the approach described in the previous section, but this only works if all the trials use the same plugin type. Timeline variables are a more general solution. With timeline variables, you define the procedure once (as a timeline), and specify a set of parameters and their values for each iteration through the timeline.
What follows is an example of how to use timeline variables.
What follows is an example of how to use timeline variables. The [simple reaction time tutorial](../tutorials/rt-task.md) also explains how to use timeline variables.
Suppose we want to create an experiment where people see a set of faces with names displayed below the face. In between each face, a fixation cross is displayed on the screen. Without timeline variables, we would need to add many trials to the timeline, alternating between trials showing the fixation cross and trials showing the face and name. This could be done efficiently in a loop or function, but timeline variables make it even easier - as well as adding extra features like sampling and randomization.
@ -113,8 +113,8 @@ var face_name_procedure = {
},
{
type: 'single-stim',
stimulus: function(){ return jsPsych.timelineVariable('face'); },
prompt: function(){ return "This person's name is "+jsPsych.timelineVariable('name'); },
stimulus: jsPsych.timelineVariable('face'),
prompt: function(){ return "This person's name is "+jsPsych.timelineVariable('name', true); },
choices: jsPsych.NO_KEYS,
timing_response: 2500
}

View File

@ -2,6 +2,6 @@
jsPsych is a JavaScript library for creating and running behavioral experiments in a web browser. The library provides a flexible framework for building a wide range of laboratory-like experiments that can be run online.
To use jsPsych, you provide a description of the structure (in the form of [a timeline](features/timeline.md)). jsPsych handles things like determining which trial to run next, storing data, and randomization. jsPsych uses *plugins* to define what to do at each point on the timeline. Plugins are ready-made templates for simple experimental tasks like displaying instructions or displaying a stimulus and collecting a keyboard response. Plugins are very flexible to support a wide variety of experiments, and it is easy to create your own plugin if you have experience with JavaScript programming.
To use jsPsych, you provide a description of the experiment in the form of [a timeline](features/timeline.md). jsPsych handles things like determining which trial to run next, storing data, and randomization. jsPsych uses *plugins* to define what to do at each point on the timeline. Plugins are ready-made templates for simple experimental tasks like displaying instructions or displaying a stimulus and collecting a keyboard response. Plugins are very flexible to support a wide variety of experiments, and it is easy to create your own plugin if you have experience with JavaScript programming.
[The page on timelines](features/timeline.md) is a good place to start learning about jsPsych. From there, you might want to complete the [Hello World! tutorial](tutorials/hello-world.md) and the [reaction time experiment tutorial](tutorials/rt-task.md).

View File

@ -6,6 +6,8 @@ In the long tradition of **"Hello world!"** examples, this tutorial creates an e
Start by downloading the jsPsych library. The most recent version can always be found on the [GitHub releases page](https://github.com/jodeleeuw/jsPsych/releases).
*Note: the images below show version 4.2, but the process is the same for the most recent version.*
![releasespage](/img/githubreleases.jpg)
## Step 2: Create a folder to store your experiment files
@ -36,6 +38,7 @@ There's some basic code that (nearly) all HTML documents have in common. Here's
<head>
<title>My experiment</title>
</head>
<body></body>
</html>
```
@ -43,16 +46,16 @@ Add the above code to the experiment.html file and save it. If you then open the
## Step 5: Import the jsPsych library
To use jsPsych, add a `<script>` tag to import the library. You'll need to import the jQuery library as well, which jsPsych depends on. Make sure to import jQuery before jsPsych. jQuery can be imported directly from [a hosted version on Google's servers](https://developers.google.com/speed/libraries/#jquery).
To use jsPsych, add a `<script>` tag to import the library.
```html
<!DOCTYPE html>
<html>
<head>
<title>My experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-6.0/jspsych.js"></script>
</head>
<body></body>
</html>
```
@ -63,10 +66,10 @@ You may also want to import the jsPsych stylesheet, which applies a basic set of
<html>
<head>
<title>My experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-6.0/jspsych.js"></script>
<link href="jspsych-6.0/css/jspsych.css" rel="stylesheet" type="text/css"></link>
</head>
<body></body>
</html>
```
@ -79,11 +82,11 @@ For the demo, we want to show some text on the screen. This is exactly what the
<html>
<head>
<title>My experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-6.0/jspsych.js"></script>
<script src="jspsych-6.0/plugins/jspsych-text.js"></script>
<link href="jspsych-6.0/css/jspsych.css" rel="stylesheet" type="text/css"></link>
</head>
<body></body>
</html>
```
@ -96,11 +99,11 @@ To add JavaScript code directly to the webpage we need to add a set of `<script>
<html>
<head>
<title>My experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-6.0/jspsych.js"></script>
<script src="jspsych-6.0/plugins/jspsych-text.js"></script>
<link href="jspsych-6.0/css/jspsych.css" rel="stylesheet" type="text/css"></link>
</head>
<body></body>
<script>
var hello_trial = {
@ -112,18 +115,18 @@ To add JavaScript code directly to the webpage we need to add a set of `<script>
</html>
```
Now that we have the trial defined, we just need to tell jsPsych to run an experiment consisting of this trial. This requires using the `jsPsych.init` function and specifying the `timeline` parameter.
Now that we have the trial defined we just need to tell jsPsych to run an experiment consisting of this trial. This requires using the `jsPsych.init` function and specifying the `timeline` parameter.
```html
<!DOCTYPE html>
<html>
<head>
<title>My experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-6.0/jspsych.js"></script>
<script src="jspsych-6.0/plugins/jspsych-text.js"></script>
<link href="jspsych-6.0/css/jspsych.css" rel="stylesheet" type="text/css"></link>
</head>
<body></body>
<script>
var hello_trial = {

File diff suppressed because it is too large Load Diff

View File

@ -7,108 +7,89 @@
<script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>
</body>
<body></body>
<script>
/* define welcome message block */
var welcome_block = {
/* create timeline */
var timeline = [];
/* define welcome message trial */
var welcome = {
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
/* define instructions block */
var instructions_block = {
/* define instructions trial */
var instructions = {
type: "text",
text: "<p>In this experiment, a circle will appear in the center " +
"of the screen.</p><p>If the circle is <strong>blue</strong>, " +
"press the letter F on the keyboard as fast as you can.</p>" +
"<p>If the circle is <strong>orange</strong>, do not press " +
"any key.</p>" +
"<div class='left center-content'><img src='img/blue.png'></img>" +
"<p>If the circle is <strong>orange</strong>, press the letter J " +
"as fast as you can.</p>" +
"<div style='float: left;'><img src='img/blue.png'></img>" +
"<p class='small'><strong>Press the F key</strong></p></div>" +
"<div class='right center-content'><img src='img/orange.png'></img>" +
"<p class='small'><strong>Do not press a key</strong></p></div>" +
"<div class='float: right;'><img src='img/orange.png'></img>" +
"<p class='small'><strong>Press the J key</strong></p></div>" +
"<p>Press any key to begin.</p>",
timing_post_trial: 2000
};
timeline.push(instructions);
/* define test block */
/* test trials */
var test_stimuli = [
{
stimulus: "img/blue.png",
data: { response: 'go' }
},
{
stimulus: "img/orange.png",
data: { response: 'no-go' }
}
{ stimulus: "img/blue.png", data: { test_part: 'test', correct_response: 'f' } },
{ stimulus: "img/orange.png", data: { test_part: 'test', correct_response: 'j' } }
];
var all_trials = jsPsych.randomization.repeat(test_stimuli, 10);
var post_trial_gap = function() {
return Math.floor( Math.random() * 1500 ) + 750;
}
var test_block = {
type: "single-stim",
choices: ['F'],
timing_response: 1500,
timing_post_trial: post_trial_gap,
on_finish: function(data){
var correct = false;
if(data.response == 'go' && data.rt > -1){
correct = true;
} else if(data.response == 'no-go' && data.rt == -1){
correct = true;
}
jsPsych.data.addDataToLastTrial({correct: correct});
var fixation = {
type: 'single-stim',
stimulus: '<div style="font-size:60px;">+</div>',
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
},
timeline: all_trials
};
/* define debrief block */
function getSubjectData() {
var trials = jsPsych.data.getData({trial_type: 'single-stim'});
var sum_rt = 0;
var correct_trial_count = 0;
var correct_rt_count = 0;
for (var i = 0; i < trials.length; i++) {
if (trials[i].correct == true) {
correct_trial_count++;
if(trials[i].rt > -1){
sum_rt += trials[i].rt;
correct_rt_count++;
}
}
}
return {
rt: Math.floor(sum_rt / correct_rt_count),
accuracy: Math.floor(correct_trial_count / trials.length * 100)
}
data: {test_part: 'fixation'}
}
var test = {
type: "single-stim",
stimulus: jsPsych.timelineVariable('stimulus'),
choices: ['f', 'j'],
data: jsPsych.timelineVariable('data'),
on_finish: function(data){
data.correct = data.key_press == jsPsych.pluginAPI.convertKeyCharacterToKeyCode(data.correct_response);
},
}
var test_procedure = {
timeline: [fixation, test],
timeline_variables: test_stimuli,
repetitions: 5,
randomize_order: true
}
timeline.push(test_procedure);
/* define debrief */
var debrief_block = {
type: "text",
text: function() {
var subject_data = getSubjectData();
return "<p>You responded correctly on "+subject_data.accuracy+"% of "+
"the trials.</p><p>Your average response time was <strong>" +
subject_data.rt + "ms</strong>. Press any key to complete the "+
"experiment. Thank you!</p>";
var trials = jsPsych.data.getData().filter({test_part: 'test'});
var correct_trials = trials.filter({correct: true});
var accuracy = Math.round(correct_trials.count() / trials.count() * 100);
var rt = Math.round(correct_trials.select('rt').mean());
return "<p>You responded correctly on "+accuracy+"% of the trials.</p>"+
"<p>Your average response time was "+rt+"ms.</p>"+
"<p>Press any key to complete the experiment. Thank you!</p>";
}
};
/* create experiment timeline array */
var timeline = [];
timeline.push(welcome_block);
timeline.push(instructions_block);
timeline.push(test_block);
timeline.push(debrief_block);
/* start the experiment */