From 5c1262f120d4fca072bc8fd9800a1a856cc46843 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Wed, 16 Sep 2020 07:02:04 +0100 Subject: [PATCH] =?utf8?q?JAL-3748=20store=20an=20AlignmentView=20for=20the=20?= =?utf8?q?complement=20within=20an=20viewport=E2=80=99s=20AlignView=20so=20i?= =?utf8?q?t=20can=20be=20recovered=20after=20a=20web=20service=20operation?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/jalview/api/AlignViewportI.java | 9 ++ src/jalview/datamodel/AlignmentView.java | 31 +++++ src/jalview/viewmodel/AlignmentViewport.java | 22 ++- test/jalview/gui/SplitFrameTest.java | 185 ++++++++++++++++++++++++++ 4 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 test/jalview/gui/SplitFrameTest.java diff --git a/src/jalview/api/AlignViewportI.java b/src/jalview/api/AlignViewportI.java index 56d25d5..2a82a32 100644 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@ -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 diff --git a/src/jalview/datamodel/AlignmentView.java b/src/jalview/datamodel/AlignmentView.java index e6604d1..6d6d4c3 100644 --- a/src/jalview/datamodel/AlignmentView.java +++ b/src/jalview/datamodel/AlignmentView.java @@ -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 diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index c9a3a80..cbc2189 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -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 index 0000000..f0ea255 --- /dev/null +++ b/test/jalview/gui/SplitFrameTest.java @@ -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 . + * 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()); + } +} -- 1.7.10.2