...
 
Commits (122)
......@@ -299,7 +299,6 @@ test_server_functional:
- sed -i '/\/etc\/nginx\/ssl\:\/etc\/nginx\/ssl/d' ./docker/docker-compose.yml
- sed -i 's/\:latest/\:test/g' ./docker/docker-compose.yml
- cd docker/vidjil-server/conf/ && mv defs.py defs_https.py && mv defs_http.py defs.py && cd ../../..
- cd docker/vidjil-client/conf/ && mv conf.js conf_https.js && mv conf_http.js conf.js && cd ../../..
- make germline && cp browser/js/germline.js docker/vidjil-client/conf
- cd docker && docker-compose up -d && cd ..
- sed -i "s/^python\ \.\.\/\.\.\/\.\./docker\ exec\ docker_uwsgi_1\ python\ \/usr\/share\/vidjil\/server\/web2py/" server/web2py/applications/vidjil/tests/init_func_test_db.sh
......
......@@ -14,7 +14,7 @@ using namespace std;
#define THRESHOLD_BAD_COVERAGE .5 /* Threshold below which the representatie
coverage is considered bad */
static ReadQualityScore DEFAULT_READ_SCORE;
static RandomScore DEFAULT_READ_SCORE;
/**
* Compute a representative sequence from a list of sequences.
......
......@@ -3,7 +3,7 @@
"samples" : {
"number" : 1,
"original_names" : [ "/some/file" ] ,
"original_names" : [ "/some/file_1" ] ,
"run_timestamp" : [ "2015-02-19 16:37:06" ] ,
"producer" : [ "vidjil dev 0cf35de (2015-02-17)" ] ,
"log" : [ "Some log" ],
......
......@@ -3,7 +3,7 @@
"samples" : {
"number" : 1,
"original_names" : [ "/some/file" ] ,
"original_names" : [ "/some/file_2" ] ,
"run_timestamp" : [ "2015-02-19 16:37:06" ] ,
"producer" : [ "vidjil dev 0cf35de (2015-02-17)" ] ,
"log" : [ "Some log" ],
......@@ -27,6 +27,7 @@
"sequence" : "seq-1",
"reads" : [ 300 ] ,
"normalized_reads" : [ 500 ] ,
"top" : 1,
"germline" : "IGH"
},
......
This diff is collapsed.
......@@ -2,12 +2,13 @@
Parses output of various RepSeq programs.
Takes either:
- a .fa file, a _Summary.txt file as produced by IMGT/V-QUEST
- or a results file produced by MiXCR
- or a results file produced by MiXCR or IgReC
and creates a .vdj file to be checked by should-vdj-to-tap.py
python repseq_vdj.py data-curated/curated_IG.fa data-curated/curated_ig_Summary.txt > data-curated/imgt-IG.vdj
python repsep_vdj.py data-curated/curated_TR.fa data-curated/curated_tr_Summary.txt > data-curated/imgt-TR.vdj
python repseq_vdj.py data-curated/mixcr.results > data-curated/mixcr.vdj
python repseq_vdj.py bla.igrec.results
python repseq_vdj.py data-curated/curated_IG.fa data-curated/igblast/IG/*.aln > data-curated/igblast-IG.vdj > data-curated/igblast-IG.vdj
python repseq_vdj.py data-curated/curated_TR.fa data-curated/igblast/TR/*.aln > data-curated/igblast-TR.vdj > data-curated/igblast-TR.vdj
'''
......@@ -91,6 +92,9 @@ class Result(VDJ_Formatter):
self.populate()
def __contains__ (self, key):
return key in self.d
def __getitem__(self, key):
return self.d[key]
......@@ -98,6 +102,49 @@ class Result(VDJ_Formatter):
return str(self.d)
### IgReC
IGREC_LABELS = [
'Read id', 'locus',
'V id', 'V start', 'V end', 'V score',
'J id', 'J start', 'J end', 'J score',
]
class IgReC_Result(Result):
r'''
>>> lig = '\t'.join(['blabli4577', 'TRB', 'TRBV13*02', '1', '164', '0.58156', 'TRBJ1-5*01', '319', '367', '0.94'])
>>> r = IgReC_Result(lig)
>>> r['Read id']
'blabli4577'
>>> r.vdj[V]
['TRBV13*02']
>>> r.vdj[J]
['TRBJ1-5*01']
'''
def parse(self, l):
self.labels = IGREC_LABELS
if ('\t' in l.strip()):
return l
else:
return None
def populate(self):
self.vdj[V] = [self['V id']]
self.vdj[J] = [self['J id']]
def header_igrec_results(ff_igrec):
f = open(ff_igrec).__iter__()
while True:
l = f.next()
result = IgReC_Result(l)
yield result['Read id'].replace('_', ' '), result.to_vdj()
### MiXCR
......@@ -111,16 +158,20 @@ class MiXCR_Result(Result):
return None
def populate(self):
self.vdj[V] = [self['Best V hit']]
if self['Best D hit']:
self.vdj[D] = [self['Best D hit']]
self.vdj[J] = [self['Best J hit']]
self.vdj[V] = [self['bestVHit']]
if self['bestDHit']:
self.vdj[D] = [self['bestDHit']]
self.vdj[J] = [self['bestJHit']]
self.vdj[N1] = self['N. Seq. VDJunction']
self.vdj[N2] = self['N. Seq. DJJunction']
self.vdj[N] = self['N. Seq. VJJunction']
if 'nSeqVDJunction' in self:
self.vdj[N1] = self['nSeqVDJunction']
if 'nSeqDJJunction' in self:
self.vdj[N2] = self['nSeqDJJunction']
if 'nSeqVJJunction' in self:
self.vdj[N] = self['nSeqVJJunction']
self.vdj[JUNCTION] = self['AA. Seq. CDR3']
if 'aaSeqCDR3' in self:
self.vdj[JUNCTION] = self['aaSeqCDR3']
def header_mixcr_results(ff_mixcr):
......@@ -128,12 +179,12 @@ def header_mixcr_results(ff_mixcr):
f = open(ff_mixcr).__iter__()
mixcr_first_line = f.next()
globals()['mixcr_labels'] = mixcr_first_line.split('\t')
globals()['mixcr_labels'] = mixcr_first_line.rstrip().split('\t')
while True:
l = f.next()
l = f.next().rstrip()
result = MiXCR_Result(l)
yield result['Description R1'], result.to_vdj()
yield result['descrsR1'], result.to_vdj()
......@@ -354,6 +405,8 @@ if __name__ == '__main__':
if 'mixcr' in sys.argv[1]:
vdj.parse_from_gen(header_mixcr_results(sys.argv[1]))
elif 'igrec' in sys.argv[1]:
vdj.parse_from_gen(header_igrec_results(sys.argv[1]))
elif 'igblast' in sys.argv[2]:
vdj.parse_from_gen(header_igblast_results(sys.argv[1], sys.argv[2:]))
else:
......
......@@ -26,7 +26,7 @@ $ First clone -- find the good number of reads
2:clone-001--.*--0000008
$ First clone -- find the good representative
1:clone-001--.*--lcl.FLN1FA001BQ9J5.1.-.88,232.-.4
1:GACAATTCCAAGAACACGCTGTACCTGCAAATGAACAGCCTGCGAGCCGAGGACACGGCCACCTATTACTGTACCCGGGAGGAACAATATAGCAGCTGGTACTTTGACTTCTGGGGCCAGGGGATCCTGGTCACCGTCTCCTCAG
$ First clone -- find the good coverage
1:clone-001--.* 145 bp .62. of 232.0 bp.
!LAUNCH: $VIDJIL_DIR/$EXEC -w 20 -g $VIDJIL_DIR/germline/homo-sapiens.g:TRG $VIDJIL_DATA/test-random-consensus.fa.gz > consensus-default.log
!LAUNCH: $VIDJIL_DIR/$EXEC -w 20 -g $VIDJIL_DIR/germline/homo-sapiens.g:TRG --consensus-on-random-sample $VIDJIL_DATA/test-random-consensus.fa.gz > consensus-random.log
!LAUNCH: $VIDJIL_DIR/$EXEC -w 20 -g $VIDJIL_DIR/germline/homo-sapiens.g:TRG --consensus-on-longest-sequences $VIDJIL_DATA/test-random-consensus.fa.gz > consensus-longest.log
!LAUNCH: $VIDJIL_DIR/$EXEC -w 20 -g $VIDJIL_DIR/germline/homo-sapiens.g:TRG $VIDJIL_DATA/test-random-consensus.fa.gz > consensus-random.log
!NO_LAUNCHER:
!LAUNCH: diff consensus-default.log consensus-random.log
!LAUNCH: diff consensus-longest.log consensus-random.log
!EXIT_CODE: 1
$ Output should differ: default has a consensus of 52bp (with the spurious insertion)
$ Output should differ: ReadQualityScore gives a consensus of 52bp (with the spurious insertion)
# Appears twice in the header of the consensus sequence and in the similarity matrix
2:^< .* 52 bp
1:^< CTTTT
......
>IGHV1-18 (IGHJ1, IGHJ2)
atggagctgaggagcctgagatctgacgacacggccgtgtattactgtgcgagagagctgaatacttccagcactggggccagggcaccctggtcaccgtctcctcag
......@@ -137,7 +137,7 @@ def should_pattern_to_regex(p):
gene = gene.replace('/', '/?')
if args.ignore_D and ('IGHD' in gene or 'TRBD' in gene or 'TRDD' in gene):
gene = '[^[:space]]*'
gene = '[^[:space:]]*'
allele = '[[:digit:]]*'
if args.ignore_allele:
......@@ -168,7 +168,7 @@ def should_pattern_to_regex(p):
if len(r) > 1 and r[1][0] == '|':
# We have an alternative
regex_pattern = '('+' '.join(r)+').*'
regex_pattern = '.*('+''.join(r)+').*'
else:
regex_pattern = '.*'.join(r)
......@@ -248,6 +248,46 @@ def should_result_to_tap(should_pattern, result, tap_id):
True
>>> srtt_ok(should, other_allele)
True
>>> should = 'TRAV1-1 TRAJ1'
>>> other = 'TRAV1-1*01 1/ACG/3 TRAJ1*01'
>>> (args.ignore_N, args.ignore_del) = (True, True)
>>> srtt_ok(should, other)
True
>>> should = 'TRAV1-1 (TRAJ1, TRAJ2)'
>>> other = 'TRAV1-1*01 1/ACG/3 TRAJ1*01'
>>> srtt_ok(should, other)
True
>>> should = '(IGKV1D-37, IGKV1-37) IGKJ5'
>>> curated = 'IGKV1D-37*01 2/ATA/0 IGKJ5*01'
>>> srtt_ok(should, curated)
True
>>> should = 'IGKV1D-37 IGKJ5'
>>> curated = 'IGKV1D-37*01 2/ATA/0 IGKJ5*01'
>>> srtt_ok(should, curated)
True
# Negative tests matter too
>>> should = '(IGKV1D-37, IGKV1-37) IGKJ5'
>>> curated = 'IGKV1D-32*01 2/ATA/0 IGKJ5*01'
>>> srtt_ok(should, curated)
False
>>> should = 'IGHV7-4-1*02 IGHD6-25*01 (IGHJ6*02 ,IGHJ6*04)'
>>> obtained = 'IGHV7-4-1*02 1//4 IGHJ6*01'
>>> args.ignore_D = True
>>> srtt_ok(should, obtained)
True
>>> args.ignore_allele = False
>>> srtt_ok(should, obtained)
False
>>> (args.ignore_allele, args.ignore_D) = (True, False)
>>> srtt_ok(should, obtained)
False
'''
m_locus = r_locus.search(should_pattern)
......
#include "core/bioreader.hpp"
#include "core/representative.h"
#include "core/read_score.h"
void testRepresentative() {
list<Sequence> reads = BioReader("data/representative.fq").getAll();
......@@ -13,7 +14,8 @@ void testRepresentative() {
krc.setCoverageReferenceLength(50);
krc.setRequiredSequence("CCGGGGGGGGGGTTT");
krc.compute();
ReadQualityScore vrs = ReadQualityScore();
krc.compute(vrs);
Sequence representative = krc.getRepresentative();
// Seq3 is the longest it should be taken when performing 0 extra iteration
......@@ -21,20 +23,20 @@ void testRepresentative() {
"If we take the first representative we should have seq3, and not at the beginning (" << representative.label << " instead)");
krc.setStabilityLimit(1);
krc.compute();
krc.compute(vrs);
representative = krc.getRepresentative();
TAP_TEST_EQUAL(representative.label.find("seq3-[37,73]"), 0, TEST_KMER_REPRESENTATIVE,
"When allowing one step before stability, we should still have seq3 (" << representative.label << " instead)");
krc.setStabilityLimit(2);
krc.compute();
krc.compute(vrs);
representative = krc.getRepresentative();
TAP_TEST_EQUAL(representative.label.find("seq1-[0,41]"), 0, TEST_KMER_REPRESENTATIVE,
"When allowing two steps before stability, we should reach seq1 (" << representative.label << " instead)");
krc.setRevcomp(true);
krc.setRequiredSequence("ATCGCGCCCT"); // revcomp
krc.compute();
krc.compute(vrs);
representative = krc.getRepresentative();
string quality = krc.getQuality();
TAP_TEST_EQUAL(representative.label.find("seq2-[33,52]"), 0, TEST_KMER_REPRESENTATIVE_REQUIRED_SEQ,
......@@ -47,7 +49,7 @@ void testRepresentative() {
krc.setRevcomp(false);
krc.compute();
krc.compute(vrs);
TAP_TEST(! krc.hasRepresentative(), TEST_KMER_REPRESENTATIVE_REQUIRED_SEQ,
"When requiring sequence AGGGCGCGAT and revcomp=false, we shouldn't find anything (the sequence is revcomp-ed)");
}
......
#include <core/windows.h>
#include <core/germline.h>
#include <core/bioreader.hpp>
#include <core/read_score.h>
#include <map>
void testWSAdd() {
......@@ -110,6 +111,8 @@ void testWSAdd() {
void testWSAddWithLimit() {
map<string, string> labels;
WindowsStorage ws(labels);
ReadQualityScore rqs;
ws.setScorer(&rqs);
ws.setMaximalNbReadsPerWindow(3);
ws.setBinParameters(1, 20);
Sequence seq = {"label", "l", "GATACATTAGACAGCT", "", 0};
......
......@@ -471,12 +471,12 @@ int main (int argc, char **argv)
-> group(group);
VirtualReadScore *readScorer = &DEFAULT_READ_SCORE;
RandomScore randomScore;
app.add_flag_function("--consensus-on-random-sample",
[&readScorer, &randomScore](size_t n) {
ReadQualityScore readQualityScore;
app.add_flag_function("--consensus-on-longest-sequences",
[&readScorer, &readQualityScore](size_t n) {
UNUSED(n);
readScorer = &randomScore;
}, "for large clones, use a random sample of reads to compute the consensus sequence (instead of a sample of the longest and highest quality reads)")
readScorer = &readQualityScore;
}, "for large clones, use a sample of the longest and highest quality reads to compute the consensus sequence (instead of a random sample)")
->group(group) -> level();
// ----------------------------------------------------------------------------------------------------------------------
......
......@@ -85,6 +85,9 @@ function loadAfterConf() {
}else{
main();
}
if (typeof config.addons !== "undefined") {
require(config.addons);
}
})
})
},
......
......@@ -277,7 +277,7 @@ VidjilAutoComplete.prototype = {
if (uncached.length > 0) {
$.ajax({
type: "GET",
type: "POST",
data: {
keys: JSON.stringify(uncached)
},
......
......@@ -234,6 +234,7 @@ Clone.prototype = {
/**
* Compute feature positions (start/stop) from its sequence, unless they are already present
* Computed positions are converted to start from 0 and can be used without manipualtions
*/
computeSegFeatureFromSeq: function(field_name)
{
......@@ -251,8 +252,8 @@ Clone.prototype = {
// No feature here
return;
this.seg[field_name].start = pos + 1
this.seg[field_name].stop = pos + seq.length
this.seg[field_name].start = pos
this.seg[field_name].stop = pos + seq.length -1
},
......@@ -273,7 +274,7 @@ Clone.prototype = {
getSegNtSequence: function(field_name) {
positions = this.getSegStartStop(field_name)
if (positions !== null) {
return this.sequence.substr(positions.start-1, positions.stop - positions.start+1)
return this.sequence.substr(positions.start, positions.stop - positions.start+1)
}
return '';
},
......@@ -311,6 +312,7 @@ Clone.prototype = {
/**
* Get the start and stop position of a given field (e.g. cdr3)
* Getted positions are 0 based.
* If it does not exist return null
*/
getSegStartStop: function(field_name) {
......
/*
* Vidjil browser, main configuration file
* Vidjil client, main configuration file
* This file must be named 'js/conf.js' to be taken into account
* */
var config = {
/****************
* Static alerts
*/
// "alert": "Rescue server",
/****************
* External services
*/
/* Used for the 'align' script
* If this is not defined, the 'align' button is not available
*/
"cgi_address" : "https://db.vidjil.org/cgi/", // Public test server
// "cgi_address" : "http://127.0.1.1/cgi-bin/",
/* The following options control how the user may have access to .vidjil files.
/* Proxy config for IMGT querying */
/*
"proxy": "https://db.vidjil.org/vidjil/proxy/imgt",
*/
/* Used for the standalone http://app.vidjil.org/analyze page */
"segmenter_address" : "https://db.vidjil.org/vidjil/segmenter",
/* Do we have access to a CloneDB ? */
"clonedb": false,
/****************
/* Access to .vidjil files
* Any combination of 1), 2) and 3) should work
*/
......@@ -42,29 +65,19 @@ var config = {
// "autoload" : "data/Stanford-S22.vidjil",
// "autoload_analysis" : "data/Stanford-S22.analysis"
// Proxy config for IMGT querying
/*
"proxy": "https://db.vidjil.org/vidjil/proxy/imgt"
*/
/* Used for the standalone segmenter page */
"segmenter_address" : "https://db.vidjil.org/vidjil/segmenter",
/****************
* Load extra scripts
*/
/* "addons" : ["js/lib/important-lib.js", "js/myscript.js"], */
/* Do we have access to a CloneDB ? */
"clonedb": false,
/****************
* Tips of the day
*/
"doc_address" : "doctips/",
"available_tips" : [
'T01', 'T02', 'T03',
'T30', 'T31', 'T32'
],
"available_tips" : [ ]
// [ 'T01', 'T02', 'T03', 'T30', 'T31', 'T32' ]
/****************
* Static alerts
*/
// "alert": "Rescue server",
}
......@@ -12,59 +12,40 @@ function setCrossDomainModel(model) {
//parametre IMGT par defaut
function initImgtInput(species) {
var imgtInput = {};
imgtInput.callback = "jQuery17106713638880755752_1378825832820";
imgtInput.livret = "1";
imgtInput.Session = "&lt;session code=¤0¤ appliName=¤IMGTvquest¤ time=¤3625396897¤/&gt;";
imgtInput.l01p01c02 = species;
imgtInput.l01p01c04 = "TR";
imgtInput.l01p01c03 = "inline";
imgtInput.l01p01c10 = "";
imgtInput.l01p01c07 = "2. Synthesis";
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 = "N";
imgtInput.l01p01c47 = "Y"; // nt-sequences
imgtInput.l01p01c48 = "N";
imgtInput.l01p01c49 = "N";
imgtInput.l01p01c50 = "N"; // Junction
imgtInput.l01p01c51 = "N";
imgtInput.l01p01c52 = "N";
imgtInput.l01p01c53 = "N";
imgtInput.l01p01c54 = "N";
imgtInput.l01p01c55 = "NO";
imgtInput.l01p01c35 = "F+ORF+ in-frame P";
imgtInput.l01p01c36 = "0";
imgtInput.l01p01c40 = "1";
imgtInput.l01p01c25 = "default";
imgtInput.l01p01c37 = "default";
imgtInput.l01p01c38 = "default";
imgtInput.l01p01c39 = "default";
imgtInput.l01p01c08 = "";
imgtInput.l01p01c26 = "";
imgtInput.l01p01c10 = ">a\nATGCGCAGATGC\n";
imgtInput.species = getSpeciesCommonName(species);
imgtInput.receptorOrLocusType = "TR";
imgtInput.inputType = "inline";
imgtInput.resultType = "synthesis";
imgtInput.outputType = "html";
imgtInput.nbNtPerLine = "60";
imgtInput.sv_V_GENEordertable = "1";
imgtInput.sv_V_GENEalignment = "true";
imgtInput.sv_V_REGIONalignment = "true";
imgtInput.sv_V_REGIONtranslation = "true";
imgtInput.sv_V_REGIONprotdisplay = "true";
imgtInput.sv_V_REGIONprotdisplay2 = "true";
imgtInput.sv_V_REGIONprotdisplay3 = "true";
imgtInput.sv_V_REGIONfrequentAA = "true";
imgtInput.sv_IMGTjctaResults = "true";
// part for the version where we asynchronously get results from V-QUEST
imgtInput.xv_IMGTgappedNt = "false";
imgtInput.xv_summary = "false";
imgtInput.xv_ntseq = "true"; // nt-sequences
imgtInput.xv_IMGTgappedAA = "false";
imgtInput.xv_AAseq = "false";
imgtInput.xv_JUNCTION = "false"; // Junction
imgtInput.xv_V_REGIONmuttable = "false";
imgtInput.xv_V_REGIONmutstatsNt = "false";
imgtInput.xv_V_REGIONmutstatsAA = "false";
imgtInput.xv_V_REGIONhotspots = "false";
// end of part
imgtInput.IMGTrefdirSet = "1"; // "F+ORF+ in-frame P";
imgtInput.IMGTrefdirAlleles = "true";
imgtInput.V_REGIONsearchIndel = "true";
imgtInput.nbD_GENE = ""; // Default value: 1 for IGH, 1 for TRB, 3 for TRD
imgtInput.sequences = "";
return imgtInput;
}
......@@ -101,17 +82,17 @@ function initIgBlastInput() {
function imgtPost(species, data, system) {
var imgtInput = initImgtInput(species);
imgtInput.l01p01c10 = data;
imgtInput.sequences = data;
if (system[0] == "I") {
imgtInput.l01p01c04 = "IG";
imgtInput.receptorOrLocusType = "IG";
}
if (system[0] == "T") {
imgtInput.l01p01c04 = "TR";
imgtInput.receptorOrLocusType = "TR";
}
var form = document.getElementById("form");
form.removeAllChildren();
form.target = "_blank";
form.action = "http://www.imgt.org/IMGT_vquest/vquest";
form.action = "http://www.imgt.org/IMGT_vquest/analysis";
form.method = "POST";
for (var k in imgtInput) {
......@@ -167,15 +148,15 @@ function imgtPostForSegmenter(species, data, system, segmenter, override_imgt_op
});
}
imgtInput.l01p01c07 = "3. Excel";
imgtInput.l01p01c10 = data;
imgtInput.l01p01c62 = 2;
imgtInput.resultType = "excel";
imgtInput.sequences = data;
imgtInput.xv_outputtype = 2;
if (system[0] == "I") {
imgtInput.l01p01c04 = "IG";
imgtInput.receptorOrLocusType = "IG";
}
if (system[0] == "T") {
imgtInput.l01p01c04 = "TR";
imgtInput.receptorOrLocusType = "TR";
}
var form = document.getElementById("form");
form.removeAllChildren();
......
......@@ -472,10 +472,6 @@ List.prototype = {
span_name.innerHTML = clone.getShortName();
span_name.title = clone.getNameAndCode();
span_name.style.color = clone.getColor();
//update star color
var span_star = div_elem.getElementsByClassName("starBox")[0];
span_star.style.color = this.m.tag[clone.getTag()].color
//update clone axis
var span_axis = div_elem.getElementsByClassName("axisBox")[0];
......
......@@ -699,8 +699,11 @@ changeAlleleNotation: function(alleleNotation) {
* if raw is defined, do not normalize
*/
normalize_reads: function(clone, time, raw) {
if (this.normalization_mode == this.NORM_EXTERNAL && clone.normalized_reads != undefined && raw == undefined) {
return clone.normalized_reads[time] ;
if (this.normalization_mode == this.NORM_EXTERNAL &&
clone.normalized_reads != undefined &&
clone.normalized_reads[time] != null &&
raw == undefined) {
return clone.normalized_reads[time] ;
} else {
return clone.reads[time] ;
}
......@@ -1201,8 +1204,11 @@ changeAlleleNotation: function(alleleNotation) {
* @param {integer[]} - list - array of clone index
* */
updateElemStyle: function (list) {
this.updateModel();
for (var i = 0; i < this.view.length; i++) {
for (var i = 0; i < list.length; i++) {
this.clone(list[i]).updateColor();
this.clone(list[i]).updateCloneTagIcon();
}
for (i = 0; i < this.view.length; i++) {
this.view[i].updateElemStyle(list);
}
},
......
......@@ -889,8 +889,8 @@ Segment.prototype = {
}
if (address == 'IMGTSeg') {
imgtPostForSegmenter(this.m.species, request, system, this);
var change_options = {'l01p01c47' : 'N', // Deactivate default output
'l01p01c45' : 'Y'}; // Activate Summary output
var change_options = {'xv_ntseq' : 'false', // Deactivate default output
'xv_summary' : 'true'}; // Activate Summary output
imgtPostForSegmenter(this.m.species, request, system, this, change_options);
}
if (address == 'ARResT') arrestPost(request, system);
......
......@@ -134,6 +134,25 @@ function get_mutations(ref, seq, frame, with_end_codon) {
return mutations;
}
/**
* @return the common name of a species. Or the original name if the common
* name has not been set. The common names are given so that they are
* compatible with IMGT/V-QUEST®
*/
function getSpeciesCommonName(species) {
var lower_species = species.toLowerCase();
switch(lower_species) {
case "homo sapiens":
return "human";
case "mus musculus":
return "house mouse";
case "gallus gallus":
return "chicken";
default:
return species;
}
}
/**
* Find the position of the nth occurence of needle
*
......
......@@ -15,7 +15,7 @@ QUnit.module("Clone", {
"3start" : 15,
"5" : {'start': 1, 'end': 5}, // 0-based (old format, with 'end')
"cdr3": {
"start": 11,
"start": 8,
"stop": 16,
"aa": "ABCDE"
},
......@@ -119,7 +119,7 @@ var json_clone6 = {
"id" : "id6",
"germline" : "TRG",
"reads" : [10,10,0,30],
"normalized_reads" : [20,20,0,30],
"normalized_reads" : [20,20,0,null],
}
QUnit.test("name, informations, getHtmlInfo", function(assert) {
......@@ -248,10 +248,10 @@ QUnit.test("name, informations, getHtmlInfo", function(assert) {
"getHtmlInfo: segmentation information (V gene) after changment");
// Test junction in html export
assert.includes(html, "<tr><td>junction</td><td colspan='4'>aat</td></tr>",
assert.includes(html, "<tr><td>junction</td><td colspan='4'>att</td></tr>",
"getHtmlInfo c1: junction info for productive clone");
html = c3.getHtmlInfo();
assert.includes(html, "<tr><td>junction</td><td colspan='4'>aaaaaaaaattt</td></tr>",
assert.includes(html, "<tr><td>junction</td><td colspan='4'>aaaaaaaatttt</td></tr>",
"getHtmlInfo c3: junction info for non productive clone");
assert.includes(html, "<tr><td>junction (AA seq)</td><td colspan='4'>WKIC</td></tr>",
"getHtmlInfo c3: junction (AAseq) info for non productive clone");
......@@ -272,10 +272,10 @@ QUnit.test('clone: get info from seg', function(assert) {
assert.notOk(c1.hasSeg('toto'), "clone1 doesn't have toto")
assert.notOk(c1.hasSeg('junction', 'toto'), "clone1 has junction but doesn't have toto")
assert.equal(c1.getSegLength('cdr3'), 6, "CDR3 length");
assert.equal(c1.getSegLength('cdr3'), 9, "CDR3 length");
assert.equal(c2.getSegLength('cdr3'), 'undefined', "no cdr3 in c2");
var pos_cdr3 = c1.getSegStartStop('cdr3')
assert.equal(pos_cdr3['start'], 10, "CDR3 length")
assert.equal(pos_cdr3['start'], 7, "CDR3 length")
assert.equal(pos_cdr3['stop'], 15, "CDR3 length")
assert.equal(c1.getSegStartStop('toto'), null, "no toto record")
var pos_junction = c3.getSegStartStop('junction')
......@@ -292,7 +292,8 @@ QUnit.test('clone: get info from seg', function(assert) {
c1.computeEValue()
assert.equal(c1.eValue, 1e-2, 'Recomputing e-value should not change its value')
assert.equal(c1.getSegNtSequence('junction'), 'aat', 'junction c1')
assert.equal(c1.getSegNtSequence('junction'), 'att', 'junction c1')
assert.equal(c1.getSegNtSequence('cdr3'), 'aaatttttt', 'sequence cdr3 c1 (by getSegNtSequence)')
assert.equal(c1.getSegAASequence('junction'), '', 'no AA junction for c1')
assert.equal(c1.getSegAASequence('cdr3'), 'ABCDE', 'AA CDR3 for c1')
......@@ -310,7 +311,7 @@ QUnit.test("clone : feature defined by a nucleotide sequence", function(assert)
assert.deepEqual(c3.getSegStartStop('somefeature'), null, "start/stop positions are not present")
c3.computeSegFeatureFromSeq('somefeature')
assert.deepEqual(c3.getSegStartStop('somefeature'), {"start": 7, "stop": 13}, "start/stop positions, computed from sequence")
assert.deepEqual(c3.getSegStartStop('somefeature'), {"start": 6, "stop": 12}, "start/stop positions, computed from sequence")
assert.equal(c3.getSegLength('somefeature'), 7, "length of the feature");
});
......@@ -439,7 +440,7 @@ QUnit.test("export", function(assert) {
"TRG", "-/-",
"undefined V", "IGHD2*03", "IGHV4*01",
"not productive",
"aaaaaaaaattt",
"aaaaaaaatttt",
"WKIC",
"AAAAAAAAAATTTTTTTTT",
10, 10, 15, 15,
......
......@@ -349,8 +349,8 @@ QUnit.test("model: primer detection", function(assert) {
// primer found inside clones
assert.equal(typeof m.clones[2]["seg"]["primer5"], "undefined", "Control neg primer 5 not in sequence")
assert.equal(typeof m.clones[2]["seg"]["primer3"], "undefined", "Control neg primer 3 not in sequence")
assert.deepEqual(m.clones[3]["seg"]["primer5"], { seq: "GGAAGGCCCCACAGCG", start: 1, stop: 16 }, "Found primer 5")
assert.deepEqual(m.clones[3]["seg"]["primer3"], { seq: "AACTTCGCCTGGTAA", start: 227, stop: 241 }, "Found primer 3")
assert.deepEqual(m.clones[3]["seg"]["primer5"], { seq: "GGAAGGCCCCACAGCG", start: 0, stop: 15 }, "Found primer 5")
assert.deepEqual(m.clones[3]["seg"]["primer3"], { seq: "AACTTCGCCTGGTAA", start: 226, stop: 240 }, "Found primer 3")
m.cleanPreviousFeature("primer3")
......@@ -423,6 +423,12 @@ QUnit.test("normalization", function(assert) {
m.initClones()
assert.equal(m.have_external_normalization, false, "Model have_external_normalization is correctly resetted")
m.set_normalization(m.NORM_EXTERNAL)
assert.equal(m.normalize_reads(c6, 0, undefined), 20, "normalize_reads; get normalized value if present")
assert.equal(m.normalize_reads(c6, 0, false), 10, "normalize_reads; get raw value if specified" )
assert.equal(m.normalize_reads(c6, 2, undefined), 0, "normalize_reads; get value at 0 as computed by external normalization" )
assert.equal(m.normalize_reads(c6, 3, undefined), 30, "normalize_reads; get raw value if normalization equal null")
})
QUnit.test("findGermlineFromGene", function(assert) {
......
......@@ -111,8 +111,8 @@ QUnit.test("sequence", function(assert) {
assert.equal(h.stop, 6, '"f1" feature, stop')
h = seq1.get_positionned_highlight('f2', '')
assert.equal(h.start, 15, '"f2" feature, start')
assert.equal(h.stop, 20, '"f2" feature, stop')
assert.equal(h.start, 14, '"f2" feature, start')
assert.equal(h.stop, 19, '"f2" feature, stop')
segment.updateElemStyle([4]) /* Will remove sequence 4 from the segmenter
* as it is not really selected
......@@ -138,11 +138,11 @@ QUnit.test("segt", function (assert) {
assert.equal(m.clone(3).getSequence(),"GGAAGGCCCCACAGCGTCTTCTGTACTATGACGTCTCCACCGCAAGGGATGTGTTGGAATCAGGACTCAGTCCAGGAAAGTATTATACTCATACACCCAGGAGGTGGAGCTGGATATTGAGACTGCAAAATCTAATTGAAAATGATTCTGGGGTCTATTACTGTGCCACCTGGGACAGGCTGAAGGATTGGATCAAGACGTTTGCAAAAGGGACTAGGCTCATAGTAACTTCGCCTGGTAA","sequence")
m.clone(3).addSegFeatureFromSeq('test_feature','CACCCAGGAGGTGGAGCTGGATATTGAGACT');
f1 = segment.sequence[3].get_positionned_highlight('test_feature','');
assert.equal(f1.start, 94 , "feature start");
assert.equal(f1.stop, 124, "feature stop");
assert.equal(f1.start, 93 , "feature start");
assert.equal(f1.stop, 123, "feature stop");
assert.equal(f1.seq,'CACCCAGGAGGTGGAGCTGGATATTGAGACT', "feature sequence");
assert.equal(m.clone(3).getSegNtSequence("test_feature"), "CACCCAGGAGGTGGAGCTGGATATTGAGACT", "feature sequence 3");
assert.deepEqual(m.clone(3).getSegFeature("test_feature"),{"seq": "CACCCAGGAGGTGGAGCTGGATATTGAGACT", "start": 94, "stop": 124}, "feature sequence 4");
assert.deepEqual(m.clone(3).getSegFeature("test_feature"),{"seq": "CACCCAGGAGGTGGAGCTGGATATTGAGACT", "start": 93, "stop": 123}, "feature sequence 4");
// segment.sequence[3].computeAAseq()
// assert.equal(m.clone(3).getSegAASequence("cdr3"),"AKDILKSLKQQLATPNWFDP","feature sequence 2")
......@@ -156,7 +156,7 @@ QUnit.test("segt", function (assert) {
var h = segment.sequence[3].get_positionned_highlight('f1','');
assert.equal(h.start,-1, " start feature value");
assert.equal(h.stop, -1, "stop feature value");
assert.deepEqual(segment.sequence[3].get_positionned_highlight("test_feature",""),{"color": "", "css": "highlight_seq", "seq": "CACCCAGGAGGTGGAGCTGGATATTGAGACT", "start": 94, "stop": 124, "tooltip": ""}, "test feature value")
assert.deepEqual(segment.sequence[3].get_positionned_highlight("test_feature",""),{"color": "", "css": "highlight_seq", "seq": "CACCCAGGAGGTGGAGCTGGATATTGAGACT", "start": 93, "stop": 123, "tooltip": ""}, "test feature value")
assert.equal(m.clone(3).getSegLength('test_feature'),31, "feature length");
m.unselectAll();
assert.equal(segment.toFasta(), "");
......
......@@ -139,6 +139,13 @@ QUnit.test("test nth_ocurrence", function(assert) {
}
);
QUnit.test("test getSpeciesCommonName", function(assert) {
assert.equal(getSpeciesCommonName("homo sapiens"), "human");
assert.equal(getSpeciesCommonName("Homo sapiens"), "human");
assert.equal(getSpeciesCommonName("mus musculus"), "house mouse");
assert.equal(getSpeciesCommonName("gallus gallus"), "chicken");
});
QUnit.test("test tsvToArray", function(assert) {
var tabstring = "head1\thead2\thead3\thead4\nLine 1 data1\tLine 1 data2\tLine 1 data3\tLine 1 data4\n";
tabstring += "Line 2 data1\tLine 2 data2\tLine 2 data3\tLine 2 data4";
......
......@@ -10,7 +10,7 @@ class VidjilBrowser < Watir::Browser
Selenium::WebDriver::Chrome.path = ENV['WATIR_BROWSER_PATH']
end
# :chrome or :safari
if ENV['WATIR_CHROME'] or ENV['WATIR_BROWSER_PATH'].include? "chrom"
if ENV['WATIR_CHROME'] or (ENV['WATIR_BROWSER_PATH'] and ENV['WATIR_BROWSER_PATH'].include? "chrom")
super :chrome
elsif ENV['WATIR_MARIONETTE']
super :firefox
......
This changelog concerns vijil-algo, the algorithmic part (C++) of the Vidjil platform.
2019-05-17 The Vidjil Team
* Better method to build consensus sequences used by default, old behaviour with --consensus-on-longest-sequences #3866
* Optimized analyses with pre-computations, including for e-value estimation !468
* Updated functional .should tests with new syntax, renaming and moving some tests #3206 #3762
2019-04-04 The Vidjil Team
* New --config and --label-json experimental options (vidjil.cpp, lib/CLI11_json.cpp) #3837 #3839
* Improved computation of consensus sequence when there are many reads (vidjil.cpp) !448
......
Here are aggregated notes forming the developer documentation of vidjil-algo.
This documentation is a work-in-progress, it is far from being as polished as the user documentation.
Help can also be found in the source code and in the commit messages.
# Algorithm
## Code organisation
The algorithm follows roughly those steps:
1. The germlines are read. Germlines are in the fasta format and are read
by the Fasta class (`core/fasta.h`). Germlines are built using the
Germline (or MultiGermline) class (`core/germline.h`)
2. The input sequence file (.fasta, .fastq, .gz) is read by an OnlineFasta
(`core/fasta.h`). The difference with the Fasta class being that all the
data is not stored in memory but the file is read online, storing only
the current entry.
3. Windows must be extracted from the read, which is done by the
WindowExtractor class (`core/windowExtractor.h`). This class has an
`extract` method which returns a WindowsStorage object
(`core/windows.h`) in which windows are stored.
4. To save space consumption, all the reads linked to a given window are
not stored. Only the longer ones are kept. The BinReadStorage class is
used for that purpose (`core/read_storage.h`).
5. In the WindowStorage, we now have the information on the clusters and on
the abundance of each cluster. However we lack a sequence representative
of the cluster. For that purpose the class provides a
`getRepresentativeComputer` method that provides a
KmerRepresentativeComputer (`core/representative.h`). This class can
compute a representative sequence using the (long) reads that were
stored for a given window.
6. The representative can then be segmented to determine what V, D and J
genes are at play. This is done by the FineSegmenter (`core/segment.h`).
## The xxx germline
- All germlines are inserted in one index using `build_with_one_index()` and
the segmentation method is set to `SEG_METHOD_MAX12` to tell that the
segmentation must somehow differ.
- So that the FineSegmenter correctly segments the sequence, the `rep_5` and
`rep_3` members (class `Fasta`) of the xxx germline are modified by the
FineSegmenter. The `override_rep5_rep3_from_labels()` method from the
Germline is the one that overwrites those members with the Fasta
corresponding to the affectation found by the KmerSegmenter.
## Tests
### Unit
Unit tests are managed using an internal lightweight poorly-designed
library that outputs a TAP file. They are organised in the directory
[algo/tests](../algo/tests).
All the tests are defined in the [tests.cpp](../algo/tests/tests.cpp) file. But, for the sake of
clarity, this file includes other `cpp` files that incorporate all the
tests. A call to `make` compiles and launches the `tests.cpp` file, which
outputs a TAP file (in case of total success) and creates a `tests.cpp.tap`
file (in every case).
1. Tap test library
The library is defined in the [testing.h](../algo/tests/testing.h) file.
Tests must be declared in the [tests.h](../algo/tests/tests.h) file:
1. Define a new macro (in the enum) corresponding to the test name
2. In `declare_tests()` use `RECORD_TAP_TEST` to associate the macro with a
description (that will be displayed in the TAP output file).
Then testing can be done using the `TAP_TEST` macro. The macro takes three
arguments. The first one is a boolean that is supposed to be true, the
second is the test name (using the macro defined in `tests.h`) and the
third one (which can be an empty string) is something which is displayed
when the test fails.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -25,7 +25,7 @@ methods and software.
- [Docker/Server installation and maintenance](server.md)
These documentations and additional developer and maintainer documentation
are availaible from the [doc/](http://gitlab.vidjil.org/tree/master/doc) directory in the source files.
are available from the [doc/](http://gitlab.vidjil.org/tree/master/doc) directory in the source files.
### Further help
......
This is the preliminary help of the Vidjil server on Ubuntu server 14.04.
This is the help of the Vidjil server.
This help is intended for server administrators.
Users should consult the web application manual.
Other documentation can also be found in [dev.org](http://git.vidjil.org/blob/dev/doc/dev.org).
Users should consult the [web application manual](http://www.vidjil.org/doc/user/)
Other documentation can also be found in [doc/](http://www.vidjil.org/doc/).
Finally, developer documentation
# Plain installation or Docker containers
# Docker containers or Plain installation
There are two ways to install and run a Vidjil server:
- We are developping and deploying in 2018 **Docker containers** to ease the installation and the maintenance.
These Docker containers are now used in some partner hospitals.
- We are developping and deploying since 2018 **Docker containers** to ease the installation and the maintenance.
These Docker containers are used on the public server (<https://app.vidjil.org>) as well as in some partner hospitals.
We recommend this installation for new instances of Vidjil.
We also provide support and remote maintenance
of such in-hospital servers through
the [VidjilNet consortium](http://www.vidjil.net/index.en.html).
- The **plain installation of the server** should run on any Linux/Unix server with Nginx (recommanded) or Apache.
We provide below detailed instructions for Ubuntu 14.04 LTS.
We use this installation on the public server (<https://app.vidjil.org>) since October 2014.
We used this installation on the public server between 2014 and 2018.
# Requirements
......@@ -265,7 +268,7 @@ Contact us (<mailto:contact@vidjil.org>) to have more information and help.
# Docker -- Troubleshooting
### Error "Can't connect to MySQL server on 'mysql'"
## Error "Can't connect to MySQL server on 'mysql'"
The mysql container is not fully launched. This can happen especially at the first launch.
You may relaunch the containers.
......@@ -295,6 +298,16 @@ you can look into:
```
If the database does not exist, mysql will display an error after logging in.
## Launching manually the backup
The backup should be handled by the backup container. If so, connect to this
container and run (for a full backup, otherwise add the `-i` option when
running `backup.sh`):
```sh
cd /usr/share/vidjil/server
sh backup.sh vidjil /mnt/backup >> /var/log/cron.log 2>&1
```
# Docker -- Updating a Docker installation
......@@ -371,8 +384,10 @@ docker-compose up -d nginx
# Plain server installation
This installation is not supported anymore.
We rather advise to use the Docker containers (see above).
## Requirements
## Requirements (for Ubuntu 16.04)
``` bash
apt-get install git
......
# vidjil-algo 2019.04
# vidjil-algo 2019.05
**Command-line manual**
*The Vidjil team (Mathieu, Mikaël, Aurélien, Florian, Marc, Tatiana and Rayan)*
......@@ -473,8 +473,12 @@ with gapped V and J sequences, as for instance, for V genes, IMGT/GENE-DB sequen
as provided by `make germline`.
The CDR3/JUNCTION detection won't work with custom non-gapped V/J repertoires.
CDR3 are reported as productive when they come from an in-frame recombination
and when the sequence does not contain any in-frame stop codons.
CDR3 are reported as *productive* when they come from an in-frame recombination
and when the full sequence does not contain any in-frame stop codons.
Note that some other software only consider stop codons in the CDR3,
and may thus under-estimate non-productivity. Vidjil-algo looks for in-frame stop codons
on all the available sequence (and may sometimes over-estimate non-productivity when
the sequence contains intronic regions).
The advanced `--analysis-cost` option sets the parameters used in the comparisons between
the clone sequence and the V(D)J germline genes. The default values should work.
......
......@@ -37,7 +37,9 @@ This is an almost minimal `.vidjil` file, describing clones in one sample.
The `seg` element is optional: clones without `seg` elements will be shown on the grid with '?/?'.
The `_average_read_length` is also optional, but allows to plot GENSCAN-like plots more precisely than getting only the length of the sequence.
All other elements are required. The `reads.germlines` list can have only one element the case of data on a unique locus.
There is here one clone on the `TRG` locus with a designation `TRGV5*01 5/CC/0 TRGJ1*02`.
There is here one clone on the `TRG` locus with a designation (`name`) `TRGV5*01 5/CC/0 TRGJ1*02`.
Note that this `name` is just used to name the clone.
The actual values used for X- and Y- axis in the V/J grid plot are `seg.5.name` and `seg.3.name` fields.
Note that other elements could be added by some program (such as `tag`, to identify some clones,
or `clusters`, to further cluster some clones, see below).
......@@ -65,6 +67,7 @@ or `clusters`, to further cluster some clones, see below).
"clones": [
{
"id": "clone-001",
"name": "TRGV5*01 5/CC/0 TRGJ1*02",
"sequence": "CTCATACACCCAGGAGGTGGAGCTGGATATTGATACTACGAAATCTAATTGAAAATGATTCTGGGGTCTATTACTGTGCCACCTGGGCCTTATTATAAGAAACTCTTTGGCAGTGGAAC",
"reads" : [ 243241 ],
"_average_read_length": [ 119.3 ],
......@@ -72,9 +75,9 @@ or `clusters`, to further cluster some clones, see below).
"top": 1,
"seg":
{
"5": {"name": "TRGV5*01", "start": 1, "stop": 86, "delRight":5},
"5": {"name": "TRGV5*01", "start": 1, "stop": 87, "delRight":5},
"3": {"name": "TRGJ1*02", "start": 89, "stop": 118, "delLeft":0},
"cdr3": { "start": 77, "stop": 104, "seq": "gccacctgggccttattataagaaactc" }
"cdr3": { "start": 78, "stop": 105, "seq": "gccacctgggccttattataagaaactc" }
}
}
......@@ -85,7 +88,7 @@ or `clusters`, to further cluster some clones, see below).
## `.vidjil` file – several related samples
This a `.vidjil` file obtained by merging with `fuse.py` two `.vidjil` files corresponding to two samples.
Clones that have a same `id` are gathered (see 'What is a clone?', above).
Clones that are from different files but that have a same `id` are gathered (see 'What is a clone?', above).
It is the responsibility of the program generating the initial `.vidjil` files to choose these `id` to
do a correct gathering.
......@@ -119,7 +122,7 @@ do a correct gathering.
"top": 1,
"seg":
{
"5": {"name": "TRGV5*01", "start": 1, "stop": 86, "delRight": 5},
"5": {"name": "TRGV5*01", "start": 1, "stop": 87, "delRight": 5},
"3": {"name": "TRGJ1*02", "start": 89, "stop": 118, "delLeft": 0}
}
},
......@@ -308,7 +311,8 @@ In the `.analysis` file, this section is intended to describe some specific clon
// Recombination with several D may use "4a", "4b"...
"3": {"name": "IGHJ3*02", "start": 136, "stop": 171, "delLeft": 5}, // J (or 3') segment
// any feature to be highlighted in the sequence, with optional fields related to this feature:
// Any feature to be highlighted in the sequence.
// All those fields are optional (though some minor feature may not properly work in the client)
// - "start"/"stop" : positions on the clone sequence (starting at 1)
// - "delLeft/delRight" : a numerical value . It is the numbers of nucleotides deleted during the rearrangment. DelRight are compatible with V/5 and D/4 segments, delLeft is compatible with D/4 and J/3 segments.
// - "seq" : a sequence
......@@ -317,6 +321,8 @@ In the `.analysis` file, this section is intended to describe some specific clon
//
// JUNCTION//CDR3 should be stored that way (in fields called "junction" of "cdr3"),
// its productivity must be stored in a boolean field called "productive".
// "seq" field should not be filled for cdr3 or junction (it is extracted from the sequence itself).
// However a "aa" field may be used to give the amino-acid translation of the cdr3 or junction.
"somefeature": { "start": 56, "stop": 61, "seq": "ACTGTA", "val": 145.7, "info": "analyzed with xyz" },
// Numerical or textual features concerning all the sequence or its analysis (such as 'evalue')
......@@ -329,6 +335,11 @@ In the `.analysis` file, this section is intended to describe some specific clon
"reads": [], // number of reads in this clones [.vidjil only, required]
// (with samples.number elements)
"_average_read_length": [],
// Average read length of the reads clustered in this clone.
// This value allows to draw a genescan-like plot.
// (with samples.number elements)
"top": 0, // (not documented now) [required] threshold to display/hide the clone
"stats": [] // (not documented now) [.vidjil only] (with sample.number elements)
......
......@@ -13,14 +13,7 @@ arg git_branch=dev
arg remote_repo=https://gitlab.inria.fr/vidjil/vidjil.git
run cd /usr/share/ && git config --global http.sslVerify false && git clone -b $git_branch $remote_repo
copy ./conf/nginx_gzip_static.conf /etc/nginx/conf.d/web2py/gzip_static.conf
copy ./conf/nginx_gzip.conf /etc/nginx/conf.d/web2py/gzip.conf
copy ./conf/uwsgi.conf /etc/nginx/conf.d/web2py/uwsgi.conf
add ./scripts/install.sh /opt/install_scripts/install.sh
copy ./conf/conf.js /opt/vidjil_conf/conf.js
copy ./conf/conf_http.js /opt/vidjil_conf/conf_http.js
copy ./conf/nginx_web2py /opt/vidjil_conf/web2py
copy ./conf/nginx_web2py_http /opt/vidjil_conf/web2py_http
copy ./conf/Gemfile /usr/share/vidjil/Gemfile
copy ./conf/align.cgi /usr/share/vidjil/browser/cgi/align.cgi
copy ./conf/similarity.cgi /usr/share/vidjil/browser/cgi/similarity.cgi
......@@ -31,9 +24,12 @@ arg build_env='PRODUCTION'
env BUILD_ENV $build_env
run mkdir /etc/vidjil
run mkdir /etc/nginx/conf.d/web2py/
run rm /etc/nginx/conf.d/default.conf
run chmod +x /opt/install_scripts/install.sh; sync && /opt/install_scripts/install.sh
run ln -s /etc/vidjil/conf.js /usr/share/vidjil/browser/js/conf.js
run ln -s /etc/vidjil/nginx_gzip_static.conf /etc/nginx/conf.d/web2py/gzip_static.conf
run ln -s /etc/vidjil/nginx_gzip.conf /etc/nginx/conf.d/web2py/gzip.conf
run ln -s /etc/vidjil/uwsgi.conf /etc/nginx/conf.d/web2py/uwsgi.conf
run ln -s /etc/vidjil/germline.js /usr/share/vidjil/browser/js/germline.js
copy ./scripts/nginx-entrypoint.sh /entrypoints/nginx-entrypoint.sh
......
#!/bin/bash
echo "${BUILD_ENV}"
if [ "${BUILD_ENV}" = "TEST" ]; then
cp -avr /opt/vidjil_conf/conf_http.js /etc/vidjil/conf.js
cp -avr /opt/vidjil_conf/web2py_http /etc/nginx/conf.d/web2py.conf
ln -s /etc/vidjil/conf_http.js /usr/share/vidjil/browser/js/conf.js
ln -s /etc/vidjil/nginx_web2py_http /etc/nginx/conf.d/web2py.conf
else
cp -avr /opt/vidjil_conf/conf.js /etc/vidjil/conf.js
cp -avr /opt/vidjil_conf/web2py /etc/nginx/conf.d/web2py.conf
ln -s /etc/vidjil/conf.js /usr/share/vidjil/browser/js/conf.js
ln -s /etc/vidjil/nginx_web2py /etc/nginx/conf.d/web2py.conf
fi;
{
"ref": "http://www.vidjil.org/germlines/germline-xxx.tar.gz",
"species": "Gallus gallus; including red junglefowl",
"species_taxon_id": 9031,
"path": "gallus-gallus",
"systems": {
"IGH": {
"shortcut": "H",
"color" : "#6c71c4",
"description": "Gallus immunoglobulin, heavy locus",
"recombinations": [ {
"5": ["IGHV.fa"],
"4": ["IGHD.fa"],
"3": ["IGHJ.fa"]
} ],
"parameters": {
"seed": "12s"
}
},
"IGH+": {
"shortcut": "h",
"color" : "#8c91e4",
"description": "Gallus immunoglobulin, heavy locus, incomplete Dh-Jh recombinations",
"follows": "IGH",
"recombinations": [ {
"5": ["IGHD+up.fa"],
"3": ["IGHJ+down.fa"]
} ],
"parameters": {
"seed": "12s"
}
},
"IGL": {
"shortcut": "L",
"color" : "#d33682",
"description": "Gallus immunoglobulin, lambda locus",
"recombinations": [ {
"5": ["IGLV.fa"],
"3": ["IGLJ.fa"]
} ],
"parameters": {
"seed": "10s"
}
}
}
}
......@@ -68,7 +68,7 @@ def gene_matches(string, list_regex):
results = []
for regex in list_regex:
match = re.search(regex, string)
if match <> None:
if match != None:
results.append(match.group(0))
return results
......@@ -274,7 +274,9 @@ SPECIES = {
"Mus musculus_C57BL/6": 'mus-musculus/',
"Rattus norvegicus": 'rattus-norvegicus/',
"Rattus norvegicus_BN/SsNHsdMCW": 'rattus-norvegicus/',
"Rattus norvegicus_BN; Sprague-Dawley": 'rattus-norvegicus/'
"Rattus norvegicus_BN; Sprague-Dawley": 'rattus-norvegicus/',
"Gallus gallus": "gallus-gallus/",
"Gallus gallus_Red Jungle fowl": "gallus-gallus/"
}
......
!NO_LAUNCHER:
!LAUNCH: (cd $VIDJIL_DIR/germline ; cat gallus-gallus/IGHV.fa | tr '|' '#' )
$ Found sequence of Gallus gallus Red Jungle fowl
1: .*#IGHV1-1.01#Gallus gallus_Red Jungle fowl#
$ Found sequence of Gallus gallus
1: .*#IGHV1-21.*#Gallus gallus#
$ Found a sequence part of IGHV1-1*01
i1: tgggtgcgacaggcgcccggcaaggggctggagtgggtcgctggtattggcagcagt
......@@ -16,7 +16,7 @@ def imgt():
if 'Session' in payload.keys():
del payload['Session']
response = requests.post("http://www.imgt.org/IMGT_vquest/vquest", data=payload)
response = requests.post("http://www.imgt.org/IMGT_vquest/analysis", data=payload)
if response.status_code == requests.codes.ok:
return response
return gluon.contrib.simplejson.dumps("the site returned an invalid response")
......
......@@ -287,6 +287,13 @@ def result_files():
if isinstance(sample_set_ids, types.StringTypes):
sample_set_ids = [sample_set_ids]
permissions = [auth.can_view_sample_set(int(id)) for id in sample_set_ids]
if sum(permissions) < len(permissions):
res = {"message": "You don't have permissions to access those sample sets"}
log.error("An error occured when creating archive of sample_sets %s" % str(sample_set_ids))
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
if int(config_id) == -1:
config_query = (db.results_file.config_id > 0)
else:
......
This diff is collapsed.
......@@ -16,6 +16,7 @@ doctests:
python -m doctest -v ../utils.py
python -m doctest -v ../vidjil-to-fasta.py
python -m doctest -v ../../algo/tests/should-vdj-to-tap.py
python -m doctest -v ../../algo/tests/repseq_vdj.py
python ../org-babel-tangle.py --test
@echo "*** All python tests passed"
......
!LAUNCH: python ../../fuse.py $FUSE_OPTIONS ../../../algo/tests/data/no_clones.vidjil ../../../algo/tests/data/results-two-clones-1-2.vidjil -o normalized_zero.vidjil; cat normalized_zero.vidjil
$ Case zero; No field normalized_reads if not contain in the given files/clones
0: normalized_reads
!LAUNCH: python ../../fuse.py $FUSE_OPTIONS ../../../algo/tests/data/results-two-clones-1-3.vidjil ../../../algo/tests/data/results-two-clones-1-3.vidjil -o normalized_both.vidjil; cat normalized_both.vidjil
$ Case both; Should find 1 field normalized_reads (clone id-1)
1: normalized_reads
$ Case both; Correct fusion of normalized_reads field if both clones are informatives
lr: normalized_reads.*500,.*500
!LAUNCH: python ../../fuse.py $FUSE_OPTIONS ../../../algo/tests/data/no_clones.vidjil ../../../algo/tests/data/results-two-clones-1-3.vidjil -o normalized_one.vidjil; cat normalized_one.vidjil
$ Case only one; Should find 1 filed normalized_reads
1: normalized_reads
$ Case only one; First value is null if on of file have not been annalysed by the normalization script
1: null
rl1: normalized_reads.*null,.*500
!LAUNCH: python ../../fuse.py $FUSE_OPTIONS ../../../algo/tests/data/results-two-clones-1-3.vidjil ../../../algo/tests/data/no_clones.vidjil -o normalized_one_revert.vidjil; cat normalized_one_revert.vidjil
$ Case inverse; Should find 1 filed normalized_reads
1: normalized_reads
$ Case inverse; Idem, but reverse files
1: null
lr: "normalized_reads".*500,.*null
!LAUNCH: python ../../fuse.py $FUSE_OPTIONS normalized_one.vidjil ../../../algo/tests/data/results-two-clones-1-3.vidjil -o normalized_double.vidjil; cat normalized_double.vidjil
$ Case double timepoint; Should find 1 filed normalized_reads
1: normalized_reads
$ Case double timepoint; Correct fusion if one of the file is a already fused vidjil
1: null
lr: "normalized_reads".*null,.*500,.*500
\ No newline at end of file
<
### Without distributions computing
!LAUNCH: python3 ../../fuse.py --output fused_with_distrib_step1.vidjil ../../../algo/tests/data/results-two-clones-1-2.vidjil ../../../algo/tests/data/results-two-clones-1-3.vidjil; cat fused_with_distrib_step1.vidjil
$ Get correct file name in original_names field