JAL-4134 properly resolve positions in associated aligned sequence for matrix group...
[jalview.git] / src / jalview / ws / datamodel / alphafold / MappableContactMatrix.java
index dc8e0d3..d545741 100644 (file)
@@ -14,9 +14,11 @@ import jalview.datamodel.SequenceI;
 import jalview.util.MapList;
 import jalview.ws.datamodel.MappableContactMatrixI;
 
-public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>> implements MappableContactMatrixI
+public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
+        implements MappableContactMatrixI
 {
   SequenceI refSeq = null;
+
   MapList toSeq = null;
 
   /**
@@ -24,7 +26,6 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
    */
   int length;
 
-
   @Override
   public boolean hasReferenceSeq()
   {
@@ -36,15 +37,18 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
   {
     return refSeq;
   }
+
   /**
    * container for groups - defined on matrix columns
    */
-  GroupSet grps=new GroupSet();
+  GroupSet grps = new GroupSet();
+
   @Override
   public GroupSetI getGroupSet()
   {
     return grps;
   };
+
   @Override
   public void setGroupSet(GroupSet makeGroups)
   {
@@ -54,28 +58,33 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
   @Override
   public MapList getMapFor(SequenceI mapSeq)
   {
-    if (refSeq!=null)
+    if (refSeq != null)
     {
-      while (mapSeq!=refSeq && mapSeq.getDatasetSequence()!=null)
+      while (mapSeq != refSeq && mapSeq.getDatasetSequence() != null)
       {
         mapSeq = mapSeq.getDatasetSequence();
       }
-      if (mapSeq!=refSeq)
+      if (mapSeq != refSeq)
       {
         return null;
       }
-    } else {
-      if (mapSeq!=null) {
+    }
+    else
+    {
+      if (mapSeq != null)
+      {
         // our MapList does not concern this seq
         return null;
       }
     }
-    
+
     return toSeq;
   }
 
   /**
-   * set the reference sequence and construct the mapping between the start-end positions of given sequence and row/columns of contact matrix
+   * set the reference sequence and construct the mapping between the start-end
+   * positions of given sequence and row/columns of contact matrix
+   * 
    * @param _refSeq
    */
   public void setRefSeq(SequenceI _refSeq)
@@ -86,9 +95,13 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
       refSeq = refSeq.getDatasetSequence();
     }
     length = _refSeq.getEnd() - _refSeq.getStart() + 1;
-//    if (length!=refSeq.getLength() || _refSeq.getStart()!=1)
+    // if (length!=refSeq.getLength() || _refSeq.getStart()!=1)
     {
-      toSeq = new MapList(new int[] { _refSeq.getStart(), _refSeq.getEnd()}, new int[] { 0,length-1}, 1,1);
+      toSeq = new MapList(
+              new int[]
+              { _refSeq.getStart(), _refSeq.getEnd() },
+              new int[]
+              { 0, length - 1 }, 1, 1);
     }
   }
 
@@ -163,35 +176,27 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
     return newCM;
   }
 
-  protected abstract T  newMappableContactMatrix(SequenceI newRefSeq,
+  protected abstract T newMappableContactMatrix(SequenceI newRefSeq,
           MapList newFromMapList);
+
   @Override
   public int[] getMappedPositionsFor(final SequenceI localFrame,
           final int column)
   {
-    return getMappedPositionsFor(localFrame,column,column);
+    return getMappedPositionsFor(localFrame, column, column);
   }
-  public int[] getMappedPositionsFor(final SequenceI localFrame,
-          int from,int to)
+
+  @Override
+  public int[] getMappedPositionsFor(final SequenceI localFrame, int from,
+          int to)
   {
-    if (localFrame==null)
+    if (localFrame == null)
     {
       throw new Error("Unimplemented when no local sequence given.");
     }
-    // return a ContactListI for column
-    // column is index into localFrame
-    // 1. map column to corresponding column in matrix
-    
-    final int _lcolumn=localFrame.findPosition(from);
-    final int _rcolumn=(from==to) ? _lcolumn:localFrame.findPosition(to);
-    if (toSeq == null)
-    {
-      // no mapping
-      return new int[] { _lcolumn,_rcolumn};
-    }
-
     SequenceI lf = localFrame, uf = refSeq;
 
+    // check that localFrame is derived from refSeq
     // just look for dataset sequences and check they are the same.
     // in future we could use DBRefMappings/whatever.
     while (lf.getDatasetSequence() != null
@@ -214,25 +219,44 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
               + localFrame.getName() + ")");
     }
     
-    int[] mappedPositions = toSeq.locateInFrom(_lcolumn,_rcolumn);
-    // TODO - trim to localFrame ?
-//    if (mappedPositions!=null) {
-//      int s=-1,e=-1; 
-//      for (int p=0;p<mappedPositions.length;p++)
+    // now look up from-to matrix columns in toSeq frame
+    
+    if (toSeq == null)
+    {
+      // no mapping - so we assume 1:1
+      return new int[] { from, to };
+    }
+    // from-to are matrix columns
+    // first locate on reference sequence
+
+    int[] mappedPositions = toSeq.locateInFrom(from, to);
+    if (mappedPositions==null)
+    {
+      return null;
+    }
+    
+    // and now map to localFrame
+    // from-to columns on the associated sequence should be
+    // i. restricted to positions in localFrame
+    // ii. 
+
+//    int s = -1, e = -1;
+//    for (int p = 0; p < mappedPositions.length; p++)
+//    {
+//      if (s == -1 && mappedPositions[p] >= localFrame.getStart())
+//      {
+//        s = p; // remember first position within local frame
+//      }
+//      if (e == -1 || mappedPositions[p] <= localFrame.getEnd())
 //      {
-//        if (s==-1 && mappedPositions[p]>=localFrame.getStart())
-//        {
-//          s=p; // remember first position within local frame
-//        }
-//        if (e==-1 || mappedPositions[p]<=localFrame.getEnd())
-//        {
-//          // update end pointer
-//          e=p;
-//          // compute local map
-//          mappedPositions[p] = localFrame.findIndex(mappedPositions[p]);
-//        }
+//        // update end pointer
+//        e = p;
+//        // compute local map
+//        mappedPositions[p] = localFrame.findIndex(mappedPositions[p]);
 //      }
 //    }
+//    int[] _trimmed = new int[e - s + 1];
+//    return _trimmed;
     return mappedPositions;
   }
 
@@ -242,16 +266,16 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
   {
     final int _column;
     final int _lcolumn;
-    if (localFrame==null)
+    if (localFrame == null)
     {
       throw new Error("Unimplemented when no local sequence given.");
     }
     // return a ContactListI for column
     // column is index into localFrame
     // 1. map column to corresponding column in matrix
-    final MappableContactMatrix us=this;
-    _lcolumn=localFrame.findPosition(column);
-    
+    final MappableContactMatrix us = this;
+    _lcolumn = localFrame.findPosition(column);
+
     if (toSeq != null)
     {
       SequenceI lf = localFrame, uf = refSeq;
@@ -287,11 +311,11 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
     }
     else
     {
-      // no mapping 
+      // no mapping
       _column = _lcolumn;
     }
 
-    // TODO - remove ? this may be a redundant check 
+    // TODO - remove ? this may be a redundant check
     if (_column < 0 || ((toSeq != null && _column > toSeq.getToHighest())
             || (toSeq == null && getHeight() <= _column)))
     {
@@ -307,11 +331,11 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
     int h = 0;
     for (int p = 0; p < matrixRange.length; p += 2)
     {
-      h += 1+Math.abs(matrixRange[p + 1] - matrixRange[p]);
+      h += 1 + Math.abs(matrixRange[p + 1] - matrixRange[p]);
     }
     final int rangeHeight = h;
     // 3. Construct ContactListImpl instance for just those segments.
-    
+
     return new ContactListImpl(new ContactListProviderI()
     {
 
@@ -403,6 +427,7 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
         }
         return matrixRange[p] + mcolumn - h;
       }
+
       @Override
       public Color getColourForGroup()
       {
@@ -415,12 +440,13 @@ public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
 
   /**
    * get a specific element of the contact matrix in its data-local coordinates
-   * rather than the mapped frame. Implementations are allowed to throw RunTimeExceptions if _column/i are out of bounds
+   * rather than the mapped frame. Implementations are allowed to throw
+   * RunTimeExceptions if _column/i are out of bounds
    * 
    * @param _column
    * @param i
    * @return
    */
   protected abstract double getElementAt(int _column, int i);
-  
+
 }