JAL-34 - quick hack to see how we can do alignment comparison for splitframes linking...
authorJames Procter <j.procter@dundee.ac.uk>
Wed, 17 Jan 2024 18:14:37 +0000 (18:14 +0000)
committerJames Procter <j.procter@dundee.ac.uk>
Wed, 17 Jan 2024 18:14:37 +0000 (18:14 +0000)
src/jalview/gui/AlignViewport.java
src/jalview/gui/SplitFrame.java
src/jalview/util/MappingUtils.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/workers/AlignmentComparisonThread.java [new file with mode: 0644]

index 91dded1..a264100 100644 (file)
@@ -964,6 +964,8 @@ public class AlignViewport extends AlignmentViewport
      */
     JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame);
     Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
+    cdnaFrame.viewport.updateConsensus(cdnaFrame.alignPanel);
+    proteinFrame.viewport.updateConsensus(proteinFrame.alignPanel);
 
     return proteinFrame.viewport.getAlignment();
   }
index 73744b3..37cb8d3 100644 (file)
@@ -138,6 +138,10 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     addKeyBindings();
 
     addCommandListeners();
+    
+    // ensure all workers are added 
+    ((AlignFrame) getTopFrame()).getViewport().updateConsensus(((AlignFrame) getTopFrame()).alignPanel);
+    ((AlignFrame) getBottomFrame()).getViewport().updateConsensus(((AlignFrame) getBottomFrame()).alignPanel);
   }
 
   /**
index 25cb810..8fd39ad 100644 (file)
@@ -635,7 +635,7 @@ public final class MappingUtils
    * @param fromGapChar
    * @return
    */
-  protected static int[] findMappedColumns(int col,
+  public static int[] findMappedColumns(int col,
           List<AlignedCodonFrame> mappings, List<SequenceI> fromSequences,
           List<SequenceI> toSequences, char fromGapChar)
   {
index 0150e62..3ab2fce 100644 (file)
@@ -74,6 +74,7 @@ import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
 import jalview.viewmodel.styles.ViewStyle;
 import jalview.workers.AlignCalcManager;
+import jalview.workers.AlignmentComparisonThread;
 import jalview.workers.ComplementConsensusThread;
 import jalview.workers.ConsensusThread;
 import jalview.workers.StrucConsensusThread;
@@ -895,6 +896,18 @@ public abstract class AlignmentViewport
         }
       }
     }
+    if (getCodingComplement() != null)
+    {
+      if (getCodingComplement().isNucleotide() == isNucleotide())
+      {
+        if (calculator.getRegisteredWorkersOfClass(
+                AlignmentComparisonThread.class) == null)
+        {
+          calculator
+                  .registerWorker(new AlignmentComparisonThread(this, ap));
+        }
+      }
+    }
   }
 
   // --------START Structure Conservation
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);
+
+  }
+
+}