JAL-2826 added action performed for hiding collapsed sequences
[jalview.git] / src / jalview / util / MappingUtils.java
index 926ccc7..78a833e 100644 (file)
@@ -108,7 +108,7 @@ public final class MappingUtils
      * Cache a copy of the target sequences so we can mimic successive edits on
      * them. This lets us compute mappings for all edits in the set.
      */
-    Map<SequenceI, SequenceI> targetCopies = new HashMap<SequenceI, SequenceI>();
+    Map<SequenceI, SequenceI> targetCopies = new HashMap<>();
     for (SequenceI seq : mapTo.getSequences())
     {
       SequenceI ds = seq.getDatasetSequence();
@@ -219,8 +219,9 @@ public final class MappingUtils
              * Shift Delete start position left, as it acts on positions to its
              * right.
              */
-            int mappedEditPos = action == Action.DELETE_GAP ? match[0]
-                    - mappedCount : match[0];
+            int mappedEditPos = action == Action.DELETE_GAP
+                    ? match[0] - mappedCount
+                    : match[0];
             Edit e = result.new Edit(action, new SequenceI[] { targetSeq },
                     mappedEditPos, mappedCount, gapChar);
             result.addEdit(e);
@@ -230,15 +231,15 @@ public final class MappingUtils
              */
             if (action == Action.INSERT_GAP)
             {
-              copyTarget.setSequence(new String(StringUtils.insertCharAt(
-                      copyTarget.getSequence(), mappedEditPos, mappedCount,
-                      gapChar)));
+              copyTarget.setSequence(new String(
+                      StringUtils.insertCharAt(copyTarget.getSequence(),
+                              mappedEditPos, mappedCount, gapChar)));
             }
             else if (action == Action.DELETE_GAP)
             {
-              copyTarget.setSequence(new String(StringUtils.deleteChars(
-                      copyTarget.getSequence(), mappedEditPos,
-                      mappedEditPos + mappedCount)));
+              copyTarget.setSequence(new String(
+                      StringUtils.deleteChars(copyTarget.getSequence(),
+                              mappedEditPos, mappedEditPos + mappedCount)));
             }
           }
         }
