Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
c5b5433
New project page
dhovart May 9, 2022
4ef39db
Add image adjustment settings component
dhovart Jun 7, 2022
b14ac30
Add Up / down arrows listeners on project page. Fix measurement tool
dhovart Jun 7, 2022
ae53c94
Add scriptconsole components. Clean up atlasmaker a bit
dhovart Jun 8, 2022
0f0b2a6
Update range slider
dhovart Jun 8, 2022
0cc2e78
Make sure to display notifications properly
dhovart Jun 8, 2022
ce5726c
Regenerate package lock file
dhovart Jun 8, 2022
32a8e74
Remove jQuery. Reorganize components using vue sfcs
dhovart Jun 9, 2022
0723cd0
Refactor MRI page (wip)
dhovart Jun 19, 2022
c4d214a
Make MRI and tools layout adaptative
dhovart Jun 26, 2022
f7a0561
Finalize the MRI page (display annotation access, style tweaks)
dhovart Jun 26, 2022
da67060
Update toolbar appearance & make it resizable
dhovart Jul 2, 2022
9ac11fa
Correct tools appearance, fix resizing issues
dhovart Aug 9, 2022
9def0c8
Fix default tools height
dhovart Aug 9, 2022
569b147
Sync annotations with atlasmaker server
dhovart Aug 9, 2022
5d0a8ea
Fix height and resizing issues
dhovart Aug 10, 2022
7a1e715
Update MRI page
dhovart Aug 10, 2022
c17f7bd
Properly resize visualization on MRI pages
dhovart Sep 20, 2022
95a9754
Correct tools resizing issues
dhovart Sep 21, 2022
c251b35
Add missing project name
dhovart Sep 26, 2022
13b3cef
Fix resize & fullscreen issues
dhovart Sep 26, 2022
92a6a54
Add embed page
dhovart Oct 24, 2022
cb81164
bump nwl-components package to 1.2.1
Jan 5, 2023
935f14b
update authenticated call count check in mri controller unit test
ntraut Feb 9, 2023
3ed8e97
fix vue compiler
ntraut Apr 13, 2023
15f3809
Fix badly resolved conflicts and remove Y.js related code for now
dhovart Jul 19, 2023
841c3ac
sync changes using hocus pocus as yjs backend
dhovart Jul 20, 2023
e0fc87a
Adjust chat height
dhovart Jul 21, 2023
b22ce6b
fix: iPad fixes
denishov Jul 25, 2023
c37fe0d
Display current slice on MRI page in tools palette header
denishov Jul 28, 2023
3e3e97b
Handle cases where MRI is empty
denishov Jul 28, 2023
c47654f
Update title in embedded projects. Add button on settings to embed pr…
denishov Jul 28, 2023
551e684
remove hardcoded crdt backend address
denishov Aug 2, 2023
1d2eb24
Handle user preferences
denishov Aug 8, 2023
8af4bb0
restore logToDatabase function
ntraut Sep 18, 2023
15345ac
give more flexibility to server configuration
ntraut Sep 18, 2023
afbb980
add eslint config for .vue files
ntraut Sep 22, 2023
de68bcd
close hocuspocus server at the end of tests
ntraut Sep 22, 2023
bf9684f
restore accidentally removed imports
ntraut Sep 23, 2023
d3c6ed9
Fix bad merge (#371)
denishov Sep 29, 2023
20161f6
Remove message that should not be logged in chat (#370)
denishov Sep 29, 2023
e66c4a8
Highlight fullscreen button when fullscreen is active (#369)
denishov Oct 2, 2023
30cb8c9
Properly lint Tools.vue
denishov Oct 2, 2023
11bf5dd
Bump nwl-components / style updates (#372)
denishov Oct 4, 2023
5eb59e1
Make sure vector layer is properly redimensionned (#368)
denishov Oct 4, 2023
0ada96c
Bump nwl-components / fade in and out for save feedback (#374)
denishov Oct 4, 2023
59d5b78
Hide by default chat in MRI mode (#375)
denishov Oct 10, 2023
a746c46
fix linting issues
ntraut Oct 19, 2023
f219d79
Fix integration tests
denishov Nov 23, 2023
0927e2f
Fix brainbox unit tests
denishov Nov 28, 2023
ae5c720
fix object merge function
ntraut Nov 29, 2023
b306d51
fix bad svg created before brain is loaded
ntraut Nov 29, 2023
7ea9c02
fix some server crashes
ntraut Nov 29, 2023
f542d63
small fixes
ntraut Dec 13, 2023
b1599e4
upgrade webpack to v5
ntraut Dec 18, 2023
19fb533
Properly check if content can be embedded (#385)
denishov Dec 29, 2023
92cf6d1
Add CSP header to allow embedding only by specific domains set in the…
denishov Jan 28, 2024
7b6b177
remove invalid characters in authorized host list
ntraut Feb 12, 2024
6052d51
lint code
ntraut Mar 29, 2024
278f29b
check that authorized hosts are valid url
ntraut Mar 29, 2024
94e4f03
return empty file array for empty project instead of void
ntraut Mar 29, 2024
1809245
set up vue compile flags
ntraut Jul 5, 2024
2044ac1
fix tooltip not showing for some tools
ntraut Feb 21, 2025
28356b4
fix display setting sliders values not preserved
ntraut Feb 24, 2025
3906c25
lint code
ntraut Mar 22, 2025
bb8e33b
request animation frame before drawing images to avoid lag
ntraut Mar 22, 2025
8a75d9c
avoid brainbox crash when user variable is not set
ntraut Mar 22, 2025
2b3dbff
fix annotation upload not working
ntraut Mar 22, 2025
a3bfb06
fix fullscreen and tools component display
ntraut Apr 18, 2025
133d420
restore slice changing with keyboard
ntraut Apr 22, 2025
17fa690
lint server code
ntraut Apr 22, 2025
4ce729a
fix logToDatabase function not returning directly payload
ntraut Apr 22, 2025
82ee5b9
fix 3d rendering no longer working
ntraut Apr 22, 2025
c02fcb1
Merge remote-tracking branch 'origin/master' into new-project-page-co…
ntraut Apr 29, 2025
9fb4e11
improve consistency between internal and displayed selected file
ntraut Apr 30, 2025
a80f447
Merge remote-tracking branch 'origin' into new-project-page-components
ntraut May 14, 2025
39f2ffc
remove unused dependencies
ntraut May 15, 2025
8299759
use readline to get server commands instead of keypress
ntraut May 15, 2025
51ea42d
update text annotations in db directly
ntraut May 15, 2025
1e13623
replace yjs with websocket implementation
ntraut May 21, 2025
9db9de4
display error when brain cannot be loaded
ntraut Jun 6, 2025
20d2076
fix toolbox touch move and overflow
ntraut Jun 6, 2025
754c7ac
update access rights on volume annotation change
ntraut Jul 13, 2025
7786c5a
fix eyedrop tool
ntraut Jul 13, 2025
97b76d1
fix access rights not set when creating new volume annotation from pr…
ntraut Jul 15, 2025
594ef29
various fixes
ntraut Jul 22, 2025
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
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/public/lib/
/public/js/
/public/js/*
!/public/js/surfacenets-worker.js
dist/
/view/atlasmaker/src/tools/render3D/three.js*
12 changes: 11 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,15 @@ module.exports = {
'env': {
'mocha': true
},
'extends': ['naat']
'extends': ['naat', 'plugin:vue/vue3-strongly-recommended'],
'rules': { 'vue/multi-word-component-names': 'off' },
'overrides': [
{
files: ['*.vue'],
rules: {
// 300 lines limit seems to short for *.vue files
'max-lines': 'off'
}
}
]
};
10 changes: 2 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,8 @@ public/_img-all/
public/.DS_Store
public/data
public/doc2/*
public/js/
public/js/ask-for-login-page.js
public/js/index-page.js
public/js/mri-page.js
public/js/project-new-page.js
public/js/project-page.js
public/js/project-settings-page.js
public/js/user-page.js
/public/js/*
!/public/js/surfacenets-worker.js
public/lib/.DS_Store
public/lib/atlasmaker-tools
public/lib/atlasmaker.js
Expand Down
10 changes: 8 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
"editor.formatOnSave": false,
"editor.codeActionsOnSave": [
// "source.formatDocument", // problem with switch case multi lines comment indents
"source.fixAll.eslint" // used by dbaeumer.vscode-eslint
"source.fixAll.eslint"
]
},
"[vue]": {
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
}
}
}
28 changes: 14 additions & 14 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
Atlas Maker Server
Roberto Toro, 25 July 2014
*/
const nwl = require('neuroweblab');
const fs = require('fs');
const express = require('express');
const compression = require('compression');
const http = require('http');
const https = require('https');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const tracer = require('tracer').console({ format: '[{{file}}:{{line}}] {{message}}' });
const cookieParser = require('cookie-parser');

const bodyParser = require('body-parser');
const compression = require('compression');
const cookieParser = require('cookie-parser');
const express = require('express');
const logger = require('morgan');
const mustacheExpress = require('mustache-express');
const nwl = require('neuroweblab');
const favicon = require('serve-favicon');
const tracer = require('tracer').console({ format: '[{{file}}:{{line}}] {{message}}' });
const Config = JSON.parse(fs.readFileSync('./cfg.json'));
const https = require('https');
const http = require('http');

global.authTokenMiddleware = nwl.authTokenMiddleware;

const AtlasmakerServer = require('./controller/atlasmakerServer/atlasmakerServer');
Expand Down Expand Up @@ -129,7 +129,7 @@ const start = async function () {
// Configure server and web socket
//========================================================================================

const server = http.createServer(app).listen(3001, () => { console.log('Listening http on port 3001'); });
const server = http.createServer(app).listen(Config.app_port, () => { console.log(`Listening http on port ${Config.app_port}`); });
const atlasmakerServer = new AtlasmakerServer(db);
atlasmakerServer.dataDirectory = dirname + '/public';

Expand All @@ -146,11 +146,11 @@ const start = async function () {
atlasmakerServer.server = http.createServer(app);
}

atlasmakerServer.server.listen(8080, () => {
atlasmakerServer.server.listen(Config.ws_port, () => {
if (Config.secure) {
console.log('Listening wss on port 8080');
console.log(`Listening wss on port ${Config.ws_port}`);
} else {
console.log('Listening ws on port 8080');
console.log(`Listening ws on port ${Config.ws_port}`);
}
atlasmakerServer.initSocketConnection();
});
Expand Down
4 changes: 3 additions & 1 deletion cfg.json.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"hostname": "http://localhost:3001",
"wshostname": "localhost:8080",
"wshostname": "ws://localhost:8080",
"app_port": 3001,
"ws_port": 8080,
"secure": false,
"ssl_key": "./key.pem",
"ssl_cert": "./cert.pem",
Expand Down
3 changes: 2 additions & 1 deletion controller/admin/admin.controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const notifier = require('../../notifier');
const { body, validationResult } = require('express-validator');

const notifier = require('../../notifier');

const validator = (req, res, next) => {
const authorizedIP = ['1']; // hardcoded authorized IPs
let ip;
Expand Down
1 change: 1 addition & 0 deletions controller/admin/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const express = require('express');

const controller = require('./admin.controller');
const router = new express.Router();

Expand Down
43 changes: 22 additions & 21 deletions controller/api/api.controller.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const fs = require('fs');
const path = require('path');

const tracer = require('tracer').console({format: '[{{file}}:{{line}}] {{message}}'});

const getLabelsets = async (req, res) => {
Expand All @@ -18,7 +19,7 @@ const getLabelsets = async (req, res) => {

const userNameQuery = (req, res) => {
const {query} = req;
if(typeof query.q === 'undefined') {
if (typeof query.q === 'undefined') {
res.status(400).send({error: 'missing q parameter'});

return;
Expand All @@ -27,8 +28,8 @@ const userNameQuery = (req, res) => {
db.get('user')
.find(
{ $or: [
{nickname: {$regex:query.q}},
{name: {$regex:query.q}}
{nickname: {$regex: query.q}},
{name: {$regex: query.q}}
]},
{ fields: ['name', 'nickname'], limit: 10 }
)
Expand All @@ -44,7 +45,7 @@ const userNameQuery = (req, res) => {
const getAtlasBackups = (req, res) => {
const { source, atlasProject, atlasName } = req.query;

if(typeof source === 'undefined'
if (typeof source === 'undefined'
|| typeof atlasProject === 'undefined'
|| atlasName === 'undefined') {
res.status(400);
Expand All @@ -59,30 +60,30 @@ const getAtlasBackups = (req, res) => {
const db = req.app.db.mongoDB();
db.get('mri').findOne({
source: source,
'mri.atlas': {$elemMatch:{name: atlasName, project: atlasProject}},
'mri.atlas': {$elemMatch: {name: atlasName, project: atlasProject}},
backup: {$exists: 0}
}, {url: 1, 'mri.atlas.$': 1})
.then( (obj) => {
.then((obj) => {
// get all filenames that have ever been associated with this atlas
let {url: dataDir} = obj;
[,, dataDir] = dataDir.split('/');
db.get('mri').aggregate([
{ $match:{ source: source, 'mri.atlas':{$elemMatch: {project: atlasProject, name: atlasName}}}},
{ $match: { source: source, 'mri.atlas': {$elemMatch: {project: atlasProject, name: atlasName}}}},
{ $unwind: '$mri.atlas' },
{ $match: { 'mri.atlas.project':atlasProject, 'mri.atlas.name': atlasName}},
{ $group: {_id:{filename: '$mri.atlas.filename'}}},
{ $project: {_id:0, filename:'$_id.filename'}}
{ $match: { 'mri.atlas.project': atlasProject, 'mri.atlas.name': atlasName}},
{ $group: {_id: {filename: '$mri.atlas.filename'}}},
{ $project: {_id: 0, filename: '$_id.filename'}}
])
.then( (obj2) => {
.then((obj2) => {
// get all backups for those files...
let i;
const promiseArray = [];
// ...from backup logs
for(i=0; i<obj2.length; i++) {
for (i = 0; i < obj2.length; i++) {
promiseArray.push(
db.get('log').aggregate([
{ $match: {key:'saveAtlasBackup', 'value.atlasDirectory': dataDir, 'value.atlasFilename': obj2[i].filename}},
{ $project: {_id:0, filename:'$value.atlasFilename', timestamp:'$value.timestamp'}}
{ $match: {key: 'saveAtlasBackup', 'value.atlasDirectory': dataDir, 'value.atlasFilename': obj2[i].filename}},
{ $project: {_id: 0, filename: '$value.atlasFilename', timestamp: '$value.timestamp'}}
])
);
}
Expand All @@ -92,23 +93,23 @@ const getAtlasBackups = (req, res) => {
result = result.concat(obj2);
res.send(result);
})
.catch( (err) => {
.catch((err) => {
res.status(500);
res.render('error', {
message: 'Can\'t query backup file logs',
error: err
});
});
})
.catch( (err) => {
.catch((err) => {
res.status(500);
res.render('error', {
message: 'Can\'t query backup files',
error: err
});
});
})
.catch( (err) => {
.catch((err) => {
res.status(400);
res.render('error', {
message: 'Can\'t find atlas',
Expand Down Expand Up @@ -136,12 +137,12 @@ const log = async (req, res) => {

const result = await db.get('log').findOne(obj);
let length = 0;
if(result) {
if (result) {
length = parseFloat(result.value.length);
}
const sum = parseFloat(json.value.length) + length;
await db.get('log').update(obj, {$set:{
'value.length':sum,
await db.get('log').update(obj, {$set: {
'value.length': sum,
date: (new Date()).toJSON()
}}, {upsert: true});
res.send({length: sum});
Expand All @@ -168,7 +169,7 @@ const log = async (req, res) => {

db.get('mri').update({
source: json.value.source,
'mri.atlas':{$elemMatch:{filename:json.value.atlas}}
'mri.atlas': {$elemMatch: {filename: json.value.atlas}}
}, {
$set: {
'mri.atlas.$.modified': (new Date()).toJSON(),
Expand Down
1 change: 1 addition & 0 deletions controller/api/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const express = require('express');

const controller = require('./api.controller');

const router = new express.Router();
Expand Down
28 changes: 14 additions & 14 deletions controller/atlasmakerServer/atlasmaker-linalg.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@
// Linear algebra
//========================================================================================
const mulMatVec = (m, v) => [
m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2],
m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2],
m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]
m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2],
m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2],
m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2]
];

const invMat = (m) => {
const w = [[], [], []];
const det = m[0][1]*m[1][2]*m[2][0] + m[0][2]*m[1][0]*m[2][1] + m[0][0]*m[1][1]*m[2][2] - m[0][2]*m[1][1]*m[2][0] - m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2];
const det = m[0][1] * m[1][2] * m[2][0] + m[0][2] * m[1][0] * m[2][1] + m[0][0] * m[1][1] * m[2][2] - m[0][2] * m[1][1] * m[2][0] - m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2];

w[0][0] = (m[1][1]*m[2][2] - m[1][2]*m[2][1])/det;
w[0][1] = (m[0][2]*m[2][1] - m[0][1]*m[2][2])/det;
w[0][2] = (m[0][1]*m[1][2] - m[0][2]*m[1][1])/det;
w[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / det;
w[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / det;
w[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / det;

w[1][0] = (m[1][2]*m[2][0] - m[1][0]*m[2][2])/det;
w[1][1] = (m[0][0]*m[2][2] - m[0][2]*m[2][0])/det;
w[1][2] = (m[0][2]*m[1][0] - m[0][0]*m[1][2])/det;
w[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / det;
w[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / det;
w[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / det;

w[2][0] = (m[1][0]*m[2][1] - m[1][1]*m[2][0])/det;
w[2][1] = (m[0][1]*m[2][0] - m[0][0]*m[2][1])/det;
w[2][2] = (m[0][0]*m[1][1] - m[0][1]*m[1][0])/det;
w[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / det;
w[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / det;
w[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / det;

return w;
};

const subVecVec = (a, b) => [a[0]-b[0], a[1]-b[1], a[2]-b[2]];
const subVecVec = (a, b) => [a[0] - b[0], a[1] - b[1], a[2] - b[2]];

const addVecVec = (a, b) => [a[0] + b[0], a[1] + b[1], a[2] + b[2]];

Expand Down
14 changes: 8 additions & 6 deletions controller/atlasmakerServer/atlasmaker-mri.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
//========================================================================================

const fs = require('fs');
const Struct = require('struct');
const zlib = require('zlib');
const { promisify } = require('util');
const zlib = require('zlib');

const Struct = require('struct');


const gunzip = promisify(zlib.gunzip);
const la = require('./atlasmaker-linalg');

Expand Down Expand Up @@ -198,8 +201,7 @@ const computeS2VTransformation = (mri) => {
const filetypeFromFilename = (mriPath) => {
if (mriPath.match(/.nii.gz$/)) {
return 'nii.gz';
} else
if (mriPath.match(/.mgz$/)) {
} else if (mriPath.match(/.mgz$/)) {
return 'mgz';
}
};
Expand Down Expand Up @@ -646,8 +648,8 @@ const loadMRI = (mriPath) => {
});
break;
default:
console.error('ERROR: nothing we can read');
reject(new Error('ERROR: nothing we can read'));
console.error('ERROR: nothing we can read ' + mriPath);
reject(new Error('ERROR: nothing we can read ' + mriPath));
}
});

Expand Down
Loading
Loading