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 org.apache.commons.collections.primitives.ArrayDoubleList;
25  
26  import fr.ens.transcriptome.doelan.Defaults;
27  import fr.ens.transcriptome.doelan.DoelanChart;
28  import fr.ens.transcriptome.doelan.DoelanRegistery;
29  import fr.ens.transcriptome.doelan.algorithms.QualityUnitTest;
30  import fr.ens.transcriptome.doelan.data.QualityUnitTestResult;
31  import fr.ens.transcriptome.doelan.data.QualityUnitTestResult.SummaryResult;
32  import fr.ens.transcriptome.nividic.om.BioAssay;
33  import fr.ens.transcriptome.nividic.om.SpotIterator;
34  import fr.ens.transcriptome.nividic.platform.PlatformException;
35  import fr.ens.transcriptome.nividic.platform.module.AboutModule;
36  import fr.ens.transcriptome.nividic.platform.module.Module;
37  import fr.ens.transcriptome.nividic.platform.module.ModuleDescription;
38  import fr.ens.transcriptome.nividic.util.SystemUtils;
39  import fr.ens.transcriptome.nividic.util.parameter.FixedParameters;
40  import fr.ens.transcriptome.nividic.util.parameter.Parameter;
41  import fr.ens.transcriptome.nividic.util.parameter.ParameterBuilder;
42  import fr.ens.transcriptome.nividic.util.parameter.ParameterException;
43  import fr.ens.transcriptome.nividic.util.parameter.Parameters;
44  
45  /***
46   * This class defines a quality test based on spot diameter.
47   * @author Laurent Jourdren
48   */
49  public class DiameterFeatureTest extends QualityUnitTest implements Module {
50  
51    private static final int DEFAULT_BINS = 16;
52    private static AboutModule aboutModule;
53  
54    /***
55     * Get the description of the module.
56     * @return The description of the module
57     */
58    public AboutModule aboutModule() {
59  
60      if (aboutModule == null) {
61  
62        ModuleDescription md = null;
63        try {
64          md = new ModuleDescription("DiameterFeatureTest",
65              "Test diameter of features");
66          md.setWebsite(DoelanRegistery.getAppURL());
67          md.setHTMLDocumentation(SystemUtils.readTextRessource("/files/test-"
68              + SystemUtils.getClassShortName(this.getClass()) + ".html"));
69          md.setStability(AboutModule.STATE_STABLE);
70          md.setVersion(Defaults.DEFAULT_TEST_VERSION);
71        } catch (PlatformException e) {
72          getLogger().error("Unable to create the module description");
73        }
74  
75        aboutModule = md;
76      }
77      return aboutModule;
78    }
79  
80    /***
81     * Set the parameters of the element.
82     * @return The defaults parameters to set.
83     */
84    protected Parameters defineParameters() {
85  
86      try {
87  
88        final Parameter min = new ParameterBuilder().withName("min").withType(
89            Parameter.DATATYPE_INTEGER).withDescription(
90            "Minimal value of the diameter for a spot (included)")
91            .withGreaterThanValue(0).withDefaultValue("80").withUnit("µm")
92            .getParameter();
93  
94        final Parameter max = new ParameterBuilder().withName("max").withType(
95            Parameter.DATATYPE_INTEGER).withDescription(
96            "Maximal value of the diameter for a spot (excluded)")
97            .withGreaterThanValue(0).withDefaultValue("140").withUnit("µm")
98            .getParameter();
99  
100       final Parameter threshold = new ParameterBuilder().withName("threshold")
101           .withLongName("Maximal threshold of bad spots").withType(
102               Parameter.DATATYPE_DOUBLE).withDescription(
103               "Threshold of invalid spots to reject the chip")
104           .withGreaterThanValue(0).withLowerThanValue(1).withDefaultValue("10")
105           .withUnit("%").getParameter();
106 
107       final Parameter filterFlags = new ParameterBuilder().withName(
108           "filterFlags").withType(Parameter.DATATYPE_YESNO).withLongName(
109           "Remove bad spots from output array list").withDescription(
110           "Remove invalid spots in output arraylist file.").withDefaultValue(
111           "yes").getParameter();
112 
113       final FixedParameters params = new FixedParameters();
114       params.addParameter(min);
115       params.addParameter(max);
116       params.addParameter(threshold);
117       params.addParameter(filterFlags);
118 
119       return params;
120 
121     } catch (ParameterException e) {
122       getLogger().error("Error while creating parameters: " + e);
123     }
124 
125     return null;
126   }
127 
128   /***
129    * Test the quality of the bioassay.
130    * @param bioassay BioAssay to test
131    * @param arrayList The array list
132    * @param parameters parameters of the test
133    * @return A QualityObjectResultTest Object
134    * @throws PlatformException if an error occurs while executing the test.
135    */
136   public QualityUnitTestResult test(final BioAssay bioassay,
137       final BioAssay arrayList, final Parameters parameters)
138       throws PlatformException {
139 
140     QualityUnitTestResult result = null;
141 
142     try {
143       final int min = parameters.getParameter("min").getIntValue();
144       final int max = parameters.getParameter("max").getIntValue();
145 
146       final double threshold = parameters.getParameter("threshold")
147           .getDoubleValue();
148 
149       final boolean filterFlags = parameters.getParameter("filterFlags")
150           .getBooleanValue();
151 
152       final boolean[] results = new boolean[bioassay.size()];
153       //final int[] flags = bioassay.getFlags();
154       final int[] dia = bioassay.getDataFieldInt("Dia.");
155 
156       if (dia == null)
157         throw new PlatformException("Diameter field doesn't exits");
158 
159       int countBadDiameter = 0;
160       int countRealSpot = 0;
161       ArrayDoubleList adl = new ArrayDoubleList();
162 
163       SpotIterator si = bioassay.iterator();
164       int i = 0;
165 
166       while (si.hasNext()) {
167         si.next();
168         if (si.isEmpty() || si.isFlagAbscent()) {
169           i++;
170           continue;
171         }
172 
173         adl.add(dia[i]);
174         if (dia[i] >= min && dia[i] < max)
175           results[i] = true;
176         else {
177           if (filterFlags)
178             results[i] = false;
179           else
180             results[i] = true;
181           countBadDiameter++;
182         }
183 
184         countRealSpot++;
185         i++;
186       }
187 
188       final double ratio = ((double) countBadDiameter)
189           / ((double) countRealSpot) * 100;
190 
191       result = new QualityUnitTestResult(bioassay, this);
192 
193       long maxThreshold = (long) (countRealSpot * threshold / 100.0);
194 
195       result.setMessage("Bad diameter features: " + countBadDiameter + "/"
196           + countRealSpot + " features (threshold: " + maxThreshold
197           + " features)");
198 
199       /*
200        * Plot p = new Plot(); p.setTitle("Diameter distribution");
201        * p.setData(data); p.setWidth(400); p.setHeight(300); p.setXRange(20);
202        * p.setYRange(1000); p.setHistRange(10); p.setXAxisUnit("Pixels");
203        * p.setYAxisUnit("# Spots"); p.setXPlotDescription("Thresholds");
204        * p.plotHistData(); p.plotXLimit(min); p.plotXLimit(max);
205        */
206 
207       DoelanChart gu = new DoelanChart();
208       gu.setData(adl.toArray());
209       gu.setTitle("Diameter distribution");
210       gu.setXAxisLegend("Spot diameter (pixels)");
211       gu.setYAxisLegend("#Spots");
212       gu.setHistCaption("Spots");
213       gu.setThreshold(max);
214       gu.setWidth(DoelanRegistery.getDoelanChartWidth());
215       gu.setHeight(DoelanRegistery.getDoelanChartHeigth());
216       gu.setBins(DEFAULT_BINS);
217 
218       result.setImage(gu.getImage());
219       result.setGlobalResultType(true);
220       result.setNewFlags(results);
221       result.setFilterFlags(filterFlags);
222       SummaryResult rac = result.getResultAllChannels();
223       rac.setPercent(true);
224       rac.setThresholdEqualityType("<=");
225       rac.setUnit("%");
226       rac.setThreshold(threshold);
227       rac.setValue(ratio);
228       rac.setPass(ratio <= threshold);
229 
230     } catch (ParameterException e) {
231       throw new PlatformException("Error while creating parameters ("
232           + this.getClass().getName() + "): " + e.getMessage());
233     }
234 
235     return result;
236   }
237 
238   //
239   // Constructor
240   //
241 
242   /***
243    * Public constructor.
244    * @throws PlatformException If the name or the version of the element is
245    *                 <b>null </b>.
246    */
247   public DiameterFeatureTest() throws PlatformException {
248     // MUST BE EMPTY
249   }
250 
251 }