From 1bd7712b5cc440ca6fb9b0e334a15fbe7b227a5c Mon Sep 17 00:00:00 2001 From: bvdmitri Date: Wed, 4 Nov 2015 18:38:34 +0300 Subject: [PATCH] readme updated --- README.md | 114 +++++++++++++----- app/views/account/account.scala.js | 10 +- .../sampleCollectionAnalysing.scala.html | 4 +- conf/application.conf | 15 +-- public/javascripts/visualisation.js | 109 +++++++++-------- public/stylesheets/main.css | 10 -- 6 files changed, 164 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index 5ab40a5..210489f 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,98 @@ -# VDJviz: a lightweight immune repertoire browser +# VDJviz: a versatile immune repertoire browser -This is a [Play Framework](https://www.playframework.com/) version 2.2.4 application. To run the server execute -``` -play run -``` -from the project directory. A local server could be accessed at `localhost:9000`. +VDJviz is a web-based graphical user interface application that allows browsing and analyzing immune repertoire sequencing ([RepSeq](http://onlinelibrary.wiley.com/doi/10.1111/j.1365-2567.2011.03527.x/epdf)) data. It can be used to visualize results of [MITCR](mitcr.milaboratory.com), [MIGEC](https://github.com/mikessh/migec), [MIXCR](mixcr.milaboratory.com) and [MIGMAP](https://github.com/mikessh/migmap) RepSeq processing software as well as popular [IMGT/HighV-QUEST](http://www.imgt.org/HighV-QUEST/login.action) and [ImmunoSEQ Analyzer](http://www.adaptivebiotech.com/immunoseq/analyzer) services. VDJviz can be installed and used as a local server, alternatively you can use an online demo version available at [vdjviz.milaboratory.com](http://vdjviz.milaboratory.com) which currently has an upload limit of 25 datasets each having size at most 10,000 clonotypes. The list of VDJviz features at a glance: -This application uses [VDJtools](https://github.com/mikessh/vdjtools) API to compute various immune repertoire statistics and [D3.js](http://d3js.org/) library for interactive graphs. +- Clonotype table browsing with V/D/J markup. +- CDR3 pattern matching for a single sample and across multiple samples with flexible filters. +- Spectratype, V-Spectratype, V-J usage and clonality analysis. Those can be compared side-by-side using the Compare panel. +- Summary statistics and rarefaction for multiple samples. +- Clonotype sharing across samples (many-to-many intersection) with flexible clonotype matching criteria. +- Uploaded data sharing. + +VDJviz uses [VDJtools API](https://github.com/mikessh/vdjtools) as a back-end. The software utilizes [Play framework](https://www.playframework.com/) for running the server instance and state-of-art web graphics libraries such as [D3js](http://d3js.org/) for visualization. + +## Installation + +The most straightforward way to install VDJviz as a local server is to download the [latest release package](https://github.com/antigenomics/vdjviz/releases/latest). + +After downloading unzip the package wherever you want, but please avoid long paths and spaces (Windows version is especially sensitive to it). + +You can find the server executable in ``bin/`` directory. To set up the server: + +- Run `vdjviz.bat` file (Windows) +- Run `bash vdjviz -Dconfig.file=application.conf` in your console (Linux/Mac OS) + +Wait until the server is started, and go to ``localhost:9000`` URL in your browser to open VDJviz. +The user generator is enabled in the config by default, so you can login with `vdjviz1@vdjviz.com` as an email and `vdjviz1` as password, + +To stop application just press `Ctrl-C` at any time in console. ## Server configuration -Before using this application you will need to edit `application.conf` and `securesocial.conf` files in the `conf/` directory +VDJviz server configuration can be performed by manually editing ``application.conf`` file in the ``bin/`` directory. The configuration file has the following fields: + +- ``application.secret`` +The secret key used in cryptographic hash functions. + +- ``uploadPath`` +Specifies the path that will be used by VDJviz to store user's uploaded files. +You can use '~' symbol as a shortcut for user home directory. +Default: `~/vdjviz/` + +- ``maxFileSize`` +File size limit in kB +Default: `0` (no limit) + +- ``maxFilesCount`` +Limit on the number of uploaded files per user. +Default: ``0`` (no limit) + +- ``maxClonotypesCount`` +Limit on the number of clonotypes for each uploaded file. +Default: ``0`` (no limit) + +- ``allowSharing`` +Disable or enable sharing feature +Default: ``true`` (enabled) + +- ``maxSharedGroups`` +Maximum number of shared analyses per user. +Default: ``0`` (no limit) + +- ``deleteAfter`` +Time period after which uploaded files are deleted from the server, in hours. +Default: ``0`` (never) -*application.conf* -- `uploadPath`, points to the path that will be used to store user-uploaded files -- `maxFileSize`, max allowed file size (set it to `0` to remove the limit) -- `maxFilesCount`, max number of uploaded files per user (set it to `0` to remove the limit) -- `maxClonotypesCount`, max number of rows in clonotype table (set it to `0` to remove the limit) -- `deleteAfter`, time after the cache is deleted (disabled if set to `0`) -- `application.secret`, the secret key used in cryptographic hash functions -- `db.default.*`, database configuration -- `smtp.*`, SMTP server configuration +- ``applyNewLimitsToOldUsers`` +If set to ``true`` the server will automatically update limtis of all existing user accounts according to the ones specified in config. If set to ``false``, the limits will only be applied to newly created users. +Default: ``true`` -In fact the configuration file is used only when the application is creating user's account. After that server is guided by your account's limits for uploading files. This is done in order to be able to specify different limits for different accounts. So if you change the default configuration it will not affect already created accounts. +- ``createDefaultUsers`` +Specifies whether the server will generate some default user accounts with predefined emails and passwords, setting their emails to ``@vdjviz.com`` (e.g. ``vdjviz1@vdjviz.com``) and passwords to ```` (e.g. ``vdjviz1``). Set this option to ``false`` if you don't need this feature and prefer to use registration via SMTP. +Default: ``true`` -*securesocial.conf* -- `smtp`, set up the SMTP server to send registration confirmation e-mails +- ``nDefaultUsers`` +Number of default users to be created. +Default: ``1`` -## Database configuration - The application uses [MySQL DBMS](http://www.mysql.com/) for handling metadata by default, if you want to change MySQL to another DBMS please see the [corresponding Play documentation section](https://www.playframework.com/documentation/2.2.4/JavaDatabase) - - `db.default.user`, MySQL server username - - `db.default.password`, MySQL server password -
+- ``nameDefaultUser`` +Default user name prefix. +Default: `vdjviz` -After setting your login and password, create **vdjviz** database by typing `CREATE DATABASE vdjviz;` in MySQL console +- ``db.default.url`` +Points to the path that will be used to store H2 database file. +Default value: ``~/vdjviz/h2.db`` +Standalone version uses [H2 Database](http://www.h2database.com/html/main.html) for handling metadata by default, if you want to change H2 to another DBMS please see the corresponding Play documentation [section](https://www.playframework.com/documentation/2.2.4/JavaDatabase) +You can also use this database to manually modify user limits. -##Dependency +- ``allowRegistration`` +Show the Register button in login screen. +Default: ``false`` - - [milib](https://github.com/milaboratory/milib) - - [vdjtools](https://github.com/mikessh/vdjtools) +- ``allowChangePasswords`` +Show the Change Password button in login screen. +Default: ``false`` +- ``smtp.*`` +SMTP server configuration. +If you don't want to use registration features, you can leave ``smtp.*`` fields empty and generate default users. diff --git a/app/views/account/account.scala.js b/app/views/account/account.scala.js index a080918..efc6209 100644 --- a/app/views/account/account.scala.js +++ b/app/views/account/account.scala.js @@ -2046,14 +2046,18 @@ var shared = false; } function openAnotherFiles() { + d3.select('.g3').remove(); + d3.select('.heatMapBlockSelection').remove(); openProgress = 0; step = steps.FILES_SELECT; - angular.copy(treshData, data); + //angular.copy(treshData, data); } function changeJoinParameters() { + d3.select('.g3').remove(); + d3.select('.heatMapBlockSelection').remove(); step = steps.JOIN_RENDERING; - angular.copy(treshData, data); + //angular.copy(treshData, data); } function isJointRendering() { @@ -2143,7 +2147,7 @@ var shared = false; $scope.isJoinInformationStep = sampleCollectionFactory.isJoinInformationStep; $scope.changeJoinParameters = sampleCollectionFactory.changeJoinParameters; $scope.openAnotherFiles = function() { - $scope.selectedFiles.splice(0, $scope.selectedFiles.length); + //$scope.selectedFiles.splice(0, $scope.selectedFiles.length); $scope.occurenceTreshold = 2; sampleCollectionFactory.openAnotherFiles(); }; diff --git a/app/views/account/visualisation/sampleCollectionAnalysing.scala.html b/app/views/account/visualisation/sampleCollectionAnalysing.scala.html index d31cf78..70f6003 100644 --- a/app/views/account/visualisation/sampleCollectionAnalysing.scala.html +++ b/app/views/account/visualisation/sampleCollectionAnalysing.scala.html @@ -15,8 +15,8 @@

Please refresh the page to reconnect

- - + +
diff --git a/conf/application.conf b/conf/application.conf index 89b5dd0..2ef4546 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -12,19 +12,20 @@ application.secret="put your secret key here" # Specify the upload path for files # You can use '~' symbol for specifying path in your user's directory uploadPath = "~/vdjviz/" -# Max allowed file size (no limit if set to `0`) +# Max file size in kB, set it to 0 if you don't want to limit max file size, default 2048 maxFileSize = 0 -# Max number of uploaded files per user (no limit if set to `0`) +# Max files count, set it to 0, if you don't want to limit max files count, default 25 maxFilesCount = 0 -# Max number of rows in clonotype table (no limit if set to `0`) +# Max clonotypes count in each file, set it to 0, if you don't want to limit max clonotypes count, default 10000 maxClonotypesCount = 0 -# Allow Sharing feature -allowSharing = true -# Max number of shared groups per user (no limit if set to `0`) +# Max shared groups for account, set it to 0, if you don't want to limit max shared groups count, default 5 maxSharedGroups = 0 -# Time after the files is deleted from the server (disabled if set to `0`) +# When files must be deleted, integer value in hours, set it to 0, if you don't want to delete cache files, default 24 deleteAfter = 0 +# Allow Sharing feature +allowSharing = true + # Apply new limits to old users # If set to ``true`` the server will automatically update limtis of all existing user accounts according to the ones specified in config. # If set to ``false``, the limits will only be applied to newly created users. diff --git a/public/javascripts/visualisation.js b/public/javascripts/visualisation.js index 4d5f3d5..e69184a 100644 --- a/public/javascripts/visualisation.js +++ b/public/javascripts/visualisation.js @@ -473,6 +473,8 @@ function rarefactionPlot(data, param) { function joinHeapMap(data) { "use strict"; + var heatMap; + var blockPage; var margin = { top: 0, right: 10, bottom: 50, left: 170 }, col_number = data.colLabel.length, row_number = data.rowLabel.length, @@ -514,6 +516,19 @@ function joinHeapMap(data) { } var svg = place.append("svg") + .on("selectstart", function() { + blockPage.style('visibility', 'visible'); + //heatMap.style("visibility", "hidden"); + }) + .on("click", function() { + blockPage.style('visibility', 'hidden'); + //heatMap.style("visibility", "visible"); + }) + .on("mouseup", function() { + blockPage.style('visibility', 'hidden'); + //heatMap.style("visibility", "visible"); + }) + .attr("class", "noselection") .attr("width", "100%") .attr("height", height + margin.top + margin.bottom + 300) .append("g") @@ -550,45 +565,13 @@ function joinHeapMap(data) { .attr("x", function(d, i) { return legendElementWidth * i; }) .attr("y", (cellSize*2)); - var rowLabels = svg.append("g") - .selectAll(".rowLabelg") - .data(rowLabel) - .enter() - .append("text") - .html(function (d) { - return d.cdr3aa_tspan; - }) - .attr("x", 0) - .attr("y", function (d, i) { return i * cellSize + 200; }) - .style("text-anchor", "end") - .attr("transform", "translate(-6," + cellSize / 1.5 + ")") - .attr("class", function (d,i) { return "rowLabel mono r"+i;} ) - ; - - - var colLabels = svg.append("g") - .selectAll(".colLabelg") - .data(colLabel) - .enter() - .append("text") - .text(function (d) { return d; }) - .attr("x", -200) - .attr("y", function (d, i) { return i * cellSize; }) - .style("text-anchor", "left") - .attr("transform", "translate("+cellSize/2 + ",-6) rotate(-90)") - .attr("class", function (d,i) { return "colLabel mono c"+i;} ) - ; - function stopEvent() { - d3.event.preventDefault(); - d3.event.sourceEvent.stopPropagation(); d3.event.preventDefault(); d3.event.stopPropagation(); - d3.event.stopImmediatePropagation(); } - var heatMap = svg + heatMap = svg .append("g") .attr("class", "cell_heat_map g3") .selectAll(".heatmap") @@ -637,6 +620,34 @@ function joinHeapMap(data) { d3.select("#heatmap_tooltip").classed("hidden", true); }); + var rowLabels = svg.append("g") + .selectAll(".rowLabelg") + .data(rowLabel) + .enter() + .append("text") + .html(function (d) { + return d.cdr3aa_tspan; + }) + .attr("x", 0) + .attr("y", function (d, i) { return i * cellSize + 200; }) + .style("text-anchor", "end") + .attr("transform", "translate(-6," + cellSize / 1.5 + ")") + .attr("class", function (d,i) { return "rowLabel mono r"+i;} ) + ; + + + var colLabels = svg.append("g") + .selectAll(".colLabelg") + .data(colLabel) + .enter() + .append("text") + .text(function (d) { return d; }) + .attr("x", -200) + .attr("y", function (d, i) { return i * cellSize; }) + .style("text-anchor", "left") + .attr("transform", "translate("+cellSize/2 + ",-6) rotate(-90)") + .attr("class", function (d,i) { return "colLabel mono c"+i;} ) + ; var numCol = (colLabel.length + 2) * cellSize; @@ -668,20 +679,24 @@ function joinHeapMap(data) { .attr("class", function (d,i) { return "numLabel mono r"+i;} ) ; - var sa=d3.select(".g3") - .on("mousedown", function() { - return null; - }) - .on("mousemove", function() { - return null; - }) - .on("mouseup", function() { - return null; - }) - .on("mouseout", function() { - return null; - }) - ; + d3.select('.heatMapBlockSelection').remove(); + + setTimeout(function() { + var st = d3.select('.g3').node().getBoundingClientRect(); + + blockPage = d3.select('body') + .append('div') + .attr('class', 'heatMapBlockSelection') + .style('visibility', 'hidden') + .style('left', st.left + 'px') + .style('top', st.top + 'px') + .style('height', st.height + 'px') + .style('width', st.width + 'px') + .style('position', 'absolute') + .style('opacity', '0.2'); + }, 10); + + function cdrTransform(cdr) { var cdr3aa = cdr.cdr3aa, diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css index 2424a2c..f74b78c 100644 --- a/public/stylesheets/main.css +++ b/public/stylesheets/main.css @@ -506,16 +506,6 @@ text.mono { fill: black!important; } -svg .cell_heat_map { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -svg .cell_heat_map::selection { - background: none; -} - .loading { position: relative; margin-left: auto;