JAL-4090 JAL-1551 source license
[jalview.git] / test / jalview / datamodel / PAEContactMatrixTest.java
index 7426cba..e4bb000 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.datamodel;
 
 import static org.testng.Assert.*;
@@ -6,6 +26,8 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import jalview.analysis.AlignmentUtils;
+import jalview.analysis.SeqsetUtils;
 import jalview.gui.JvOptionPane;
 import jalview.util.MapList;
 import jalview.ws.datamodel.MappableContactMatrixI;
@@ -20,132 +42,230 @@ public class PAEContactMatrixTest
     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
   }
 
-  static float[][] PAEdata = {
-      {1.0f,2.0f,3.0f,4.0f,5.0f},
-      {2.0f,1.0f,2.0f,3.0f,4.0f},
-      {3.0f,2.0f,1.0f,2.0f,3.0f},
-      {4.0f,3.0f,2.0f,1.0f,2.0f},
-      {5.0f,4.0f,3.0f,2.0f,1.0f}};
-  
+  static float[][] PAEdata = { { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f },
+      { 2.0f, 1.0f, 2.0f, 3.0f, 4.0f },
+      { 3.0f, 2.0f, 1.0f, 2.0f, 3.0f },
+      { 4.0f, 3.0f, 2.0f, 1.0f, 2.0f },
+      { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f } };
+
   /**
    * test associations for a PAE matrix
    */
   @Test(groups = { "Functional" })
   public void testSeqAssociatedPAEMatrix()
   {
-    Sequence seq = new Sequence("Seq","ASDQE");
-    AlignmentAnnotation aa = seq.addContactList(new PAEContactMatrix(seq, PAEdata));
+    Sequence seq = new Sequence("Seq", "ASDQE");
+    AlignmentAnnotation aa = seq
+            .addContactList(new PAEContactMatrix(seq, PAEdata));
     assertNotNull(seq.getContactListFor(aa, 0));
-    assertEquals(seq.getContactListFor(aa, 0).getContactAt(0),1.0);
+    assertEquals(seq.getContactListFor(aa, 0).getContactAt(0), 1.0);
     assertNotNull(seq.getContactListFor(aa, 1));
-    assertEquals(seq.getContactListFor(aa, 1).getContactAt(1),1.0);
+    assertEquals(seq.getContactListFor(aa, 1).getContactAt(1), 1.0);
     assertNotNull(seq.getContactListFor(aa, 2));
-    assertEquals(seq.getContactListFor(aa, 2).getContactAt(2),1.0);
+    assertEquals(seq.getContactListFor(aa, 2).getContactAt(2), 1.0);
     assertNotNull(seq.getContactListFor(aa, 3));
-    assertEquals(seq.getContactListFor(aa, 3).getContactAt(3),1.0);
+    assertEquals(seq.getContactListFor(aa, 3).getContactAt(3), 1.0);
     assertNotNull(seq.getContactListFor(aa, 4));
-    assertEquals(seq.getContactListFor(aa, 4).getContactAt(4),1.0);
-    
-    assertNotNull(seq.getContactListFor(aa, seq.getEnd()-1));
+    assertEquals(seq.getContactListFor(aa, 4).getContactAt(4), 1.0);
+
+    assertNotNull(seq.getContactListFor(aa, seq.getEnd() - 1));
     assertNull(seq.getContactListFor(aa, seq.getEnd()));
-    
+
     ContactListI cm = seq.getContactListFor(aa, seq.getStart());
-    assertEquals(cm.getContactAt(seq.getStart()),1d);
-    verifyPAEmatrix(seq, aa, 0,0,4);
-    
+    assertEquals(cm.getContactAt(seq.getStart()), 1d);
+    verifyPAEmatrix(seq, aa, 0, 0, 4);
+
     // Now associated with sequence not starting at 1
-    seq = new Sequence("Seq/5-9","ASDQE");
+    seq = new Sequence("Seq/5-9", "ASDQE");
     ContactMatrixI paematrix = new PAEContactMatrix(seq, PAEdata);
     aa = seq.addContactList(paematrix);
+    assertNotNull(aa);
+    // individual annotation elements need to be distinct for Matrix associated
+    // rows
+    Annotation ae5 = aa.getAnnotationForPosition(5);
+    Annotation ae6 = aa.getAnnotationForPosition(6);
+    assertNotNull(ae5);
+    assertNotNull(ae6);
+    assertTrue(ae5 != ae6);
+
     cm = seq.getContactListFor(aa, 0);
-    assertEquals(cm.getContactAt(0),1d);
+    assertEquals(cm.getContactAt(0), 1d);
     verifyPAEmatrix(seq, aa, 0, 0, 4);
-    
+
+    // test clustering
+    paematrix.setGroupSet(
+            GroupSet.makeGroups(paematrix, false, 0.1f, false));
+
     // remap - test the MappableContactMatrix.liftOver method
-    SequenceI newseq = new Sequence("Seq","ASDQEASDQEASDQE");
-    Mapping sqmap = new Mapping(seq, new MapList(new int[] {5,8,10,10},new int[] { 5,9}, 1, 1));
+    SequenceI newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    Mapping sqmap = new Mapping(seq,
+            new MapList(new int[]
+            { 5, 8, 10, 10 }, new int[] { 5, 9 }, 1, 1));
     assertTrue(paematrix instanceof MappableContactMatrixI);
-    
-    MappableContactMatrixI remapped = ((MappableContactMatrixI)paematrix).liftOver(newseq, sqmap);
+
+    MappableContactMatrixI remapped = ((MappableContactMatrixI) paematrix)
+            .liftOver(newseq, sqmap);
     assertTrue(remapped instanceof PAEContactMatrix);
-    
+
     AlignmentAnnotation newaa = newseq.addContactList(remapped);
-    assertNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(1)));
-    assertNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(4)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(5)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(6)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(7)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(8)));
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(1)));
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(4)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(5)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(6)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(7)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(8)));
     // no mapping for position 9
