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.graphics.GraphicsUtil;
40  import fr.ens.transcriptome.nividic.util.parameter.FixedParameters;
41  import fr.ens.transcriptome.nividic.util.parameter.Parameter;
42  import fr.ens.transcriptome.nividic.util.parameter.ParameterBuilder;
43  import fr.ens.transcriptome.nividic.util.parameter.ParameterException;
44  import fr.ens.transcriptome.nividic.util.parameter.Parameters;
45  
46  /***
47   * Test there are real spots in "abscent" spot.
48   * @author Laurent Jourdren
49   */
50  public class MinimalIntensityTest extends QualityUnitTest implements Module {
51  
52    private static final int DEFAULT_BINS = 16;
53    private static final String CHANNEL_CY3 = "Cy3 (green)";
54    private static final String CHANNEL_CY5 = "Cy5 (red)";
55    private static final String CHANNEL_CY3CY5 = "Both";
56  
57    private static AboutModule aboutModule;
58  
59    /***
60     * Get the description of the module.
61     * @return The description of the module
62     */
63    public AboutModule aboutModule() {
64  
65      if (aboutModule == null) {
66  
67        ModuleDescription md = null;
68        try {
69          md = new ModuleDescription("MinimalIntensityTest",
70              "Test if the spots have the required minimal intensity");
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  
80        aboutModule = md;
81      }
82  
83      return aboutModule;
84    }
85  
86    /***
87     * Define the parameters of the algorithm.
88     */
89    protected Parameters defineParameters() {
90  
91      try {
92  
93        final Parameter minimalIntensity = new ParameterBuilder().withName(
94            "minimalIntensity").withLongName("Minimal spot intensity").withType(
95            Parameter.DATATYPE_INTEGER).withDescription(
96            "Minimal intensity of a spot").withGreaterThanValue(0)
97            .withDefaultValue("50").getParameter();
98  
99        final Parameter channel = new ParameterBuilder().withName("channel")
100           .withLongName("Channel(s)").withType(Parameter.DATATYPE_STRING)
101           .withDescription("Channel(s) to test").withChoices(
102               new String[] {CHANNEL_CY5, CHANNEL_CY3, CHANNEL_CY3CY5})
103           .withDefaultValue(CHANNEL_CY3CY5).getParameter();
104 
105       final Parameter threshold = new ParameterBuilder().withName("threshold")
106           .withLongName("Maximal threshold of bad spots").withType(
107               Parameter.DATATYPE_DOUBLE).withDescription(
108               "Threshold of invalid spots to reject the chip")
109           .withGreaterThanValue(0).withDefaultValue("10").withUnit("%")
110           .getParameter();
111 
112       final Parameter filterFlags = new ParameterBuilder().withName(
113           "filterFlags").withType(Parameter.DATATYPE_YESNO).withLongName(
114           "Remove bad spots from output array list").withDescription(
115           "Remove invalid spots in output arraylist file.").withDefaultValue(
116           "yes").getParameter();
117 
118       final FixedParameters params = new FixedParameters();
119       params.addParameter(minimalIntensity);
120       params.addParameter(channel);
121       params.addParameter(threshold);
122       params.addParameter(filterFlags);
123 
124       return params;
125 
126     } catch (ParameterException e) {
127       getLogger().error("Error while creating parameters: " + e);
128     }
129 
130     return null;
131   }
132 
133   /***
134    * Test the quality of the bioassay.
135    * @param bioassay BioAssay to test
136    * @param arrayList The array list
137    * @param parameters parameters of the test
138    * @return A QualityObjectResultTest Object
139    * @throws PlatformException if an error occurs while executing the test.
140    */
141   public QualityUnitTestResult test(final BioAssay bioassay,
142       final BioAssay arrayList, final Parameters parameters)
143       throws PlatformException {
144 
145     if (bioassay == null)
146       return null;
147 
148     QualityUnitTestResult result = null;
149 
150     try {
151 
152       final int minimalIntensity = getParameters().getParameter(
153           "minimalIntensity").getIntValue();
154       final double threshold = getParameters().getParameter("threshold")
155           .getDoubleValue();
156       final boolean filterFlags = parameters.getParameter("filterFlags")
157           .getBooleanValue();
158       final String channel = parameters.getParameter("channel")
159           .getStringValue();
160 
161       boolean testGreen = true;
162       boolean testRed = true;
163 
164       if (CHANNEL_CY3.equals(channel))
165         testRed = false;
166       else if (CHANNEL_CY5.equals(channel))
167         testGreen = false;
168 
169       final boolean[] results = new boolean[bioassay.size()];
170 
171       SpotIterator si = bioassay.iterator();
172       ArrayDoubleList dataGreen = new ArrayDoubleList();
173       ArrayDoubleList dataRed = new ArrayDoubleList();
174 
175       int count = 0;
176       int countRealSpot = 0;
177 
178       while (si.hasNext()) {
179 
180         si.next();
181         results[si.getIndex()] = true;
182 
183         if (si.getFlag() == BioAssay.FLAG_ABSCENT)
184           continue;
185 
186         if (!si.isEmpty() && !si.isFlagAbscent()) {
187 
188           boolean notPassRed = si.getRed() < minimalIntensity;
189           boolean notPassGreen = si.getGreen() < minimalIntensity;
190 
191           if (notPassRed && testRed || notPassGreen && testGreen) {
192             count++;
193             results[si.getIndex()] = false;
194           }
195 
196         }
197 
198         dataGreen.add(si.getGreen());
199         dataRed.add(si.getRed());
200 
201         countRealSpot++;
202       }
203 
204       final double ratio = ((double) count) / ((double) countRealSpot) * 100;
205       result = new QualityUnitTestResult(bioassay, this);
206 
207       final long max = (long) (countRealSpot * threshold / 100);
208       result.setMessage("Features with invalid invalid intensity : " + count
209           + "/" + countRealSpot + " features (threshold: " + max
210           + " features)<br>");
211 
212       result.setGlobalResultType(true);
213 
214       result.setNewFlags(results);
215       result.setFilterFlags(filterFlags);
216       SummaryResult rac = result.getResultAllChannels();
217       rac.setPercent(true);
218       rac.setThresholdEqualityType("<=");
219       rac.setUnit("%");
220       rac.setThreshold(threshold);
221       rac.setValue(ratio);
222       rac.setPass(ratio <= threshold);
223 
224       DoelanChart guGreen = null;
225 
226       if (testGreen) {
227 
228         guGreen = new DoelanChart();
229         guGreen.setData(dataGreen.toArray());
230         guGreen.setTitle("Green Median Intensity distribution");
231         guGreen.setXAxisLegend("Intensity");
232         guGreen.setYAxisLegend("#Spots");
233         guGreen.setHistCaption("Spots");
234         guGreen.setThreshold(minimalIntensity);
235         guGreen.setWidth(DoelanRegistery.getDoelanChartWidth());
236         guGreen.setHeight(DoelanRegistery.getDoelanChartHeigth());
237         guGreen.setBins(DEFAULT_BINS);
238         guGreen.setYLogAxis(true);
239       }
240 
241       DoelanChart guRed = null;
242 
243       if (testRed) {
244 
245         guRed = new DoelanChart();
246         guRed.setData(dataRed.toArray());
247         guRed.setTitle("Red Median Intensity distribution");
248         guRed.setXAxisLegend("Intensity");
249         guRed.setYAxisLegend("#Spots");
250         guRed.setHistCaption("Spots");
251         guRed.setThreshold(minimalIntensity);
252         guRed.setWidth(DoelanRegistery.getDoelanChartWidth());
253         guRed.setHeight(DoelanRegistery.getDoelanChartHeigth());
254         guRed.setBins(DEFAULT_BINS);
255         guRed.setYLogAxis(true);
256       }
257 
258       if (testGreen && testRed)
259         result.setImage(GraphicsUtil.mergeImages(guGreen.getImage(), guRed
260             .getImage()));
261       else if (testRed)
262         result.setImage(guRed.getImage());
263       else
264         result.setImage(guGreen.getImage());
265 
266     } catch (ParameterException e) {
267       throw new PlatformException("Error while creating parameters ("
268           + this.getClass().getName() + "): " + e.getMessage());
269     }
270 
271     return result;
272   }
273 
274   //
275   // Constructor
276   //
277 
278   /***
279    * Public constructor.
280    * @throws PlatformException If the name or the version of the element is
281    *           <b>null </b>.
282    */
283   public MinimalIntensityTest() throws PlatformException {
284     // MUST BE EMPTY
285   }
286 
287 }