Plugins for jspsych@6.1
This commit is contained in:
50
docs/jspsych-audio-keyboard-response-wait.md
Normal file
50
docs/jspsych-audio-keyboard-response-wait.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# jspsych-audio-keyboard-response-wait
|
||||
|
||||
This plugin is similar to [jspsych-audio-keyboard-response](https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/), but allows more control on when the trial stops.
|
||||
|
||||
This plugin plays audio files and records responses generated with the keyboard.
|
||||
|
||||
If the browser supports it, audio files are played using the WebAudio API. This allows for reasonably precise timing of the playback. The timing of responses generated is measured against the WebAudio specific clock, improving the measurement of response times. If the browser does not support the WebAudio API, then the audio file is played with HTML5 audio.
|
||||
|
||||
Audio files are automatically preloaded by jsPsych. However, if you are using timeline variables or another dynamic method to specify the audio stimulus you will need to [manually preload](https://www.jspsych.org/overview/media-preloading/#manual-preloading) the audio.
|
||||
|
||||
The trial can end when the subject responds, when the audio file has finished playing, or if the subject has failed to respond within a fixed length of time. In addition, the trial can end after the subject has responded *and* the audio file has finished playing if you want to make sure the subject always hears the stimulus completely. Once the subject pressed a key, following key presses are not registered anymore. It is possible to dim the interface to signify this to the participant.
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.
|
||||
|
||||
Parameter | Type | Default Value | Description
|
||||
----------------|-------------------|---------------|------------
|
||||
stimulus | string (audio) | undefined | The audio to be played.
|
||||
choices | array of keycodes | ALL_KEYS | The keys the subject is allowed to press to respond to the stimulus.
|
||||
prompt | string | null | This string can contain HTML markup. The intention is that it can be used to provide a reminder about the action the subject is supposed to take.
|
||||
trial_duration | numeric | null | How long to wait for the subject to make a response before ending the trial, in milliseconds. If the subject fails to make a response before this timer is reached, the subject's response will be recorded as null for the trial and the trial will end. If the value of this parameter is null, the trial will wait for a response indefinitely.
|
||||
response_ends_trial | boolean | true | If true, then the trial will end whenever the subject makes a response (assuming they make their response before the cutoff specified by the `trial_duration` parameter). If false, then the trial will continue until another condition ends the trial (either `trial_duration` or `trials_ends_after_audio`, but see `wait_for_audio`).
|
||||
trial_ends_after_audio | boolean | false | If true, then the trial will end as soon as the audio file finishes playing.
|
||||
wait_for_audio | boolean | false | If `response_ends_trial` is true, this will still wait for the audio to end before ending the trial.
|
||||
dim_content_after_response | boolean | false | Will dim the content once the response has been given (a key has been pressed).
|
||||
## Data Generated
|
||||
|
||||
In addition to the [default data collected by all plugins](overview#data-collected-by-plugins), this plugin collects the following data for each trial.
|
||||
|
||||
Name | Type | Value
|
||||
-----|------|------
|
||||
key_press | numeric | Indicates which key the subject pressed. The value is the [numeric key code](http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes) corresponding to the subject's response.
|
||||
rt | numeric | The response time in milliseconds for the subject to make a response. The time is measured from when the stimulus first appears on the screen until the subject's response.
|
||||
stimulus | string | Path to the audio file that played during the trial.
|
||||
|
||||
## Example
|
||||
|
||||
#### Plays a sound, and keeps playing until the end of the sound even if a response was given
|
||||
|
||||
```javascript
|
||||
var trial = {
|
||||
type: 'audio-keyboard-response-wait',
|
||||
stimulus: 'sound/tone.mp3',
|
||||
choices: ['e', 'i'],
|
||||
prompt: "<p>Is the pitch high or low? Press 'e' for low and 'i' for high.</p>",
|
||||
response_ends_trial: true.
|
||||
wait_for_audio: true
|
||||
};
|
||||
```
|
||||
82
docs/jspsych-audio-sequence-button-response.md
Normal file
82
docs/jspsych-audio-sequence-button-response.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# jspsych-audio-sequence-button-response
|
||||
|
||||
This plugin plays a sequence of audio files, highlighting answer buttons as they are played.
|
||||
|
||||
This plugin is based on [jspsych-audio-button-response](https://www.jspsych.org/plugins/jspsych-audio-button-response/).
|
||||
|
||||
Audio files are automatically preloaded by jsPsych. However, if you are using timeline variables or another dynamic method to specify the audio stimulus you will need to manually preload the audio.
|
||||
|
||||
The trial can end when the subject responds, when the audio file has finished playing, or if the subject has failed to respond within a fixed length of time.
|
||||
|
||||
Note that the buttons are disabled during playing so the subject cannot press any button during that time.
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.
|
||||
|
||||
Parameter | Type | Default Value | Description
|
||||
----------------|------------------|---------------|------------
|
||||
stimuli | array of strings | undefined | An array listing the path (url) to the audio files to be played.
|
||||
choices | array of strings | [] | Labels for the buttons. Each different string in the array will generate a different button. It is not absolutely mandatory, but it is probably a good idea to have this being the same length as `stimuli`.
|
||||
button_html | HTML string | `'<button class="jspsych-btn">%choice%</button>'` | A template of HTML for generating the button elements. You can override this to create customized buttons of various kinds. The string `%choice%` will be changed to the corresponding element of the `choices` array. You may also specify an array of strings, if you need different HTML to render for each button. If you do specify an array, the `choices` array and this array must have the same length. The HTML from position 0 in the `button_html` array will be used to create the button for element 0 in the `choices` array, and so on.
|
||||
prompt | string | null | This string can contain HTML markup. Any content here will be displayed below or above the stimulus (see `prompt_position`). The intention is that it can be used to provide a reminder about the action the subject is supposed to take.
|
||||
prompt_position | string | `'bottom'` | The position of the prompt: `'bottom'` or `'above'`.
|
||||
isi | numeric | 0 | Inter-stimulus-interval: The delay in between stimulus presentation (in ms).
|
||||
trial_duration | numeric | null | How long to wait for the subject to make a response before ending the trial in milliseconds. If the subject fails to make a response before this timer is reached, the subject's response will be recorded as null for the trial and the trial will end. If the value of this parameter is null, the trial will wait for a response indefinitely.
|
||||
margin_vertical | string | `'0px'` | Vertical margin of the button(s).
|
||||
margin_horizontal | string | `'8px'` | Horizontal margin of the button(s).
|
||||
response_ends_trial | boolean | true | If true, then the trial will end whenever the subject makes a response (assuming they make their response before the cutoff specified by the `trial_duration` parameter). If false, then the trial will continue until the value for `timing_response` is reached. You can use this parameter to force the subject to view a stimulus for a fixed amount of time, even if they respond before the time is complete.
|
||||
trial_ends_after_audio | boolean | false | If true, then the trial will end as soon as the audio file finishes playing.
|
||||
visual_feedback | boolean | false | If true, provides feedback after the subject gave their answer. If this is set to true, `i_correct` has to be also specified.
|
||||
i_correct | numeric | null | The index of the choice that corresponds to the correct answer (for feedback, otherwise it is optional).
|
||||
|
||||
## Data Generated
|
||||
|
||||
In addition to the [default data collected by all plugins](https://www.jspsych.org/plugins/overview/#data-collected-by-plugins), this plugin collects the following data for each trial.
|
||||
|
||||
Name | Type | Value
|
||||
-----|------|------
|
||||
rt | numeric | The response time in milliseconds for the subject to make a response. The time is measured from when the stimulus first appears on the screen until the subject's response.
|
||||
stimuli | array of strings | The list of stimuli that was passed as parameter (just for convenience).
|
||||
button_pressed | numeric | Indicates which button the subject pressed. The first button in the `choices` array is 0, the second is 1, and so on.
|
||||
|
||||
## Styling elements
|
||||
|
||||
### IDs
|
||||
|
||||
id | Description
|
||||
-------------------------------------------|------------------------------------
|
||||
`jspsych-audio-sequence-button-response-#` | Where `#` is the index of the choice. This is the div that is wrapping each response button (not the button itself).
|
||||
|
||||
|
||||
### CSS Classes
|
||||
|
||||
Class | Description
|
||||
-------------------------------------------|------------------------------------
|
||||
jspsych-audio-button-response-btngroup | The `<div>` wrapping the button group.
|
||||
jspsych-audio-sequence-button-response | This class is applied to the `<div>`s wrapping the buttons.
|
||||
jspsych-prompt | The `<p>` that contains the prompt.
|
||||
highlighted | The button inside the `<div>`s receive this class when the button is highlighted.
|
||||
disabled | When the buttons are disabled. This is a class, for convenience, although attribute selector should also work `[disabled]`.
|
||||
visual-feedback | This class is given to the button that represents the correct option, *after* the subject has given their answer.
|
||||
correct, incorrect | One of these classes is given to the button that represents the correct option, depending on whether the subject's answer was correct or incorrect.
|
||||
|
||||
## Dependencies
|
||||
|
||||
This plugin relies on [jQuery](https://jquery.com/). Note that this is not absolutely necessary, but it makes some things fail silently instead of raising errors. If you need this plugin without jQuery, you can easily
|
||||
replace the jQuery syntax with standard Javascript DOM manipulation.
|
||||
|
||||
The animation of the visual feedback can make use of [Semantic UI's transitions](https://semantic-ui.com/modules/transition.html) ('bounce' for correct, 'shake' for incorrect). But if it's not available a simpler blink animation is implemented within this plugin.
|
||||
|
||||
## Example
|
||||
|
||||
#### Three alternative forced choice (3AFC)
|
||||
|
||||
```javascript
|
||||
var trial = {
|
||||
type: 'audio-button-response',
|
||||
stimuli: ['sound/bi.mp3', 'sound/ba.mp3', 'sound/bi.mp3'],
|
||||
choices: ['1', '2', '3'],
|
||||
prompt: "<p>Which one is different from the two others?</p>"
|
||||
};
|
||||
```
|
||||
84
docs/jspsych-crm.md
Normal file
84
docs/jspsych-crm.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# jspsych-crm
|
||||
|
||||
This plugin displays an interface for the Coordinate Response Measure [(Bolia _et al._, 2000)](https://doi.org/10.1121/1.428288). The interface is a grid where
|
||||
each row corresponds to a color and each column corresponds to a number. The participants hear a sound and then can click on one of the cells to give their response.
|
||||
|
||||
The trial can end when the subject responds, when the audio file has finished playing, or if the subject has failed to respond within a fixed length of time.
|
||||
|
||||
Note that the buttons are disabled during playing so the subject cannot press any button during that time.
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.
|
||||
|
||||
Parameter | Type | Default Value | Description
|
||||
----------------|------------------|---------------|------------
|
||||
stimulus | string | undefined | The path (url) to the audio file to play.
|
||||
colors | array of strings | undefined | Labels for the rows.
|
||||
numbers | array | undefined | Labels for the columns (can be strings or plain numbers).
|
||||
prompt | string | null | This string can contain HTML markup. Any content here will be displayed above the response grid. The intention is that it can be used to provide a reminder about the action the subject is supposed to take.
|
||||
trial_duration | numeric | null | How long to wait for the subject to make a response before ending the trial in milliseconds. If the subject fails to make a response before this timer is reached, the subject's response will be recorded as null for the trial and the trial will end. If the value of this parameter is null, the trial will wait for a response indefinitely.
|
||||
response_ends_trial | boolean | true | If true, then the trial will end whenever the subject makes a response (assuming they make their response before the cutoff specified by the `trial_duration` parameter).
|
||||
trial_ends_after_audio | boolean | false | If true, then the trial will end as soon as the audio file finishes playing.
|
||||
visual_feedback | boolean | false | If true, provides feedback after the subject gave their answer. Visual feedback automatically ends the trial.
|
||||
correct | object | undefined | An object containing the correct color and number (used to calculate the score and to provide feedback).
|
||||
color_values | object | null | An object with keys corresponding to the `colors`, and containing a valid CSS color description. If left to `null`, some default colors are used (see below).
|
||||
text_color_values | object | 'auto' | Same as `color_values` but for the text color of the cells. `'auto'` (the default) means that the text color is either black or white depending on the computed luminance of the background.
|
||||
|
||||
Default color values:
|
||||
|
||||
```javascript
|
||||
color_values = {
|
||||
red: "#ff3333",
|
||||
blue: "#6b6bff",
|
||||
green: "#80ee59",
|
||||
yellow: "#ffe534",
|
||||
pink: "#ff57df",
|
||||
purple: "#a522ff",
|
||||
brown: "#7a5630",
|
||||
black: "#22222",
|
||||
white: "#fcfcfc",
|
||||
grey: "#8c8c8c",
|
||||
gray: "#8c8c8c"
|
||||
};
|
||||
```
|
||||
|
||||
## Data Generated
|
||||
|
||||
In addition to the [default data collected by all plugins](https://www.jspsych.org/plugins/overview/#data-collected-by-plugins), this plugin collects the following data for each trial.
|
||||
|
||||
Name | Type | Value
|
||||
---------|----------|------
|
||||
rt | numeric | The response time in milliseconds for the subject to make a response. The time is measured from when the stimulus first appears on the screen until the subject's response.
|
||||
stimulus | string | The stimulus that was passed as parameter (just for convenience).
|
||||
response_color | string | Indicate which color was selected by the participant. `null` if not response was given.
|
||||
response_number | string | Indicate which number was selected by the participant. `null` if not response was given.
|
||||
correct_color | string | Indicate which color was the correct one (from `trial.correct`).
|
||||
correct_number | string | Indicate which number was the correct one (from `trial.correct`).
|
||||
|
||||
## Styling elements
|
||||
|
||||
### IDs
|
||||
|
||||
id | Description
|
||||
---------------------------------|------------------------------------
|
||||
`jspsych-crm-buttons-container` | The `<div>` that wraps around the grid and prompt.
|
||||
|
||||
|
||||
### Classes and elements
|
||||
|
||||
CSS selectors | Description
|
||||
-------------------------------------------|------------------------------------
|
||||
`table.jspsych-crm` | The grid containing the CRM buttons.
|
||||
`table.jspsych-crm th` | The color labels on the sides of each row.
|
||||
`table.jspsych-crm td` | The cells of the grid.
|
||||
`.visual-feedback` | This class is given to the button that represents the correct option, *after* the subject has given their answer.
|
||||
`.correct`, `.incorrect` | One of these classes is given to the button that represents the correct option, depending on whether the subject's answer was correct or incorrect.
|
||||
`.crm-`*{color}* | Each element displayed in a color receives a class which is constructed from the name of the color.
|
||||
|
||||
## Dependencies
|
||||
|
||||
This plugin relies on [jQuery](https://jquery.com/). Note that this is not absolutely necessary, but it makes some things fail silently instead of raising errors. If you need this plugin without jQuery, you can easily
|
||||
replace the jQuery syntax with standard Javascript DOM manipulation.
|
||||
|
||||
The animation of the visual feedback can make use of [Semantic UI's transitions](https://semantic-ui.com/modules/transition.html) ('bounce' for correct, 'shake' for incorrect). But if it's not available a simpler blink animation is implemented within this plugin.
|
||||
361
docs/jspsych-nafc-adaptive.md
Normal file
361
docs/jspsych-nafc-adaptive.md
Normal file
@@ -0,0 +1,361 @@
|
||||
# jspsych-nafc-adaptive
|
||||
|
||||
This is not a jsPsych plugin, but instead a module that generates a timeline for adaptive
|
||||
tracking of a threshold using an odd-one-out task (nAFC).
|
||||
|
||||
An adaptive method is a method where each new set of stimuli in a trial is based on the
|
||||
previous response(s). [Levitt (1971)](https://doi.org/10.1121/1.1912375) has described these
|
||||
methods for auditory stimuli. In the case of a discrimination task, the difference between
|
||||
a reference and test stimuli decreases progressively to reach a certain point of the psychometric
|
||||
function. Rules to go up and down, i.e. increase or decrease the physical distance between
|
||||
the reference and test are described in number of 'up' and 'down'. For instance, "2-down, 1-up"
|
||||
means that the difference is decreased by a given step when two consecutive correct answers are given,
|
||||
while the difference is increased as soon as one mistake is made. This yields a threshold corresponding
|
||||
to 70.7%-correct. Adaptive procedures are meant to be a faster alternative to a *constant-stimuli* method.
|
||||
|
||||
The threshold is defined as the average difference over a number of "turn-points" or "reversals". A
|
||||
turn-point occurs when a the difference was increasing and start decreasing, or vice-versa.
|
||||
|
||||
The procedure also stops after a number of turn-points.
|
||||
|
||||
Some adaptive procedures use a fixed step size. These generally end-up being almost as long as constant-stimuli
|
||||
approaches. To benefit from the adaptiveness of the method, it is better to use an initial step that is
|
||||
large, and then refine it when we get close to threshold. The method proposed here packs mechanisms
|
||||
to do so.
|
||||
|
||||
A progress bar is shown per run. The progress is updated using the number of turn-points.
|
||||
|
||||
## Usage
|
||||
|
||||
To use it you'll need the following jsPsych dependencies included in your webpage (after adapting the path to wherever your Javascript files are):
|
||||
|
||||
```html
|
||||
<script src="/js/vendor/jspsych.js"></script>
|
||||
<script src="/js/vendor/jspsych-plugins/jspsych-instructions.js"></script>
|
||||
<script src="/js/vendor/jspsych-plugins/jspsych-waitfor-function.js"></script>
|
||||
<script src="/js/vendor/jspsych-plugins/jspsych-audio-sequence-button-response.js"></script>
|
||||
<script src="/js/tools.js"></script>
|
||||
<script src="/js/jspsych-nafc-adaptive.js"></script>
|
||||
```
|
||||
|
||||
* `jspsych-audio-sequence-button-response.js` can be found [here](../plugins/jspsych-audio-sequence-button-response.js).
|
||||
* `jspsych-waitfor-response.js` can be found [here](../plugins/jspsych-waitfor-response.js).
|
||||
* `tools.js` can be found [here](../../js/tools.js).
|
||||
|
||||
`tools.js` defines new functions to `Array.prototype` to help some calculations of the threshold.
|
||||
|
||||
The module defines a single function called `nAFC_adapt` that generates a timeline. It is then used like
|
||||
this in a `<script>` markup:
|
||||
|
||||
```javascript
|
||||
var options = ...;
|
||||
var condition = "...";
|
||||
var main_timeline = main_timeline.push( nAFC_adapt(options, condition) );
|
||||
jsPsych.init({
|
||||
timeline: main_timeline,
|
||||
display_element: 'jspsych-target',
|
||||
show_progress_bar: true,
|
||||
auto_update_progress_bar: false,
|
||||
});
|
||||
```
|
||||
The values of `options` and `condition` are described below.
|
||||
|
||||
## Options
|
||||
|
||||
Options is an object that contains all the parameters of the adaptive method.
|
||||
|
||||
Parameter | Type | Description
|
||||
-------------------------------|------------------|-----------------------------
|
||||
initial_step_size | numeric | The step-size at the beginning. Make it big to go down fast, but no so big that the learning curve is too steep for the subject.
|
||||
starting_difference | numeric | The initial difference. Make it big too, so the first trials are dead obvious, but no so big that it'll take forever to get it to converge.
|
||||
step_size_modifier | numeric | When we update the step-size, by how much do we do so? The modifier is multiplied to the previous step.
|
||||
down_up | array of ints | An array of length 2. The first number is the number of correct responses needed to go down. The second number is the number of incorrect responses needed to go up.
|
||||
terminate_on_nturns | int | We consider the procedure will have converged after this number of turn-points.
|
||||
terminate_on_ntrials | int | This is a safety measure so that the procedure doesn't go on forever if the participant hears nothing... The procedure will stop, no matter what, after this many trials.
|
||||
terminate_on_max_difference | numeric | Similar, but will stop the procedure when the we reach a difference larger or equal to this.
|
||||
threshold_on_last_nturns | int | The number of turn-points used for the calculation of the threshold. This has to be smaller than `terminate_on_nturns`, and it is recommended to keep it even.
|
||||
change_step_size_on_difference | numeric | Is used to determine when the step-size should be updated. When the current difference ≤ current step-size * `change_step_size_on_difference`, the step-size will be updated.
|
||||
change_step_size_on_ntrials | int | We also change the step size every `change_step_size_on_ntrials`.
|
||||
prompt | string | The prompt that is displayed above the buttons (e.g. "Click on the sound that is different from the others"). If `null` or unspecified, no prompt will be shown.
|
||||
isi | int | The inter-stimulus-interval in milliseconds.
|
||||
intervals | array of strings | An array of strings specifying the labels of the buttons shown on the screen.
|
||||
prepare_trial | function | A callback function to prepare the stimuli for the next trial.
|
||||
after_the_run | function | A callback function executed once the run is finished.
|
||||
start_button | string | The label of the start button after the instructions.
|
||||
opening_message | HTML string | The instructions before the first trial is presented. If `null` or omitted, this is skipped.
|
||||
closing_message | HTML string | The closing message after the run is finished. If `null` or omitted, this is skipped.
|
||||
visual_feedback | boolean | Wether visual feedback is used.
|
||||
|
||||
The callback functions are detailed below.
|
||||
|
||||
Here's an example:
|
||||
|
||||
```javascript
|
||||
var options = {
|
||||
initial_step_size: 2,
|
||||
starting_difference: 12,
|
||||
step_size_modifier: 1/Math.sqrt(2),
|
||||
down_up: [2, 1], // 2-down, 1-up => 70.7%
|
||||
terminate_on_nturns: 8,
|
||||
terminate_on_ntrials: 150,
|
||||
terminate_on_max_difference: 25,
|
||||
threshold_on_last_nturns: 6,
|
||||
change_step_size_on_difference: 2,
|
||||
change_step_size_on_ntrials: 15,
|
||||
prompt: "Which of the three is different from the two others?",
|
||||
isi: 500,
|
||||
intervals: ['1', '2', '3'],
|
||||
prepare_trial: prepare_trial, // function(last_trial, step, options, condition, done_cb())
|
||||
after_the_run: send_data_securely_to_server, // function(options, condition, data, success_cb())
|
||||
start_button: 'Beginnen',
|
||||
opening_message: "<h1>Test</h1><p>You will hear three sounds. Choose the one that is different from the two others.</p>",
|
||||
closing_message: "<h1>Thank you!</h1><p>This is the end of this block. Thank you for your help!</p>"
|
||||
visual_feedback: true,
|
||||
/* ------- You can also add yur custom options ------- */
|
||||
sound_folder: 'CV/nl_nl',
|
||||
sound_format: 'wav',
|
||||
syllables: ["su", "si+", "po", "l@", "sa"],
|
||||
ref_f0: 242
|
||||
};
|
||||
```
|
||||
|
||||
### `prepare_trial()`
|
||||
|
||||
This callback is called before the trial is presented. It has the following signature:
|
||||
|
||||
```javascript
|
||||
function prepare_trial(last_trial, step, options, condition, done_cb) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
It receives the following arguments:
|
||||
|
||||
* `last_trial`: This is the data from the last 'audio-sequence-button-response' trial. It corresponds to:
|
||||
`var last_trial = jsPsych.data.get().filter({trial_type: 'audio-sequence-button-response'}).last().values()[0];`.
|
||||
|
||||
It contains the following fields:
|
||||
```javascript
|
||||
{
|
||||
button_pressed: "2"
|
||||
correct: false
|
||||
difference: 12
|
||||
i_correct: 1
|
||||
internal_node_id: "0.0-0.0-1.0-1.0"
|
||||
rt: 17810.014999995474
|
||||
step: 0
|
||||
stimuli: ["snd/a.mp3", "snd/b.mp3", "snd/c.mp3"]
|
||||
time_elapsed: 22901
|
||||
trial_definition: {df0: "12st", syllables: Array(3)}
|
||||
trial_index: 2
|
||||
trial_type: "audio-sequence-button-response"
|
||||
}
|
||||
```
|
||||
|
||||
You can use these to construct the next trial. On the first trial, `last_trial` is `undefined`.
|
||||
|
||||
* `step`: This is the current, computed value for the trial we're preparing. That is, step size modifications have been applied and the sign determines whether we're going up or down.
|
||||
You can compute the new value of the difference with: `var diff = options.current_difference + step;`. The reason we don't pass on the difference is because there may be reasons to alter the
|
||||
step-size in the trial preparation process, or the difference may be quantised if we're dealing with a set of pre-computed stimuli. In other words, the actual difference may end up being different from
|
||||
the value of `diff` as computed above. The actual value of the difference will be passed on to the `done_cb` callback within the `next_trial` structure (see below).
|
||||
|
||||
* `options`: The general options. It contains the parameters passed on to `nAFC_adapt`, including the custom ones, but also `current_difference`, which was the difference applied during the last trial (it is equal to `starting_difference` on the first trial).
|
||||
|
||||
* `condition`: You can use this field to specify the type of condition you're testing. For instance you can use a label to distinguish between a condition "A" and a condition "B", that then allows you to write a generic function for the preparation of all your stimuli, since most of the code would likely be the same for different conditions.
|
||||
|
||||
* `done_cb`: This is a callback with a single argument `next_trial` you need to call once your function's finished. If the function is synchronous, then just call it at the end. If it is asynchronous, you can pass that as callback to the asynchronous function. The function takes one argument: `next_trial`, which is an object with the following properties:
|
||||
|
||||
- `stimuli`: The list of sound files to load. Will be used to pre-load the stimuli before the trial begins.
|
||||
- `i_correct`: The index of the correct response.
|
||||
- `trial_definition`: The parameters that define the trial (can be anything, string, array, or object).
|
||||
- `step`: The step used to create the new trial.
|
||||
- `difference`: The difference used to create the new trial. This is used to update `options.current_difference`.
|
||||
|
||||
You have to prepare this object in your `prepare_trial` function and pass it to `done_cb` when you're done.
|
||||
|
||||
This callback is executed as the main function in a (`jspsych-waitfor-function`)[jspsych-waitfor-function.md] trial. That means a loader will be displayed on the page (for at least 1 s) while this is running.
|
||||
|
||||
### `after_the_run()`
|
||||
|
||||
This callback is called after a run is finished, i.e. after the procedure has converged and a threshold has been obtained, or when there's been too many trials, or a difference too large has been requested. You can use this to send data to the server. It has the following signature:
|
||||
|
||||
```javascript
|
||||
function after_the_run(options, condition, data, success_cb) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Here are the arguments:
|
||||
|
||||
* `options`: The general options.
|
||||
|
||||
* `condition`: The condition label (or definition).
|
||||
|
||||
* `data`: This is a jsPsych [DataCollection](https://www.jspsych.org/core_library/jspsych-data/#datacollection) object containing the trials of the run. At the end of the run, a new row is added with `type: 'threshold'`, containing the threshold information.
|
||||
|
||||
* `success_cb`: You have to call this callback once you're done. It takes no argument (or optionally some data you might want to add to the jsPsych experiment data). If the function is synchronous, just call it at the end of your function. If it runs asynchronously, pass the callback to your async function.
|
||||
|
||||
## Data
|
||||
|
||||
When a run is finished, the following data row is added to the jsPsych data collection:
|
||||
|
||||
```javascript
|
||||
{
|
||||
type: 'threshold',
|
||||
threshold: thr, // this is the arithmetic mean of the turn-points, or NaN
|
||||
geom_threshold: geom_thr, // this is the geometric mean of the turn-points, or NaN
|
||||
reason: 'nturns', // the reason why the run ended, can be 'ntrials', 'max_difference'
|
||||
steps: steps, // the list of steps
|
||||
differences: differences, // the list of differences
|
||||
condition: condition, // the condition label
|
||||
corrects: corrects, // the list of responses
|
||||
internal_node_id: data.last().select('internal_node_id').values[0] // The internal_node_id, this can be removed before transmission to server.
|
||||
}
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Here's a simplified example with some pseudo code so that you get an idea of how to implement this experiment. This is the code of the whole HTML file:
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<title>Adaptive nAFC</title>
|
||||
|
||||
<link rel="stylesheet" href="/css/semantic.css">
|
||||
<script src="/css/semantic.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/css/jspsych.css">
|
||||
|
||||
<script src="/js/vendor/jquery.js"></script>
|
||||
<script src="/js/vendor/jspsych.js"></script>
|
||||
<script src="/js/vendor/jspsych-plugins/jspsych-instructions.js"></script>
|
||||
<script src="/js/vendor/jspsych-plugins/jspsych-waitfor-function.js"></script>
|
||||
<script src="/js/vendor/jspsych-plugins/jspsych-html-button-response.js"></script>
|
||||
<script src="/js/vendor/jspsych-plugins/jspsych-audio-sequence-button-response.js"></script>
|
||||
<script src="/js/jspsych-nafc-adaptive.js"></script>
|
||||
<script src="/js/tools.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="jspsych-target"></div>
|
||||
<script>
|
||||
function show_error_nAFC(msg){
|
||||
$('#jspsych-target').append("<div class='ui error message'>"+msg+"</div>");
|
||||
}
|
||||
|
||||
function send_nAFC_data(options, condition, data, success_cb)
|
||||
{
|
||||
var dat = {
|
||||
exp_id: EXP_ID,
|
||||
subject_id: SUBJECT_ID,
|
||||
to: 'trial',
|
||||
trial_id: TRIAL_ID+'/'+condition,
|
||||
trial: data.values(),
|
||||
response: jsPsych.data.get().filter({type: 'threshold'}).last().values()[0],
|
||||
};
|
||||
$.post({
|
||||
url: "myserver.org/ajax/data-handler.php",
|
||||
data: dat,
|
||||
success: success_cb,
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
show_error_nAFC(errorThrown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function prepare_trial(last_trial, step, options, condition, done){
|
||||
|
||||
// If this is the first time, `last_trial` will be undefined
|
||||
|
||||
var diff = options.current_difference + step;
|
||||
|
||||
// We can get some random stuff and access our custom options (see below)
|
||||
var syllables = jsPsych.randomization.sampleWithoutReplacement(options.syllables, 3);
|
||||
|
||||
// We pre-allocate `new_trial`
|
||||
var new_trial = {
|
||||
stimuli: null,
|
||||
i_correct: getRandomIntInclusive(0,options.intervals.length-1),
|
||||
trial_definition: {
|
||||
dim: diff,
|
||||
condition: condition,
|
||||
stimuli: syllables
|
||||
}, // The parameters that define the trial
|
||||
step: step, // Just in case we modified the provided step
|
||||
difference: diff
|
||||
};
|
||||
|
||||
// We need to prepare N stimuli, where one is the odd-one-out,
|
||||
// based on diff. This can be done server side, with a callback.
|
||||
$.post({
|
||||
url: "myserver.org/prepare_stimuli.php",
|
||||
data: new_trial,
|
||||
success: function(dat) {
|
||||
var files = JSON.parse(dat); // Assuming we're getting a list of files from server
|
||||
new_trial.stimuli = files;
|
||||
// We call 'done' to start the trial.
|
||||
done(new_trial);
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
show_error_nAFC(errorThrown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var options = {
|
||||
initial_step_size: 2,
|
||||
starting_difference: 12,
|
||||
step_size_modifier: 1/Math.sqrt(2),
|
||||
down_up: [2, 1], // 2-down, 1-up => 70.7%
|
||||
terminate_on_nturns: 8,
|
||||
terminate_on_ntrials: 150,
|
||||
terminate_on_max_difference: 25,
|
||||
threshold_on_last_nturns: 6,
|
||||
change_step_size_on_difference: 2,
|
||||
change_step_size_on_ntrials: 15,
|
||||
intervals: ['1', '2', '3'],
|
||||
prepare_trial: prepare_trial,
|
||||
after_the_run: send_nAFC_data, // function(data, success_cb())
|
||||
start_button: 'Start',
|
||||
prompt: "Which of the three is different from the two others?",
|
||||
opening_message: "<h1>Test</h1><p>You will hear three sounds. Choose the one that is different from the two others.</p>",
|
||||
closing_message: "<h1>Thank you!</h1><p>This is the end of this block. Thank you for your help!</p>",
|
||||
isi: 500, // Note that the original experiment had more like 600ms
|
||||
visual_feedback: true,
|
||||
|
||||
/* ------- Our custom options ------- */
|
||||
sound_folder: 'CV/nl_nl',
|
||||
sound_format: 'wav',
|
||||
syllables: ["su", "si+", "po", "l@", "sa", "r3", "di", "f3", "ra", "t@", "pi", "ni+"]
|
||||
};
|
||||
|
||||
// We do this to defer to when the document is ready
|
||||
$(function(){
|
||||
|
||||
var main_timeline = [];
|
||||
var conditions = ['A', 'B', 'C'];
|
||||
|
||||
// We create a run for each condition
|
||||
for(c of conditions)
|
||||
{
|
||||
main_timeline.push( nAFC_adapt(options, c) );
|
||||
}
|
||||
|
||||
// You can add other trials before or after the adaptive runs, here.
|
||||
|
||||
jsPsych.init({
|
||||
timeline: main_timeline,
|
||||
display_element: 'jspsych-target',
|
||||
show_progress_bar: true,
|
||||
auto_update_progress_bar: false,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
61
docs/jspsych-waitfor-function.md
Normal file
61
docs/jspsych-waitfor-function.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# jspsych-waitfor-function
|
||||
|
||||
This plugin executes a specified function and displays a spinning wheel while waiting for the function to complete.
|
||||
This allows the experimenter to run arbitrary code at any point during the experiment.
|
||||
|
||||
The function cannot take any arguments. If arguments are needed, then an anonymous function should be used to wrap the function call (see examples below).
|
||||
|
||||
This plugin is based on [jspsych-call-function](https://www.jspsych.org/plugins/jspsych-call-function/).
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.
|
||||
|
||||
Parameter | Type | Default Value | Description
|
||||
-------------|----------|---------------|------------
|
||||
func | function | *undefined* | The function to call. See the `async` argument for details.
|
||||
async | boolean | `false` | If set to true, `func` will be executed asynchoronously. In that case, the first argument passed to `func` is a callback that jsPsych will pass to it, and that you need to call when the async operation is complete. This callback can receive data as argument, that will be added to the trial's data. See example below.
|
||||
min_duration | int | 0 | The spinner will be displayed *at least* this time. Value in milliseconds.
|
||||
|
||||
## Data Generated
|
||||
|
||||
In addition to the [default data collected by all plugins](https://www.jspsych.org/plugins/overview/#data-collected-by-plugins), this plugin collects the following data for each trial.
|
||||
|
||||
Name | Type | Value
|
||||
-----|------|------
|
||||
value | any | The return value of the called function.
|
||||
|
||||
## Dependencies
|
||||
|
||||
The spinner is currently using Semantic UI's [loader](https://semantic-ui.com/elements/loader.html), so you need to add the related CSS (and its dependencies) to your page, or the whole Semantic CSS.
|
||||
|
||||
## Examples
|
||||
|
||||
### Async function call
|
||||
|
||||
When doing an asynchronous function call, the function needs to take a argument that will be a callback function (called `done` in the example below),
|
||||
and you need to execute that callback when the function is done doing its work:
|
||||
|
||||
```javascript
|
||||
var trial = {
|
||||
type: 'call-function',
|
||||
async: true,
|
||||
func: function(done){
|
||||
// can perform async operations here like
|
||||
// creating an XMLHttpRequest to communicate
|
||||
// with a server
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var response_data = xhttp.responseText;
|
||||
// line below is what causes jsPsych to
|
||||
// continue to next trial. response_data
|
||||
// will be stored in jsPsych data object.
|
||||
done(response_data);
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", "path_to_server_script.php", true);
|
||||
xhttp.send();
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user