Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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)",
Expand Down
190 changes: 96 additions & 94 deletions public/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;

Expand All @@ -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);
Expand Down Expand Up @@ -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 () {
Expand Down Expand Up @@ -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));
Expand Down
5 changes: 3 additions & 2 deletions src/language/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"task": {
"name": "Effort Task",
"end": "This experiment has ended.",
"version": "v1.3.4"
"version": "v1.3.4.2"
},
"prompt": {
"continue": {
Expand All @@ -25,7 +25,8 @@
"message": "Instructions"
},
"userid": {
"set": "Please enter the <i>Subject ID</i>. <br><span class='text-smoll'>(The file will automatically be named <i>Subject ID</i>_Effort.)</span>",
"set": "Please enter the <i>Subject ID</i>. <br><span class='text-smoll'>(The file will automatically be named <i>Subject ID</i>_<i>Session</i>_Effort.)</span>",
"sessionNum": "Please enter the <i>Session #</i> (Enter ONLY 1 or 2). <br><span class='text-smoll'>(The file will automatically be named <i>Subject ID</i>_<i>Session</i>_Effort.)</span>",
"get_prolific": "Collecting your Prolific ID...",
"set_prolific": "Please enter your Prolific ID into the box below:<br><span class='text-smoll'>Warning: You cannot leave this box empty!</span>"
},
Expand Down
19 changes: 16 additions & 3 deletions src/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 4 additions & 2 deletions src/timelines/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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),
Expand Down
6 changes: 3 additions & 3 deletions src/timelines/taskTrial.js
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -61,4 +61,4 @@ const taskTrial = (blockSettings, blockDetails, opts) => {
};
};

export default taskTrial;
export default taskTrial;
44 changes: 44 additions & 0 deletions src/trials/checkSess.js
Original file line number Diff line number Diff line change
@@ -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;
Loading