@@ -363,8 +364,9 @@ public final class MappingUtils
 
       for (AlignedCodonFrame acf : codonFrames)
       {
-        SequenceI mappedSequence = targetIsNucleotide ? acf
-                .getDnaForAaSeq(selected) : acf.getAaForDnaSeq(selected);
+        SequenceI mappedSequence = targetIsNucleotide
+                ? acf.getDnaForAaSeq(selected)
+                : acf.getAaForDnaSeq(selected);
         if (mappedSequence != null)
         {
           for (SequenceI seq : mapTo.getAlignment().getSequences())
@@ -377,7 +379,8 @@ public final class MappingUtils
                * Found a sequence mapping. Locate the start/end mapped residues.
                */
               List<AlignedCodonFrame> mapping = Arrays
-                      .asList(new AlignedCodonFrame[] { acf });
+                      .asList(new AlignedCodonFrame[]
+                      { acf });
               SearchResultsI sr = buildSearchResults(selected,
                       startResiduePos, mapping);
               for (SearchResultMatchI m : sr.getResults())
@@ -398,11 +401,11 @@ public final class MappingUtils
                * returns a base 1 position, SequenceGroup uses base 0
                */
               int mappedStartCol = seq.findIndex(mappedStartResidue) - 1;
-              minStartCol = minStartCol == -1 ? mappedStartCol : Math.min(
-                      minStartCol, mappedStartCol);
+              minStartCol = minStartCol == -1 ? mappedStartCol
+                      : Math.min(minStartCol, mappedStartCol);
               int mappedEndCol = seq.findIndex(mappedEndResidue) - 1;
-              maxEndCol = maxEndCol == -1 ? mappedEndCol : Math.max(
-                      maxEndCol, mappedEndCol);
+              maxEndCol = maxEndCol == -1 ? mappedEndCol
+                      : Math.max(maxEndCol, mappedEndCol);
               mappedGroup.addSequence(seq, false);
               break;
             }
@@ -429,11 +432,11 @@ public final class MappingUtils
    *          the mappings available
    * @return
    */
-  public static CommandI mapOrderCommand(OrderCommand command,
-          boolean undo, AlignmentI mapTo, List<AlignedCodonFrame> mappings)
+  public static CommandI mapOrderCommand(OrderCommand command, boolean undo,
+          AlignmentI mapTo, List<AlignedCodonFrame> mappings)
   {
     SequenceI[] sortOrder = command.getSequenceOrder(undo);
-    List<SequenceI> mappedOrder = new ArrayList<SequenceI>();
+    List<SequenceI> mappedOrder = new ArrayList<>();
     int j = 0;
 
     /*
@@ -518,7 +521,6 @@ public final class MappingUtils
     AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo;
     List<AlignedCodonFrame> codonFrames = protein.getAlignment()
             .getCodonFrames();
-    // ColumnSelection mappedColumns = new ColumnSelection();
 
     if (colsel == null)
     {
@@ -540,7 +542,7 @@ public final class MappingUtils
               toSequences, fromGapChar);
     }
 
-    for (int[] hidden : hiddencols.getHiddenRegions())
+    for (int[] hidden : hiddencols.getHiddenColumnsCopy())
     {
       mapHiddenColumns(hidden, codonFrames, newHidden, fromSequences,
               toSequences, fromGapChar);
@@ -593,10 +595,9 @@ public final class MappingUtils
    * @param toSequences
    * @param fromGapChar
    */
-  protected static void mapColumn(int col,
-          List<AlignedCodonFrame> mappings, ColumnSelection mappedColumns,
-          List<SequenceI> fromSequences, List<SequenceI> toSequences,
-          char fromGapChar)
+  protected static void mapColumn(int col, List<AlignedCodonFrame> mappings,
+          ColumnSelection mappedColumns, List<SequenceI> fromSequences,
+          List<SequenceI> toSequences, char fromGapChar)
   {
     int[] mappedTo = findMappedColumns(col, mappings, fromSequences,
             toSequences, fromGapChar);
@@ -696,14 +697,14 @@ public final class MappingUtils
   public static List<char[]> findCodonsFor(SequenceI seq, int col,
           List<AlignedCodonFrame> mappings)
   {
-    List<char[]> result = new ArrayList<char[]>();
+    List<char[]> result = new ArrayList<>();
     int dsPos = seq.findPosition(col);
     for (AlignedCodonFrame mapping : mappings)
     {
       if (mapping.involvesSequence(seq))
       {
-        List<char[]> codons = mapping.getMappedCodons(
-                seq.getDatasetSequence(), dsPos);
+        List<char[]> codons = mapping
+                .getMappedCodons(seq.getDatasetSequence(), dsPos);
         if (codons != null)
         {
           result.addAll(codons);
@@ -775,7 +776,7 @@ public final class MappingUtils
           SequenceI sequence, List<AlignedCodonFrame> mappings,
           List<SequenceI> filterList)
   {
-    List<AlignedCodonFrame> result = new ArrayList<AlignedCodonFrame>();
+    List<AlignedCodonFrame> result = new ArrayList<>();
     if (sequence == null || mappings == null)
     {
       return result;
@@ -791,8 +792,9 @@ public final class MappingUtils
             SequenceI otherDataset = otherseq.getDatasetSequence();
             if (otherseq == sequence
                     || otherseq == sequence.getDatasetSequence()
-                    || (otherDataset != null && (otherDataset == sequence || otherDataset == sequence
-                            .getDatasetSequence())))
+                    || (otherDataset != null && (otherDataset == sequence
+                            || otherDataset == sequence
+                                    .getDatasetSequence())))
             {
               // skip sequences in subset which directly relate to sequence
               continue;
@@ -832,8 +834,8 @@ public final class MappingUtils
     {
       if (range.length % 2 != 0)
       {
-        System.err.println("Error unbalance start/end ranges: "
-                + ranges.toString());
+        System.err.println(
+                "Error unbalance start/end ranges: " + ranges.toString());
         return 0;
       }
       for (int i = 0; i < range.length - 1; i += 2)
@@ -937,4 +939,74 @@ public final class MappingUtils
     }
     return copy;
   }
+
+  /**
+   * Removes the specified number of positions from the given ranges. Provided
+   * to allow a stop codon to be stripped from a CDS sequence so that it matches
+   * the peptide translation length.
+   * 
+   * @param positions
+   * @param ranges
+   *          a list of (single) [start, end] ranges
+   * @return
+   */
+  public static void removeEndPositions(int positions,
+          List<int[]> ranges)
+  {
+    int toRemove = positions;
+    Iterator<int[]> it = new ReverseListIterator<>(ranges);
+    while (toRemove > 0)
+    {
+      int[] endRange = it.next();
+      if (endRange.length != 2)
+      {
+        /*
+         * not coded for [start1, end1, start2, end2, ...]
+         */
+        System.err
+                .println("MappingUtils.removeEndPositions doesn't handle multiple  ranges");
+        return;
+      }
+
+      int length = endRange[1] - endRange[0] + 1;
+      if (length <= 0)
+      {
+        /*
+         * not coded for a reverse strand range (end < start)
+         */
+        System.err
+                .println("MappingUtils.removeEndPositions doesn't handle reverse strand");
+        return;
+      }
+      if (length > toRemove)
+      {
+        endRange[1] -= toRemove;
+        toRemove = 0;
+      }
+      else
+      {
+        toRemove -= length;
+        it.remove();
+      }
+    }
+  }
+
+
+  public static <K, V> Map<K, V> putWithDuplicationCheck(Map<K, V> map, K key,
+          V value)
+  {
+    if (!map.containsKey(key))
+    {
+      map.put(key, value);
+    }
+    else
+    {
+      jalview.bin.Cache.log.warn(
+              "Attempt to add duplicate entry detected for map with key: "
+                      + key.toString() + " and value: " + value.toString());
+    }
+  
+    return map;
+    
+  }
 }