1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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
101 BioAssay gpr = DoelanDataUtils.getBioAssay(c);
102
103
104 TestSuiteResult testSuiteResult = DoelanDataUtils.getTestSuiteResult(c);
105
106
107 BioAssay gal = DoelanDataUtils.getArrayList(c);
108
109
110 QualityTestResult[] results = DoelanDataUtils
111 .getOrderedQualityTestResults(c);
112
113
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
201
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
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
237
238 if (p.getUnit() != null) {
239 sb.append(' ');
240 sb.append(p.getUnit());
241 }
242
243
244 sb.append("</i></li>\n");
245 }
246
247
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
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
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 = "<";
318 else if ("<=".equals(sign))
319 result = "<=";
320 else if (">".equals(sign))
321 result = ">";
322 else if (">=".equals(sign))
323 result = ">=";
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
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
615
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
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
675 }
676
677 }