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.io.AppletFormatAdapter;
28 import jalview.io.FileFormat;
30 import org.testng.annotations.Test;
32 public class AlignmentAnnotationTests
34 @Test(groups = { "Functional" })
35 public void testCopyConstructor()
37 SequenceI sq = new Sequence("Foo", "ARAARARARAWEAWEAWRAWEAWE");
39 AlignmentAnnotation alc, alo = sq.getAnnotation()[0];
40 alc = new AlignmentAnnotation(alo);
41 for (String key : alo.getProperties())
43 assertEquals("Property mismatch", alo.getProperty(key),
44 alc.getProperty(key));
49 * create some dummy annotation derived from the sequence
53 public static void createAnnotation(SequenceI sq)
55 Annotation[] al = new Annotation[sq.getLength()];
56 for (int i = 0; i < al.length; i++)
58 al[i] = new Annotation(new Annotation("" + sq.getCharAt(i), "",
59 (char) 0, sq.findPosition(i)));
61 AlignmentAnnotation alan = new AlignmentAnnotation("For "
62 + sq.getName(), "Fake alignment annot", al);
63 // create a sequence mapping for the annotation vector in its current state
64 alan.createSequenceMapping(sq, sq.getStart(), false);
65 alan.setProperty("CreatedBy", "createAnnotation");
66 sq.addAlignmentAnnotation(alan);
70 * use this to test annotation derived from method above as it is transferred
71 * across different sequences derived from same dataset coordinate frame
75 public static void testAnnotTransfer(AlignmentAnnotation ala)
78 "Failed - need annotation created by createAnnotation method",
79 ala.description, "Fake alignment annot");
80 ala.adjustForAlignment();
81 for (int p = 0; p < ala.annotations.length; p++)
83 if (ala.annotations[p] != null)
85 assertEquals("Mismatch at position " + p
86 + " between annotation position value and sequence"
87 + ala.annotations[p], (int) ala.annotations[p].value,
88 ala.sequenceRef.findPosition(p));
94 * Tests the liftOver method and also exercises the functions for remapping
95 * annotation across different reference sequences. Here, the test is between
96 * different dataset frames (annotation transferred by mapping between
99 @Test(groups = { "Functional" })
100 public void testLiftOver()
102 SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
104 sqFrom.setEnd(sqFrom.findPosition(sqFrom.getLength() - 1));
105 SequenceI sqTo = new Sequence("toShort", "RCDEW");
107 sqTo.setEnd(sqTo.findPosition(sqTo.getLength() - 1));
108 createAnnotation(sqTo);
109 AlignmentAnnotation origTo = sqTo.getAnnotation()[0];
110 createAnnotation(sqFrom);
111 AlignmentAnnotation origFrom = sqFrom.getAnnotation()[0];
112 AlignSeq align = AlignSeq.doGlobalNWAlignment(sqFrom, sqTo,
114 SequenceI alSeq1 = new Sequence(sqFrom.getName(), align.getAStr1());
115 alSeq1.setStart(sqFrom.getStart() + align.getSeq1Start() - 1);
116 alSeq1.setEnd(sqFrom.getStart() + align.getSeq1End() - 1);
117 alSeq1.setDatasetSequence(sqFrom);
118 SequenceI alSeq2 = new Sequence(sqTo.getName(), align.getAStr2());
119 alSeq2.setStart(sqTo.getStart() + align.getSeq2Start() - 1);
120 alSeq2.setEnd(sqTo.getStart() + align.getSeq2End() - 1);
121 alSeq2.setDatasetSequence(sqTo);
122 System.out.println(new AppletFormatAdapter()
124 FileFormat.Stockholm, new Alignment(new SequenceI[] { sqFrom,
125 alSeq1, sqTo, alSeq2 }), true));
127 Mapping mp = align.getMappingFromS1(false);
129 AlignmentAnnotation almap1 = new AlignmentAnnotation(
130 sqTo.getAnnotation()[0]);
131 almap1.liftOver(sqFrom, mp);
132 assertEquals(almap1.sequenceRef, sqFrom);
133 alSeq1.addAlignmentAnnotation(almap1);
134 almap1.setSequenceRef(alSeq1);
135 almap1.adjustForAlignment();
136 AlignmentAnnotation almap2 = new AlignmentAnnotation(
137 sqFrom.getAnnotation()[0]);
138 almap2.liftOver(sqTo, mp);
139 assertEquals(almap2.sequenceRef, sqTo);
141 alSeq2.addAlignmentAnnotation(almap2);
142 almap2.setSequenceRef(alSeq2);
143 almap2.adjustForAlignment();
145 AlignmentI all = new Alignment(new SequenceI[] { alSeq1, alSeq2 });
146 all.addAnnotation(almap1);
147 all.addAnnotation(almap2);
148 System.out.println(new AppletFormatAdapter().formatSequences(
149 FileFormat.Stockholm,
152 for (int p = 0; p < alSeq1.getLength(); p++)
154 Annotation orig1, trans1, orig2, trans2;
155 trans2 = almap2.annotations[p];
156 orig2 = origFrom.annotations[alSeq1.findPosition(p)
157 - sqFrom.getStart()];
158 orig1 = origTo.annotations[alSeq2.findPosition(p) - sqTo.getStart()];
159 trans1 = almap1.annotations[p];
160 if (trans1 == trans2)
162 System.out.println("Pos " + p + " mismatch");
166 "Mismatch on Original From and transferred annotation on 2",
167 (orig2 != null) ? orig2.toString() : null,
168 (trans2 != null) ? trans2.toString() : null);
170 "Mismatch on Original To and transferred annotation on 1",
171 (orig1 != null) ? orig1.toString() : null,
172 (trans1 != null) ? trans1.toString() : null);
174 + (almap1.annotations.length > p ? almap1.annotations[p].displayCharacter
177 + (almap2.annotations.length > p ? almap2.annotations[p].displayCharacter
179 assertEquals("Position " + p + " " + alm1 + " " + alm2, alm1, alm2);
183 @Test(groups = { "Functional" })
184 public void testAdjustForAlignment()
186 SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
187 seq.createDatasetSequence();
190 * Annotate positions 3/4/5 (CDE) with values 1/2/3
192 Annotation[] anns = new Annotation[] { null, null, new Annotation(1),
193 new Annotation(2), new Annotation(3) };
194 AlignmentAnnotation ann = new AlignmentAnnotation("SS",
195 "secondary structure", anns);
196 seq.addAlignmentAnnotation(ann);
199 * Check annotation map before modifying aligned sequence
201 assertNull(ann.getAnnotationForPosition(1));
202 assertNull(ann.getAnnotationForPosition(2));
203 assertNull(ann.getAnnotationForPosition(6));
204 assertNull(ann.getAnnotationForPosition(7));
205 assertEquals(1, ann.getAnnotationForPosition(3).value, 0.001d);
206 assertEquals(2, ann.getAnnotationForPosition(4).value, 0.001d);
207 assertEquals(3, ann.getAnnotationForPosition(5).value, 0.001d);
210 * Trim the displayed sequence to BCD and adjust annotations
212 seq.setSequence("BCD");
215 ann.adjustForAlignment();
218 * Should now have annotations for aligned positions 2, 3Q (CD) only
220 assertEquals(3, ann.annotations.length);
221 assertNull(ann.annotations[0]);
222 assertEquals(1, ann.annotations[1].value, 0.001);
223 assertEquals(2, ann.annotations[2].value, 0.001);