Commit 9daceb5c authored by Marc Duez's avatar Marc Duez Committed by Mathieu Giraud

First public release of the Vidjil browser

	* browser/ : D3.js/javascript-based V(D)J recombination browser
	* server/fuse.py : script to combine data from several points
parent 113ee8ee
germline/????.fa
data/Stanford_S22.fasta
data/Stanford_S22.rc.fasta
*.data
*.clntab
*.tap
*.log
dep.mk
*~
*.o
*.a
*.pyc
/vidjil
/algo/tests/tests
/algo/tests/out/
/algo/TAGS
/algo/tools/affectanalyser
/algo/tools/align
/algo/tools/compareV
/algo/tools/cut
/algo/tools/dynprog
/algo/tools/segmentD
/out
/browser/css/*.css
/browser/cgi/align.cgi
align: core align.o
mkdir -p ../../interface/cgi
g++ -o ../../interface/cgi/align.cgi align.o ../core.a
mkdir -p ../../browser/cgi
g++ -o ../../browser/cgi/align.cgi align.o ../core.a
align.o: align.cpp
g++ -c align.cpp
......
all: cp deep
cp:
mkdir -p data/
scp -pr "vdj:vdj/data/runs/13-0*/*.data" data/
mkdir -p data/run/
scp -pr "vdj:vdj/data/runs/13-0*/run-*" data/run/
deep:
ssh vdj "cd vdj/data/runs ; sh cp-deep-data-json"
scp -pr "vdj:vdj/data/runs/export-data" data/
Leu:
cd data/export-data/13-09 ; python ../../../fuse.py BCD-Leu.data 100 out-vidjil/BCD/data.json out-vidjil/Leu+0*/data.json out-vidjil/Leu+1*/data.json out-vidjil/Leu+5*/data.json out-vidjil/Leu+2*/data.json out-vidjil/Leu+[3467]*/data.json
LESSC=lessc
all: dark.css light.css
dark.css: dark.less vidjil.less
$(LESSC) dark.less dark.css
light.css: light.less vidjil.less
$(LESSC) light.less light.css
no:
make LESSC="./node lessc"
/* default color solarizeD */
@default : #839496;
@background : #002b36;
@highlight : #073642;
@select : #fdf6e3;
@secondary : #586e75;
@border : #284e55;
@import "vidjil.less";
/* default color solarizeL */
@default : #657b83;
@background : #eee8d5;
@highlight : #fdf6e3;
@select : #002b36;
@secondary : #93a1a1;
@border : #b3c1c1;
@import "vidjil.less";
This diff is collapsed.
import collections
import json
import sys
import time
if len(sys.argv) < 2:
print "Usage: %s <FASTA input file> [JSON output file]" % sys.argv[0]
sys.exit()
input_name = sys.argv[1]
output_name = ""
if len(sys.argv) == 3:
output_name = sys.argv[2]
fasta = open(sys.argv[1], "r")
table = {}
identifiant = ""
sequence = ""
for ligne in fasta :
ligne = ligne.rstrip('\n\r')
if len(ligne) != 0 :
if ligne[0]=='>' :
if len(sequence)!=0 :
table[identifiant]=sequence
identifiant=ligne[1:]
if identifiant.count('|') != 0 :
tmp=identifiant.split('|')
identifiant=tmp[1]
if identifiant.count('_') != 0 :
tmp2=identifiant.split('_')
identifiant=tmp2[0]
sequence="";
else :
sequence+=ligne
if len(sequence)!=0 :
table[identifiant]=sequence
fasta.close()
print json.dumps(table, indent=2, sort_keys=True)
if output_name != "":
with open(output_name, "w") as file :
json.dump(table, file, indent=2, sort_keys=True)
This diff is collapsed.
Vidjil browser - Developer manual
///////////////////////////////////////////////////////////////////////////////////////
Class Model
I Contenu
la class model contient toute les données chargées des fichiers data et analysis
et stock/genere un bon nombre de meta-données utile pour toutes les views
-windows
-liste des fenêtres
-germline
-liste des genes + nombre d'alleles
-clones
-liste des clones, un clones est basiquement un ensemble de fenêtre
-il existe autant de clones que de fenêtres et par defaut chaque clone
est un ensemble d'une fenêtre clone[1]=[window[1]] ...
-une fenêtre ne peut se trouver que dans un seul clone a la fois
-un clone vide est considéré comme inactif (non affiché)
-la taille d'un clone correspond a la somme des tailles de ses fenêtres
-la fenetre representative de clone[x] est toujours la windows[x]
-view
-la liste des vues associées
-t et r
-le point de suivi actuel et le ratio utilisé (normalization)
-chaque window/clone possede une taille différente suivant le point de suivi
et le ratio utilisé, ces valeurs sont utilisées par defaut pour les calculs
-f
-le clone actuellement en focus
II fonction de chargement/sauvegarde
-load (data, analysis, limit)
-loadGermline()
-initClones()
-loadAnalysis(analysis)
-saveAnalysis()
-resetAnalysis()
III manipulation du Model
-changeName(cloneID, new_name)
-getName(cloneID)
-getCode(cloneID)
-getSize(cloneID)
-changeRatio(new_r)
-changeTime(new_t)
-focusIn(cloneID)
-focusOut()
IV selection
permet de placer/retirer le status select sur un/plusieurs clones
-select(cloneID)
-unselect(cloneID)
-unselectAll()
-getSelected()
V merge/split
-merge()
merge all clones currently in the selection into one
exemple:
1/getSelected()
selection = 1, 2, 5, 8,
2/l'état des clones au départ
clones[1]=[windows[1]]
clones[2]=[windows[2]]
clones[5]=[windows[5]]
clones[8]=[windows[8]]
3/merge() création d'un nouvel ensemble de fenetre
[windows[1],windows[2],windows[5],windows[8]]
4/attribution du nouvel ensemble au clone ayant le meilleur top
clones[1]=[windows[1],windows[2],windows[5],windows[8]]
clones[2]=[]->inactif
clones[5]=[]->inactif
clones[8]=[]->inactif
-split(cloneID, windowID)
exemple:
1/
clones[1]=[windows[1],windows[2],windows[5],windows[8]]
clones[5]=[]->inactif
2/
split(1,5)
3/
clones[1]=[windows[1],windows[2],windows[8]]
clones[5]=[windows[5]]
VI manipulation des views
-init()
-update()
-updateElem(list)
-resize()
///////////////////////////////////////////////////////////////////////////////////////
Views
I Contenu commun a toutes les vues
-id
l'identifiant de l'element HTML contenant la vue
-m
le model associé a la vue
II fonctions communes a toutes les vues
-init()
-update()
-updateElem(list)
-resize()
///////////////////////////////////////////////////////////////////////////////////////
Class Graph
I Contenu spécifique a la vue graph
resizeW=1; coef d'agrandissement largeur
resizeH=1; coef d'agrandissement hauteur
w=1400; largeur graph avant resize
h=450; hauteur graph avant resize
marge1=50; marge droite bord du graph/premiere colonne
marge2=50; marge gauche derniere colonne/bord du graph
marge4=75; marge droite/gauche (non influencé par le resize)
marge5=25; marge top (non influencé par le resize)
II fonctions spécifiques a la vue graph
-drawElem(list) retrace la liste de clone passé en parametre
-draw() retrace le graph ( clones + axis + legendes)
-constructPathR(res) calcul un tracé pour une résolution
-constructPath(cloneID) calcul un tracé pour un clone
/////////////////////////////////////////////////////////////////////////////////////
Class ScatterPlot
I Contenu spécifique a la vue scatterPlot
resizeCoef=1; coef d'agrandissement a appliquer aux rayons des elements
resizeW=1; coef d'agrandissement largeur
resizeH=1; coef d'agrandissement hauteur
w=1400; largeur avant resize
h=700; hauteur avant resize
marge_left=80;
marge_top=50;
max_precision=8; precision max atteignable
positionGene={}; positions des genes
positionAllele={}; positions des alleles
grid[] les grilles de répartition disponibles
splitMethod="gene"; méthode de répartition actuelle (defaut: gene)
II fonctions spécifiques a la vue graph
a/ fonction de manipulation
-initGridModel()
-getRadius(cloneID)
-updateStyle()
-initGrid()
-changeSplitMethod(new_splitM)
b/ fonction d'animation
-tick() retrace une image
-move() déplace les nodes
-updateRadius() modifie la taille des rayons de chaque nodes
-debugNaN()
-collide() résolution des collisions
/////////////////////////////////////////////////////////////////////////////////////
Class List
I Contenu spécifique a la vue List
II fonctions spécifiques a la vue List
-div_elem
-div_cluster
-edit_name
//////////////////////////////////////////////////////////////////////////////////////
les noms par defaut dans vidjil
Model m
ScatterPlot sp
Graph graph
List list
Segmenter segment
quelques exemples:
pour accéder aux objets depuis une console javascript
(avec chrome/chromium pour un résultat plus lisible)
m : retourne le contenu du model
m.__proto__ : retourne la liste des methodes disponibles pour le model
m.windows : retourne la liste des fenetres
m.clones[15] : retourne le clone n°15
graph.update() : met a jour le graphique
graph.update : retourne le code de la fonction upate() de l'objet graph
sp.changeSplitMethod("gene") : active la répartition par gene sur le scatterplot
etc ...
//parametre IMGT par defaut
var imgtInput={};
imgtInput["callback"]="jQuery17106713638880755752_1378825832820"
imgtInput["livret"]="1";
imgtInput["Session"]="&lt;session code=¤0¤ appliName=¤IMGTvquest¤ time=¤3625396897¤/&gt;";
imgtInput["l01p01c02"]="Homo sapiens";
imgtInput["l01p01c04"]="TR";
imgtInput["l01p01c03"]="inline";
imgtInput["l01p01c10"]="";
imgtInput["l01p01c07"]="1. Details";
imgtInput["l01p01c05"]="HTML";
imgtInput["l01p01c09"]="60";
imgtInput["l01p01c60"]="5";
imgtInput["l01p01c12"]="Y";
imgtInput["l01p01c13"]="Y";
imgtInput["l01p01c06"]="Y";
imgtInput["l01p01c24"]="N";
imgtInput["l01p01c14"]="Y";
imgtInput["l01p01c15"]="Y";
imgtInput["l01p01c16"]="Y";
imgtInput["l01p01c41"]="Y";
imgtInput["l01p01c22"]="Y";
imgtInput["l01p01c17"]="Y";
imgtInput["l01p01c23"]="Y";
imgtInput["l01p01c19"]="Y";
imgtInput["l01p01c18"]="Y";
imgtInput["l01p01c20"]="Y";
imgtInput["l01p01c27"]="Y";
imgtInput["l01p01c28"]="Y";
imgtInput["l01p01c29"]="Y";
imgtInput["l01p01c30"]="Y";
imgtInput["l01p01c31"]="Y";
imgtInput["l01p01c32"]="Y";
imgtInput["l01p01c33"]="Y";
imgtInput["l01p01c34"]="Y";
imgtInput["l01p01c46"]="Y";
imgtInput["l01p01c47"]="Y";
imgtInput["l01p01c48"]="Y";
imgtInput["l01p01c49"]="Y";
imgtInput["l01p01c50"]="Y";
imgtInput["l01p01c51"]="Y";
imgtInput["l01p01c52"]="Y";
imgtInput["l01p01c53"]="Y";
imgtInput["l01p01c54"]="Y";
imgtInput["l01p01c55"]="NO";
imgtInput["l01p01c35"]="F+ORF+ in-frame P";
imgtInput["l01p01c36"]="0";
imgtInput["l01p01c40"]="0";
imgtInput["l01p01c25"]="default";
imgtInput["l01p01c37"]="default";
imgtInput["l01p01c38"]="default";
imgtInput["l01p01c39"]="default";
imgtInput["l01p01c08"]="";
imgtInput["l01p01c26"]="";
imgtInput["l01p01c10"]=">a\nATGCGCAGATGC\n";
//parametre igBlast par defaut
var igBlastInput= {};
igBlastInput["queryseq"]="GAAGGCCCCACAGCGTCTTCTGTACTATGACGTCTCCACCGCAAGGGATGTGTTGGAATCAGGACTCAGTCCAGGAAAGTATTATACTCATACACCCAGGAGGTGGAGCTGGATATTGAGACTGCAAAATCTAATTGAAAATGATTCTGGGGTCTATTACTGTGCCACCTTCTGACATAAGAAACCCTTTGGCAGTGGAACAACAC"
igBlastInput["organism"]="human"
igBlastInput["germline_db_V"]="IG_DB/imgt.TR.Homo_sapiens.V.f.orf.p";
igBlastInput["germline_db_D"]="IG_DB/imgt.TR.Homo_sapiens.D.f.orf";
igBlastInput["germline_db_J"]="IG_DB/imgt.TR.Homo_sapiens.J.f.orf.p";
igBlastInput["program"]="blastn";
igBlastInput["min_D_match"]=5;
igBlastInput["D_penalty"]=-4;
igBlastInput["num_alignments_V"]=3;
igBlastInput["num_alignments_D"]=3;
igBlastInput["num_alignments_J"]=3;
igBlastInput["translation="]=true;
igBlastInput["domain"]="imgt";
igBlastInput["outfmt"]=3;
igBlastInput["additional_db"]="";
igBlastInput["v_focus"]=true;
igBlastInput["num_alignments_additional"]=10;
igBlastInput["evalue"]=1;
igBlastInput["LINK_LOC"]="";
igBlastInput["SEARCH_TYPE"]="TCR";
igBlastInput["igsource"]="new";
igBlastInput["analyze"]="on";
igBlastInput["CMD"]="request";
igBlastInput["seqtype"]="TCR";
function imgtPost(data, system) {
imgtInput["l01p01c10"]=data;
if (system=="IGH"){
imgtInput["l01p01c04"]="IG";
}
if (system=="TRG"){
imgtInput["l01p01c04"]="TR";
}
var form = document.getElementById("form");
form.innerHTML="";
form.target = "_blank";
form.action = "http://www.imgt.org/IMGT_vquest/vquest";
form.method = "POST";
for (var k in imgtInput){
var input = document.createElement("input");
input.type = "hidden";
input.name = k;
input.value = imgtInput[k];
form.appendChild(input);
}
form.submit();
}
function igBlastPost(data,system){
igBlastInput["queryseq"]=data;
if (system=="IGH"){
igBlastInput["germline_db_V"]="IG_DB/imgt.Homo_sapiens.V.f.orf.p";
igBlastInput["germline_db_D"]="IG_DB/imgt.Homo_sapiens.D.f.orf";
igBlastInput["germline_db_J"]="IG_DB/imgt.Homo_sapiens.J.f.orf";
}
if (system=="TRG"){
igBlastInput["germline_db_V"]="IG_DB/imgt.TR.Homo_sapiens.V.f.orf.p";
igBlastInput["germline_db_D"]="IG_DB/imgt.TR.Homo_sapiens.D.f.orf";
igBlastInput["germline_db_J"]="IG_DB/imgt.TR.Homo_sapiens.J.f.orf.p";
}
var form = document.getElementById("form");
form.innerHTML="";
form.target = "_blank";
form.action = "http://www.ncbi.nlm.nih.gov/igblast/igblast.cgi";
form.method = "POST";
for (var k in igBlastInput){
var input = document.createElement("input");
input.type = "hidden";
input.name = k;
input.value = igBlastInput[k];
form.appendChild(input);
}
form.submit();
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* FileSaver.js
* A saveAs() FileSaver implementation.
* 2013-01-23
*
* By Eli Grey, http://eligrey.com
* License: X11/MIT
* See LICENSE.md
*/
/*global self */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs = saveAs
|| (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator))
|| (function(view) {
"use strict";
var
doc = view.document
// only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
, get_URL = function() {
return view.URL || view.webkitURL || view;
}
, URL = view.URL || view.webkitURL || view
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
, can_use_save_link = "download" in save_link
, click = function(node) {
var event = doc.createEvent("MouseEvents");
event.initMouseEvent(
"click", true, false, view, 0, 0, 0, 0, 0
, false, false, false, false, 0, null
);
node.dispatchEvent(event);
}
, webkit_req_fs = view.webkitRequestFileSystem
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
, throw_outside = function (ex) {
(view.setImmediate || view.setTimeout)(function() {
throw ex;
}, 0);
}
, force_saveable_type = "application/octet-stream"
, fs_min_size = 0
, deletion_queue = []
, process_deletion_queue = function() {
var i = deletion_queue.length;
while (i--) {
var file = deletion_queue[i];
if (typeof file === "string") { // file is an object URL
URL.revokeObjectURL(file);
} else { // file is a File
file.remove();
}
}
deletion_queue.length = 0; // clear queue
}
, dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
}
, FileSaver = function(blob, name) {
// First try a.download, then web filesystem, then object URLs
var
filesaver = this
, type = blob.type
, blob_changed = false
, object_url
, target_view
, get_object_url = function() {
var object_url = get_URL().createObjectURL(blob);
deletion_queue.push(object_url);
return object_url;
}
, dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
}
// on any filesys errors revert to saving with object URLs
, fs_error = function() {
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_object_url(blob);
}
if (target_view) {
target_view.location.href = object_url;
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
}
, abortable = function(func) {
return function() {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
}
, create_if_not_found = {create: true, exclusive: false}
, slice
;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_object_url(blob);
save_link.href = object_url;
save_link.download = name;
click(save_link);
filesaver.readyState = filesaver.DONE;
dispatch_all();
return;
}
// Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
}
// Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.