Implemented method for keeping track of all descriptions as dictionaries and testing

This commit is contained in:
vzhang03 2024-06-10 14:01:27 -04:00
parent 0de4185a8b
commit ae738f0e74
3 changed files with 55 additions and 38 deletions

View File

@ -13,6 +13,7 @@
var jsPsych = initJsPsych({ var jsPsych = initJsPsych({
on_finish: function() { on_finish: function() {
metadata.generate(jsPsych.data.get().json()); metadata.generate(jsPsych.data.get().json());
// metadata.saveAsJsonFile(); // metadata.saveAsJsonFile();

View File

@ -34,7 +34,7 @@ export class VariablesMap {
const trial_type_var = { const trial_type_var = {
type: "PropertyValue", type: "PropertyValue",
name: "trial_type", name: "trial_type",
description: "The name of the plugin used to run the trial.", description: { default: "The name of the plugin used to run the trial." },
value: "string", value: "string",
}; };
this.setVariable(trial_type_var); this.setVariable(trial_type_var);
@ -42,7 +42,7 @@ export class VariablesMap {
const trial_index_var = { const trial_index_var = {
type: "PropertyValue", type: "PropertyValue",
name: "trial_index", name: "trial_index",
description: "The index of the current trial across the whole experiment.", description: { default: "The index of the current trial across the whole experiment." },
value: "numeric", value: "numeric",
}; };
this.setVariable(trial_index_var); this.setVariable(trial_index_var);
@ -50,27 +50,13 @@ export class VariablesMap {
const time_elapsed_var = { const time_elapsed_var = {
type: "PropertyValue", type: "PropertyValue",
name: "time_elapsed", name: "time_elapsed",
description: description: {
"The number of milliseconds between the start of the experiment and when the trial ended.", default:
"The number of milliseconds between the start of the experiment and when the trial ended.",
},
value: "numeric", value: "numeric",
}; };
this.setVariable(time_elapsed_var); this.setVariable(time_elapsed_var);
// const response_time_var = {
// type: "PropertyValue",
// name: "rt", // adjusted to response time
// description: "Time measured in ms participant takes to respond to a stimulus",
// value: "numeric",
// };
// this.setVariable(response_time_var);
// not necessary in this iteration
// const internal_type_node_id = {
// type: "PropertyValue",
// name: "internal_node_id",
// description: "A string identifier for the current TimelineNode.",
// value: "interval",
// };
// this.setVariable(internal_type_node_id);
} }
/** /**
@ -80,8 +66,32 @@ export class VariablesMap {
*/ */
getList(): {}[] { getList(): {}[] {
var var_list = []; var var_list = [];
// need to check that this works as intended
for (const key of Object.keys(this.variables)) { for (const key of Object.keys(this.variables)) {
var_list.push(this.variables[key]); const variable = this.variables[key];
const description = variable["description"];
const numKeys = Object.keys(description).length;
if (numKeys === 0) console.error("Empty description"); // error: description empty
else if (numKeys === 1) {
// description becomes single field (assumed to be default)
const key = Object.keys(description)[0];
variable["description"] = description[key];
} else if (numKeys == 2) {
delete description["default"]; // deletes default
if (Object.keys(description).length == 1) {
// error checking that it reduced to one key
const key = Object.keys(description)[0];
variable["description"] = description[key];
}
} else if (numKeys > 2) {
// deletes default
delete description["default"];
}
var_list.push(variable);
} }
return var_list; return var_list;
} }
@ -189,11 +199,7 @@ export class VariablesMap {
this.updateLevels(updated_var, added_value); this.updateLevels(updated_var, added_value);
} else if (field_name === "minValue" || field_name === "maxValue") { } else if (field_name === "minValue" || field_name === "maxValue") {
this.updateMinMax(updated_var, added_value, field_name); this.updateMinMax(updated_var, added_value, field_name);
} else if ( } else if (field_name === "description") {
field_name === "description" &&
(var_name === "response" || var_name === "stimulus" || var_name == "rt") // error with not hard coding - mention with josh
) {
// handles logic with dict description
this.updateDescription(updated_var, added_value); this.updateDescription(updated_var, added_value);
} else if (field_name === "name") { } else if (field_name === "name") {
this.updateName(updated_var, added_value); this.updateName(updated_var, added_value);
@ -232,6 +238,12 @@ export class VariablesMap {
// getting key and value for new value for clarity // getting key and value for new value for clarity
const add_key = Object.keys(added_value)[0]; const add_key = Object.keys(added_value)[0];
const add_value = Object.values(added_value)[0]; const add_value = Object.values(added_value)[0];
if (add_key === "undefined" || add_value === "undefined") {
console.error("New value is passed in correct format");
return;
}
var exists = false; var exists = false;
// creates map for description if doesn't exist // creates map for description if doesn't exist
if (typeof updated_var["description"] !== "object") { if (typeof updated_var["description"] !== "object") {

View File

@ -11,6 +11,7 @@ import { VariablesMap } from "./VariablesMap";
* @typedef {JsPsychMetadata} * @typedef {JsPsychMetadata}
*/ */
export default class JsPsychMetadata { export default class JsPsychMetadata {
private count: number;
/** /**
* Field that contains all metadata fields that aren't represented as a list. * Field that contains all metadata fields that aren't represented as a list.
* *
@ -57,6 +58,7 @@ export default class JsPsychMetadata {
this.setMetadataField("description", "Dataset generated using JsPsych"); this.setMetadataField("description", "Dataset generated using JsPsych");
this.authors = new AuthorsMap(); this.authors = new AuthorsMap();
this.variables = new VariablesMap(); this.variables = new VariablesMap();
this.count = 0;
} }
/** /**
@ -244,6 +246,7 @@ export default class JsPsychMetadata {
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
} }
// passing in authors mapping and variables mapping and then goes through each variable
generate(data) { generate(data) {
// have it so that can pass in a dict of object that the researcher wants to do // have it so that can pass in a dict of object that the researcher wants to do
if (typeof data === "string") { if (typeof data === "string") {
@ -283,14 +286,13 @@ export default class JsPsychMetadata {
// probably should work in a call to the plugin here // probably should work in a call to the plugin here
const description = this.getPluginInfo(pluginType); const description = this.getPluginInfo(pluginType);
const type = typeof value; const type = typeof value;
// should check type in order to see if need to see with levels -- if numeric type is not it console.log(type);
// do need to update levels? -- write in levels logic ot the VariablesMap
// probs should have update description called here // probs should have update description called here
const new_var = { const new_var = {
type: "PropertyValue", type: "PropertyValue",
name: variable, name: variable,
description: "FILL IN THIS DESCRIPTION", // can't get description unless finish the unpkg description: { default: "FILL IN THIS DESCRIPTION" }, // can't get description unless finish the unpkg
value: type, value: type,
}; };
@ -301,22 +303,24 @@ export default class JsPsychMetadata {
} }
// hardest part is updating the description // hardest part is updating the description
// want to hardcode in the variables check
// logic is that probably won't need to be doing the dict thing
// implement all as description
private generateUpdate(variable, value, pluginType) { private generateUpdate(variable, value, pluginType) {
const type = typeof value; const type = typeof value;
const field_name = "description"; const field_name = "description";
// update description // update description
const description = this.getPluginInfo(pluginType); const description = this.getPluginInfo(pluginType);
const new_value = {}; // logic: this is an object with { key = pluginType, value = Description } // const new_value = { pluginType: description };
// if the field is already a dictionary const key = "hello" + this.count;
// if the new value that is being added doesn't match the old value const test_value = "THIS IS ANOTHER DESCRIPTION" + this.count;
const new_value = { [key]: test_value };
// fill in with logic on how to update the plugin -- will need to think about levels this.updateVariable(variable, field_name, new_value);
// need to call the other UPDATEVARIABLE logic -- where if it is just a description can probably add it to the thing
// how to check levels
// this.updateVariable(variable, field_name, new_value);
this.updateFields(variable, value, type); this.updateFields(variable, value, type);
this.count += 1;
} }
private updateFields(variable, value, type) { private updateFields(variable, value, type) {