JAL-2629 add documentation to previous work
[jalview.git] / src / jalview / datamodel / Alignment.java
index a6f2bf4..abbd8e3 100755 (executable)
@@ -62,6 +62,8 @@ public class Alignment implements AlignmentI
 
   HiddenSequences hiddenSequences;
 
+  HiddenColumns hiddenCols;
+
   public Hashtable alignmentProperties;
 
   private List<AlignedCodonFrame> codonFrameList;
@@ -70,7 +72,8 @@ public class Alignment implements AlignmentI
   {
     groups = Collections.synchronizedList(new ArrayList<SequenceGroup>());
     hiddenSequences = new HiddenSequences(this);
-    codonFrameList = new ArrayList<AlignedCodonFrame>();
+    hiddenCols = new HiddenColumns();
+    codonFrameList = new ArrayList<>();
 
     nucleotide = Comparison.isNucleotide(seqs);
 
@@ -125,7 +128,7 @@ public class Alignment implements AlignmentI
   public Alignment(SeqCigar[] alseqs)
   {
     SequenceI[] seqs = SeqCigar.createAlignmentSequences(alseqs,
-            gapCharacter, new ColumnSelection(), null);
+            gapCharacter, new HiddenColumns(), null);
     initAlignment(seqs);
   }
 
@@ -185,14 +188,7 @@ public class Alignment implements AlignmentI
     return AlignmentUtils.getSequencesByName(this);
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param i
-   *          DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
+
   @Override
   public SequenceI getSequenceAt(int i)
   {
@@ -206,6 +202,28 @@ public class Alignment implements AlignmentI
     return null;
   }
 
