JAL-34 - quick hack to see how we can do alignment comparison for splitframes linking...
[jalview.git] / src / jalview / workers / AlignmentComparisonThread.java
diff --git a/src/jalview/workers/AlignmentComparisonThread.java b/src/jalview/workers/AlignmentComparisonThread.java
new file mode 100644 (file)
index 0000000..dfdbb87
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.workers;
+
+import jalview.analysis.AAFrequency;
+import jalview.analysis.Conservation;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
+import jalview.util.MappingUtils;
+
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * A thread to compute the columnwise correspondence between aligned positions
+ * and their positions in a linked alignment
+ * 
+ * @author jprocter
+ *
+ */
+public class AlignmentComparisonThread extends AlignCalcWorker
+{
+
+  public AlignmentComparisonThread(AlignViewportI alignViewport,
+          AlignmentViewPanel alignPanel)
+  {
+    super(alignViewport, alignPanel);
+  }
+
+  Annotation[] correspondence = new Annotation[] {};
+  AlignmentAnnotation comparisonAnnot=null;
+  int alWidth;
+
+  @Override
+  public void run()
+  {
+    try
+    {
+      calcMan.notifyStart(this); // updatingConservation = true;
+
+      while ((calcMan != null) && (!calcMan.notifyWorking(this)))
+      {
+        try
+        {
+          if (ap != null)
+          {
+            // ap.paintAlignment(false);
+          }
+          Thread.sleep(200);
+        } catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+      }
+      if ((alignViewport == null) || (calcMan == null)
+              || (alignViewport.isClosed()))
+      {
+        abortAndDestroy();
+        return;
+      }
+      List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
+
+      AlignmentI alignment = alignViewport.getAlignment();
+      AlignViewportI codingComplement = alignViewport.getCodingComplement();
+      if (alignment == null || (alWidth = alignment.getWidth()) < 0
+              || (codingComplement == null))
+      {
+        calcMan.workerComplete(this);
+        // .updatingConservation = false;
+        // AlignViewport.UPDATING_CONSERVATION = false;
+
+        return;
+      }
+      comparisonAnnot = alignViewport.getAlignment().findOrCreateAnnotation("Comparison", "CORRESPONDENCE", true, null, null);
+      comparisonAnnot.annotations=correspondence;
+      ourAnnot.add(comparisonAnnot);
+      ourAnnots = ourAnnot;
+
+      try
+      {
+        computeColumnCorrespondence(alignViewport, codingComplement);
+      } catch (IndexOutOfBoundsException x)
+      {
+        // probable race condition. just finish and return without any fuss.
+        calcMan.workerComplete(this);
+        return;
+      }
+      updateResultAnnotation(true);
+    } catch (OutOfMemoryError error)
+    {
+      ap.raiseOOMWarning("calculating conservation", error);
+      calcMan.disableWorker(this);
+      // alignViewport.conservation = null;
+      // this.alignViewport.quality = null;
+
+    }
+    calcMan.workerComplete(this);
+
+    if ((alignViewport == null) || (calcMan == null)
+            || (alignViewport.isClosed()))
+    {
+      abortAndDestroy();
+      return;
+    }
+    if (ap != null)
+    {
+      ap.paintAlignment(true, true);
+    }
+
+  }
+
+  private void computeColumnCorrespondence(AlignViewportI alignViewport,
+          AlignViewportI codingComplement)
+  {
+    List<SequenceI> us = alignViewport.getAlignment().getSequences();
+    List<AlignedCodonFrame> ourMappings = alignViewport.getAlignment()
+            .getCodonFrames();
+    List<SequenceI> them = codingComplement.getAlignment().getSequences();
+    List<AlignedCodonFrame> theirMappings = codingComplement.getAlignment()
+            .getCodonFrames();
+    if (us == null || them == null || us.isEmpty() || them.isEmpty())
+    {
+      return;
+    }
+
+    int colEnd = alignViewport.getAlignment().getWidth();
+    Annotation[] colCorrsp = new Annotation[colEnd];
+    for (int col = 0; col < colEnd; col++)
+    {
+      int[] theirWidth = MappingUtils.findMappedColumns(col, ourMappings,
+              us, them, alignViewport.getGapCharacter());
+      colCorrsp[col] = new Annotation(
+              theirWidth != null ? Math.abs(theirWidth[1] - theirWidth[0])
+                      : 0);
+    }
+    correspondence=colCorrsp;
+  }
+
+  private void updateResultAnnotation(boolean b)
+  {
+    if (b || !calcMan.isWorking(this) && correspondence!=null)
+    {
+      comparisonAnnot.annotations = correspondence;
+      comparisonAnnot.validateRangeAndDisplay();
+    }
+  }
+
+  @Override
+  public void updateAnnotation()
+  {
+    updateResultAnnotation(false);
+
+  }
+
+}