file format enum wip changes
[jalview.git] / test / jalview / datamodel / AlignmentAnnotationTests.java
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.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNull;
25
26 import jalview.analysis.AlignSeq;
27 import jalview.io.AppletFormatAdapter;
28 import jalview.io.FileFormat;
29
30 import org.testng.annotations.Test;
31
32 public class AlignmentAnnotationTests
33 {
34   @Test(groups = { "Functional" })
35   public void testCopyConstructor()
36   {
37     SequenceI sq = new Sequence("Foo", "ARAARARARAWEAWEAWRAWEAWE");
38     createAnnotation(sq);
39     AlignmentAnnotation alc, alo = sq.getAnnotation()[0];
40     alc = new AlignmentAnnotation(alo);
41     for (String key : alo.getProperties())
42     {
43       assertEquals("Property mismatch", alo.getProperty(key),
44               alc.getProperty(key));
45     }
46   }
47
48   /**
49    * create some dummy annotation derived from the sequence
50    * 
51    * @param sq
52    */
53   public static void createAnnotation(SequenceI sq)
54   {
55     Annotation[] al = new Annotation[sq.getLength()];
56     for (int i = 0; i < al.length; i++)
57     {
58       al[i] = new Annotation(new Annotation("" + sq.getCharAt(i), "",
59               (char) 0, sq.findPosition(i)));
60     }
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);
67   }
68
69   /**
70    * use this to test annotation derived from method above as it is transferred
71    * across different sequences derived from same dataset coordinate frame
72    * 
73    * @param ala
74    */
75   public static void testAnnotTransfer(AlignmentAnnotation ala)
76   {
77     assertEquals(
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++)
82     {
83       if (ala.annotations[p] != null)
84       {
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));
89       }
90     }
91   }
92
93   /**
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
97    * sequences)
98    */
99   @Test(groups = { "Functional" })
100   public void testLiftOver()
101   {
102     SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
103     sqFrom.setStart(10);
104     sqFrom.setEnd(sqFrom.findPosition(sqFrom.getLength() - 1));
105     SequenceI sqTo = new Sequence("toShort", "RCDEW");
106     sqTo.setStart(20);
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,
113             AlignSeq.PEP);
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()
123 .formatSequences(
124             FileFormat.Stockholm, new Alignment(new SequenceI[] { sqFrom,
125                 alSeq1, sqTo, alSeq2 }), true));
126
127     Mapping mp = align.getMappingFromS1(false);
128
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);
140
141     alSeq2.addAlignmentAnnotation(almap2);
142     almap2.setSequenceRef(alSeq2);
143     almap2.adjustForAlignment();
144
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,
150             all, true));
151
152     for (int p = 0; p < alSeq1.getLength(); p++)
153     {
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)
161       {
162         System.out.println("Pos " + p + " mismatch");
163         continue;
164       }
165       assertEquals(
166               "Mismatch on Original From and transferred annotation on 2",
167               (orig2 != null) ? orig2.toString() : null,
168               (trans2 != null) ? trans2.toString() : null);
169       assertEquals(
170               "Mismatch on Original To and transferred annotation on 1",
171               (orig1 != null) ? orig1.toString() : null,
172               (trans1 != null) ? trans1.toString() : null);
173       String alm1 = ""
174               + (almap1.annotations.length > p ? almap1.annotations[p].displayCharacter
175                       : "Out of range");
176       String alm2 = ""
177               + (almap2.annotations.length > p ? almap2.annotations[p].displayCharacter
178                       : "Out of range");
179       assertEquals("Position " + p + " " + alm1 + " " + alm2, alm1, alm2);
180     }
181   }
182
183   @Test(groups = { "Functional" })
184   public void testAdjustForAlignment()
185   {
186     SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
187     seq.createDatasetSequence();
188
189     /*
190      * Annotate positions 3/4/5 (CDE) with values 1/2/3
191      */
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);
197
198     /*
199      * Check annotation map before modifying aligned sequence
200      */
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);
208
209     /*
210      * Trim the displayed sequence to BCD and adjust annotations
211      */
212     seq.setSequence("BCD");
213     seq.setStart(2);
214     seq.setEnd(4);
215     ann.adjustForAlignment();
216
217     /*
218      * Should now have annotations for aligned positions 2, 3Q (CD) only
219      */
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);
224   }
225 }