Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / datamodel / MappedFeatures.java
index 520ff92..4637974 100644 (file)
@@ -1,5 +1,27 @@
+/*
+ * 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 java.util.Locale;
+
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -29,21 +51,16 @@ public class MappedFeatures
   /*
    * the sequence the mapped features are on
    */
-  private final SequenceI linkedSeq;
+  private final SequenceI featureSequence;
 
   /*
    * the mapping between sequences;
-   * NB this could be in either sense
+   * NB this could be in either sense (from or to featureSequence)
    */
   private final Mapping mapping;
 
   /*
-   * if true, mapping is from the linked sequence, else to the linked sequence
-   */
-  private boolean mappingIsFromLinkedSequence;
-
-  /*
-   * features on linkedSeq that overlap the mapped positions
+   * features on featureSequence that overlap the mapped positions
    */
   public final List<SequenceFeature> features;
 
@@ -70,22 +87,23 @@ public class MappedFeatures
    * Constructor
    * 
    * @param theMapping
-   * @param from
-   *                      the sequence mapped from (e.g. CDS)
+   *          sequence mapping (which may be either to, or from, the sequence
+   *          holding the linked features)
+   * @param featureSeq
+   *          the sequence hosting the virtual features
    * @param pos
-   *                      the residue position in the sequence mapped to
+   *          the residue position in the sequence mapped to
    * @param res
-   *                      the residue character at position pos
+   *          the residue character at position pos
    * @param theFeatures
-   *                      list of mapped features found in the 'from' sequence at
-   *                      the mapped position(s)
+   *          list of mapped features found in the 'featureSeq' sequence at the
+   *          mapped position(s)
    */
-  public MappedFeatures(Mapping theMapping, SequenceI from, int pos,
+  public MappedFeatures(Mapping theMapping, SequenceI featureSeq, int pos,
           char res, List<SequenceFeature> theFeatures)
   {
     mapping = theMapping;
-    linkedSeq = from;
-    mappingIsFromLinkedSequence = mapping.to != linkedSeq;
+    featureSequence = featureSeq;
     toPosition = pos;
     toResidue = res;
     features = theFeatures;
@@ -94,20 +112,21 @@ public class MappedFeatures
      * determine codon positions and canonical codon
      * for a peptide-to-CDS mapping
      */
-    int[] codonIntervals = mapping.getMap().locateInFrom(toPosition, toPosition);
+    int[] codonIntervals = mapping.getMap().locateInFrom(toPosition,
+            toPosition);
     int[] codonPositions = codonIntervals == null ? null
             : MappingUtils.flattenRanges(codonIntervals);
     if (codonPositions != null && codonPositions.length == 3)
     {
       codonPos = codonPositions;
       baseCodon = new char[3];
-      int cdsStart = linkedSeq.getStart();
-      baseCodon[0] = Character
-              .toUpperCase(linkedSeq.getCharAt(codonPos[0] - cdsStart));
-      baseCodon[1] = Character
-              .toUpperCase(linkedSeq.getCharAt(codonPos[1] - cdsStart));
-      baseCodon[2] = Character
-              .toUpperCase(linkedSeq.getCharAt(codonPos[2] - cdsStart));
+      int cdsStart = featureSequence.getStart();
+      baseCodon[0] = Character.toUpperCase(
+              featureSequence.getCharAt(codonPos[0] - cdsStart));
+      baseCodon[1] = Character.toUpperCase(
+              featureSequence.getCharAt(codonPos[1] - cdsStart));
+      baseCodon[2] = Character.toUpperCase(
+              featureSequence.getCharAt(codonPos[2] - cdsStart));
     }
     else
     {
@@ -183,12 +202,12 @@ public class MappedFeatures
      * e.g. C,G,T gives variants G and T for base C
      */
     Set<String> variantPeptides = new HashSet<>();
-    String[] alleles = alls.toUpperCase().split(",");
+    String[] alleles = alls.toUpperCase(Locale.ROOT).split(",");
     StringBuilder vars = new StringBuilder();
 
     for (String allele : alleles)
     {
-      allele = allele.trim().toUpperCase();
+      allele = allele.trim().toUpperCase(Locale.ROOT);
       if (allele.length() > 1 || "-".equals(allele))
       {
         continue; // multi-locus variant
@@ -204,7 +223,7 @@ public class MappedFeatures
        */
       final int i = cdsPos == codonPos[0] ? 0
               : (cdsPos == codonPos[1] ? 1 : 2);
-      variantCodon[i] = allele.toUpperCase().charAt(0);
+      variantCodon[i] = allele.toUpperCase(Locale.ROOT).charAt(0);
       if (variantCodon[i] == baseCodon[i])
       {
         continue;
@@ -220,8 +239,7 @@ public class MappedFeatures
          */
         var.append("c.").append(String.valueOf(cdsPos))
                 .append(String.valueOf(baseCodon[i])).append(">")
-                .append(String.valueOf(variantCodon[i]))
-                .append("(p.=)");
+                .append(String.valueOf(variantCodon[i])).append("(p.=)");
       }
       else
       {
@@ -255,7 +273,7 @@ public class MappedFeatures
    */
   public String getLinkedSequenceName()
   {
-    return linkedSeq == null ? null : linkedSeq.getName();
+    return featureSequence == null ? null : featureSequence.getName();
   }
 
   /**
@@ -278,16 +296,22 @@ public class MappedFeatures
   public int[] getMappedPositions(int begin, int end)
   {
     MapList map = mapping.getMap();
-    return mappingIsFromLinkedSequence ? map.locateInTo(begin, end)
-            : map.locateInFrom(begin, end);
+    return mapping.to == featureSequence ? map.getOverlapsInFrom(begin, end)
+            : map.getOverlapsInTo(begin, end);
   }
 
+  /**
+   * Answers true if the linked features are on coding sequence, false if on
+   * peptide
+   * 
+   * @return
+   */
   public boolean isFromCds()
   {
     if (mapping.getMap().getFromRatio() == 3)
     {
-      return mappingIsFromLinkedSequence;
+      return mapping.to != featureSequence;
     }
-    return !mappingIsFromLinkedSequence;
+    return mapping.to == featureSequence;
   }
 }