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

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

References #540: Make sure Reggie works with BASE 3.3

Include main-2.js in protocol generation scripts or they will not work properly.

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