-    assertNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(9)));
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(9)));
     // last column
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(10)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(10)));
+
+    // verify MappedPositions includes discontinuity
+    int[] mappedCl = newseq.getContactListFor(newaa, 5)
+            .getMappedPositionsFor(0, 4);
+    assertEquals(4, mappedCl.length,
+            "getMappedPositionsFor doesn't support discontinuous mappings to contactList");
+
+    // make it harder.
+
+    SequenceI alseq = newseq.getSubSequence(6, 10);
+    alseq.insertCharAt(2, 2, '-');
+    AlignmentI alForSeq = new Alignment(new SequenceI[] { alseq });
+    newaa = AlignmentUtils.addReferenceAnnotationTo(alForSeq, alseq, newaa,
+            null);
+    // check for null on out of bounds
+    ContactListI alcl = alForSeq.getContactListFor(newaa,
+            newaa.annotations.length);
+    assertNull(alcl, "Should've gotten null!");
+    // now check for mapping
+    alcl = alForSeq.getContactListFor(newaa, 1);
+    assertNotNull(alcl);
+    mappedCl = alcl.getMappedPositionsFor(0, 4);
+    assertNotNull(mappedCl);
+    assertEquals(4, mappedCl.length,
+            "getMappedPositionsFor doesn't support discontinuous mappings to contactList");
 
     // remap2 - test with original matrix map from 1-5 remapped to 5-9
-    
-    seq = new Sequence("Seq/1-5","ASDQE");
+
+    seq = new Sequence("Seq/1-5", "ASDQE");
     paematrix = new PAEContactMatrix(seq, PAEdata);
     assertTrue(paematrix instanceof MappableContactMatrixI);
     aa = seq.addContactList(paematrix);
-    
-    newseq = new Sequence("Seq","ASDQEASDQEASDQE");
-    sqmap = new Mapping(seq, new MapList(new int[] {5,9},new int[] { 1,5}, 1, 1));
-    
-    remapped = ((MappableContactMatrixI)paematrix).liftOver(newseq, sqmap);
+
+    newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    sqmap = new Mapping(seq,
+            new MapList(new int[]
+            { 5, 9 }, new int[] { 1, 5 }, 1, 1));
+
+    remapped = ((MappableContactMatrixI) paematrix).liftOver(newseq, sqmap);
     assertTrue(remapped instanceof PAEContactMatrix);
-    
-    
+
     newaa = newseq.addContactList(remapped);
     verify_mapping(newseq, newaa);
 
     // remap3 - remap2 but mapping sense in liftover is reversed
-    
-    seq = new Sequence("Seq/1-5","ASDQE");
+
+    seq = new Sequence("Seq/1-5", "ASDQE");
     paematrix = new PAEContactMatrix(seq, PAEdata);
     assertTrue(paematrix instanceof MappableContactMatrixI);
     aa = seq.addContactList(paematrix);
