JAL-3567 report mapped location for virtual features in tooltip etc
[jalview.git] / src / jalview / datamodel / MappedFeatures.java
index 0fa03cf..a42f34a 100644 (file)
@@ -1,14 +1,15 @@
 package jalview.datamodel;
 
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 import jalview.io.gff.Gff3Helper;
 import jalview.schemes.ResidueProperties;
+import jalview.util.MapList;
 import jalview.util.MappingUtils;
 import jalview.util.StringUtils;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 /**
  * A data bean to hold a list of mapped sequence features (e.g. CDS features
  * mapped from protein), and the mapping between the sequences. It also provides
@@ -18,22 +19,31 @@ import java.util.Set;
  */
 public class MappedFeatures
 {
+  /*
+   * VEP CSQ:HGVSp (if present) is a short-cut to the protein variant consequence
+   */
   private static final String HGV_SP = "HGVSp";
 
   private static final String CSQ = "CSQ";
 
   /*
-   * the mapping from one sequence to another
+   * the sequence the mapped features are on
    */
-  public final Mapping mapping;
+  private final SequenceI linkedSeq;
 
-  /**
-   * the sequence mapped from
+  /*
+   * the mapping between sequences;
+   * NB this could be in either sense
    */
-  public final SequenceI fromSeq;
+  private final Mapping mapping;
 
   /*
-   * features on the sequence mapped to that overlap the mapped positions
+   * if true, mapping is from the linked sequence, else to the linked sequence
+   */
+  private boolean mappingIsFromLinkedSequence;
+
+  /*
+   * features on linkedSeq that overlap the mapped positions
    */
   public final List<SequenceFeature> features;
 
@@ -74,7 +84,8 @@ public class MappedFeatures
           char res, List<SequenceFeature> theFeatures)
   {
     mapping = theMapping;
-    fromSeq = from;
+    linkedSeq = from;
+    mappingIsFromLinkedSequence = mapping.to != linkedSeq;
     toPosition = pos;
     toResidue = res;
     features = theFeatures;
@@ -90,13 +101,13 @@ public class MappedFeatures
     {
       codonPos = codonPositions;
       baseCodon = new char[3];
-      int cdsStart = fromSeq.getStart();
+      int cdsStart = linkedSeq.getStart();
       baseCodon[0] = Character
-              .toUpperCase(fromSeq.getCharAt(codonPos[0] - cdsStart));
+              .toUpperCase(linkedSeq.getCharAt(codonPos[0] - cdsStart));
       baseCodon[1] = Character
-              .toUpperCase(fromSeq.getCharAt(codonPos[1] - cdsStart));
+              .toUpperCase(linkedSeq.getCharAt(codonPos[1] - cdsStart));
       baseCodon[2] = Character
-              .toUpperCase(fromSeq.getCharAt(codonPos[2] - cdsStart));
+              .toUpperCase(linkedSeq.getCharAt(codonPos[2] - cdsStart));
     }
     else
     {
@@ -233,4 +244,47 @@ public class MappedFeatures
 
     return vars.toString();
   }
+
+  /**
+   * Answers the name of the linked sequence holding any mapped features
+   * 
+   * @return
+   */
+  public String getLinkedSequenceName()
+  {
+    return linkedSeq == null ? null : linkedSeq.getName();
+  }
+
+  /**
+   * Answers the mapped ranges (as one or more [start, end] positions) which
+   * correspond to the given [begin, end] range of the linked sequence.
+   * 
+   * <pre>
+   * Example: MappedFeatures with CDS features mapped to peptide 
+   * CDS/200-220 gtc aac TGa acGt att AAC tta
+   * mapped to PEP/6-7 WN by mapping [206, 207, 210, 210, 215, 217] to [6, 7]
+   * getMappedPositions(206, 206) should return [6, 6]
+   * getMappedPositions(200, 214) should return [6, 6]
+   * getMappedPositions(210, 215) should return [6, 7]
+   * </pre>
+   * 
+   * @param begin
+   * @param end
+   * @return
+   */
+  public int[] getMappedPositions(int begin, int end)
+  {
+    MapList map = mapping.getMap();
+    return mappingIsFromLinkedSequence ? map.locateInTo(begin, end)
+            : map.locateInFrom(begin, end);
+  }
+
+  public boolean isFromCds()
+  {
+    if (mapping.getMap().getFromRatio() == 3)
+    {
+      return mappingIsFromLinkedSequence;
+    }
+    return !mappingIsFromLinkedSequence;
+  }
 }