source: extensions/net.sf.basedb.reggie/trunk/resources/analysis/demux_confirm.jsp @ 2593

Last change on this file since 2593 was 2593, checked in by Nicklas Nordborg, 8 years ago

Resetting debug flags.

File size: 17.6 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.User"
5  import="net.sf.basedb.core.DbControl"
6  import="net.sf.basedb.core.SessionControl"
7  import="net.sf.basedb.core.Application"
8  import="net.sf.basedb.clients.web.Base" 
9  import="net.sf.basedb.clients.web.util.HTML" 
10  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
11%>
12<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
13<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
14<%
15final SessionControl sc = Base.getExistingSessionControl(request, true);
16final String ID = sc.getId();
17final float scale = Base.getScale(sc);
18final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
19DbControl dc = null;
20try
21{
22  dc = sc.newDbControl();
23  final User user = User.getById(dc, sc.getLoggedInUserId());
24%>
25<base:page type="default" >
26<base:head scripts="ajax.js" styles="path.css">
27  <link rel="stylesheet" type="text/css" href="../css/reggie.css">
28  <script language="JavaScript" src="../reggie.js" type="text/javascript" charset="UTF-8"></script>
29
30<script language="JavaScript">
31
32var debug = 0;
33var currentStep = 1;
34
35
36function init()
37{
38  var frm = document.forms['reggie'];
39  var jobs = getDemuxJobs();
40
41  // Load existing Demux jobs
42  if (jobs != null && jobs.length > 0)
43  {
44    for (var jobNo=0; jobNo < jobs.length; jobNo++)
45    {
46      var job = jobs[jobNo];
47      var option = new Option(job.name, job.id);
48      //option.title = title;
49      option.job = job;
50      frm.demuxJobs.options[frm.demuxJobs.length] = option;
51    }
52    demuxJobOnChange();
53  }
54  else
55  {
56    var msg = 'No jobs available for processing.';
57    setFatalError(msg);
58    return;
59  }
60
61  // All is ok
62  frm.demuxJobs.focus();
63}
64
65function getPoolNum(poolName)
66{
67  var num = poolName.match(/Pool(\d+)/);
68  return num ? parseInt(num[1], 10) : null; 
69}
70
71function goNextAuto()
72{
73  goNext(false);
74}
75
76function goNext(manual)
77{
78  setInnerHTML('gonext.message', '');
79  if (currentStep == 1)
80  {
81    if (step1IsValid()) gotoStep2();
82  }
83  setCurrentStep(currentStep);
84}
85
86function step1IsValid()
87{
88  return true;
89}
90
91function step2IsValid()
92{
93  return true;
94}
95
96
97function getDemuxJobs()
98{
99  var frm = document.forms['reggie']; 
100 
101  var request = Ajax.getXmlHttpRequest();
102  try
103  {
104    showLoadingAnimation('Loading demux jobs...');
105    var url = '../DemuxMerge.servlet?ID=<%=ID%>&cmd=GetUnconfirmedDemuxJobs';   
106    request.open("GET", url, false); 
107    request.send(null);
108  }
109  finally
110  {
111    hideLoadingAnimation();
112  }
113 
114  if (debug) Main.debug(request.responseText);
115  var response = JSON.parse(request.responseText); 
116  if (response.status != 'ok')
117  {
118    setFatalError(response.message);
119    return false;
120  }
121  return response.jobs;
122}
123
124function demuxJobOnChange()
125{
126  var frm = document.forms['reggie']; 
127  var job = frm.demuxJobs[frm.demuxJobs.selectedIndex].job;
128 
129  setInnerHTML('startDate', formatDate(job.started));
130  setInnerHTML('endDate', formatDate(job.ended));
131  setInnerHTML('jobStatus', job.status+'; '+Strings.encodeTags(job.statusMessage));
132 
133  var demuxedSequences = job.demuxedSequences;
134  var fcHtml = '<table id="fc-info-table"><tr><th>ID</th><th>PF_READS</th><th>PF_UNUSED_PCT</th><th>PF_NNNN_PCT</th><th>Warnings</th></tr>';
135  var poolHtml = '';
136  var libPlateHtml = '';
137  var warningsHtml = '';
138  for (var dxNo = 0; dxNo < demuxedSequences.length; dxNo++)
139  {
140    var dx = demuxedSequences[dxNo];
141    var fc = dx.seqRun.flowCell;
142   
143    //if (dxNo > 0) fcHtml += '<br>';
144    fcHtml += '<tr><td>'+Main.encodeTags(fc.FlowCellID)+'</td>';
145    fcHtml += '<td>' + formatNumber(dx.PF_READS/1000000, 'M', 2) + '</td>';
146    fcHtml += '<td>' + formatNumber(dx.PF_UNUSED_PCT, '%', 2)+' </td>';
147    fcHtml += '<td>'+formatNumber(dx.PF_NNNN_PCT, '%', 2) + '</td>';
148    fcHtml += '<td>'+dx.DEMUX_WARNING.length;
149    if (dx.DEMUX_WARNING.length > 0) fcHtml += ' (see below)';
150    fcHtml += '</td></tr>';
151   
152    var pools = fc.pools;
153    for (var poolNo = 0; poolNo < pools.length; poolNo++)
154    {
155      var pool = pools[poolNo];
156      if (poolHtml.indexOf(pool.name) == -1)
157      {
158        if (poolHtml.length > 0) poolHtml += ', ';
159        poolHtml += Main.encodeTags(pool.name);
160      }
161      if (pool.LibPlate && libPlateHtml.indexOf(pool.LibPlate.name) == -1)
162      {
163        if (libPlateHtml.length > 0) libPlateHtml += ', ';
164        libPlateHtml += Main.encodeTags(pool.LibPlate.name);
165      }
166    }
167   
168    if (dx.DEMUX_WARNING.length > 0)
169    {
170      for (var warnNo = 0; warnNo < dx.DEMUX_WARNING.length; warnNo++)
171      {
172        warningsHtml += '<li class="warning">'+Main.encodeTags(fc.FlowCellID)+': '+Main.encodeTags(dx.DEMUX_WARNING[warnNo]) + '<br>';
173      }
174    }
175  }
176  fcHtml += '</table>';
177
178  setInnerHTML('flowCellsInDemux', fcHtml);
179  setInnerHTML('pools', poolHtml);
180  setInnerHTML('libPlates', libPlateHtml || 'n/a');
181  setInnerHTML('comments', Main.encodeTags(job.comments));
182  setInnerHTML('warnings', warningsHtml);
183}
184
185
186function formatDate(value)
187{
188  if (!value) return '';
189  if (value.length == 8)
190  {
191    // YYYYMMDD
192    value = value.substr(0, 4) + '-' + value.substr(4, 2) + '-' + value.substr(6, 2);
193  }
194  else if (value.length == 13)
195  {
196    // YYYYMMDD HHMM
197    value = value.substr(0, 4) + '-' + value.substr(4, 2) + '-' + value.substr(6, 2) + ' ' + value.substr(9, 2) + ':' + value.substr(11, 2);
198  }
199  return value;
200}
201
202
203function gotoStep2()
204{
205  var frm = document.forms['reggie'];
206 
207  // Disable controls
208  frm.demuxJobs.disabled = true;
209
210  currentStep = 2;
211  Main.hide('step.1.section');
212  Main.show('step.2.section');
213  Main.addClass(document.getElementById('step.1.section'), 'disabled');
214  Main.show('gocancel');
215  Main.show('goregister');
216  Main.hide('gonext');
217 
218  var job = frm.demuxJobs[frm.demuxJobs.selectedIndex].job;
219
220  var mergedSeq = getMergedSequences();
221  job.mergedSequences = mergedSeq;
222 
223  var html = '<table id="mergedSequencesTable">';
224  html += '<thead style="background-color: #E8E8E8; border-top: 1px solid #A0A0A0;">';
225  // Header row
226  html += '<tr>';
227  html += '<th>Library</th>';
228  html += '<th class="dottedleft">READS</th>';
229  html += '<th class="dottedleft">PF_READS</th>';
230  html += '<th class="dottedleft">PT_READS</th>';
231  html += '<th class="dottedleft">Flag RNA</th>';
232  html += '<th class="dottedleft">Align</th>';
233  html += '<th class="dottedleft">Comment</th>';
234  html += '</tr>';
235  html += '<tr>';
236  html += '<th></th>';
237  html += '<th class="dottedleft">(millions)</th>';
238  html += '<th class="dottedleft">(millions)</th>';
239  html += '<th class="dottedleft">(millions)</th>';
240  html += '<th class="dottedleft"></th>';
241  html += '<th class="dottedleft"></th>';
242  html += '<th class="dottedleft"></th>';
243  html += '</tr>';
244  html += '</thead>';
245  html += '<tbody>';
246  for (var mergedNo = 0; mergedNo < mergedSeq.length; mergedNo++)
247  {
248    var merged = mergedSeq[mergedNo];
249    var lib = merged.lib;
250    lib.stratagene = lib.name.indexOf(GENERIC_STRATAGENE_NAME) == 0;
251    lib.external = lib.name.indexOf(EXTERNAL_RNA_NAME) == 0;
252   
253    html += '<tr class="highlight">';
254    html += '<td class="prompt">'+lib.name+'</td>';
255    html += '<td class="dottedleft">'+formatNumber(merged.READS/1000000, null, 2)+'</td>';
256    html += '<td class="dottedleft">'+formatNumber(merged.PF_READS/1000000, null, 2)+'</td>';
257    html += '<td class="dottedleft">'+formatNumber(merged.PT_READS/1000000, null, 2)+'</td>';
258
259    // Do not allow flagging external or stratagene
260    var alignChecked = 'checked';
261    if (lib.stratagene || lib.external)
262    {
263      html += '<td class="dottedleft">-</td>';
264      alignChecked = '';
265    }
266    else
267    {
268      if (!merged.PF_READS) alignChecked = '';
269      html += '<td class="dottedleft"><input type="checkbox" name="flag.'+merged.id+'"></td>';
270    }
271   
272    html += '<td class="dottedleft"><input type="checkbox" name="align.'+merged.id+'" '+alignChecked+'></td>';
273    html += '<td class="dottedleft"><input type="text" name="comment.'+merged.id+'" style="width: 20em;"></td>';
274    html += '</tr>';
275  }
276  html += '</tbody>';
277  html += '</table>';
278  setInnerHTML('mergedSequences', html);
279 
280  if (job.status == 'ERROR')
281  {
282    Doc.element('outcomeFailed').checked = true;
283    outcomeOnChange();
284  }
285
286}
287
288
289function getMergedSequences()
290{
291  var frm = document.forms['reggie'];
292  var job = frm.demuxJobs[frm.demuxJobs.selectedIndex].job;
293 
294  var request = Ajax.getXmlHttpRequest();
295  try
296  {
297    showLoadingAnimation('Loading merged sequences...');
298    var url = '../DemuxMerge.servlet?ID=<%=ID%>&cmd=GetMergedSequences&job='+job.id;   
299    request.open("GET", url, false); 
300    request.send(null);
301  }
302  finally
303  {
304    hideLoadingAnimation();
305  }
306 
307  if (debug) Main.debug(request.responseText);
308  var response = JSON.parse(request.responseText); 
309  if (response.status != 'ok')
310  {
311    setFatalError(response.message);
312    return false;
313  }
314  return response.mergedSequences;
315
316}
317
318function outcomeOnChange()
319{
320  var frm = document.forms['reggie'];
321  var failed = document.getElementById('outcomeFailed').checked;
322  frm.flagPools.disabled = !failed;
323 
324  var job = frm.demuxJobs[frm.demuxJobs.selectedIndex].job;
325  var mergedSequences = job.mergedSequences;
326 
327  for (var mergeNo = 0; mergeNo < mergedSequences.length; mergeNo++)
328  {
329    var merge = mergedSequences[mergeNo];
330    if (frm['flag.'+merge.id])
331    {
332      frm['flag.'+merge.id].disabled = failed;
333    }
334    frm['align.'+merge.id].disabled = failed;
335  }
336 
337}
338
339
340function goRegister()
341{
342  if (!step2IsValid()) return;
343  var failed = document.getElementById('outcomeFailed').checked;
344
345  var frm = document.forms['reggie'];
346  Main.addClass(document.getElementById('step.2.section'), 'disabled');
347 
348 
349  Main.hide('goregister');
350  Main.hide('gocancel');
351  Main.hide('gonext.message');
352 
353  var submitInfo = {};
354 
355  submitInfo.failed = failed;
356  submitInfo.flagPools = !frm.flagPools.disabled && frm.flagPools.checked ? true : false;
357 
358  var job = frm.demuxJobs[frm.demuxJobs.selectedIndex].job;
359  var demuxedSequences = job.demuxedSequences;
360  var mergedSequences = job.mergedSequences;
361 
362  var demux = [];
363  submitInfo.demuxedSequences = demux;
364  for (var demuxNo = 0; demuxNo < demuxedSequences.length; demuxNo++)
365  {
366    var dx = demuxedSequences[demuxNo];
367    var tmp = {};
368    tmp.id = dx.id;
369    demux[demux.length] = tmp;
370  }
371 
372  var merged = [];
373  submitInfo.mergedSequences = merged;
374  for (var mergeNo = 0; mergeNo < mergedSequences.length; mergeNo++)
375  {
376    var merge = mergedSequences[mergeNo];
377    var tmp = {};
378    tmp.id = merge.id;
379    tmp.flag = frm['flag.'+merge.id] && frm['flag.'+merge.id].checked;
380    tmp.align = frm['align.'+merge.id].checked;
381    tmp.comment = frm['comment.'+merge.id].value;
382    merged[merged.length] = tmp;
383  }
384 
385  if (debug) Main.debug(JSON.stringify(submitInfo));
386  var url = '../DemuxMerge.servlet?ID=<%=ID%>&cmd=RegisterDemuxAndMerge';
387  var request = Ajax.getXmlHttpRequest();
388  try
389  {
390    showLoadingAnimation('Performing registration...');
391    request.open("POST", url, false);
392    request.send(JSON.stringify(submitInfo));
393  }
394  finally
395  {
396    hideLoadingAnimation();
397  }
398 
399  if (debug) Main.debug(request.responseText);
400  var response = JSON.parse(request.responseText);
401 
402  if (response.messages && response.messages.length > 0)
403  {
404    var msg = '<ul>';
405    for (var i = 0; i < response.messages.length; i++)
406    {
407      var msgLine = response.messages[i];
408      if (msgLine.indexOf('[Warning]') >= 0)
409      {
410        msg += '<li class="warning">' + msgLine.replace('[Warning]', '');
411      }
412      else
413      {
414        msg += '<li>' + msgLine;
415      }
416    }
417    msg += '</ul>';
418    setInnerHTML('messages', msg);
419    Main.show('messages');
420  }
421 
422  if (response.status != 'ok')
423  {
424    Main.addClass(document.getElementById('messages'), 'failure');
425    setFatalError(response.message);
426    return false;
427  }
428
429  Main.show('gorestart');
430
431 
432}
433
434
435
436</script>
437<style>
438.fc-info
439{
440  background-color: #F4F4F4;
441  border-top: 1em solid transparent;
442}
443
444.fc-info .subprompt
445{
446  font-weight: normal;
447  padding-left: 2em;
448  text-align: left;
449}
450
451.fc-info .input
452{
453  font-style: italic;
454}
455
456#fc-info-table
457{
458  border-collapse: collapse;
459  background-color: #FFFFFF;
460  border: 1px solid #A0A0A0;
461}
462
463#fc-info-table td, #fc-info-table th
464{
465  padding: 1px 4px 1px 4px;
466  text-align: center;
467  border-left: 1px dotted #A0A0A0;
468  border-right: 1px dotted #A0A0A0;
469}
470
471tr.highlight
472{
473  border-top: 1px dotted #A0A0A0;
474}
475
476.dottedleft
477{
478  border-left: 1px dotted #A0A0A0;
479}
480
481#mergedSequencesTable
482{
483  width: 100%;
484  border-collapse: collapse;
485}
486
487#mergedSequencesTable td
488{
489  text-align: center;
490  min-width: 4.5em;
491}
492
493#mergedSequencesTable tbody td
494{
495  padding-top: 1px;
496  padding-bottom: 1px;
497}
498
499#mergedSequencesTable .italic
500{
501  font-style: italic;
502}
503
504</style>
505</base:head>
506<base:body onload="init()">
507
508  <p:path><p:pathelement 
509    title="Reggie" href="<%="../index.jsp?ID="+ID%>" 
510    /><p:pathelement title="Confirm demux and merge ended" 
511    /></p:path>
512
513  <div class="content">
514  <%
515  if (sc.getActiveProjectId() == 0)
516  {
517    %>
518    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
519      No project has been selected. You may proceed with the registration but
520      created items will not be shared.
521    </div>
522    <%
523  }
524  %>
525 
526  <div class="allsteps">
527    <div class="step current" id="step.1">1</div>
528    ›
529    <div class="step future" id="step.2">2</div>
530  </div>
531
532  <form name="reggie" onsubmit="return false;">
533 
534  <div id="step.1.section">
535  <table id="step.1.section" class="stepform">
536  <tr>
537    <td rowspan="3" class="stepno">1</td>
538    <td class="steptitle">Select demux job</td>
539  </tr>
540  <tr>
541    <td class="stepfields">
542      <table style="border-collapse: collapse;">
543      <tr valign="top">
544        <td class="prompt">Demux jobs</td>
545        <td class="input"><select class="required" style="width:90%;" 
546            name="seqRuns" id="demuxJobs" onchange="demuxJobOnChange()"></select>
547        </td>
548        <td class="status" id="demuxJobs.status"></td>
549        <td class="help"><span id="demuxJobs.message" class="message" style="display: none;"></span>
550          Select a demux job. The list contains all demux jobs that has
551          ended but has not been confirmed (determined by the absense of AnalysisResult
552          annotation on demuxed sequences items).
553        </td>
554      </tr>
555      <tbody class="fc-info">
556      <tr valign="top">
557        <td class="subprompt">Start date</td>
558        <td class="input" id="startDate" colspan="3"></td>
559      </tr>
560      <tr valign="top">
561        <td class="subprompt">End date</td>
562        <td class="input" id="endDate" colspan="3"></td>
563      </tr>
564      <tr valign="top">
565        <td class="subprompt">Status</td>
566        <td class="input" id="jobStatus" colspan="3"></td>
567      </tr>
568      <tr valign="top">
569        <td class="subprompt">Flow cells</td>
570        <td class="input" id="flowCellsInDemux" colspan="3"></td>
571      </tr>
572      <tr valign="top">
573        <td class="subprompt">Pools</td>
574        <td class="input" id="pools" colspan="3"></td>
575      </tr>
576      <tr valign="top">
577        <td class="subprompt">LibPlates</td>
578        <td class="input" id="libPlates" colspan="3"></td>
579      </tr>
580      <tr valign="top">
581        <td class="subprompt">Comments</td>
582        <td class="input" id="comments" colspan="3"></td>
583      </tr>
584      <tr valign="top">
585        <td class="subprompt">Warnings</td>
586        <td class="input" id="warnings" colspan="3">-</td>
587      </tr>
588      </tbody>
589      </table>
590    </td>
591  </tr>
592  </table>
593  </div>
594 
595  <div id="step.2.section" style="display: none;">
596  <table class="stepform">
597  <tr>
598    <td rowspan="3" class="stepno">2</td>
599    <td class="steptitle" id="step.2.title">Demux job</td>
600  </tr>
601  <tr>
602    <td class="stepfields">
603      <table>
604      <tr valign="top">
605        <td class="prompt">Outcome</td>
606        <td class="input">
607          <label><input type="radio" name="outcome" id="outcomeSuccessful" 
608            onclick="outcomeOnChange()" checked>Success</label> - continue with alignment<br>
609          <label><input type="radio" name="outcome" id="outcomeFailed" 
610            onclick="outcomeOnChange()">Failure</label> - no alignment<br>
611          <img src="../images/joinbottom.gif"><label><input type="checkbox" name="flagPools" value="1" disabled checked>Flag pools for re-clustering</label>
612        </td>
613        <td class="status" id="outcome.status"></td>
614        <td class="help"><span id="outcome.message" class="message" style="display: none;"></span>
615          Select the <b>Success</b> option if the demux was successful and it is possible to continue
616          with filtering and alignment of the sequences.
617          Select the <b>Failure</b> option if it not possible to continue.
618          Existing pooled libraries can optionally
619          be flagged for re-clustering and re-sequencing.
620        </td>
621      </tr>
622      </table>
623     
624      <div id="mergedSequences">
625       
626      </div>
627     
628    </td>
629  </tr>
630  </table>
631  </div>
632   
633  <div class="loading" id="loading" style="display: none;"><table><tr><td><img src="../images/loading.gif"></td><td id="loading.msg">Please wait...</td></tr></table></div>
634 
635  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
636 
637  <div id="messages" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
638 
639  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
640    <tr>
641      <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
642      <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)"/></td>
643      <td><base:button id="goregister" title="Register" image="<%=home+"/images/import.png"%>" onclick="goRegister()" style="display: none;"/></td>
644      <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
645      <td id="gonext.message" class="message"></td>
646    </tr>
647  </table>
648 
649  </form>
650  </div>
651 
652</base:body>
653</base:page>
654<%
655}
656finally
657{
658  if (dc != null) dc.close();
659}
660%>
Note: See TracBrowser for help on using the repository browser.