-    
-    newseq = new Sequence("Seq","ASDQEASDQEASDQE");
-    sqmap = new Mapping(newseq, new MapList(new int[] { 1,5},new int[] {5,9},1, 1));
-    
-    remapped = ((MappableContactMatrixI)paematrix).liftOver(newseq, sqmap);
+
+    newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    sqmap = new Mapping(newseq,
+            new MapList(new int[]
+            { 1, 5 }, new int[] { 5, 9 }, 1, 1));
+
+    remapped = ((MappableContactMatrixI) paematrix).liftOver(newseq, sqmap);
     assertTrue(remapped instanceof PAEContactMatrix);
-    
-    
+
     newaa = newseq.addContactList(remapped);
     verify_mapping(newseq, newaa);
-    
   }
+
   /**
-   * checks that the PAE matrix is located at positions 1-9 in newseq, and columns are not truncated.
+   * checks that the PAE matrix is located at positions 1-9 in newseq, and
+   * columns are not truncated.
+   * 
    * @param newseq
    * @param newaa
    */
   private void verify_mapping(SequenceI newseq, AlignmentAnnotation newaa)
   {
-  assertNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(1)));
-    assertNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(4)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(5)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(6)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(7)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(8)));
-    assertNotNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(9)));
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(1)));
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(4)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(5)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(6)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(7)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(8)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(9)));
     // last column should be null this time
-    assertNull(newseq.getContactListFor(newaa, -1+newseq.findIndex(10)));
-    
-    verifyPAEmatrix(newseq, newaa, 4, 4, 8);
-    
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(10)));
 
+    verifyPAEmatrix(newseq, newaa, 4, 4, 8);
   }
 
-  private void verifyPAEmatrix(SequenceI seq, AlignmentAnnotation aa, int topl, int rowl, int rowr)
+  private void verifyPAEmatrix(SequenceI seq, AlignmentAnnotation aa,
+          int topl, int rowl, int rowr)
   {
-    for (int f=rowl;f<=rowr;f++) {
+    int[] mappedCl;
+    for (int f = rowl; f <= rowr; f++)
+    {
       ContactListI clist = seq.getContactListFor(aa, f);
-      assertNotNull(clist,"No ContactListI for position "+(f));
-      assertEquals(clist.getContactAt(0), (double) f-topl+1,"for column "+f+" relative to "+topl);
-      assertEquals(clist.getContactAt(f-topl),1d, "for column and row "+f+" relative to "+topl);
-    }    
+      assertNotNull(clist, "No ContactListI for position " + (f));
+      assertEquals(clist.getContactAt(0), (double) f - topl + 1,
+              "for column " + f + " relative to " + topl);
+      mappedCl = clist.getMappedPositionsFor(0, 0);
+      assertNotNull(mappedCl);
+      assertEquals(mappedCl[0], mappedCl[1]);
+      assertEquals(mappedCl[0], seq.findIndex(seq.getStart() + topl));
+      assertEquals(clist.getContactAt(f - topl), 1d,
+              "for column and row " + f + " relative to " + topl);
+    }
   }
 
+  /**
+   * check mapping and resolution methods work
+   */
+  @Test(groups = { "Functional" })
+  public void testMappableContactMatrix()
+  {
+    SequenceI newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    MapList map = new MapList(new int[] { 5, 9 }, new int[] { 1, 5 }, 1, 1);
+    AlignmentAnnotation aa = newseq.addContactList(
+            new PAEContactMatrix(newseq, map, PAEdata, null));
+    ContactListI clist = newseq.getContactListFor(aa, 4);
+    assertNotNull(clist);
+    clist = newseq.getContactListFor(aa, 3);
+    assertNull(clist);
+
+    ContactMatrixI cm = newseq.getContactMatrixFor(aa);
+    MappableContactMatrixI mcm = (MappableContactMatrixI) cm;
+    int[] pos = mcm.getMappedPositionsFor(newseq, 0);
+    assertNull(pos);
+
+    pos = mcm.getMappedPositionsFor(newseq, 1);
+    assertNotNull(pos);
+    assertEquals(pos[0], 4 + newseq.getStart());
+
+    pos = mcm.getMappedPositionsFor(newseq, 6); // after end of matrix
+    assertNull(pos);
+    pos = mcm.getMappedPositionsFor(newseq, 5); // at end of matrix
+    assertNotNull(pos);
+    assertEquals(pos[0], 8 + newseq.getStart());
+    SequenceI alseq = newseq.deriveSequence();
+    alseq.insertCharAt(5, '-');
+    pos = mcm.getMappedPositionsFor(alseq, 5); // at end of matrix
+    assertNotNull(pos);
+    assertEquals(pos[0], 8 + newseq.getStart());
+
+  }
 }