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