npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@kogpsy/jspsych-staircase

v1.1.2

Published

A small framework that integrates with jsPsych to build staircase method timelines.

Downloads

2

Readme

jspsych-staircase

A small framework that integrates with jsPsych to build staircase method timelines.

npm version

How to use

With the staircase method, one can measure individual perceptual thresholds. It can be used as a calibration which preceeds the actual experiment, to make sure the collected data points are clustered around the psychometric threshold.

As an example, let's assume we want to present participants with a word (either black or block). The word is displayed really quickly, and we want to figure out the exact presentation time, at which a participant gets a response accuracy of 70%. This serves as a simplified example with no claim of relevance and important methodological considerations (e.g. stimulus masking) left out. Basic jsPsych knowledge is assumed.

Terminology

We first briefly define some terms to prevent confusion.

A presentation is a set of jsPsych trials which includes at least the stimulus (here the word) and the response screen (fixation and masking would be part of a presentation as well).

A cycle is one run during which multiple presentations take place, and after which the performance is evaluated and the diffculty is adjusted. We might, e.g., present the participants with 10 words (randomly sampled, either black or block), and then evaluate their accuracy. If the accuracy is higher than our target, the difficulty is increased, if it is lower, the difficulty is decreased.

The full staircase procedure consists of a certain number of cycles.

Example

Install the library:

$ yarn add @kogpsy/jspsych-staircase

Then import the generateStaircaseTimeline() function in your experiment file:

import { generateStaircaseTimeline } from '@kogpsy/jspsych-staircase';

This function takes a configuration object and returns a jsPsych timeline object which you can add to your main timeline. We will now go through some basic configuration options. First we create a difficulty object:

// The difficulty variable (in our example in milliseconds)
let difficulty = 80;
// And the difficulty object
const difficultyStaircase = {
  max: 1,
  min: 100,
  get: () => {
    return difficulty;
  },
  set: (value) => {
    difficulty = value;
  },
};

Note that bigger difficulty numbers do not always mean the tasks is more difficult. With presentation times, as in our example, a presentation time of 100ms is easier than a presentation time of 20ms. You can (and must) define your own difficulty scale by setting the max and min fields of the difficulty object.

Now we can create our presentation and cycle logic:

// The stimulus trial (here just HTML displaying a word grabbed from timeline
// variables)
const stimulus = {
  type: HtmlKeyboardResponsePlugin,
  stimulus: () => {
    return `<p>${jsPsych.timelineVariable('word')}</p>`;
  },
  // The trial duration is set to the value of the difficulty (note that the
  // function is not called, but passed - it will get called at runtime).
  trial_duration: difficultyStaircase.get,
  post_trial_gap: 1000,
  choices: 'NO_KEYS',
};
// The response trial
const response = {
  type: HtmlKeyboardResponsePlugin,
  stimulus: `
    <p>
      Press [ F ] if you have read 'block' and [ J ] if you have read 'black'.
    </p>`,
  choices: ['f', 'j'],
  post_trial_gap: 500,
  on_finish: (data) => {
    // Important: you need to add a label to the trial data, so that
    // jspsych-staircase can identify the relevant trials to calculate accuracy.
    data.data_label = 'staircase';
    // Further we need to add a correct field, which holds true if the
    // participant responded correctly and false otherwise.
    const correctResponse = jsPsych.timelineVariable('correctResponse');
    data.correct = jsPsych.pluginAPI.compareKeys(
      data.response,
      correctResponse
    );
  },
};
// The cycle node. This presents the presentation (the above two trials) 5 times
// with the word 'black' and 5 times with the word 'block', in random order.
const cycle = {
  timeline: [stimulus, response],
  timeline_variables: [
    { word: 'black', correctResponse: 'j' },
    { word: 'block', correctResponse: 'f' },
  ],
  sample: {
    type: 'fixed-repetitions',
    size: 5,
  },
};

See the comments to learn what each piece of this code does exactly. If things remain unclear, it might be a good idea to read through the jsPsych documentation, as this is mostly just jsPsych syntax.

Now we have the major building blocks to generate the staircase method timeline. To do so, call the generateStaircaseTimeline() function and pass a config object as a parameter:

const staircaseTimeline = generateStaircaseTimeline({
  // Your jsPsych instance (required to fetch data)
  jsPsychInstance: jsPsych,
  // The target accurcy (between 0 and 1)
  targetAccuracy: 0.7,
  // The number of cycles to be carried out
  numberOfCycles: 5,
  // The difficulty object
  difficulty: difficultyStaircase,
  // The data label. Must be the same string that you added to the response
  // trials.
  dataLabel: 'staircase',
  // And finally your cycle.
  cycle,
});
// Add it to your main timeline (may be called differently in your porject)
timeline.push(staircaseTimeline);

jspsych-staircase just generated a timeline for you, which will run your cycle 5 times and after each run it will adjust the difficulty according to the participant's performance.

For all configuration options, see the section below.

Configuration reference

The framework exposes one function which generates a jsPsych timeline based on the configuration object passed to it. Here you find all possible configuration options.

| Parameter | Type | Description | | ----------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | jsPsychInstance | object | The jsPsych instance of your experiment. | | targetAccuracy | number | The desired accuracy. This must be a number between 0 and 1. | | numberOfCycles | number | The number of cycles that should be carried out in total. | | dataLabel | string | The label you add to your response trial's data object. This is used internally to identify the relevant trials. See the example above, this should make it more clear. | | difficulty | object | The difficulty object, with a max and a min field, as well as a set() and a get() function. See the example above to learn what this is exaclty. | | cycle | object | A jsPsych node that describes one cycle. Again, see the example above for a more information. | | postCycleCallback (Optional) | function | A function which gets called after each cycle. It receives an object containing some information, most importantly the adjusted difficulty and the cycle accuracy. | | customDifficultyAdjuster (Optional) | function | By default, if the accuracy is e.g. 20% higher than the target accuracy, the difficulty will be increased by half of that value (i.e. 10%). To change this behavior, you can supply a custom adjuster function. It should take a difficulty object (see above), the accuracy of the past cycle and the target accuracy, and return the adjusted difficulty. |

Development

Available scripts:

yarn run build

Build and bundle the library with rollup. A JavaScript bundle as well as TypeScript declarations are placed in the dist/ directory.

yarn run fmt

Format the code with prettier. See .prettierrc.json for configuration options.

yarn run test

Run tests with Jest. To add new tests, simply create a *.test.ts file containing Jest tests. Refer to the Jest documentation for an in-depth tutorial.