Autocalculate consensus
[jalview.git] / src / jalview / datamodel / Alignment.java
index ac8f47a..00d1be8 100755 (executable)
@@ -24,23 +24,24 @@ import jalview.util.*;
 \r
 import java.util.*;\r
 \r
-\r
 /** Data structure to hold and manipulate a multiple sequence alignment\r
  */\r
 public class Alignment implements AlignmentI\r
 {\r
+    protected Alignment dataset;\r
     protected Vector sequences;\r
     protected Vector groups = new Vector();\r
     protected Vector superGroup = new Vector();\r
     protected char gapCharacter = '-';\r
-    protected boolean isNucleotide = true;\r
-\r
+    protected int type = NUCLEOTIDE;\r
+    public static final int PROTEIN = 0;\r
+    public static final int NUCLEOTIDE = 1;\r
 \r
     /** DOCUMENT ME!! */\r
     public AlignmentAnnotation[] annotations;\r
 \r
-    /** DOCUMENT ME!! */\r
-    public boolean featuresAdded = false;\r
+    HiddenSequences hiddenSequences = new HiddenSequences(this);\r
+\r
 \r
     /** Make an alignment from an array of Sequences.\r
      *\r
@@ -48,27 +49,28 @@ public class Alignment implements AlignmentI
      */\r
     public Alignment(SequenceI[] seqs)\r
     {\r
-        int i=0, iSize = seqs.length, j, jSize;\r
-        while(isNucleotide && i<iSize)\r
-        {\r
-            jSize = seqs[i].getLength();\r
-            for(j=0; j<jSize; j++)\r
-            {\r
-              if(!jalview.schemes.ResidueProperties.nucleotideHash.containsKey(seqs[i].getSequence(j, j+1))\r
-              && !jalview.util.Comparison.isGap(seqs[i].getSequence().charAt(j)))\r
-              {\r
-                isNucleotide = false;\r
-                break;\r
-              }\r
-            }\r
-            i++;\r
-        }\r
+        int i=0;\r
+\r
+        if( jalview.util.Comparison.isNucleotide(seqs))\r
+          type = NUCLEOTIDE;\r
+        else\r
+          type = PROTEIN;\r
 \r
         sequences = new Vector();\r
 \r
         for (i = 0; i < seqs.length; i++)\r
         {\r
             sequences.addElement(seqs[i]);\r
+\r
+            if(seqs[i].getDatasetSequence()!=null\r
+            && seqs[i].getDatasetSequence().getAnnotation()!=null)\r
+            {\r
+\r
+              for(int a=0; a<seqs[i].getDatasetSequence().getAnnotation().length; a++)\r
+              {\r
+                       this.addAnnotation(seqs[i].getDatasetSequence().getAnnotation()[a], seqs[i]);\r
+              }\r
+            }\r
         }\r
 \r
         getWidth();\r
@@ -215,13 +217,23 @@ public class Alignment implements AlignmentI
      */\r
     public void trimLeft(int i)\r
     {\r
-        for (int j = 0; j < getHeight(); j++)\r
+        int j, jSize = getHeight();\r
+        for (j = 0; j < jSize; j++)\r
         {\r
             SequenceI s = getSequenceAt(j);\r
             int newstart = s.findPosition(i);\r
 \r
-            s.setStart(newstart);\r
-            s.setSequence(s.getSequence().substring(i));\r
+            if(i>s.getLength())\r
+            {\r
+              sequences.removeElement(s);\r
+              j--;\r
+              jSize--;\r
+            }\r
+            else\r
+            {\r
+              s.setStart(newstart);\r
+              s.setSequence(s.getSequence().substring(i));\r
+            }\r
         }\r
     }\r
 \r
@@ -238,7 +250,8 @@ public class Alignment implements AlignmentI
             int newend = s.findPosition(i);\r
 \r
             s.setEnd(newend);\r
-            s.setSequence(s.getSequence().substring(0, i + 1));\r
+            if(s.getLength()>i)\r
+              s.setSequence(s.getSequence().substring(0, i + 1));\r
         }\r
     }\r
 \r
@@ -379,47 +392,7 @@ public class Alignment implements AlignmentI
         return ret;\r
     }\r
 \r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param sg DOCUMENT ME!\r
