JAL-3748 store an AlignmentView for the complement within an viewport’s AlignView...
authorJim Procter <jprocter@issues.jalview.org>
Wed, 16 Sep 2020 06:02:04 +0000 (07:02 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Wed, 16 Sep 2020 06:02:04 +0000 (07:02 +0100)
src/jalview/api/AlignViewportI.java
src/jalview/datamodel/AlignmentView.java
src/jalview/viewmodel/AlignmentViewport.java
test/jalview/gui/SplitFrameTest.java [new file with mode: 0644]

index 56d25d5..2a82a32 100644 (file)
@@ -268,6 +268,15 @@ public interface AlignViewportI extends ViewStyleI
   AlignmentView getAlignmentView(boolean selectedOnly, boolean markGroups);
 
   /**
+   * @return an alignment view, optionally without a complement view
+   * @param selectedOnly
+   * @param markGroups
+   * @param withComplement - false if no complement view required
+   */
+  AlignmentView getAlignmentViewWithComplement(boolean selectedOnly,
+          boolean markGroups, boolean withComplement);
+
+  /**
    * This method returns the visible alignment as text, as seen on the GUI, ie
    * if columns are hidden they will not be returned in the result. Use this for
    * calculating trees, PCA, redundancy etc on views which contain hidden
index e6604d1..6d6d4c3 100644 (file)
@@ -51,6 +51,37 @@ public class AlignmentView
   private boolean isNa = false;
 
   /**
+   * reference to the complementary CDS/Protein alignment for this alignment, if available
+   */
+  private AlignmentView complementView=null;
+  
+  /**
+   * setter for 
+   * @param complementView
+   */
+  public void setComplement(AlignmentView complementView)
+  {
+    this.complementView = complementView;
+    
+  }
+  /**
+   * 
+   * @return true if a complement is available
+   */
+  public boolean hasComplementView()
+  {
+    return complementView!=null;
+  }
+  /**
+   * 
+   * @return the complement view or null
+   */
+  public AlignmentView getComplementView()
+  {
+    return complementView;
+  }
+  
+  /**
    * false if the view concerns peptides
    * 
    * @return
index c9a3a80..cbc2189 100644 (file)
@@ -1694,11 +1694,29 @@ public abstract class AlignmentViewport
   public jalview.datamodel.AlignmentView getAlignmentView(
           boolean selectedOnly, boolean markGroups)
   {
-    return new AlignmentView(alignment, alignment.getHiddenColumns(),
-            selectionGroup,
+    return getAlignmentViewWithComplement(selectedOnly,markGroups,true);
+  }
+  
+  @Override
+  public jalview.datamodel.AlignmentView getAlignmentViewWithComplement(
+          boolean selectedOnly, boolean markGroups,boolean withComplment)
+  {
+    AlignmentView complementView = null;
+    if (withComplment)
+    {
+      if (codingComplement != null)
+      {
+        complementView = codingComplement.getAlignmentViewWithComplement(
+                selectedOnly, markGroups, false);
+      }
+    }
+    AlignmentView thisView = new AlignmentView(alignment,
+            alignment.getHiddenColumns(), selectionGroup,
             alignment.getHiddenColumns() != null
                     && alignment.getHiddenColumns().hasHiddenColumns(),
             selectedOnly, markGroups);
+    thisView.setComplement(complementView);
+    return thisView;
   }
 
   @Override
diff --git a/test/jalview/gui/SplitFrameTest.java b/test/jalview/gui/SplitFrameTest.java
new file mode 100644 (file)
index 0000000..f0ea255
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 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.gui;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import jalview.api.FeatureColourI;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.project.Jalview2xmlTests;
+import jalview.renderer.ResidueShaderI;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.JalviewColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class SplitFrameTest
+{
+  AlignFrame dnaAf, proteinAf;
+
+  SplitFrame testSplitFrame;
+
+  @BeforeClass(alwaysRun = true)
+  public static void setUpBeforeClass() throws Exception
+  {
+    setUpJvOptionPane();
+    /*
+     * use read-only test properties file
+     */
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Jalview.main(new String[] { "-nonews" });
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+  }
+
+  /**
+   * configure (read-only) properties for test to ensure Consensus is computed
+   * for colour Above PID testing
+   */
+  @BeforeMethod(alwaysRun = true)
+  public void setUp()
+  {
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+            Boolean.TRUE.toString());
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/testdata/MN908947.jvp", DataSourceType.FILE);
+
+    /*
+     * wait for Consensus thread to complete
+     */
+    synchronized (this)
+    {
+      while (af.getViewport().getConsensusSeq() == null)
+      {
+        try
+        {
+          wait(50);
+        } catch (InterruptedException e)
+        {
+        }
+      }
+    }
+    testSplitFrame = (SplitFrame) af.getSplitViewContainer();
+    proteinAf=af.getViewport().getAlignment().isNucleotide() ? testSplitFrame.getComplementAlignFrame(af) : af;
+    dnaAf=testSplitFrame.getComplementAlignFrame(proteinAf);
+  }
+
+  public static void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups= {"Functional"})
+  public void testAlignAsSplitFrame()
+  {
+
+    /*
+     * If alignment was requested from one half of a SplitFrame, show in a
+     * SplitFrame with the other pane similarly aligned.
+     */
+    AlignFrame requestedBy = proteinAf;
+    AlignmentI wholeProteinAl = proteinAf.getViewport().getAlignment();
+    SequenceI[] sel = wholeProteinAl.getSequencesArray();
+    // Select 3 sequences, from columns 3-7 inclusive
+    SequenceGroup selRegion = new SequenceGroup(
+            Arrays.asList(sel[0], sel[1], sel[3]));
+    selRegion.setStartRes(3);
+    selRegion.setEndRes(7);
+    proteinAf.getViewport().setSelectionGroup(selRegion);
+    proteinAf.getViewport().sendSelection();
+    assertNotNull(dnaAf.getViewport().getSelectionGroup());
+    AlignmentView inputView = proteinAf.gatherSequencesForAlignment();
+    assertEquals(inputView.getSequences().length, 3);
+    assertEquals(inputView.getWidth(), 5);
+    assertNotNull(inputView.getComplementView());
+
+    Object alAndHidden[] = inputView.getAlignmentAndHiddenColumns(
+            proteinAf.getViewport().getGapCharacter());
+    AlignmentI result = new Alignment((SequenceI[]) alAndHidden[0]);
+    result.setHiddenColumns((HiddenColumns) alAndHidden[1]);
+    // check we are referring to the expected alignment
+    assertEquals(
+            requestedBy.getSplitViewContainer().getComplement(requestedBy),
+            dnaAf.getCurrentView().getAlignment());
+    // and that datasets are consistent (if not, there's a problem elsewhere in
+    // splitframe construction
+    AlignmentI complementDs = requestedBy.getSplitViewContainer()
+            .getComplement(requestedBy).getDataset();
+    assertTrue(dnaAf.getViewport().getAlignment().getDataset() == dnaAf
+            .getViewport().getAlignment().getDataset());
+    assertTrue(complementDs == proteinAf.getViewport().getAlignment()
+            .getDataset());
+
+    char gc = requestedBy.getSplitViewContainer().getComplement(requestedBy)
+            .getGapCharacter();
+
+    AlignmentI complement = inputView.getComplementView()
+            .getVisibleAlignment(gc);
+    String complementTitle = requestedBy.getSplitViewContainer()
+            .getComplementTitle(requestedBy);
+    // becomes null if the alignment window was closed before the alignment
+    // job finished.
+    AlignmentI copyComplement = new Alignment(complement);
+    // todo should this be done by copy constructor?
+    copyComplement.setGapCharacter(complement.getGapCharacter());
+    // share the same dataset (and the mappings it holds)
+    copyComplement.setDataset(complementDs);
+    copyComplement.alignAs(result);
+    // check shape is as expected
+    assertEquals(copyComplement.getWidth(), result.getWidth() * 3);
+    assertEquals(copyComplement.getHeight(), result.getHeight());
+  }
+}