three iterations to choose target number
[sgn.git] / js / tools / vigs.js
blobeed6e7fe51b58bf3e68532471445e06403517f5d
3 $(document).ready(function () {
4         
5         //safari_alert();
6         
7         var score_array;
8         var seq;
9         var seq_length;
10         var bt2_file;
11         var best_start;
12         var best_end;
13         var best_seq;
14         var expr_msg;
15         var expr_f;
16         var ids;
17         var m_aoa;
18         var temp_file;
19         var n_mer;
20         var si_rna;
21         
22         //start the tool when click on Run VIGS Analysis
23         $('#upload_expression_file').click(function () {
24                 
25                 //get the expression file from the web input form
26                 expr_f = $('#expression_file').val();
27                 $("#region_square").css("height","0px");
28                 
29                 //submit the form
30                 $("#upload_expression_form").submit();
31     });
33         //get the expression file from the form (in a iframe) and start the analysis
34         $('#upload_expression_form').iframePostForm({
35                 json: true,
36                 post: function () {
37                 },
38                 complete: function (response) {
39                         if (response.error) {
40                                 alert("The expression file could not be uploaded"+response.error);
41                         }
42                         if (response.success) {
43                                 expr_f = response.expr_file;
44                                 
45                                 //get the arguments from the HTML elements
46                                 seq = $("#sequence").val();
47                                 si_rna = $("#si_rna").val();
48                                 f_length = $("#f_length").val();
49                                 mm = $("#mm").val();
50                                 db = $("#bt2_db").val();
51                                 
52                                 //Run Bowtie2
53                                 runBt2(si_rna, f_length, mm, db);
54                         }
55                 }
56         });
58         //expand/collapse the n-mers graph when click on 'Collapse Graph' button
59         $('#collapse').click(function () {
60                 activateCollapse(score_array,best_seq,seq,expr_msg,ids,m_aoa);
61         });
63         //zoom in/out the n-mers graph when click on 'Zoom' button
64         $('#zoom').click(function () {
65                 activateZoom(score_array,best_seq,seq,expr_msg,ids,m_aoa);
66         });
68         //display custom region selection rectangle when click on 'Set Custom Region' button
69         $('#set_custom').click(function () {
70                 getCustomRegion(score_array,best_seq,seq);
71         });
73         $('#change_par').click(function () {
74                 res = changeTargets(bt2_file,score_array,seq,best_seq,expr_f,ids,m_aoa);
75                 score_array = res[0];
76                 seq = res[1];
77                 best_seq = res[2];
78                 expr_msg = res[3];
79                 ids = res[4];
80                 m_aoa = res[5];
81         });
83         $('#region_square').mouseup(function () {
84                 getSquareCoords(score_array,best_seq,seq);
85         });
86         
87         $('#open_descriptions_dialog').click(function () {
88                 $('#dialog_info').replaceWith($('#target_info').clone());
90                 $('#desc_dialog').dialog({
91                         draggable:true,
92                         resizable:true,
93                         width:900,
94                         minWidth:400,
95                         maxHeight:400,
96                         closeOnEscape:true,
97                         title: "Gene Functional annotation",
98                 });
99         });
101         $('#params_dialog').click(function () {
102                 
103                 $('#params').html("&bull;&nbsp;<b>Fragment size: </b>"+$("#help_fsize").val()+"<br /> \
104                 &bull;&nbsp;<b>n-mer: </b>"+$("#help_nmer").val()+"<br /> \
105                 &bull;&nbsp;<b>Mismatches: </b>"+$("#help_mm").val()+"<br />\
106                 &bull;&nbsp;<b>Database: </b>"+$("#db_name").val());
108                 $('#params').dialog({
109                         draggable:true,
110                         resizable:false,
111                         width:500,
112                         closeOnEscape:true,
113                         title: "Parameters used",
114                 });
115         });
117         $('#help_dialog_1').click(function () {
118                 
119                 $('#help_dialog_tmp').html("&bull;&nbsp;The best target region score value indicates how good the yellow highlighted region is, taking into account the number of target and off-target n-mers. \
120                         The closer to 100 the better is the value. In the same way, the custom region score indicates the value of the custom region, represented by the transparent grey rectangle.<br/> \
121                         &bull;&nbsp;Set Custom Region button will activate a draggable and resizable transparent grey rectangle to manually select a custom region.<br/> \
122                         &bull;&nbsp;Change button will recalculate the results using the new parameters chosen. In case of changing the n-mer size, the algorithm will run Bowtie 2 again, so this process could take a while.");
124                 $('#help_dialog_tmp').dialog({
125                         draggable:true,
126                         resizable:false,
127                         width:500,
128                         closeOnEscape:true,
129                         title: "Modify parameters help",
130                 });
131         });
133         $('#help_dialog_2').click(function () {
134                 
135                 $('#help_dialog_tmp').html("&bull;&nbsp;N-mers mapping to the target/s are shown in blue and to off-targets in red. The yellow area highlights the region with the highest score using the selected parameters<br/> \
136                         &bull;&nbsp;The bottom graph represents in red the score values along the sequence. The score value = 0 is indicated with a green line. \
137                         Below this line are represented the regions with more off-targets than targets, and the opposite when the score is above the green line.<br/> \
138                         &bull;&nbsp;Expand graph button will display every n-mer fragment aligned over the query for each subject.<br /> \
139                         &bull;&nbsp;Zoom button will zoom in/out the VIGS map representation.");
141                 $('#help_dialog_tmp').dialog({
142                         draggable:true,
143                         resizable:false,
144                         width:500,
145                         closeOnEscape:true,
146                         title: "Distribution of n-mers help",
147                 });
148         });
150         $('#help_dialog_3').click(function () {
151                 
152                 $('#help_dialog_tmp').html("&bull;&nbsp;This section shows the best or the custom region sequence in FASTA format.<br/> \
153                         &bull;&nbsp;The custom region will update as the grey selection rectangle is moved.");
155                 $('#help_dialog_tmp').dialog({
156                         draggable:true,
157                         resizable:false,
158                         width:500,
159                         closeOnEscape:true,
160                         title: "Best region help",
161                 });
162         });
164         $('#help_dialog_4').click(function () {
165                 
166                 $('#help_dialog_tmp').html("&bull;&nbsp;In this section is shown the query sequence, highlighting the best target region in yellow or the custom region in grey.<br/> \
167                         &bull;&nbsp;The custom region will be updated as the grey selection rectangle is moved.");
169                 $('#help_dialog_tmp').dialog({
170                         draggable:true,
171                         resizable:false,
172                         width:500,
173                         closeOnEscape:true,
174                         title: "Sequence overview help",
175                 });
176         });
178         $('#help_dialog_5').click(function () {
179                 
180                 $('#help_dialog_tmp').html("&bull;&nbsp;Number of n-mer matches and gene functional description are shown for each matched gene.<br/> \
181                         &bull;&nbsp;The View link will open a draggable dialog with this information.");
183                 $('#help_dialog_tmp').dialog({
184                         draggable:true,
185                         resizable:false,
186                         width:500,
187                         closeOnEscape:true,
188                         title: "Description of genes mapped help",
189                 });
190         });
192         $('#clear_form').click(function () {
193                 $("#sequence").val(null);
194                 $("#si_rna").val(21);
195                 $("#f_length").val(300);
196                 $("#mm").val(0);
197                 $("#expression_file").val(null);
198         });
200         $('#working').dialog( { 
201                 height: 100,
202                 width:  50,
203                 modal: true,
204                 autoOpen: false,
205                 closeOnEscape: false,
206                 draggable: false,
207                 resizable: false,
208                 open: function() { $(this).closest('.ui-dialog').find('.ui-dialog-titlebar-close').hide(); },
209                 title: 'Working...'
210         });
211         
212         // sent the data to the controller to run bowtie2 and parse the results
213         function runBt2(si_rna, f_length, mm, db) {
214                 var db_name;
215                 
216                 $("#no_results").html("");
217                 // alert("seq: "+seq.length+", si_rna: "+si_rna+", f_length: "+f_length+", mm: "+mm+", db: "+db+", expr_file: "+expr_file);
218                 $.ajax({
219                         url: '/tools/vigs/result/',
220                         // async: false,
221                         timeout: 600000,
222                         method: 'POST',
223                         data: { 'tmp_file_name': temp_file, 'sequence': seq, 'fragment_size': si_rna, 'seq_fragment': f_length, 'missmatch': mm, 'database': db },
224                         beforeSend: function(){
225                                 disable_ui();
226                         },
227                         success: function(response) {
228                                 if (response.error) { 
229                                         alert("ERROR: "+response.error);
230                                         enable_ui();
231                                 } else {
232                                         db_name = response.db_name;
233                                         bt2_file = response.jobid;
234                                         
235                                         $("#help_fsize").val(f_length);
236                                         $("#help_nmer").val(si_rna);
237                                         $("#help_mm").val(mm);
238                                         $("#db_name").val(db_name);
239                                         
240                                         getResults(1, bt2_file, si_rna, f_length, mm, 0, db, expr_f);
241                                 }
242                         },
243                         error: function(response) {
244                                 alert("An error occurred. The service may not be available right now. Bowtie2 could not be executed");
245                                 //safari_alert();
246                                 enable_ui();
247                         }
248                 });
249         }
252         function getResults(status, bt2_res, si_rna, f_length, mm, coverage, db, expr_file) {
253                 
254                 var t_info = "<tr><th>Gene</th><th>Matches</th><th>Functional Description</th></tr>";
255                 $("#no_results").html("");
257                 $.ajax({
258                         url: '/tools/vigs/view/',
259                         // async: false,
260                         timeout: 600000,
261                         method: 'POST',
262                         data: {'id': bt2_res, 'sequence': seq, 'fragment_size': si_rna, 'seq_fragment': f_length, 'missmatch': mm, 'targets': coverage, 'expr_file': expr_file, 'status': status, 'database': db},
263                         complete: function(){
264                                 enable_ui();
265                                 hide_ui();
266                         },
267                         success: function(response) { 
268                                 if (response.error) { 
269                                         alert("ERROR: "+response.error);
270                                         enable_ui();
271                                 } else {
272                                         
273                                         //assign values to global variables
274                                         score_array = response.all_scores;
275                                         best_seq = response.best_seq;
276                                         expr_msg = response.expr_msg;
277                                         var best_score = response.score;
278                                         var best_start = response.cbr_start;
279                                         var best_end = response.cbr_end;
280                                         seq = response.query_seq;
281                                         var seq_length = seq.length;
282                                         coverage = response.coverage;
283                                         ids = response.ids;
284                                         m_aoa = response.matches_aoa;
286                                         if (+response.score > 0) {
287                                                 $("#score_p").html("<b>Best target region score:</b> "+best_score+" &nbsp;&nbsp;(-&infin;&mdash;100)<br />");
288                                                 $("#t_num").val(coverage);
289                                         } else {
290                                                 $("#no_results").html("Note: No results found! Try again increasing the number of targets or the n-mer length, or decreasing the mismatches");
291                                         }
293                                         //show result sections
294                                         $("#hide1").css("display","inline");
296                                         //assign values to html variables
297                                         $("#coverage_val").val(coverage);
298                                         $("#seq_length").val(seq_length);
299                                         $("#f_size").val(response.f_size);
300                                         $("#n_mer").val(si_rna);
301                                         $("#align_mm").val(response.missmatch);
302                                         $("#best_start").val(best_start);
303                                         $("#best_end").val(best_end);
304                                         $("#cbr_start").val(best_start);
305                                         $("#cbr_end").val(best_end);
306                                         $("#best_score").val(best_score);
307                                         $("#img_height").val(response.img_height);
309                                         //set collapse and zoom buttons
310                                         $("#collapse").val(1);
311                                         $("#collapse").html("Expand Graph");
312                                         $("#zoom").val(0);
313                                         $("#zoom").html("Zoom In");
315                                         createMap(1,0,score_array,expr_msg,ids,m_aoa);
317                                         if (+best_seq.length > 10) {
318                                                 $("#best_seq").html("<b>>best_target_region_("+best_start+"-"+best_end+")</b><br />"+best_seq);
319                                         } else {
320                                                 $("#best_seq").html("<b>No results were found</b>");
321                                         }
322                                         $("#query").html(seq);
323                                         hilite_sequence(best_start,best_end,0);
325                                         var desc="";
326                                         var gene_name="";
328                                         for (var i=0; i<ids.length; i=i+1) {
329                                                 if (ids[i][2].match(/Niben/)) {
330                                                         desc = ids[i][2].replace(/Niben\d+Scf[\:\.\d]+/,"");
331                                                         gene_name = ids[i][0];
332                                                 } else if (ids[i][0].match(/Solyc/)) {
333                                                         desc = ids[i][2].replace(/.+functional_description:/,"");
334                                                         desc = desc.replace(/\"/g,"");
335                                                         gene_name = ids[i][0].replace(/lcl\|/,"");
336                                                 }
337                                                 t_info += "<tr><td>"+gene_name+"</td><td style='text-align:right;'>"+ids[i][1]+"</td><td>"+desc+"</td></tr>";
338                                         }
340                                         $("#target_info").html(t_info);
341                                         $("#hide2").css("display","inline");
342                                         $("#hide3").css("display","inline");
343                                         
344                                         $("#help_fsize").val(f_length);
345                                         $("#help_mm").val(mm);
346                                 }
347                         },
348                         error: function(response) {
349                                 alert("An error occurred. The service may not be available right now.");
350                                 //safari_alert();
351                                 enable_ui();
352                         }
353                 });
354         }
357         function createMap(collapsed,zoom,score_array,expr_msg,ids,m_aoa) {
358                 var img_height = +$("#img_height").val();
359                 var best_start = +$("#best_start").val();
360                 var best_end = +$("#best_end").val();
361                 var seq_length = +$("#seq_length").val();
362                 var img_width = 700;
363                 var xscale = +(700/seq_length); // to transform sequence length to pixels
364                 var vline_tag = 100;
366                 var c=document.getElementById("myCanvas");
367                 var ctx=c.getContext("2d");
369                 if (collapsed) {
370                         c.height = +(((ids.length)*35)+73);
371                         img_height = c.height;
372                 } else {
373                         c.height = +img_height;
374                 }
375                 if (seq_length < 700 || zoom) {
376                         xscale = 1;
377                         img_width = seq_length;
378                 }
380                 c.width = img_width;
382                 var cbr_start = +(best_start*xscale);
383                 var cbr_width = +((best_end-best_start)*xscale);
385                 //print black background
386                 ctx.beginPath();
387                 ctx.rect(0,(img_height-52),img_width,102);
388                 ctx.fillStyle='rgb(30,30,30)';
389                 ctx.fill();
390                 ctx.stroke();
392                 //print yellow rectangle for the best region
393                 ctx.beginPath();
394                 ctx.rect(cbr_start,0,cbr_width,img_height);
395                 ctx.strokeStyle='yellow';
396                 ctx.fillStyle='yellow';
397                 ctx.fill();
398                 ctx.stroke();
400                 //print the rectangles
401                 off_set_array = printSquares(collapsed,zoom,ids,m_aoa);
403                 //print vertical lines and tick values
404                 ctx.fillStyle='black';
405                 ctx.lineWidth=1;
406                 ctx.strokeStyle='rgb(200,200,200)';
407                 ctx.font="10px Arial";
408                 if (seq_length >=2700) {ctx.font="8px Arial";}
409                 if (seq_length >=4500) {ctx.font="6px Arial";}
411                 for (var l=100; l<seq_length; l+=100) {
412                         var i = l*xscale;
413                         ctx.beginPath();
414                         ctx.moveTo(i,15);
415                         ctx.lineTo(i,img_height);
416                         ctx.fillText(vline_tag,i-14,12);
417                         ctx.stroke();
419                         vline_tag+=100;
420                 }
422                 // print horizontal line under ticks
423                 ctx.beginPath();
424                 ctx.moveTo(0,20);
425                 ctx.lineTo(img_width,20);
426                 ctx.lineWidth=2;
427                 ctx.strokeStyle='#000000';
428                 ctx.stroke();
430                 //print subject names
431                 var ids_aoa = expr_msg; //aoa with subject ids
432                 for (var t=0; t<ids_aoa.length;t++) {
433                         ctx.beginPath();
434                         ctx.fillStyle='#000000';
435                         ctx.font="12px Arial";
436                         ctx.fillText(ids_aoa[t][0],5,off_set_array[t]+17);
437                         ctx.stroke();
438                 }
439                 printScoreGraph(collapsed,zoom,score_array,ids);    
440         }  
443         function printSquares(collapsed,zoom,ids,m_aoa) {
444                 var coverage = $("#coverage_val").val();
445                 var seq_length = $("#seq_length").val();
447                 var xscale = +(700/seq_length); // to transform sequence length to pixels
448                 var img_width = 700;
449                 var off_set = 20; //just under the horizontal line
450                 var coord_y = 0;
452                 var before_block = 20;
453                 var after_block = 10;
455                 if (collapsed) {
456                         before_block = 25;
457                 }
458                 if (seq_length < 700 || zoom) {
459                         xscale = 1;
460                         img_width = seq_length;
461                 }
463                 var off_set_array = []; //to print names
465                 var c=document.getElementById("myCanvas");
466                 var ctx=c.getContext("2d");
468                 ctx.lineWidth=1;
470                 // each track
471                 for (var t=0; t<ids.length;t++) {
472                         var max_row_num = 0; //to calculate the height of every track
473                         off_set_array.push(off_set);
475                         off_set += before_block; //add some space for the names
477                         //target and off-target colors
478                         if (t < coverage) {
479                                 ctx.strokeStyle='rgb(0,0,180)';
480                                 ctx.fillStyle='rgb(0,120,255)';
481                         } else {
482                                 ctx.strokeStyle='rgb(150,0,0)';
483                                 ctx.fillStyle='rgb(255,0,0)';
484                         }
485                         var row = 1;
486                         var prev_match_end = 9999;
487                         var prev_match_start = 0;
488                         var collapsed_start = 0;
489                         var collapsed_end = 0;
491                         //each match (rectangles)
492                         for (var i=0; i<m_aoa[t].length;i++) {
494                                 var coord = m_aoa[t][i].split("-"); //array with start and end for every match
495                                 m_width = +((+coord[1] - +coord[0] +1)*xscale); //rectangle width in pixels
496                                 m_start = +(+coord[0]*xscale); //rectangle start in pixels
498                                 //to allow as many rows as the n-mer size
499                                 var match_distance = +(+coord[0] - +prev_match_start);
500                                 if ((row < si_rna -1) && (coord[0] <= prev_match_end) && prev_match_end != 9999) {
501                                         if ((match_distance > 1) && ((+row + match_distance) > si_rna)) {
502                                                 row = 1;
503                                         } else {
504                                                 row++;
505                                         }
506                                 } else {
507                                         row = 1;
508                                 }
510                                 if (!collapsed) {
511                                         coord_y = off_set + row*4;
513                                         //print rectangles              
514                                         ctx.beginPath();
515                                         ctx.rect(m_start,coord_y,m_width,4);
516                                         ctx.fill();
517                                         ctx.stroke();
518                                 } else {
519                                         
520                                         if (collapsed_start == 0) {
521                                                 collapsed_start = +coord[0];
522                                         }
523                                         if (+coord[0] < +prev_match_end) {
524                                                 collapsed_end = prev_match_end;
525                                         } else {
526                                                 coord_y = off_set; //to collapse all rectangles of the track
527                                                 if (collapsed_end == 9999) {collapsed_end = prev_match_end;}
528                                                 var collapsed_width = (+collapsed_end - +collapsed_start + 1)*xscale;                 
530                                                 //print rectangles
531                                                 ctx.beginPath();
532                                                 ctx.rect(collapsed_start*xscale,coord_y,collapsed_width,4);
533                                                 ctx.fill();
534                                                 ctx.stroke();
536                                                 collapsed_start = coord[0];
537                                                 collapsed_end = coord[1];
538                                         }
539                                 }
540                                 prev_match_end = +coord[1];
541                                 prev_match_start = +coord[0];
543                                 if (row > max_row_num) {max_row_num = row;} //get maximum number of rows per track to calculate the track height
544                         }
546                         if (!collapsed) {
547                                 var track_height = (max_row_num*4)+after_block; 
548                                 off_set += track_height; //add space for next track
549                         } else {
550                                 if (collapsed_end == 9999) {collapsed_end = prev_match_end;}
551                                 coord_y = off_set; //to collapse all rectangles of the track
552                                 var collapsed_width = (+collapsed_end - +collapsed_start + 1)*xscale;
554                                 //print rectangles              
555                                 ctx.beginPath();
556                                 ctx.rect(collapsed_start*xscale,coord_y,collapsed_width,4);
557                                 ctx.fill();
558                                 ctx.stroke();
560                                 off_set += 10;
561                         }
563                         // print horizontal line under tracks
564                         ctx.beginPath();
565                         ctx.moveTo(0,off_set);
566                         ctx.lineTo(img_width,off_set);
567                         ctx.lineWidth=1;
568                         ctx.strokeStyle='rgb(200,200,200)';
569                         ctx.stroke();
570                 }
571                 return off_set_array;
572         }
575         function printScoreGraph(collapsed,zoom,score_array,ids) {
576                 var img_height = document.getElementById("img_height").value;
577                 var coverage = $("#coverage_val").val();
578                 var seq_length = $("#seq_length").val();
580                 var xscale = +(700/seq_length); // to transform sequence legth to pixels
581                 var img_h = +(img_height-52);
582                 var img_width = 700;
584                 if (collapsed) {
585                         img_h = +((ids.length*35)+21);
586                 }
587                 if (seq_length < 700 || zoom) {
588                         xscale = 1;
589                         img_width = seq_length;
590                 }
592                 var c=document.getElementById("myCanvas");
593                 var ctx=c.getContext("2d");
595                 //print black background
596                 ctx.beginPath();
597                 ctx.rect(0,img_h,img_width,52);
598                 ctx.globalAlpha = 0.7;
599                 ctx.fillStyle='rgb(30,30,30)';
600                 ctx.fill();
601                 ctx.stroke();
602                 ctx.globalAlpha = 1;
604                 //print x axis (green line)
605                 ctx.lineWidth=1;
606                 ctx.beginPath();
607                 ctx.strokeStyle='rgb(0,200,0)';
608                 ctx.moveTo(0,(img_h+26));
609                 ctx.lineTo(img_width,(img_h+26));
610                 ctx.stroke();
612                 if (score_array) { 
613                         ctx.beginPath();
614                         ctx.moveTo(0,+img_h+25);
615                         ctx.strokeStyle='rgb(255,0,0)';
617                         for (var i=0; i<score_array.length; i++) {
618                                 var xpos = (i+1)*xscale;
619                                 var ypos = 0;
621                                 // var final_score = (+score_array[i]/+si_rna/coverage*100).toFixed(2); //using coverage in algorithm
622                                 var final_score = (+score_array[i]*100/coverage).toFixed(2);
624                                 if (+final_score >= 0) {
625                                         ypos = 25-(+final_score*25/100)+2;
626                                 } else {
627                                         ypos = 50-(+final_score*25/100);
628                                 }
629                                 if (ypos > 50) {
630                                         ypos = 50;
631                                 }
632                                 ctx.lineTo(xpos,img_h+ypos);
633                                 ctx.stroke();
634                         }
635                 }
636         }
639         // Highlights best region in Sequence Overview section
640         function hilite_sequence(cbr_start,cbr_end,color) {
642                 if (color) {
643                         var markup = new Text.Markup( { 'highlight' : [ '<span class="highlighted2" style="background:#D2D4D6;">', '</span>' ], 'break' : [ '<br />', '' ], 'space' : [ '<span>&nbsp;</span>', '' ] });
644                 } else {
645                         var markup = new Text.Markup( { 'highlight' : [ '<span class="highlighted">', '</span>' ], 'break' : [ '<br />', '' ], 'space' : [ '<span>&nbsp;</span>', '' ] });
646                 }
648                 var source_el = document.getElementById('query');
649                 var markup_el = document.getElementById('markup');
651                 var hilite_regions=[];
653                 if (cbr_end > 10) {
654                         cbr_start = cbr_start-1;
655                         if (cbr_start < 1) {
656                                 cbr_start = 1;
657                         }
658                         hilite_regions.push(['highlight', cbr_start, cbr_end]);
659                 }
661                 var sequence = source_el.innerHTML;
663                 var break_regions = [];
664                 for (var i=0; i<sequence.length; i=i+60) {
665                         break_regions.push([ 'break', i, i ]);
666                 }
668                 var space_regions = [];
669                 for (var i =0; i<sequence.length; i=i+10) {
670                         space_regions.push(['space', i, i]);
671                 }
673                 var all_regions = break_regions.concat(hilite_regions, space_regions);
674                 var markedup_seq = markup.markup(all_regions, sequence);
676                 //insert line numbers
677                 var line_length = 60;
678                 var current_pos = 1;
679                 var lines = markedup_seq.split('<br />');
680                 var final_seq = '';
681                 var leading_spaces = new Array('', '', '', '', '', '');
683                 for (var i=1; i<lines.length; i++) {
684                         leading_str = leading_spaces.slice(0,Math.ceil(6-(Math.log(current_pos)/Math.log(10)))).join('&nbsp;'); // poor man's sprintf
685                         leading_str2 = leading_spaces.slice(0,Math.ceil(6-(Math.log(current_pos +line_length -1)/Math.log(10)))).join('&nbsp;');
687                         if (current_pos + line_length < sequence.length) {
688                                 final_seq = final_seq + leading_str + current_pos +' '+ lines[i] +' '+ leading_str2 + ( current_pos + line_length - 1) +'<br />';
689                         } else {
690                                 final_seq = final_seq + leading_str + current_pos + ' ' + lines[i] + ' ' + leading_str2 + sequence.length + '<br />';
691                         }
693                         current_pos += line_length;
694                 }
696                 markup_el.innerHTML='<font face="courier" size="2">'+final_seq+'</font>';
697         }
700         function activateCollapse(score_array,best_seq,seq,expr_msg,ids,m_aoa) {
701                 document.getElementById("region_square").style.height="0px";
702                 var collapsed = $("#collapse").val();
703                 var zoom = $("#zoom").val();
704                 var seq_length = $("#seq_length").val();
706                 if (collapsed == 0) {
707                         $("#collapse").html("Expand Graph");
708                         $("#collapse").val(1);
709                         collapsed = 1;
710                 } else {
711                         $("#collapse").html("Collapse Graph");
712                         $("#collapse").val(0);
713                         collapsed = 0;
714                 }
715                 createMap(+collapsed,+zoom,score_array,expr_msg,ids,m_aoa);
716                 getCustomRegion(score_array,best_seq,seq);
717         }
719         function activateZoom(score_array,best_seq,seq,expr_msg,ids,m_aoa) {
720                 var collapsed = $("#collapse").val();
721                 var zoom = $("#zoom").val();
722                 var seq_length = $("#seq_length").val();
724                 if (zoom == 0) {
725                         $("#zoom").html("Zoom Out");
726                         $("#zoom").val(1);
727                         zoom = 1;
728                 } else {
729                         $("#zoom").html("Zoom In");
730                         $("#zoom").val(0);
731                         zoom = 0;
732                 }
733                 createMap(+collapsed,+zoom,score_array,expr_msg,ids,m_aoa);
734                 getCustomRegion(score_array,best_seq,seq);
735         }
737         //Function to change values of custom region by dragging the selection square
738         function getSquareCoords(score_array,best_seq,seq) {
739                 var img_width = 700;
740                 var seq_length = $("#seq_length").val();
741                 var zoom = $("#zoom").val();
742                 var rev_xscale = +(seq_length/img_width); // to transform sequence length to pixels
743                 $("#cbr_p").html("");
745                 if (+zoom || seq_length < 700) {
746                         rev_xscale = 1;
747                         img_width = seq_length;
748                 }
750                 var r_left = document.getElementById("region_square").style.left;
751                 var r_width = document.getElementById("region_square").style.width;
752                 var left_num = r_left.replace("px","");
753                 var right_num = r_width.replace("px","");
754                 var sqr_left = Math.round(+left_num*rev_xscale);
755                 var sqr_right = Math.round((+left_num + +right_num)*rev_xscale);
757                 var cbr_start = (+sqr_left + 1);
758                 var cbr_end = (+sqr_right);
759                 var fragment = (+cbr_end - +cbr_start +1);
761                 if (+cbr_end > seq_length) {cbr_end = seq_length;}
762                 if (+cbr_start < 1) {cbr_start = 1;}
764                 $("#cbr_start").val(cbr_start);
765                 $("#cbr_end").val(cbr_end);
766                 $("#f_size").val(fragment);
768                 var best_region = [cbr_start,cbr_end];
769                 hilite_sequence(cbr_start,cbr_end,1);
770                 printCustomSeq(best_seq,seq);
772                 if (score_array) {
773                         printCustomScore(cbr_start,cbr_end,score_array);
774                 }
775         }
777         //Prints custom sequence in Best Region section
778         function printCustomSeq(best_seq,seq) {
779                 var best_seq_el = document.getElementById("best_seq");
780                 var cbr_start = +$("#cbr_start").val();
781                 var cbr_end = +$("#cbr_end").val();
782                 var best_start = +$("#best_start").val();
783                 var best_end = +$("#best_end").val();
785                 best_seq_el.innerHTML = "<b>>custom_region_("+cbr_start+"-"+cbr_end+")</b><br />";
787                 for (var i=cbr_start; i<cbr_end; i=i+60) {
788                         if (cbr_end<i+61) {
789                                 best_seq_el.innerHTML += seq.substring(i-1,cbr_end)+"<br />";
790                         } else {
791                                 best_seq_el.innerHTML += seq.substring(i-1,i+59)+"<br />";
792                         }
793                 }
794                 best_seq_el.innerHTML += "<br /><b>>best_target_region_("+best_start+"-"+best_end+")</b><br />";
795                 best_seq_el.innerHTML += best_seq+"<br />";
796         }
799         // Prints Scores
800         function printCustomScore(start,end,score_array){
801                 var custom_score = 0;
802                 var coverage = +$("#coverage_val").val();
803                 var seq_length = +$("#seq_length").val();
804                 var best_score = +$("#best_score").val();
806                 if (+end > seq_length) {end = seq_length;}
807                 if (+start < 1) {start = 1;}
809                 if (score_array) {
810                         for (var i= +start-1; i< +end; i++) {
811                                 custom_score += +score_array[i];
812                         }
813                 }
815                 var fragment_length = (+end - +start + 1);
817                 if (coverage > 0 && fragment_length > 0) {
818                         var final_score = ((custom_score*100/fragment_length)/coverage).toFixed(2); 
819                         // var final_score = (custom_score*100/+si_rna/fragment_length/coverage).toFixed(2); //using coverage
820                         $("#score_p").html("<b>Best target region score:</b> "+best_score+" &nbsp;&nbsp; <b> Custom region score: </b>"+final_score+" &nbsp;&nbsp; (-&infin;&mdash;100)");
821                 }
822         }
825         // Creates the draggable selection square and modifies custom region when push a button
826         function getCustomRegion(score_array,best_seq,seq) {
828                 var cbr_start = +$("#cbr_start").val();
829                 var cbr_end = +$("#cbr_end").val();
830                 var map_el = document.getElementById('myCanvas');
831                 var seq_length = +$("#seq_length").val();
833                 var img_width = 700;
834                 var xscale = +(+img_width/+seq_length); // to transform sequence length to pixels
836                 var zoom = $("#zoom").val();
838                 if (zoom == 1 || seq_length < 700) {
839                         xscale = 1;
840                         img_width = seq_length;
841                 }
842                 if (seq_length < 700) {document.getElementById("seq_map").style.width=""+seq_length+"px";}
845                 if ((cbr_start > 0) && (cbr_end <= seq_length) && (cbr_end >= cbr_start+99)) {
846                         var cbr_left = Math.round((+cbr_start-1)*xscale);
847                         var cbr_width = ((+cbr_end - +cbr_start +1)*xscale);
849                         var cbr_height = (map_el.height - 21);
851                         //a border will add pixels to all end coordinates
852                         $("#region_square").css("border","0px solid #000000");
853                         $("#region_square").css("top","21px");
854                         $("#region_square").css("background","rgba(80,100,100,0.3)");
855                         $("#region_square").css("left",cbr_left+"px");
856                         $("#region_square").css("width",cbr_width+"px");
857                         $("#region_square").css("height",cbr_height+"px");
859             $("#region_square").resizable({
860                                 containment:map_el,
861                                 handles: 'e, w',
862                                 minWidth: 100*xscale,
863                         });
865                         $("#region_square").draggable({
866                                 axis: 'x',
867                                 containment:map_el,
868                                 cursor: "move"
869                         });
870                         
871                         $("#cbr_p").html("");
872                         var fragment = (+cbr_end - +cbr_start +1);
873                         $("#f_size").val(fragment);
875                         hilite_sequence(cbr_start,cbr_end,1);
876                 
877                 
878                         printCustomSeq(best_seq,seq);
880                         if (score_array) {
881                                 printCustomScore(cbr_start,cbr_end,score_array);
882                         }
884                 } else {
885                         $("#cbr_p").html("Values must be between 1 and "+seq_length+", getting a sequence not shorter than 100 bp!");
886                 }
887         }
890         function changeTargets(bt2_file,score_array,seq,best_seq,expr_f,ids,m_aoa) {
891                 
892                 var t_num = $("#t_num").val();
893                 var coverage = $("#coverage_val").val();
894                 var f_size = $("#f_size").val();
895                 var f_length = $("#f_length").val();
896                 var n_mer = $("#n_mer").val();
897                 si_rna = $("#si_rna").val();
898                 var align_mm = $("#align_mm").val();
899                 var mm = $("#mm").val();
900                 var db = $("#bt2_db").val();
901                 var expr_msg;
902                 var seq_length = $("#seq_length").val();
903                 
904                 if (n_mer != si_rna) {
905                         $("#f_length").val(f_size);
906                         $("#mm").val(align_mm);
907                         $("#si_rna").val(n_mer);
908                         si_rna = n_mer;
909                         $("#coverage_val").val(t_num);
910                         $("#region_square").css("height","0px");
911                         
912                         //check values before recalculate
913                         if (+n_mer >= 18 && +n_mer <= 30) {
914                                 disable_ui();
915                                 runBt2(n_mer, f_size, align_mm, db);
916                         } else {
917                                 alert("n-mer value must be between 18-30");
918                         }
919                 } else if (align_mm != mm) {
920                         $("#f_length").val(f_size);
921                         $("#mm").val(align_mm);
922                         $("#coverage_val").val(t_num);
923                         
924                         if (!align_mm || +align_mm < 0 || +align_mm > 1) {
925                                 alert("miss-match value ("+align_mm+") must be between 0-1");
926                         } else {
927                                 disable_ui();
928                                 getResults(1, bt2_file, n_mer, f_size, align_mm, t_num, db, expr_f);
929                                 $("#region_square").css("height","0px");
930                                 //getCustomRegion(score_array,best_seq,seq)
931                         }
932                 } else if (t_num != coverage || f_size != f_length) {
933                         $("#f_length").val(f_size);
934                         $("#coverage_val").val(t_num);
935                         
936                         //check values before recalculate
937                         if (!f_size || +f_size < 100 || +f_size > +seq_length) {
938                                 alert("Wrong fragment size ("+f_size+"), it must be 100 bp or higher, and lower than sequence length");
939                         } else {
940                                 disable_ui();
941                                 getResults(0, bt2_file, n_mer, f_size, align_mm, t_num, db, expr_f);
942                                 $("#region_square").css("height","0px");
943                                 //getCustomRegion(score_array,best_seq,seq)
944                         }
945                 } else {
946                         alert("there are no parameters to change");
947                 }
948                 return [score_array,seq,best_seq,expr_msg,ids,m_aoa]
949         }
951         function disable_ui() {
952                 $('#working').dialog("open");
953         }
955         function enable_ui() {
956                 $('#working').dialog("close");
957         }
959         function hide_ui() {
960                 Effects.swapElements('vigs_input_offswitch', 'vigs_input_onswitch');
961                 Effects.hideElement('vigs_input_content');
962                 Effects.swapElements('vigs_usage_offswitch', 'vigs_usage_onswitch');
963                 Effects.hideElement('vigs_usage_content');
964         }
965         
966         // function safari_alert() {
967         //      if (navigator.appVersion.match(/Safari/i) && !navigator.appVersion.match(/chrome/i)) {
968         //              alert("SGN VIGS Tool does not support Safari, please use a different browser like Firefox (recommended) or Google chrome.");
969         //      }
970         // }