View Javadoc

1   /*
2    *                Doelan development code
3    *
4    * This code may be freely distributed and modified under the
5    * terms of the GNU General Public Licence.  This should
6    * be distributed with the code. If you do not have a copy,
7    * see:
8    *
9    *      http://www.gnu.org/copyleft/gpl.txt
10   *
11   * Copyright (c) 2004-2005 ENS Microarray Platform
12   * Copyright for this code is held jointly by the individual
13   * authors.  These should be listed in @author doc comments.
14   *
15   * For more information on the Doelan project and its aims,
16   * or to join the Doelan mailing list, visit the home page
17   * at:
18   *
19   *      http://www.transcriptome.ens.fr/doelan
20   */
21  
22  package fr.ens.transcriptome.doelan.algorithms;
23  
24  import java.text.DateFormat;
25  import java.text.NumberFormat;
26  import java.util.Date;
27  import java.util.Locale;
28  
29  import fr.ens.transcriptome.doelan.Defaults;
30  import fr.ens.transcriptome.doelan.DoelanRegistery;
31  import fr.ens.transcriptome.doelan.data.DoelanDataUtils;
32  import fr.ens.transcriptome.doelan.data.QualityGlobalTestResult;
33  import fr.ens.transcriptome.doelan.data.QualityTestResult;
34  import fr.ens.transcriptome.doelan.data.QualityUnitTestResult;
35  import fr.ens.transcriptome.doelan.data.TestSuiteResult;
36  import fr.ens.transcriptome.nividic.om.BioAssay;
37  import fr.ens.transcriptome.nividic.om.BioAssayUtils;
38  import fr.ens.transcriptome.nividic.om.GenepixArrayList;
39  import fr.ens.transcriptome.nividic.om.GenepixResults;
40  import fr.ens.transcriptome.nividic.platform.PlatformException;
41  import fr.ens.transcriptome.nividic.platform.module.AboutModule;
42  import fr.ens.transcriptome.nividic.platform.module.Module;
43  import fr.ens.transcriptome.nividic.platform.module.ModuleDescription;
44  import fr.ens.transcriptome.nividic.platform.workflow.Algorithm;
45  import fr.ens.transcriptome.nividic.platform.workflow.Container;
46  import fr.ens.transcriptome.nividic.util.NividicUtils;
47  import fr.ens.transcriptome.nividic.util.parameter.Parameter;
48  import fr.ens.transcriptome.nividic.util.parameter.ParameterException;
49  import fr.ens.transcriptome.nividic.util.parameter.Parameters;
50  
51  /***
52   * This class define an algorithm to show test suite report.
53   * @author Laurent Jourdren
54   */
55  public class DoelanGenerateReport extends Algorithm implements Module {
56  
57    private boolean galResult;
58    private String galResultMessage;
59  
60    //
61    // Other methods
62    //
63  
64    /***
65     * Get the description of the module.
66     * @return The description of the module
67     */
68    public AboutModule aboutModule() {
69      ModuleDescription md = null;
70      try {
71        md = new ModuleDescription("DoelanGenerateReport",
72            "Show report of a test suite");
73        md.setStability(AboutModule.STATE_STABLE);
74      } catch (PlatformException e) {
75        getLogger().error("Unable to create the module description");
76      }
77      return md;
78    }
79  
80    /***
81     * Set the parameters of the element.
82     * @return The defaults parameters to set.
83     */
84    protected Parameters defineParameters() {
85      return null;
86    }
87  
88    /***
89     * This method contains all the code to manipulate the container <b>c </b> in
90     * this element.
91     * @param c The container to be manipulated
92     * @param parameters Parameters of the elements
93     * @throws PlatformException if an error occurs while executing the test.
94     */
95    protected void doIt(final Container c, final Parameters parameters)
96        throws PlatformException {
97  
98      StringBuffer sb = new StringBuffer();
99  
100     // Get GPR data
101     BioAssay gpr = DoelanDataUtils.getBioAssay(c);
102 
103     // Get test suitel result
104     TestSuiteResult testSuiteResult = DoelanDataUtils.getTestSuiteResult(c);
105 
106     // Get GAL data
107     BioAssay gal = DoelanDataUtils.getArrayList(c);
108 
109     // Get the test results
110     QualityTestResult[] results = DoelanDataUtils
111         .getOrderedQualityTestResults(c);
112 
113     // Get the new array list
114     BioAssay newGal = testSuiteResult.getNewArrayList();
115 
116     if (gal != null) {
117 
118       this.galResult = newGal != null;
119 
120       final String msg;
121       if (newGal == null)
122         msg = "No array list data.";
123       else
124         msg = "The output array contains " + newGal.size()
125             + " features of the " + gal.size()
126             + " features of the original file.";
127 
128       this.galResultMessage = msg;
129     }
130 
131     sb.append(header());
132     sb.append(writeInfo(testSuiteResult.getChipTypeName(), testSuiteResult
133         .getTestSuiteName(), gal, gpr, testSuiteResult.getDescription()));
134 
135     sb.append(writeSummary(results, testSuiteResult, gpr));
136 
137     if (gal != null)
138       sb.append(writeEmptySpot(gal));
139     sb.append(writeTests(results));
140 
141     if (testSuiteResult.getArrayPlot() != null)
142       sb.append(writeArrayPlot());
143 
144     sb.append(footer());
145 
146     testSuiteResult.setHtmlReport(sb.toString());
147   }
148 
149   private String writeArrayPlot() {
150 
151     StringBuffer sb = new StringBuffer();
152 
153     sb
154         .append("<h2>Visualisation of removed features in ouput array list</h2>\n<hr>\n");
155 
156     sb.append("<img src=\"arrayplot.jpeg\" alt=\"arraplot image\"><br>\n");
157 
158     sb.append("<b><u>Legend:</u></b>");
159     sb
160         .append("<li>Circle spot in <font color=\"#C0C0C0\">Light gray</font>: Empty feature"
161             + " or absent feature in the original Gal file.</li>\n");
162     sb.append("<li>Spot in <font color=\"green\">Green</font>: Feature"
163         + " accepted in the new Gal file.</li>\n");
164     sb.append("<li>Spot in <font color=\"red\">Red</font>: Feature rejected"
165         + " in the new Gal file.</li>\n");
166     sb.append("<li>Spot in <font color=\"#C0C0C0\">White</font>: Feature "
167         + "fail to one or more test but not rejected"
168         + " in the new Gal file.</li>\n");
169     sb.append("</ul>");
170 
171     return sb.toString();
172 
173   }
174 
175   private String writeTests(final QualityTestResult[] results) {
176     StringBuffer sb = new StringBuffer();
177 
178     sb.append("<h2>Tests</h2>\n<hr>\n");
179 
180     for (int i = 0; i < results.length; i++) {
181 
182       final QualityTestResult r = results[i];
183 
184       sb.append("<a name=\"");
185       sb.append(r.getTestId());
186       sb.append("\" id=\"test_");
187       sb.append(i);
188       sb.append("\"></a>");
189       sb.append("<h3>Test: ");
190       sb.append(r.getTestId());
191       sb.append("</h3>\n");
192       sb.append("<ul>\n<li><b>Description:</b> ");
193       sb.append(r.getTestDescription());
194       sb.append("</li>\n");
195       sb.append("<li><b>Test module:</b> ");
196       sb.append(r.getTestType());
197       sb.append("</li>\n");
198 
199       sb.append("<li><b>Parameters:</b> \n");
200       // sb.append("<table border=\"2\">\n");
201       // sb.append("<tr><th>Name</th><th>Value</th><th>Unit</th></tr>");
202       sb.append("<ul>\n");
203 
204       String[] pNames = r.getParameters().getParametersNames();
205       for (int j = 0; j < pNames.length; j++) {
206         Parameter p = r.getParameters().getParameter(pNames[j]);
207         // sb.append("<tr><td>");
208         sb.append("<li>");
209 
210         if (p.getLongName() != null)
211           sb.append(p.getLongName());
212         else
213           sb.append(p.getName());
214 
215         sb.append(": <i>");
216 
217         try {
218           if (p.getType() == Parameter.DATATYPE_INTEGER)
219             sb.append(p.getIntValue());
220           else if (p.getType() == Parameter.DATATYPE_DOUBLE)
221             sb.append(p.getDoubleValue());
222           else if (p.getType() == Parameter.DATATYPE_BOOLEAN)
223             sb.append(p.getBooleanValue());
224           else if (p.getType() == Parameter.DATATYPE_STRING)
225             sb.append(p.getStringValue());
226           else if (p.getType() == Parameter.DATATYPE_YESNO) {
227             if (p.getBooleanValue())
228               sb.append("Yes");
229             else
230               sb.append("No");
231           }
232         } catch (ParameterException e) {
233           NividicUtils.nop();
234         }
235 
236         // sb.append("</td><td>");
237 
238         if (p.getUnit() != null) {
239           sb.append(' ');
240           sb.append(p.getUnit());
241         }
242 
243         // sb.append("</td></tr>");
244         sb.append("</i></li>\n");
245       }
246 
247       // sb.append("</table><br></li>\n");
248       sb.append("</ul>\n");
249 
250       if (r.getImage() != null) {
251         sb.append("<li><b>Result graph:</b><br><br>");
252         sb.append("<img src=\"");
253         sb.append(r.getTestId());
254         sb.append(".jpeg");
255         sb.append("\" alt=\"result graph image\"><br><br></li>\n");
256       }
257 
258       if (r instanceof QualityUnitTestResult) {
259         // unit result
260         QualityUnitTestResult unitResultTest = (QualityUnitTestResult) r;
261 
262         if (unitResultTest.isGlobalResult()) {
263           sb.append("<li><b>Result:</b> ");
264           if (unitResultTest.getResult())
265             sb.append("<b class=\"pass\">Pass");
266           else
267             sb.append("<b class=\"fail\">Fail");
268 
269           sb.append("</b></li>\n");
270         } else {
271 
272           sb.append("<li><b>Result 635 channel : </b>");
273           if (unitResultTest.getResultChannel635().isPass())
274             sb.append("<b class=\"pass\">Pass");
275           else
276             sb.append("<b class=\"fail\">Fail");
277           sb.append("</b></li>\n");
278 
279           sb.append("<li><b>Result 532 channel:</b> ");
280           if (unitResultTest.getResultChannel532().isPass())
281             sb.append("<b class=\"pass\">Pass");
282           else
283             sb.append("<b class=\"fail\">Fail");
284           sb.append("</b></li>\n");
285 
286         }
287       } else {
288         // Global result
289         sb.append("<li><b>Result:</b> ");
290         if (r.getResult())
291           sb.append("<b class=\"pass\">Pass");
292         else
293           sb.append("<b class=\"fail\">Fail");
294 
295         sb.append("</b></li>\n");
296       }
297 
298       sb.append("<li><b>Comment:</b> <br>");
299 
300       sb.append(r.getMessage());
301       sb.append("</li>\n");
302       sb.append("</ul>\n");
303 
304     }
305 
306     return sb.toString();
307   }
308 
309   private static String getHTMLSign(final String sign) {
310 
311     String result = null;
312 
313     if (sign == null)
314       return result;
315 
316     if ("<".equals(sign))
317       result = "&lt;";
318     else if ("<=".equals(sign))
319       result = "&lt;=";
320     else if (">".equals(sign))
321       result = "&gt;";
322     else if (">=".equals(sign))
323       result = "&gt;=";
324 
325     return result;
326   }
327 
328   private String writeInfo(final String chipTypeName,
329       final String testSuiteName, final BioAssay gal, final BioAssay gpr,
330       final String arrayDescription) {
331 
332     StringBuffer sb = new StringBuffer();
333 
334     DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL,
335         DateFormat.MEDIUM, Locale.UK);
336 
337     GenepixResults gResult = new GenepixResults(gpr);
338     GenepixArrayList gArrayList = null;
339 
340     if (gal != null)
341       gArrayList = new GenepixArrayList(gal);
342 
343     sb.append("<a href=\"");
344     sb.append(DoelanRegistery.getAppURL());
345     sb.append("\"><img src=\"logo.jpeg\" alt=\"");
346     sb.append(DoelanRegistery.getAppName());
347     sb.append(" logo\"></a>");
348     sb.append("<h1 align=\"center\"><u>");
349     // sb.append(DoelanRegistery.getAppName());
350     sb.append(" Quality Test report");
351     sb.append("</u></h1>\n");
352 
353     sb.append("<h2><b>Chip type: </b><i>");
354     sb.append(chipTypeName);
355     sb.append("</i><br><b>Test suite: </b><i>");
356     sb.append(testSuiteName);
357     sb.append("</i></h2>\n<br>");
358 
359     sb.append("<b>");
360     sb.append(DoelanRegistery.getAppName());
361     sb.append(" version: </b>");
362     sb.append(DoelanRegistery.getAppVersion());
363     Date compileDate = DoelanRegistery.getAppCompileDate();
364     if (compileDate != null) {
365       sb.append(" (compiled on ");
366       sb.append(df.format(compileDate));
367       sb.append(")");
368     }
369 
370     sb.append("<br><b>Report date: </b>");
371     sb.append(df.format(new Date(System.currentTimeMillis())));
372     sb.append("<br>");
373 
374     Date gprDate = gResult.getDateTime();
375     if (gprDate != null) {
376       sb.append("<b>Array scanned on:</b> ");
377       sb.append(df.format(gprDate));
378       sb.append("<br>\n");
379     }
380     String scannedBy = gResult.getScanner();
381     if (scannedBy != null) {
382       sb.append("<b>Array scanned by:</b> ");
383       sb.append(scannedBy);
384       sb.append("<br>\n");
385     }
386 
387     if (gal != null) {
388       sb.append("<b>Array name:</b> ");
389       String arrayName = gArrayList.getArrayName();
390       if (arrayName != null)
391         sb.append(scannedBy);
392       else
393         sb.append("unknown");
394       sb.append("<br>\n");
395 
396       sb.append("<b>Array revision:</b> ");
397       String revision = gArrayList.getArrayRevision();
398       if (revision != null)
399         sb.append(revision);
400       else
401         sb.append("unknown");
402       sb.append("<br>\n");
403 
404       sb.append("<b>Array manufacturer:</b> ");
405       String manufacturer = gArrayList.getManufacturer();
406       if (manufacturer != null)
407         sb.append(manufacturer);
408       else
409         sb.append("unknown");
410       sb.append("<br>\n");
411     }
412 
413     if (arrayDescription != null) {
414       String desc = arrayDescription.trim();
415       if (!"".equals(desc)) {
416 
417         sb.append("<b>Array description:</b> ");
418         sb.append(desc);
419         sb.append("<br>\n");
420       }
421     }
422 
423     return sb.toString();
424   }
425 
426   private String writeSummary(final QualityTestResult[] results,
427       final TestSuiteResult testSuiteResult, final BioAssay gpr) {
428 
429     StringBuffer sb = new StringBuffer();
430 
431     sb.append("<h2>Summary</h2>\n<hr>\n");
432 
433     sb.append("<table border=\"1\">\n<tr>"
434         + "<th>Test name</th><th>Description</th>"
435         + "<th>635</th><th>532</th><th>Threshold</th>"
436         + "<th>Result 635</th><th>Result 532</th><th>Global Result</th></tr>");
437 
438     NumberFormat nf = NumberFormat.getNumberInstance(Locale.UK);
439     nf.setMaximumFractionDigits(2);
440     nf.setMinimumFractionDigits(2);
441 
442     for (int i = 0; i < results.length; i++) {
443 
444       final QualityTestResult r = results[i];
445 
446       sb.append("<tr><td><a href=\"#test_");
447       sb.append(i);
448       sb.append("\">");
449       sb.append(r.getTestId());
450       sb.append("</a></td>");
451 
452       sb.append("<td>");
453       sb.append(r.getTestDescription());
454       sb.append("</td>");
455 
456       if (r instanceof QualityUnitTestResult) {
457 
458         QualityUnitTestResult unitResult = (QualityUnitTestResult) r;
459 
460         if (unitResult.isGlobalResult()) {
461           sb.append("<td colspan=\"2\">");
462           sb.append(nf.format(unitResult.getResultAllChannels().getValue()));
463           sb.append(" ");
464           sb.append(unitResult.getResultAllChannels().getUnit());
465           sb.append("</td>");
466 
467           sb.append("<td>");
468           sb.append(getHTMLSign(unitResult.getResultAllChannels()
469               .getThresholdEqualityType()));
470           sb.append(" ");
471           sb
472               .append(nf.format(unitResult.getResultAllChannels()
473                   .getThreshold()));
474           sb.append(" ");
475           sb.append(unitResult.getResultAllChannels().getUnit());
476           sb.append("</td>");
477 
478           sb.append("<td colspan=\"2\"></td>");
479 
480         } else {
481           sb.append("<td>");
482           sb.append(nf.format(unitResult.getResultChannel635().getValue()));
483           sb.append(" ");
484           sb.append(unitResult.getResultChannel635().getUnit());
485           sb.append("</td>");
486 
487           sb.append("<td>");
488           sb.append(nf.format(unitResult.getResultChannel532().getValue()));
489           sb.append(" ");
490           sb.append(unitResult.getResultChannel532().getUnit());
491           sb.append("</td>");
492 
493           sb.append("<td>");
494 
495           sb.append(getHTMLSign(unitResult.getResultChannel532()
496               .getThresholdEqualityType()));
497           sb.append(" ");
498           sb.append(nf.format(unitResult.getResultChannel635().getThreshold()));
499           sb.append(" ");
500           sb.append(unitResult.getResultChannel635().getUnit());
501           sb.append("</td>");
502 
503           if (unitResult.getResultChannel635().isPass())
504             sb.append("<td class=\"pass\">Pass");
505           else
506             sb.append("<td class=\"fail\">Fail");
507           sb.append("</td>");
508 
509           sb.append("");
510           if (unitResult.getResultChannel532().isPass())
511             sb.append("<td class=\"pass\">Pass");
512           else
513             sb.append("<td class=\"fail\">Fail");
514           sb.append("</td>");
515 
516         }
517       } else {
518 
519         QualityGlobalTestResult globalResult = (QualityGlobalTestResult) r;
520 
521         sb.append("<td colspan=\"2\">");
522         sb.append(nf.format(globalResult.getValue()));
523         sb.append(" ");
524         sb.append(globalResult.getUnit());
525         sb.append("</td>");
526 
527         sb.append("<td>");
528         sb.append(getHTMLSign(globalResult.getThresholdEqualityType()));
529         sb.append(" ");
530         sb.append(nf.format(globalResult.getThreshold()));
531         sb.append(" ");
532         sb.append(globalResult.getUnit());
533         sb.append("</td>");
534 
535         sb.append("<td colspan=\"2\"></td>");
536       }
537 
538       sb.append("");
539       if (r.getResult())
540         sb.append("<td class=\"pass\">Pass");
541       else
542         sb.append("<td class=\"fail\">Fail");
543       sb.append("</td></tr>\n");
544 
545     }
546     sb.append("</table><br>");
547 
548     sb.append("<b>Test suite result:</b> ");
549     if (testSuiteResult.getResult())
550       sb.append("<b class=\"pass\">Pass</b><br><br>\n");
551     else
552       sb.append("<b class=\"fail\">Fail</b><br><br>\n");
553 
554     sb.append("<b>Empty features on the chip:</b> ");
555     sb.append(BioAssayUtils.countEmptySpots(gpr));
556     sb.append("/");
557     sb.append(gpr.size());
558     sb.append(".<br>\n");
559 
560     final String[] emptySpotIds = testSuiteResult.getEmptySpotIds();
561     if (emptySpotIds != null || emptySpotIds.length != 0) {
562       sb.append("<b>Empty feature identifiers: </b>\n<ul>\n");
563 
564       for (int i = 0; i < emptySpotIds.length; i++) {
565         sb.append("<li>");
566         sb.append(emptySpotIds[i]);
567         sb.append("</li>");
568       }
569 
570       sb.append("</ul>\n");
571     }
572 
573     sb.append("<b>New output Array list:</b> ");
574     if (this.galResult)
575       sb.append("<b class=\"pass\">Yes</b><br>\n");
576     else
577       sb.append("<b class=\"fail\">No</b><br>\n");
578     sb.append("<b>New Array list generator message:</b> ");
579     sb.append(this.galResultMessage);
580     sb.append("<br>");
581 
582     return sb.toString();
583   }
584 
585   private String writeEmptySpot(final BioAssay gal) {
586 
587     if (gal == null)
588       return null;
589 
590     final int emptyFeatures = BioAssayUtils.countEmptySpots(gal);
591     final int totalFeatures = gal.size();
592     final int realFeatures = totalFeatures - emptyFeatures;
593 
594     StringBuffer sb = new StringBuffer();
595 
596     sb.append("<b>Empty features in array list file:</b> ");
597     sb.append(emptyFeatures);
598     sb.append("<br>\n<b>Real features in array list file:</b> ");
599     sb.append(realFeatures);
600     sb.append("<br>\n<b>Total features in array list file:</b> ");
601     sb.append(totalFeatures);
602     sb.append("<br>\n");
603 
604     return sb.toString();
605   }
606 
607   /***
608    * Create a string with the header of the HTML page.
609    * @return A string with the header of the HTML page
610    */
611   private String header() {
612 
613     StringBuffer sb = new StringBuffer();
614     // sb.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01
615     // Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
616     sb.append("<!-- PRINT HEADER1 HERE -->");
617     //
618     sb.append("<html>\n<head>\n");
619 
620     sb.append("<title>");
621     sb.append(Defaults.APP_NAME);
622     sb.append(" Quality Test report");
623     sb.append(" </title>\n");
624     sb.append("<!-- PRINT HEADER2 HERE -->");
625 
626     sb
627         .append("<style>body {font-size: 11px; font-family: sans-serif;}</style>\n");
628     sb.append("<style>.fail {color: red;}</style>\n");
629     sb.append("<style>.pass {color: green;}</style>\n");
630     sb
631         .append("<style>td {font-size: 11px; font-family: sans-serif;}</style>\n");
632     sb
633         .append("<style>th {font-size: 11px; font-family: sans-serif;}</style>\n");
634     sb.append("<style>h1 {font-size: 20px; font-family: serif;}</style>\n");
635     sb
636         .append("<style>h2 {font-size: 14px; font-family: sans-serif;}</style>\n");
637 
638     sb.append("</head>\n<body>\n");
639     return sb.toString();
640   }
641 
642   /***
643    * Create a string with the footer of the HTML page.
644    * @return A string with the footer of the HTML page
645    */
646   private String footer() {
647 
648     StringBuffer sb = new StringBuffer();
649     sb.append("<br><hr><a href='");
650     sb.append(DoelanRegistery.getAppURL());
651     sb.append("'>");
652     sb.append(Defaults.APP_NAME);
653     sb.append("</a> ");
654     sb.append(DoelanRegistery.getAppVersion());
655     sb.append(", Copyright " + DoelanRegistery.getCopyrightDate() + " "
656         + "<a href=\"" + DoelanRegistery.getOrganizationURL() + "\">"
657         + DoelanRegistery.getOrganizationName() + "</a>.\n");
658     sb.append("<!-- PRINT COMMAND HERE -->");
659     sb.append("</body></html>");
660 
661     return sb.toString();
662   }
663 
664   //
665   // Constructor
666   //
667 
668   /***
669    * Public constructor.
670    * @throws PlatformException If the name or the version of the element is
671    *           <b>null </b>.
672    */
673   public DoelanGenerateReport() throws PlatformException {
674     // MUST BE EMPTY
675   }
676 
677 }