JAL-3748 preserve sequence IDs from original alignment view when alignment returned...
[jalview.git] / src / jalview / datamodel / SeqCigar.java
index 09b2e89..c282d6e 100644 (file)
  */
 package jalview.datamodel;
 
-import java.util.Enumeration;
-import java.util.Hashtable;
-
 import jalview.analysis.AlignSeq;
 import jalview.analysis.SeqsetUtils;
 import jalview.util.MessageManager;
 import jalview.util.ShiftList;
 
+import java.util.Enumeration;
+import java.util.Hashtable;
+
 public class SeqCigar extends CigarSimple
 {
   /**
@@ -68,14 +68,54 @@ public class SeqCigar extends CigarSimple
   }
 
   /**
+   * 
+   * @param column
+   * @return position in sequence for column (or -1 if no match state exists)
+   */
+  public int findPosition(int column)
+  {
+    int w = 0, ew, p = refseq.findPosition(start);
+    if (column < 0)
+    {
+      return -1;
+    }
+    if (range != null)
+    {
+      for (int i = 0; i < length; i++)
+      {
+        if (operation[i] == M || operation[i] == D)
+        {
+          p += range[i];
+        }
+        if (operation[i] == M || operation[i] == I)
+        {
+          ew = w + range[i];
+          if (column < ew)
+          {
+            if (operation[i] == I)
+            {
+              return -1;
+            }
+            return p - (ew - column);
+          }
+          w = ew;
+        }
+      }
+    }
+    return -1;
+  }
+
+  /**
    * Returns sequence as a string with cigar operations applied to it
    * 
    * @return String
    */
+  @Override
   public String getSequenceString(char GapChar)
   {
-    return (length == 0) ? "" : (String) getSequenceAndDeletions(
-            refseq.getSequenceAsString(start, end), GapChar)[0];
+    return (length == 0) ? ""
+            : (String) getSequenceAndDeletions(
+                    refseq.getSequenceAsString(start, end), GapChar)[0];
   }
 
   /**
@@ -95,12 +135,13 @@ public class SeqCigar extends CigarSimple
             refseq.getSequenceAsString(start, end), GapChar);
     if (edit_result == null)
     {
-      throw new Error(MessageManager.getString("error.implementation_error_unexpected_null_from_get_sequence_and_deletions"));
+      throw new Error(MessageManager.getString(
+              "error.implementation_error_unexpected_null_from_get_sequence_and_deletions"));
     }
     int bounds[] = (int[]) edit_result[1];
     seq = new Sequence(refseq.getName(), (String) edit_result[0],
-            refseq.getStart() + start + bounds[0], refseq.getStart()
-                    + start + ((bounds[2] == 0) ? -1 : bounds[2]));
+            refseq.getStart() + start + bounds[0], refseq.getStart() + start
+                    + ((bounds[2] == 0) ? -1 : bounds[2]));
     seq.setDescription(refseq.getDescription());
     int sstart = seq.getStart(), send = seq.getEnd();
     // seq.checkValidRange(); probably not needed
@@ -143,11 +184,14 @@ public class SeqCigar extends CigarSimple
     boolean hasgaps = false;
     if (seq == null)
     {
-      throw new Error(MessageManager.getString("error.implementation_error_set_seq_null"));
+      throw new Error(MessageManager
+              .getString("error.implementation_error_set_seq_null"));
     }
     if (_s < 0)
     {
-      throw new Error(MessageManager.formatMessage("error.implementation_error_s", new String[]{Integer.valueOf(_s).toString()}));
+      throw new Error(MessageManager
+              .formatMessage("error.implementation_error_s", new String[]
+              { Integer.valueOf(_s).toString() }));
     }
     String seq_string = seq.getSequenceAsString();
     if (_e == 0 || _e < _s || _e > seq_string.length())
@@ -213,7 +257,8 @@ public class SeqCigar extends CigarSimple
     // Check offsets
     if (end > ds.getLength())
     {
-      throw new Error(MessageManager.getString("error.implementation_error_seqcigar_possible"));
+      throw new Error(MessageManager
+              .getString("error.implementation_error_seqcigar_possible"));
       // end = ds.getLength();
     }
 
@@ -237,11 +282,13 @@ public class SeqCigar extends CigarSimple
     super();
     if (seq == null)
     {
-      throw new Error(MessageManager.getString("error.implmentation_bug_seq_null"));
+      throw new Error(
+              MessageManager.getString("error.implmentation_bug_seq_null"));
     }
     if (operation.length != range.length)
     {
-      throw new Error(MessageManager.getString("error.implementation_bug_cigar_operation_list_range_list"));
+      throw new Error(MessageManager.getString(
+              "error.implementation_bug_cigar_operation_list_range_list"));
     }
 
     if (operation != null)
@@ -251,14 +298,21 @@ public class SeqCigar extends CigarSimple
 
       if (_setSeq(seq, false, 0, 0))
       {
-        throw new Error(MessageManager.getString("error.not_yet_implemented_cigar_object_from_cigar_string"));
+        throw new Error(MessageManager.getString(
+                "error.not_yet_implemented_cigar_object_from_cigar_string"));
       }
       for (int i = this.length, j = 0; j < operation.length; i++, j++)
       {
         char op = operation[j];
         if (op != M && op != I && op != D)
         {
-          throw new Error(MessageManager.formatMessage("error.implementation_bug_cigar_operation", new String[]{Integer.valueOf(j).toString(),Integer.valueOf(op).toString(),Integer.valueOf(M).toString(),Integer.valueOf(I).toString(),Integer.valueOf(D).toString()}));
+          throw new Error(MessageManager.formatMessage(
+                  "error.implementation_bug_cigar_operation", new String[]
+                  { Integer.valueOf(j).toString(),
+                      Integer.valueOf(op).toString(),
+                      Integer.valueOf(M).toString(),
+                      Integer.valueOf(I).toString(),
+                      Integer.valueOf(D).toString() }));
         }
         this.operation[i] = op;
         this.range[i] = range[j];
@@ -272,7 +326,8 @@ public class SeqCigar extends CigarSimple
       this.length = 0;
       if (_setSeq(seq, false, 0, 0))
       {
-        throw new Error(MessageManager.getString("error.not_yet_implemented_cigar_object_from_cigar_string"));
+        throw new Error(MessageManager.getString(
+                "error.not_yet_implemented_cigar_object_from_cigar_string"));
       }
     }
   }
@@ -318,8 +373,9 @@ public class SeqCigar extends CigarSimple
 
     while (p <= endpos)
     {
-      boolean isGap = (p < res) ? jalview.util.Comparison.isGap(seq
-              .getCharAt(p)) : true;
+      boolean isGap = (p < res)
+              ? jalview.util.Comparison.isGap(seq.getCharAt(p))
+              : true;
       if ((startpos <= p) && (p <= endpos))
       {
         if (isGap)
@@ -379,7 +435,8 @@ public class SeqCigar extends CigarSimple
     super();
     if (seq == null)
     {
-      throw new Error(MessageManager.getString("error.implementation_error_for_new_cigar"));
+      throw new Error(MessageManager
+              .getString("error.implementation_error_for_new_cigar"));
     }
     _setSeq(seq, false, 0, 0);
     // there is still work to do
@@ -401,7 +458,8 @@ public class SeqCigar extends CigarSimple
     super();
     if (seq == null)
     {
-      throw new Error(MessageManager.getString("error.implementation_error_for_new_cigar"));
+      throw new Error(MessageManager
+              .getString("error.implementation_error_for_new_cigar"));
     }
     _setSeq(seq, false, start, end + 1);
     // there is still work to do
@@ -430,18 +488,18 @@ public class SeqCigar extends CigarSimple
   /**
    * create an alignment from the given array of cigar sequences and gap
    * character, and marking the given segments as visible in the given
-   * columselection.
+   * hiddenColumns.
    * 
    * @param alseqs
    * @param gapCharacter
-   * @param colsel
-   *          - columnSelection where hidden regions are marked
+   * @param hidden
+   *          - hiddenColumns where hidden regions are marked
    * @param segments
    *          - visible regions of alignment
    * @return SequenceI[]
    */
   public static SequenceI[] createAlignmentSequences(SeqCigar[] alseqs,
-          char gapCharacter, ColumnSelection colsel, int[] segments)
+          char gapCharacter, HiddenColumns hidden, int[] segments)
   {
     SequenceI[] seqs = new SequenceI[alseqs.length];
     StringBuffer[] g_seqs = new StringBuffer[alseqs.length];
@@ -449,14 +507,17 @@ public class SeqCigar extends CigarSimple
     Object[] gs_regions = new Object[alseqs.length];
     for (int i = 0; i < alseqs.length; i++)
     {
-      alseqs_string[i] = alseqs[i].getRefSeq().getSequenceAsString(
-              alseqs[i].start, alseqs[i].end);
+      alseqs_string[i] = alseqs[i].getRefSeq()
+              .getSequenceAsString(alseqs[i].start, alseqs[i].end);
       gs_regions[i] = alseqs[i].getSequenceAndDeletions(alseqs_string[i],
               gapCharacter); // gapped sequence, {start, start col, end.
       // endcol}, hidden regions {{start, end, col}})
       if (gs_regions[i] == null)
       {
-        throw new Error(MessageManager.formatMessage("error.implementation_error_cigar_seq_no_operations", new String[]{Integer.valueOf(i).toString()}));
+        throw new Error(MessageManager.formatMessage(
+                "error.implementation_error_cigar_seq_no_operations",
+                new String[]
+                { Integer.valueOf(i).toString() }));
       }
       g_seqs[i] = new StringBuffer((String) ((Object[]) gs_regions[i])[0]); // the
       // visible
@@ -511,7 +572,7 @@ public class SeqCigar extends CigarSimple
           if (segments == null)
           {
             // add a hidden column for this deletion
-            colsel.hideColumns(inspos, inspos + insert.length - 1);
+            hidden.hideColumns(inspos, inspos + insert.length - 1);
           }
         }
       }
