JAL-4090 JAL-1551 source license
[jalview.git] / test / jalview / datamodel / PAEContactMatrixTest.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.Assert.*;
24
25 import org.testng.Assert;
26 import org.testng.annotations.BeforeClass;
27 import org.testng.annotations.Test;
28
29 import jalview.analysis.AlignmentUtils;
30 import jalview.analysis.SeqsetUtils;
31 import jalview.gui.JvOptionPane;
32 import jalview.util.MapList;
33 import jalview.ws.datamodel.MappableContactMatrixI;
34 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
35
36 public class PAEContactMatrixTest
37 {
38   @BeforeClass(alwaysRun = true)
39   public void setUpJvOptionPane()
40   {
41     JvOptionPane.setInteractiveMode(false);
42     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
43   }
44
45   static float[][] PAEdata = { { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f },
46       { 2.0f, 1.0f, 2.0f, 3.0f, 4.0f },
47       { 3.0f, 2.0f, 1.0f, 2.0f, 3.0f },
48       { 4.0f, 3.0f, 2.0f, 1.0f, 2.0f },
49       { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f } };
50
51   /**
52    * test associations for a PAE matrix
53    */
54   @Test(groups = { "Functional" })
55   public void testSeqAssociatedPAEMatrix()
56   {
57     Sequence seq = new Sequence("Seq", "ASDQE");
58     AlignmentAnnotation aa = seq
59             .addContactList(new PAEContactMatrix(seq, PAEdata));
60     assertNotNull(seq.getContactListFor(aa, 0));
61     assertEquals(seq.getContactListFor(aa, 0).getContactAt(0), 1.0);
62     assertNotNull(seq.getContactListFor(aa, 1));
63     assertEquals(seq.getContactListFor(aa, 1).getContactAt(1), 1.0);
64     assertNotNull(seq.getContactListFor(aa, 2));
65     assertEquals(seq.getContactListFor(aa, 2).getContactAt(2), 1.0);
66     assertNotNull(seq.getContactListFor(aa, 3));
67     assertEquals(seq.getContactListFor(aa, 3).getContactAt(3), 1.0);
68     assertNotNull(seq.getContactListFor(aa, 4));
69     assertEquals(seq.getContactListFor(aa, 4).getContactAt(4), 1.0);
70
71     assertNotNull(seq.getContactListFor(aa, seq.getEnd() - 1));
72     assertNull(seq.getContactListFor(aa, seq.getEnd()));
73
74     ContactListI cm = seq.getContactListFor(aa, seq.getStart());
75     assertEquals(cm.getContactAt(seq.getStart()), 1d);
76     verifyPAEmatrix(seq, aa, 0, 0, 4);
77
78     // Now associated with sequence not starting at 1
79     seq = new Sequence("Seq/5-9", "ASDQE");
80     ContactMatrixI paematrix = new PAEContactMatrix(seq, PAEdata);
81     aa = seq.addContactList(paematrix);
82     assertNotNull(aa);
83     // individual annotation elements need to be distinct for Matrix associated
84     // rows
85     Annotation ae5 = aa.getAnnotationForPosition(5);
86     Annotation ae6 = aa.getAnnotationForPosition(6);
87     assertNotNull(ae5);
88     assertNotNull(ae6);
89     assertTrue(ae5 != ae6);
90
91     cm = seq.getContactListFor(aa, 0);
92     assertEquals(cm.getContactAt(0), 1d);
93     verifyPAEmatrix(seq, aa, 0, 0, 4);
94
95     // test clustering
96     paematrix.setGroupSet(
97             GroupSet.makeGroups(paematrix, false, 0.1f, false));
98
99     // remap - test the MappableContactMatrix.liftOver method
100     SequenceI newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
101     Mapping sqmap = new Mapping(seq,
102             new MapList(new int[]
103             { 5, 8, 10, 10 }, new int[] { 5, 9 }, 1, 1));
104     assertTrue(paematrix instanceof MappableContactMatrixI);
105
106     MappableContactMatrixI remapped = ((MappableContactMatrixI) paematrix)
107             .liftOver(newseq, sqmap);
108     assertTrue(remapped instanceof PAEContactMatrix);
109
110     AlignmentAnnotation newaa = newseq.addContactList(remapped);
111     assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(1)));
112     assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(4)));
113     assertNotNull(
114             newseq.getContactListFor(newaa, -1 + newseq.findIndex(5)));
115     assertNotNull(
116             newseq.getContactListFor(newaa, -1 + newseq.findIndex(6)));
117     assertNotNull(
118             newseq.getContactListFor(newaa, -1 + newseq.findIndex(7)));
119     assertNotNull(
120             newseq.getContactListFor(newaa, -1 + newseq.findIndex(8)));
121     // no mapping for position 9
122     assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(9)));
123     // last column
124     assertNotNull(
125             newseq.getContactListFor(newaa, -1 + newseq.findIndex(10)));
126
127     // verify MappedPositions includes discontinuity
128     int[] mappedCl = newseq.getContactListFor(newaa, 5)
129             .getMappedPositionsFor(0, 4);
130     assertEquals(4, mappedCl.length,
131             "getMappedPositionsFor doesn't support discontinuous mappings to contactList");
132
133     // make it harder.
134
135     SequenceI alseq = newseq.getSubSequence(6, 10);
136     alseq.insertCharAt(2, 2, '-');
137     AlignmentI alForSeq = new Alignment(new SequenceI[] { alseq });
138     newaa = AlignmentUtils.addReferenceAnnotationTo(alForSeq, alseq, newaa,
139             null);
140     // check for null on out of bounds
141     ContactListI alcl = alForSeq.getContactListFor(newaa,
142             newaa.annotations.length);
143     assertNull(alcl, "Should've gotten null!");
144     // now check for mapping
145     alcl = alForSeq.getContactListFor(newaa, 1);
146     assertNotNull(alcl);
147     mappedCl = alcl.getMappedPositionsFor(0, 4);
148     assertNotNull(mappedCl);
149     assertEquals(4, mappedCl.length,
150             "getMappedPositionsFor doesn't support discontinuous mappings to contactList");
151
152     // remap2 - test with original matrix map from 1-5 remapped to 5-9
153
154     seq = new Sequence("Seq/1-5", "ASDQE");
155     paematrix = new PAEContactMatrix(seq, PAEdata);
156     assertTrue(paematrix instanceof MappableContactMatrixI);
157     aa = seq.addContactList(paematrix);
158
159     newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
160     sqmap = new Mapping(seq,
161             new MapList(new int[]
162             { 5, 9 }, new int[] { 1, 5 }, 1, 1));
163
164     remapped = ((MappableContactMatrixI) paematrix).liftOver(newseq, sqmap);
165     assertTrue(remapped instanceof PAEContactMatrix);
166
167     newaa = newseq.addContactList(remapped);
168     verify_mapping(newseq, newaa);
169
170     // remap3 - remap2 but mapping sense in liftover is reversed
171
172     seq = new Sequence("Seq/1-5", "ASDQE");
173     paematrix = new PAEContactMatrix(seq, PAEdata);
174     assertTrue(paematrix instanceof MappableContactMatrixI);
175     aa = seq.addContactList(paematrix);
176
177     newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
178     sqmap = new Mapping(newseq,
179             new MapList(new int[]
180             { 1, 5 }, new int[] { 5, 9 }, 1, 1));
181
182     remapped = ((MappableContactMatrixI) paematrix).liftOver(newseq, sqmap);
183     assertTrue(remapped instanceof PAEContactMatrix);
184
185     newaa = newseq.addContactList(remapped);
186     verify_mapping(newseq, newaa);
187   }
188
189   /**
190    * checks that the PAE matrix is located at positions 1-9 in newseq, and
191    * columns are not truncated.
192    * 
193    * @param newseq
194    * @param newaa
195    */
196   private void verify_mapping(SequenceI newseq, AlignmentAnnotation newaa)
197   {
198     assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(1)));
199     assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(4)));
200     assertNotNull(
201             newseq.getContactListFor(newaa, -1 + newseq.findIndex(5)));
202     assertNotNull(
203             newseq.getContactListFor(newaa, -1 + newseq.findIndex(6)));
204     assertNotNull(
205             newseq.getContactListFor(newaa, -1 + newseq.findIndex(7)));
206     assertNotNull(
207             newseq.getContactListFor(newaa, -1 + newseq.findIndex(8)));
208     assertNotNull(
209             newseq.getContactListFor(newaa, -1 + newseq.findIndex(9)));
210     // last column should be null this time
211     assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(10)));
212
213     verifyPAEmatrix(newseq, newaa, 4, 4, 8);
214   }
215
216   private void verifyPAEmatrix(SequenceI seq, AlignmentAnnotation aa,
217           int topl, int rowl, int rowr)
218   {
219     int[] mappedCl;
220     for (int f = rowl; f <= rowr; f++)
221     {
222       ContactListI clist = seq.getContactListFor(aa, f);
223       assertNotNull(clist, "No ContactListI for position " + (f));
224       assertEquals(clist.getContactAt(0), (double) f - topl + 1,
225               "for column " + f + " relative to " + topl);
226       mappedCl = clist.getMappedPositionsFor(0, 0);
227       assertNotNull(mappedCl);
228       assertEquals(mappedCl[0], mappedCl[1]);
229       assertEquals(mappedCl[0], seq.findIndex(seq.getStart() + topl));
230       assertEquals(clist.getContactAt(f - topl), 1d,
231               "for column and row " + f + " relative to " + topl);
232     }
233   }
234
235   /**
236    * check mapping and resolution methods work
237    */
238   @Test(groups = { "Functional" })
239   public void testMappableContactMatrix()
240   {
241     SequenceI newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
242     MapList map = new MapList(new int[] { 5, 9 }, new int[] { 1, 5 }, 1, 1);
243     AlignmentAnnotation aa = newseq.addContactList(
244             new PAEContactMatrix(newseq, map, PAEdata, null));
245     ContactListI clist = newseq.getContactListFor(aa, 4);
246     assertNotNull(clist);
247     clist = newseq.getContactListFor(aa, 3);
248     assertNull(clist);
249
250     ContactMatrixI cm = newseq.getContactMatrixFor(aa);
251     MappableContactMatrixI mcm = (MappableContactMatrixI) cm;
252     int[] pos = mcm.getMappedPositionsFor(newseq, 0);
253     assertNull(pos);
254
255     pos = mcm.getMappedPositionsFor(newseq, 1);
256     assertNotNull(pos);
257     assertEquals(pos[0], 4 + newseq.getStart());
258
259     pos = mcm.getMappedPositionsFor(newseq, 6); // after end of matrix
260     assertNull(pos);
261     pos = mcm.getMappedPositionsFor(newseq, 5); // at end of matrix
262     assertNotNull(pos);
263     assertEquals(pos[0], 8 + newseq.getStart());
264     SequenceI alseq = newseq.deriveSequence();
265     alseq.insertCharAt(5, '-');
266     pos = mcm.getMappedPositionsFor(alseq, 5); // at end of matrix
267     assertNotNull(pos);
268     assertEquals(pos[0], 8 + newseq.getStart());
269
270   }
271 }