809dce32c53668ea6d94b918332216e283acc882
[jalview.git] / test / jalview / schemes / ResidueColourSchemeTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.schemes;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertTrue;
26
27 import jalview.datamodel.Alignment;
28 import jalview.datamodel.AlignmentAnnotation;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.AnnotatedCollectionI;
31 import jalview.datamodel.Annotation;
32 import jalview.datamodel.Profile;
33 import jalview.datamodel.ProfileI;
34 import jalview.datamodel.Profiles;
35 import jalview.datamodel.Sequence;
36 import jalview.datamodel.SequenceI;
37 import jalview.gui.JvOptionPane;
38 import jalview.io.TCoffeeScoreFile;
39
40 import java.awt.Color;
41
42 import org.testng.annotations.BeforeClass;
43 import org.testng.annotations.Test;
44
45 public class ResidueColourSchemeTest
46 {
47
48   @BeforeClass(alwaysRun = true)
49   public void setUpJvOptionPane()
50   {
51     JvOptionPane.setInteractiveMode(false);
52     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
53   }
54
55   @Test(groups = "Functional")
56   public void testAboveThreshold()
57   {
58     /*
59      * make up profiles for this alignment:
60      * AR-Q
61      * AR--
62      * SR-T
63      * SR-T
64      */
65     ProfileI[] profiles = new ProfileI[4];
66     profiles[0] = new Profile(4, 0, 2, "AS");
67     profiles[1] = new Profile(4, 0, 4, "R");
68     profiles[2] = new Profile(4, 4, 0, "");
69     profiles[3] = new Profile(4, 1, 2, "T");
70     ResidueColourScheme rcs = new ResidueColourScheme();
71     rcs.setConsensus(new Profiles(profiles));
72     
73     /*
74      * no threshold
75      */
76     rcs.setThreshold(0, true);
77     assertTrue(rcs.aboveThreshold('a', 0));
78     assertTrue(rcs.aboveThreshold('S', 0));
79     assertFalse(rcs.aboveThreshold('W', 0));
80     assertTrue(rcs.aboveThreshold('R', 1));
81     assertFalse(rcs.aboveThreshold('W', 2));
82     assertTrue(rcs.aboveThreshold('t', 3));
83     assertFalse(rcs.aboveThreshold('Q', 3));
84
85     /*
86      * with threshold, include gaps
87      */
88     rcs.setThreshold(60, false);
89     assertFalse(rcs.aboveThreshold('a', 0));
90     assertFalse(rcs.aboveThreshold('S', 0));
91     assertTrue(rcs.aboveThreshold('R', 1));
92     assertFalse(rcs.aboveThreshold('W', 2));
93     assertFalse(rcs.aboveThreshold('t', 3)); // 50% < 60%
94
95     /*
96      * with threshold, ignore gaps
97      */
98     rcs.setThreshold(60, true);
99     assertFalse(rcs.aboveThreshold('a', 0));
100     assertFalse(rcs.aboveThreshold('S', 0));
101     assertTrue(rcs.aboveThreshold('R', 1));
102     assertFalse(rcs.aboveThreshold('W', 2));
103     assertTrue(rcs.aboveThreshold('t', 3)); // 67% > 60%
104   }
105
106   /**
107    * Test colour bleaching based on conservation score and conservation slider.
108    * Scores of 10 or 11 should leave colours unchanged. Gap is always white.
109    */
110   @Test(groups = "Functional")
111   public void testApplyConservation()
112   {
113     ResidueColourScheme rcs = new ResidueColourScheme();
114
115     // no conservation present - no fading
116     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 12));
117     
118     // cheat by setting conservation sequence directly
119     // rather than calculating it - good enough for this test
120     String consensus = "0123456789+*-";
121     rcs.conservation = consensus.toCharArray();
122
123     // column out of range:
124     assertEquals(Color.RED,
125             rcs.applyConservation(Color.RED, consensus.length()));
126
127     /*
128      * with 100% threshold, 'fade factor' is 
129      * (11-score)/10 * 100/20 = (11-score)/2
130      * which is >= 1 for all scores i.e. all fade to white except +, *
131      */
132     rcs.setConservationInc(100);
133     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 0));
134     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 1));
135     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 2));
136     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 3));
137     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 4));
138     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 5));
139     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 6));
140     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 7));
141     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 8));
142     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 9));
143     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
144     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
145     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12));
146
147     /*
148      * with 0% threshold, there should be no fading
149      */
150     rcs.setConservationInc(0);
151     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 0));
152     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 1));
153     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 2));
154     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 3));
155     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 4));
156     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 5));
157     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 6));
158     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 7));
159     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 8));
160     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 9));
161     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
162     assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
163     assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12)); // gap
164
165     /*
166      * with 40% threshold, 'fade factor' is 
167      * (11-score)/10 * 40/20 = (11-score)/5
168      * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9
169      * e.g. score 7 colour fades 80% of the way to white (255, 255, 255)
170      */
171     rcs.setConservationInc(40);
172     Color colour = new Color(155, 105, 55);
173     assertEquals(Color.WHITE, rcs.applyConservation(colour, 0));
174     assertEquals(Color.WHITE, rcs.applyConservation(colour, 1));
175     assertEquals(Color.WHITE, rcs.applyConservation(colour, 2));
176     assertEquals(Color.WHITE, rcs.applyConservation(colour, 3));
177     assertEquals(Color.WHITE, rcs.applyConservation(colour, 4));
178     assertEquals(Color.WHITE, rcs.applyConservation(colour, 5));
179     assertEquals(Color.WHITE, rcs.applyConservation(colour, 6));
180     assertEquals(new Color(235, 225, 215), rcs.applyConservation(colour, 7));
181     assertEquals(new Color(215, 195, 175), rcs.applyConservation(colour, 8));
182     assertEquals(new Color(195, 165, 135), rcs.applyConservation(colour, 9));
183     assertEquals(colour, rcs.applyConservation(colour, 10));
184     assertEquals(colour, rcs.applyConservation(colour, 11));
185     assertEquals(Color.WHITE, rcs.applyConservation(colour, 12));
186   }
187
188   @Test
189   public void testIsApplicableTo()
190   {
191     SequenceI pep1 = new Sequence("pep1", "APQTWLS");
192     SequenceI pep2 = new Sequence("pep2", "AILFQYG");
193     SequenceI dna1 = new Sequence("dna1", "ACTGAC");
194     SequenceI dna2 = new Sequence("dna2", "TCCAAG");
195     AlignmentI peptide = new Alignment(new SequenceI[] { pep1, pep2 });
196     AlignmentI nucleotide = new Alignment(new SequenceI[] { dna1, dna2 });
197
198     /*
199      * peptide-specific colour schemes
200      */
201     assertTrue(new ClustalxColourScheme(peptide, null)
202             .isApplicableTo(peptide));
203     assertFalse(new ClustalxColourScheme(nucleotide, null)
204             .isApplicableTo(nucleotide));
205     assertTrue(new Blosum62ColourScheme().isApplicableTo(peptide));
206     assertFalse(new Blosum62ColourScheme().isApplicableTo(nucleotide));
207     assertTrue(new BuriedColourScheme().isApplicableTo(peptide));
208     assertFalse(new BuriedColourScheme().isApplicableTo(nucleotide));
209     assertTrue(new HelixColourScheme().isApplicableTo(peptide));
210     assertFalse(new HelixColourScheme().isApplicableTo(nucleotide));
211     assertTrue(new HydrophobicColourScheme().isApplicableTo(peptide));
212     assertFalse(new HydrophobicColourScheme().isApplicableTo(nucleotide));
213     assertTrue(new StrandColourScheme().isApplicableTo(peptide));
214     assertFalse(new StrandColourScheme().isApplicableTo(nucleotide));
215     assertTrue(new TaylorColourScheme().isApplicableTo(peptide));
216     assertFalse(new TaylorColourScheme().isApplicableTo(nucleotide));
217     assertTrue(new TurnColourScheme().isApplicableTo(peptide));
218     assertFalse(new TurnColourScheme().isApplicableTo(nucleotide));
219     assertTrue(new ZappoColourScheme().isApplicableTo(peptide));
220     assertFalse(new ZappoColourScheme().isApplicableTo(nucleotide));
221
222     /*
223      * nucleotide-specific colour schemes
224      */
225     assertFalse(new NucleotideColourScheme().isApplicableTo(peptide));
226     assertTrue(new NucleotideColourScheme().isApplicableTo(nucleotide));
227     assertFalse(new PurinePyrimidineColourScheme().isApplicableTo(peptide));
228     assertTrue(new PurinePyrimidineColourScheme()
229             .isApplicableTo(nucleotide));
230     assertFalse(new RNAInteractionColourScheme().isApplicableTo(peptide));
231     assertTrue(new RNAInteractionColourScheme().isApplicableTo(nucleotide));
232
233     /*
234      * indifferent
235      */
236     assertTrue(new UserColourScheme().isApplicableTo(peptide));
237     assertTrue(new UserColourScheme().isApplicableTo(nucleotide));
238     assertTrue(new ScoreColourScheme(new int[] {}, new double[] {}, 0, 0d)
239             .isApplicableTo(peptide));
240     assertTrue(new ScoreColourScheme(new int[] {}, new double[] {}, 0, 0d)
241             .isApplicableTo(nucleotide));
242     assertTrue(new ResidueColourScheme().isApplicableTo(peptide));
243     assertTrue(new ResidueColourScheme().isApplicableTo(nucleotide));
244     assertTrue(new PIDColourScheme().isApplicableTo(peptide));
245     assertTrue(new PIDColourScheme().isApplicableTo(nucleotide));
246     assertTrue(new FollowerColourScheme().isApplicableTo(peptide));
247     assertTrue(new FollowerColourScheme().isApplicableTo(nucleotide));
248
249     /*
250      * TCoffee colour requires the presence of TCoffee score annotation
251      */
252     assertFalse(new TCoffeeColourScheme(peptide).isApplicableTo(peptide));
253     assertFalse(new TCoffeeColourScheme(nucleotide)
254             .isApplicableTo(nucleotide));
255     AlignmentAnnotation aa = new AlignmentAnnotation("T-COFFEE", "", null);
256     aa.setCalcId(TCoffeeScoreFile.TCOFFEE_SCORE);
257     peptide.addAnnotation(aa);
258     aa = new AlignmentAnnotation("T-COFFEE", "", null);
259     aa.setCalcId(TCoffeeScoreFile.TCOFFEE_SCORE);
260     nucleotide.addAnnotation(aa);
261     assertTrue(new TCoffeeColourScheme(peptide).isApplicableTo(peptide));
262     assertTrue(new TCoffeeColourScheme(nucleotide)
263             .isApplicableTo(nucleotide));
264
265     /*
266      * RNAHelices requires the presence of rna secondary structure
267      */
268     assertFalse(new RNAHelicesColour(peptide).isApplicableTo(peptide));
269     assertFalse(new RNAHelicesColour(nucleotide).isApplicableTo(nucleotide));
270     // add secondary structure (small but perfectly formed)
271     Annotation[] ss = new Annotation[2];
272     ss[0] = new Annotation("", "", '{', 0f);
273     ss[1] = new Annotation("", "", '}', 0f);
274     nucleotide.addAnnotation(new AlignmentAnnotation("SS", "", ss));
275     assertTrue(new RNAHelicesColour(nucleotide).isApplicableTo(nucleotide));
276   }
277
278   @Test
279   public void testIsApplicableTo_dynamicColourScheme()
280   {
281     SequenceI pep1 = new Sequence("pep1", "APQTWLS");
282     SequenceI pep2 = new Sequence("pep2", "AILFQYG");
283     AlignmentI peptide = new Alignment(new SequenceI[] { pep1, pep2 });
284   
285     /*
286      * demonstrate that we can 'plug in' a colour scheme with specified
287      * criteria for applicability; here, that there are more than 2 sequences
288      */
289     ColourSchemeI cs = new UserColourScheme()
290     {
291       @Override
292       public boolean isApplicableTo(AnnotatedCollectionI ac)
293       {
294         AlignmentI al = ac.getContext() == null ? (AlignmentI) ac
295                 : (AlignmentI) ac.getContext();
296         return al.getSequences().size() > 2;
297       }
298     };
299     assertFalse(cs.isApplicableTo(peptide));
300     peptide.addSequence(pep1);
301     assertTrue(cs.isApplicableTo(peptide));
302   }
303
304   @Test
305   public void testGetName()
306   {
307     SequenceI pep1 = new Sequence("pep1", "APQTWLS");
308     AlignmentI peptide = new Alignment(new SequenceI[] { pep1 });
309
310     assertEquals("Blosum62", new Blosum62ColourScheme().getSchemeName());
311     assertEquals("Buried Index", new BuriedColourScheme().getSchemeName());
312     assertEquals("Helix Propensity", new HelixColourScheme().getSchemeName());
313     assertEquals("Hydrophobic", new HydrophobicColourScheme().getSchemeName());
314     assertEquals("Strand Propensity", new StrandColourScheme().getSchemeName());
315     assertEquals("Taylor", new TaylorColourScheme().getSchemeName());
316     assertEquals("Turn Propensity", new TurnColourScheme().getSchemeName());
317     assertEquals("Zappo", new ZappoColourScheme().getSchemeName());
318     assertEquals("Nucleotide", new NucleotideColourScheme().getSchemeName());
319     assertEquals("Purine/Pyrimidine",
320             new PurinePyrimidineColourScheme().getSchemeName());
321     assertEquals("RNA Interaction type",
322             new RNAInteractionColourScheme().getSchemeName());
323     assertEquals("User Defined", new UserColourScheme().getSchemeName());
324     assertEquals("Score", new ScoreColourScheme(new int[] {},
325             new double[] {}, 0, 0d).getSchemeName());
326     assertEquals("Residue", new ResidueColourScheme().getSchemeName());
327     assertEquals("% Identity", new PIDColourScheme().getSchemeName());
328     assertEquals("Follower", new FollowerColourScheme().getSchemeName());
329     assertEquals("T-Coffee Scores",
330             new TCoffeeColourScheme(peptide).getSchemeName());
331     assertEquals("RNA Helices",
332             new RNAHelicesColour(peptide).getSchemeName());
333   }
334 }