Unverified Commit acff08f1 authored by katja heuer's avatar katja heuer Committed by GitHub

Merge pull request #10 from neuroanatomy/master

sync
parents 036b482b cbf1e20e
......@@ -17,10 +17,13 @@ jobs:
command: 'echo "{ \"clientID\": \"$GITHUB_CLIENT_ID\", \"clientSecret\": \"$GITHUB_CLIENT_SECRET\", \"callbackURL\": \"$GITHUB_CALLBACK_URL\"}">github-keys.json'
- run:
name: Instantiate blacklist
command: 'echo {} > controller/atlasMakerServer/blacklist.json'
command: 'echo {} > controller/atlasmakerServer/blacklist.json'
- run:
name: Instantiate whitelist
command: 'echo "{}" > controller/atlasMakerServer/whitelist.json'
command: 'echo "{}" > controller/atlasmakerServer/whitelist.json'
- run:
name: Instantiate websocket configuration file
command: 'echo "{\"secure\":false,\"port\":8080,\"ssl_key\": \"\",\"ssl_cert\": \"\",\"ssl_chain\":\"\"}" > ws_cfg.json'
- run:
name: Run server in background
command: 'PORT=3001 npm start'
......
......@@ -6,7 +6,8 @@ module.exports = {
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
"sourceType": "module",
"ecmaVersion": 8
},
"rules": {
"accessor-pairs": "error",
......
......@@ -18,14 +18,14 @@ public/js/project-page.js
public/js/project-settings-page.js
public/js/user-page.js
public/lib/.DS_Store
public/lib/atlasMaker.js
public/lib/atlasMaker-tools
public/lib/atlasmaker.js
public/lib/atlasmaker-tools
public/lib/brainbox.js
scripts/atlasMaker-resources.js
scripts/atlasmaker-resources.js
test/screenshots/
tmp
view/atlasMaker/dist/
view/atlasMaker/src/tools/dist/
view/atlasmaker/dist/
view/atlasmaker/src/tools/dist/
view/brainbox/dist/
whitelist.json
ws_cfg.json
**Come and join our team of
[BrainMappers](https://github.com/neuroanatomy/BrainBox/blob/master/BrainMappers.md)!!**
We will be happy to work with anyone who would love to join our effort.
While you can see in real-time what your collaborators are writing or drawing on a given
data set, you can also chat with them, and ask for help or approval of your work. We want
to open this scientific process to everyone with any background including citizen
scientists and researchers. Join us!
Here is a little video showing the [collaborative editing of brain masks in BrainBox](https://m.youtube.com/watch?v=bFHXS-lya5M).
**Next goal: finish the ♥ Bottlenose dolphin ♥!!**
Come to our [**dolphin brain**](http://brainbox.pasteur.fr/mri?url=http://braincatalogue.org/data/Bottlenose_dolphin/MRI-n4.nii.gz&view=cor&slice=143) , (log in with your GitHub account) and select the Cerebrum from the Braincatalogue project and **join our segmentation sprint!**
<img width="769" alt="screen shot 2017-06-01 at 11 08 34" src="https://cloud.githubusercontent.com/assets/6297454/26672835/f7892d80-46ba-11e7-8be8-51adbee9288d.png">
When you have done 1 slice,
* add your name or github handle to our [BrainMappers.md](https://github.com/neuroanatomy/BrainBox/blob/master/BrainMappers.md) file
* add the slice number where you have been working (currently, 111 & 112 are done, you could continue with 113++)
* add "length:..." and
* "volume:..." from the upper left corner of the BrainBox viewer into the file (just for the fun!! :D)
* and make a pull request!
The best devices for drawing over the brain are tablets with pens. With a computer mouse or trackpad it is a bit more tedious but works very fine as well 😃 Looking forward to seeing you!
Just say hi in the BrainBox chat and we will guide you to the view where we are currently working.
We will work in an axial slice (113++) and erase all the parts of the mask that cover the sulci of the brain. You see the impressively folded structure of the dolphin brain. The sulci, which are the valleys of the folds, appear darker. We erase them from the mask to being able to reconstruct the 3D surface preserving the folding.
**It's fun! Join us! :)** Careful! It's addictive! <3 😄
![gyrus_sulcus](https://cloud.githubusercontent.com/assets/6297454/26672808/de7c347c-46ba-11e7-9f19-01fef1da9295.png)
:sparkles: We are the brain mappers! / :sparkles:
Here, we are segmenting an amazingly folded [**dolphin brain**](http://brainbox.pasteur.fr/mri?url=http://braincatalogue.org/data/Bottlenose_dolphin/MRI-n4.nii.gz&view=cor&slice=143). Once you clicked the link, you will find our work in progress on the dolphin brain in the Braincatalogue project. You can **join our segmentation sprint any time!** You can also choose a different species to work on, if you prefer! Any contributions are featured below. More information on segmenting can be found in our [Annotations.md] file(https://github.com/neuroanatomy/BrainBox/blob/master/Annotations.md).
<img width="769" alt="screen shot 2017-06-01 at 11 08 34" src="https://cloud.githubusercontent.com/assets/6297454/26672835/f7892d80-46ba-11e7-8be8-51adbee9288d.png">
**Our BrainMapper team**
initial volume segmented: 509 368 mm3
current volume segmented: **445 823 mm3** (please update! :D)
Name: **name**
GitHub: @
Species: Bottlenose dolphin
Slice numbers: axial (cor) __
Length: __ mm
Volume: __ mm3
Name: **faruk**
GitHub: @ofgulban
Species: Bottlenose dolphin
Slice numbers: all
Length: mm
Volume: 445 823 mm3
Name: **katja**
GitHub: @katjaq
Species: Bottlenose dolphin
Slice numbers: axial (cor) 112
Length: mm
Volume: 509368 mm3
Name: **stef**
GitHub: @stemarcotti
Species: Bottlenose dolphin
Slice numbers: axial (cor) 114-124
Length: mm
Volume: mm3
Name: **stef**
GitHub: @stemarcotti
Species: Bottlenose dolphin
Slice numbers: axial (cor) 125-134
Length: mm
Volume: mm3
:sparkles: We are the brain mappers! / :sparkles:
Here, we are segmenting corpus callosum of 34 different primate species [**Green Monkey**](http://brainbox.pasteur.fr/mri?url=https://drive.google.com/uc?id=1l7wVJ39a7eaKWnhrFA6BRXs7VmfVnOjD&view=sag&slice=108). Once you clicked the link, you will find our work in progress in the brain catalogue primate corpus callosum project. You can **join our segmentation sprint any time!** You can also choose a different species to work on, if you prefer! Any contributions are featured below. More information on segmenting can be found in our [Annotations.md] file(https://github.com/neuroanatomy/BrainBox/blob/master/Annotations.md).
<img width="705" alt="screenshot 2018-12-07 at 12 22 09" src="https://user-images.githubusercontent.com/45625538/49645111-f289a200-fa1a-11e8-871b-96ec7a10778a.png">
**Our BrainMapper team**
Name: **Eleonora Galletti**
GitHub: @eleonoragalletti
Name: **Margherita Calderan**
GitHub: @Margheritacalderan
Name: **Corinna Moradei**
GitHub: @CorinnaMoradei
Name: **Francesco Alberti**
GitHub: @FrAlberti
Name: **Yasmina Ardern**
GitHub: @YasminaArdern
Copyright [2016] OpenNeuroLab Developers
Copyright [2016] BrainBox Developers
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
......
[![CircleCI](https://circleci.com/gh/neuroanatomy/BrainBox/tree/master.svg?style=shield)](https://circleci.com/gh/neuroanatomy/BrainBox/tree/master) [![Join the chat at https://gitter.im/OpenNeuroLab-Brainbox/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OpenNeuroLab-Brainbox/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# BrainBox - An application from the [Open Neuroimaging Laboratory](http://openneu.ro/)
# BrainBox - A platform for real-time collaboration in neuroimaging
[![Join the chat at https://gitter.im/OpenNeuroLab-Brainbox/Lobby](https://badges.gitter.im/OpenNeuroLab-Brainbox/Lobby.svg)](https://gitter.im/OpenNeuroLab-Brainbox/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
......@@ -75,8 +75,8 @@ If you want to work on BrainBox's code, you'll need a local installation:
2. clone the repo and `cd` to the brainbox directory
4. [create a new OAuth application](https://github.com/settings/applications/new) for your local brainbox url (http://localhost:3000 by default)
5. paste the keys into the github-keys.json.example file, and drop the .example
6. drop the `.example` from `controller/atlasMakerServer/blacklist.json.example`
7. drop the `.example` from `controller/atlasMakerServer/whitelist.json.example`
6. drop the `.example` from `controller/atlasmakerServer/blacklist.json.example`
7. drop the `.example` from `controller/atlasmakerServer/whitelist.json.example`
8. drop the `.example` from `blacklist.json.example`
9. drop the `.example` from `whitelist.json.example`
10. `npm install`
......@@ -94,8 +94,8 @@ These installation instructions may need to be updated.
3. `cd` to brainbox
4. [create a new OAuth application](https://github.com/settings/applications/new) for your local brainbox url (http://localhost:3000 by default)
5. paste the keys into the github-keys.json.example file, change the `callbackURL` to `"http://localhost:3000/auth/github/callback"` and drop the .example
6. drop the `.example` from `controller/atlasMakerServer/blacklist.json.example`
7. drop the `.example` from `controller/atlasMakerServer/whitelist.json.example`
6. drop the `.example` from `controller/atlasmakerServer/blacklist.json.example`
7. drop the `.example` from `controller/atlasmakerServer/whitelist.json.example`
7. make sure Docker is installed
8. `docker-compose up`
9. Then open `http://localhost:3000` in your browser.
......
......@@ -5,13 +5,12 @@
Atlas Maker Server
Roberto Toro, 25 July 2014
Launch using > node atlasMakerServer.js
Launch using > node atlasmakerServer.js
*/
const debug = 1;
const fs = require('fs');
const express = require('express');
var compression = require('compression');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
......@@ -19,13 +18,15 @@ const tracer = require('tracer').console({format: '[{{file}}:{{line}}] {{messag
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const mustacheExpress = require('mustache-express');
const crypto = require('crypto');
const request = require('request');
const url = require('url');
const async = require('async');
const mongo = require('mongodb');
const monk = require('monk');
// const debug = 1;
// const crypto = require('crypto');
// const request = require('request');
// const url = require('url');
// const async = require('async');
// const mongo = require('mongodb');
let MONGO_DB;
const DOCKER_DB = process.env.DB_PORT;
const DOCKER_DEVELOP = process.env.DEVELOP;
......@@ -36,6 +37,7 @@ if (DOCKER_DB) {
MONGO_DB = 'localhost:27017/brainbox'; //process.env.MONGODB;
}
/** @todo Handle the case when MongoDB is not installed */
var db = monk(MONGO_DB);
var expressValidator = require('express-validator');
......@@ -55,7 +57,7 @@ if (DOCKER_DEVELOP === '1') {
// Specify the folder to watch for file-changes.
hotServer.watch(__dirname);
tracer.log('Watching: ' + __dirname);
tracer.log(`Watching: ${__dirname}`);
}
const app = express();
......@@ -67,6 +69,9 @@ app.use(function(req, res, next) {
next();
});
// enable compression
app.use(compression());
app.engine('mustache', mustacheExpress());
app.set('views', path.join(dirname, 'templates'));
app.set('view engine', 'mustache');
......@@ -94,9 +99,9 @@ app.use((req, res, next) => {
// }
// { Init web socket server
const atlasMakerServer = require('./controller/atlasMakerServer/atlasMakerServer.js');
atlasMakerServer.initSocketConnection();
atlasMakerServer.dataDirectory = dirname + '/public';
const atlasmakerServer = require('./controller/atlasmakerServer/atlasmakerServer.js');
atlasmakerServer.initSocketConnection();
atlasmakerServer.dataDirectory = dirname + '/public';
// }
// { Check that the 'anyone' user exists. Insert it otherwise
......@@ -249,14 +254,13 @@ app.use('/user', require('./controller/user/'));
// { API routes
app.get('/api/getLabelsets', (req, res) => {
let i;
const arr = fs.readdirSync(dirname + '/public/labels/');
const info = [];
for (i in arr) {
var json = JSON.parse(fs.readFileSync(dirname + "/public/labels/" + arr[i]));
for (const label of arr) {
var json = JSON.parse(fs.readFileSync(dirname + "/public/labels/" + label));
info.push({
name: json.name,
source: arr[i]
source: label
});
}
res.send(info);
......
......@@ -3,13 +3,13 @@ const os = require('os');
const zlib = require('zlib');
const tracer = require('tracer').console({format: '[{{file}}:{{line}}] {{message}}'});
const jpeg = require('jpeg-js'); // jpeg-js library: https://github.com/eugeneware/jpeg-js
const keypress = require('keypress');
const Struct = require('struct');
const childProcess = require('child_process');
const merge = require('merge');
const path = require('path');
const monk = require('monk');
const db = monk('localhost:27017/brainbox');
const keypress = require('keypress');
// Get whitelist and blacklist
const useWhitelist = false;
......@@ -22,16 +22,33 @@ tracer.log("Use blacklist:", useBlacklist);
tracer.log(blacklist);
var http = require('http');
//const server = http.createServer(),
const server = http.createServer(function(req, res) {
let server;
const ws_cfg = JSON.parse(fs.readFileSync('ws_cfg.json'));
const {secure, port} = ws_cfg;
if(secure) {
// wss
var http = require('https');
server = http.createServer({
key: fs.readFileSync(ws_cfg.ssl_key),
cert: fs.readFileSync(ws_cfg.ssl_cert),
ca: fs.readFileSync(ws_cfg.ssl_chain)
}, function(req, res) {
var ip = req.ip
|| req.connection.remoteAddress
|| req.socket.remoteAddress
|| req.connection.socket.remoteAddress;
}).listen(ws_cfg.port);
} else {
var http = require('http');
server = http.createServer(function(req, res) {
var ip = req.ip
|| req.connection.remoteAddress
|| req.socket.remoteAddress
|| req.connection.socket.remoteAddress;
});
});
}
const WebSocketServer = require('ws').Server;
var websocket;
const port = 8080;
server.on("upgrade", function(req, socket, head) {
var ip = req.ip
......@@ -77,7 +94,7 @@ function bufferTag(str, sz) {
return buf;
}
const atlasMakerServer = (function() {
const atlasmakerServer = (function() {
const me = {
debug: 2,
dataDirectory: '',
......@@ -2299,7 +2316,7 @@ const atlasMakerServer = (function() {
/*
Init
*/
tracer.log("atlasMakerServer.js");
tracer.log("atlasmakerServer.js");
tracer.log("date:", new Date());
setInterval(function() { tracer.log("date:", new Date()); }, me.timeMarkInterval); // time mark
tracer.log("free memory", os.freemem());
......@@ -2325,7 +2342,11 @@ const atlasMakerServer = (function() {
Init WS connection
*/
try {
websocket = new WebSocketServer({ server: server, verifyClient: me.verifyClient });
if(secure) {
websocket = new WebSocketServer({server: server});
} else {
websocket = new WebSocketServer({ server: server, verifyClient: me.verifyClient });
}
websocket.on("connection", function connectionFromInitSocketConnection(s, req) {
me.traceLog(connectionFromInitSocketConnection);
......@@ -2584,7 +2605,7 @@ const atlasMakerServer = (function() {
return me;
}());
module.exports = atlasMakerServer;
module.exports = atlasmakerServer;
/*
Atlases
......
......@@ -5,7 +5,7 @@ const url = require('url');
const fs = require('fs');
const request = require('request');
const path = require('path');
const atlasMakerServer = require('../atlasMakerServer/atlasMakerServer');
const atlasmakerServer = require('../atlasmakerServer/atlasmakerServer');
const checkAccess = require('../checkAccess/checkAccess.js');
const dataSlices = require('../dataSlices/dataSlices.js');
......@@ -121,7 +121,7 @@ function downloadMRI(myurl, req, res, callback) {
dest = newDest;
// NOTE: getBrainAtPath has to be called with a client-side path like "/data/[md5hash]/..."
atlasMakerServer.getBrainAtPath('/data/' + hash + '/' + filename)
atlasmakerServer.getBrainAtPath('/data/' + hash + '/' + filename)
.then(mri => {
// Create json file for new dataset
const ip = req.headers['x-forwarded-for'] ||
......@@ -367,7 +367,7 @@ const apiMriGet = function (req, res) {
return;
}
req.db.get('mri').findOne({source: myurl, backup: {$exists: 0}}, {_id: 0})
req.db.get('mri').findOne({source: myurl, backup: {$exists: backups}}, {_id: 0})
.then(json => {
if (!json) {
console.log("MRI not present in DB");
......@@ -455,7 +455,7 @@ const reset = function reset(req, res) {
req.db.get('mri').findOne({source: myurl, backup: {$exists: 0}})
.then(mridb => {
const filename = mridb.filename;
atlasMakerServer.getBrainAtPath('/data/' + hash + '/' + filename)
atlasmakerServer.getBrainAtPath('/data/' + hash + '/' + filename)
.then(mri => {
req.db.get('mri').update({source: myurl, backup: {$exists: 0}}, {$set: {
dim: mri.dim,
......
"use strict";
const fs = require('fs');
const atlasMakerServer = require('../atlasMakerServer/atlasMakerServer');
const atlasmakerServer = require('../atlasmakerServer/atlasmakerServer');
// ExpressValidator = require('express-validator')
var validator = function (req, res, next) {
......@@ -85,7 +85,7 @@ var upload = function(req, res) {
var files = req.files;
delete mri._id;
console.log("Everything is in order");
console.log("username:",username);
console.log("url:", url);
......@@ -94,19 +94,20 @@ var upload = function(req, res) {
console.log("atlasProject:", atlasProject);
console.log("atlasLabelSet:", atlasLabelSet);
console.log("files:", files);
// create final filename
var ext;
var filename;
var dir, path;
if(/.nii.gz$/.test(files[0].originalname))
if(/.nii.gz$/.test(files[0].originalname)) {
ext=".nii.gz";
else
if(/.mgz$/.test(files[0].originalname))
} else if(/.mgz$/.test(files[0].originalname)) {
ext=".mgz";
else {
} else {
return res.json({error:"Atlas encoding neither .nii.gz nor .mgz"}).status(400).end();
}
filename=Math.random().toString(36).slice(2)+ext;
// check if directory exists (it may not exist if a volume annotation is being uploaded
......@@ -129,7 +130,7 @@ var upload = function(req, res) {
// Check that the dimensions of the atlas are the same as its parent mri
console.log("> load parent mri");
atlasMakerServer.loadMRI(path)
atlasmakerServer.loadMRI(path)
.then(function(atlas){
console.log("atlas.dim: ",atlas.dim);
console.log("mri.dim: ",mri.dim);
......
......@@ -672,4 +672,4 @@ var projectController = function(){
this.delete_project = delete_project;
}
module.exports = new projectController();
\ No newline at end of file
module.exports = new projectController();
const exec = require('child_process').execSync;
const del = require('del');
const gulp = require('gulp');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const uglify = require('gulp-uglify-es').default;
const sourcemaps = require('gulp-sourcemaps');
const download = require('gulp-download');
const gulpif = require('gulp-if');
const print = require('gulp-print');
const brainboxFiles = ['view/dist/atlasMaker.*js', 'view/brainbox/*.js'];
const atlasmakerFiles = ['view/downloads/*.js', 'view/atlasMaker/*.js', 'view/dist/atlasMaker-*.js'];
const jsdest = 'view/dist/';
const tmpFiles = ['atlasMaker-resources.js'];
gulp.task('default', ['brainbox-dev']);
gulp.task('brainbox-dev', ['pack-brainbox-dev']);
gulp.task('brainbox', ['pack-brainbox']);
gulp.task('atlasMaker-dev', ['pack-atlasMaker-dev']);
gulp.task('atlasMaker', ['pack-atlasMaker']);
gulp.task('pack-brainbox-dev', ['pack-atlasMaker-dev'], function () {
return gulp.src(brainboxFiles)
.pipe(print())
.pipe(sourcemaps.init())
//.pipe(gulpif(file => !(file.path.includes('.min.js')), uglify()))
.pipe(concat('brainbox.js'))
//.pipe(gulp.dest(jsdest))
//.pipe(rename('brainbox.min.js'))
.pipe(sourcemaps.write())
.pipe(gulp.dest(jsdest));
});
gulp.task('pack-atlasMaker-dev', ['download', 'pack-resources'], function () {
return gulp.src(atlasmakerFiles)
//.pipe(sourcemaps.init())
//.pipe(gulpif(file => !(file.path.includes('.min.js')), uglify()))
.pipe(concat('atlasMaker.js'))
//.pipe(gulp.dest(jsdest))
//.pipe(rename('atlasMaker.min.js'))
//.pipe(sourcemaps.write())
.pipe(gulp.dest(jsdest));
});
gulp.task('pack-brainbox', ['pack-atlasMaker'], function () {
return gulp.src(brainboxFiles)
.pipe(gulpif((file) => !(file.path.includes('.min.js')), uglify()))
.pipe(concat('brainbox.js'))
.pipe(gulp.dest(jsdest))
.pipe(rename('brainbox.min.js'))
.pipe(gulp.dest(jsdest));
});
gulp.task('pack-atlasMaker', ['download', 'pack-resources'], function () {
return gulp.src(atlasmakerFiles)
.pipe(gulpif((file) => !(file.path.includes('.min.js')), uglify()))
.pipe(concat('atlasMaker.js'))
.pipe(gulp.dest(jsdest))
.pipe(rename('atlasMaker.min.js'))
.pipe(gulp.dest(jsdest));