JAL-653 (experimental) methods to resolve dummy to real sequence
[jalview.git] / src / jalview / datamodel / AlignedCodonFrame.java
index 9c642cf..d24593a 100644 (file)
@@ -461,4 +461,117 @@ public class AlignedCodonFrame
     }
     return result;
   }
+
+  /**
+   * Test whether the given sequence is substitutable for one or more dummy
+   * sequences in this mapping
+   * 
+   * @param map
+   * @param seq
+   * @return
+   */
+  public boolean isRealisableWith(SequenceI seq)
+  {
+    return realiseWith(seq, false) > 0;
+  }
+
+  /**
+   * Replace any matchable mapped dummy sequences with the given real one.
+   * Returns the count of sequence mappings instantiated.
+   * 
+   * @param seq
+   * @return
+   */
+  public int realiseWith(SequenceI seq)
+  {
+    return realiseWith(seq, true);
+  }
+
+  /**
+   * Returns the number of mapped dummy sequences that could be replaced with
+   * the given real sequence.
+   * 
+   * @param seq
+   *          a dataset sequence
+   * @param doUpdate
+   *          if true, performs replacements, else only counts
+   * @return
+   */
+  protected int realiseWith(SequenceI seq, boolean doUpdate)
+  {
+    SequenceI ds = seq.getDatasetSequence() != null ? seq
+            .getDatasetSequence() : seq;
+    int count = 0;
+
+    /*
+     * check for replaceable DNA ('map from') sequences
+     */
+    for (int i = 0; i < dnaSeqs.length; i++)
+    {
+      SequenceI dna = dnaSeqs[i];
+      if (dna instanceof SequenceDummy
+              && dna.getName().equals(ds.getName()))
+      {
+        Mapping mapping = dnaToProt[i];
+        int mapStart = mapping.getMap().getFromLowest();
+        int mapEnd = mapping.getMap().getFromHighest();
+        boolean mappable = couldReplaceSequence(dna, ds, mapStart, mapEnd);
+        if (mappable)
+        {
+          count++;
+          if (doUpdate)
+          {
+            dnaSeqs[i] = ds;
+          }
+        }
+      }
+
+      /*
+       * check for replaceable protein ('map to') sequences
+       */
+      SequenceI prot = dnaToProt[i].getTo();
+      Mapping mapping = dnaToProt[i];
+      int mapStart = mapping.getMap().getToLowest();
+      int mapEnd = mapping.getMap().getToHighest();
+      boolean mappable = couldReplaceSequence(prot, ds, mapStart, mapEnd);
+      if (mappable)
+      {
+        count++;
+        if (doUpdate)
+        {
+          dnaToProt[i].setTo(ds);
+        }
+      }
+    }
+    return count;
+  }
+
+  /**
+   * Helper method to test whether a 'real' sequence could replace a 'dummy'
+   * sequence in the map. The criteria are that they have the same name, and
+   * that the mapped region overlaps the candidate sequence.
+   * 
+   * @param existing
+   * @param replacement
+   * @param mapStart
+   * @param mapEnd
+   * @return
+   */
+  protected static boolean couldReplaceSequence(SequenceI existing,
+          SequenceI replacement, int mapStart, int mapEnd)
+  {
+    if (existing instanceof SequenceDummy
+            && existing.getName().equals(replacement.getName()))
+    {
+      int start = replacement.getStart();
+      int end = replacement.getEnd();
+      boolean mappingOverlapsSequence = (mapStart >= start && mapStart <= end)
+              || (mapEnd >= start && mapEnd <= end);
+      if (mappingOverlapsSequence)
+      {
+        return true;
+      }
+    }
+    return false;
+  }
 }