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.tests;
23  
24  import fr.ens.transcriptome.doelan.Defaults;
25  import fr.ens.transcriptome.doelan.DoelanRegistery;
26  import fr.ens.transcriptome.doelan.algorithms.QualityUnitTest;
27  import fr.ens.transcriptome.doelan.data.QualityUnitTestResult;
28  import fr.ens.transcriptome.doelan.data.QualityUnitTestResult.SummaryResult;
29  import fr.ens.transcriptome.nividic.om.BioAssay;
30  import fr.ens.transcriptome.nividic.om.GenepixResults;
31  import fr.ens.transcriptome.nividic.om.SpotIterator;
32  import fr.ens.transcriptome.nividic.om.io.GPRConverterFieldNames;
33  import fr.ens.transcriptome.nividic.platform.PlatformException;
34  import fr.ens.transcriptome.nividic.platform.module.AboutModule;
35  import fr.ens.transcriptome.nividic.platform.module.Module;
36  import fr.ens.transcriptome.nividic.platform.module.ModuleDescription;
37  import fr.ens.transcriptome.nividic.util.SystemUtils;
38  import fr.ens.transcriptome.nividic.util.parameter.FixedParameters;
39  import fr.ens.transcriptome.nividic.util.parameter.Parameter;
40  import fr.ens.transcriptome.nividic.util.parameter.ParameterBuilder;
41  import fr.ens.transcriptome.nividic.util.parameter.ParameterException;
42  import fr.ens.transcriptome.nividic.util.parameter.Parameters;
43  
44  /***
45   * This class define a generic unit test
46   * @author Laurent Jourdren
47   */
48  public class GenericTest extends QualityUnitTest implements Module {
49  
50    private static final int LESSER_THAN_OR_EQUALS_TO = 1;
51    private static final int LESSER_THAN = 2;
52    private static final int EQUALS = 3;
53    private static final int NOT_EQUALS = 4;
54    private static final int GREATER_THAN_OR_EQUALS_TO = 5;
55    private static final int GREATER_THAN = 6;
56    private static AboutModule aboutModule;
57  
58    /***
59     * Get the description of the module.
60     * @return The description of the module
61     */
62    public AboutModule aboutModule() {
63  
64      if (aboutModule == null) {
65  
66        ModuleDescription md = null;
67        try {
68  
69          md = new ModuleDescription("GenericTest",
70              "Generic test for a column of GPR");
71          md.setWebsite(DoelanRegistery.getAppURL());
72          md.setHTMLDocumentation(SystemUtils.readTextRessource("/files/test-"
73              + SystemUtils.getClassShortName(this.getClass()) + ".html"));
74          md.setStability(AboutModule.STATE_STABLE);
75          md.setVersion(Defaults.DEFAULT_TEST_VERSION);
76        } catch (PlatformException e) {
77          getLogger().error("Unable to create the module description");
78        }
79        aboutModule = md;
80      }
81  
82      return aboutModule;
83    }
84  
85    /***
86     * Set the parameters of the element.
87     * @return The defaults parameters to set.
88     */
89    protected Parameters defineParameters() {
90  
91      try {
92  
93        final Parameter columnName = new ParameterBuilder()
94            .withName("columnName").withLongName("Column name").withType(
95                Parameter.DATATYPE_STRING).withDescription(
96                "Name of the column to test").getParameter();
97  
98        final Parameter testToApply = new ParameterBuilder().withName(
99            "testToApply").withLongName("Test").withType(
100           Parameter.DATATYPE_STRING).withDescription("Test to apply")
101           .withChoices(
102               new String[] {"<", "<=", "equals", "not equals", ">=", ">"})
103           .withDefaultValue("<").getParameter();
104 
105       final Parameter testValue = new ParameterBuilder().withName("testValue")
106           .withLongName("Test value").withType(Parameter.DATATYPE_STRING)
107           .withDescription("Test value").getParameter();
108 
109       final Parameter threshold = new ParameterBuilder().withName("threshold")
110           .withLongName("Maximal threshold of bad spots").withType(
111               Parameter.DATATYPE_DOUBLE).withDescription(
112               "Threshold of invalid spots to reject the test")
113           .withGreaterThanValue(0).withDefaultValue("10").withUnit("%")
114           .getParameter();
115 
116       final Parameter filterFlags = new ParameterBuilder().withType(
117           Parameter.DATATYPE_YESNO).withName("filterFlags").withLongName(
118           "Remove bad spots from output array list").withDescription(
119           "Remove invalid spots in output arraylist file.").withDefaultValue(
120           "yes").getParameter();
121 
122       final FixedParameters params = new FixedParameters();
123       params.addParameter(columnName);
124       params.addParameter(testToApply);
125       params.addParameter(testValue);
126       params.addParameter(threshold);
127       params.addParameter(filterFlags);
128 
129       return params;
130 
131     } catch (ParameterException e) {
132       getLogger().error("Error while creating parameters: " + e);
133     }
134 
135     return null;
136   }
137 
138   /***
139    * Test the quality of the bioassay.
140    * @param bioassay BioAssay to test
141    * @param arrayList The array list
142    * @param parameters parameters of the test
143    * @return A QualityObjectResultTest Object
144    * @throws PlatformException if an error occurs while executing the test.
145    */
146   public QualityUnitTestResult test(final BioAssay bioassay,
147       final BioAssay arrayList, final Parameters parameters)
148       throws PlatformException {
149 
150     QualityUnitTestResult result = null;
151 
152     try {
153 
154       final boolean[] results = new boolean[bioassay.size()];
155 
156       String columnName = parameters.getParameter("columnName")
157           .getStringValue();
158       final String testToApply = parameters.getParameter("testToApply")
159           .getStringValue();
160 
161       final double threshold = parameters.getParameter("threshold")
162           .getDoubleValue();
163 
164       final String testValue = parameters.getParameter("testValue")
165           .getStringValue();
166 
167       final boolean filterFlags = parameters.getParameter("filterFlags")
168           .getBooleanValue();
169 
170       int intThreshold = 0;
171       double doubleThreshold = 0;
172       String stringThreshold = testValue.trim();
173 
174       int fieldType = -1;
175       int testType = getTestType(testToApply);
176 
177       boolean somethingToTest = false;
178       if (columnName != null) {
179         columnName = columnName.trim();
180 
181         if (new GenepixResults(bioassay).isGPRData())
182           columnName = new GPRConverterFieldNames()
183               .getBioAssayFieldName(columnName);
184 
185         if (bioassay.isField(columnName)) {
186           somethingToTest = true;
187 
188           fieldType = bioassay.getFieldType(columnName);
189 
190           switch (fieldType) {
191 
192           case BioAssay.DATATYPE_DOUBLE:
193 
194             try {
195               doubleThreshold = Double.parseDouble(stringThreshold);
196             } catch (NumberFormatException e) {
197               somethingToTest = false;
198             }
199             break;
200 
201           case BioAssay.DATATYPE_INTEGER:
202 
203             try {
204               intThreshold = Integer.parseInt(stringThreshold);
205             } catch (NumberFormatException e) {
206               somethingToTest = false;
207             }
208             break;
209 
210           default:
211             break;
212           }
213 
214         }
215       }
216 
217       int countBad = 0;
218       int countRealSpot = 0;
219 
220       SpotIterator si = bioassay.iterator();
221 
222       while (si.hasNext()) {
223         si.next();
224 
225         if (si.isEmpty() || si.isFlagAbscent())
226           continue;
227 
228         if (somethingToTest) {
229 
230           boolean bad = true;
231 
232           switch (fieldType) {
233 
234           case BioAssay.DATATYPE_DOUBLE:
235 
236             double dv = si.getDataFieldDouble(columnName);
237 
238             switch (testType) {
239             case LESSER_THAN_OR_EQUALS_TO:
240 
241               if (dv <= doubleThreshold)
242                 bad = false;
243               break;
244 
245             case LESSER_THAN:
246 
247               if (dv < doubleThreshold)
248                 bad = false;
249               break;
250 
251             case EQUALS:
252 
253               if (dv == doubleThreshold)
254                 bad = false;
255               break;
256 
257             case NOT_EQUALS:
258 
259               if (dv != doubleThreshold)
260                 bad = false;
261               break;
262 
263             case GREATER_THAN_OR_EQUALS_TO:
264 
265               if (dv >= doubleThreshold)
266                 bad = false;
267               break;
268 
269             case GREATER_THAN:
270 
271               if (dv > doubleThreshold)
272                 bad = false;
273               break;
274 
275             default:
276               break;
277             }
278 
279             break;
280 
281           case BioAssay.DATATYPE_INTEGER:
282             int iv = si.getDataFieldInt(columnName);
283 
284             switch (testType) {
285             case LESSER_THAN_OR_EQUALS_TO:
286 
287               if (iv <= intThreshold)
288                 bad = false;
289               break;
290 
291             case LESSER_THAN:
292 
293               if (iv < intThreshold)
294                 bad = false;
295               break;
296 
297             case EQUALS:
298 
299               if (iv == intThreshold)
300                 bad = false;
301               break;
302 
303             case NOT_EQUALS:
304 
305               if (iv != intThreshold)
306                 bad = false;
307               break;
308 
309             case GREATER_THAN_OR_EQUALS_TO:
310 
311               if (iv >= intThreshold)
312                 bad = false;
313               break;
314 
315             case GREATER_THAN:
316 
317               if (iv > intThreshold)
318                 bad = false;
319               break;
320 
321             default:
322               break;
323             }
324             break;
325 
326           case BioAssay.DATATYPE_STRING:
327             String sv = si.getDataFieldString(columnName);
328 
329             switch (testType) {
330             case LESSER_THAN_OR_EQUALS_TO:
331 
332               if (stringThreshold.compareTo(sv) >= 0)
333                 bad = false;
334               break;
335 
336             case LESSER_THAN:
337 
338               if (stringThreshold.compareTo(sv) > 0)
339                 bad = false;
340               break;
341 
342             case EQUALS:
343 
344               if (stringThreshold.compareTo(sv) == 0)
345                 bad = false;
346               break;
347 
348             case NOT_EQUALS:
349 
350               if (stringThreshold.compareTo(sv) != 0)
351                 bad = false;
352               break;
353 
354             case GREATER_THAN_OR_EQUALS_TO:
355 
356               if (stringThreshold.compareTo(sv) <= 0)
357                 bad = false;
358               break;
359 
360             case GREATER_THAN:
361 
362               if (stringThreshold.compareTo(sv) < 0)
363                 bad = false;
364               break;
365 
366             default:
367               break;
368             }
369             break;
370 
371           default:
372             break;
373           }
374 
375           if (bad)
376             countBad++;
377           else
378             results[si.getIndex()] = true;
379         } else
380           results[si.getIndex()] = true;
381 
382         countRealSpot++;
383       }
384 
385       final double ratio = ((double) countBad) / ((double) countRealSpot) * 100;
386 
387       result = new QualityUnitTestResult(bioassay, this);
388       final long max = (long) (countRealSpot * threshold / 100);
389 
390       if (somethingToTest)
391 
392         result.setMessage("Bad features: " + countBad + "/" + countRealSpot
393             + " features (threshold: " + max + " features)");
394 
395       else
396         result.setMessage("Invalid field or invalid test value.");
397 
398       result.setGlobalResultType(true);
399       result.setFilterFlags(filterFlags);
400       result.setNewFlags(results);
401       SummaryResult rac = result.getResultAllChannels();
402       rac.setPercent(true);
403       rac.setThresholdEqualityType("<=");
404       rac.setThreshold(threshold);
405       rac.setUnit("%");
406       rac.setValue(ratio);
407       rac.setPercent(false);
408       rac.setPass(ratio <= threshold);
409 
410     } catch (ParameterException e) {
411       throw new PlatformException("Error while creating parameters ("
412           + this.getClass().getName() + "): " + e.getMessage());
413     }
414 
415     return result;
416   }
417 
418   private int getTestType(final String test) {
419 
420     if (test == null)
421       return -1;
422 
423     String t = test.trim();
424 
425     if ("<=".equals(t))
426       return LESSER_THAN_OR_EQUALS_TO;
427     else if ("<".equals(t))
428       return LESSER_THAN;
429     else if ("equals".equals(t))
430       return EQUALS;
431     else if ("not equals".equals(t))
432       return NOT_EQUALS;
433     else if (">=".equals(t))
434       return GREATER_THAN_OR_EQUALS_TO;
435     else if (">".equals(t))
436       return GREATER_THAN;
437 
438     return -1;
439   }
440 
441   //
442   // Constructor
443   //
444 
445   /***
446    * Public constructor.
447    * @throws PlatformException If the name or the version of the element is
448    *           <b>null </b>.
449    */
450   public GenericTest() throws PlatformException {
451     // MUST BE EMPTY
452   }
453 
454 }