@@ -521,10 +582,12 @@ public class SeqCigar extends CigarSimple
       int[] bounds = ((int[]) ((Object[]) gs_regions[i])[1]);
       SequenceI ref = alseqs[i].getRefSeq();
       seqs[i] = new Sequence(ref.getName(), g_seqs[i].toString(),
-              ref.getStart() + alseqs[i].start + bounds[0], ref.getStart()
-                      + alseqs[i].start + (bounds[2] == 0 ? -1 : bounds[2]));
+              ref.getStart() + alseqs[i].start + bounds[0],
+              ref.getStart() + alseqs[i].start
+                      + (bounds[2] == 0 ? -1 : bounds[2]));
       seqs[i].setDatasetSequence(ref);
       seqs[i].setDescription(ref.getDescription());
+      SeqsetUtils.SeqCharacterUnhash(seqs[i],alseqs[i].seqProps);
     }
     if (segments != null)
     {
@@ -532,8 +595,8 @@ public class SeqCigar extends CigarSimple
       {
         // int start=shifts.shift(segments[i]-1)+1;
         // int end=shifts.shift(segments[i]+segments[i+1]-1)-1;
-        colsel.hideColumns(segments[i + 1], segments[i + 1]
-                + segments[i + 2] - 1);
+        hidden.hideColumns(segments[i + 1],
+                segments[i + 1] + segments[i + 2] - 1);
       }
     }
     return seqs;