X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Farchaeopteryx%2FAptxInit.java;h=3dc2e884912b88c51869785ea589b71a104b0692;hb=075c1528d363ca18476cb9f0b12709158c78fa5e;hp=4a49734b7209e6387aff4c31a24cf6a023bdef05;hpb=dd31808c17e9882806a200438d319cb1374f203c;p=jalview.git diff --git a/src/jalview/ext/archaeopteryx/AptxInit.java b/src/jalview/ext/archaeopteryx/AptxInit.java index 4a49734..3dc2e88 100644 --- a/src/jalview/ext/archaeopteryx/AptxInit.java +++ b/src/jalview/ext/archaeopteryx/AptxInit.java @@ -5,21 +5,38 @@ import jalview.datamodel.SequenceI; import jalview.ext.treeviewer.ExternalTreeBuilderI; import jalview.ext.treeviewer.ExternalTreeViewerBindingI; import jalview.gui.Desktop; +import jalview.gui.JvOptionPane; +import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; import java.awt.Dimension; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; +import java.util.HashMap; import java.util.Map; 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.archaeopteryx.webservices.WebservicesManager; +import org.forester.io.parsers.PhylogenyParser; +import org.forester.io.parsers.nexus.NexusPhylogeniesParser; import org.forester.io.parsers.nhx.NHXParser; +import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException; +import org.forester.io.parsers.phyloxml.PhyloXmlParser; +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; /** * Static class for creating Archaeopteryx tree viewer instances from calculated @@ -49,123 +66,442 @@ public final class AptxInit private final static NHXParser.TAXONOMY_EXTRACTION TAXONOMY_EXTRACTION = APTX_CONFIG .getTaxonomyExtraction(); - /** - * Test method, should generally not be used as it does not bind the tree to - * its alignment - * - * @param aptxTrees - * @return - */ - public static MainFrame createUnboundInstance(final Phylogeny aptxTree) - { - Phylogeny[] aptxTrees = { aptxTree }; - return createAptxFrame(aptxTrees); - } + private static Map activeAptx = new HashMap<>(); - // public static MainFrame createInstance(final Phylogeny[] aptxTrees, - // AlignmentViewport jalviewAlignmentView) - // { - // return createAptxFrameInJalview(aptxTrees); - // - // } - // - // public static MainFrame createInstance(final Phylogeny aptxTree, - // final AlignmentViewport jalviewAlignmentView) - // { - // Phylogeny[] aptxTrees = { aptxTree }; // future possibility to load in - // // several trees simultaneously - // return createAptxFrameInJalview(aptxTrees); - // - // } - public static MainFrame createInstance( - final TreeBuilder calculatedTree) // very dense method, to be split up + + public static MainFrame createInstanceFromCalculation( + final TreeBuilder calculatedTree) { ExternalTreeBuilderI aptxTreeBuilder = new AptxTreeBuilder( calculatedTree); Phylogeny aptxTree = aptxTreeBuilder.buildTree(); - Phylogeny[] aptxTrees = { aptxTree }; // future possibility to load in - // several trees simultaneously - MainFrame aptxApp = createAptxFrame(aptxTrees); + MainFrame aptxApp = createAptxFrame(aptxTree, + calculatedTree.getAvport(), null); - bindNodesToJalviewSequences(aptxApp, calculatedTree.getAvport(), - aptxTreeBuilder.getAlignmentBoundNodes(), - aptxTreeBuilder.getNodesBoundAlignment()); - - return bindFrameToJalview(aptxApp); - + return aptxApp; } - public static MainFrame createInstanceFromFile(String filePath, + /** + * Refactored from Archaeopteryx.main + * + * @param filePath + * @param viewport + * @return + * @throws IOException + * @throws FileNotFoundException + */ + public static MainFrame[] createInstancesFromFile(String filePath, AlignmentViewport viewport) + throws FileNotFoundException, IOException { - String[] AptxArgs = new String[] { "-c", - APTX_CONFIG.getConfigFilename(), filePath }; - MainFrame aptxApp = Archaeopteryx.main(AptxArgs); - - int tabCount = aptxApp.getMainPanel().getTabbedPane().getTabCount(); + File treeFile = new File(filePath); + final String err = ForesterUtil.isReadableFile(treeFile); + if (!ForesterUtil.isEmpty(err)) + { + JvOptionPane.showMessageDialog(Desktop.desktop, err, + MessageManager.getString("label.problem_reading_tree_file"), + JvOptionPane.WARNING_MESSAGE); + } - for (int i = 0; i < tabCount; i++) + if (Desktop.instance != null) + { + Desktop.instance.startLoading(filePath); + } + boolean nhx_or_nexus = false; + final PhylogenyParser parser = ParserUtils.createParserDependingOnFileType( + treeFile, VALIDATE_PHYLOXML_XSD); + if (parser instanceof NHXParser) + { + nhx_or_nexus = true; + final NHXParser nhx = (NHXParser) parser; + nhx.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES); + nhx.setIgnoreQuotes(false); + nhx.setTaxonomyExtraction(TAXONOMY_EXTRACTION); + } + else if (parser instanceof NexusPhylogeniesParser) + { + nhx_or_nexus = true; + final NexusPhylogeniesParser nex = (NexusPhylogeniesParser) parser; + nex.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES); + nex.setIgnoreQuotes(false); + } + else if (parser instanceof PhyloXmlParser) { - // roundabout way to select each tree because getComponentAt(i) requires - // casting to TreePanel which doesn't work - aptxApp.getMainPanel().getTabbedPane().setSelectedIndex(i); - Phylogeny tree = aptxApp.getMainPanel().getCurrentTreePanel() - .getPhylogeny(); + if ( VALIDATE_PHYLOXML_XSD ) { + JvOptionPane.showInternalMessageDialog( null, + ForesterUtil.wordWrap( + "phyloXML XSD-based validation is turned off [enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file]", + 80 ), + "Warning", + JvOptionPane.WARNING_MESSAGE ); + } + } + Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser, treeFile); + MainFrame[] aptxFrames = new MainFrame[trees.length]; - LoadedTreeAssociation bindAptxNodes = new LoadedTreeAssociation( - viewport.getAlignment().getSequencesArray(), - tree); - bindAptxNodes.associateLeavesToSequences(); + for (int i = 0; i < trees.length; i++) + { + Phylogeny tree = trees[i]; + + if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE) + { + PhylogenyMethods.transferInternalNodeNamesToConfidence(tree, ""); + } + String treeTitle = treeFile.getName() + "[" + i + "]"; + tree.setName(treeTitle); + aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle); - bindNodesToJalviewSequences(aptxApp, viewport, - bindAptxNodes.getAlignmentWithNodes(), - bindAptxNodes.getNodesWithAlignment()); } - return bindFrameToJalview(aptxApp); - } + if (Desktop.instance != null) + { + Desktop.instance.stopLoading(); + } + return aptxFrames; + } + - public static MainFrame createInstanceFromUrl(URL treeUrl, + public static MainFrame[] createInstancesFromUrl(URL treeUrl, AlignmentViewport viewport) throws FileNotFoundException, IOException, RuntimeException { + String treeTitle = treeUrl.getFile(); + if (Desktop.instance != null) + { + Desktop.instance.startLoading(treeTitle); + } Phylogeny[] trees = AptxUtil.readPhylogeniesFromUrl(treeUrl, VALIDATE_PHYLOXML_XSD, REPLACE_NHX_UNDERSCORES, INTERNAL_NUMBERS_AS_CONFIDENCE, TAXONOMY_EXTRACTION, MIDPOINT_REROOT); - MainFrame aptxApp = Archaeopteryx.createApplication(trees, APTX_CONFIG, - null); - for (Phylogeny tree : trees) + MainFrame[] aptxFrames = new MainFrame[trees.length]; + for (int i = 0; i < trees.length; i++) + { + Phylogeny tree = trees[i]; + aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle); + } + + if (Desktop.instance != null) + { + Desktop.instance.stopLoading(); + } + + return aptxFrames; + + } + + /** + * Refactored from Forester's UrlTreeReader, this can be more efficient + * + * @param databaseIndex + * @param viewport + * @return + */ + public static MainFrame[] createInstancesFromDb(int databaseIndex, + AlignmentViewport viewport, String defaultIdentifier) + { + + URL url = null; + Phylogeny[] trees = null; + final WebservicesManager webservices_manager = WebservicesManager + .getInstance(); + final PhylogeniesWebserviceClient client = webservices_manager + .getAvailablePhylogeniesWebserviceClient(databaseIndex); + String identifier = JvOptionPane.showInternalInputDialog( + Desktop.desktop, + client.getInstructions() + "\n(Reference: " + + client.getReference() + ")", + client.getDescription(), JvOptionPane.QUESTION_MESSAGE, null, + null, defaultIdentifier).toString(); + + if ((identifier != null) && (identifier.trim().length() > 0)) { - LoadedTreeAssociation bindAptxNodes = new LoadedTreeAssociation( - viewport.getAlignment().getSequencesArray(), tree); + if (Desktop.instance != null) + { + Desktop.instance.startLoading(identifier); + } + + identifier = identifier.trim(); + if (client.isQueryInteger()) + { + identifier = identifier.replaceAll("^\\D+", ""); + + int id; + try + { + id = Integer.parseInt(identifier); + } catch (final NumberFormatException e) + { + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + "Identifier is expected to be a number", + "Can not open URL", JvOptionPane.ERROR_MESSAGE); + return new MainFrame[0]; + } + identifier = id + ""; + } + boolean exception = false; + try + { + String url_str = client.getUrl(); + url_str = url_str.replaceFirst( + PhylogeniesWebserviceClient.QUERY_PLACEHOLDER, identifier); + url = new URL(url_str); + PhylogenyParser parser = null; + switch (client.getReturnFormat()) + { + case TOL_XML_RESPONSE: + parser = new TolParser(); + break; + case NEXUS: + parser = new NexusPhylogeniesParser(); + ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true); + break; + case TREEBASE_TREE: + parser = new NexusPhylogeniesParser(); + ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true); + ((NexusPhylogeniesParser) parser) + .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO); + break; + case TREEBASE_STUDY: + parser = new NexusPhylogeniesParser(); + ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true); + ((NexusPhylogeniesParser) parser) + .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO); + break; + case NH: + parser = new NHXParser(); + ((NHXParser) parser) + .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO); + ((NHXParser) parser).setReplaceUnderscores(true); + ((NHXParser) parser).setGuessRootedness(true); + break; + case NH_EXTRACT_TAXONOMY: + parser = new NHXParser(); + ((NHXParser) parser).setTaxonomyExtraction( + NHXParser.TAXONOMY_EXTRACTION.AGGRESSIVE); + ((NHXParser) parser).setReplaceUnderscores(false); + ((NHXParser) parser).setGuessRootedness(true); + break; + case PFAM: + parser = new NHXParser(); + ((NHXParser) parser).setTaxonomyExtraction( + NHXParser.TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT); + ((NHXParser) parser).setReplaceUnderscores(false); + ((NHXParser) parser).setGuessRootedness(true); + break; + case NHX: + parser = new NHXParser(); + ((NHXParser) parser) + .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO); + ((NHXParser) parser).setReplaceUnderscores(false); + ((NHXParser) parser).setGuessRootedness(true); + break; + case PHYLOXML: + parser = PhyloXmlParser.createPhyloXmlParserXsdValidating(); + break; + default: + throw new IllegalArgumentException( + "unknown format: " + client.getReturnFormat()); + } + // + // if (_main_frame.getMainPanel().getCurrentTreePanel() != null) + // { + // _main_frame.getMainPanel().getCurrentTreePanel().setWaitCursor(); + // } + // else + // { + // _main_frame.getMainPanel().setWaitCursor(); + // } + trees = ForesterUtil.readPhylogeniesFromUrl(url, parser); + } catch (final MalformedURLException e) + { + exception = true; + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + "Malformed URL: " + url + "\n" + e.getLocalizedMessage(), + "Malformed URL", JvOptionPane.ERROR_MESSAGE); + } catch (final IOException e) + { + exception = true; + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + "Could not read from " + url + "\n" + + e.getLocalizedMessage(), + "Failed to read tree from " + client.getName() + " for " + + identifier, + JvOptionPane.ERROR_MESSAGE); + } catch (final NumberFormatException e) + { + exception = true; + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + "Could not read from " + url + "\n" + + e.getLocalizedMessage(), + "Failed to read tree from " + client.getName() + " for " + + identifier, + JvOptionPane.ERROR_MESSAGE); + } catch (final Exception e) + { + exception = true; + e.printStackTrace(); + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + e.getLocalizedMessage(), "Unexpected Exception", + JvOptionPane.ERROR_MESSAGE); + } finally + { + // if (_main_frame.getCurrentTreePanel() != null) + // { + // _main_frame.getCurrentTreePanel().setArrowCursor(); + // } + // else + // { + // _main_frame.getMainPanel().setArrowCursor(); + // } + } + if ((trees != null) && (trees.length > 0)) + { + for (final Phylogeny phylogeny : trees) + { + if (!phylogeny.isEmpty()) + { + if (client.getName().equals(WebserviceUtil.TREE_FAM_NAME)) + { + phylogeny.setRerootable(false); + phylogeny.setRooted(true); + } + if (client.getProcessingInstructions() != null) + { + try + { + WebserviceUtil.processInstructions(client, phylogeny); + } catch (final PhyloXmlDataFormatException e) + { + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + "Error:\n" + e.getLocalizedMessage(), "Error", + JvOptionPane.ERROR_MESSAGE); + } + } + if (client.getNodeField() != null) + { + try + { + PhylogenyMethods.transferNodeNameToField(phylogeny, + client.getNodeField(), false); + } catch (final PhyloXmlDataFormatException e) + { + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + "Error:\n" + e.getLocalizedMessage(), "Error", + JvOptionPane.ERROR_MESSAGE); + } + } + phylogeny.setIdentifier( + new Identifier(identifier, client.getName())); + // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu()); + // _main_frame.getMenuBarOfMainFrame() + // .add(_main_frame.getHelpMenu()); + // _main_frame.getMainPanel().addPhylogenyInNewTab(phylogeny, + // _main_frame.getConfiguration(), + // new File(url.getFile()).getName(), url.toString()); + + MainFrame aptxApp = createAptxFrame(phylogeny, viewport, + url.getFile()); + String my_name_for_file = ""; + if (!ForesterUtil.isEmpty(phylogeny.getName())) + { + my_name_for_file = new String(phylogeny.getName()) + .replaceAll(" ", "_"); + } + else if (phylogeny.getIdentifier() != null) + { + final StringBuffer sb = new StringBuffer(); + if (!ForesterUtil + .isEmpty(phylogeny.getIdentifier().getProvider())) + { + sb.append(phylogeny.getIdentifier().getProvider()); + sb.append("_"); + } + sb.append(phylogeny.getIdentifier().getValue()); + my_name_for_file = new String( + sb.toString().replaceAll(" ", "_")); + } + // _main_frame.getMainPanel().getCurrentTreePanel() + // .setTreeFile(new File(my_name_for_file)); + AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings( + phylogeny, aptxApp.getMainPanel().getControlPanel(), + APTX_CONFIG); + // _main_frame.getMainPanel().getControlPanel().showWhole(); + + aptxApp.activateSaveAllIfNeeded(); + } + } + } + else if (!exception) + { + JvOptionPane.showMessageDialog(null, + ForesterUtil.wordWrap( + "Failed to read in tree(s) from [" + url + "]", 80), + "Error", JvOptionPane.ERROR_MESSAGE); + } + if ((trees != null) && (trees.length > 0)) + { + try + { + JvOptionPane.showMessageDialog(null, + ForesterUtil.wordWrap("Successfully read in " + + trees.length + " tree(s) from [" + url + "]", + 80), + "Success", JvOptionPane.INFORMATION_MESSAGE); + } catch (final Exception e) + { + // Not important if this fails, do nothing. + } + // _main_frame.getContentPane().repaint(); + } + } - bindAptxNodes.associateLeavesToSequences(); - bindNodesToJalviewSequences(aptxApp, viewport, - bindAptxNodes.getAlignmentWithNodes(), - bindAptxNodes.getNodesWithAlignment()); + System.gc(); + + if (Desktop.instance != null) + { + Desktop.instance.stopLoading(); } + return null; - return bindFrameToJalview(aptxApp); } + + public static MainFrame createAptxFrame( - final Phylogeny[] aptxTrees) + final Phylogeny aptxTree, + final AlignmentViewport jalviewAlignport, String treeTitle) { - MainFrame aptxApp = Archaeopteryx.createApplication(aptxTrees, - APTX_CONFIG, null); + MainFrame aptxApp = Archaeopteryx.createApplication(aptxTree, + APTX_CONFIG, treeTitle); + + LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation( + jalviewAlignport.getAlignment().getSequencesArray(), aptxTree); + bindAptxNodes.associateLeavesToSequences(); + + bindNodesToJalviewSequences(aptxApp, jalviewAlignport, + bindAptxNodes.getAlignmentWithNodes(), + bindAptxNodes.getNodesWithAlignment()); + bindTreeViewFrameToJalview(aptxApp); + return aptxApp; } + // private static void addPartitioningSlider(MainFrame aptxFrame) + // { + // JSlider slider = new JSlider(); + // + // + // } public static ExternalTreeViewerBindingI bindNodesToJalviewSequences( final MainFrame aptxApp, @@ -173,25 +509,41 @@ public final class AptxInit final Map alignMappedToNodes, final Map nodesMappedToAlign) { - return new JalviewBinding(aptxApp, jalviewAlignViewport, + JalviewBinding treeBinding = new JalviewBinding(aptxApp, + jalviewAlignViewport, alignMappedToNodes, nodesMappedToAlign); + activeAptx.put(aptxApp, treeBinding); + return treeBinding; } - public static MainFrame bindFrameToJalview(final MainFrame aptxApp) + public static MainFrame bindTreeViewFrameToJalview( + final MainFrame aptxApp) { int width = 400; int height = 550; aptxApp.setMinimumSize(new Dimension(width, height)); // aptxApp.setFont(Desktop.instance.getFont()); // aptxApp.getMainPanel().setFont(Desktop.instance.getFont()); - - Desktop.addInternalFrame(aptxApp, "Archaeopteryx Tree View", true, - width, height, true, true); - + String frameTitle = MessageManager.getString("label.aptx_title"); + File treeFile = aptxApp.getMainPanel().getCurrentTreePanel() + .getTreeFile(); + if (treeFile != null) + { + frameTitle += MessageManager.formatMessage("label.aptx_title_append", + new String[] + { treeFile.getAbsolutePath() }); + } + Desktop.addInternalFrame(aptxApp, frameTitle, true, width, height, true, + true); return aptxApp; } + public static Map getAllAptxFrames() + { + return activeAptx; + } + }