JAL-1260 file formats and IdentifyFile updates for GenBank and ENA
[jalview.git] / test / jalview / analysis / ParsePropertiesTest.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.analysis;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNull;
25
26 import jalview.datamodel.Alignment;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.Sequence;
29 import jalview.datamodel.SequenceI;
30 import jalview.gui.AlignFrame;
31 import jalview.gui.JvOptionPane;
32
33 import java.util.List;
34
35 import org.testng.annotations.BeforeClass;
36 import org.testng.annotations.BeforeMethod;
37 import org.testng.annotations.Test;
38
39 public class ParsePropertiesTest
40 {
41
42   @BeforeClass(alwaysRun = true)
43   public void setUpJvOptionPane()
44   {
45     JvOptionPane.setInteractiveMode(false);
46     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
47   }
48
49   private Alignment al;
50
51   private ParseProperties pp;
52
53   /**
54    * Construct an alignment with 4 sequences with varying description format
55    */
56   @BeforeMethod(alwaysRun = true)
57   public void setUp()
58   {
59     SequenceI[] seqs = new SequenceI[] {
60         new Sequence("sq1", "THISISAPLACEHOLDER"),
61         new Sequence("sq2", "THISISAPLACEHOLDER"),
62         new Sequence("sq3", "THISISAPLACEHOLDER"),
63         new Sequence("sq4", "THISISAPLACEHOLDER") };
64     seqs[0].setDescription("1 mydescription1");
65     seqs[1].setDescription("mydescription2");
66     seqs[2].setDescription("2. 0.1 mydescription+3");
67     seqs[3].setDescription("3 0.01 mydescription4");
68     al = new Alignment(seqs);
69
70     pp = new ParseProperties(al);
71
72   }
73
74   /**
75    * Test with a description pattern that matches any string ending in one or
76    * more 'number characters' (0-9+.), i.e. greedily matches any trailing
77    * numeric part of the string
78    */
79   @Test(groups = { "Functional" })
80   public void testGetScoresFromDescription()
81   {
82     String regex = ".*([-0-9.+]+)";
83     final int count = pp.getScoresFromDescription("my Score",
84             "my Score Description", regex, true);
85     System.out.println("Matched " + count + " for " + regex);
86     assertEquals(4, count);
87
88     /*
89      * Verify values 1/2/3/4 have been parsed from sequence descriptions
90      */
91     AlignmentAnnotation[] anns = al.getSequenceAt(0).getAnnotation();
92     assertEquals(1, anns.length);
93     assertEquals(1d, anns[0].getScore(), 0.001d);
94     assertEquals("my Score Description", anns[0].description);
95     assertEquals("my Score", anns[0].label);
96     anns = al.getSequenceAt(1).getAnnotation();
97     assertEquals(1, anns.length);
98     assertEquals(2d, anns[0].getScore(), 0.001d);
99     assertEquals("my Score Description", anns[0].description);
100     assertEquals("my Score", anns[0].label);
101     anns = al.getSequenceAt(2).getAnnotation();
102     assertEquals(1, anns.length);
103     assertEquals(3d, anns[0].getScore(), 0.001d);
104     anns = al.getSequenceAt(3).getAnnotation();
105     assertEquals(1, anns.length);
106     assertEquals(4d, anns[0].getScore(), 0.001d);
107   }
108
109   /**
110    * Test with a description pattern that matches any string (or none), followed
111    * by a 'number character' (0-9+.), followed by at least one separator
112    * character, followed by at least one 'number character', then any trailing
113    * characters.
114    */
115   @Test(groups = { "Functional" })
116   public void testGetScoresFromDescription_twoScores()
117   {
118     String regex = ".*([-0-9.+]+).+([-0-9.+]+).*";
119     final int count = pp.getScoresFromDescription("my Score",
120             "my Score Description", regex, true);
121     System.out.println("Matched " + count + " for " + regex);
122     assertEquals(3, count);
123
124     /*
125      * Seq1 has two score values parsed out
126      */
127     AlignmentAnnotation[] anns = al.getSequenceAt(0).getAnnotation();
128     assertEquals(2, anns.length);
129     assertEquals(1d, anns[0].getScore(), 0.001d);
130     assertEquals("my Score Description", anns[0].description);
131     assertEquals("my Score", anns[0].label);
132     assertEquals(1d, anns[1].getScore(), 0.001d);
133     assertEquals("my Score Description (column 1)", anns[1].description);
134     assertEquals("my Score_1", anns[1].label);
135
136     /*
137      * Seq2 has no score parsed out (is this right?)
138      */
139     assertNull(al.getSequenceAt(1).getAnnotation());
140
141     /*
142      * Seq3 has two score values parsed out
143      */
144     // TODO parsed values (1.0 and 3.0) look wrong v description
145     // would expect 2.0 and 0.1
146     // undesired 'greedy' behaviour of regex?
147     anns = al.getSequenceAt(2).getAnnotation();
148     assertEquals(2, anns.length);
149     assertEquals(1d, anns[0].getScore(), 0.001d);
150     assertEquals("my Score Description", anns[0].description);
151     assertEquals("my Score", anns[0].label);
152     assertEquals(3d, anns[1].getScore(), 0.001d);
153     assertEquals("my Score Description (column 1)", anns[1].description);
154     assertEquals("my Score_1", anns[1].label);
155
156     /*
157      * Seq3 has two score values parsed out
158      */
159     // TODO parsed values (1.0 and 4.0) look wrong v description
160     // would expect 3 and 0.01
161     anns = al.getSequenceAt(3).getAnnotation();
162     assertEquals(2, anns.length);
163     assertEquals(1d, anns[0].getScore(), 0.001d);
164     assertEquals("my Score Description", anns[0].description);
165     assertEquals("my Score", anns[0].label);
166     assertEquals(4d, anns[1].getScore(), 0.001d);
167     assertEquals("my Score Description (column 1)", anns[1].description);
168     assertEquals("my Score_1", anns[1].label);
169   }
170
171   /**
172    * Test with a regex that looks for numbers separated by words - as currently
173    * used in Jalview (May 2015)
174    * 
175    * @see AlignFrame.extractScores_actionPerformed
176    */
177   @Test(groups = { "Functional" })
178   public void testGetScoresFromDescription_wordBoundaries()
179   {
180     String regex = "\\W*([-+eE0-9.]+)";
181     List<SequenceI> seqs = al.getSequences();
182     seqs.get(0).setDescription("Ferredoxin");
183     seqs.get(1).setDescription(" Ferredoxin-1, chloroplast precursor");
184     seqs.get(2).setDescription("GH28E30p");
185     seqs.get(3).setDescription("At1g10960/T19D16_12");
186     final int count = pp.getScoresFromDescription("description column",
187             "score in description column ", regex, true);
188     assertEquals(3, count);
189
190     /*
191      * No score parsable from seq1 description
192      */
193     AlignmentAnnotation[] anns = al.getSequenceAt(0).getAnnotation();
194     assertNull(anns);
195
196     /*
197      * Seq2 description has a '1' in it
198      */
199     anns = al.getSequenceAt(1).getAnnotation();
200     assertEquals(1, anns.length);
201     assertEquals(1d, anns[0].getScore(), 0.001d);
202
203     /*
204      * Seq3 description has '28E30' in it
205      * 
206      * Note: 1.8E308 or larger would result in 'Infinity'
207      */
208     anns = al.getSequenceAt(2).getAnnotation();
209     assertEquals(1, anns.length);
210     assertEquals(2.8E31d, anns[0].getScore(), 0.001d);
211
212     /*
213      * Seq4 description has several numbers in it
214      */
215     anns = al.getSequenceAt(3).getAnnotation();
216     assertEquals(5, anns.length);
217     assertEquals(1d, anns[0].getScore(), 0.001d);
218     assertEquals(10960d, anns[1].getScore(), 0.001d);
219     assertEquals(19d, anns[2].getScore(), 0.001d);
220     assertEquals(16d, anns[3].getScore(), 0.001d);
221     assertEquals(12d, anns[4].getScore(), 0.001d);
222   }
223 }