Skip to content

Instantly share code, notes, and snippets.

@coronin
Last active Aug 29, 2015
Embed
What would you like to do?
run nicely with ots_server and Web Blat
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>crispr scanner, made by Liang Cai</title>
<style type="text/css" media="screen"><!--
body{margin:25px;padding:0;font-family:Arial,Helvetica,sans-serif;font-size:100%;line-height:1.5}
article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}
h1,h2,h3,h4{margin:1em 0 .5em;line-height:1.25;font-weight:700}
h1{font-size:2em}
h2{font-size:1.5em}
h3{font-size:1.2em}
h4{font-size:1em}
ol,ul{margin:1em 0;padding:1em;background:#eee;list-style-type:none;font-family:"Courier New",Courier,monospace}
p{margin:1em 0}
blockquote{margin:1em 40px}
figure{margin:1em 0}
a{text-decoration:underline}
a:link{color:#00E}
a:visited{color:#551A8B}
a:active{color:#E00}
a:active,a:hover{outline:0}
a img{border:none}
cite,q{font-style:italic}
q:after,q:before{content:""}
sub,sup{line-height:0}
fieldset{margin:0;padding:0;border:none}
button,input,select{vertical-align:middle}
table{border-collapse:collapse}
td,th{padding:1px;vertical-align:top;text-align:left}
td:first-child,th:first-child{empty-cells:hide}
.blat{font-size:0.8em}
.line{position:fixed;bottom:0;width:12px;height:20px;font-size:8px}
--></style>
</head>
<body>
<h1>crispr scanner, made by Liang Cai</h1>
<p>Cas9 species = S. pyogenes (PAM = NGG)</p>
<p>Use <a href="https://github.com/htgt/CRISPR-Analyser">ots_server</a> as data source
<span id="server_status"><br/></span></p>
<hr/>
<p>
<em>species</em><br/>
<input type="radio" name="species" value="dog" id="species_dog" checked /><label for="species_dog">dog</label><br/>
<input type="radio" name="species" value="human" id="species_human" /><label for="species_human">human</label><br/>
<input type="radio" name="species" value="mouse" id="species_mouse" /><label for="species_mouse">mouse</label>
</p>
<hr/>
<p>
option 1, <em>check a gRNA sequence</em><br/>
<input type="text" name="gRNA" size="20" id="gRNA_seq" />
</p>
<p>
option 2, <em>search gRNAs in a genomic sequence</em> &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" id="rigorous" /><span id="rigorous_label">only four</span><br/>
<!-- human EMX1 locus : ggaggaagggcctgagtccgagcagaagaagaagggctcccatcacatcaaccggtggcgcattgccacgaagcaggccaatggggaggacatcgatgtcacctccaatgactagggtgggc -->
<textarea cols="60" rows="12" id="target_seq"></textarea>
</p>
<hr/>
<p>
<input type="submit" value="submit" id="submit" />
<span id="progress" style="background:yellow;font-size:75%;margin-left:25px"></span>
</p>
<div><ul id="ots_result"></ul></div>
<div id="graph_show"></div>
<script src="jquery-2.1.1.min.js"></script>
<script>
var ots_addr = 'http://localhost:8080',
blat_addr = 'http://localhost/cgi-bin/webBlat',
rigorous = false,
pix_size = 1;
function quick_e(g, idx, pam, antiparallel) {
var e = '';
if (idx && antiparallel) {
e = '<span style="color:#f00;background:white">-</span> <i>'+pam+'</i> <b>'+g+'</b> : #'+(idx+3)+', ';
} else if (idx) {
e = '<span style="color:#0f0;background:white">+</span> <b>'+g+'</b> <i>'+pam+'</i> : #'+(idx-21)+', ';
} else {
e = '5-<b>'+g+'</b>-3 : ';
}
return e;
}
function blat_23nt(idx, s) {
var seq = $('#q'+idx).text().split(' : ')[0].replace(/[^ATgC]/g, '');
$.ajax({
type: 'POST',
url: blat_addr,
dataType: 'html',
data: {'wb_db':s,'wb_seq':seq,'wb_qType':'DNA','wb_sort':'query,score','wb_output':'psl no header'},
success: function (d) {
var psl = $(d).find('TT').text(), pslsub;
if (psl.substr(0,2) !== '23') {
console.log(seq);
console.log( 'blat output : '+psl.replace(/\t/g, ' ') );
$('#q'+idx).remove(); // not a genomic seq, most likely on different exons
$('.line'+idx).remove();
} else {
pslsub = psl.split("query\t")[1].split("\t");
$('#blat'+idx).text('['+pslsub[3]+' '+pslsub[5]+'-'+pslsub[6]+']');
}
return true;
},
error: function () {
$('#blat'+idx).text('[please verify 23nt by Blat or Blast]');
return false;
}
});
}
function search_an_id(s, a, g, idx, pam, antiparallel) {
$.getJSON(ots_addr+'/api/off_targets?callback=?',
{'species':s, 'ids':a},
function (d) {
var b = d[''+a].off_target_summary,
c = eval('(' + b + ')'), e;
if (c[0] === 0) {
if (idx) {
$('#q'+idx).remove();
} else {
$('#ots_result').append('<li>5-<b>'+g+'</b>-3 : ignore. zero hit in '+s+'</li>');
}
} else if (c[0] > 1) {
if (idx) {
$('#q'+idx).remove();
} else {
$('#ots_result').append('<li>5-<b>'+g+'</b>-3 : alert! do not use, '+c[0]+' exact hits</li>');
}
} else if (c[1] || c[2]) {
if (idx) {
$('#q'+idx).remove();
} else {
$('#ots_result').append('<li>5-<b>'+g+'</b>-3 : warning! one '+c[1]+', two '+c[2]+'</li>');
}
} else if (c[3]) {
e = quick_e(g, idx, pam, antiparallel) + 'fine. three '+c[3]+', four '+c[4];
if (idx && rigorous) {
$('#q'+idx).remove();
} else if (idx) {
$('#q'+idx).html(e+' <span class="blat" id="blat'+idx+'"></span>');
if (antiparallel) {
$('#graph_show').append('<div class="line line'+idx+'" style="background-color:rgba(255,100,100,0.6);text-align:left;border-left:1px solid #999;left:'+(25+idx*pix_size)+'px">'+(idx+3)+'</div>');
} else {
$('#graph_show').append('<div class="line line'+idx+'" style="background-color:rgba(100,255,100,0.6);text-align:right;border-right:1px solid #999;left:'+(25+idx*pix_size)+'px">'+(idx-21)+'</div>');
}
blat_23nt(idx, s);
} else {
$('#ots_result').append('<li>'+e+'</li>');
}
} else {
e = quick_e(g, idx, pam, antiparallel) + 'good. four '+c[4];
if (idx) {
$('#q'+idx).html(e+' <span class="blat" id="blat'+idx+'"></span>');
if (antiparallel) {
$('#graph_show').append('<div class="line line'+idx+'" style="background-color:rgba(255,0,0,0.6);text-align:left;border-left:1px solid #333;left:'+(25+idx*pix_size)+'px">'+(idx+3)+'</div>');
} else {
$('#graph_show').append('<div class="line line'+idx+'" style="background-color:rgba(0,255,0,0.6);text-align:right;border-right:1px solid #333;left:'+(25+idx*pix_size)+'px">'+(idx-21)+'</div>');
}
blat_23nt(idx, s);
} else {
$('#ots_result').append('<li>'+e+'</li>');
}
}
}).done(function () {
$('#progress').append(' .');
});
}
function search_seq(s, g, idx, pam, antiparallel) {
return $.getJSON(ots_addr+'/api/search?callback=?',
{'species':s, 'seq':g},
function (d) {
if (d.length > 1) {
if (!idx) { $('#ots_result').append('<li>5-<b>'+s+'</b>-3 : '+d.length+' hits</li>'); }
} else if (d.length === 1) {
if (idx && antiparallel) {
$('#ots_result').append('<li id="q'+idx+'">...</li>');
} else if (idx) {
$('#ots_result').append('<li id="q'+idx+'">...</li>');
}
search_an_id(s, d[0], g, idx, pam, antiparallel);
} else {
if (!idx) { $('#ots_result').append('<li>5-<b>'+g+'</b>-3 : ignore. zero hit in '+s+'</li>'); }
}
});
}
function plus_strand_search(s, t) {
var pam_seq = 'gg', // NGG
t1 = t.indexOf(pam_seq), tsub, tsub1,
t2 = t.lastIndexOf(pam_seq);
while (t1 < 21) {
t1 += 1;
tsub = t.substr(t1);
tsub1 = tsub.indexOf(pam_seq);
if (tsub1 > -1) {
t1 += tsub1;
} else { break; }
}
if (t1 > t2) {
$('#progress').append(', none in the + strand');
} else {
$('#progress').append('; will process the + strand between '+t1+' ~ '+t2);
var seqs = [], idxs = [], ti, tt, pams = [];
for (ti = t1; ti <= t2; ti += 1) {
if (t.substr(ti, 2) === pam_seq) {
tt = t.substr(ti-21, 20);
if (seqs.indexOf(tt) === -1) {
seqs.push(tt);
idxs.push(ti);
pams.push( t.substr(ti-1, 3) );
}
}
}
defrs_search(s, seqs, idxs, pams, false);
}
}
function minus_strand_search(s, t) {
var pam_seq = 'CC', // CCN
t1 = t.indexOf(pam_seq), tsub, tsub2,
t2 = t.lastIndexOf(pam_seq);
while ((t.length-t2) < 21) {
tsub = t.substring(0, t2-1);
tsub2 = tsub.lastIndexOf(pam_seq);
t2 = -1
if (tsub2 > -1) {
t2 = tsub2;
} else { break; }
}
if (t2 === -1) {
$('#progress').append(', none in the - strand');
} else {
$('#progress').append('; will process the - strand between '+t1+' ~ '+t2);
var seqs = [], idxs = [], ti, tt, pams = [];
for (ti = t1; ti <= t2; ti += 1) {
if (t.substr(ti, 2) === pam_seq) {
tt = t.substr(ti+3, 20);
if (seqs.indexOf(tt) === -1) {
seqs.push(tt);
idxs.push(ti);
pams.push( t.substr(ti, 3) );
}
}
}
defrs_search(s, seqs, idxs, pams, true);
}
}
function defrs_search(s, seqs, idxs, pams, antiparallel) {
var defrs = [];
$.each(seqs, function (iV, ele) {
defrs.push( search_seq(s, ele, idxs[iV], pams[iV], antiparallel) );
});
$('#progress').append(', looped');
$.when(defrs).done(function () {
$('#progress').append(', queued');
});
}
function anti_parallel(t) {
var apt_list = [],
t_list = t.split('');
$.each(t_list, function (iV, ele) {
if (ele === 'A') {
apt_list.unshift( 'T' );
} else if (ele === 'T') {
apt_list.unshift( 'A' );
} else if (ele === 'g') {
apt_list.unshift( 'C' );
} else if (ele === 'C') {
apt_list.unshift( 'g' );
}
});
return apt_list.join('');
}
function check_server() {
$.getJSON(ots_addr+'/api/search?callback=?',
{'seq':'TTAATTGTTTAGCAGTGTCA', 'species':'mouse'},
function (d) {
if (d.length === 1) {
$('#server_status').append('the server is running');
$('#server_status').css({'background':'#eee','color':'green'});
} else {
$('#server_status').append('SERVER ERROR');
$('#server_status').css({'background':'yellow','color':'red'});
$('#submit').hide();
}
});
}
$(document).ready(function () {
check_server();
$('#submit').on('click', function (event) {
$('#ots_result').html('');
$('#graph_show').html('');
$('#progress').text('ing...');
var s = $('input:checked').val(),
g = $('#gRNA_seq').val(),
t = $('#target_seq').val();
if (g) {
$('#target_seq').val('');
rigorous = false;
$('#rigorous').attr('checked', false);
$('#rigorous_label').show();
g = g.replace(/[^atgc]/gi, '').toUpperCase().replace(/G/g, 'g');
if (g && g.length === 20) {
search_seq(s, g);
$('#progress').text('done job1!');
} else {
$('#progress').text('!! please input a 20-nt seq :-p');
$('#gRNA_seq').focus();
}
} else if (t) {
$('#gRNA_seq').val('');
if( $('#rigorous').is(':checked') ) {
rigorous = true;
$('#rigorous_label').show();
} else {
rigorous = false;
$('#rigorous_label').hide();
}
t = t.replace(/[^atgc]/gi, '').toUpperCase().replace(/G/g, 'g');
if ( $('#graph_show').width() > t.length ) {
pix_size = $('#graph_show').width() / t.length;
}
$('#progress').text('job2 starts (if nothing shown means no hit)');
plus_strand_search(s, t);
$('#progress').append('; now the anti-parallel');
minus_strand_search(s, t);
} else {
$('#progress').text('!! please input something correct :-p');
$('#gRNA_seq').focus();
}
event.preventDefault();
});
});
</script>
</body>
</html>
@coronin

This comment has been minimized.

Copy link
Owner Author

@coronin coronin commented Sep 7, 2014

now, it is public

@coronin

This comment has been minimized.

Copy link
Owner Author

@coronin coronin commented Sep 8, 2014

now, with local Web Blat support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment