JAL-4313 Test and patch annots trimming
[jalview.git] / src / jalview / datamodel / AlignmentAnnotation.java
index 3e532df..e832c2f 100755 (executable)
  */
 package jalview.datamodel;
 
-import jalview.analysis.Rna;
-import jalview.analysis.SecStrConsensus.SimpleBP;
-import jalview.analysis.WUSSParseException;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -31,9 +27,14 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import jalview.analysis.Rna;
+import jalview.analysis.SecStrConsensus.SimpleBP;
+import jalview.analysis.WUSSParseException;
+
 /**
  * DOCUMENT ME!
  * 
@@ -185,7 +186,8 @@ public class AlignmentAnnotation
     return rnaSecondaryStructureEquivalent(that, true);
   }
 
-  public boolean rnaSecondaryStructureEquivalent(AlignmentAnnotation that, boolean compareType)
+  public boolean rnaSecondaryStructureEquivalent(AlignmentAnnotation that,
+          boolean compareType)
   {
     SequenceFeature[] thisSfArray = this.getRnaSecondaryStructure();
     SequenceFeature[] thatSfArray = that.getRnaSecondaryStructure();
@@ -198,21 +200,28 @@ public class AlignmentAnnotation
       return false;
     }
     Arrays.sort(thisSfArray, new SFSortByEnd()); // probably already sorted
-                                                   // like this
+                                                 // like this
     Arrays.sort(thatSfArray, new SFSortByEnd()); // probably already sorted
-                                                   // like this
-    for (int i=0; i < thisSfArray.length; i++) {
+                                                 // like this
+    for (int i = 0; i < thisSfArray.length; i++)
+    {
       SequenceFeature thisSf = thisSfArray[i];
       SequenceFeature thatSf = thatSfArray[i];
-      if (compareType) {
-        if (thisSf.getType() == null || thatSf.getType() == null) {
-          if (thisSf.getType() == null && thatSf.getType() == null) {
+      if (compareType)
+      {
+        if (thisSf.getType() == null || thatSf.getType() == null)
+        {
+          if (thisSf.getType() == null && thatSf.getType() == null)
+          {
             continue;
-          } else {
+          }
+          else
+          {
             return false;
           }
         }
-        if (! thisSf.getType().equals(thatSf.getType())) {
+        if (!thisSf.getType().equals(thatSf.getType()))
+        {
           return false;
         }
       }
@@ -376,21 +385,24 @@ public class AlignmentAnnotation
         // annotations[i].secondaryStructure + "'");
         // TODO: 2.8.2 should this ss symbol validation check be a function in
         // RNA/ResidueProperties ?
+        // allow for DSSP extended code:
+        // https://www.wikidoc.org/index.php/Secondary_structure#The_DSSP_code
+        // GHITEBS as well as C and X (for missing?)
         if (annotations[i].secondaryStructure == '('
                 || annotations[i].secondaryStructure == '['
                 || annotations[i].secondaryStructure == '<'
                 || annotations[i].secondaryStructure == '{'
                 || annotations[i].secondaryStructure == 'A'
-                || annotations[i].secondaryStructure == 'B'
-                || annotations[i].secondaryStructure == 'C'
+                // || annotations[i].secondaryStructure == 'B'
+                // || annotations[i].secondaryStructure == 'C'
                 || annotations[i].secondaryStructure == 'D'
                 // || annotations[i].secondaryStructure == 'E' // ambiguous on
                 // its own -- already checked above
                 || annotations[i].secondaryStructure == 'F'
-                || annotations[i].secondaryStructure == 'G'
+                // || annotations[i].secondaryStructure == 'G'
                 // || annotations[i].secondaryStructure == 'H' // ambiguous on
                 // its own -- already checked above
-                || annotations[i].secondaryStructure == 'I'
+                // || annotations[i].secondaryStructure == 'I'
                 || annotations[i].secondaryStructure == 'J'
                 || annotations[i].secondaryStructure == 'K'
                 || annotations[i].secondaryStructure == 'L'
@@ -400,12 +412,12 @@ public class AlignmentAnnotation
                 || annotations[i].secondaryStructure == 'P'
                 || annotations[i].secondaryStructure == 'Q'
                 || annotations[i].secondaryStructure == 'R'
-                || annotations[i].secondaryStructure == 'S'
-                || annotations[i].secondaryStructure == 'T'
+                // || annotations[i].secondaryStructure == 'S'
+                // || annotations[i].secondaryStructure == 'T'
                 || annotations[i].secondaryStructure == 'U'
                 || annotations[i].secondaryStructure == 'V'
                 || annotations[i].secondaryStructure == 'W'
-                || annotations[i].secondaryStructure == 'X'
+                // || annotations[i].secondaryStructure == 'X'
                 || annotations[i].secondaryStructure == 'Y'
                 || annotations[i].secondaryStructure == 'Z')
         {
@@ -541,12 +553,12 @@ public class AlignmentAnnotation
                       : annotations[index + offset].displayCharacter == null
                               || annotations[index
                                       + offset].displayCharacter
-                                              .length() == 0
-                                                      ? annotations[index
-                                                              + offset].secondaryStructure
-                                                      : annotations[index
-                                                              + offset].displayCharacter
-                                                                      .charAt(0));
+                                      .length() == 0
+                                              ? annotations[index
+                                                      + offset].secondaryStructure
+                                              : annotations[index
+                                                      + offset].displayCharacter
+                                                      .charAt(0));
     }
 
     @Override
@@ -710,6 +722,17 @@ public class AlignmentAnnotation
   public AlignmentAnnotation(AlignmentAnnotation annotation)
   {
     setAnnotationId();
+    updateAlignmentAnnotationFrom(annotation);
+  }
+
+  /**
+   * copy attributes and annotation from an existing annotation (used by copy
+   * constructor). This method does not update the unique annotationId
+   * 
+   * @param annotation
+   */
+  public void updateAlignmentAnnotationFrom(AlignmentAnnotation annotation)
+  {
     this.label = new String(annotation.label);
     if (annotation.description != null)
     {
@@ -831,15 +854,15 @@ public class AlignmentAnnotation
     }
     if (startRes >= annotations.length)
     {
-      startRes = annotations.length - 1;
+      startRes = annotations.length;
     }
-    if (endRes >= annotations.length)
+    if (endRes < 0)
     {
-      endRes = annotations.length - 1;
+      endRes = -1;
     }
-    if (annotations == null)
+    if (endRes >= annotations.length)
     {
-      return;
+      endRes = annotations.length - 1;
     }
     Annotation[] temp = new Annotation[endRes - startRes + 1];
     if (startRes < annotations.length)
@@ -1234,7 +1257,7 @@ public class AlignmentAnnotation
   {
     if (seqname && this.sequenceRef != null)
     {
-      int i = description.toLowerCase().indexOf("<html>");
+      int i = description.toLowerCase(Locale.ROOT).indexOf("<html>");
       if (i > -1)
       {
         // move the html tag to before the sequence reference.
@@ -1558,7 +1581,7 @@ public class AlignmentAnnotation
   {
     if (annotations != null)
     {
-      makeVisibleAnnotation(0, annotations.length, hiddenColumns);
+      makeVisibleAnnotation(0, annotations.length - 1, hiddenColumns);
     }
   }
 
@@ -1741,4 +1764,22 @@ public class AlignmentAnnotation
     this.eValue = eValue;
   }
 
+  public static AlignmentAnnotation findFirstAnnotation(
+          Iterable<AlignmentAnnotation> alignmentAnnotation, String name,
+          String calcId, boolean autoCalc, SequenceI seqRef,
+          SequenceGroup groupRef)
+  {
+
+    for (AlignmentAnnotation annot : alignmentAnnotation)
+    {
+      if (annot.autoCalculated == autoCalc && (name.equals(annot.label))
+              && (calcId == null || annot.getCalcId().equals(calcId))
+              && annot.sequenceRef == seqRef && annot.groupRef == groupRef)
+      {
+        return annot;
+      }
+    }
+    return null;
+  }
+
 }