+  @Override
+  public SequenceI getSequenceAtAbsoluteIndex(int i)
+  {
+    SequenceI seq = null;
+    if (getHiddenSequences().getSize() > 0)
+    {
+      seq = getHiddenSequences().getHiddenSequence(i);
+      if (seq == null)
+      {
+        // didn't find the sequence in the hidden sequences, get it from the
+        // alignment
+        int index = getHiddenSequences().findIndexWithoutHiddenSeqs(i);
+        seq = getSequenceAt(index);
+      }
+    }
+    else
+    {
+      seq = getSequenceAt(i);
+    }
+    return seq;
+  }
+
   /**
    * Adds a sequence to the alignment. Recalculates maxLength and size. Note
    * this currently does not recalculate whether or not the alignment is
@@ -271,6 +289,32 @@ public class Alignment implements AlignmentI
   }
 
   /**
+   * Inserts a sequence at a point in the alignment.
+   * 
+   * @param i
+   *          the index of the position the sequence is to be inserted in.
+   */
+  @Override
+  public void insertSequenceAt(int i, SequenceI snew)
+  {
+    synchronized (sequences)
+    {
+      if (sequences.size() > i)
+      {
+        sequences.add(i, snew);
+        return;
+
+      }
+      else
+      {
+        sequences.add(snew);
+        hiddenSequences.adjustHeightSequenceAdded();
+      }
+      return;
+    }
+  }
+
+  /**
    * DOCUMENT ME!
    * 
    * @return DOCUMENT ME!
@@ -320,30 +364,21 @@ public class Alignment implements AlignmentI
     }
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param s
-   *          DOCUMENT ME!
-   */
   @Override
   public void deleteSequence(SequenceI s)
   {
-    deleteSequence(findIndex(s));
+    synchronized (sequences)
+    {
+      deleteSequence(findIndex(s));
+    }
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param i
-   *          DOCUMENT ME!
-   */
   @Override
   public void deleteSequence(int i)
   {
-    if (i > -1 && i < getHeight())
+    synchronized (sequences)
     {
-      synchronized (sequences)
+      if (i > -1 && i < getHeight())
       {
         sequences.remove(i);
         hiddenSequences.adjustHeightSequenceDeleted(i);
@@ -351,6 +386,18 @@ public class Alignment implements AlignmentI
     }
   }
 
+  @Override
+  public void deleteHiddenSequence(int i)
+  {
+    synchronized (sequences)
+    {
+      if (i > -1 && i < getHeight())
+      {
+        sequences.remove(i);
+      }
+    }
+  }
+
   /*
    * (non-Javadoc)
    * 
@@ -384,7 +431,7 @@ public class Alignment implements AlignmentI
   @Override
   public SequenceGroup[] findAllGroups(SequenceI s)
   {
-    ArrayList<SequenceGroup> temp = new ArrayList<SequenceGroup>();
+    ArrayList<SequenceGroup> temp = new ArrayList<>();
 
     synchronized (groups)
     {
@@ -435,7 +482,7 @@ public class Alignment implements AlignmentI
             return;
           }
         }
-        sg.setContext(this);
+        sg.setContext(this, true);
         groups.add(sg);
       }
     }
@@ -512,7 +559,7 @@ public class Alignment implements AlignmentI
       }
       for (SequenceGroup sg : groups)
       {
-        sg.setContext(null);
+        sg.setContext(null, false);
       }
       groups.clear();
     }
@@ -528,7 +575,7 @@ public class Alignment implements AlignmentI
       {
         removeAnnotationForGroup(g);
         groups.remove(g);
-        g.setContext(null);
+        g.setContext(null, false);
       }
     }
   }
@@ -668,22 +715,19 @@ public class Alignment implements AlignmentI
     return -1;
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
+
   @Override
   public int getHeight()
   {
     return sequences.size();
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
+  @Override
+  public int getAbsoluteHeight()
+  {
+    return sequences.size() + getHiddenSequences().getSize();
+  }
+
   @Override
   public int getWidth()
   {
@@ -769,6 +813,12 @@ public class Alignment implements AlignmentI
     return true;
   }
 
+  @Override
+  public boolean isHidden(int alignmentIndex)
+  {
+    return (getHiddenSequences().getHiddenSequence(alignmentIndex) != null);
+  }
+
   /**
    * Delete all annotations, including auto-calculated if the flag is set true.
    * Returns true if at least one annotation was deleted, else false.
@@ -990,6 +1040,10 @@ public class Alignment implements AlignmentI
     }
     else if (dataset == null && data != null)
     {
+      if (data == this)
+      {
+        throw new IllegalArgumentException("Circular dataset reference");
+      }
       if (!(data instanceof Alignment))
       {
         throw new Error(
@@ -1043,7 +1097,7 @@ public class Alignment implements AlignmentI
     {
       return;
     }
-    List<SequenceI> toProcess = new ArrayList<SequenceI>();
+    List<SequenceI> toProcess = new ArrayList<>();
     toProcess.add(currentSeq);
     while (toProcess.size() > 0)
     {
@@ -1096,7 +1150,7 @@ public class Alignment implements AlignmentI
       return;
     }
     // try to avoid using SequenceI.equals at this stage, it will be expensive
-    Set<SequenceI> seqs = new LinkedIdentityHashSet<SequenceI>();
+    Set<SequenceI> seqs = new LinkedIdentityHashSet<>();
 
     for (int i = 0; i < getHeight(); i++)
     {
@@ -1302,6 +1356,12 @@ public class Alignment implements AlignmentI
   }
 
   @Override
+  public HiddenColumns getHiddenColumns()
+  {
+    return hiddenCols;
+  }
+
+  @Override
   public CigarArray getCompactAlignment()
   {
     synchronized (sequences)
@@ -1375,7 +1435,7 @@ public class Alignment implements AlignmentI
     {
       return null;
     }
-    List<AlignedCodonFrame> cframes = new ArrayList<AlignedCodonFrame>();
+    List<AlignedCodonFrame> cframes = new ArrayList<>();
     for (AlignedCodonFrame acf : getCodonFrames())
     {
       if (acf.involvesSequence(seq))
@@ -1452,7 +1512,7 @@ public class Alignment implements AlignmentI
     if (sqs != null)
     {
       // avoid self append deadlock by
-      List<SequenceI> toappendsq = new ArrayList<SequenceI>();
+      List<SequenceI> toappendsq = new ArrayList<>();
       synchronized (sqs)
       {
         for (SequenceI addedsq : sqs)
@@ -1593,7 +1653,7 @@ public class Alignment implements AlignmentI
   @Override
   public Iterable<AlignmentAnnotation> findAnnotation(String calcId)
   {
-    List<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
+    List<AlignmentAnnotation> aa = new ArrayList<>();
     AlignmentAnnotation[] alignmentAnnotation = getAlignmentAnnotation();
     if (alignmentAnnotation != null)
     {
@@ -1610,20 +1670,18 @@ public class Alignment implements AlignmentI
     return aa;
   }
 
-  /**
-   * Returns an iterable collection of any annotations that match on given
-   * sequence ref, calcId and label (ignoring null values).
-   */
   @Override
   public Iterable<AlignmentAnnotation> findAnnotations(SequenceI seq,
           String calcId, String label)
   {
-    ArrayList<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
+    ArrayList<AlignmentAnnotation> aa = new ArrayList<>();
     for (AlignmentAnnotation ann : getAlignmentAnnotation())
     {
-      if (ann.getCalcId() != null && ann.getCalcId().equals(calcId)
-              && ann.sequenceRef != null && ann.sequenceRef == seq
-              && ann.label != null && ann.label.equals(label))
+      if ((calcId == null || (ann.getCalcId() != null && ann.getCalcId()
+              .equals(calcId)))
+              && (seq == null || (ann.sequenceRef != null && ann.sequenceRef == seq))
+              && (label == null || (ann.label != null && ann.label
+                      .equals(label))))
       {
         aa.add(ann);
       }
@@ -1821,7 +1879,7 @@ public class Alignment implements AlignmentI
   @Override
   public Set<String> getSequenceNames()
   {
-    Set<String> names = new HashSet<String>();
+    Set<String> names = new HashSet<>();
     for (SequenceI seq : getSequences())
     {
       names.add(seq.getName());
@@ -1921,4 +1979,53 @@ public class Alignment implements AlignmentI
     }
     return new int[] { startPos, endPos };
   }
+
+  @Override
+  public void setHiddenColumns(HiddenColumns cols)
+  {
+    hiddenCols = cols;
+  }
+
+  /**
+   * Returns all HMM consensus sequences. This will not return real sequences
+   * with HMMs. If remove is set to true, the consensus sequences will be
+   * removed from the alignment.
+   */
+  @Override
+  public List<SequenceI> getHMMConsensusSequences(boolean remove)
+  {
+    List<SequenceI> seqs = new ArrayList<>();
+    int position = 0;
+    int seqsRemoved = 0;
+    boolean endReached = false;
+
+    while (!endReached)
+    {
+      SequenceI seq = sequences.get(position);
+      if (seq.isHMMConsensusSequence())
+      {
+        if (remove)
+        {
+          sequences.remove(position);
+          seqsRemoved++;
+          seq.setPreviousPosition(seqsRemoved + position - 1);
+        }
+        else
+        {
+          position++;
+        }
+        seqs.add(seq);
+      }
+      else
+      {
+        position++;
+      }
+
+      if (position >= sequences.size())
+      {
+        endReached = true;
+      }
+    }
+    return seqs;
+  }
 }