Merge branch 'JAL-2075_features_hiddeng' into develop
authorJim Procter <jprocter@issues.jalview.org>
Sun, 24 Apr 2016 10:28:48 +0000 (11:28 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Sun, 24 Apr 2016 10:28:48 +0000 (11:28 +0100)
src/jalview/analysis/scoremodels/FeatureScoreModel.java
src/jalview/datamodel/SeqCigar.java
test/jalview/datamodel/SeqCigarTest.java

index 1ca3342..7c81912 100644 (file)
@@ -23,9 +23,8 @@ package jalview.analysis.scoremodels;
 import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.ViewBasedAnalysisI;
 import jalview.datamodel.AlignmentView;
+import jalview.datamodel.SeqCigar;
 import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceI;
-import jalview.util.Comparison;
 
 import java.util.ArrayList;
 import java.util.Hashtable;
@@ -48,13 +47,10 @@ public class FeatureScoreModel implements ScoreModelI, ViewBasedAnalysisI
   {
     int nofeats = 0;
     List<String> dft = fr.getDisplayedFeatureTypes();
-
     nofeats = dft.size();
-
-    SequenceI[] sequenceString = seqData.getVisibleAlignment(
-            Comparison.GapChars.charAt(0)).getSequencesArray();
-    int noseqs = sequenceString.length;
-    int cpwidth = seqData.getWidth();
+    SeqCigar[] seqs = seqData.getSequences();
+    int noseqs = seqs.length;
+    int cpwidth = 0;// = seqData.getWidth();
     float[][] distance = new float[noseqs][noseqs];
     if (nofeats == 0)
     {
@@ -67,54 +63,64 @@ public class FeatureScoreModel implements ScoreModelI, ViewBasedAnalysisI
       }
       return distance;
     }
-    float max = 0;
-    for (int cpos = 0; cpos < cpwidth; cpos++)
+    // need to get real position for view position
+    int[] viscont = seqData.getVisibleContigs();
+    for (int vc = 0; vc < viscont.length; vc += 2)
     {
-      // get visible features at cpos under view's display settings and compare
-      // them
-      List<Hashtable<String, SequenceFeature>> sfap = new ArrayList<Hashtable<String, SequenceFeature>>();
-      for (int i = 0; i < noseqs; i++)
-      {
-        Hashtable<String, SequenceFeature> types = new Hashtable<String, SequenceFeature>();
-        List<SequenceFeature> sfs = fr.findFeaturesAtRes(sequenceString[i],
-                sequenceString[i].findPosition(cpos));
-        for (SequenceFeature sf : sfs)
-        {
-          types.put(sf.getType(), sf);
-        }
-        sfap.add(types);
-      }
-      for (int i = 0; i < (noseqs - 1); i++)
+
+      for (int cpos = viscont[vc]; cpos <= viscont[vc + 1]; cpos++)
       {
-        if (cpos == 0)
-        {
-          distance[i][i] = 0f;
-        }
-        for (int j = i + 1; j < noseqs; j++)
+        cpwidth++;
+        // get visible features at cpos under view's display settings and
+        // compare them
+        List<Hashtable<String, SequenceFeature>> sfap = new ArrayList<Hashtable<String, SequenceFeature>>();
+        for (int i = 0; i < noseqs; i++)
         {
-          int sfcommon = 0;
-          // compare the two lists of features...
-          Hashtable<String, SequenceFeature> fi = sfap.get(i), fk, fj = sfap
-                  .get(j);
-          if (fi.size() > fj.size())
+          Hashtable<String, SequenceFeature> types = new Hashtable<String, SequenceFeature>();
+          int spos = seqs[i].findPosition(cpos);
+          if (spos != -1)
           {
-            fk = fj;
+            List<SequenceFeature> sfs = fr.findFeaturesAtRes(
+                    seqs[i].getRefSeq(), spos);
+            for (SequenceFeature sf : sfs)
+            {
+              types.put(sf.getType(), sf);
+            }
           }
-          else
+          sfap.add(types);
+        }
+        for (int i = 0; i < (noseqs - 1); i++)
+        {
+          if (cpos == 0)
           {
-            fk = fi;
-            fi = fj;
+            distance[i][i] = 0f;
           }
-          for (String k : fi.keySet())
+          for (int j = i + 1; j < noseqs; j++)
           {
-            SequenceFeature sfj = fk.get(k);
-            if (sfj != null)
+            int sfcommon = 0;
+            // compare the two lists of features...
+            Hashtable<String, SequenceFeature> fi = sfap.get(i), fk, fj = sfap
+                    .get(j);
+            if (fi.size() > fj.size())
+            {
+              fk = fj;
+            }
+            else
+            {
+              fk = fi;
+              fi = fj;
+            }
+            for (String k : fi.keySet())
             {
-              sfcommon++;
+              SequenceFeature sfj = fk.get(k);
+              if (sfj != null)
+              {
+                sfcommon++;
+              }
             }
+            distance[i][j] += (fi.size() + fk.size() - 2f * sfcommon);
+            distance[j][i] += distance[i][j];
           }
-          distance[i][j] += (fi.size() + fk.size() - 2f * sfcommon);
-          distance[j][i] += distance[i][j];
         }
       }
     }
index d279a26..98b0de5 100644 (file)
@@ -68,10 +68,49 @@ public class SeqCigar extends CigarSimple
   }
 
   /**
+   * 
+   * @param column
+   * @return position in sequence for column (or -1 if no match state exists)
+   */
+  public int findPosition(int column)
+  {
+    int w = 0, ew, p = refseq.findPosition(start);
+    if (column < 0)
+    {
+      return -1;
+    }
+    if (range != null)
+    {
+      for (int i = 0; i < length; i++)
+      {
+        if (operation[i] == M || operation[i] == D)
+        {
+          p += range[i];
+        }
+        if (operation[i] == M || operation[i] == I)
+        {
+          ew = w + range[i];
+          if (column < ew)
+          {
+            if (operation[i] == I)
+            {
+              return -1;
+            }
+            return p - (ew - column);
+          }
+          w = ew;
+        }
+      }
+    }
+    return -1;
+  }
+
+  /**
    * Returns sequence as a string with cigar operations applied to it
    * 
    * @return String
    */
+  @Override
   public String getSequenceString(char GapChar)
   {
     return (length == 0) ? "" : (String) getSequenceAndDeletions(
index 705c773..8d3c878 100644 (file)
@@ -23,6 +23,8 @@ package jalview.datamodel;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 
+import jalview.util.Comparison;
+
 import org.testng.annotations.Test;
 
 /**
@@ -30,6 +32,29 @@ import org.testng.annotations.Test;
  */
 public class SeqCigarTest
 {
+  @Test(groups = { "Functional" })
+  public void testFindPosition()
+  {
+    SequenceI oseq = new Sequence("MySeq", "ASD---ASD---ASD", 37, 45);
+    oseq.createDatasetSequence();
+    SeqCigar cs = new SeqCigar(oseq);
+    assertEquals(oseq.getSequenceAsString(), cs.getSequenceString('-'));
+    for (int c = 0, cLen = oseq.getLength(); c < cLen; c++)
+    {
+      int os_p = oseq.findPosition(c);
+      int cigar_p = cs.findPosition(c);
+      if (Comparison.isGap(oseq.getCharAt(c)))
+      {
+        assertEquals("Expected gap at position " + os_p + " column " + c,
+                -1, cigar_p);
+      }
+      else
+      {
+        assertEquals("Positions don't match for at column " + c, os_p,
+                cigar_p);
+      }
+    }
+  }
   /*
    * refactored 'as is' from main method
    *