source: extensions/net.sf.basedb.reggie/trunk/resources/libprep/sequencing_started.jsp @ 2231

Last change on this file since 2231 was 2231, checked in by Nicklas Nordborg, 9 years ago

References #562: Re-design clustering and sequencing startup wizards

Some minor changes to the layout.

File size: 17.4 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 = 1;
33var currentStep = 1;
34var runParametersIsValid = false;
35
36var runParameters;
37var flowCell;
38
39function goNextAuto()
40{
41  goNext(false);
42}
43
44function goNext(manual)
45{
46  setInnerHTML('gonext.message', '');
47  if (currentStep == 1)
48  {
49    if (step1IsValid()) gotoStep2();
50  }
51}
52
53
54function step1IsValid()
55{
56  return runParametersIsValid;
57}
58
59
60function init()
61{
62  var frm = document.forms['reggie'];
63 
64  // Load sequencing protocols
65  var sequencingProtocols = getProtocols('SEQUENCING_PROTOCOL');
66  for (var i = 0; i < sequencingProtocols.length; i++)
67  {
68    var protocol = sequencingProtocols[i];
69    frm.sequencingProtocol[frm.sequencingProtocol.length] = new Option(protocol.name, protocol.id, protocol.isDefault);
70    setInputStatus('sequencingProtocol', '', 'valid');
71  }
72  if (frm.sequencingProtocol.length == 0)
73  {
74    frm.sequencingProtocol[0] = new Option('- none -', '');
75  }
76 
77  // Load sequencing machines
78  var sequencers = getHardware('SEQUENCER');
79  for (var i = 0; i < sequencers.length; i++)
80  {
81    var sequencer = sequencers[i];
82    frm.sequencer[frm.sequencer.length] = new Option(sequencer.name, sequencer.id, sequencer.isDefault);
83    setInputStatus('sequencer', '', 'valid');
84  }
85  if (frm.sequencer.length == 0)
86  {
87    frm.sequencer[0] = new Option('- none -', '');
88  }
89}
90
91function getProtocols(subtype)
92{
93  var request = Ajax.getXmlHttpRequest();
94  try
95  {
96    showLoadingAnimation('Loading ' + subtype + ' protocols...');
97    var url = '../Protocol.servlet?ID=<%=ID%>&cmd=GetProtocols&subtype='+subtype;   
98    request.open("GET", url, false); 
99    request.send(null);
100  }
101  finally
102  {
103    hideLoadingAnimation();
104  }
105
106  if (debug) Main.debug(request.responseText);
107  var response = JSON.parse(request.responseText); 
108  if (response.status != 'ok')
109  {
110    setFatalError(response.message);
111    return false;
112  }
113  return response.protocols;
114}
115
116function getHardware(subtype)
117{
118  var request = Ajax.getXmlHttpRequest();
119  try
120  {
121    showLoadingAnimation('Loading ' + subtype + ' hardware...');
122    var url = '../Hardware.servlet?ID=<%=ID%>&cmd=GetHardware&subtype='+subtype;   
123    request.open("GET", url, false); 
124    request.send(null);
125  }
126  finally
127  {
128    hideLoadingAnimation();
129  }
130
131  if (debug) Main.debug(request.responseText);
132  var response = JSON.parse(request.responseText); 
133  if (response.status != 'ok')
134  {
135    setFatalError(response.message);
136    return false;
137  }
138  return response.hardware;
139}
140
141
142function runParametersXmlFileOnChange(event)
143{
144  var frm = document.forms['reggie'];
145  var file = event.target.files[0];
146 
147  // Clear information
148  setInnerHTML('experimentName', '');
149  setInnerHTML('externalId', '');
150  setInnerHTML('runId', '');
151  setInnerHTML('position', '');
152  setInnerHTML('runNumber', '');
153  setInnerHTML('startDate', '');
154  setInnerHTML('sequencingCycles', '');
155  Main.hide('existing-sequencing-runs');
156  setInnerHTML('existing-sequencing-runs', '');
157 
158  var reader = new FileReader();
159  reader.onload = runParametersXmlFileLoaded;
160  reader.readAsText(file);
161}
162
163function runParametersXmlFileLoaded(event)
164{
165  parseRunParametersXmlFile(event.target.result);
166  var frm = document.forms['reggie'];
167  frm.comments.focus();
168}
169
170
171function parseRunParametersXmlFile(data)
172{
173  var frm = document.forms['reggie'];
174  runParametersIsValid = false;
175  setInputStatus('runParametersXml', '', '');
176 
177  var doc;
178  try
179  {
180    var parser = new DOMParser();
181    doc = parser.parseFromString(data, "application/xml");
182 
183    if (doc.documentElement.tagName == 'parsererror')
184    {
185      setInputStatus('runParametersXml', doc.documentElement.firstChild.textContent.split(/\n/)[0], 'invalid');
186      return;
187    }
188  }
189  catch (err)
190  {
191    setInputStatus('runParametersXml', err, 'invalid');
192    return;
193  }
194 
195  var info = {};
196  try
197  {
198    info.ExperimentName = getTextValue(doc, 'ExperimentName');
199    info.RunID = getTextValue(doc, 'RunID');
200    info.HiSeqPosition = getTextValue(doc, 'FCPosition');
201    info.ScannerID = getTextValue(doc, 'ScannerID');
202    info.ScanNumber = parseInt(getTextValue(doc, 'ScanNumber'));
203    info.FlowCellID = getTextValue(doc, 'Barcode');
204    info.SequencingCycles = getTextValue(doc, 'Read1') + '-' + getTextValue(doc, 'IndexRead1') + '-' + getTextValue(doc, 'Read2');
205    info.SequencingStart = '20'+getTextValue(doc, 'RunStartDate');
206
207    validateAndCopyRunParameters(info);
208  }
209  catch (msg)
210  {
211    setInputStatus('runParametersXml', msg, 'invalid');
212    if (debug) Main.debug(JSON.stringify(info));
213    return;
214  }
215 
216  runParametersIsValid = true;
217  runParameters = info;
218  setInputStatus('runParametersXml', '', 'valid');
219
220  if (debug) Main.debug(JSON.stringify(info));
221}
222
223
224function getTextValue(doc, selector)
225{
226  var el = doc.querySelector(selector);
227  if (el == null)
228  {
229    throw "Can't find tag &lt;"+selector+"&gt;";
230  }
231  return el.textContent;
232}
233
234function validateAndCopyRunParameters(info)
235{
236  var frm = document.forms['reggie'];
237
238  setInnerHTML('experimentName', info.ExperimentName);
239  setInnerHTML('externalId', info.FlowCellID);
240  setInnerHTML('runId', info.RunID);
241  setInnerHTML('position', info.HiSeqPosition);
242  setInnerHTML('runNumber', info.ScanNumber);
243  setInnerHTML('startDate', formatDate(info.SequencingStart));
244  setInnerHTML('sequencingCycles', info.SequencingCycles);
245
246  flowCell = getFlowCellInfoByBarcode(info.FlowCellID);
247  if (flowCell == null)
248  {
249    throw 'Flow cell with ID='+info.FlowCellID+' not found.';
250  }
251  var html = '';
252  html += '<tr valign="top" class="fc-info">';
253  html += '<td class="prompt" colspan="2">Existing sequencing runs for ' + flowCell.name + '</td>';
254  html += '';
255  html += '<td class="status"></td>';
256  html += '<td class="help">Start and end date is shown for other registered sequencing runs.</td>';
257  html += '</tr>';
258
259  var seqRuns = getSequencingRunsForFlowCell(flowCell);
260  var runExists = null;
261  if (seqRuns.length > 0)
262  {
263    for (var seqNo = 0; seqNo < seqRuns.length; seqNo++)
264    {
265      var seqRun = seqRuns[seqNo];
266      html += '<tr valign="top" class="fc-info">';
267      html += '<td class="subprompt">'+seqRun.name+'</td>';
268      html += '<td class="input" colspan="2">';
269      html += formatDate(seqRun.SequencingStart, '(no start date)') + ' -- ' + formatDate(seqRun.SequencingEnd, '(no end date)');
270      if (seqRun.SequencingResult)
271      {
272        html += ': ' + seqRun.SequencingResult;
273      }
274      html += '</td>';
275      html += '<td class="help"></td>';
276      html += '</tr>';
277      if (seqRun.DataFilesFolder == info.RunID)
278      {
279        runExists = seqRun;
280      }
281    }
282  }
283  else
284  {
285    html += '<tr valign="top" class="fc-info">';
286    html += '<td class="subprompt"></td>';
287    html += '<td class="input" colspan="2">';
288    html += 'none';
289    html += '</td>';
290    html += '<td class="help"></td>';
291    html += '</tr>';
292   
293  }
294  Main.show('existing-sequencing-runs');
295  setInnerHTML('existing-sequencing-runs', html);
296  if (runExists != null)
297  {
298    throw 'This sequencing run has already been registered: ' + runExists.name;
299  }
300 
301}
302
303function getFlowCellInfoByBarcode(barcode)
304{
305  var url = '../FlowCell.servlet?ID=<%=ID%>&cmd=GetFlowCellByBarcode';
306  url += '&barcode='+encodeURIComponent(barcode);
307 
308  var request = Ajax.getXmlHttpRequest();
309  try
310  {
311    showLoadingAnimation('Checking flow cell id...');
312    request.open("GET", url, false);
313    request.send(null);
314  }
315  finally
316  {
317    hideLoadingAnimation();
318  }
319 
320  if (debug) Main.debug(request.responseText);
321  var response = JSON.parse(request.responseText);
322
323  if (response.status != 'ok')
324  {
325    throw response.message;
326  }
327
328  return response.flowCell;
329}
330
331function getSequencingRunsForFlowCell(flowCell)
332{
333  var url = '../SequencingRun.servlet?ID=<%=ID%>&cmd=GetSequencingRunsForFlowCell';
334  url += '&flowCell='+flowCell.id;
335 
336  var request = Ajax.getXmlHttpRequest();
337  try
338  {
339    showLoadingAnimation('Loading sequencing runs...');
340    request.open("GET", url, false);
341    request.send(null);
342  }
343  finally
344  {
345    hideLoadingAnimation();
346  }
347 
348  if (debug) Main.debug(request.responseText);
349  var response = JSON.parse(request.responseText);
350
351  if (response.status != 'ok')
352  {
353    throw response.message;
354  }
355
356  return response.sequencingRuns;
357}
358
359function formatDate(value, defaultValue)
360{
361  if (!value) return defaultValue || '';
362  if (value.length == 8)
363  {
364    // YYYYMMDD
365    value = value.substr(0, 4) + '-' + value.substr(4, 2) + '-' + value.substr(6, 2);
366  }
367  else if (value.length == 13)
368  {
369    // YYYYMMDD HHMM
370    value = value.substr(0, 4) + '-' + value.substr(4, 2) + '-' + value.substr(6, 2) + ' ' + value.substr(9, 2) + ':' + value.substr(11, 2);
371  }
372  return value;
373}
374
375
376function goRegister()
377{
378  if (!step1IsValid()) return;
379  var frm = document.forms['reggie'];
380
381  frm.sequencingOperator.disabled = true;
382  frm.sequencer.disabled = true;
383  frm.sequencingProtocol.disabled = true;
384  frm.comments.disabled = true;
385 
386  Main.hide('goregister');
387  Main.hide('gocancel');
388  Main.hide('gonext.message');
389 
390  var submitInfo = {};
391  submitInfo.flowCell = flowCell;
392  submitInfo.runParameters = runParameters;
393 
394  var sequencingRun = {};
395  sequencingRun.operator = frm.sequencingOperator.value;
396  sequencingRun.sequencer = parseInt(frm.sequencer.value);
397  sequencingRun.protocol = parseInt(frm.sequencingProtocol.value);
398  sequencingRun.comments = frm.comments.value;
399  submitInfo.sequencingRun = sequencingRun;
400 
401  if (debug) Main.debug(JSON.stringify(submitInfo));
402  var url = '../SequencingRun.servlet?ID=<%=ID%>&cmd=RegisterSequencingStarted';
403  var request = Ajax.getXmlHttpRequest();
404 
405  try
406  {
407    showLoadingAnimation('Performing registration...');
408    request.open("POST", url, false);
409    request.send(JSON.stringify(submitInfo));
410  }
411  finally
412  {
413    hideLoadingAnimation();
414  }
415 
416  if (debug) Main.debug(request.responseText);
417  var response = JSON.parse(request.responseText);
418 
419  if (response.messages && response.messages.length > 0)
420  {
421    var msg = '<ul>';
422    for (var i = 0; i < response.messages.length; i++)
423    {
424      var msgLine = response.messages[i];
425      if (msgLine.indexOf('[Warning]') >= 0)
426      {
427        msg += '<li class="warning">' + msgLine.replace('[Warning]', '');
428      }
429      else
430      {
431        msg += '<li>' + msgLine;
432      }
433    }
434    msg += '</ul>';
435    setInnerHTML('messages', msg);
436    Main.show('messages');
437  }
438 
439  if (response.status != 'ok')
440  {
441    Main.addClass(document.getElementById('messages'), 'failure');
442    setFatalError(response.message);
443    return false;
444  }
445
446  Main.show('gorestart');
447}
448
449</script>
450<style>
451
452.fc-info
453{
454  background-color: #F4F4F4;
455}
456
457.fc-info .subprompt
458{
459  font-weight: normal;
460  padding-left: 2em;
461  text-align: left;
462}
463
464.fc-info .input
465{
466  font-style: italic;
467}
468
469</style>
470</base:head>
471<base:body onload="init()">
472
473  <p:path><p:pathelement 
474    title="Reggie" href="<%="../index.jsp?ID="+ID%>" 
475    /><p:pathelement title="Register sequencing started" 
476    /></p:path>
477
478  <div class="content">
479  <%
480  if (sc.getActiveProjectId() == 0)
481  {
482    %>
483    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
484      No project has been selected. You may proceed with the registration but
485      created items will not be shared.
486    </div>
487    <%
488  }
489  %>
490
491  <form name="reggie" onsubmit="return false;">
492  <div id="step.1.section">
493  <table class="stepform">
494  <tr>
495    <td rowspan="3" class="stepno">1</td>
496    <td class="steptitle">Sequencing startup information</td>
497  </tr>
498  <tr>
499    <td class="stepfields">
500      <table style="border-collapse: collapse;">
501      <tr valign="top">
502        <td class="prompt">Operator</td>
503        <td class="input">
504          <input type="text" name="sequencingOperator" value="<%=HTML.encodeTags(user.getName()) %>" 
505            style="width: 90%;" maxlength="255" onkeypress="focusOnEnter(event, 'sequencer')">
506        </td>
507        <td class="status" id="sequencingOperator.status"></td>
508        <td class="help">
509          <span id="sequencingOperator.message" class="message" style="display: none;"></span>
510        </td>
511      </tr>
512      <tr valign="top">
513        <td class="prompt">Sequencing machine</td>
514        <td class="input"><select style="width:90%" name="sequencer" id="sequencer" 
515          onkeypress="focusOnEnter(event, 'sequencingProtocol')"></select></td>
516        <td class="status" id="sequencer.status"></td>
517        <td class="help"><span id="sequencer.message" class="message" style="display: none;"></span>
518          Select the HiSeq machine which is used for sequencing.
519        </td>
520      </tr>
521      <tr valign="top">
522        <td class="prompt">Protocol</td>
523        <td class="input"><select style="width:90%" name="sequencingProtocol" id="sequencingProtocol" 
524          onkeypress="focusOnEnter(event, 'fc-0.externalId')"></select></td>
525        <td class="status" id="sequencingProtocol.status"></td>
526        <td class="help"><span id="sequencingProtocol.message" class="message" style="display: none;"></span>
527          Select the protocol which was used in the clustering.
528        </td>
529      </tr>
530      <tr valign="baseline">
531        <td class="prompt">runParameters.xml</td>
532        <td class="input">
533          <input type="file" multiple class="required" name="runParametersXml" onchange="runParametersXmlFileOnChange(event)" style="width: 90%;">
534        </td>
535        <td class="status" id="runParametersXml.status"></td>
536        <td class="help" rowspan="8"><span id="runParametersXml.message" class="message" style="display:none;"></span>
537          Select the <b>runParameters.xml</b> file that was created by the HiSeq. Typically found in
538          <b>D:\Illumina\HiSeqTemp\&lt;run-folder&gt;</b> subfolder.
539        </td>
540      </tr>
541      <tr valign="top" class="fc-info" style="border-top: 1em solid transparent;">
542        <td class="subprompt">Experiment</td>
543        <td class="input" id="experimentName"></td>
544        <td class="status"></td>
545      </tr>
546      <tr valign="top" class="fc-info">
547        <td class="subprompt">RunID</td>
548        <td class="input" id="runId"></td>
549        <td class="status"></td>
550      </tr>
551      <tr valign="top" class="fc-info">
552        <td class="subprompt">Barcode</td>
553        <td class="input" id="externalId"></td>
554        <td class="status"></td>
555      </tr>
556      <tr valign="top" class="fc-info">
557        <td class="subprompt">HiSeq position</td>
558        <td class="input" id="position"></td>
559        <td class="status"></td>
560      </tr>
561      <tr valign="top" class="fc-info">
562        <td class="subprompt">Run number</td>
563        <td class="input" id="runNumber"></td>
564        <td class="status"></td>
565      </tr>
566      <tr valign="top" class="fc-info">
567        <td class="subprompt">Start date</td>
568        <td class="input" id="startDate"></td>
569        <td class="status"></td>
570      </tr>
571      <tr valign="top" class="fc-info">
572        <td class="subprompt">Sequencing cycles</td>
573        <td class="input" id="sequencingCycles"></td>
574        <td class="status"></td>
575      </tr>
576      <tbody id="existing-sequencing-runs" style="border-bottom: 1em solid transparent;">
577      <tr valign="top" class="fc-info">
578        <td class="subprompt"></td>
579        <td class="input"></td>
580        <td class="status"></td>
581        <td class="help"></td>
582      </tr>
583      </tbody>
584      <tr valign="top">
585        <td class="prompt">Comments</td>
586        <td class="input"><textarea rows="6" cols="50" style="width: 95%;" name="comments"></textarea></td>
587        <td class="status" id="comments.status"></td>
588        <td class="help"><span id="comments.message" class="message" style="display: none;"></span>
589          Comments about the sequencing startup.
590        </td>
591      </tr>
592      </table>
593    </td>
594  </tr>
595  </table>
596  </div>
597 
598 
599  <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>
600 
601  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
602 
603  <div id="messages" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
604 
605  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
606    <tr>
607      <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
608      <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)" style="display: none;"/></td>
609      <td><base:button id="goregister" title="Register" image="<%=home+"/images/import.png"%>" onclick="goRegister()" /></td>
610      <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
611      <td id="gonext.message" class="message"></td>
612    </tr>
613  </table>
614 
615  </form>
616  </div>
617 
618</base:body>
619</base:page>
620<%
621}
622finally
623{
624  if (dc != null) dc.close();
625}
626%>
Note: See TracBrowser for help on using the repository browser.