source: extensions/net.sf.basedb.reggie/branches/ticket-422/resources/libprep/mrna_protocol2.jsp @ 1817

Last change on this file since 1817 was 1817, checked in by Nicklas Nordborg, 7 years ago

References #425: Generate a lab protocol for RNA -> cDNA processing

Show comments in the lab protocol.

File size: 14.7 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.core.Extract"
9  import="net.sf.basedb.core.BioMaterial"
10  import="net.sf.basedb.core.MeasuredBioMaterial"
11  import="net.sf.basedb.core.BioMaterialEventSource"
12  import="net.sf.basedb.core.BioPlate"
13  import="net.sf.basedb.core.BioWell"
14  import="net.sf.basedb.core.PermissionDeniedException"
15  import="net.sf.basedb.core.ItemQuery"
16  import="net.sf.basedb.core.query.Restrictions"
17  import="net.sf.basedb.core.query.Hql"
18  import="net.sf.basedb.util.Values"
19  import="net.sf.basedb.util.formatter.WellCoordinateFormatter"
20  import="net.sf.basedb.util.extensions.Extension"
21  import="net.sf.basedb.clients.web.Base" 
22  import="net.sf.basedb.clients.web.util.HTML"
23  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
24  import="java.util.List"
25  import="java.util.ArrayList"
26%>
27<%
28final SessionControl sc = Base.getExistingSessionControl(request, true);
29final String ID = sc.getId();
30final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
31final String root = request.getContextPath();
32DbControl dc = null;
33try
34{
35  dc = sc.newDbControl();
36  final Extension reggie = ExtensionsControl.get(dc).getExtension("net.sf.basedb.reggie");
37  final User user = User.getById(dc, sc.getLoggedInUserId());
38  int mRnaPlateId = Values.getInt(request.getParameter("bioplate"));
39  final Float stratageneConc = Values.getFloat(request.getParameter("stratageneConc"), null);
40  String poolSchema = request.getParameter("poolSchema");
41 
42  BioPlate plate = BioPlate.getById(dc, mRnaPlateId);
43  int columns = plate.getColumns();
44  int rows = plate.getRows();
45  String view = Values.getString(request.getParameter("view"), "list");
46%>
47<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
48<html>
49<head>
50  <title>Lab tracking protocol for mRNA and cDNA preparation</title>
51  <link rel="SHORTCUT ICON" href="<%=home%>/images/pipette.png">
52  <link rel="stylesheet" type="text/css" href="<%=home %>/css/printable.css">
53  <link rel="stylesheet" type="text/css" href="<%=home %>/css/plate.css">
54  <script language="JavaScript" src="<%=root%>/include/scripts/main.js" type="text/javascript" charset="UTF-8"></script>
55  <script language="JavaScript" src="<%=root%>/include/scripts/ajax.js" type="text/javascript" charset="UTF-8"></script>
56  <script language="JavaScript" src="<%=home %>/reggie.js" type="text/javascript" charset="UTF-8"></script>
57  <script language="JavaScript" src="pools.js" type="text/javascript" charset="UTF-8"></script>
58  <script language="JavaScript" src="plate.js" type="text/javascript" charset="UTF-8"></script>
59 
60  <script language="JavaScript">
61  var debug = true;
62  var currentStep = 1;
63 
64  function init()
65  {
66    // Load mRNA and related info from the selected bioplate
67    var request = Ajax.getXmlHttpRequest();
68    try
69    {
70      showLoadingAnimation('Loading mRNA bioplate information...');
71      var url = '../MRna.servlet?ID=<%=ID%>&cmd=GetMRnaInfoForPlate&bioplate=<%=mRnaPlateId%>';   
72      request.open("GET", url, false); 
73      request.send(null);
74    }
75    finally
76    {
77      hideLoadingAnimation();
78    }
79   
80    if (debug) Main.debug(request.responseText);
81    var response = JSON.parse(request.responseText);
82    if (response.status != 'ok')
83    {
84      setFatalError(response.message);
85      return false;
86    }
87   
88    var list = response.mrna;
89    // Pre-process the return mRNA items
90    for (var i = 0; i < list.length; i++)
91    {
92      checkAndPreProcessMRna(list[i]);
93    }
94   
95    <%
96    if (view.equals("list"))
97    {
98      %>
99      viewAsList(list);
100      <%
101    }
102    else
103    {
104      %>
105      viewAsPlate(list)
106      <%
107    }
108    %>
109  }
110 
111  /**
112    Get the plate coordinate string for a well, optionally including the plate
113    name or not.
114  */
115  function getPlateCoordinate(well, includePlateName)
116  {
117    var c = '';
118    if (well)
119    {
120      if (includePlateName) c += well.bioPlate.name;
121      c += ' ' + WELL_ALPHA[well.row] + (well.column+1);
122    }
123    return c;
124  }
125 
126  /**
127    Check the mRNA and RNA items for problems and calculate derived
128    information such as volume and water, qc/stratagene flags.
129  */
130  function checkAndPreProcessMRna(mrna)
131  {
132    var rna = mrna.rna;
133    // Set the 'stratagene' flag
134    rna.stratagene = rna.name == STRATAGENE_NAME;
135    rna.external = rna.name == EXTERNAL_RNA_NAME;
136   
137    // Set the 'QC' flag if more than 1.2µg is used
138    rna.qc = rna.usedQuantity > 1.2;
139   
140    <%
141    if (stratageneConc != null && stratageneConc > 0)
142    {
143      %>
144      if (rna.stratagene) rna.NDConc = <%=stratageneConc%>;
145      <%
146    }
147    %>
148   
149    // Calculate volume to use and water to add based on concentration
150    if (rna.NDConc && rna.usedQuantity)
151    {
152      rna.volume = Math.ceil(10000*rna.usedQuantity/rna.NDConc) / 10;
153      rna.water = 50-rna.volume;
154    }
155   
156    // check for some issues that may indicate problems
157    var remarks = [];
158    if (rna.qc) remarks[remarks.length] = 'QC';
159    if (!rna.stratagene && !rna.external)
160    {
161      if (!rna.bioWell)
162      {
163        remarks[remarks.length] = 'No location';
164      }
165      if (!rna.remainingQuantity)
166      {
167        remarks[remarks.length] = 'No quantity';
168      }
169      else if (rna.remainingQuantity < (rna.qc ? 1.22 : 1.1))
170      {
171        remarks[remarks.length] = 'Low quantity';
172      }
173      if (!rna.NDConc)
174      {
175        remarks[remarks.length] = 'No NDConc value';
176      }
177      if (mrna.comment) remarks[remarks.length] = mrna.comment;
178    }
179    else if (rna.stratagene)
180    {
181      if (!rna.NDConc && rna.usedQuantity)
182      {
183        remarks[remarks.length] = 'Use ' + Numbers.formatNumber(rna.usedQuantity, 2) + ' µg RNA';
184      }
185    }
186    else if (rna.external)
187    {
188      remarks[remarks.length] = 'Use ' + Numbers.formatNumber(rna.usedQuantity, 2) + ' µg RNA';
189    }
190    rna.remarks = remarks;
191  }
192 
193  function viewAsList(list)
194  {
195    for (var i = 0; i < list.length; i++)
196    {
197      var mrna = list[i];
198      var rna = mrna.rna;
199     
200      var idSuffix = mrna.bioWell.column + '.' + mrna.bioWell.row;
201      Main.removeClass(document.getElementById('row.'+idSuffix), 'empty');
202      setInnerHTML('rna.'+idSuffix, rna.name);
203      setInnerHTML('box.'+idSuffix, getPlateCoordinate(rna.bioWell, true));
204      setInnerHTML('ndconc.'+idSuffix, Numbers.formatNumber(rna.NDConc, 2));
205      setInnerHTML('remain.'+idSuffix, Numbers.formatNumber(rna.remainingQuantity, 2));
206      setInnerHTML('volume.'+idSuffix, Numbers.formatNumber(rna.volume, 1));
207      setInnerHTML('water.'+idSuffix, Numbers.formatNumber(rna.water, 1));
208      setInnerHTML('remarks.'+idSuffix, rna.remarks.join('; '));
209    }
210  }
211 
212 
213  function viewAsPlate(list)
214  {
215    var schema = PoolSchema.getById('<%=poolSchema%>');
216    Plate.init(<%=rows%>, <%=columns%>, schema, WellPainter);
217   
218    for (var i = 0; i < list.length; i++)
219    {
220      var mrna = list[i];
221      var well = mrna.bioWell;
222      Plate.getWell(well.row, well.column).setExtract(mrna);
223    }
224
225    Plate.paint(Plate.getWells());
226    PoolSchema.buildPoolTableRow(schema, <%=columns%>);
227    Main.show('plateview');
228  }
229
230  var WellPainter = function()
231  {
232    var painter = {};
233   
234    painter.getClassNameForWell = function(well)
235    {
236      var cls = '';
237      var mrna = well.extract;
238      if (mrna)
239      {
240        if (mrna.rna.qc) cls += ' qc';
241      }
242      return cls;
243    }
244   
245    painter.getWellText = function(well)
246    {
247      var text = '';
248      var mrna = well.extract;
249      if (mrna)
250      {
251        var rna = mrna.rna;
252        text += '<div class="rna">'+rna.name+'</div>';
253        text += '<div class="box">'+getPlateCoordinate(rna.bioWell, true)+'</div>';
254        text += '<div class="remain">'+Numbers.formatNumber(rna.remainingQuantity, 2, 'µg')+'</div>';
255        text += '<div class="ndconc">'+Numbers.formatNumber(rna.NDConc, 2, 'ng/µl') + '</div>';
256
257        if (rna.volume && rna.water)
258        {
259          text += '<div><span class="volume">'+Numbers.formatNumber(rna.volume, 1)+'</span>';
260          text += ' + <span class="water">'+Numbers.formatNumber(rna.water, 1)+'</span>µl</div>';
261        }
262        text += '<div class="remarks">'+ rna.remarks.join('; ') + '</div>';
263      }
264      return text;
265    }
266
267    return painter;
268  }();
269  </script>
270  <style>
271  table.protocolheader
272  {
273    width: 100%;
274  }
275
276  table.protocolheader > tbody > tr
277  {
278    height: 1.25em;
279  }
280
281  table.protocolheader > tbody > tr > th
282  {
283    width: 50%;
284    text-align: left;
285    font-size: 1em;
286  }
287 
288  #listview
289  {
290    width: 100%;
291    font-size: 85%;
292    border-collapse: collapse;
293    border: 1px solid #000000;
294  }
295 
296  #listview tr.evencol
297  {
298    background-color: #E8E8E8;
299  }
300 
301  #listview thead
302  {
303    border: 1px solid #000000;
304    background-color: #E8E8E8;
305  }
306 
307  #listview tbody
308  {
309    page-break-inside: avoid;
310    border-top: 1px solid #000000;
311    border-bottom: 1px solid #000000;
312  }
313 
314  #listview th
315  {
316    border-left: 1px solid #000000;
317  }
318 
319  #listview td
320  {
321    border-left: 1px solid #000000;
322    border-top: 1px dotted #666666;
323    vertical-align: middle;
324  }
325 
326  #listview .col-num
327  {
328    width: 1.75em;
329    text-align: center;
330    font-size: 125%;
331    font-weight: bold;
332    vertical-align: top;
333  }
334 
335  #listview .rna
336  {
337    width: 9em;
338    text-align: center;
339  }
340 
341  #listview .empty .rna
342  {
343    font-style: italic;
344    color: #666666;
345    text-align: center;
346  }
347 
348  #listview .box
349  {
350    width: 8em;
351    text-align: center;
352  }
353  #listview .workplate
354  {
355    width: 5em;
356    text-align: center;
357  }
358  #listview .ndconc
359  {
360    width: 4.5em;
361    padding-right: 0.5em;
362    text-align: right;
363  }
364  #listview .remain
365  {
366    width: 4.5em;
367    padding-right: 0.5em;
368    text-align: right;
369  }
370  #listview .volume
371  {
372    width: 3.5em;
373    padding-right: 0.5em;
374    text-align: right;
375    color: #C80000;
376  }
377  #listview .water
378  {
379    width: 3.5em;
380    padding-right: 0.5em;
381    text-align: right;
382    color: #0000C8;
383  }
384  #listview .remarks
385  {
386    vertical-align: top;
387    padding-left: 0.25em;
388  }
389 
390  /* Divide the 12 wells across the full page */
391  #plateview .well
392  {
393    width: 8.2%;
394    max-width: 8.2%;
395    min-width: 8.2%;
396  }
397   
398  #plateview .rowheader
399  {
400    width: 2em;
401  }
402 
403  #plateview .rna
404  {
405    font-weight: bold;
406  }
407  #plateview .ndconc
408  {
409    display: none;
410  }
411  #plateview .remain
412  {
413    display: none;
414  }
415  #plateview .volume
416  {
417    color: #C80000;
418  }
419  #plateview .water
420  {
421    color: #0000C8;
422  }
423  #plateview .remarks
424  {
425    color: #C80000;
426    font-style: italic;
427  }
428  #plateview .qc
429  {
430    background-image: url('../images/mrnaqc.png');
431    background-position: 95% 5%;
432    background-repeat: no-repeat;
433  }
434  </style>
435</head>
436<body onload="init()">
437  <div class="paper <%=view.equals("list") ? "" : "landscape"%>">
438  <div class="noprint fullwidth" style="border-bottom: 1px dashed #A0A0A0; padding-left: 1em; padding-bottom: 1em;">
439    <span class="button" onclick="window.print()" style="float: left; margin-right: 1em;">
440      <img src="../images/print.png">Print&hellip;
441    </span>
442    <b>Note!</b> 
443    <%
444    if (view.equals("list"))
445    {
446      %>
447      For better printing reduce margins to about <i>5mm</i> and set page orientation
448      to <i>portrait</i>. To fit everything on a single page, scale down to <i>60-70%</i>.
449      <%
450    }
451    else
452    {
453      %>
454      For better printing reduce margins to about <i>5mm</i> and set page orientation
455      to <i>landscape</i>. The recommended scale is <i>100%</i>.
456      <%
457    }
458    %>
459    <br clear="all">
460  </div>
461 
462  <h1>Lab tracking protocol for mRNA and cDNA preparation <span class="reggie">Reggie <%=reggie.getAbout().getVersion() %></span></h1>
463
464  <table style="width: 100%; border: 0px;" class="protocolheader">
465  <tr valign="top">
466    <th style="width: 30%;">Work plate: <%=HTML.encodeTags(plate.getName())%></th>
467    <th style="width: 20%; text-align: right;">Comments:&nbsp;</th>
468    <td rowspan="3"><%=HTML.encodeTags(plate.getDescription()) %></td>
469  </tr>
470  <tr>
471    <th style="width: 50%;" colspan="2">Date+operator for mRNA:</th>
472  </tr>
473  <tr>
474    <th style="width: 50%;" colspan="2">Date+operator for cDNA:</th>
475  </tr>
476  </table>
477
478  <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>
479  <div class="messagecontainer error" id="errorMessage" style="display: none;"></div>
480  <%
481  if (view.equals("list"))
482  {
483    %>
484    <table style="width: 100%;" id="listview">
485    <thead>
486      <tr class="toprow">
487        <th></th>
488        <th class="rna"></th>
489        <th class="box">Storage</th>
490        <th class="workplate">Work</th>
491        <th>NDConc</th>
492        <th>Remain</th>
493        <th colspan="2">Volume</th>
494        <th></th>
495      </tr>
496      <tr>
497        <th></th>
498        <th class="rna">RNA</th>
499        <th class="box">box</th>
500        <th class="workplate">plate</th>
501        <th>(ng/µl)</th>
502        <th>(µg)</th>
503        <th>(µl)</th>
504        <th>H<sub>2</sub>O</th>
505        <th>Remarks</th>
506      </tr>
507    </thead>
508    <%
509    WellCoordinateFormatter rowF = new WellCoordinateFormatter(true);
510    WellCoordinateFormatter colF = new WellCoordinateFormatter(false);
511    for (int c = 0; c < columns; ++c)
512    {
513      String rowClass = c % 2 == 0 ? "evencol" : "oddcol";
514      %>
515      <tbody>
516      <%
517      for (int r = 0; r < rows; ++r)
518      {
519        String idSuffix = c + "." + r;
520        %>
521        <tr class="<%=rowClass%> empty" id="row.<%=idSuffix%>">
522          <%
523          if (r == 0)
524          {
525            %>
526            <td class="col-num" rowspan="<%=rows%>"><%=c+1%></td>
527            <%
528          }
529          %>
530          <td class="rna" id="rna.<%=idSuffix%>">empty</td>
531          <td class="box" id="box.<%=idSuffix%>"></td>
532          <td class="workplate"><%=rowF.format(r)+colF.format(c)%></td>
533          <td class="ndconc" id="ndconc.<%=idSuffix%>"></td>
534          <td class="remain" id="remain.<%=idSuffix%>"></td>
535          <td class="volume" id="volume.<%=idSuffix%>"></td>
536          <td class="water" id="water.<%=idSuffix%>"></td>
537          <td class="remarks" id="remarks.<%=idSuffix%>"></td>
538        </tr>
539        <%
540      }
541      %>
542      </tbody>
543      <%
544    }
545    %>
546    </table>
547    <%
548  }
549  else
550  {
551    %>
552    <table class="plate" style="margin: 0em 0 0 0; width: 100%; display: none;" id="plateview">
553    <%
554    WellCoordinateFormatter rowF = new WellCoordinateFormatter(true);
555    WellCoordinateFormatter colF = new WellCoordinateFormatter(false);
556    %>
557    <tr class="header">
558      <th></th>
559      <%
560      for (int c = 0; c < columns; ++c)
561      {
562        %>
563        <th id="col.<%=c%>"><%=colF.format(c)%></th>
564        <%
565      }
566      %>
567    </tr>
568    <tbody>
569    <%
570    for (int r = 0; r < rows; ++r)
571    {
572      String row = rowF.format(r);
573      %>
574      <tr class="row-<%=r%>">
575        <th id="row.<%=r%>" class="rowheader"><%=row%></th>
576        <%
577        for (int c = 0; c < columns; ++c)
578        {
579          %>
580          <td class="well col-<%=c%>" id="well.<%=r%>.<%=c%>"></td>
581          <%
582        }
583        %>
584      </tr>
585      <%
586    }
587    %>
588    </tbody>
589    <tr id="pool-row">
590      <th colspan="13">&nbsp;</th>
591    </tr>
592    </table>
593    <%
594  }
595  %>
596  </div>
597</body>
598</html>
599<%
600}
601finally
602{
603  if (dc != null) dc.close();
604}
605%>
Note: See TracBrowser for help on using the repository browser.