6b36dbd8c771130e7c42e4c7965395c842874e68
[jalview.git] / test / jalview / renderer / ContactGeometryTest.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.renderer;
22
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertFalse;
25 import static org.testng.Assert.assertNotEquals;
26 import static org.testng.Assert.assertNotNull;
27 import static org.testng.Assert.assertTrue;
28
29 import org.testng.annotations.Test;
30
31 import jalview.datamodel.AlignmentAnnotation;
32 import jalview.datamodel.ColumnSelection;
33 import jalview.datamodel.ContactListI;
34 import jalview.datamodel.ContactRange;
35 import jalview.datamodel.Mapping;
36 import jalview.datamodel.SeqDistanceContactMatrix;
37 import jalview.datamodel.Sequence;
38 import jalview.datamodel.SequenceI;
39 import jalview.util.MapList;
40 import jalview.util.StringUtils;
41 import jalview.ws.datamodel.MappableContactMatrixI;
42
43 public class ContactGeometryTest
44 {
45   @Test(groups = "Functional")
46   public void testCoverageofRange()
47   {
48     // a really dumb test to make sure we really cover the requested pixel and
49     // contactList range for any dimension of each
50     for (int range = 12; range < 2000; range += 35)
51     {
52       StringBuilder sb = new StringBuilder();
53       while (sb.length() < range)
54       {
55         sb.append("c");
56       }
57       SequenceI sq = new Sequence("a", sb.toString());
58       MappableContactMatrixI cm = new SeqDistanceContactMatrix(range);
59       AlignmentAnnotation cm_aan = sq.addContactList(cm);
60       ContactListI cl = sq.getContactListFor(cm_aan, 10);
61       assertNotNull(cl);
62       for (int ht = range / 2; ht < range * 3; ht++)
63       {
64         ContactGeometry clgeom = new ContactGeometry(cl, ht);
65         assertNotNull(clgeom.allSteps());
66       }
67     }
68   }
69
70   @Test(groups = "Functional")
71   public void testContactGeometry()
72   {
73     SequenceI sq = new Sequence("a", "SSSQ");
74     MappableContactMatrixI cm = new SeqDistanceContactMatrix(4);
75     AlignmentAnnotation cm_aan = sq.addContactList(cm);
76     checkConsistencyFor(sq, cm_aan);
77     // Also check all is good when there's a sequence mapping involved
78     MappableContactMatrixI newcm = cm.liftOver(sq,
79             new Mapping(sq, new MapList(new int[]
80             { 1, 4 }, new int[] { 1, 4 }, 1, 1)));
81     AlignmentAnnotation mapped_cm = sq.addContactList(newcm);
82     checkConsistencyFor(sq, mapped_cm);
83   }
84
85   // Do some asserts for a sequence and a contact matrix
86   private void checkConsistencyFor(SequenceI sq, AlignmentAnnotation cm_aan)
87   {
88     int col = 1;
89     ContactListI cl = sq.getContactListFor(cm_aan, col);
90     assertNotNull(cl);
91     assertEquals(cl.getContactHeight(), 4);
92
93     // Map contacts 0 to 3 to a tiny range and check
94     ContactGeometry testee = new ContactGeometry(cl, 2);
95     assertEquals(testee.contacts_per_pixel, 2d);
96     ContactGeometry.contactInterval lastInterval = testee.mapFor(1);
97     assertEquals(lastInterval.cStart, 2);
98     assertEquals(lastInterval.cEnd, 3);
99     assertEquals(lastInterval.pStart, 1);
100     assertEquals(lastInterval.pEnd, 1);
101     ContactGeometry.contactInterval another = testee.mapFor(1, 2);
102     assertEquals(lastInterval, another);
103     // Also check for a big pixel range
104     testee = new ContactGeometry(cl, 395);
105     lastInterval = testee.mapFor(390, 395); // 395 is one over limit.
106     assertNotNull(lastInterval);
107     assertEquals(lastInterval.cEnd, 3);
108     assertEquals(lastInterval.pEnd, 394);
109     // Map contacts 0 to 3 to Pixels 0-9, 10-19, 20-29, 30-39
110     testee = new ContactGeometry(cl, 40);
111
112     // verify mapping from pixel to contacts
113
114     // renderer thinks base 0 for pixel coordinates
115     // contact coordinates are base 1
116     for (int p = 0; p < 40; p++)
117     {
118       int expectC = (p / 10);
119       int expectP = (expectC) * 10;
120       ContactGeometry.contactInterval ci_at = testee.mapFor(p),
121               ci_from = testee.mapFor(p, p);
122       assertNotNull(ci_at);
123       // mapFor and map should locate the same pixel window
124       assertEquals(ci_at.cStart, expectC,
125               "Different cStart at position " + p);
126       assertEquals(ci_at.cEnd, expectC, "Different cEnd at position " + p);
127       assertEquals(ci_at.pStart, expectP,
128               "Different pStart at position " + p);
129       assertEquals(ci_at.pEnd, expectP + 9,
130               "Different pEnd at position " + p);
131
132       assertEquals(ci_from, ci_at,
133               "Different contactIntervals at position " + p);
134       // also test getRangeFor
135       ContactRange cr = cl.getRangeFor(ci_at.cStart, ci_at.cEnd);
136       assertEquals(cr.getFrom_column(), cr.getTo_column());
137       assertEquals((double) cr.getMean(),
138               (double) Math.abs(col - cr.getFrom_column()),
139               "Didn't resolve expected value at position " + p);
140     }
141
142     ContactGeometry.contactInterval ci_at0 = testee.mapFor(0);
143     ContactGeometry.contactInterval ci_at9 = testee.mapFor(9);
144     assertNotNull(ci_at9);
145
146     assertEquals(ci_at0, ci_at9);
147
148     // Adjacent cell
149     ContactGeometry.contactInterval ci_at10 = testee.mapFor(10);
150     assertNotNull(ci_at10);
151     ContactGeometry.contactInterval ci_at11 = testee.mapFor(11);
152     assertNotNull(ci_at11);
153
154     assertEquals(ci_at11, ci_at10,
155             "Off-by-one in ContactGeometry mapping.");
156
157     assertNotEquals(ci_at0, ci_at10,
158             "Expected adjacent cells to be not equal.");
159
160     // verify adjacent window is mapped
161     assertEquals(ci_at11.cStart, ci_at9.cStart + 1);
162
163     assertEquals(ci_at9.cEnd + 1, ci_at11.cStart);
164     assertEquals(ci_at9.cEnd + 1, ci_at11.cEnd);
165
166     // verify interval/intersection
167     // column selection is base 0
168     ColumnSelection cs = new ColumnSelection();
169     cs.addElement(2);
170
171     boolean mask = false;
172     do
173     {
174       assertFalse(testee.intersects(ci_at0, cs, null, mask));
175       assertFalse(testee.intersects(ci_at11, cs, null, mask));
176       assertTrue(testee.intersects(testee.mapFor(21), cs, null, mask));
177       assertFalse(testee.intersects(testee.mapFor(31), cs, null, mask));
178       cs.addElement(3);
179       assertTrue(testee.intersects(testee.mapFor(31), cs, null, mask));
180       cs.removeElement(2);
181       assertFalse(testee.intersects(testee.mapFor(21), cs, null, mask));
182       mask = !mask;
183     } while (!mask);
184
185   }
186 }