JAL-1925 update source version in license
[jalview.git] / src / jalview / analysis / AlignmentUtils.java
index cbd9c96..f2262fb 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2)
+ * Copyright (C) 2015 The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
@@ -228,8 +228,8 @@ public class AlignmentUtils
    * @param cdnaAlignment
    * @return
    */
-  public static boolean mapProteinToCdna(final AlignmentI proteinAlignment,
-          final AlignmentI cdnaAlignment)
+  public static boolean mapProteinAlignmentToCdna(
+          final AlignmentI proteinAlignment, final AlignmentI cdnaAlignment)
   {
     if (proteinAlignment == null || cdnaAlignment == null)
     {
@@ -275,7 +275,7 @@ public class AlignmentUtils
           final AlignmentI cdnaAlignment, Set<SequenceI> mappedDna,
           Set<SequenceI> mappedProtein, boolean xrefsOnly)
   {
-    boolean mappingPerformed = false;
+    boolean mappingExistsOrAdded = false;
     List<SequenceI> thisSeqs = proteinAlignment.getSequences();
     for (SequenceI aaSeq : thisSeqs)
     {
@@ -308,14 +308,18 @@ public class AlignmentUtils
         {
           continue;
         }
-        if (!mappingExists(proteinAlignment.getCodonFrames(),
+        if (mappingExists(proteinAlignment.getCodonFrames(),
                 aaSeq.getDatasetSequence(), cdnaSeq.getDatasetSequence()))
         {
-          MapList map = mapProteinToCdna(aaSeq, cdnaSeq);
+          mappingExistsOrAdded = true;
+        }
+        else
+        {
+          MapList map = mapProteinSequenceToCdna(aaSeq, cdnaSeq);
           if (map != null)
           {
             acf.addMap(cdnaSeq, aaSeq, map);
-            mappingPerformed = true;
+            mappingExistsOrAdded = true;
             proteinMapped = true;
             mappedDna.add(cdnaSeq);
             mappedProtein.add(aaSeq);
@@ -327,7 +331,7 @@ public class AlignmentUtils
         proteinAlignment.addCodonFrame(acf);
       }
     }
-    return mappingPerformed;
+    return mappingExistsOrAdded;
   }
 
   /**
@@ -360,7 +364,7 @@ public class AlignmentUtils
    * @param cdnaSeq
    * @return
    */
-  public static MapList mapProteinToCdna(SequenceI proteinSeq,
+  public static MapList mapProteinSequenceToCdna(SequenceI proteinSeq,
           SequenceI cdnaSeq)
   {
     /*
@@ -384,10 +388,10 @@ public class AlignmentUtils
      */
     final int mappedLength = 3 * aaSeqChars.length;
     int cdnaLength = cdnaSeqChars.length;
-    int cdnaStart = 1;
-    int cdnaEnd = cdnaLength;
-    final int proteinStart = 1;
-    final int proteinEnd = aaSeqChars.length;
+    int cdnaStart = cdnaSeq.getStart();
+    int cdnaEnd = cdnaSeq.getEnd();
+    final int proteinStart = proteinSeq.getStart();
+    final int proteinEnd = proteinSeq.getEnd();
 
     /*
      * If lengths don't match, try ignoring stop codon.
@@ -410,11 +414,13 @@ public class AlignmentUtils
     /*
      * If lengths still don't match, try ignoring start codon.
      */
+    int startOffset = 0;
     if (cdnaLength != mappedLength
             && cdnaLength > 2
             && String.valueOf(cdnaSeqChars, 0, 3).toUpperCase()
                     .equals(ResidueProperties.START))
     {
+      startOffset += 3;
       cdnaStart += 3;
       cdnaLength -= 3;
     }
@@ -423,7 +429,7 @@ public class AlignmentUtils
     {
       return null;
     }
-    if (!translatesAs(cdnaSeqChars, cdnaStart - 1, aaSeqChars))
+    if (!translatesAs(cdnaSeqChars, startOffset, aaSeqChars))
     {
       return null;
     }
@@ -567,6 +573,8 @@ public class AlignmentUtils
     /*
      * Traverse the aligned protein sequence.
      */
+    int fromOffset = alignFrom.getStart() - 1;
+    int toOffset = alignTo.getStart() - 1;
     int sourceGapMappedLength = 0;
     boolean inExon = false;
     for (char sourceChar : thatAligned)
@@ -583,7 +591,7 @@ public class AlignmentUtils
       sourceDsPos++;
       // Note mapping positions are base 1, our sequence positions base 0
       int[] mappedPos = mapping.getMappedRegion(alignTo, alignFrom,
-              sourceDsPos);
+              sourceDsPos + fromOffset);
       if (mappedPos == null)
       {
         /*
@@ -607,14 +615,15 @@ public class AlignmentUtils
        * But then 'align dna as protein' doesn't make much sense otherwise.
        */
       int intronLength = 0;
-      while (basesWritten < mappedCodonEnd && thisSeqPos < thisSeq.length)
+      while (basesWritten + toOffset < mappedCodonEnd
+              && thisSeqPos < thisSeq.length)
       {
         final char c = thisSeq[thisSeqPos++];
         if (c != myGapChar)
         {
           basesWritten++;
-
-          if (basesWritten < mappedCodonStart)
+          int sourcePosition = basesWritten + toOffset;
+          if (sourcePosition < mappedCodonStart)
           {
             /*
              * Found an unmapped (intron) base. First add in any preceding gaps
@@ -631,7 +640,7 @@ public class AlignmentUtils
           }
           else
           {
-            final boolean startOfCodon = basesWritten == mappedCodonStart;
+            final boolean startOfCodon = sourcePosition == mappedCodonStart;
             int gapsToAdd = calculateGapsToInsert(preserveMappedGaps,
                     preserveUnmappedGaps, sourceGapMappedLength, inExon,
                     trailingCopiedGap.length(), intronLength, startOfCodon);
@@ -1090,7 +1099,7 @@ public class AlignmentUtils
      * Just try to make a mapping (it is not yet stored), test whether
      * successful.
      */
-    return mapProteinToCdna(proteinDs, dnaDs) != null;
+    return mapProteinSequenceToCdna(proteinDs, dnaDs) != null;
   }
 
   /**