Merge branch 'develop' into patch/JAL-4281_idwidthandannotHeight_in_project
[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   @Test(groups = "Functional")
70   public void testContactGeometry()
71   {
72     SequenceI sq = new Sequence("a", "SSSQ");
73     MappableContactMatrixI cm = new SeqDistanceContactMatrix(4);
74     AlignmentAnnotation cm_aan = sq.addContactList(cm);
75     checkConsistencyFor(sq,cm_aan);
76     // Also check all is good when there's a sequence mapping involved
77     MappableContactMatrixI newcm=cm.liftOver(sq,
78             new Mapping(sq, new MapList(new int[]
79             { 1, 4 }, new int[] { 1, 4 }, 1, 1)));
80     AlignmentAnnotation mapped_cm = sq.addContactList(newcm);
81     checkConsistencyFor(sq,mapped_cm);    
82   }
83   // Do some asserts for a sequence and a contact matrix
84   private void checkConsistencyFor(SequenceI sq, AlignmentAnnotation cm_aan)
85   {
86     int col=1;
87     ContactListI cl = sq.getContactListFor(cm_aan, col);
88     assertNotNull(cl);
89     assertEquals(cl.getContactHeight(),4);
90     
91     // Map contacts 0 to 3 to a tiny range and check    
92     ContactGeometry  testee = new ContactGeometry(cl,2);
93     assertEquals(testee.contacts_per_pixel,2d);
94     ContactGeometry.contactInterval lastInterval = testee.mapFor(1);
95     assertEquals(lastInterval.cStart,2);
96     assertEquals(lastInterval.cEnd,3);
97     assertEquals(lastInterval.pStart,1);
98     assertEquals(lastInterval.pEnd,1);
99     ContactGeometry.contactInterval another = testee.mapFor(1,2); 
100     assertEquals(lastInterval,another);
101     // Also check for a big pixel range
102     testee = new ContactGeometry(cl, 395);
103     lastInterval = testee.mapFor(390, 395); // 395 is one over limit.
104     assertNotNull(lastInterval);
105     assertEquals(lastInterval.cEnd,3);
106     assertEquals(lastInterval.pEnd,394);
107     // Map contacts 0 to 3 to Pixels 0-9, 10-19, 20-29, 30-39
108     testee = new ContactGeometry(cl, 40);
109
110     // verify mapping from pixel to contacts
111     
112     // renderer thinks base 0 for pixel coordinates
113     // contact coordinates are base 1
114     for (int p = 0; p < 40; p++)
115     {
116       int expectC=(p / 10);
117       int expectP=(expectC)*10;
118       ContactGeometry.contactInterval ci_at = testee.mapFor(p),
119               ci_from = testee.mapFor(p, p);
120       assertNotNull(ci_at);
121       // mapFor and map should locate the same pixel window
122       assertEquals(ci_at.cStart, expectC,"Different cStart at position "+p);
123       assertEquals(ci_at.cEnd, expectC,"Different cEnd at position "+p);
124       assertEquals(ci_at.pStart,expectP, "Different pStart at position "+p);
125       assertEquals(ci_at.pEnd,expectP+9, "Different pEnd at position "+p);
126       
127       assertEquals(ci_from,ci_at, "Different contactIntervals at position "+p);
128       // also test getRangeFor
129       ContactRange cr = cl.getRangeFor(ci_at.cStart, ci_at.cEnd);
130       assertEquals(cr.getFrom_column(),cr.getTo_column());
131       assertEquals((double) cr.getMean(),(double)Math.abs(col-cr.getFrom_column()), "Didn't resolve expected value at position "+p);
132     }
133     
134     ContactGeometry.contactInterval ci_at0 = testee.mapFor(0);
135     ContactGeometry.contactInterval ci_at9 = testee.mapFor(9);
136     assertNotNull(ci_at9);
137     
138     assertEquals(ci_at0,ci_at9);
139
140     // Adjacent cell
141     ContactGeometry.contactInterval ci_at10 = testee.mapFor(10);
142     assertNotNull(ci_at10);
143     ContactGeometry.contactInterval ci_at11 = testee.mapFor(11);
144     assertNotNull(ci_at11);
145
146     assertEquals(ci_at11,ci_at10,"Off-by-one in ContactGeometry mapping.");
147
148     assertNotEquals(ci_at0,ci_at10,"Expected adjacent cells to be not equal.");
149     
150     // verify adjacent window is mapped
151     assertEquals(ci_at11.cStart,ci_at9.cStart+1);
152     
153     assertEquals(ci_at9.cEnd+1,ci_at11.cStart);
154     assertEquals(ci_at9.cEnd+1,ci_at11.cEnd);
155     
156     // verify interval/intersection
157     // column selection is base 0
158     ColumnSelection cs = new ColumnSelection();
159     cs.addElement(2);
160
161     boolean mask = false;
162     do
163     {
164       assertFalse(testee.intersects(ci_at0, cs, null, mask));
165       assertFalse(testee.intersects(ci_at11, cs, null, mask));
166       assertTrue(testee.intersects(testee.mapFor(21), cs, null, mask));
167       assertFalse(testee.intersects(testee.mapFor(31), cs, null, mask));
168       cs.addElement(3);
169       assertTrue(testee.intersects(testee.mapFor(31), cs, null, mask));
170       cs.removeElement(2);
171       assertFalse(testee.intersects(testee.mapFor(21), cs, null, mask));
172       mask = !mask;
173     } while (!mask);    
174     
175   }
176 }