5d67cb74c79a969184f86a383f565602169d4bba
[jalview.git] / test / jalview / datamodel / AlignmentAnnotationTests.java
1 package jalview.datamodel;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertNull;
5 import org.testng.annotations.Test;
6 import jalview.analysis.AlignSeq;
7 import jalview.io.AppletFormatAdapter;
8
9 public class AlignmentAnnotationTests
10 {
11   @Test
12   public void testCopyConstructor()
13   {
14     SequenceI sq = new Sequence("Foo", "ARAARARARAWEAWEAWRAWEAWE");
15     createAnnotation(sq);
16     AlignmentAnnotation alc, alo = sq.getAnnotation()[0];
17     alc = new AlignmentAnnotation(alo);
18     for (String key : alo.getProperties())
19     {
20       assertEquals("Property mismatch", alo.getProperty(key),
21               alc.getProperty(key));
22     }
23   }
24   /**
25    * create some dummy annotation derived from the sequence
26    * 
27    * @param sq
28    */
29   public static void createAnnotation(SequenceI sq)
30   {
31     Annotation[] al = new Annotation[sq.getLength()];
32     for (int i = 0; i < al.length; i++)
33     {
34       al[i] = new Annotation(new Annotation("" + sq.getCharAt(i), "",
35               (char) 0, sq.findPosition(i)));
36     }
37     AlignmentAnnotation alan = new AlignmentAnnotation("For "
38             + sq.getName(), "Fake alignment annot", al);
39     // create a sequence mapping for the annotation vector in its current state
40     alan.createSequenceMapping(sq, sq.getStart(), false);
41     alan.setProperty("CreatedBy", "createAnnotation");
42     sq.addAlignmentAnnotation(alan);
43   }
44
45   /**
46    * use this to test annotation derived from method above as it is transferred
47    * across different sequences derived from same dataset coordinate frame
48    * 
49    * @param ala
50    */
51   public static void testAnnotTransfer(AlignmentAnnotation ala)
52   {
53     assertEquals(
54             "Failed - need annotation created by createAnnotation method",
55             ala.description, "Fake alignment annot");
56     ala.adjustForAlignment();
57     for (int p = 0; p < ala.annotations.length; p++)
58     {
59       if (ala.annotations[p] != null)
60       {
61         assertEquals("Mismatch at position " + p
62                 + " between annotation position value and sequence"
63                 + ala.annotations[p], (int) ala.annotations[p].value,
64                 ala.sequenceRef.findPosition(p));
65       }
66     }
67   }
68
69   /**
70    * Tests the liftOver method and also exercises the functions for remapping
71    * annotation across different reference sequences. Here, the test is between
72    * different dataset frames (annotation transferred by mapping between
73    * sequences)
74    */
75   @Test
76   public void testLiftOver()
77   {
78     SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
79     sqFrom.setStart(10);
80     sqFrom.setEnd(sqFrom.findPosition(sqFrom.getLength() - 1));
81     SequenceI sqTo = new Sequence("toShort", "RCDEW");
82     sqTo.setStart(20);
83     sqTo.setEnd(sqTo.findPosition(sqTo.getLength() - 1));
84     createAnnotation(sqTo);
85     AlignmentAnnotation origTo = sqTo.getAnnotation()[0];
86     createAnnotation(sqFrom);
87     AlignmentAnnotation origFrom = sqFrom.getAnnotation()[0];
88     AlignSeq align = AlignSeq.doGlobalNWAlignment(sqFrom, sqTo,
89             AlignSeq.PEP);
90     SequenceI alSeq1 = new Sequence(sqFrom.getName(), align.getAStr1());
91     alSeq1.setStart(sqFrom.getStart() + align.getSeq1Start() - 1);
92     alSeq1.setEnd(sqFrom.getStart() + align.getSeq1End() - 1);
93     alSeq1.setDatasetSequence(sqFrom);
94     SequenceI alSeq2 = new Sequence(sqTo.getName(), align.getAStr2());
95     alSeq2.setStart(sqTo.getStart() + align.getSeq2Start() - 1);
96     alSeq2.setEnd(sqTo.getStart() + align.getSeq2End() - 1);
97     alSeq2.setDatasetSequence(sqTo);
98     System.out.println(new AppletFormatAdapter().formatSequences("STH",
99             new Alignment(new SequenceI[]
100             { sqFrom, alSeq1, sqTo, alSeq2 }), true));
101
102     Mapping mp = align.getMappingFromS1(false);
103
104     AlignmentAnnotation almap1 = new AlignmentAnnotation(
105             sqTo.getAnnotation()[0]);
106     almap1.liftOver(sqFrom, mp);
107     assertEquals(almap1.sequenceRef, sqFrom);
108     alSeq1.addAlignmentAnnotation(almap1);
109     almap1.setSequenceRef(alSeq1);
110     almap1.adjustForAlignment();
111     AlignmentAnnotation almap2 = new AlignmentAnnotation(
112             sqFrom.getAnnotation()[0]);
113     almap2.liftOver(sqTo, mp);
114     assertEquals(almap2.sequenceRef, sqTo);
115
116     alSeq2.addAlignmentAnnotation(almap2);
117     almap2.setSequenceRef(alSeq2);
118     almap2.adjustForAlignment();
119
120     AlignmentI all = new Alignment(new SequenceI[]
121     { alSeq1, alSeq2 });
122     all.addAnnotation(almap1);
123     all.addAnnotation(almap2);
124     System.out.println(new AppletFormatAdapter().formatSequences("STH",
125             all, true));
126
127     for (int p = 0; p < alSeq1.getLength(); p++)
128     {
129       Annotation orig1, trans1, orig2, trans2;
130       trans2 = almap2.annotations[p];
131       orig2 = origFrom.annotations[alSeq1.findPosition(p)
132               - sqFrom.getStart()];
133       orig1 = origTo.annotations[alSeq2.findPosition(p) - sqTo.getStart()];
134       trans1 = almap1.annotations[p];
135       if (trans1 == trans2)
136       {
137         System.out.println("Pos " + p + " mismatch");
138         continue;
139       }
140       assertEquals(
141               "Mismatch on Original From and transferred annotation on 2",
142               (orig2 != null) ? orig2.toString() : null,
143               (trans2 != null) ? trans2.toString() : null);
144       assertEquals(
145               "Mismatch on Original To and transferred annotation on 1",
146               (orig1 != null) ? orig1.toString() : null,
147               (trans1 != null) ? trans1.toString() : null);
148       String alm1 = ""
149               + (almap1.annotations.length > p ? almap1.annotations[p].displayCharacter
150                       : "Out of range");
151       String alm2 = ""
152               + (almap2.annotations.length > p ? almap2.annotations[p].displayCharacter
153                       : "Out of range");
154       assertEquals("Position " + p + " " + alm1 + " " + alm2, alm1, alm2);
155     }
156   }
157
158   @Test
159   public void testAdjustForAlignment()
160   {
161     SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
162     seq.createDatasetSequence();
163
164     /*
165      * Annotate positions 3/4/5 (CDE) with values 1/2/3
166      */
167     Annotation[] anns = new Annotation[]
168     { null, null, new Annotation(1), new Annotation(2), new Annotation(3) };
169     AlignmentAnnotation ann = new AlignmentAnnotation("SS",
170             "secondary structure", anns);
171     seq.addAlignmentAnnotation(ann);
172
173     /*
174      * Check annotation map before modifying aligned sequence
175      */
176     assertNull(ann.getAnnotationForPosition(1));
177     assertNull(ann.getAnnotationForPosition(2));
178     assertNull(ann.getAnnotationForPosition(6));
179     assertNull(ann.getAnnotationForPosition(7));
180     assertEquals(1, ann.getAnnotationForPosition(3).value, 0.001d);
181     assertEquals(2, ann.getAnnotationForPosition(4).value, 0.001d);
182     assertEquals(3, ann.getAnnotationForPosition(5).value, 0.001d);
183
184     /*
185      * Trim the displayed sequence to BCD and adjust annotations
186      */
187     seq.setSequence("BCD");
188     seq.setStart(2);
189     seq.setEnd(4);
190     ann.adjustForAlignment();
191
192     /*
193      * Should now have annotations for aligned positions 2, 3Q (CD) only
194      */
195     assertEquals(3, ann.annotations.length);
196     assertNull(ann.annotations[0]);
197     assertEquals(1, ann.annotations[1].value, 0.001);
198     assertEquals(2, ann.annotations[2].value, 0.001);
199   }
200 }