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

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

References #425, #457, #479. Format comment text with line breaks.

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