From 45cc7240488ccc4ec95bdcef7f681dd703a76a85 Mon Sep 17 00:00:00 2001 From: kjvdheide Date: Wed, 10 Jan 2018 10:45:02 +0000 Subject: [PATCH] JAL-2795 calculated trees are now passed along as Newick strings --- src/jalview/ext/archaeopteryx/AptxInit.java | 79 +++-- src/jalview/ext/archaeopteryx/AptxTreeBuilder.java | 334 ++++++++++---------- src/jalview/gui/CalculationChooser.java | 26 +- 3 files changed, 248 insertions(+), 191 deletions(-) diff --git a/src/jalview/ext/archaeopteryx/AptxInit.java b/src/jalview/ext/archaeopteryx/AptxInit.java index ba34213..11ee71e 100644 --- a/src/jalview/ext/archaeopteryx/AptxInit.java +++ b/src/jalview/ext/archaeopteryx/AptxInit.java @@ -1,15 +1,14 @@ package jalview.ext.archaeopteryx; -import jalview.analysis.TreeBuilder; import jalview.ext.forester.io.UtilityMethods; import jalview.ext.treeviewer.LoadedTreeAssociationI; import jalview.ext.treeviewer.LoadedTreeSequenceAssociation; -import jalview.ext.treeviewer.TreeBuilderI; import jalview.ext.treeviewer.TreeFrameI; import jalview.ext.treeviewer.TreeI; import jalview.ext.treeviewer.TreeViewerUtils; import jalview.gui.Desktop; import jalview.gui.JvOptionPane; +import jalview.io.NewickFile; import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; @@ -34,6 +33,8 @@ import org.forester.io.parsers.util.ParserUtils; import org.forester.phylogeny.Phylogeny; import org.forester.phylogeny.PhylogenyMethods; import org.forester.phylogeny.data.Identifier; +import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory; +import org.forester.phylogeny.factories.PhylogenyFactory; import org.forester.util.ForesterUtil; /** @@ -74,20 +75,60 @@ public final class AptxInit private final static NHXParser.TAXONOMY_EXTRACTION TAXONOMY_EXTRACTION = APTX_CONFIG .getTaxonomyExtraction(); - public static TreeFrameI createInstanceFromCalculation( - final TreeBuilder calculatedTree) + // public static TreeFrameI createInstanceFromCalculation( + // final TreeBuilder calculatedTree) + // { + // TreeBuilderI aptxTreeBuilder = new AptxTreeBuilder( + // calculatedTree); + // + // TreeI aptxTree = aptxTreeBuilder.buildTree(); + // + // TreeFrameI aptxApp = createAptxFrame(aptxTree, + // calculatedTree.getAvport(), null); + // + // return aptxApp; + // } + + public static TreeFrameI[] createInstances(String treeTitle, + Object source, PhylogenyParser parser, AlignmentViewport viewport) + throws IOException { - TreeBuilderI aptxTreeBuilder = new AptxTreeBuilder( - calculatedTree); + TreeFrameI[] aptxFrames = null; + PhylogenyFactory parserFact = ParserBasedPhylogenyFactory.getInstance(); + Phylogeny[] trees = parserFact.create(source, parser); + aptxFrames = new TreeFrameI[trees.length]; + + for (int i = 0; i < trees.length; i++) + { + Phylogeny aptxPhylogeny = trees[i]; - TreeI aptxTree = aptxTreeBuilder.buildTree(); + // if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE) + // { + // PhylogenyMethods + // .transferInternalNodeNamesToConfidence(aptxPhylogeny, ""); + // } + aptxPhylogeny.setName(treeTitle); + aptxFrames[i] = createAptxFrame(aptxPhylogeny, viewport, treeTitle); + + } + if (Desktop.instance != null) + { + Desktop.instance.stopLoading(); + } + + return aptxFrames; - TreeFrameI aptxApp = createAptxFrame(aptxTree, - calculatedTree.getAvport(), null); - - return aptxApp; } + /** + * Refactored from Archaeopteryx.main + * + * @param filePath + * @param viewport + * @return + * @throws IOException + * @throws FileNotFoundException + */ public static TreeFrameI[] createInstancesFromFile(File treeFile, AlignmentViewport viewport) throws FileNotFoundException, IOException @@ -155,15 +196,7 @@ public final class AptxInit return aptxFrames; } - /** - * Refactored from Archaeopteryx.main - * - * @param filePath - * @param viewport - * @return - * @throws IOException - * @throws FileNotFoundException - */ + public static TreeFrameI[] createInstancesFromFile( String filePath, AlignmentViewport viewport) @@ -174,6 +207,12 @@ public final class AptxInit } + public static TreeFrameI[] createInstancesFromFile(NewickFile newickFile, + AlignmentViewport viewport) + { + return null; + } + public static TreeFrameI[] createInstancesFromUrl(URL treeUrl, AlignmentViewport viewport) diff --git a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java index 9dff141..1be7da3 100644 --- a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java +++ b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java @@ -1,167 +1,167 @@ -package jalview.ext.archaeopteryx; - -import jalview.analysis.TreeBuilder; -import jalview.datamodel.SequenceI; -import jalview.ext.forester.ForesterMatrix; -import jalview.ext.treeviewer.TreeBuilderI; -import jalview.ext.treeviewer.TreeI; -import jalview.ext.treeviewer.TreeNodeI; -import jalview.util.MappingUtils; -import jalview.util.MessageManager; - -import java.util.HashMap; -import java.util.Map; - -import org.forester.evoinference.matrix.distance.DistanceMatrix; -import org.forester.phylogeny.Phylogeny; -import org.forester.phylogeny.PhylogenyNode; - -/** - * Class for converting trees made in Jalview (through TreeBuilder) to trees - * compatible with Forester (Phylogeny objects). - * - * Note that this currently demands a 1:1 relationship between tree nodes and - * the sequences used for generating them. - * - * @author kjvanderheide - * - */ -public class AptxTreeBuilder - implements TreeBuilderI -{ - protected final SequenceI[] sequences; - - protected final DistanceMatrix distances; - - protected final TreeBuilder jalviewTree; - - public String treeTitle; - - private final TreeI aptxTree; - - private TreeNodeI rootNode; - - private final Map alignmentWithNodes; - - private final Map nodesWithAlignment; - - public AptxTreeBuilder(final TreeBuilder calculatedTree) - { - jalviewTree = calculatedTree; - sequences = jalviewTree.getSequences(); - distances = ForesterMatrix.convertJalviewToForester( - jalviewTree.getDistances(), sequences); - - aptxTree = new Tree(new Phylogeny()); - rootNode = TreeNode.getUniqueWrapper(new PhylogenyNode()); - - int amountOfSequences = distances.getSize(); - alignmentWithNodes = new HashMap<>(amountOfSequences); - nodesWithAlignment = new HashMap<>(amountOfSequences); - - - } - - @Override - public TreeI buildTree(final TreeNodeI treeRoot) - { - - if (treeRoot != null) - { - rootNode = treeRoot; - } - - buildTree(); - - return aptxTree; - - } - - - @Override - public TreeI buildTree() - { - - for (SequenceI sequence : sequences) - { - - TreeNodeI sequenceNode = TreeNode - .getUniqueWrapper( - new PhylogenyNode(sequence.getName())); - - sequenceNode.setSequence(sequence); - - MappingUtils.putWithDuplicationCheck(nodesWithAlignment, - sequenceNode, sequence); - MappingUtils.putWithDuplicationCheck(alignmentWithNodes, - sequence, sequenceNode); - rootNode.addAsChild(sequenceNode); - } - - - aptxTree.setRoot(rootNode); - - treeTitle = generateTreeName(); - aptxTree.setTreeName(treeTitle); - - return aptxTree; - - } - - @Override - public Map getAlignmentBoundNodes() - { - return alignmentWithNodes; - } - - @Override - public Map getNodesBoundAlignment() - { - return nodesWithAlignment; - } - - - /** - * Formats a localised title for the tree panel, like - *

- * Neighbour Joining Using BLOSUM62 - *

- * For a tree loaded from file, just uses the file name - * - * @return - */ - @Override - public String generateTreeName() // Move this and add selection region to the - // title when applicable - { - if (treeTitle != null) // will currently never happen, loaded tree file will - // take a different path - { - return treeTitle; - } - else - { - /* - * i18n description of Neighbour Joining or Average Distance method - */ - String treecalcnm = MessageManager - .getString("label.tree_calc_" + jalviewTree.getClass() - .getSimpleName().substring(0, 2).toLowerCase()); - /* - * short score model name (long description can be too long) - */ - String smn = jalviewTree.getScoreModel().getName(); - - /* - * put them together as Using - */ - final String ttl = MessageManager - .formatMessage("label.treecalc_title", treecalcnm, smn); - return ttl; - } - } - - - - -} +// package jalview.ext.archaeopteryx; +// +// import jalview.analysis.TreeBuilder; +// import jalview.datamodel.SequenceI; +// import jalview.ext.forester.ForesterMatrix; +// import jalview.ext.treeviewer.TreeBuilderI; +// import jalview.ext.treeviewer.TreeI; +// import jalview.ext.treeviewer.TreeNodeI; +// import jalview.util.MappingUtils; +// import jalview.util.MessageManager; +// +// import java.util.HashMap; +// import java.util.Map; +// +// import org.forester.evoinference.matrix.distance.DistanceMatrix; +// import org.forester.phylogeny.Phylogeny; +// import org.forester.phylogeny.PhylogenyNode; +// +/// ** +// * Class for converting trees made in Jalview (through TreeBuilder) to trees +// * compatible with Forester (Phylogeny objects). +// * +// * Note that this currently demands a 1:1 relationship between tree nodes and +// * the sequences used for generating them. +// * +// * @author kjvanderheide +// * +// */ +// public class AptxTreeBuilder +// implements TreeBuilderI +// { +// protected final SequenceI[] sequences; +// +// protected final DistanceMatrix distances; +// +// protected final TreeBuilder jalviewTree; +// +// public String treeTitle; +// +// private final TreeI aptxTree; +// +// private TreeNodeI rootNode; +// +// private final Map alignmentWithNodes; +// +// private final Map nodesWithAlignment; +// +// public AptxTreeBuilder(final TreeBuilder calculatedTree) +// { +// jalviewTree = calculatedTree; +// sequences = jalviewTree.getSequences(); +// distances = ForesterMatrix.convertJalviewToForester( +// jalviewTree.getDistances(), sequences); +// +// aptxTree = new Tree(new Phylogeny()); +// rootNode = TreeNode.getUniqueWrapper(new PhylogenyNode()); +// +// int amountOfSequences = distances.getSize(); +// alignmentWithNodes = new HashMap<>(amountOfSequences); +// nodesWithAlignment = new HashMap<>(amountOfSequences); +// +// +// } +// +// @Override +// public TreeI buildTree(final TreeNodeI treeRoot) +// { +// +// if (treeRoot != null) +// { +// rootNode = treeRoot; +// } +// +// buildTree(); +// +// return aptxTree; +// +// } +// +// +// @Override +// public TreeI buildTree() +// { +// +// for (SequenceI sequence : sequences) +// { +// +// TreeNodeI sequenceNode = TreeNode +// .getUniqueWrapper( +// new PhylogenyNode(sequence.getName())); +// +// sequenceNode.setSequence(sequence); +// +// MappingUtils.putWithDuplicationCheck(nodesWithAlignment, +// sequenceNode, sequence); +// MappingUtils.putWithDuplicationCheck(alignmentWithNodes, +// sequence, sequenceNode); +// rootNode.addAsChild(sequenceNode); +// } +// +// +// aptxTree.setRoot(rootNode); +// +// treeTitle = generateTreeName(); +// aptxTree.setTreeName(treeTitle); +// +// return aptxTree; +// +// } +// +// @Override +// public Map getAlignmentBoundNodes() +// { +// return alignmentWithNodes; +// } +// +// @Override +// public Map getNodesBoundAlignment() +// { +// return nodesWithAlignment; +// } +// +// +// /** +// * Formats a localised title for the tree panel, like +// *

+// * Neighbour Joining Using BLOSUM62 +// *

+// * For a tree loaded from file, just uses the file name +// * +// * @return +// */ +// @Override +// public String generateTreeName() // Move this and add selection region to the +// // title when applicable +// { +// if (treeTitle != null) // will currently never happen, loaded tree file will +// // take a different path +// { +// return treeTitle; +// } +// else +// { +// /* +// * i18n description of Neighbour Joining or Average Distance method +// */ +// String treecalcnm = MessageManager +// .getString("label.tree_calc_" + jalviewTree.getClass() +// .getSimpleName().substring(0, 2).toLowerCase()); +// /* +// * short score model name (long description can be too long) +// */ +// String smn = jalviewTree.getScoreModel().getName(); +// +// /* +// * put them together as Using +// */ +// final String ttl = MessageManager +// .formatMessage("label.treecalc_title", treecalcnm, smn); +// return ttl; +// } +// } +// +// +// +// +// } diff --git a/src/jalview/gui/CalculationChooser.java b/src/jalview/gui/CalculationChooser.java index f092e40..b973572 100644 --- a/src/jalview/gui/CalculationChooser.java +++ b/src/jalview/gui/CalculationChooser.java @@ -46,6 +46,7 @@ import java.awt.event.FocusListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyVetoException; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -63,6 +64,8 @@ import javax.swing.JRadioButton; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; +import org.forester.io.parsers.nhx.NHXParser; + /** * A dialog where a user can choose and action Tree or PCA calculation options */ @@ -464,6 +467,8 @@ public class CalculationChooser extends JPanel /** * Open and calculate the selected tree or PCA on 'OK' + * + * @throws IOException */ protected void calculate_actionPerformed() { @@ -477,7 +482,14 @@ public class CalculationChooser extends JPanel } else { - createTree(substitutionMatrix, params); + try + { + createTree(substitutionMatrix, params); + } catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } @@ -490,17 +502,23 @@ public class CalculationChooser extends JPanel } protected void createTree(String substitutionMatrix, - SimilarityParamsI params) + SimilarityParamsI params) throws IOException { String treeAlgo = determineTreeAlgo(); TreeCalculator treeCalculator = new TreeCalculator(treeAlgo, substitutionMatrix, params); TreeBuilder calculatedTree = treeCalculator.makeTree(af.getViewport()); - AptxInit.createInstanceFromCalculation(calculatedTree); + // AptxInit.createInstanceFromCalculation(calculatedTree); TreeModel tree = new TreeModel(calculatedTree); - openTreePanel(tree, treeAlgo, substitutionMatrix); + jalview.io.NewickFile newick = new jalview.io.NewickFile( + tree.getTopNode()); + String output = newick.print(tree.hasBootstrap(), tree.hasDistances(), + tree.hasRootDistance()); + AptxInit.createInstances(af.getTitle(), output, new NHXParser(), + af.getViewport()); + // openTreePanel(tree, treeAlgo, substitutionMatrix); } -- 1.7.10.2