Clover icon

Coverage Report

  1. Project Clover database Wed Nov 12 2025 13:01:44 GMT
  2. Package jalview.datamodel

File AlignmentAnnotationTests.java

 

Code metrics

26
214
13
1
488
372
27
0.13
16.46
13
2.08

Classes

Class Line # Actions
AlignmentAnnotationTests 38 214 27
0.936758993.7%
 

Contributing tests

This file is covered by 13 tests. .

Source view

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.datamodel;
22   
23    import static org.testng.Assert.assertFalse;
24    import static org.testng.Assert.assertNull;
25    import static org.testng.Assert.assertTrue;
26    import static org.testng.AssertJUnit.assertEquals;
27   
28    import jalview.analysis.AlignSeq;
29    import jalview.gui.JvOptionPane;
30    import jalview.io.AppletFormatAdapter;
31    import jalview.io.FileFormat;
32   
33    import org.testng.Assert;
34    import org.testng.annotations.BeforeClass;
35    import org.testng.annotations.DataProvider;
36    import org.testng.annotations.Test;
37   
 
38    public class AlignmentAnnotationTests
39    {
40   
 
41  1 toggle @BeforeClass(alwaysRun = true)
42    public void setUpJvOptionPane()
43    {
44  1 JvOptionPane.setInteractiveMode(false);
45  1 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
46    }
47   
 
48  1 toggle @Test(groups = { "Functional" })
49    public void testCopyConstructor()
50    {
51  1 SequenceI sq = new Sequence("Foo", "ARAARARARAWEAWEAWRAWEAWE");
52  1 createAnnotation(sq);
53  1 AlignmentAnnotation alc, alo = sq.getAnnotation()[0];
54  1 alc = new AlignmentAnnotation(alo);
55  1 for (String key : alo.getProperties())
56    {
57  1 assertEquals("Property mismatch", alo.getProperty(key),
58    alc.getProperty(key));
59    }
60    }
61   
62    /**
63    * create some dummy annotation derived from the sequence
64    *
65    * @param sq
66    */
 
67  3 toggle public static void createAnnotation(SequenceI sq)
68    {
69  3 Annotation[] al = new Annotation[sq.getLength()];
70  41 for (int i = 0; i < al.length; i++)
71    {
72  38 al[i] = new Annotation(new Annotation("" + sq.getCharAt(i), "",
73    (char) 0, sq.findPosition(i)));
74    }
75  3 AlignmentAnnotation alan = new AlignmentAnnotation(
76    "For " + sq.getName(), "Fake alignment annot", al);
77    // create a sequence mapping for the annotation vector in its current state
78  3 alan.createSequenceMapping(sq, sq.getStart(), false);
79  3 alan.setProperty("CreatedBy", "createAnnotation");
80  3 sq.addAlignmentAnnotation(alan);
81    }
82   
83    /**
84    * use this to test annotation derived from method above as it is transferred
85    * across different sequences derived from same dataset coordinate frame
86    *
87    * @param ala
88    */
 
89  0 toggle public static void testAnnotTransfer(AlignmentAnnotation ala)
90    {
91  0 assertEquals(
92    "Failed - need annotation created by createAnnotation method",
93    ala.description, "Fake alignment annot");
94  0 ala.adjustForAlignment();
95  0 for (int p = 0; p < ala.annotations.length; p++)
96    {
97  0 if (ala.annotations[p] != null)
98    {
99  0 assertEquals(
100    "Mismatch at position " + p
101    + " between annotation position value and sequence"
102    + ala.annotations[p],
103    (int) ala.annotations[p].value,
104    ala.sequenceRef.findPosition(p));
105    }
106    }
107    }
108   
109    /**
110    * Tests the liftOver method and also exercises the functions for remapping
111    * annotation across different reference sequences. Here, the test is between
112    * different dataset frames (annotation transferred by mapping between
113    * sequences)
114    */
 
115  1 toggle @Test(groups = { "Functional" })
116    public void testLiftOver()
117    {
118  1 SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
119  1 sqFrom.setStart(10);
120  1 sqFrom.setEnd(sqFrom.findPosition(sqFrom.getLength() - 1));
121  1 SequenceI sqTo = new Sequence("toShort", "RCDEW");
122  1 sqTo.setStart(20);
123  1 sqTo.setEnd(sqTo.findPosition(sqTo.getLength() - 1));
124  1 createAnnotation(sqTo);
125  1 AlignmentAnnotation origTo = sqTo.getAnnotation()[0];
126  1 createAnnotation(sqFrom);
127  1 AlignmentAnnotation origFrom = sqFrom.getAnnotation()[0];
128  1 AlignSeq align = AlignSeq.doGlobalNWAlignment(sqFrom, sqTo,
129    AlignSeq.PEP);
130  1 SequenceI alSeq1 = new Sequence(sqFrom.getName(), align.getAStr1());
131  1 alSeq1.setStart(sqFrom.getStart() + align.getSeq1Start() - 1);
132  1 alSeq1.setEnd(sqFrom.getStart() + align.getSeq1End() - 1);
133  1 alSeq1.setDatasetSequence(sqFrom);
134  1 SequenceI alSeq2 = new Sequence(sqTo.getName(), align.getAStr2());
135  1 alSeq2.setStart(sqTo.getStart() + align.getSeq2Start() - 1);
136  1 alSeq2.setEnd(sqTo.getStart() + align.getSeq2End() - 1);
137  1 alSeq2.setDatasetSequence(sqTo);
138  1 System.out.println(new AppletFormatAdapter().formatSequences(
139    FileFormat.Stockholm, new Alignment(new SequenceI[]
140    { sqFrom, alSeq1, sqTo, alSeq2 }), true));
141   
142  1 Mapping mp = align.getMappingFromS1(false);
143   
144  1 AlignmentAnnotation almap1 = new AlignmentAnnotation(
145    sqTo.getAnnotation()[0]);
146  1 almap1.liftOver(sqFrom, mp);
147  1 assertEquals(almap1.sequenceRef, sqFrom);
148  1 alSeq1.addAlignmentAnnotation(almap1);
149  1 almap1.setSequenceRef(alSeq1);
150  1 almap1.adjustForAlignment();
151  1 AlignmentAnnotation almap2 = new AlignmentAnnotation(
152    sqFrom.getAnnotation()[0]);
153  1 almap2.liftOver(sqTo, mp);
154  1 assertEquals(almap2.sequenceRef, sqTo);
155   
156  1 alSeq2.addAlignmentAnnotation(almap2);
157  1 almap2.setSequenceRef(alSeq2);
158  1 almap2.adjustForAlignment();
159   
160  1 AlignmentI all = new Alignment(new SequenceI[] { alSeq1, alSeq2 });
161  1 all.addAnnotation(almap1);
162  1 all.addAnnotation(almap2);
163  1 System.out.println(new AppletFormatAdapter()
164    .formatSequences(FileFormat.Stockholm, all, true));
165   
166  6 for (int p = 0; p < alSeq1.getLength(); p++)
167    {
168  5 Annotation orig1, trans1, orig2, trans2;
169  5 trans2 = almap2.annotations[p];
170  5 orig2 = origFrom.annotations[alSeq1.findPosition(p)
171    - sqFrom.getStart()];
172  5 orig1 = origTo.annotations[alSeq2.findPosition(p) - sqTo.getStart()];
173  5 trans1 = almap1.annotations[p];
174  5 if (trans1 == trans2)
175    {
176  1 System.out.println("Pos " + p + " mismatch");
177  1 continue;
178    }
179  4 assertEquals(
180    "Mismatch on Original From and transferred annotation on 2",
181  4 (orig2 != null) ? orig2.toString() : null,
182  4 (trans2 != null) ? trans2.toString() : null);
183  4 assertEquals(
184    "Mismatch on Original To and transferred annotation on 1",
185  4 (orig1 != null) ? orig1.toString() : null,
186  4 (trans1 != null) ? trans1.toString() : null);
187  4 String alm1 = "" + (almap1.annotations.length > p
188    ? almap1.annotations[p].displayCharacter
189    : "Out of range");
190  4 String alm2 = "" + (almap2.annotations.length > p
191    ? almap2.annotations[p].displayCharacter
192    : "Out of range");
193  4 assertEquals("Position " + p + " " + alm1 + " " + alm2, alm1, alm2);
194    }
195    }
196   
 
197  1 toggle @Test(groups = { "Functional" })
198    public void testAdjustForAlignment()
199    {
200  1 SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
201  1 seq.createDatasetSequence();
202   
203    /*
204    * Annotate positions 3/4/5 (CDE) with values 1/2/3
205    */
206  1 Annotation[] anns = new Annotation[] { null, null, new Annotation(1),
207    new Annotation(2), new Annotation(3) };
208  1 AlignmentAnnotation ann = new AlignmentAnnotation("SS",
209    "secondary structure", anns);
210  1 seq.addAlignmentAnnotation(ann);
211   
212    /*
213    * Check annotation map before modifying aligned sequence
214    */
215  1 assertNull(ann.getAnnotationForPosition(1));
216  1 assertNull(ann.getAnnotationForPosition(2));
217  1 assertNull(ann.getAnnotationForPosition(6));
218  1 assertNull(ann.getAnnotationForPosition(7));
219  1 assertEquals(1, ann.getAnnotationForPosition(3).value, 0.001d);
220  1 assertEquals(2, ann.getAnnotationForPosition(4).value, 0.001d);
221  1 assertEquals(3, ann.getAnnotationForPosition(5).value, 0.001d);
222   
223    /*
224    * Trim the displayed sequence to BCD and adjust annotations
225    */
226  1 seq.setSequence("BCD");
227  1 seq.setStart(2);
228  1 seq.setEnd(4);
229  1 ann.adjustForAlignment();
230   
231    /*
232    * Should now have annotations for aligned positions 2, 3Q (CD) only
233    */
234  1 assertEquals(3, ann.annotations.length);
235  1 assertNull(ann.annotations[0]);
236  1 assertEquals(1, ann.annotations[1].value, 0.001);
237  1 assertEquals(2, ann.annotations[2].value, 0.001);
238    }
239   
240    /**
241    * Test the method that defaults rna symbol to the one matching the preceding
242    * unmatched opening bracket (if any)
243    */
 
244  1 toggle @Test(groups = { "Functional" })
245    public void testGetDefaultRnaHelixSymbol()
246    {
247  1 AlignmentAnnotation ann = new AlignmentAnnotation("SS",
248    "secondary structure", null);
249  1 assertEquals("(", ann.getDefaultRnaHelixSymbol(4));
250   
251  1 Annotation[] anns = new Annotation[20];
252  1 ann.annotations = anns;
253  1 assertEquals("(", ann.getDefaultRnaHelixSymbol(4));
254   
255  1 anns[1] = new Annotation("(", "S", '(', 0f);
256  1 assertEquals("(", ann.getDefaultRnaHelixSymbol(0));
257  1 assertEquals("(", ann.getDefaultRnaHelixSymbol(1));
258  1 assertEquals(")", ann.getDefaultRnaHelixSymbol(2));
259  1 assertEquals(")", ann.getDefaultRnaHelixSymbol(3));
260   
261    /*
262    * .(.[.{.<.}.>.).].
263    */
264  1 anns[1] = new Annotation("(", "S", '(', 0f);
265  1 anns[3] = new Annotation("[", "S", '[', 0f);
266  1 anns[5] = new Annotation("{", "S", '{', 0f);
267  1 anns[7] = new Annotation("<", "S", '<', 0f);
268  1 anns[9] = new Annotation("}", "S", '}', 0f);
269  1 anns[11] = new Annotation(">", "S", '>', 0f);
270  1 anns[13] = new Annotation(")", "S", ')', 0f);
271  1 anns[15] = new Annotation("]", "S", ']', 0f);
272   
273  1 String expected = "(())]]}}>>>>]]]](";
274  18 for (int i = 0; i < expected.length(); i++)
275    {
276  17 assertEquals("column " + i, String.valueOf(expected.charAt(i)),
277    ann.getDefaultRnaHelixSymbol(i));
278    }
279   
280    /*
281    * .(.[.(.).{.}.<.].D.
282    */
283  1 anns[1] = new Annotation("(", "S", '(', 0f);
284  1 anns[3] = new Annotation("[", "S", '[', 0f);
285  1 anns[5] = new Annotation("(", "S", '(', 0f);
286  1 anns[7] = new Annotation(")", "S", ')', 0f);
287  1 anns[9] = new Annotation("{", "S", '{', 0f);
288  1 anns[11] = new Annotation("}", "S", '}', 0f);
289  1 anns[13] = new Annotation("<", "S", '>', 0f);
290  1 anns[15] = new Annotation("]", "S", ']', 0f);
291  1 anns[17] = new Annotation("D", "S", 'D', 0f);
292   
293  1 expected = "(())]]))]]}}]]>>>>dd";
294  21 for (int i = 0; i < expected.length(); i++)
295    {
296  20 assertEquals("column " + i, String.valueOf(expected.charAt(i)),
297    ann.getDefaultRnaHelixSymbol(i));
298    }
299    }
300   
 
301  15 toggle public static Annotation newAnnotation(String ann)
302    {
303  15 float val = 0f;
304  15 try
305    {
306  15 val = Float.parseFloat(ann);
307    } catch (NumberFormatException q)
308    {
309    }
310  15 ;
311  15 return new Annotation(ann, ann, '\0', val);
312    }
313   
 
314  1 toggle @Test(groups = { "Functional" })
315    public void testIsQuantitative()
316    {
317  1 AlignmentAnnotation ann = null;
318   
319  1 ann = new AlignmentAnnotation("an", "some an", null);
320  1 Assert.assertFalse(ann.isQuantitative(),
321    "Empty annotation set should not be quantitative.");
322   
323  1 ann = new AlignmentAnnotation("an", "some an",
324    new Annotation[]
325    { newAnnotation("4"), newAnnotation("1"), newAnnotation("1"),
326    newAnnotation("0.1"), newAnnotation("0.3") });
327  1 Assert.assertTrue(ann.isQuantitative(),
328    "All numbers annotation set should be quantitative.");
329   
330  1 ann = new AlignmentAnnotation("an", "some an",
331    new Annotation[]
332    { newAnnotation("E"), newAnnotation("E"), newAnnotation("E"),
333    newAnnotation("E"), newAnnotation("E") });
334  1 Assert.assertFalse(ann.isQuantitative(),
335    "All 'E' annotation set should not be quantitative.");
336   
337  1 ann = new AlignmentAnnotation("an", "some an",
338    new Annotation[]
339    { newAnnotation("E"), newAnnotation("1"), newAnnotation("2"),
340    newAnnotation("3"), newAnnotation("E") });
341  1 Assert.assertTrue(ann.isQuantitative(),
342    "Mixed 'E' annotation set should be quantitative.");
343    }
344   
 
345  1 toggle @Test(groups = "Functional")
346    public void testMakeVisibleAnnotation()
347    {
348  1 HiddenColumns h = new HiddenColumns();
349  1 Annotation[] anns = new Annotation[] { null, null, new Annotation(1),
350    new Annotation(2), new Annotation(3), null, null, new Annotation(4),
351    new Annotation(5), new Annotation(6), new Annotation(7),
352    new Annotation(8) };
353  1 AlignmentAnnotation ann = new AlignmentAnnotation("an", "some an",
354    anns);
355   
356    // null annotations
357  1 AlignmentAnnotation emptyann = new AlignmentAnnotation("an", "some ann",
358    null);
359  1 emptyann.makeVisibleAnnotation(h);
360  1 assertNull(emptyann.annotations);
361   
362  1 emptyann.makeVisibleAnnotation(3, 4, h);
363  1 assertNull(emptyann.annotations);
364   
365    // without bounds, does everything
366  1 ann.makeVisibleAnnotation(h);
367  1 assertEquals(12, ann.annotations.length);
368  1 assertNull(ann.annotations[0]);
369  1 assertNull(ann.annotations[1]);
370  1 assertEquals(1.0f, ann.annotations[2].value);
371  1 assertEquals(2.0f, ann.annotations[3].value);
372  1 assertEquals(3.0f, ann.annotations[4].value);
373  1 assertNull(ann.annotations[5]);
374  1 assertNull(ann.annotations[6]);
375  1 assertEquals(4.0f, ann.annotations[7].value);
376  1 assertEquals(5.0f, ann.annotations[8].value);
377  1 assertEquals(6.0f, ann.annotations[9].value);
378  1 assertEquals(7.0f, ann.annotations[10].value);
379  1 assertEquals(8.0f, ann.annotations[11].value);
380   
381    // without hidden cols, just truncates
382  1 ann.makeVisibleAnnotation(3, 5, h);
383  1 assertEquals(3, ann.annotations.length);
384  1 assertEquals(2.0f, ann.annotations[0].value);
385  1 assertEquals(3.0f, ann.annotations[1].value);
386  1 assertNull(ann.annotations[2]);
387   
388  1 anns = new Annotation[] { null, null, new Annotation(1),
389    new Annotation(2), new Annotation(3), null, null, new Annotation(4),
390    new Annotation(5), new Annotation(6), new Annotation(7),
391    new Annotation(8) };
392  1 ann = new AlignmentAnnotation("an", "some an", anns);
393  1 h.hideColumns(4, 7);
394  1 ann.makeVisibleAnnotation(1, 9, h);
395  1 assertEquals(5, ann.annotations.length);
396  1 assertNull(ann.annotations[0]);
397  1 assertEquals(1.0f, ann.annotations[1].value);
398  1 assertEquals(2.0f, ann.annotations[2].value);
399  1 assertEquals(5.0f, ann.annotations[3].value);
400  1 assertEquals(6.0f, ann.annotations[4].value);
401   
402  1 anns = new Annotation[] { null, null, new Annotation(1),
403    new Annotation(2), new Annotation(3), null, null, new Annotation(4),
404    new Annotation(5), new Annotation(6), new Annotation(7),
405    new Annotation(8) };
406  1 ann = new AlignmentAnnotation("an", "some an", anns);
407  1 h.hideColumns(1, 2);
408  1 ann.makeVisibleAnnotation(1, 9, h);
409  1 assertEquals(3, ann.annotations.length);
410  1 assertEquals(2.0f, ann.annotations[0].value);
411  1 assertEquals(5.0f, ann.annotations[1].value);
412  1 assertEquals(6.0f, ann.annotations[2].value);
413   
414  1 anns = new Annotation[] { null, null, new Annotation(1),
415    new Annotation(2), new Annotation(3), null, null, new Annotation(4),
416    new Annotation(5), new Annotation(6), new Annotation(7),
417    new Annotation(8), new Annotation(9), new Annotation(10),
418    new Annotation(11), new Annotation(12), new Annotation(13),
419    new Annotation(14), new Annotation(15) };
420  1 ann = new AlignmentAnnotation("an", "some an", anns);
421  1 h = new HiddenColumns();
422  1 h.hideColumns(5, 18);
423  1 h.hideColumns(20, 21);
424  1 ann.makeVisibleAnnotation(1, 21, h);
425  1 assertEquals(5, ann.annotations.length);
426  1 assertEquals(1.0f, ann.annotations[1].value);
427  1 assertEquals(2.0f, ann.annotations[2].value);
428  1 assertEquals(3.0f, ann.annotations[3].value);
429  1 assertNull(ann.annotations[0]);
430  1 assertNull(ann.annotations[4]);
431    }
432   
433    /**
434    * test the contact matrix nogroups property methods
435    */
 
436  1 toggle @Test(groups = { "Functional" })
437    public void test_contactMatrixGroups()
438    {
439  1 AlignmentAnnotation aa = new AlignmentAnnotation("foo", "foo desc",
440    null);
441  1 assertTrue(aa.isShowGroupsForContactMatrix());
442  1 aa.setShowGroupsForContactMatrix(false);
443  1 assertFalse(aa.isShowGroupsForContactMatrix());
444  1 AlignmentAnnotation copy = new AlignmentAnnotation(aa);
445  1 assertFalse(copy.isShowGroupsForContactMatrix());
446  1 aa.setShowGroupsForContactMatrix(true);
447  1 assertTrue(aa.isShowGroupsForContactMatrix());
448    // copy should not be updated
449  1 assertFalse(copy.isShowGroupsForContactMatrix());
450   
451    }
452   
 
453  1 toggle @DataProvider(name = "data_labelAndCalcIdMatches")
454    public Object[][] testData()
455    {
456  1 String label = "label";
457  1 String wrongLabel = "wrongLabel";
458  1 String calcId = "123";
459  1 String wrongCalcId = "abc";
460  1 AlignmentAnnotation aaWithCalcId = new AlignmentAnnotation(label, "foo desc",
461    null);
462  1 aaWithCalcId.setCalcId(calcId);
463   
464  1 AlignmentAnnotation aaWithoutCalcId = new AlignmentAnnotation(label, "foo desc",
465    null);
466  1 return new Object[][] { { aaWithCalcId, label, calcId, true },
467    { aaWithCalcId, wrongLabel, calcId, false },
468    { aaWithCalcId, label, wrongCalcId, false },
469    { aaWithCalcId, wrongLabel, wrongCalcId, false },
470    { aaWithCalcId, label, null, false },
471    { aaWithoutCalcId, label, "", true },
472    { aaWithoutCalcId, label, calcId, false },
473    { aaWithoutCalcId, wrongLabel, null, false },
474    { aaWithoutCalcId, wrongLabel, wrongCalcId, false },
475    };
476    }
477   
478    /**
479    * test the labelAndCalcIdMatches method
480    */
 
481  9 toggle @Test(groups = { "Functional" }, dataProvider = "data_labelAndCalcIdMatches")
482    public void test_labelAndCalcIdMatches(AlignmentAnnotation aa, String label, String calcId, boolean expected)
483    {
484  9 boolean result = aa.labelAndCalcIdMatches(label, calcId);
485  9 assertEquals(expected, result);
486    }
487   
488    }