Skip to content

Commit

Permalink
finish adding randomizers and move some info over from lookit-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Kim Scott committed Nov 7, 2020
1 parent fb2aebd commit 2d40118
Show file tree
Hide file tree
Showing 17 changed files with 2,810 additions and 124 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ node_modules
blueprints
vendor
helpers.js
_build
_themes
611 changes: 611 additions & 0 deletions app/components/exp-frame-base/conditional_logic.rst

Large diffs are not rendered by default.

57 changes: 8 additions & 49 deletions app/components/exp-frame-base/doc.rst
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
.. _base frame:

Overview
=================
All frames support...
======================

All Lookit frames share some common features. While frame-specific features are described on the pagse for those frames,
like exp-lookit-video, you can also use any of the parameters listed here to customize any frame, and will receive
the data and events described here.

Parameters
=================
------------------

There are several parameters that ALL frames accept to allow you to customize the study "flow," which are:

.. glossary::

.. _selectNextFrame:

selectNextFrame
selectNextFrame [String]
Function to select which frame index to go to when using the 'next' action on this
frame. Allows flexible looping / short-circuiting based on what has happened so far
in the study (e.g., once the child answers N questions correctly, move on to next
Expand Down Expand Up @@ -72,7 +72,7 @@ There are several parameters that ALL frames accept to allow you to customize th

.. _generateProperties:

generateProperties
generateProperties [String]
Function to generate additional properties for this frame (like {"kind": "exp-lookit-text"})
at the time the frame is initialized. Allows behavior of study to depend on what has
happened so far (e.g., answers on a form or to previous test trials).
Expand Down Expand Up @@ -155,48 +155,7 @@ There are several parameters that ALL frames accept to allow you to customize th
parameters
An object containing values for any parameters (variables) to use in this frame.
Any property VALUES in this frame that match any of the property NAMES in `parameters`
will be replaced by the corresponding parameter value. For example, suppose your frame
is:

.. code:: javascript
{
'kind': 'FRAME_KIND',
'parameters': {
'FRAME_KIND': 'exp-lookit-text'
}
}
Then the frame ``kind`` will be ``exp-lookit-text``. This may be useful if you need
to repeat values for different frame properties, especially if your frame is actually
a randomizer or group. You may use parameters nested within objects (at any depth) or
within lists.

You can also use selectors to randomly sample from or permute
a list defined in ``parameters``. Suppose ``STIMLIST`` is defined in
``parameters``, e.g. a list of potential stimuli. Rather than just using ``STIMLIST``
as a value in your frames, you can also:

- Select the Nth element (0-indexed) of the value of ``STIMLIST``: (Will cause error if ``N >= THELIST.length``)

``'parameterName': 'STIMLIST#N'``

- Select (uniformly) a random element of the value of ``STIMLIST``:

``'parameterName': 'STIMLIST#RAND'``

- Set ``parameterName`` to a random permutation of the value of ``STIMLIST``:

``'parameterName': 'STIMLIST#PERM'``

- Select the next element in a random permutation of the value of ``STIMLIST``, which is used across all
substitutions in this randomizer. This allows you, for instance, to provide a list
of possible images in your ``parameterSet``, and use a different one each frame with the
subset/order randomized per participant. If more ``STIMLIST#UNIQ`` parameters than
elements of ``STIMLIST`` are used, we loop back around to the start of the permutation
generated for this randomizer.

``'parameterName': 'STIMLIST#UNIQ'``
will be replaced by the corresponding parameter value. For details, see :ref:`frame parameters`.

There are also some miscellaneous parameters you can set on any frame:

Expand Down Expand Up @@ -230,7 +189,7 @@ There are also some miscellaneous parameters you can set on any frame:
adding this to an arbitrary frame.

Data collected
=================
------------------


.. glossary::
Expand All @@ -251,7 +210,7 @@ Data collected


Events recorded
=================
------------------

Events recorded by a frame will be available inside the ``expData`` for this session and frame. If the
frame ID is ``'0-video-config'``, then you could find a list of events in ``expData['0-video-config']['eventTimings']``.
Expand Down
75 changes: 75 additions & 0 deletions app/components/exp-frame-base/groups.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.. _frame groups:

Frame groups
=================

Overview
----------

Sometimes it may be convenient to group several frames together. For instance, you might want to randomize the order
of several blocks of trials, but keep the blocks together.

To create a frame group, set the frame ``"kind"`` to ``"group"``.

You will also need to provide a ``"frameList"`` which is a list of frames that go in this group.

You can optionally provide a ``"commonFrameProperties"`` object which provides default parameter-value pairs to add to
each frame in the list (any parameters additionally defined in the ``frameList`` will take precedence).

As with other frames, ``"parameters"`` can be defined on the frame group to allow substitution of values. This can
be a convenient way to substitute in common values across several frames, or even across your entire study - for instance,
if you want to use the same ``baseDir`` in every frame that supports it.

Example
----------

Here is an example of a frame group that just contains two text frames:

.. code:: json
"testFrameGroup": {
"kind": "group",
"frameList": [
{
"id": "first-test-trial",
"blocks": [
{
text: "Hello and welcome to the study"
}
]
},
{
"id": "second-test-trial",
"blocks": [
{
text: "Some more info"
}
]
}
],
"commonFrameProperties": {
"kind": "exp-lookit-text"
}
}
Parameters
----------------

.. glossary::

frameList [Array]
List of frames to be included in this group. All frames will be displayed in order. Each frame is an
object with any necessary frame-specific properties specified. The
'kind' of frame can be specified either here (per frame) or in
commonFrameProperties. If a property is defined for a given frame both
in this frame list and in commonFrameProperties, the value in the frame
list will take precedence.

(E.g., you could include ``'kind': 'normal-frame'`` in
commmonFrameProperties, but for a single frame in frameOptions, include
``'kind': 'special-frame'``.)

commonFrameProperties [Object]
Object describing common parameters to use as defaults for every frame created
by this randomizer. Parameter names and values are as described in
the documentation for the frameType used.
136 changes: 136 additions & 0 deletions app/components/exp-frame-base/parameters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
.. _frame parameters:

Frame parameters
=================

Overview
----------

Frame parameters can be used to reuse or randomize values in any Lookit frame.

Rather than inserting actual values for frame properties such as stimulus image locations,
you may want sometimes want to use a variable the way you would in a programming language -
for instance, so that you can show the same cat picture throughout a group of frames, without
having to replace it in ten separate places if you decide to use a different one.
You can accomplish this (and more, including selecting randomly from or cycling through lists
of values) by setting the ``"parameters"`` property on any frame (including frame groups and
randomizers).

Syntax
--------

You can pass frame parameters to any frame by including ``"parameters": { ... }`` in the frame definition, like
this:

.. code::
{
'kind': 'FRAME_KIND',
'parameters': {
'FRAME_KIND': 'exp-lookit-text'
}
}
Any property *values* in this frame that match any of the property *names* in ``parameters``
will be replaced by the corresponding parameter value. For example, the frame above will be resolved to
have ``'kind': 'exp-lookit-text'``.

Frame parameters are useful if you need to repeat values for different properties or across multiple frames, especially
if your frame is actually a randomizer or group. You may use parameters nested within objects (at any depth) or
within lists.

You can also use selectors to randomly sample from or permute
a list defined in ``parameters``. Suppose ``STIMLIST`` is defined in
``parameters``, e.g. a list of potential stimuli. Rather than just using ``STIMLIST``
as a value in your frames, you can also:

- Select the Nth element (0-indexed) of the value of ``STIMLIST``: (Will cause error if ``N >= THELIST.length``)

``'parameterName': 'STIMLIST#N'``

- Select (uniformly) a random element of the value of ``STIMLIST``:

``'parameterName': 'STIMLIST#RAND'``

- Set ``parameterName`` to a random permutation of the value of ``STIMLIST``:

``'parameterName': 'STIMLIST#PERM'``

- Select the next element in a random permutation of the value of ``STIMLIST``, which is used across all
substitutions in this randomizer. This allows you, for instance, to provide a list
of possible images in your ``parameterSet``, and use a different one each frame with the
subset/order randomized per participant. If more ``STIMLIST#UNIQ`` parameters than
elements of ``STIMLIST`` are used, we loop back around to the start of the permutation
generated for this randomizer.

``'parameterName': 'STIMLIST#UNIQ'``


Case study: randomizing the order of options in a survey
--------------------------------------------------------

Suppose you're including a survey where you ask participants to record whether their child performed a certain task, and you want to present the options in a random order to avoid systematically biasing the results towards either option. You start with a survey frame like this (see the frame docs for more information about this frame):

.. code:: json
"example-survey": {
"kind": "exp-lookit-survey",
"formSchema": {
"schema": {
"type": "object",
"title": "And now, a thrilling survey!",
"properties": {
"didit": {
"enum": ["yes", "no"],
"type": "string",
"title": "Did your child do the thing?",
"default": ""
}
}
},
"options": {
"fields": {
"didit": {
"type": "radio",
"validator": "required-field"
}
}
}
}
},
To randomize the options, we'll need to make a few small changes. First, add ``"sort": false`` to the options for your ``didit`` field, so that AlpacaJS doesn't automatically sort the options alphabetically.

Next, you want the ``enum`` list for ``didit`` to actually be in random order. To achieve that, you can add a property like ``DIDIT_OPTIONS`` as a frame property, and then specify that the value of ``enum`` should be a random permutation of that list, like this:

.. code:: json
"example-survey": {
"kind": "exp-lookit-survey",
"formSchema": {
"schema": {
"type": "object",
"title": "And now, a thrilling survey!",
"properties": {
"didit": {
"enum": "DIDIT_OPTIONS#PERM",
"type": "string",
"title": "Did your child do the thing?",
"default": ""
}
}
},
"options": {
"fields": {
"didit": {
"sort": false,
"type": "radio",
"validator": "required-field"
}
}
}
},
"parameters": {
"DIDIT_OPTIONS": ["yes", "no"]
}
},
2 changes: 1 addition & 1 deletion app/components/exp-lookit-video/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ let ExpLookitVideo = ExpFrameBaseComponent.extend(VideoRecord, ExpandAssets, {
}
},

isReadyToFinish() {
isReadyToFinish() {
let ready = (this.get('testVideoTimesPlayed') >= this.get('requireVideoCount')) &&
(this.get('testAudioTimesPlayed') >= this.get('requireAudioCount')) &&
(this.get('satisfiedDuration'));
Expand Down

0 comments on commit 2d40118

Please sign in to comment.