From ef887ebe817cd6595b6275f5f51001677c377214 Mon Sep 17 00:00:00 2001 From: kjvdheide Date: Mon, 11 Dec 2017 20:34:15 +0000 Subject: [PATCH] JAL-1953 start on making everything interface based --- forester | 2 +- src/jalview/analysis/AlignmentSorter.java | 28 ++- src/jalview/ext/archaeopteryx/AptxConfig.java | 14 ++ .../ext/archaeopteryx/AptxControlPanel.java | 31 ++++ src/jalview/ext/archaeopteryx/AptxFrame.java | 116 ++++++++++-- src/jalview/ext/archaeopteryx/AptxInit.java | 185 ++++++++------------ src/jalview/ext/archaeopteryx/AptxTreeBuilder.java | 44 +++-- src/jalview/ext/archaeopteryx/AptxTreePanel.java | 46 ++++- src/jalview/ext/archaeopteryx/JalviewBinding.java | 177 +++++++++---------- .../LoadedTreeSequenceAssociation.java | 93 ++-------- src/jalview/ext/archaeopteryx/Tree.java | 93 +++++++++- src/jalview/ext/archaeopteryx/TreeIterator.java | 31 ++++ src/jalview/ext/archaeopteryx/TreeNode.java | 86 ++++++++- src/jalview/ext/forester/DataConversions.java | 17 ++ .../treeviewer/ExternalLoadedTreeAssociationI.java | 8 + .../ext/treeviewer/ExternalTreeBuilderI.java | 18 +- .../ext/treeviewer/ExternalTreeControlsI.java | 9 + src/jalview/ext/treeviewer/ExternalTreeFrame.java | 19 ++ src/jalview/ext/treeviewer/ExternalTreeI.java | 30 +++- .../ext/treeviewer/ExternalTreeIteratorI.java | 6 + src/jalview/ext/treeviewer/ExternalTreeNodeI.java | 30 +++- src/jalview/ext/treeviewer/ExternalTreePanel.java | 22 +++ src/jalview/ext/treeviewer/ExternalTreePanelI.java | 6 - .../ext/treeviewer/ExternalTreeViewerBindingI.java | 19 +- .../ext/treeviewer/ExternalTreeViewerConfigI.java | 6 + .../ext/treeviewer/ExternalTreeViewerFrameI.java | 7 - src/jalview/gui/AlignFrame.java | 17 +- src/jalview/viewmodel/AlignmentViewport.java | 15 ++ 28 files changed, 774 insertions(+), 401 deletions(-) create mode 100644 src/jalview/ext/archaeopteryx/AptxConfig.java create mode 100644 src/jalview/ext/archaeopteryx/AptxControlPanel.java create mode 100644 src/jalview/ext/archaeopteryx/TreeIterator.java create mode 100644 src/jalview/ext/treeviewer/ExternalTreeControlsI.java create mode 100644 src/jalview/ext/treeviewer/ExternalTreeFrame.java create mode 100644 src/jalview/ext/treeviewer/ExternalTreeIteratorI.java create mode 100644 src/jalview/ext/treeviewer/ExternalTreePanel.java delete mode 100644 src/jalview/ext/treeviewer/ExternalTreePanelI.java create mode 100644 src/jalview/ext/treeviewer/ExternalTreeViewerConfigI.java delete mode 100644 src/jalview/ext/treeviewer/ExternalTreeViewerFrameI.java diff --git a/forester b/forester index 5642da5..835739d 160000 --- a/forester +++ b/forester @@ -1 +1 @@ -Subproject commit 5642da5f473ab9ae57fee86c0cb3b33525a2e916 +Subproject commit 835739d782b7099677aadf653ecc682cf74fc87f diff --git a/src/jalview/analysis/AlignmentSorter.java b/src/jalview/analysis/AlignmentSorter.java index bb3dbcc..058cc72 100755 --- a/src/jalview/analysis/AlignmentSorter.java +++ b/src/jalview/analysis/AlignmentSorter.java @@ -29,6 +29,8 @@ import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.datamodel.SequenceNode; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.util.QuickSort; import java.util.ArrayList; @@ -37,10 +39,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.forester.phylogeny.Phylogeny; -import org.forester.phylogeny.PhylogenyNode; -import org.forester.phylogeny.iterators.PhylogenyNodeIterator; - /** * Routines for manipulating the order of a multiple sequence alignment TODO: * this class retains some global states concerning sort-order which should be @@ -74,7 +72,7 @@ public class AlignmentSorter static TreeModel lastTree = null; - static Phylogeny lastAptxTree = null; + static ExternalTreeI lastExternalTree = null; static boolean sortTreeAscending = true; @@ -470,16 +468,16 @@ public class AlignmentSorter - private static List getOrderByTree(Phylogeny aptxTree, - Map nodesWithBoundSeqs) + private static List getOrderByTree(ExternalTreeI aptxTree, + Map nodesWithBoundSeqs) { List seqsByTreeOrder = new ArrayList<>(); if (!aptxTree.isEmpty()) { - for (final PhylogenyNodeIterator iter = aptxTree - .iteratorPreorder(); iter.hasNext();) + for (final Iterator iter = aptxTree + .iterateInPreOrder(); iter.hasNext();) { - PhylogenyNode treeNode = iter.next(); + ExternalTreeNodeI treeNode = iter.next(); seqsByTreeOrder.add(nodesWithBoundSeqs.get(treeNode)); } @@ -532,17 +530,17 @@ public class AlignmentSorter * tree which has */ public static void sortByTree(AlignmentI align, - Map aptxNodesWithSeqs, - Phylogeny aptxTree) throws IllegalArgumentException + Map nodesBoundToSequences, + ExternalTreeI externalTreeI) throws IllegalArgumentException { - List tmp = getOrderByTree(aptxTree, aptxNodesWithSeqs); + List tmp = getOrderByTree(externalTreeI, nodesBoundToSequences); if (!tmp.isEmpty()) { - if (lastAptxTree != aptxTree) + if (lastExternalTree != externalTreeI) { sortTreeAscending = true; - lastAptxTree = aptxTree; + lastExternalTree = externalTreeI; } else { diff --git a/src/jalview/ext/archaeopteryx/AptxConfig.java b/src/jalview/ext/archaeopteryx/AptxConfig.java new file mode 100644 index 0000000..9563a0a --- /dev/null +++ b/src/jalview/ext/archaeopteryx/AptxConfig.java @@ -0,0 +1,14 @@ +package jalview.ext.archaeopteryx; + +import org.forester.archaeopteryx.Configuration; + +public class AptxConfig +{ + private final Configuration config; + + public AptxConfig(Configuration aptxConfig) + { + config = aptxConfig; + } + +} diff --git a/src/jalview/ext/archaeopteryx/AptxControlPanel.java b/src/jalview/ext/archaeopteryx/AptxControlPanel.java new file mode 100644 index 0000000..6c1bfb4 --- /dev/null +++ b/src/jalview/ext/archaeopteryx/AptxControlPanel.java @@ -0,0 +1,31 @@ +package jalview.ext.archaeopteryx; + +import jalview.ext.treeviewer.ExternalTreeControlsI; + +import org.forester.archaeopteryx.ControlPanel; + +public class AptxControlPanel implements ExternalTreeControlsI +{ + ControlPanel aptxCp; + + public AptxControlPanel(ControlPanel aptxControlPanel) + { + aptxCp = aptxControlPanel; + + } + + @Override + public void defaultSettings() + { + // TODO Auto-generated method stub + + } + + @Override + public void displayEntireTree() + { + aptxCp.showWhole(); + + } + +} diff --git a/src/jalview/ext/archaeopteryx/AptxFrame.java b/src/jalview/ext/archaeopteryx/AptxFrame.java index f0c535b..4223147 100644 --- a/src/jalview/ext/archaeopteryx/AptxFrame.java +++ b/src/jalview/ext/archaeopteryx/AptxFrame.java @@ -1,27 +1,123 @@ package jalview.ext.archaeopteryx; -import jalview.ext.treeviewer.ExternalTreePanelI; -import jalview.ext.treeviewer.ExternalTreeViewerI; +import jalview.ext.treeviewer.ExternalTreeControlsI; +import jalview.ext.treeviewer.ExternalTreeFrame; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreePanel; + +import java.awt.Component; + +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JSeparator; import org.forester.archaeopteryx.MainFrame; -public class Aptx implements ExternalTreeViewerI +public class AptxFrame extends ExternalTreeFrame { - private final MainFrame aptxApp; + private final MainFrame aptxFrame; - public Aptx(MainFrame aptx) + public AptxFrame(MainFrame aptx) { - aptxApp = aptx; + aptxFrame = aptx; + adaptAptxGui(aptxFrame); + } + /** + * Hides certain redundant Archaeopteryx GUI elements such as the menu items + * for reading in trees and adds extra items related to Jalview such as the + * tree sorting item. + * + * + * @param aptxFrame + */ + private void adaptAptxGui(MainFrame aptxFrame) + { + JMenuBar frameBar = aptxFrame.getJMenuBar(); + for (int i = 0; i < frameBar.getMenuCount(); i++) + { + JMenu menu = frameBar.getMenu(i); + if (menu.getText().startsWith("File")) + { + // hide all "Read from ..." and "New" menu items and any Separators that + // come directly after them + Component previousMenuItem = null; + for (Component menuItem : menu.getMenuComponents()) + { + if (previousMenuItem instanceof JMenuItem) + { + if (((JMenuItem) previousMenuItem).getText().startsWith("Read") + || ((JMenuItem) previousMenuItem).getText() + .startsWith("New")) + { + previousMenuItem.setVisible(false); + + if (menuItem instanceof JSeparator) + { + menuItem.setVisible(false); + } + } + } + previousMenuItem = menuItem; + } + } + else if (menu.getText().startsWith("Inference")) + { + menu.setVisible(false); + } + else if (menu.getText().startsWith("View")) + { + menu.addSeparator(); + JMenuItem sortMenuItem = new JMenuItem("Sort alignment by tree"); + sortMenuItem.setVisible(false); + menu.add(sortMenuItem); + } + + } + aptxFrame.validate(); } @Override - public ExternalTreePanelI getTreePanel() + public ExternalTreePanel getTreePanel() { - ExternalTreePanelI aptxPanel = new AptxTreePanel( - aptxApp.getMainPanel().getCurrentTreePanel()); + ExternalTreePanel aptxPanel = new AptxTreePanel( + aptxFrame.getMainPanel().getCurrentTreePanel()); return aptxPanel; } -} + + @Override + public void switchTreePanel(int panelIndex) + { + aptxFrame.getMainPanel().getTabbedPane().getTabComponentAt(panelIndex); + + } + + @Override + public ExternalTreeI getTree() + { + return new Tree( + aptxFrame.getMainPanel().getCurrentTreePanel().getPhylogeny()); + } + + @Override + public void checkMultipleTrees() + { + aptxFrame.activateSaveAllIfNeeded(); + + } + + @Override + public int getNumberOfTrees() + { + return aptxFrame.getMainPanel().getTabbedPane().getTabCount(); + } + + @Override + public ExternalTreeControlsI getTreeControls() + { + return new AptxControlPanel(aptxFrame.getMainPanel().getControlPanel()); + } +} \ No newline at end of file diff --git a/src/jalview/ext/archaeopteryx/AptxInit.java b/src/jalview/ext/archaeopteryx/AptxInit.java index dfc4387..e8fa7d0 100644 --- a/src/jalview/ext/archaeopteryx/AptxInit.java +++ b/src/jalview/ext/archaeopteryx/AptxInit.java @@ -2,14 +2,17 @@ package jalview.ext.archaeopteryx; import jalview.analysis.TreeBuilder; import jalview.datamodel.SequenceI; +import jalview.ext.treeviewer.ExternalLoadedTreeAssociationI; import jalview.ext.treeviewer.ExternalTreeBuilderI; +import jalview.ext.treeviewer.ExternalTreeFrame; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.ext.treeviewer.ExternalTreeViewerBindingI; import jalview.gui.Desktop; import jalview.gui.JvOptionPane; import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; -import java.awt.Component; import java.awt.Dimension; import java.io.File; import java.io.FileNotFoundException; @@ -19,15 +22,8 @@ import java.net.URL; import java.util.HashMap; import java.util.Map; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JSeparator; - import org.forester.archaeopteryx.AptxUtil; -import org.forester.archaeopteryx.Archaeopteryx; import org.forester.archaeopteryx.Configuration; -import org.forester.archaeopteryx.MainFrame; import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient; import org.forester.archaeopteryx.webservices.WebserviceUtil; import org.forester.io.parsers.PhylogenyParser; @@ -39,7 +35,6 @@ import org.forester.io.parsers.tol.TolParser; import org.forester.io.parsers.util.ParserUtils; import org.forester.phylogeny.Phylogeny; import org.forester.phylogeny.PhylogenyMethods; -import org.forester.phylogeny.PhylogenyNode; import org.forester.phylogeny.data.Identifier; import org.forester.util.ForesterUtil; @@ -52,7 +47,7 @@ import org.forester.util.ForesterUtil; */ public final class AptxInit { - private final static Configuration APTX_CONFIG = new Configuration( + public final static Configuration APTX_CONFIG = new Configuration( "_aptx_jalview_configuration_file", false, false, false); @@ -71,19 +66,19 @@ public final class AptxInit private final static NHXParser.TAXONOMY_EXTRACTION TAXONOMY_EXTRACTION = APTX_CONFIG .getTaxonomyExtraction(); - private static Map activeAptx = new HashMap<>(); + private static Map activeAptx = new HashMap<>(); - public static MainFrame createInstanceFromCalculation( + public static ExternalTreeFrame createInstanceFromCalculation( final TreeBuilder calculatedTree) { - ExternalTreeBuilderI aptxTreeBuilder = new AptxTreeBuilder( + ExternalTreeBuilderI aptxTreeBuilder = new AptxTreeBuilder( calculatedTree); - Phylogeny aptxTree = aptxTreeBuilder.buildTree(); + ExternalTreeI aptxTree = aptxTreeBuilder.buildTree(); - MainFrame aptxApp = createAptxFrame(aptxTree, + ExternalTreeFrame aptxApp = createAptxFrame(aptxTree, calculatedTree.getAvport(), null); return aptxApp; @@ -98,7 +93,8 @@ public final class AptxInit * @throws IOException * @throws FileNotFoundException */ - public static MainFrame[] createInstancesFromFile(String filePath, + public static ExternalTreeFrame[] createInstancesFromFile( + String filePath, AlignmentViewport viewport) throws FileNotFoundException, IOException { @@ -116,7 +112,8 @@ public final class AptxInit Desktop.instance.startLoading(filePath); } boolean nhx_or_nexus = false; - final PhylogenyParser parser = ParserUtils.createParserDependingOnFileType( + final PhylogenyParser parser = ParserUtils + .createParserDependingOnFileType( treeFile, VALIDATE_PHYLOXML_XSD); if (parser instanceof NHXParser) { @@ -143,21 +140,24 @@ public final class AptxInit JvOptionPane.WARNING_MESSAGE ); } } - Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser, treeFile); - MainFrame[] aptxFrames = new MainFrame[trees.length]; + Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser, + treeFile); + ExternalTreeFrame[] aptxFrames = new ExternalTreeFrame[trees.length]; for (int i = 0; i < trees.length; i++) { - Phylogeny tree = trees[i]; + Phylogeny aptxPhylogeny = trees[i]; if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE) { - PhylogenyMethods.transferInternalNodeNamesToConfidence(tree, ""); + PhylogenyMethods.transferInternalNodeNamesToConfidence(aptxPhylogeny, + ""); } String treeTitle = treeFile.getName() + "[" + i + "]"; - tree.setName(treeTitle); - aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle); + aptxPhylogeny.setName(treeTitle); + Tree aptxTree = new Tree(aptxPhylogeny); + aptxFrames[i] = createAptxFrame(aptxTree, viewport, treeTitle); } if (Desktop.instance != null) @@ -168,7 +168,7 @@ public final class AptxInit } - public static MainFrame[] createInstancesFromUrl(URL treeUrl, + public static ExternalTreeFrame[] createInstancesFromUrl(URL treeUrl, AlignmentViewport viewport) throws FileNotFoundException, IOException, RuntimeException { @@ -183,11 +183,12 @@ public final class AptxInit REPLACE_NHX_UNDERSCORES, INTERNAL_NUMBERS_AS_CONFIDENCE, TAXONOMY_EXTRACTION, MIDPOINT_REROOT); - MainFrame[] aptxFrames = new MainFrame[trees.length]; + ExternalTreeFrame[] aptxFrames = new ExternalTreeFrame[trees.length]; for (int i = 0; i < trees.length; i++) { - Phylogeny tree = trees[i]; - aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle); + Phylogeny aptxTree = trees[i]; + Tree jalviewTree = new Tree(aptxTree); + aptxFrames[i] = createAptxFrame(jalviewTree, viewport, treeTitle); } if (Desktop.instance != null) @@ -206,7 +207,7 @@ public final class AptxInit * @param viewport * @return */ - public static MainFrame[] createInstancesFromDb( + public static ExternalTreeFrame[] createInstancesFromDb( PhylogeniesWebserviceClient treeDbClient, String identifier, AlignmentViewport viewport) { @@ -238,7 +239,7 @@ public final class AptxInit { identifier }), MessageManager.getString("label.invalid_url"), JvOptionPane.ERROR_MESSAGE); - return new MainFrame[0]; + return new ExternalTreeFrame[0]; } identifier = id + ""; } @@ -357,20 +358,21 @@ public final class AptxInit } if ((trees != null) && (trees.length > 0)) { - for (final Phylogeny phylogeny : trees) + for (final Phylogeny aptxTree : trees) { - if (!phylogeny.isEmpty()) + if (!aptxTree.isEmpty()) { if (treeDbClient.getName().equals(WebserviceUtil.TREE_FAM_NAME)) { - phylogeny.setRerootable(false); - phylogeny.setRooted(true); + aptxTree.setRerootable(false); + aptxTree.setRooted(true); } if (treeDbClient.getProcessingInstructions() != null) { try { - WebserviceUtil.processInstructions(treeDbClient, phylogeny); + WebserviceUtil.processInstructions(treeDbClient, + aptxTree); } catch (final PhyloXmlDataFormatException e) { JvOptionPane.showInternalMessageDialog(Desktop.desktop, @@ -382,7 +384,7 @@ public final class AptxInit { try { - PhylogenyMethods.transferNodeNameToField(phylogeny, + PhylogenyMethods.transferNodeNameToField(aptxTree, treeDbClient.getNodeField(), false); } catch (final PhyloXmlDataFormatException e) { @@ -391,44 +393,47 @@ public final class AptxInit JvOptionPane.ERROR_MESSAGE); } } - phylogeny.setIdentifier( + aptxTree.setIdentifier( new Identifier(identifier, treeDbClient.getName())); // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu()); - // _main_frame.getMenuBarOfMainFrame() + // _main_frame.getMenuBarOfExternalTreeFrameI() // .add(_main_frame.getHelpMenu()); - // _main_frame.getMainPanel().addPhylogenyInNewTab(phylogeny, + // _main_frame.getMainPanel().addExternalTreeIInNewTab(ExternalTreeI, // _main_frame.getConfiguration(), // new File(url.getFile()).getName(), url.toString()); - MainFrame aptxApp = createAptxFrame(phylogeny, viewport, + Tree jalviewTree = new Tree(aptxTree); + + ExternalTreeFrame aptxApp = createAptxFrame(jalviewTree, + viewport, url.getFile()); String my_name_for_file = ""; - if (!ForesterUtil.isEmpty(phylogeny.getName())) + if (!ForesterUtil.isEmpty(jalviewTree.getTreeName())) { - my_name_for_file = new String(phylogeny.getName()) + my_name_for_file = new String(jalviewTree.getTreeName()) .replaceAll(" ", "_"); } - else if (phylogeny.getIdentifier() != null) + else if (aptxTree.getIdentifier() != null) { final StringBuffer sb = new StringBuffer(); if (!ForesterUtil - .isEmpty(phylogeny.getIdentifier().getProvider())) + .isEmpty(aptxTree.getIdentifier().getProvider())) { - sb.append(phylogeny.getIdentifier().getProvider()); + sb.append(aptxTree.getIdentifier().getProvider()); sb.append("_"); } - sb.append(phylogeny.getIdentifier().getValue()); + sb.append(aptxTree.getIdentifier().getValue()); my_name_for_file = new String( sb.toString().replaceAll(" ", "_")); } - aptxApp.getMainPanel().getCurrentTreePanel() + aptxApp.getTreePanel() .setTreeFile(new File(my_name_for_file)); - AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings( - phylogeny, aptxApp.getMainPanel().getControlPanel(), - APTX_CONFIG); - // _main_frame.getMainPanel().getControlPanel().showWhole(); + // AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings( + // aptxTree, aptxApp.getMainPanel().getControlPanel(), + // APTX_CONFIG); + aptxApp.getTreeControls().displayEntireTree(); - aptxApp.activateSaveAllIfNeeded(); + aptxApp.checkMultipleTrees(); } } } @@ -472,8 +477,8 @@ public final class AptxInit - public static MainFrame createAptxFrame( - final Phylogeny aptxTree, + public static ExternalTreeFrame createAptxFrame( + final ExternalTreeI aptxTree, final AlignmentViewport jalviewAlignport, String treeTitle) { if (APTX_CONFIG == null || APTX_CONFIG.isCouldReadConfigFile() == false) @@ -493,11 +498,9 @@ public final class AptxInit } } - MainFrame aptxApp = Archaeopteryx.createApplication(aptxTree, - APTX_CONFIG, treeTitle); + ExternalTreeFrame aptxApp = aptxTree.createInstanceFromTree(treeTitle); - adaptAptxGui(aptxApp); - LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation( + ExternalLoadedTreeAssociationI bindAptxNodes = new LoadedTreeSequenceAssociation( jalviewAlignport.getAlignment().getSequencesArray(), aptxTree); bindAptxNodes.associateLeavesToSequences(); @@ -506,15 +509,16 @@ public final class AptxInit bindAptxNodes.getNodesWithAlignment()); bindTreeViewFrameToJalview(aptxApp); + // adaptAptxGui(aptxApp); //moved to AptxFrame return aptxApp; } - public static ExternalTreeViewerBindingI bindNodesToJalviewSequences( - final MainFrame aptxApp, + public static ExternalTreeViewerBindingI bindNodesToJalviewSequences( + final ExternalTreeFrame aptxApp, final AlignmentViewport jalviewAlignViewport, - final Map alignMappedToNodes, - final Map nodesMappedToAlign) + final Map alignMappedToNodes, + final Map nodesMappedToAlign) { JalviewBinding treeBinding = new JalviewBinding(aptxApp, jalviewAlignViewport, @@ -524,8 +528,8 @@ public final class AptxInit } - public static MainFrame bindTreeViewFrameToJalview( - final MainFrame aptxApp) + public static ExternalTreeFrame bindTreeViewFrameToJalview( + final ExternalTreeFrame aptxApp) { int width = 400; int height = 550; @@ -533,8 +537,7 @@ public final class AptxInit // aptxApp.setFont(Desktop.instance.getFont()); // aptxApp.getMainPanel().setFont(Desktop.instance.getFont()); String frameTitle = MessageManager.getString("label.aptx_title"); - File treeFile = aptxApp.getMainPanel().getCurrentTreePanel() - .getTreeFile(); + File treeFile = aptxApp.getTreePanel().getTreeFile(); if (treeFile != null) { frameTitle += MessageManager.formatMessage("label.aptx_title_append", @@ -547,59 +550,9 @@ public final class AptxInit } - /** - * Hides certain redundant Archaeopteryx GUI elements such as the menu items - * for reading in trees and adds extra items related to Jalview such as the - * tree sorting item. - * - * - * @param aptxFrame - */ - private static void adaptAptxGui(MainFrame aptxFrame) - { - JMenuBar frameBar = aptxFrame.getJMenuBar(); - for (int i = 0; i < frameBar.getMenuCount();i++) { - JMenu menu = frameBar.getMenu(i); - - if (menu.getText().contains("File")) - { - // hide all "Read from ..." and "New" menu items and any Separators that - // come directly after them - Component previousMenuItem = null; - for (Component menuItem : menu.getMenuComponents()) { - if (previousMenuItem instanceof JMenuItem) - { - if (((JMenuItem) previousMenuItem).getText().startsWith("Read") - || ((JMenuItem) previousMenuItem).getText() - .startsWith("New")) - { - previousMenuItem.setVisible(false); - - if (menuItem instanceof JSeparator) - { - menuItem.setVisible(false); - } - } - } - previousMenuItem = menuItem; - } - } - else if (menu.getText().contains("Inference")) - { - menu.setVisible(false); - } - else if (menu.getText().contains("View")) - { - menu.addSeparator(); - menu.add(new JMenuItem("Sort alignment by tree")); - } - - } - aptxFrame.validate(); - } - public static Map getAllAptxFrames() + public static Map getAllAptxFrames() { return activeAptx; } diff --git a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java index 74d89d2..54bcff1 100644 --- a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java +++ b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java @@ -2,9 +2,10 @@ package jalview.ext.archaeopteryx; import jalview.analysis.TreeBuilder; import jalview.datamodel.SequenceI; -import jalview.ext.forester.DataConversions; import jalview.ext.forester.ForesterMatrix; import jalview.ext.treeviewer.ExternalTreeBuilderI; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.util.MappingUtils; import jalview.util.MessageManager; @@ -14,8 +15,6 @@ import java.util.Map; import org.forester.evoinference.matrix.distance.DistanceMatrix; import org.forester.phylogeny.Phylogeny; import org.forester.phylogeny.PhylogenyNode; -import org.forester.phylogeny.data.NodeData; -import org.forester.phylogeny.data.Sequence; /** * Class for converting trees made in Jalview (through TreeBuilder) to trees @@ -28,7 +27,7 @@ import org.forester.phylogeny.data.Sequence; * */ public class AptxTreeBuilder - implements ExternalTreeBuilderI + implements ExternalTreeBuilderI { protected final SequenceI[] sequences; @@ -38,13 +37,13 @@ public class AptxTreeBuilder public String treeTitle; - private final Phylogeny aptxTree; + private final ExternalTreeI aptxTree; - private PhylogenyNode rootNode; + private ExternalTreeNodeI rootNode; - private final Map alignmentWithNodes; + private final Map alignmentWithNodes; - private final Map nodesWithAlignment; + private final Map nodesWithAlignment; public AptxTreeBuilder(final TreeBuilder calculatedTree) { @@ -53,8 +52,8 @@ public class AptxTreeBuilder distances = ForesterMatrix.convertJalviewToForester( jalviewTree.getDistances(), sequences); - aptxTree = new Phylogeny(); - rootNode = new PhylogenyNode(); + aptxTree = new Tree(new Phylogeny()); + rootNode = new TreeNode(new PhylogenyNode()); int amountOfSequences = distances.getSize(); alignmentWithNodes = new HashMap<>(amountOfSequences); @@ -64,7 +63,7 @@ public class AptxTreeBuilder } @Override - public Phylogeny buildTree(final PhylogenyNode treeRoot) + public ExternalTreeI buildTree(final ExternalTreeNodeI treeRoot) { if (treeRoot != null) @@ -80,17 +79,16 @@ public class AptxTreeBuilder @Override - public Phylogeny buildTree() + public ExternalTreeI buildTree() { for (SequenceI sequence : sequences) { - Sequence seq = DataConversions - .createForesterSequence(sequence, true); - PhylogenyNode sequenceNode = new PhylogenyNode(sequence.getName()); - NodeData nodeData = sequenceNode.getNodeData(); - nodeData.setSequence(seq); + ExternalTreeNodeI sequenceNode = new TreeNode( + new PhylogenyNode(sequence.getName())); + + sequenceNode.setSequence(sequence); MappingUtils.putWithDuplicationCheck(nodesWithAlignment, sequenceNode, sequence); @@ -103,29 +101,25 @@ public class AptxTreeBuilder aptxTree.setRoot(rootNode); treeTitle = generateTreeName(); - aptxTree.setName(treeTitle); + aptxTree.setTreeName(treeTitle); return aptxTree; } @Override - public Map getAlignmentBoundNodes() + public Map getAlignmentBoundNodes() { return alignmentWithNodes; } @Override - public Map getNodesBoundAlignment() + public Map getNodesBoundAlignment() { return nodesWithAlignment; } - private Phylogeny clusterNodes() - { - return aptxTree; - } /** * Formats a localised title for the tree panel, like *

@@ -165,6 +159,8 @@ public class AptxTreeBuilder return ttl; } } + + } diff --git a/src/jalview/ext/archaeopteryx/AptxTreePanel.java b/src/jalview/ext/archaeopteryx/AptxTreePanel.java index 631ff15..94e0f91 100644 --- a/src/jalview/ext/archaeopteryx/AptxTreePanel.java +++ b/src/jalview/ext/archaeopteryx/AptxTreePanel.java @@ -1,8 +1,13 @@ package jalview.ext.archaeopteryx; -import jalview.ext.treeviewer.ExternalTreePanelI; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; +import jalview.ext.treeviewer.ExternalTreePanel; -public class AptxTreePanel implements ExternalTreePanelI +import java.io.File; +import java.util.Set; + +public class AptxTreePanel extends ExternalTreePanel { private final org.forester.archaeopteryx.TreePanel treeView; @@ -11,4 +16,41 @@ public class AptxTreePanel implements ExternalTreePanelI treeView = aptxTreePanel; } + + @Override + public void setTreeFile(File file) + { + treeView.setTreeFile(file); + } + + @Override + public ExternalTreeI getTree() + { + return new Tree(treeView.getPhylogeny()); + } + + @Override + public File getTreeFile() + { + return treeView.getTreeFile(); + } + + @Override + public ExternalTreeNodeI findNode(int x, int y) + { + return new TreeNode(treeView.findNode(x, y)); + } + + @Override + public void setMatchingNodes(Set hashSet) + { + treeView.setFoundNodes0(hashSet); + + } + + @Override + public Set getMatchingNodes() + { + return treeView.getFoundNodes0(); + } } diff --git a/src/jalview/ext/archaeopteryx/JalviewBinding.java b/src/jalview/ext/archaeopteryx/JalviewBinding.java index 88b2d15..510becf 100644 --- a/src/jalview/ext/archaeopteryx/JalviewBinding.java +++ b/src/jalview/ext/archaeopteryx/JalviewBinding.java @@ -9,6 +9,10 @@ import jalview.datamodel.ColumnSelection; import jalview.datamodel.HiddenColumns; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.ext.treeviewer.ExternalTreeFrame; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; +import jalview.ext.treeviewer.ExternalTreePanel; import jalview.ext.treeviewer.ExternalTreeViewerBindingI; import jalview.gui.AlignViewport; import jalview.gui.AlignmentPanel; @@ -34,19 +38,10 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; -import org.forester.archaeopteryx.MainFrame; -import org.forester.phylogeny.Phylogeny; -import org.forester.phylogeny.PhylogenyMethods; -import org.forester.phylogeny.PhylogenyNode; -import org.forester.phylogeny.data.BranchColor; - /** * Class for binding the Archaeopteryx tree viewer to the Jalview alignment that * it originates from, meaning that selecting sequences in the tree viewer also @@ -56,23 +51,21 @@ import org.forester.phylogeny.data.BranchColor; * */ public final class JalviewBinding - implements ExternalTreeViewerBindingI + implements ExternalTreeViewerBindingI { - private final MainFrame aptxFrame; + private final ExternalTreeFrame aptxFrame; - private org.forester.archaeopteryx.TreePanel treeView; + private ExternalTreePanel treeView; private AlignmentViewport parentAvport; - private final JTabbedPane treeTabs; - private final StructureSelectionManager ssm; private AlignmentPanel[] associatedPanels; - private Map sequencesBoundToNodes; + private Map sequencesBoundToNodes; - private Map nodesBoundToSequences; + private Map nodesBoundToSequences; private float rootX; @@ -97,13 +90,13 @@ public final class JalviewBinding * map with tree nodes and matching sequences used to calculate the * tree as key, value pair respectively. */ - public JalviewBinding(final MainFrame archaeopteryx, + public JalviewBinding(final ExternalTreeFrame archaeopteryx, final AlignmentViewport jalviewAlignmentViewport, - final Map alignMappedToNodes, - final Map nodesMappedToAlign) + final Map alignMappedToNodes, + final Map nodesMappedToAlign) { - if (archaeopteryx.getMainPanel().getTabbedPane().getTabCount() > 1) + if (archaeopteryx.getNumberOfTrees() > 1) { JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager.getString("label.tabs_detected_archaeopteryx"), @@ -118,8 +111,7 @@ public final class JalviewBinding sequencesBoundToNodes = alignMappedToNodes; nodesBoundToSequences = nodesMappedToAlign; - treeView = archaeopteryx.getMainPanel().getCurrentTreePanel(); - treeTabs = archaeopteryx.getMainPanel().getTabbedPane(); + treeView = archaeopteryx.getTreePanel(); ssm = parentAvport.getStructureSelectionManager(); ssm.addSelectionListener(this); @@ -141,36 +133,36 @@ public final class JalviewBinding }); - treeTabs.addChangeListener(new ChangeListener() - { - - @Override - public void stateChanged(ChangeEvent e) - { - - SwingUtilities.invokeLater(new Runnable() - { - - @Override - /** - * Resend the selection to the tree view when tabs get switched, this - * has to be buried in invokeLater as Forester first resets the tree - * view on switching tabs, without invokeLater this would get called - * before Forester resets which would nullify the selection. - */ - public void run() - { - treeView = archaeopteryx.getMainPanel().getCurrentTreePanel(); - parentAvport.sendSelection(); - // PaintRefresher.Refresh(treeView, - // parentAvport.getSequenceSetId()); - - } - }); - - } - - }); + // treeTabs.addChangeListener(new ChangeListener() + // { + // + // @Override + // public void stateChanged(ChangeEvent e) + // { + // + // SwingUtilities.invokeLater(new Runnable() + // { + // + // @Override + // /** + // * Resend the selection to the tree view when tabs get switched, this + // * has to be buried in invokeLater as Forester first resets the tree + // * view on switching tabs, without invokeLater this would get called + // * before Forester resets which would nullify the selection. + // */ + // public void run() + // { + // treeView = archaeopteryx.getMainPanel().getCurrentTreePanel(); + // parentAvport.sendSelection(); + // // PaintRefresher.Refresh(treeView, + // // parentAvport.getSequenceSetId()); + // + // } + // }); + // + // } + // + // }); } @@ -192,7 +184,8 @@ public final class JalviewBinding */ public void run() { - final PhylogenyNode node = treeView.findNode(e.getX(), e.getY()); + final ExternalTreeNodeI node = treeView.findNode(e.getX(), + e.getY()); if (node != null) { if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous @@ -249,26 +242,27 @@ public final class JalviewBinding if (source == parentAvport) // check if source is alignment from where the // tree originates { - treeView.setFoundNodes0( + treeView.setMatchingNodes( new HashSet(seqsel.getSequences().size())); for (SequenceI selectedSequence : seqsel.getSequences()) { - PhylogenyNode matchingNode = sequencesBoundToNodes.get(selectedSequence); + ExternalTreeNodeI matchingNode = sequencesBoundToNodes + .get(selectedSequence); if (matchingNode != null) { - treeView.getFoundNodes0().add(matchingNode.getId()); + treeView.getMatchingNodes().add(matchingNode.getId()); - if (!matchingNode.getBranchData().isHasBranchColor()) - { - // Color foundNodesColour = treeView.getTreeColorSet() - // .getFoundColor0(); - // matchingNode.getBranchData() - // .setBranchColor(new BranchColor(foundNodesColour)); - - } + // if (!matchingNode.getBranchData().isHasBranchColor()) + // { + // // Color foundNodesColour = treeView.getTreeColorSet() + // // .getFoundColor0(); + // // matchingNode.getBranchData() + // // .setBranchColor(new BranchColor(foundNodesColour)); + // + // } } @@ -285,14 +279,13 @@ public final class JalviewBinding */ public void partitionTree(final int x) { - Phylogeny tree = treeView.getPhylogeny(); + ExternalTreeI tree = treeView.getTree(); if (!tree.isEmpty()) { // should be calculated on each partition as the tree can theoretically // change in the meantime - PhylogenyNode furthestNode = PhylogenyMethods - .calculateNodeWithMaxDistanceToRoot(tree); + ExternalTreeNodeI furthestNode = tree.getFurthestNode(); furthestNodeX = furthestNode.getXcoord(); rootX = tree.getRoot().getXcoord(); @@ -300,7 +293,8 @@ public final class JalviewBinding if (furthestNodeX != rootX && !(x > furthestNodeX)) { float threshold = (x - rootX) / (furthestNodeX - rootX); - List foundNodes = getNodesAboveThreshold(threshold, + List foundNodes = getNodesAboveThreshold( + threshold, tree.getRoot()); } @@ -309,11 +303,11 @@ public final class JalviewBinding } - public List getNodesAboveThreshold(double threshold, - PhylogenyNode node) + public List getNodesAboveThreshold(double threshold, + ExternalTreeNodeI node) { - List nodesAboveThreshold = new ArrayList<>(); + List nodesAboveThreshold = new ArrayList<>(); parentAvport.setSelectionGroup(null); parentAvport.getAlignment().deleteAllGroups(); @@ -341,15 +335,14 @@ public final class JalviewBinding * @param node * @return */ - private List colourNodesAboveThreshold( - List nodeList, double threshold, - PhylogenyNode node) + private List colourNodesAboveThreshold( + List nodeList, double threshold, + ExternalTreeNodeI node) { - for (PhylogenyNode childNode : node.getDescendants()) + for (ExternalTreeNodeI childNode : node.getDirectChildren()) { - childNode.getBranchData() - .setBranchColor(new BranchColor(Color.black)); + childNode.setBranchColor(Color.black); float nodeCutoff = (childNode.getXcoord() - rootX) / (furthestNodeX - rootX); @@ -359,8 +352,7 @@ public final class JalviewBinding Color randomColour = new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255)); - childNode.getBranchData() - .setBranchColor(new BranchColor(randomColour)); + childNode.setBranchColor(randomColour); List groupSeqs = new ArrayList<>(); SequenceI seq = nodesBoundToSequences.get(childNode); @@ -370,10 +362,10 @@ public final class JalviewBinding parentAvport.setSequenceColour(seq, randomColour); } - List descendantNodes = PhylogenyMethods - .getAllDescendants(childNode); + List descendantNodes = childNode + .getAllDescendants(); // .forEach instead? - for (PhylogenyNode descNode : descendantNodes) + for (ExternalTreeNodeI descNode : descendantNodes) { seq = nodesBoundToSequences.get(descNode); if (seq != null) @@ -382,8 +374,7 @@ public final class JalviewBinding parentAvport.setSequenceColour(seq, randomColour); } - descNode.getBranchData() - .setBranchColor(new BranchColor(randomColour)); + descNode.setBranchColor(randomColour); } if (groupSeqs != null) @@ -493,7 +484,7 @@ public final class JalviewBinding * does) */ @Override - public void showNodeSelectionOnAlign(final PhylogenyNode node) + public void showNodeSelectionOnAlign(final ExternalTreeNodeI node) { if (node.isInternal()) @@ -514,13 +505,13 @@ public final class JalviewBinding @Override - public void showMatchingSequence(final PhylogenyNode nodeToMatch) + public void showMatchingSequence(final ExternalTreeNodeI nodeToMatch) { SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch); if (matchingSequence != null) { long nodeId = nodeToMatch.getId(); - addOrRemoveInSet(treeView.getFoundNodes0(), nodeId); + addOrRemoveInSet(treeView.getMatchingNodes(), nodeId); treeSelectionChanged(matchingSequence); parentAvport.sendSelection(); @@ -528,15 +519,14 @@ public final class JalviewBinding } @Override - public void showMatchingChildSequences(final PhylogenyNode parentNode) + public void showMatchingChildSequences(final ExternalTreeNodeI parentNode) { // redundancy here, Forester already iterates through tree to get all // descendants - List childNodes = PhylogenyMethods - .getAllDescendants(parentNode); + List childNodes = parentNode.getAllDescendants(); - for (PhylogenyNode childNode : childNodes) + for (ExternalTreeNodeI childNode : childNodes) { // childNode.getBranchData().setBranchColor(new BranchColor(Color.BLUE)); @@ -544,7 +534,7 @@ public final class JalviewBinding if (matchingSequence != null) { long nodeId = childNode.getId(); - addOrRemoveInSet(treeView.getFoundNodes0(), nodeId); + addOrRemoveInSet(treeView.getMatchingNodes(), nodeId); treeSelectionChanged(matchingSequence); @@ -642,6 +632,7 @@ public final class JalviewBinding } + @Override public CommandI sortAlignmentIn(AlignmentPanel ap) { // TODO: move to alignment view controller @@ -652,7 +643,7 @@ public final class JalviewBinding { AlignmentSorter.sortByTree(viewport.getAlignment(), nodesBoundToSequences, - treeView.getPhylogeny()); + treeView.getTree()); CommandI undo; undo = new OrderCommand("Tree Sort", oldOrder, viewport.getAlignment()); diff --git a/src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java b/src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java index 86f27d1..f05ba45 100644 --- a/src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java +++ b/src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java @@ -2,30 +2,29 @@ package jalview.ext.archaeopteryx; import jalview.analysis.SequenceIdMatcher; import jalview.datamodel.SequenceI; -import jalview.ext.forester.DataConversions; import jalview.ext.treeviewer.ExternalLoadedTreeAssociationI; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.util.MappingUtils; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; -import org.forester.phylogeny.Phylogeny; -import org.forester.phylogeny.PhylogenyNode; -import org.forester.phylogeny.iterators.PhylogenyNodeIterator; public class LoadedTreeSequenceAssociation implements ExternalLoadedTreeAssociationI { SequenceI[] alignSequences; - Phylogeny tree; + ExternalTreeI tree; - Map alignmentWithNodes; + Map alignmentWithNodes; - Map nodesWithAlignment; + Map nodesWithAlignment; public LoadedTreeSequenceAssociation(SequenceI[] alignmentSequences, - Phylogeny aptxTree) + ExternalTreeI aptxTree) { alignSequences = alignmentSequences; tree = aptxTree; @@ -56,18 +55,18 @@ public class LoadedTreeSequenceAssociation if (!tree.isEmpty()) { - for (final PhylogenyNodeIterator iter = tree.iteratorPreorder(); iter + for (final Iterator iter = tree + .iterateInPreOrder(); iter .hasNext();) { - PhylogenyNode treeNode = iter.next(); - nodeSequenceName = treeNode.getName(); + ExternalTreeNodeI treeNode = iter.next(); + nodeSequenceName = treeNode.getNodeName(); nodeSequence = algnIds.findIdMatch(nodeSequenceName); if (nodeSequence != null) { - org.forester.phylogeny.data.Sequence foresterNodeSeq = DataConversions - .createForesterSequence(nodeSequence, true); - treeNode.getNodeData().setSequence(foresterNodeSeq); + + treeNode.setSequence(nodeSequence); MappingUtils.putWithDuplicationCheck(alignmentWithNodes, nodeSequence, treeNode); @@ -84,78 +83,16 @@ public class LoadedTreeSequenceAssociation - public Map getAlignmentWithNodes() + public Map getAlignmentWithNodes() { return alignmentWithNodes; } - public Map getNodesWithAlignment() + public Map getNodesWithAlignment() { return nodesWithAlignment; } - // { - // SequenceIdMatcher algnIds = new SequenceIdMatcher(seqs); - // - // List leaves = aptxTree.getExternalNodes(); - // - // int namesleft = seqs.length; - // SequenceI nodeSequence; - // String nodeSequenceName; - // List one2many = new ArrayList<>(); - // int countOne2Many = 0; - // - // for (PhylogenyNode treeNode : leaves) - // { - // nodeSequenceName = treeNode.getName(); - // nodeSequence = null; - // - // if (namesleft > -1) - // { - // nodeSequence = algnIds.findIdMatch(nodeSequenceName); - // } - // - // if (nodeSequence != null) - // { - // org.forester.phylogeny.data.Sequence foresterNodeSeq = - // ForesterDataConversions.createForesterSequence(nodeSequence, true); - // - // treeNode.getNodeData().setSequence(foresterNodeSeq); - // if (one2many.contains(nodeSequence)) - // { - // countOne2Many++; - // if (jalview.bin.Cache.log.isDebugEnabled()) - // { - // jalview.bin.Cache.log.debug("One 2 many relationship for" - // +nodeSequence.getName()); - // } - // } - // else - // { - // one2many.add(nodeSequence); - // namesleft--; - // } - // } - // else - // { - // treeNode.setCollapse(true); // collapse nodes that couldn't be connected - // // to a sequence - // - // - // // treeNode.setElement( new Sequence(nodeSequenceName, - // "THISISAPLACEHOLDER")); - // // treeNode.setPlaceholder(true); - // } - // } - // if (jalview.bin.Cache.log.isDebugEnabled() && countOne2Many > 0) - // { - // jalview.bin.Cache.log.debug("There were " + countOne2Many - // + "alignment sequence ids (out of" + one2many.size() - // + " unique ids) linked to two or more leaves."); - // } - // one2many.clear(); - // - // } } diff --git a/src/jalview/ext/archaeopteryx/Tree.java b/src/jalview/ext/archaeopteryx/Tree.java index 884a359..d06339e 100644 --- a/src/jalview/ext/archaeopteryx/Tree.java +++ b/src/jalview/ext/archaeopteryx/Tree.java @@ -1,9 +1,15 @@ package jalview.ext.archaeopteryx; +import jalview.ext.treeviewer.ExternalTreeFrame; import jalview.ext.treeviewer.ExternalTreeI; import jalview.ext.treeviewer.ExternalTreeNodeI; +import java.util.Iterator; + +import org.forester.archaeopteryx.Archaeopteryx; import org.forester.phylogeny.Phylogeny; +import org.forester.phylogeny.PhylogenyMethods; +import org.forester.phylogeny.PhylogenyNode; public class Tree implements ExternalTreeI { @@ -14,12 +20,6 @@ public class Tree implements ExternalTreeI tree = aptxTree; } - @Override - public Phylogeny getOriginalTree() - { - return tree; - - } @Override public ExternalTreeNodeI getRoot() @@ -47,4 +47,85 @@ public class Tree implements ExternalTreeI { return tree.getAllExternalNodeNames(); } + + @Override + public void setRerootable(boolean b) + { + tree.setRerootable(b); + + } + + @Override + public void setRooted(boolean b) + { + tree.setRooted(b); + + } + + @Override + public boolean isEmpty() + { + return tree.isEmpty(); + } + + @Override + public String getTreeName() + { + return tree.getName(); + } + + @Override + public void setRoot(ExternalTreeNodeI rootNode) + { + PhylogenyNode treeRoot = new PhylogenyNode(rootNode.getNodeName()); + // expand this + tree.setRoot(treeRoot); + + } + + @Override + public double getHeight(boolean adjustForCollapsedSubtrees) + { + return tree.calculateHeight(adjustForCollapsedSubtrees); + } + + @Override + public Iterator iterateInPreOrder() + { + Iterator iter = new TreeIterator( + tree.iteratorPreorder()); + return iter; + } + + @Override + public Iterator iterateInLevelOrder() + { + Iterator iter = new TreeIterator( + tree.iteratorLevelOrder()); + return iter; + } + + @Override + public Iterator iterateInPostOrder() + { + Iterator iter = new TreeIterator( + tree.iteratorPostorder()); + return iter; + } + + @Override + public ExternalTreeNodeI getFurthestNode() + { + PhylogenyNode furthestNode = PhylogenyMethods + .calculateNodeWithMaxDistanceToRoot(tree); + return new TreeNode(furthestNode); + } + + @Override + public ExternalTreeFrame createInstanceFromTree(String instanceTitle) + { + return new AptxFrame(Archaeopteryx.createApplication(tree, + AptxInit.APTX_CONFIG, + instanceTitle)); + } } diff --git a/src/jalview/ext/archaeopteryx/TreeIterator.java b/src/jalview/ext/archaeopteryx/TreeIterator.java new file mode 100644 index 0000000..79e8e49 --- /dev/null +++ b/src/jalview/ext/archaeopteryx/TreeIterator.java @@ -0,0 +1,31 @@ +package jalview.ext.archaeopteryx; + +import jalview.ext.treeviewer.ExternalTreeNodeI; + +import java.util.Iterator; + +import org.forester.phylogeny.iterators.PhylogenyNodeIterator; + +public class TreeIterator implements Iterator +{ + private final PhylogenyNodeIterator iter; + + public TreeIterator(PhylogenyNodeIterator aptxIterator) + { + iter = aptxIterator; + } + + @Override + public boolean hasNext() + { + return iter.hasNext(); + } + + @Override + public ExternalTreeNodeI next() + { + ExternalTreeNodeI node = new TreeNode(iter.next()); + return node; + } + +} diff --git a/src/jalview/ext/archaeopteryx/TreeNode.java b/src/jalview/ext/archaeopteryx/TreeNode.java index b2e33d4..78b3981 100644 --- a/src/jalview/ext/archaeopteryx/TreeNode.java +++ b/src/jalview/ext/archaeopteryx/TreeNode.java @@ -1,39 +1,111 @@ package jalview.ext.archaeopteryx; +import jalview.datamodel.SequenceI; +import jalview.ext.forester.DataConversions; import jalview.ext.treeviewer.ExternalTreeNodeI; +import java.awt.Color; import java.util.List; +import org.forester.phylogeny.PhylogenyMethods; import org.forester.phylogeny.PhylogenyNode; +import org.forester.phylogeny.data.BranchColor; public class TreeNode implements ExternalTreeNodeI { private final PhylogenyNode node; + private SequenceI nodeSeq; + public TreeNode(PhylogenyNode aptxNode) { node = aptxNode; + } + @Override - public PhylogenyNode getOriginalNode() + public String getNodeName() { - return node; + return node.getName(); } @Override - public String getNodeName() + public List getAllDescendants() { - return node.getName(); + List descNodes = PhylogenyMethods + .getAllDescendants(node); + return DataConversions.getConvertedTreeNodes(descNodes); + } @Override - public List getChildren() + public List getExternalDescendants() { - // return node.getDescendants(); - return null; + List extDescNodes = node.getAllExternalDescendants(); + return DataConversions.getConvertedTreeNodes(extDescNodes); + } + + @Override + public List getDirectChildren() + { + List childNodes = node.getDescendants(); + return DataConversions.getConvertedTreeNodes(childNodes); + } + + + + @Override + public void setSequence(SequenceI seq) + { + nodeSeq = seq; + org.forester.phylogeny.data.Sequence foresterFormatSeq = DataConversions + .createForesterSequence(seq, true); + node.getNodeData().setSequence(foresterFormatSeq); + + } + + @Override + public SequenceI getSequence() + { + return nodeSeq; + // ideally this would return a converted node.getNodeData().getSequence() } + @Override + public void addAsChild(ExternalTreeNodeI childNode) + { + PhylogenyNode aptxNode = new PhylogenyNode(childNode.getNodeName()); + + // expand on this + node.addAsChild(aptxNode); + + } + + @Override + public long getId() + { + return node.getId(); + } + + @Override + public float getXcoord() + { + return node.getXcoord(); + } + + @Override + public void setBranchColor(Color branchColor) + { + node.getBranchData().setBranchColor(new BranchColor(branchColor)); + + } + + @Override + public boolean isInternal() + { + return node.isInternal(); + } } diff --git a/src/jalview/ext/forester/DataConversions.java b/src/jalview/ext/forester/DataConversions.java index be97e0e..22c4df0 100644 --- a/src/jalview/ext/forester/DataConversions.java +++ b/src/jalview/ext/forester/DataConversions.java @@ -1,10 +1,16 @@ package jalview.ext.forester; import jalview.datamodel.SequenceI; +import jalview.ext.archaeopteryx.TreeNode; +import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.math.MatrixI; +import java.util.ArrayList; +import java.util.List; + import org.forester.evoinference.matrix.distance.DistanceMatrix; import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException; +import org.forester.phylogeny.PhylogenyNode; public final class DataConversions { @@ -73,4 +79,15 @@ public final class DataConversions return foresterMatrix; } + + public static List getConvertedTreeNodes( + List aptxNodes) + { + List jalviewNodes = new ArrayList<>(); + for (PhylogenyNode aptxNode : aptxNodes) + { + jalviewNodes.add(new TreeNode(aptxNode)); + } + return jalviewNodes; + } } diff --git a/src/jalview/ext/treeviewer/ExternalLoadedTreeAssociationI.java b/src/jalview/ext/treeviewer/ExternalLoadedTreeAssociationI.java index 83ffac6..8d35fd7 100644 --- a/src/jalview/ext/treeviewer/ExternalLoadedTreeAssociationI.java +++ b/src/jalview/ext/treeviewer/ExternalLoadedTreeAssociationI.java @@ -1,5 +1,9 @@ package jalview.ext.treeviewer; +import jalview.datamodel.SequenceI; + +import java.util.Map; + /** * Interface for associating the leaves of a loaded in (not calculated) tree to * the alignment sequences in Jalview. @@ -11,4 +15,8 @@ package jalview.ext.treeviewer; public interface ExternalLoadedTreeAssociationI { public void associateLeavesToSequences(); + + public Map getAlignmentWithNodes(); + + public Map getNodesWithAlignment(); } diff --git a/src/jalview/ext/treeviewer/ExternalTreeBuilderI.java b/src/jalview/ext/treeviewer/ExternalTreeBuilderI.java index 8fd1d1d..44ca06e 100644 --- a/src/jalview/ext/treeviewer/ExternalTreeBuilderI.java +++ b/src/jalview/ext/treeviewer/ExternalTreeBuilderI.java @@ -5,26 +5,18 @@ import jalview.datamodel.SequenceI; import java.util.Map; /** - * Note that this will take anything as a Tree or TreeNode object as no - * assumptions can be made about the inheritance structure of Tree or TreeNode - * (besides being Objects). - * * @author kjvanderheide * - * @param - * Tree object that the tree viewer requires. - * @param - * Tree node object that the tree viewer requires. */ -public interface ExternalTreeBuilderI +public interface ExternalTreeBuilderI { - public T buildTree(N treeRoot); + public ExternalTreeI buildTree(ExternalTreeNodeI treeRoot); - public T buildTree(); + public ExternalTreeI buildTree(); - public Map getAlignmentBoundNodes(); + public Map getAlignmentBoundNodes(); - public Map getNodesBoundAlignment(); + public Map getNodesBoundAlignment(); public String generateTreeName(); diff --git a/src/jalview/ext/treeviewer/ExternalTreeControlsI.java b/src/jalview/ext/treeviewer/ExternalTreeControlsI.java new file mode 100644 index 0000000..e278879 --- /dev/null +++ b/src/jalview/ext/treeviewer/ExternalTreeControlsI.java @@ -0,0 +1,9 @@ +package jalview.ext.treeviewer; + +public interface ExternalTreeControlsI +{ + public void defaultSettings(); + + public void displayEntireTree(); + +} diff --git a/src/jalview/ext/treeviewer/ExternalTreeFrame.java b/src/jalview/ext/treeviewer/ExternalTreeFrame.java new file mode 100644 index 0000000..32c8e51 --- /dev/null +++ b/src/jalview/ext/treeviewer/ExternalTreeFrame.java @@ -0,0 +1,19 @@ +package jalview.ext.treeviewer; + +import javax.swing.JInternalFrame; + +public abstract class ExternalTreeFrame extends JInternalFrame +{ + public abstract ExternalTreePanel getTreePanel(); + + public abstract void switchTreePanel(int panelIndex); + + public abstract ExternalTreeI getTree(); + + public abstract void checkMultipleTrees(); + + public abstract int getNumberOfTrees(); + + public abstract ExternalTreeControlsI getTreeControls(); + +} diff --git a/src/jalview/ext/treeviewer/ExternalTreeI.java b/src/jalview/ext/treeviewer/ExternalTreeI.java index 0184227..68e5ff8 100644 --- a/src/jalview/ext/treeviewer/ExternalTreeI.java +++ b/src/jalview/ext/treeviewer/ExternalTreeI.java @@ -1,15 +1,37 @@ package jalview.ext.treeviewer; +import java.util.Iterator; + public interface ExternalTreeI { - public void setTreeName(String name); - - public T getOriginalTree(); - public ExternalTreeNodeI getRoot(); public ExternalTreeNodeI getNodeWithName(String name); + public ExternalTreeNodeI getFurthestNode(); + public String[] getAllLeafNames(); + public void setTreeName(String treeTitle); + + public void setRerootable(boolean b); + + public void setRooted(boolean b); + + public boolean isEmpty(); + + public String getTreeName(); + + public void setRoot(ExternalTreeNodeI rootNode); + + public double getHeight(boolean adjustForCollapsedSubtrees); + + public Iterator iterateInPreOrder(); + + public Iterator iterateInLevelOrder(); + + public Iterator iterateInPostOrder(); + + public ExternalTreeFrame createInstanceFromTree(String instanceTitle); + } diff --git a/src/jalview/ext/treeviewer/ExternalTreeIteratorI.java b/src/jalview/ext/treeviewer/ExternalTreeIteratorI.java new file mode 100644 index 0000000..e5a39f6 --- /dev/null +++ b/src/jalview/ext/treeviewer/ExternalTreeIteratorI.java @@ -0,0 +1,6 @@ +package jalview.ext.treeviewer; + +public interface ExternalTreeIteratorI +{ + +} diff --git a/src/jalview/ext/treeviewer/ExternalTreeNodeI.java b/src/jalview/ext/treeviewer/ExternalTreeNodeI.java index 34f45bd..1481b06 100644 --- a/src/jalview/ext/treeviewer/ExternalTreeNodeI.java +++ b/src/jalview/ext/treeviewer/ExternalTreeNodeI.java @@ -1,12 +1,38 @@ package jalview.ext.treeviewer; +import jalview.datamodel.SequenceI; + +import java.awt.Color; import java.util.List; public interface ExternalTreeNodeI { - public N getOriginalNode(); + final static int nodeCount = 0; public String getNodeName(); - public List getChildren(); + public List getAllDescendants(); + + public List getExternalDescendants(); + + public List getDirectChildren(); + + public void setSequence(SequenceI seq); + + public SequenceI getSequence(); + + public void addAsChild(ExternalTreeNodeI childNode); + + public long getId(); + + public float getXcoord(); + + public void setBranchColor(Color branchColor); + + public boolean isInternal(); + + public static int getTotalNodes() + { + return nodeCount; + } } diff --git a/src/jalview/ext/treeviewer/ExternalTreePanel.java b/src/jalview/ext/treeviewer/ExternalTreePanel.java new file mode 100644 index 0000000..705117d --- /dev/null +++ b/src/jalview/ext/treeviewer/ExternalTreePanel.java @@ -0,0 +1,22 @@ +package jalview.ext.treeviewer; + +import java.io.File; +import java.util.Set; + +import javax.swing.JPanel; + +public abstract class ExternalTreePanel extends JPanel +{ + + public abstract void setTreeFile(File file); + + public abstract File getTreeFile(); + + public abstract ExternalTreeI getTree(); + + public abstract ExternalTreeNodeI findNode(int x, int y); + + public abstract void setMatchingNodes(Set matchingNodes); + + public abstract Set getMatchingNodes(); +} diff --git a/src/jalview/ext/treeviewer/ExternalTreePanelI.java b/src/jalview/ext/treeviewer/ExternalTreePanelI.java deleted file mode 100644 index c488683..0000000 --- a/src/jalview/ext/treeviewer/ExternalTreePanelI.java +++ /dev/null @@ -1,6 +0,0 @@ -package jalview.ext.treeviewer; - -public interface ExternalTreePanelI -{ - -} diff --git a/src/jalview/ext/treeviewer/ExternalTreeViewerBindingI.java b/src/jalview/ext/treeviewer/ExternalTreeViewerBindingI.java index 4fc267a..de76b82 100644 --- a/src/jalview/ext/treeviewer/ExternalTreeViewerBindingI.java +++ b/src/jalview/ext/treeviewer/ExternalTreeViewerBindingI.java @@ -20,7 +20,9 @@ */ package jalview.ext.treeviewer; +import jalview.commands.CommandI; import jalview.datamodel.SequenceI; +import jalview.gui.AlignmentPanel; import jalview.structure.SelectionListener; import jalview.structure.SelectionSource; @@ -30,16 +32,13 @@ import java.awt.event.MouseListener; /** * * Interface for binding a tree viewer to Jalview alignments. Assumes a tree - * viewer will both want to receive and send selection events. Note that this - * will take anything as a TreeNode object as no assumptions can be made about - * the inheritance structure of the TreeNode (besides being an Object). + * viewer will both want to receive and send selection events. * * @author kjvanderheide * - * @param - * Tree node object. + * */ -public interface ExternalTreeViewerBindingI +public interface ExternalTreeViewerBindingI extends ActionListener, MouseListener, SelectionListener, SelectionSource { @@ -48,14 +47,16 @@ public interface ExternalTreeViewerBindingI * corresponding sequence in the Jalview alignment view. If an internal node * is selected all child sequences get highlighted as well. */ - public void showNodeSelectionOnAlign(N node); + public void showNodeSelectionOnAlign(ExternalTreeNodeI node); public void treeSelectionChanged(SequenceI sequence); - public void showMatchingSequence(N nodeToMatch); + public void showMatchingSequence(ExternalTreeNodeI nodeToMatch); - public void showMatchingChildSequences(N parentNode); + public void showMatchingChildSequences(ExternalTreeNodeI parentNode); public void sortByTree_actionPerformed(); + public CommandI sortAlignmentIn(AlignmentPanel alignPanel); + } diff --git a/src/jalview/ext/treeviewer/ExternalTreeViewerConfigI.java b/src/jalview/ext/treeviewer/ExternalTreeViewerConfigI.java new file mode 100644 index 0000000..7617c97 --- /dev/null +++ b/src/jalview/ext/treeviewer/ExternalTreeViewerConfigI.java @@ -0,0 +1,6 @@ +package jalview.ext.treeviewer; + +public interface ExternalTreeViewerConfigI +{ + +} diff --git a/src/jalview/ext/treeviewer/ExternalTreeViewerFrameI.java b/src/jalview/ext/treeviewer/ExternalTreeViewerFrameI.java deleted file mode 100644 index bc1924a..0000000 --- a/src/jalview/ext/treeviewer/ExternalTreeViewerFrameI.java +++ /dev/null @@ -1,7 +0,0 @@ -package jalview.ext.treeviewer; - -public interface ExternalTreeViewerI -{ - public ExternalTreePanelI getTreePanel(); - -} diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 84e02c7..184ffeb 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -62,9 +62,10 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.ext.archaeopteryx.AptxInit; -import jalview.ext.archaeopteryx.JalviewBinding; import jalview.ext.forester.io.SupportedTreeFileFilter; import jalview.ext.forester.io.TreeParser; +import jalview.ext.treeviewer.ExternalTreeFrame; +import jalview.ext.treeviewer.ExternalTreeViewerBindingI; import jalview.gui.ColourMenuHelper.ColourChangeListener; import jalview.gui.ViewSelectionMenu.ViewSetProvider; import jalview.io.AlignmentProperties; @@ -141,6 +142,7 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.StringTokenizer; import java.util.Vector; @@ -156,7 +158,6 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; -import org.forester.archaeopteryx.MainFrame; import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient; import org.forester.archaeopteryx.webservices.WebservicesManager; @@ -3764,7 +3765,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .get(viewport.getSequenceSetId()); List treePanels = new ArrayList<>(); - Map aptxFrames = AptxInit.getAllAptxFrames(); + Map aptxFrames = AptxInit + .getAllAptxFrames(); for (Component comp : comps) { @@ -3784,19 +3786,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sortByTreeMenu.setVisible(true); - for (Map.Entry aptxFrameWithBinding : aptxFrames + for (Entry aptxFrameWithBinding : aptxFrames .entrySet()) { - MainFrame aptxFrame = aptxFrameWithBinding.getKey(); - JalviewBinding binding = aptxFrameWithBinding.getValue(); + ExternalTreeFrame aptxFrame = aptxFrameWithBinding.getKey(); + ExternalTreeViewerBindingI binding = aptxFrameWithBinding.getValue(); // future support for multiple tabs // for (org.forester.archaeopteryx.TreePanel aptxTree : aptxFrame // .getMainPanel().getTreePanels()) { final JMenuItem item = new JMenuItem( - aptxFrame.getMainPanel().getCurrentTreePanel() - .getPhylogeny().getName()); + aptxFrame.getTree().getTreeName()); item.addActionListener(new ActionListener() { diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index d40ce8d..3ff0b75 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -43,6 +43,7 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.ext.treeviewer.ExternalTreeI; import jalview.renderer.ResidueShader; import jalview.renderer.ResidueShaderI; import jalview.schemes.ColourSchemeI; @@ -956,6 +957,7 @@ public abstract class AlignmentViewport changeSupport = null; ranges = null; currentTree = null; + currentExtTree = null; selectionGroup = null; setAlignment(null); } @@ -2879,6 +2881,8 @@ public abstract class AlignmentViewport protected TreeModel currentTree = null; + protected ExternalTreeI currentExtTree = null; + @Override public boolean hasSearchResults() { @@ -2949,4 +2953,15 @@ public abstract class AlignmentViewport { return currentTree; } + + public ExternalTreeI getCurrentExtTree() + { + return currentExtTree; + } + + public void setCurrentExtTree(ExternalTreeI externalTree) + { + currentExtTree = externalTree; + } + } -- 1.7.10.2