aiom_pack
Version:
Framework for interdependent (mcmc-like) behavioral experiments
87 lines (80 loc) • 3.16 kB
JavaScript
// controllers/dataController.js
const { pool } = require('../../core/database');
const transformer = require('../../models/transformer');
const fs = require('fs');
const path = require('path');
class CategorizationController {
constructor(experimentPath) {
this.folderPath = path.join(experimentPath, 'static/stimuli/categorization');
const files = fs.readdirSync(this.folderPath);
this.colnames = files.map(file => file.split('.')[0]);
this.postfix = files[0].split('.')[1];
this.cat_table_name = 'categorization';
}
async setupCategorization() {
try {
// Create table if it doesn't exist
await pool.query(`CREATE TABLE IF NOT EXISTS ${this.cat_table_name} (
id SERIAL PRIMARY KEY,
participant TEXT NOT NULL
);`);
// Add columns if they don't exist
for (const colname of this.colnames) {
await pool.query(`
ALTER TABLE ${this.cat_table_name}
ADD COLUMN IF NOT EXISTS "${colname}" TEXT,
ADD COLUMN IF NOT EXISTS "${colname}_conf" INTEGER;
`);
}
} catch (error) {
console.error('Error setting up categorization database:', error);
}
}
async get_stimuli(req, res, next) {
const name = req.header('ID');
let selected_stimulus;
try {
// check if the participant already exists in the table
const participant = await pool.query(`SELECT * FROM ${this.cat_table_name} WHERE participant = $1`, [name]);
if (participant.rowCount === 0) {
await pool.query(`INSERT INTO ${this.cat_table_name} (participant) VALUES ($1)`, [name]);
selected_stimulus = this.colnames[Math.floor(Math.random() * this.colnames.length)];
} else {
// get a colname from the participant's row where the value is null
const null_colnames = this.colnames.filter(colname => participant.rows[0][colname] === null);
selected_stimulus = null_colnames[Math.floor(Math.random() * null_colnames.length)];
}
const stimulus_path = path.join(this.folderPath, selected_stimulus + '.' + this.postfix);
res.status(200).json({
"filename": selected_stimulus,
"stimulus": transformer.grab_image(stimulus_path)
});
} catch (error) {
next(error);
}
}
async register_choices(req, res, next) {
const name = req.header('ID');
const filename = req.header('filename');
const n_trial = req.header('n_trial');
const selected = req.body.choice;
const confidence = req.body.confidence;
const max_trial = this.colnames.length;
try {
await pool.query(
`UPDATE ${this.cat_table_name}
SET "${filename}" = $1, "${filename}_conf" = $2
WHERE participant = $3`,
[selected, confidence, name]
);
if (n_trial < max_trial) {
res.status(200).json({"finish": 0, "progress": n_trial/max_trial});
} else {
res.status(200).json({"finish": 1, "progress": 0});
}
} catch (error) {
next(error);
}
}
}
module.exports = { CategorizationController };