mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 10:40:54 +00:00
polished up QuestHandler, various comestic improvements, small fixes to Camera
This commit is contained in:
parent
0a7d15077c
commit
b6125d5b16
@ -145,9 +145,9 @@ export class PsychoJS
|
||||
psychoJS: this
|
||||
});
|
||||
|
||||
// to be loading `configURL` files in `_configure` calls from
|
||||
const hostsEvidently = new Set([...hosts, 'https://pavlovia.org/run/', 'https://run.pavlovia.org/']);
|
||||
this._hosts = Array.from(hostsEvidently);
|
||||
// add the pavlovia server to the list of hosts:
|
||||
const hostsWithPavlovia = new Set([...hosts, 'https://pavlovia.org/run/', 'https://run.pavlovia.org/']);
|
||||
this._hosts = Array.from(hostsWithPavlovia);
|
||||
|
||||
// GUI:
|
||||
this._gui = new GUI(this);
|
||||
@ -181,7 +181,7 @@ export class PsychoJS
|
||||
this.logger.info('[PsychoJS] Initialised.');
|
||||
this.logger.info('[PsychoJS] @version 2021.2.x');
|
||||
|
||||
// Hide #root::after
|
||||
// hide the initialisation message:
|
||||
jQuery('#root').addClass('is-ready');
|
||||
}
|
||||
|
||||
@ -591,17 +591,17 @@ export class PsychoJS
|
||||
{
|
||||
this.status = PsychoJS.Status.CONFIGURING;
|
||||
|
||||
// if the experiment is running from the pavlovia.org server, we read the configuration file:
|
||||
// if the experiment is running from an approved hosts, e.e pavlovia.org,
|
||||
// we read the configuration file:
|
||||
const experimentUrl = window.location.href;
|
||||
// go through each url in allow list
|
||||
const isHost = this._hosts.some(url => experimentUrl.indexOf(url) === 0);
|
||||
if (isHost)
|
||||
{
|
||||
const serverResponse = await this._serverManager.getConfiguration(configURL);
|
||||
this._config = serverResponse.config;
|
||||
|
||||
// legacy experiments had a psychoJsManager block instead of a pavlovia block,
|
||||
// and the URL pointed to https://pavlovia.org/server
|
||||
// update the configuration for legacy experiments, which had a psychoJsManager
|
||||
// block instead of a pavlovia block, with URL pointing to https://pavlovia.org/server
|
||||
if ('psychoJsManager' in this._config)
|
||||
{
|
||||
delete this._config.psychoJsManager;
|
||||
@ -744,10 +744,13 @@ export class PsychoJS
|
||||
window.onunhandledrejection = function (error)
|
||||
{
|
||||
console.error(error?.reason);
|
||||
if (error?.reason?.stack === undefined) {
|
||||
if (error?.reason?.stack === undefined)
|
||||
{
|
||||
// No stack? Error thrown by PsychoJS; stringify whole error
|
||||
document.body.setAttribute('data-error', JSON.stringify(error?.reason));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Yes stack? Error thrown by JS; stringify stack
|
||||
document.body.setAttribute('data-error', JSON.stringify(error?.reason?.stack));
|
||||
}
|
||||
|
@ -445,8 +445,7 @@ export class ServerManager extends PsychObject
|
||||
// if the experiment is hosted on the pavlovia.org server and
|
||||
// resources is [ServerManager.ALL_RESOURCES], then we register all the resources
|
||||
// in the "resources" sub-directory
|
||||
if (this._psychoJS.config.environment === ExperimentHandler.Environment.SERVER
|
||||
&& allResources)
|
||||
if (this._psychoJS.config.environment === ExperimentHandler.Environment.SERVER && allResources)
|
||||
{
|
||||
// list the resources from the resources directory of the experiment on the server:
|
||||
const serverResponse = await this._listResources();
|
||||
@ -475,8 +474,7 @@ export class ServerManager extends PsychObject
|
||||
{
|
||||
// we cannot ask for all resources to be registered locally, since we cannot list
|
||||
// them:
|
||||
if (this._psychoJS.config.environment === ExperimentHandler.Environment.LOCAL
|
||||
&& allResources)
|
||||
if (this._psychoJS.config.environment === ExperimentHandler.Environment.LOCAL && allResources)
|
||||
{
|
||||
throw "resources must be manually specified when the experiment is running locally: ALL_RESOURCES cannot be used";
|
||||
}
|
||||
@ -818,11 +816,11 @@ export class ServerManager extends PsychObject
|
||||
// query the pavlovia server:
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
mode: 'cors', // no-cors, *cors, same-origin
|
||||
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
|
||||
credentials: 'same-origin', // include, *same-origin, omit
|
||||
redirect: 'follow', // manual, *follow, error
|
||||
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
|
||||
mode: 'cors',
|
||||
cache: 'no-cache',
|
||||
credentials: 'same-origin',
|
||||
redirect: 'follow',
|
||||
referrerPolicy: 'no-referrer',
|
||||
body: formData
|
||||
});
|
||||
const jsonResponse = await response.json();
|
||||
|
@ -33,7 +33,7 @@ export class ExperimentHandler extends PsychObject
|
||||
/**
|
||||
* Getter for experimentEnded.
|
||||
*
|
||||
* @name module:core.Window#experimentEnded
|
||||
* @name module:data.ExperimentHandler#experimentEnded
|
||||
* @function
|
||||
* @public
|
||||
*/
|
||||
@ -45,7 +45,7 @@ export class ExperimentHandler extends PsychObject
|
||||
/**
|
||||
* Setter for experimentEnded.
|
||||
*
|
||||
* @name module:core.Window#experimentEnded
|
||||
* @name module:data.ExperimentHandler#experimentEnded
|
||||
* @function
|
||||
* @public
|
||||
*/
|
||||
|
@ -14,14 +14,26 @@ import {TrialHandler} from "./TrialHandler";
|
||||
|
||||
/**
|
||||
* <p>A Trial Handler that implements the Quest algorithm for quick measurement of
|
||||
psychophysical thresholds.</p>
|
||||
psychophysical thresholds.QuestHandler relies on the [jsQuest]{@link https://github.com/kurokida/jsQUEST} library, a port of Prof Dennis Pelli's QUEST algorithm by [Daiichiro Kuroki]{@link https://github.com/kurokida}.</p>
|
||||
*
|
||||
* @class
|
||||
* @extends PsychObject
|
||||
* @class module.data.QuestHandler
|
||||
* @extends TrialHandler
|
||||
* @param {Object} options
|
||||
* @param {module:core.PsychoJS} options.psychoJS - the PsychoJS instance
|
||||
* @param {string} options.varName - the name of the variable / intensity / contrast / threshold manipulated by QUEST
|
||||
* @param {number} options.startVal - initial guess for the threshold
|
||||
* @param {number} options.startValSd - standard deviation of the initial guess
|
||||
* @param {number} options.minVal - minimum value for the threshold
|
||||
* @param {number} options.maxVal - maximum value for the threshold
|
||||
* @param {number} [options.pThreshold=0.82] - threshold criterion expressed as probability of getting a correct response
|
||||
* @param {number} options.nTrials - maximum number of trials
|
||||
* @param {number} options.stopInterval - minimum [5%, 95%] confidence interval required for the loop to stop
|
||||
* @param {module:data.QuestHandler.Method} options.method - the QUEST method
|
||||
* @param {number} [options.beta=3.5] - steepness of the QUEST psychometric function
|
||||
* @param {number} [options.delta=0.01] - fraction of trials with blind responses
|
||||
* @param {number} [options.gamma=0.5] - fraction of trails that would generate a correct response when the threshold is infinitely small
|
||||
* @param {number} [options.grain=0.01] - quantization of the internal table
|
||||
* @param {string} options.name - name of the handler
|
||||
* @param {boolean} [options.autoLog= false] - whether or not to log
|
||||
*/
|
||||
export class QuestHandler extends TrialHandler
|
||||
@ -80,9 +92,11 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Add a response and update the PDF.
|
||||
*
|
||||
* @name module:data.QuestHandler#addResponse
|
||||
* @function
|
||||
* @public
|
||||
* @param{number} response - the response to the trial, must be either 0 (incorrect,
|
||||
* non-detected) or 1 (correct, detected).
|
||||
* @param{number} response - the response to the trial, must be either 0 (incorrect or
|
||||
* non-detected) or 1 (correct or detected).
|
||||
*/
|
||||
addResponse(response)
|
||||
{
|
||||
@ -110,7 +124,10 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Simulate a response.
|
||||
*
|
||||
* @param{number} trueValue
|
||||
* @name module:data.QuestHandler#simulate
|
||||
* @function
|
||||
* @public
|
||||
* @param{number} trueValue - the true, known value of the threshold / contrast / intensity
|
||||
*/
|
||||
simulate(trueValue)
|
||||
{
|
||||
@ -128,6 +145,9 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Get the mean of the Quest posterior PDF.
|
||||
*
|
||||
* @name module:data.QuestHandler#mean
|
||||
* @function
|
||||
* @public
|
||||
* @returns {number} the mean
|
||||
*/
|
||||
mean()
|
||||
@ -139,6 +159,9 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Get the standard deviation of the Quest posterior PDF.
|
||||
*
|
||||
* @name module:data.QuestHandler#sd
|
||||
* @function
|
||||
* @public
|
||||
* @returns {number} the standard deviation
|
||||
*/
|
||||
sd()
|
||||
@ -150,6 +173,9 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Get the mode of the Quest posterior PDF.
|
||||
*
|
||||
* @name module:data.QuestHandler#mode
|
||||
* @function
|
||||
* @public
|
||||
* @returns {number} the mode
|
||||
*/
|
||||
mode()
|
||||
@ -162,6 +188,9 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Get the standard deviation of the Quest posterior PDF.
|
||||
*
|
||||
* @name module:data.QuestHandler#quantile
|
||||
* @function
|
||||
* @public
|
||||
* @param{number} quantileOrder the quantile order
|
||||
* @returns {number} the quantile
|
||||
*/
|
||||
@ -174,6 +203,8 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Get an estimate of the 5%-95% confidence interval (CI).
|
||||
*
|
||||
* @name module:data.QuestHandler#confInterval
|
||||
* @function
|
||||
* @public
|
||||
* @param{boolean} [getDifference=false] if true, return the width of the CI instead of the CI
|
||||
*/
|
||||
@ -198,6 +229,8 @@ export class QuestHandler extends TrialHandler
|
||||
/**
|
||||
* Setup the JS Quest object.
|
||||
*
|
||||
* @name module:data.QuestHandler#_setupJsQuest
|
||||
* @function
|
||||
* @protected
|
||||
*/
|
||||
_setupJsQuest()
|
||||
@ -219,6 +252,8 @@ export class QuestHandler extends TrialHandler
|
||||
* Estimate the next value of the QUEST variable, based on the current value
|
||||
* and on the selected QUEST method.
|
||||
*
|
||||
* @name module:data.QuestHandler#_estimateQuestValue
|
||||
* @function
|
||||
* @protected
|
||||
*/
|
||||
_estimateQuestValue()
|
||||
@ -248,7 +283,6 @@ export class QuestHandler extends TrialHandler
|
||||
|
||||
this._psychoJS.logger.debug(`estimated value for QUEST variable ${this._varName}: ${this._questValue}`);
|
||||
|
||||
|
||||
// check whether we should finish the trial:
|
||||
if (this.thisN > 0 &&
|
||||
(this.nRemaining === 0 || this.confInterval(true) < this._stopInterval))
|
||||
@ -269,7 +303,6 @@ export class QuestHandler extends TrialHandler
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// update the next undefined trial in the trial list, and the associated snapshot:
|
||||
for (let t = 0; t < this._trialList.length; ++t)
|
||||
{
|
||||
|
@ -1454,5 +1454,10 @@ export function extensionFromMimeType(mimeType)
|
||||
return '.wav';
|
||||
}
|
||||
|
||||
if (mimeType.indexOf('video/webm') === 0)
|
||||
{
|
||||
return '.webm';
|
||||
}
|
||||
|
||||
return '.dat';
|
||||
}
|
||||
|
@ -456,14 +456,15 @@ export class Camera extends PsychObject
|
||||
|
||||
// create a new stream with ideal dimensions:
|
||||
this._stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: {
|
||||
video: true
|
||||
/*video: {
|
||||
width: {
|
||||
ideal: 1920
|
||||
ideal: 640 //1920
|
||||
},
|
||||
height: {
|
||||
ideal: 1080
|
||||
ideal: 480 //1080
|
||||
}
|
||||
}
|
||||
}*/
|
||||
});
|
||||
|
||||
// check the actual width and height:
|
||||
|
Loading…
Reference in New Issue
Block a user