diff --git a/package-lock.json b/package-lock.json index db37d2f..8c50be3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "effort-v1.3.3", - "version": "1.3.3", + "name": "effort-v1.3.4.2", + "version": "1.3.4.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index deefd1a..c922804 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "effort-v1.3.3", + "name": "effort-v1.3.4.2", "description": "all-in-one app with jsPsych + React + Electron + psiTurk", "author": { "name": "Wasita Mahaphanit (Brown) & Rashi Dhar (Brown CCV)", diff --git a/public/electron.js b/public/electron.js index 996941a..550b545 100644 --- a/public/electron.js +++ b/public/electron.js @@ -12,12 +12,12 @@ const log = require("electron-log"); const AT_HOME = process.env.REACT_APP_AT_HOME === "true"; // Event Trigger -const { eventCodes, comName } = require("./config/trigger"); -const { isPort, getPort, sendToPort } = require("event-marker"); +//const { eventCodes, comName } = require("./config/trigger"); +//const { isPort, getPort, sendToPort } = require("event-marker"); // Override comName if environment variable set -const activeComName = process.env.COMNAME || comName; -log.info("Trigger Box comName", activeComName); +//const activeComName = process.env.COMNAME || comName; +//log.info("Trigger Box comName", activeComName); // Data Saving const { dataDir } = require("./config/saveData"); @@ -99,97 +99,98 @@ function createWindow() { }); } // end of createWindow -// TRIGGER PORT HELPERS -let triggerPort; -let portAvailable; -let SKIP_SENDING_DEV = false; - -const setUpPort = async () => { - p = await getPort(activeComName); - if (p) { - triggerPort = p; - portAvailable = true; - - triggerPort.on("error", (err) => { - log.error(err); - let buttons = ["OK", "Continue Anyway"]; - // if (process.env.ELECTRON_START_URL) { - // buttons.push("Continue Anyway") - // } - dialog - .showMessageBox(mainWindow, { - type: "error", - message: "Error communicating with event marker.", - title: "Task Error", - buttons: buttons, - defaultId: 0, - }) - .then((opt) => { - if (opt.response == 0) { - app.exit(); - } else { - SKIP_SENDING_DEV = true; - portAvailable = false; - triggerPort = false; - } - }); - }); - } else { - triggerPort = false; - portAvailable = false; - } -}; - -const handleEventSend = async (code) => { - if (!portAvailable && !SKIP_SENDING_DEV) { - let message = "Event Marker not connected"; - log.warn(message); - let buttons = ["Quit", "Retry", "Continue Anyway"]; - // if (process.env.ELECTRON_START_URL) { - // buttons.push("Continue Anyway") - // } - dialog - .showMessageBox(mainWindow, { - type: "error", - message: message, - title: "Task Error", - buttons: buttons, - defaultId: 0, - }) - .then((resp) => { - let opt = resp.response; - if (opt == 0) { - // quit - app.exit(); - } else if (opt == 1) { - // retry - setUpPort().then(() => handleEventSend(code)); - } else if (opt == 2) { - SKIP_SENDING_DEV = true; - } - }); - } else if (!SKIP_SENDING_DEV) { - await sendToPort(triggerPort, code); - } -}; - -// EVENT TRIGGER - -ipc.on("trigger", (event, args) => { - let code = args; - if (code != undefined) { - log.info(`Event: ${_.invert(eventCodes)[code]}, code: ${code}`); - if (!AT_HOME) { - handleEventSend(code); - } - } -}); +// // TRIGGER PORT HELPERS +// let triggerPort; +// let portAvailable; +// let SKIP_SENDING_DEV = false; + +// const setUpPort = async () => { +// p = await getPort(activeComName); +// if (p) { +// triggerPort = p; +// portAvailable = true; + +// triggerPort.on("error", (err) => { +// log.error(err); +// let buttons = ["OK", "Continue Anyway"]; +// // if (process.env.ELECTRON_START_URL) { +// // buttons.push("Continue Anyway") +// // } +// dialog +// .showMessageBox(mainWindow, { +// type: "error", +// message: "Error communicating with event marker.", +// title: "Task Error", +// buttons: buttons, +// defaultId: 0, +// }) +// .then((opt) => { +// if (opt.response == 0) { +// app.exit(); +// } else { +// SKIP_SENDING_DEV = true; +// portAvailable = false; +// triggerPort = false; +// } +// }); +// }); +// } else { +// triggerPort = false; +// portAvailable = false; +// } +// }; + +// const handleEventSend = async (code) => { +// if (!portAvailable && !SKIP_SENDING_DEV) { +// let message = "Event Marker not connected"; +// log.warn(message); +// let buttons = ["Quit", "Retry", "Continue Anyway"]; +// // if (process.env.ELECTRON_START_URL) { +// // buttons.push("Continue Anyway") +// // } +// dialog +// .showMessageBox(mainWindow, { +// type: "error", +// message: message, +// title: "Task Error", +// buttons: buttons, +// defaultId: 0, +// }) +// .then((resp) => { +// let opt = resp.response; +// if (opt == 0) { +// // quit +// app.exit(); +// } else if (opt == 1) { +// // retry +// setUpPort().then(() => handleEventSend(code)); +// } else if (opt == 2) { +// SKIP_SENDING_DEV = true; +// } +// }); +// } else if (!SKIP_SENDING_DEV) { +// await sendToPort(triggerPort, code); +// } +// }; + +// // EVENT TRIGGER + +// ipc.on("trigger", (event, args) => { +// let code = args; +// if (code != undefined) { +// log.info(`Event: ${_.invert(eventCodes)[code]}, code: ${code}`); +// if (!AT_HOME) { +// handleEventSend(code); +// } +// } +// }); // INCREMENTAL FILE SAVING let stream = false; let fileName = ""; let filePath = ""; let patientID = ""; +let sessionNum = ""; let images = []; let startTrial = -1; @@ -199,8 +200,9 @@ ipc.on("data", (event, args) => { if (args.patient_id && fileName === "") { const dir = app.getPath("userData"); patientID = args.patient_id; + sessionNum = args.sessionNum; Effort = "Effort"; - fileName = `${patientID}_${Effort}.json`; + fileName = `${patientID}_${sessionNum}_${Effort}.json`; filePath = path.resolve(dir, fileName); startTrial = args.trial_index; log.warn(filePath); @@ -267,9 +269,9 @@ process.on("uncaughtException", (error) => { // Some APIs can only be used after this event occurs. app.on("ready", () => { createWindow(); - if (!AT_HOME) { - setUpPort().then(() => handleEventSend(eventCodes.test_connect)); - } + //if (!AT_HOME) { + //setUpPort().then(() => handleEventSend(eventCodes.test_connect)); + //} }); // Quit when all windows are closed. app.on("window-all-closed", function () { @@ -300,7 +302,7 @@ app.on("will-quit", () => { const today = new Date(Date.now()); // const date = today.toISOString().slice(0,10) // currently don't need date // fileName = `${patientID}_${Effort}.json` - const copyPath = path.join(desktop, dataDir, `${patientID}_${Effort}`); + const copyPath = path.join(desktop, dataDir, `${patientID}_${sessionNum}_${Effort}`); fs.mkdir(copyPath, { recursive: true }, (err) => { log.error(err); fs.copyFileSync(filePath, path.join(copyPath, fileName)); diff --git a/src/language/en_us.json b/src/language/en_us.json index 9ce218e..def50a3 100644 --- a/src/language/en_us.json +++ b/src/language/en_us.json @@ -2,7 +2,7 @@ "task": { "name": "Effort Task", "end": "This experiment has ended.", - "version": "v1.3.4" + "version": "v1.3.4.2" }, "prompt": { "continue": { @@ -25,7 +25,8 @@ "message": "Instructions" }, "userid": { - "set": "Please enter the Subject ID.
(The file will automatically be named Subject ID_Effort.)", + "set": "Please enter the Subject ID.
(The file will automatically be named Subject ID_Session_Effort.)", + "sessionNum": "Please enter the Session # (Enter ONLY 1 or 2).
(The file will automatically be named Subject ID_Session_Effort.)", "get_prolific": "Collecting your Prolific ID...", "set_prolific": "Please enter your Prolific ID into the box below:
Warning: You cannot leave this box empty!" }, diff --git a/src/lib/utils.js b/src/lib/utils.js index e159603..59afa48 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -108,9 +108,22 @@ const getProlificId = (data) => { }; const getUserId = (data) => { - const patientId = JSON.parse(data.responses)["Q0"]; - jsPsych.data.addProperties({ patient_id: patientId, timestamp: Date.now() }); - console.log("ID", patientId); + // IAN: Try to check that session number is correct (0 or 1). If it is not, + // we don't add Properties to data, and thus don't create a new listener. + if ( + // IAN: + JSON.parse(data.responses)["Q1"] == 1 || JSON.parse(data.responses)["Q1"] == 2 + ) { + const patientId = JSON.parse(data.responses)["Q0"]; + jsPsych.data.addProperties({ patient_id: patientId, timestamp: Date.now() }); + console.log("ID", patientId); + + const sessionNum = JSON.parse(data.responses)["Q1"]; + jsPsych.data.addProperties({ sessionNum: sessionNum, timestamp: Date.now() }); + console.log("session", sessionNum); + } + + }; export { diff --git a/src/timelines/main.js b/src/timelines/main.js index 09d85a9..18b9fc1 100644 --- a/src/timelines/main.js +++ b/src/timelines/main.js @@ -23,10 +23,12 @@ import { postPracticeInstructions, } from "../trials/instructions"; import quizTimeline from "../trials/quizTrials"; +import checkSessTimeline from "../trials/checkSess"; const inLabTimeline = [ experimentStart(), userId(), + checkSessTimeline(), preamble, bluePracticeInstructions(), buildCountdown(lang.countdown.practice1, 3), @@ -38,8 +40,8 @@ const inLabTimeline = [ buildCountdown(lang.countdown.practice3, 3), taskBlock(practiceBlock3), quizTimeline(practiceBlock3), - relaxReminder(), - recordNow(), + //relaxReminder(), + //recordNow(), postPracticeInstructions(), buildCountdown(lang.countdown.expt1, 3), practiceAndMainBlockDivider(500), diff --git a/src/timelines/taskTrial.js b/src/timelines/taskTrial.js index a0aaee0..53bae03 100644 --- a/src/timelines/taskTrial.js +++ b/src/timelines/taskTrial.js @@ -44,8 +44,8 @@ const taskTrial = (blockSettings, blockDetails, opts) => { // show condition fixation(300), rewardProbability(1000, blockSettings, opts, trialDetails), - frameSpike(700, blockSettings, opts, trialDetails), - costBenefits(1500, blockSettings, opts, trialDetails), + //frameSpike(700, blockSettings, opts, trialDetails), + //costBenefits(1500, blockSettings, opts, trialDetails), choice(6000, blockSettings, opts, trialDetails), pressBalloon(25000, blockSettings, opts), fixation(500), @@ -61,4 +61,4 @@ const taskTrial = (blockSettings, blockDetails, opts) => { }; }; -export default taskTrial; \ No newline at end of file +export default taskTrial; diff --git a/src/trials/checkSess.js b/src/trials/checkSess.js new file mode 100644 index 0000000..51ae065 --- /dev/null +++ b/src/trials/checkSess.js @@ -0,0 +1,44 @@ +import userId from "../trials/userId"; +import { jsPsych } from "jspsych-react"; + +const retakeLoop = () => { + return { + timeline: [ userId() ], + loop_function: () => { + const sess1 = jsPsych.data.getLastTrialData().values()[0]; + var sess = parseInt(JSON.parse(sess1.responses)["Q1"]); + + if ( + sess != 1 & sess!=2 + ) { + return true; + } else { + return false; + } + }, + }; + }; + +const checkSess = () => { + return { + timeline: [retakeLoop()], + conditional_function: () => { + const sess1 = jsPsych.data.getLastTrialData().values()[0]; + var sess = parseInt(JSON.parse(sess1.responses)["Q1"]); + if ( + sess != 1 & sess!=2 + ) { + return true; + } else { + return false; + } + }, + }; + }; + let checkSessTimeline = () => { + return { + timeline: [checkSess()], + type: "html_keyboard_response", + }; + } + export default checkSessTimeline; \ No newline at end of file diff --git a/src/trials/userId.js b/src/trials/userId.js index 6dc71ee..287ff72 100644 --- a/src/trials/userId.js +++ b/src/trials/userId.js @@ -50,13 +50,11 @@ const userId = () => { type: "survey_text", questions: [ { - prompt: baseStimulus( - `
-

${lang.userid.set}

-
`, - true - ), - }, + prompt:`${lang.userid.set}`, + }, + { + prompt:`${lang.userid.sessionNum}`, + }, ], on_finish: (data) => { getUserId(data);