2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.datamodel;
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNull;
26 import jalview.analysis.AlignSeq;
27 import jalview.gui.JvOptionPane;
28 import jalview.io.AppletFormatAdapter;
29 import jalview.io.FileFormat;
31 import org.testng.Assert;
32 import org.testng.annotations.BeforeClass;
33 import org.testng.annotations.Test;
35 public class AlignmentAnnotationTests
38 @BeforeClass(alwaysRun = true)
39 public void setUpJvOptionPane()
41 JvOptionPane.setInteractiveMode(false);
42 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
45 @Test(groups = { "Functional" })
46 public void testCopyConstructor()
48 SequenceI sq = new Sequence("Foo", "ARAARARARAWEAWEAWRAWEAWE");
50 AlignmentAnnotation alc, alo = sq.getAnnotation()[0];
51 alc = new AlignmentAnnotation(alo);
52 for (String key : alo.getProperties())
54 assertEquals("Property mismatch", alo.getProperty(key),
55 alc.getProperty(key));
60 * create some dummy annotation derived from the sequence
64 public static void createAnnotation(SequenceI sq)
66 Annotation[] al = new Annotation[sq.getLength()];
67 for (int i = 0; i < al.length; i++)
69 al[i] = new Annotation(new Annotation("" + sq.getCharAt(i), "",
70 (char) 0, sq.findPosition(i)));
72 AlignmentAnnotation alan = new AlignmentAnnotation("For "
73 + sq.getName(), "Fake alignment annot", al);
74 // create a sequence mapping for the annotation vector in its current state
75 alan.createSequenceMapping(sq, sq.getStart(), false);
76 alan.setProperty("CreatedBy", "createAnnotation");
77 sq.addAlignmentAnnotation(alan);
81 * use this to test annotation derived from method above as it is transferred
82 * across different sequences derived from same dataset coordinate frame
86 public static void testAnnotTransfer(AlignmentAnnotation ala)
89 "Failed - need annotation created by createAnnotation method",
90 ala.description, "Fake alignment annot");
91 ala.adjustForAlignment();
92 for (int p = 0; p < ala.annotations.length; p++)
94 if (ala.annotations[p] != null)
96 assertEquals("Mismatch at position " + p
97 + " between annotation position value and sequence"
98 + ala.annotations[p], (int) ala.annotations[p].value,
99 ala.sequenceRef.findPosition(p));
105 * Tests the liftOver method and also exercises the functions for remapping
106 * annotation across different reference sequences. Here, the test is between
107 * different dataset frames (annotation transferred by mapping between
110 @Test(groups = { "Functional" })
111 public void testLiftOver()
113 SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
115 sqFrom.setEnd(sqFrom.findPosition(sqFrom.getLength() - 1));
116 SequenceI sqTo = new Sequence("toShort", "RCDEW");
118 sqTo.setEnd(sqTo.findPosition(sqTo.getLength() - 1));
119 createAnnotation(sqTo);
120 AlignmentAnnotation origTo = sqTo.getAnnotation()[0];
121 createAnnotation(sqFrom);
122 AlignmentAnnotation origFrom = sqFrom.getAnnotation()[0];
123 AlignSeq align = AlignSeq.doGlobalNWAlignment(sqFrom, sqTo,
125 SequenceI alSeq1 = new Sequence(sqFrom.getName(), align.getAStr1());
126 alSeq1.setStart(sqFrom.getStart() + align.getSeq1Start() - 1);
127 alSeq1.setEnd(sqFrom.getStart() + align.getSeq1End() - 1);
128 alSeq1.setDatasetSequence(sqFrom);
129 SequenceI alSeq2 = new Sequence(sqTo.getName(), align.getAStr2());
130 alSeq2.setStart(sqTo.getStart() + align.getSeq2Start() - 1);
131 alSeq2.setEnd(sqTo.getStart() + align.getSeq2End() - 1);
132 alSeq2.setDatasetSequence(sqTo);
133 System.out.println(new AppletFormatAdapter()
135 FileFormat.Stockholm, new Alignment(new SequenceI[] { sqFrom,
136 alSeq1, sqTo, alSeq2 }), true));
138 Mapping mp = align.getMappingFromS1(false);
140 AlignmentAnnotation almap1 = new AlignmentAnnotation(
141 sqTo.getAnnotation()[0]);
142 almap1.liftOver(sqFrom, mp);
143 assertEquals(almap1.sequenceRef, sqFrom);
144 alSeq1.addAlignmentAnnotation(almap1);
145 almap1.setSequenceRef(alSeq1);
146 almap1.adjustForAlignment();
147 AlignmentAnnotation almap2 = new AlignmentAnnotation(
148 sqFrom.getAnnotation()[0]);
149 almap2.liftOver(sqTo, mp);
150 assertEquals(almap2.sequenceRef, sqTo);
152 alSeq2.addAlignmentAnnotation(almap2);
153 almap2.setSequenceRef(alSeq2);
154 almap2.adjustForAlignment();
156 AlignmentI all = new Alignment(new SequenceI[] { alSeq1, alSeq2 });
157 all.addAnnotation(almap1);
158 all.addAnnotation(almap2);
159 System.out.println(new AppletFormatAdapter().formatSequences(
160 FileFormat.Stockholm,
163 for (int p = 0; p < alSeq1.getLength(); p++)
165 Annotation orig1, trans1, orig2, trans2;
166 trans2 = almap2.annotations[p];
167 orig2 = origFrom.annotations[alSeq1.findPosition(p)
168 - sqFrom.getStart()];
169 orig1 = origTo.annotations[alSeq2.findPosition(p) - sqTo.getStart()];
170 trans1 = almap1.annotations[p];
171 if (trans1 == trans2)
173 System.out.println("Pos " + p + " mismatch");
177 "Mismatch on Original From and transferred annotation on 2",
178 (orig2 != null) ? orig2.toString() : null,
179 (trans2 != null) ? trans2.toString() : null);
181 "Mismatch on Original To and transferred annotation on 1",
182 (orig1 != null) ? orig1.toString() : null,
183 (trans1 != null) ? trans1.toString() : null);
185 + (almap1.annotations.length > p ? almap1.annotations[p].displayCharacter
188 + (almap2.annotations.length > p ? almap2.annotations[p].displayCharacter
190 assertEquals("Position " + p + " " + alm1 + " " + alm2, alm1, alm2);
194 @Test(groups = { "Functional" })
195 public void testAdjustForAlignment()
197 SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
198 seq.createDatasetSequence();
201 * Annotate positions 3/4/5 (CDE) with values 1/2/3
203 Annotation[] anns = new Annotation[] { null, null, new Annotation(1),
204 new Annotation(2), new Annotation(3) };
205 AlignmentAnnotation ann = new AlignmentAnnotation("SS",
206 "secondary structure", anns);
207 seq.addAlignmentAnnotation(ann);
210 * Check annotation map before modifying aligned sequence
212 assertNull(ann.getAnnotationForPosition(1));
213 assertNull(ann.getAnnotationForPosition(2));
214 assertNull(ann.getAnnotationForPosition(6));
215 assertNull(ann.getAnnotationForPosition(7));
216 assertEquals(1, ann.getAnnotationForPosition(3).value, 0.001d);
217 assertEquals(2, ann.getAnnotationForPosition(4).value, 0.001d);
218 assertEquals(3, ann.getAnnotationForPosition(5).value, 0.001d);
221 * Trim the displayed sequence to BCD and adjust annotations
223 seq.setSequence("BCD");
226 ann.adjustForAlignment();
229 * Should now have annotations for aligned positions 2, 3Q (CD) only
231 assertEquals(3, ann.annotations.length);
232 assertNull(ann.annotations[0]);
233 assertEquals(1, ann.annotations[1].value, 0.001);
234 assertEquals(2, ann.annotations[2].value, 0.001);
238 * Test the method that defaults rna symbol to the one matching the preceding
239 * unmatched opening bracket (if any)
241 @Test(groups = { "Functional" })
242 public void testGetDefaultRnaHelixSymbol()
244 AlignmentAnnotation ann = new AlignmentAnnotation("SS",
245 "secondary structure", null);
246 assertEquals("(", ann.getDefaultRnaHelixSymbol(4));
248 Annotation[] anns = new Annotation[20];
249 ann.annotations = anns;
250 assertEquals("(", ann.getDefaultRnaHelixSymbol(4));
252 anns[1] = new Annotation("(", "S", '(', 0f);
253 assertEquals("(", ann.getDefaultRnaHelixSymbol(0));
254 assertEquals("(", ann.getDefaultRnaHelixSymbol(1));
255 assertEquals(")", ann.getDefaultRnaHelixSymbol(2));
256 assertEquals(")", ann.getDefaultRnaHelixSymbol(3));
261 anns[1] = new Annotation("(", "S", '(', 0f);
262 anns[3] = new Annotation("[", "S", '[', 0f);
263 anns[5] = new Annotation("{", "S", '{', 0f);
264 anns[7] = new Annotation("<", "S", '<', 0f);
265 anns[9] = new Annotation("}", "S", '}', 0f);
266 anns[11] = new Annotation(">", "S", '>', 0f);
267 anns[13] = new Annotation(")", "S", ')', 0f);
268 anns[15] = new Annotation("]", "S", ']', 0f);
270 String expected = "(())]]}}>>>>]]]](";
271 for (int i = 0; i < expected.length(); i++)
273 assertEquals("column " + i, String.valueOf(expected.charAt(i)),
274 ann.getDefaultRnaHelixSymbol(i));
278 * .(.[.(.).{.}.<.].D.
280 anns[1] = new Annotation("(", "S", '(', 0f);
281 anns[3] = new Annotation("[", "S", '[', 0f);
282 anns[5] = new Annotation("(", "S", '(', 0f);
283 anns[7] = new Annotation(")", "S", ')', 0f);
284 anns[9] = new Annotation("{", "S", '{', 0f);
285 anns[11] = new Annotation("}", "S", '}', 0f);
286 anns[13] = new Annotation("<", "S", '>', 0f);
287 anns[15] = new Annotation("]", "S", ']', 0f);
288 anns[17] = new Annotation("D", "S", 'D', 0f);
290 expected = "(())]]))]]}}]]>>>>dd";
291 for (int i = 0; i < expected.length(); i++)
293 assertEquals("column " + i, String.valueOf(expected.charAt(i)),
294 ann.getDefaultRnaHelixSymbol(i));
298 public static Annotation newAnnotation(String ann)
303 val = Float.parseFloat(ann);
304 } catch (NumberFormatException q)
308 return new Annotation(ann, ann, '\0', val);
311 @Test(groups = { "Functional" })
312 public void testIsQuantitative()
314 AlignmentAnnotation ann = null;
316 ann = new AlignmentAnnotation("an", "some an", null);
317 Assert.assertFalse(ann.isQuantitative(),
318 "Empty annotation set should not be quantitative.");
320 ann = new AlignmentAnnotation("an", "some an", new Annotation[] {
321 newAnnotation("4"), newAnnotation("1"), newAnnotation("1"),
322 newAnnotation("0.1"), newAnnotation("0.3") });
323 Assert.assertTrue(ann.isQuantitative(),
324 "All numbers annotation set should be quantitative.");
326 ann = new AlignmentAnnotation("an", "some an", new Annotation[] {
327 newAnnotation("E"), newAnnotation("E"), newAnnotation("E"),
328 newAnnotation("E"), newAnnotation("E") });
329 Assert.assertFalse(ann.isQuantitative(),
330 "All 'E' annotation set should not be quantitative.");
332 ann = new AlignmentAnnotation("an", "some an", new Annotation[] {
333 newAnnotation("E"), newAnnotation("1"), newAnnotation("2"),
334 newAnnotation("3"), newAnnotation("E") });
335 Assert.assertTrue(ann.isQuantitative(),
336 "Mixed 'E' annotation set should be quantitative.");