source: extensions/net.sf.basedb.reggie/trunk/resources/libprep/mrna_protocol2.jsp @ 1929

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

References #424, #425, #457, #479. Re-designed protocols to make the header section a bit more compact when the comment text is large. Display a warning when the remaining RNA quanitity is below 1.5 times the required amount (eg. 1.1µg or 1.22µg).

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