-     */\r
-    public void addSuperGroup(SuperGroup sg)\r
-    {\r
-        superGroup.addElement(sg);\r
-    }\r
 \r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param sg DOCUMENT ME!\r
-     */\r
-    public void removeSuperGroup(SuperGroup sg)\r
-    {\r
-        superGroup.removeElement(sg);\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param sg DOCUMENT ME!\r
-     *\r
-     * @return DOCUMENT ME!\r
-     */\r
-    public SuperGroup getSuperGroup(SequenceGroup sg)\r
-    {\r
-        for (int i = 0; i < this.superGroup.size(); i++)\r
-        {\r
-            SuperGroup temp = (SuperGroup) superGroup.elementAt(i);\r
-\r
-            if (temp.sequenceGroups.contains(sg))\r
-            {\r
-                return temp;\r
-            }\r
-        }\r
-\r
-        return null;\r
-    }\r
 \r
     /**    */\r
     public void addGroup(SequenceGroup sg)\r
@@ -464,11 +437,9 @@ public class Alignment implements AlignmentI
 \r
         while (i < sequences.size())\r
         {\r
-            SequenceI s = getSequenceAt(i);\r
-\r
-            if (s.getName().equals(name))\r
+            if (getSequenceAt(i).getName().equals(name))\r
             {\r
-                return s;\r
+                return getSequenceAt(i);\r
             }\r
 \r
             i++;\r
@@ -477,25 +448,6 @@ public class Alignment implements AlignmentI
         return null;\r
     }\r
 \r
-    /**    */\r
-    public SequenceI findbyDisplayId(String name)\r
-    {\r
-        int i = 0;\r
-\r
-        while (i < sequences.size())\r
-        {\r
-            SequenceI s = getSequenceAt(i);\r
-\r
-            if (s.getDisplayId().equals(name))\r
-            {\r
-                return s;\r
-            }\r
-\r
-            i++;\r
-        }\r
-\r
-        return null;\r
-    }\r
 \r
     /**    */\r
     public int findIndex(SequenceI s)\r
@@ -663,6 +615,85 @@ public class Alignment implements AlignmentI
     }\r
 \r
     /**\r
+     *\r
+     * @param aa AlignmentAnnotation\r
+     * @param seqRef The sequence to associate this annotation with\r
+     * @return The adjusted AlignmentAnnotation, with dataset sequence and annotation added\r
+     */\r
+    public AlignmentAnnotation addAnnotation(AlignmentAnnotation aa, SequenceI seqRef)\r
+    {\r
+      if(seqRef!=null)\r
+      {\r
+          //We can only add Annotations to the dataset sequences\r
+           if(seqRef.getDatasetSequence()==null)\r
+           {\r
+                  setDataset(null);\r
+            }\r
+\r
+        AlignmentAnnotation []  old = seqRef.getDatasetSequence().getAnnotation();\r
+\r
+        //First check if this is a new annotation or not. If it is new,\r
+        //we must add the annotation to the dataset\r
+        boolean newAnnotation = true;\r
+        if(seqRef.getDatasetSequence().getAnnotation()!=null)\r
+        {\r
+          for(int a=0; a<old.length; a++)\r
+          {\r
+            if(old[a] == aa)\r
+            {\r
+\r
+              newAnnotation = false;\r
+              break;\r
+            }\r
+          }\r
+        }\r
+\r
+        if(newAnnotation)\r
+         {\r
+           seqRef.getDatasetSequence().addAlignmentAnnotation(aa);\r
+         }\r
+\r
+          AlignmentAnnotation copy = null;\r
+          if (aa.graph > 0)\r
+            copy = new AlignmentAnnotation(\r
+                aa.label, aa.description, aa.annotations, aa.graphMin,\r
+                aa.graphMax, aa.graph\r
+                );\r
+          else\r
+            copy = new AlignmentAnnotation(\r
+                aa.label, aa.description, aa.annotations\r
+                );\r
+\r
+         copy.datasetAnnotation = aa;\r
+\r
+         addAnnotation(copy);\r
+\r
+         copy.sequenceRef = seqRef;\r
+\r
+         return copy;\r
+      }\r
+      else\r
+      {\r
+        addAnnotation(aa);\r
+        return aa;\r
+      }\r
+    }\r
+\r
+    public void adjustSequenceAnnotations()\r
+    {\r
+      if(annotations!=null)\r
+      {\r
+        for (int a = 0; a < annotations.length; a++)\r
+        {\r
+          if (annotations[a].sequenceRef != null)\r
+          {\r
+            annotations[a].adjustForAlignment();\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    /**\r
      * DOCUMENT ME!\r
      *\r
      * @param aa DOCUMENT ME!\r
@@ -670,24 +701,48 @@ public class Alignment implements AlignmentI
     public void addAnnotation(AlignmentAnnotation aa)\r
     {\r
         int aSize = 1;\r
-\r
         if (annotations != null)\r
         {\r
             aSize = annotations.length + 1;\r
         }\r
 \r
         AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];\r
+\r
+        temp[aSize-1] = aa;\r
+\r
         int i = 0;\r
 \r
         if (aSize > 1)\r
         {\r
-            for (i = 0; i < (aSize - 1); i++)\r
+            for (i = 0; i < (aSize-1); i++)\r
             {\r
                 temp[i] = annotations[i];\r
             }\r
         }\r
 \r
-        temp[i] = aa;\r
+        annotations = temp;\r
+    }\r
+\r
+    public void setAnnotationIndex(AlignmentAnnotation aa, int index)\r
+    {\r
+      if(aa==null || annotations==null || annotations.length-1<index)\r
+        return;\r
+\r
+      int aSize = annotations.length;\r
+      AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];\r
+\r
+      temp[index] = aa;\r
+\r
+      for (int i = 0; i < aSize; i++)\r
+      {\r
+        if(i==index)\r
+          continue;\r
+\r
+        if(i<index)\r
+          temp[i] = annotations[i];\r
+        else\r
+          temp[i] = annotations[i-1];\r
+      }\r
 \r
         annotations = temp;\r
     }\r
@@ -704,11 +759,76 @@ public class Alignment implements AlignmentI
 \r
     public void setNucleotide(boolean b)\r
     {\r
-      isNucleotide = b;\r
+      if(b)\r
+        type = NUCLEOTIDE;\r
+      else\r
+        type = PROTEIN;\r
     }\r
 \r
     public boolean isNucleotide()\r
     {\r
-      return isNucleotide;\r
+      if(type==NUCLEOTIDE)\r
+        return true;\r
+      else\r
+        return false;\r
     }\r
+\r
+    public void setDataset(Alignment data)\r
+    {\r
+      if(dataset==null && data==null)\r
+      {\r
+        // Create a new dataset for this alignment.\r
+        // Can only be done once, if dataset is not null\r
+        // This will not be performed\r
+        Sequence[] seqs = new Sequence[getHeight()];\r
+        for (int i = 0; i < getHeight(); i++)\r
+        {\r
+\r
+          seqs[i] = new Sequence(getSequenceAt(i).getName(),\r
+                                 AlignSeq.extractGaps(\r
+                                     jalview.util.Comparison.GapChars,\r
+                                     getSequenceAt(i).getSequence()\r
+                                 ),\r
+                                 getSequenceAt(i).getStart(),\r
+                                 getSequenceAt(i).getEnd());\r
+\r
+          getSequenceAt(i).setDatasetSequence(seqs[i]);\r
+        }\r
+\r
+        dataset = new Alignment(seqs);\r
+      }\r
+      else if(dataset==null && data!=null)\r
+      {\r
+        dataset = data;\r
+      }\r
+    }\r
+\r
+    public Alignment getDataset()\r
+    {\r
+      return dataset;\r
+    }\r
+\r
+    public boolean padGaps() {\r
+      boolean modified=false;\r
+      int Width = getWidth();\r
+      SequenceI current;\r
+      for (int i = 0; i < sequences.size();\r
+           i++)\r
+      {\r
+        current = getSequenceAt(i);\r
+\r
+        if (current.getLength() < Width)\r
+        {\r
+          current.insertCharAt(Width - 1, gapCharacter);\r
+          modified=true;\r
+        }\r
+      }\r
+      return modified;\r
+    }\r
+\r
+    public HiddenSequences getHiddenSequences()\r
+    {\r
+      return hiddenSequences;\r
+    }\r
+\r
 }\r