Merge branch 'develop' into improvement/JAL-4124_dont_duplacate_PAE_data_acrossviews
[jalview.git] / src / jalview / datamodel / Alignment.java
index 1f0e1c2..375e6b4 100755 (executable)
  */
 package jalview.datamodel;
 
-import jalview.analysis.AlignmentUtils;
-import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
-import jalview.io.FastaFile;
-import jalview.util.Comparison;
-import jalview.util.LinkedIdentityHashSet;
-import jalview.util.MessageManager;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
@@ -41,6 +34,13 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
 
+import jalview.analysis.AlignmentUtils;
+import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
+import jalview.io.FastaFile;
+import jalview.util.Comparison;
+import jalview.util.LinkedIdentityHashSet;
+import jalview.util.MessageManager;
+
 /**
  * Data structure to hold and manipulate a multiple sequence alignment
  */
@@ -196,6 +196,7 @@ public class Alignment implements AlignmentI, AutoCloseable
   {
     synchronized (sequences)
     {
+
       if (i > -1 && i < sequences.size())
       {
         return sequences.get(i);
@@ -595,11 +596,12 @@ public class Alignment implements AlignmentI, AutoCloseable
     int i = 0;
     SequenceI sq = null;
     String sqname = null;
+    int nseq = sequences.size();
     if (startAfter != null)
     {
       // try to find the sequence in the alignment
       boolean matched = false;
-      while (i < sequences.size())
+      while (i < nseq)
       {
         if (getSequenceAt(i++) == startAfter)
         {
@@ -612,7 +614,7 @@ public class Alignment implements AlignmentI, AutoCloseable
         i = 0;
       }
     }
-    while (i < sequences.size())
+    while (i < nseq)
     {
       sq = getSequenceAt(i);
       sqname = sq.getName();
@@ -715,7 +717,7 @@ public class Alignment implements AlignmentI, AutoCloseable
   public int getWidth()
   {
     int maxLength = -1;
-  
+
     for (int i = 0; i < sequences.size(); i++)
     {
       maxLength = Math.max(maxLength, getSequenceAt(i).getLength());
@@ -1194,7 +1196,8 @@ public class Alignment implements AlignmentI, AutoCloseable
     int maxLength = -1;
 
     SequenceI current;
-    for (int i = 0; i < sequences.size(); i++)
+    int nseq = sequences.size();
+    for (int i = 0; i < nseq; i++)
     {
       current = getSequenceAt(i);
       for (int j = current.getLength(); j > maxLength; j--)
@@ -1211,7 +1214,7 @@ public class Alignment implements AlignmentI, AutoCloseable
     maxLength++;
 
     int cLength;
-    for (int i = 0; i < sequences.size(); i++)
+    for (int i = 0; i < nseq; i++)
     {
       current = getSequenceAt(i);
       cLength = current.getLength();
@@ -1650,8 +1653,10 @@ public class Alignment implements AlignmentI, AutoCloseable
   public Iterable<AlignmentAnnotation> findAnnotations(SequenceI seq,
           String calcId, String label)
   {
-    return AlignmentAnnotation.findAnnotations(
-            Arrays.asList(getAlignmentAnnotation()), seq, calcId, label);
+    return annotations == null ? null
+            : AlignmentAnnotation.findAnnotations(
+                    Arrays.asList(getAlignmentAnnotation()), seq, calcId,
+                    label);
   }
 
   @Override
@@ -1912,11 +1917,12 @@ public class Alignment implements AlignmentI, AutoCloseable
   @Override
   public boolean setHiddenColumns(HiddenColumns cols)
   {
-  boolean changed = cols == null ? hiddenCols != null
-          : !cols.equals(hiddenCols);
-  hiddenCols = cols;
-  return changed;
+    boolean changed = cols == null ? hiddenCols != null
+            : !cols.equals(hiddenCols);
+    hiddenCols = cols;
+    return changed;
   }
+
   @Override
   public void setupJPredAlignment()
   {
@@ -2029,37 +2035,90 @@ public class Alignment implements AlignmentI, AutoCloseable
     }
   }
 
-  Map<Object, ContactMatrixI> contactmaps = new HashMap<>();
+  ////
+  //// Contact Matrix Holder Boilerplate
+  ////
+  ContactMapHolder cmholder = new ContactMapHolder();
+
+  @Override
+  public Collection<ContactMatrixI> getContactMaps()
+  {
+    return cmholder.getContactMaps();
+  }
+
   @Override
-  public
-  ContactListI getContactListFor(AlignmentAnnotation _aa, int column)
+  public ContactMatrixI getContactMatrixFor(AlignmentAnnotation _aa)
   {
-    ContactMatrixI cm = contactmaps.get(_aa.annotationId);
-    if (cm == null)
+    ContactMatrixI cm = cmholder.getContactMatrixFor(_aa);
+    if (cm == null && _aa.groupRef != null)
+    {
+      cm = _aa.groupRef.getContactMatrixFor(_aa);
+    }
+    if (cm == null && _aa.sequenceRef != null)
+    {
+      cm = _aa.sequenceRef.getContactMatrixFor(_aa);
+      if (cm == null && _aa.sequenceRef.getDatasetSequence()!=null)
+      {
+        // TODO fix up this logic and unify with getContactListFor
+        cm = _aa.sequenceRef.getDatasetSequence().getContactMatrixFor(_aa);
+      }
+    }
+    return cm;
+  }
+
+  @Override
+  public ContactListI getContactListFor(AlignmentAnnotation _aa, int column)
+  {
+    if (_aa.annotations==null || column>=_aa.annotations.length || column<0)
     {
       return null;
     }
-    return cm.getContactList(column);
+    ContactListI cl = cmholder.getContactListFor(_aa, column);
+    if (cl == null && _aa.groupRef != null)
+    {
+      cl = _aa.groupRef.getContactListFor(_aa, column);
+    }
+    if (cl == null && _aa.sequenceRef != null)
+    {
+      if (_aa.annotations[column] != null)
+      {
+        // sequence associated
+        cl = _aa.sequenceRef.getContactListFor(_aa, column);
+        if (cl == null && _aa.sequenceRef.getDatasetSequence() != null)
+        {
+          int spos = _aa.sequenceRef.findPosition(column);
+          if (spos >= _aa.sequenceRef.getStart()
+                  && spos <= 1 + _aa.sequenceRef.getEnd())
+          {
+            cl = _aa.sequenceRef.getDatasetSequence().getContactListFor(_aa,
+                    spos - _aa.sequenceRef.getStart());
+          }
+        }
+      }
+    }
+    return cl;
   }
 
   @Override
   public AlignmentAnnotation addContactList(ContactMatrixI cm)
   {
+    AlignmentAnnotation aa = cmholder.addContactList(cm);
+
     Annotation _aa[] = new Annotation[getWidth()];
-    Annotation dummy = new Annotation(0.0f);
-    for (int i = 0; i < _aa.length; _aa[i++] = dummy)
+    for (int i = 0; i < _aa.length; _aa[i++] = new Annotation(0.0f))
     {
       ;
     }
-    AlignmentAnnotation aa = new AlignmentAnnotation("Contact Matrix",
-            "Contact Matrix", _aa);
-    aa.graph = AlignmentAnnotation.CUSTOMRENDERER;
-    aa.graphMin = cm.getMin();
-    aa.graphMax = cm.getMax();
-    aa.editable = false;
-    // aa.autoCalculated = true;
-    contactmaps.put(aa.annotationId, cm);
+    aa.annotations = _aa;
     addAnnotation(aa);
     return aa;
   }
+
+  @Override
+  public void addContactListFor(AlignmentAnnotation annotation,
+          ContactMatrixI cm)
+  {
+    cmholder.addContactListFor(annotation, cm);
+
+  }
 }