1 package jalview.ext.archaeopteryx;
3 import jalview.analysis.TreeBuilder;
4 import jalview.datamodel.SequenceI;
5 import jalview.ext.treeviewer.ExternalTreeBuilderI;
6 import jalview.ext.treeviewer.ExternalTreeViewerBindingI;
7 import jalview.gui.Desktop;
8 import jalview.gui.JvOptionPane;
9 import jalview.util.MessageManager;
10 import jalview.viewmodel.AlignmentViewport;
12 import java.awt.Dimension;
14 import java.io.FileNotFoundException;
15 import java.io.IOException;
16 import java.net.MalformedURLException;
18 import java.util.HashMap;
21 import org.forester.archaeopteryx.AptxUtil;
22 import org.forester.archaeopteryx.Archaeopteryx;
23 import org.forester.archaeopteryx.Configuration;
24 import org.forester.archaeopteryx.MainFrame;
25 import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;
26 import org.forester.archaeopteryx.webservices.WebserviceUtil;
27 import org.forester.archaeopteryx.webservices.WebservicesManager;
28 import org.forester.io.parsers.PhylogenyParser;
29 import org.forester.io.parsers.nexus.NexusPhylogeniesParser;
30 import org.forester.io.parsers.nhx.NHXParser;
31 import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
32 import org.forester.io.parsers.phyloxml.PhyloXmlParser;
33 import org.forester.io.parsers.tol.TolParser;
34 import org.forester.io.parsers.util.ParserUtils;
35 import org.forester.phylogeny.Phylogeny;
36 import org.forester.phylogeny.PhylogenyMethods;
37 import org.forester.phylogeny.PhylogenyNode;
38 import org.forester.phylogeny.data.Identifier;
39 import org.forester.util.ForesterUtil;
42 * Static class for creating Archaeopteryx tree viewer instances from calculated
43 * trees and letting them be bound to Jalview.
45 * @author kjvanderheide
48 public final class AptxInit
51 private final static Configuration APTX_CONFIG = new Configuration(
52 "_aptx_jalview_configuration_file", false, false, false);
54 private final static boolean VALIDATE_PHYLOXML_XSD = APTX_CONFIG
55 .isValidatePhyloXmlAgainstSchema();
57 private final static boolean REPLACE_NHX_UNDERSCORES = APTX_CONFIG
58 .isReplaceUnderscoresInNhParsing();
60 private final static boolean INTERNAL_NUMBERS_AS_CONFIDENCE = APTX_CONFIG
61 .isInternalNumberAreConfidenceForNhParsing();
63 private final static boolean MIDPOINT_REROOT = APTX_CONFIG
66 private final static NHXParser.TAXONOMY_EXTRACTION TAXONOMY_EXTRACTION = APTX_CONFIG
67 .getTaxonomyExtraction();
69 private static Map<MainFrame, JalviewBinding> activeAptx = new HashMap<>();
73 public static MainFrame createInstanceFromCalculation(
74 final TreeBuilder calculatedTree)
76 ExternalTreeBuilderI<Phylogeny, PhylogenyNode> aptxTreeBuilder = new AptxTreeBuilder(
79 Phylogeny aptxTree = aptxTreeBuilder.buildTree();
81 MainFrame aptxApp = createAptxFrame(aptxTree,
82 calculatedTree.getAvport(), null);
88 * Refactored from Archaeopteryx.main
94 * @throws FileNotFoundException
96 public static MainFrame[] createInstancesFromFile(String filePath,
97 AlignmentViewport viewport)
98 throws FileNotFoundException, IOException
100 File treeFile = new File(filePath);
101 final String err = ForesterUtil.isReadableFile(treeFile);
102 if (!ForesterUtil.isEmpty(err))
104 JvOptionPane.showMessageDialog(Desktop.desktop, err,
105 MessageManager.getString("label.problem_reading_tree_file"),
106 JvOptionPane.WARNING_MESSAGE);
109 if (Desktop.instance != null)
111 Desktop.instance.startLoading(filePath);
113 boolean nhx_or_nexus = false;
114 final PhylogenyParser parser = ParserUtils.createParserDependingOnFileType(
115 treeFile, VALIDATE_PHYLOXML_XSD);
116 if (parser instanceof NHXParser)
119 final NHXParser nhx = (NHXParser) parser;
120 nhx.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
121 nhx.setIgnoreQuotes(false);
122 nhx.setTaxonomyExtraction(TAXONOMY_EXTRACTION);
124 else if (parser instanceof NexusPhylogeniesParser)
127 final NexusPhylogeniesParser nex = (NexusPhylogeniesParser) parser;
128 nex.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
129 nex.setIgnoreQuotes(false);
131 else if (parser instanceof PhyloXmlParser)
133 if ( VALIDATE_PHYLOXML_XSD ) {
134 JvOptionPane.showInternalMessageDialog( null,
135 ForesterUtil.wordWrap(
136 "phyloXML XSD-based validation is turned off [enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file]",
139 JvOptionPane.WARNING_MESSAGE );
142 Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser, treeFile);
143 MainFrame[] aptxFrames = new MainFrame[trees.length];
146 for (int i = 0; i < trees.length; i++)
148 Phylogeny tree = trees[i];
150 if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE)
152 PhylogenyMethods.transferInternalNodeNamesToConfidence(tree, "");
154 String treeTitle = treeFile.getName() + "[" + i + "]";
155 tree.setName(treeTitle);
156 aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle);
159 if (Desktop.instance != null)
161 Desktop.instance.stopLoading();
167 public static MainFrame[] createInstancesFromUrl(URL treeUrl,
168 AlignmentViewport viewport)
169 throws FileNotFoundException, IOException, RuntimeException
172 String treeTitle = treeUrl.getFile();
173 if (Desktop.instance != null)
175 Desktop.instance.startLoading(treeTitle);
177 Phylogeny[] trees = AptxUtil.readPhylogeniesFromUrl(treeUrl,
178 VALIDATE_PHYLOXML_XSD,
179 REPLACE_NHX_UNDERSCORES, INTERNAL_NUMBERS_AS_CONFIDENCE,
180 TAXONOMY_EXTRACTION, MIDPOINT_REROOT);
182 MainFrame[] aptxFrames = new MainFrame[trees.length];
183 for (int i = 0; i < trees.length; i++)
185 Phylogeny tree = trees[i];
186 aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle);
189 if (Desktop.instance != null)
191 Desktop.instance.stopLoading();
199 * Refactored from Forester's UrlTreeReader, this can be more efficient
201 * @param databaseIndex
205 public static MainFrame[] createInstancesFromDb(int databaseIndex,
206 AlignmentViewport viewport, String defaultIdentifier)
210 Phylogeny[] trees = null;
211 final WebservicesManager webservices_manager = WebservicesManager
213 final PhylogeniesWebserviceClient client = webservices_manager
214 .getAvailablePhylogeniesWebserviceClient(databaseIndex);
215 String identifier = JvOptionPane.showInternalInputDialog(
217 client.getInstructions() + "\n(Reference: "
218 + client.getReference() + ")",
219 client.getDescription(), JvOptionPane.QUESTION_MESSAGE, null,
220 null, defaultIdentifier).toString();
222 if ((identifier != null) && (identifier.trim().length() > 0))
224 if (Desktop.instance != null)
226 Desktop.instance.startLoading(identifier);
229 identifier = identifier.trim();
230 if (client.isQueryInteger())
232 identifier = identifier.replaceAll("^\\D+", "");
237 id = Integer.parseInt(identifier);
238 } catch (final NumberFormatException e)
240 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
241 "Identifier is expected to be a number",
242 "Can not open URL", JvOptionPane.ERROR_MESSAGE);
243 return new MainFrame[0];
245 identifier = id + "";
247 boolean exception = false;
250 String url_str = client.getUrl();
251 url_str = url_str.replaceFirst(
252 PhylogeniesWebserviceClient.QUERY_PLACEHOLDER, identifier);
253 url = new URL(url_str);
254 PhylogenyParser parser = null;
255 switch (client.getReturnFormat())
257 case TOL_XML_RESPONSE:
258 parser = new TolParser();
261 parser = new NexusPhylogeniesParser();
262 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
265 parser = new NexusPhylogeniesParser();
266 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
267 ((NexusPhylogeniesParser) parser)
268 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
271 parser = new NexusPhylogeniesParser();
272 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
273 ((NexusPhylogeniesParser) parser)
274 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
277 parser = new NHXParser();
279 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
280 ((NHXParser) parser).setReplaceUnderscores(true);
281 ((NHXParser) parser).setGuessRootedness(true);
283 case NH_EXTRACT_TAXONOMY:
284 parser = new NHXParser();
285 ((NHXParser) parser).setTaxonomyExtraction(
286 NHXParser.TAXONOMY_EXTRACTION.AGGRESSIVE);
287 ((NHXParser) parser).setReplaceUnderscores(false);
288 ((NHXParser) parser).setGuessRootedness(true);
291 parser = new NHXParser();
292 ((NHXParser) parser).setTaxonomyExtraction(
293 NHXParser.TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT);
294 ((NHXParser) parser).setReplaceUnderscores(false);
295 ((NHXParser) parser).setGuessRootedness(true);
298 parser = new NHXParser();
300 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
301 ((NHXParser) parser).setReplaceUnderscores(false);
302 ((NHXParser) parser).setGuessRootedness(true);
305 parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
308 throw new IllegalArgumentException(
309 "unknown format: " + client.getReturnFormat());
312 // if (_main_frame.getMainPanel().getCurrentTreePanel() != null)
314 // _main_frame.getMainPanel().getCurrentTreePanel().setWaitCursor();
318 // _main_frame.getMainPanel().setWaitCursor();
320 trees = ForesterUtil.readPhylogeniesFromUrl(url, parser);
321 } catch (final MalformedURLException e)
324 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
325 "Malformed URL: " + url + "\n" + e.getLocalizedMessage(),
326 "Malformed URL", JvOptionPane.ERROR_MESSAGE);
327 } catch (final IOException e)
330 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
331 "Could not read from " + url + "\n"
332 + e.getLocalizedMessage(),
333 "Failed to read tree from " + client.getName() + " for "
335 JvOptionPane.ERROR_MESSAGE);
336 } catch (final NumberFormatException e)
339 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
340 "Could not read from " + url + "\n"
341 + e.getLocalizedMessage(),
342 "Failed to read tree from " + client.getName() + " for "
344 JvOptionPane.ERROR_MESSAGE);
345 } catch (final Exception e)
349 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
350 e.getLocalizedMessage(), "Unexpected Exception",
351 JvOptionPane.ERROR_MESSAGE);
354 // if (_main_frame.getCurrentTreePanel() != null)
356 // _main_frame.getCurrentTreePanel().setArrowCursor();
360 // _main_frame.getMainPanel().setArrowCursor();
363 if ((trees != null) && (trees.length > 0))
365 for (final Phylogeny phylogeny : trees)
367 if (!phylogeny.isEmpty())
369 if (client.getName().equals(WebserviceUtil.TREE_FAM_NAME))
371 phylogeny.setRerootable(false);
372 phylogeny.setRooted(true);
374 if (client.getProcessingInstructions() != null)
378 WebserviceUtil.processInstructions(client, phylogeny);
379 } catch (final PhyloXmlDataFormatException e)
381 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
382 "Error:\n" + e.getLocalizedMessage(), "Error",
383 JvOptionPane.ERROR_MESSAGE);
386 if (client.getNodeField() != null)
390 PhylogenyMethods.transferNodeNameToField(phylogeny,
391 client.getNodeField(), false);
392 } catch (final PhyloXmlDataFormatException e)
394 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
395 "Error:\n" + e.getLocalizedMessage(), "Error",
396 JvOptionPane.ERROR_MESSAGE);
399 phylogeny.setIdentifier(
400 new Identifier(identifier, client.getName()));
401 // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu());
402 // _main_frame.getMenuBarOfMainFrame()
403 // .add(_main_frame.getHelpMenu());
404 // _main_frame.getMainPanel().addPhylogenyInNewTab(phylogeny,
405 // _main_frame.getConfiguration(),
406 // new File(url.getFile()).getName(), url.toString());
408 MainFrame aptxApp = createAptxFrame(phylogeny, viewport,
410 String my_name_for_file = "";
411 if (!ForesterUtil.isEmpty(phylogeny.getName()))
413 my_name_for_file = new String(phylogeny.getName())
414 .replaceAll(" ", "_");
416 else if (phylogeny.getIdentifier() != null)
418 final StringBuffer sb = new StringBuffer();
420 .isEmpty(phylogeny.getIdentifier().getProvider()))
422 sb.append(phylogeny.getIdentifier().getProvider());
425 sb.append(phylogeny.getIdentifier().getValue());
426 my_name_for_file = new String(
427 sb.toString().replaceAll(" ", "_"));
429 // _main_frame.getMainPanel().getCurrentTreePanel()
430 // .setTreeFile(new File(my_name_for_file));
431 AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings(
432 phylogeny, aptxApp.getMainPanel().getControlPanel(),
434 // _main_frame.getMainPanel().getControlPanel().showWhole();
436 aptxApp.activateSaveAllIfNeeded();
442 JvOptionPane.showMessageDialog(null,
443 ForesterUtil.wordWrap(
444 "Failed to read in tree(s) from [" + url + "]", 80),
445 "Error", JvOptionPane.ERROR_MESSAGE);
447 if ((trees != null) && (trees.length > 0))
451 JvOptionPane.showMessageDialog(null,
452 ForesterUtil.wordWrap("Successfully read in "
453 + trees.length + " tree(s) from [" + url + "]",
455 "Success", JvOptionPane.INFORMATION_MESSAGE);
456 } catch (final Exception e)
458 // Not important if this fails, do nothing.
460 // _main_frame.getContentPane().repaint();
467 if (Desktop.instance != null)
469 Desktop.instance.stopLoading();
480 public static MainFrame createAptxFrame(
481 final Phylogeny aptxTree,
482 final AlignmentViewport jalviewAlignport, String treeTitle)
484 MainFrame aptxApp = Archaeopteryx.createApplication(aptxTree,
485 APTX_CONFIG, treeTitle);
487 LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation(
488 jalviewAlignport.getAlignment().getSequencesArray(), aptxTree);
489 bindAptxNodes.associateLeavesToSequences();
491 bindNodesToJalviewSequences(aptxApp, jalviewAlignport,
492 bindAptxNodes.getAlignmentWithNodes(),
493 bindAptxNodes.getNodesWithAlignment());
494 bindTreeViewFrameToJalview(aptxApp);
499 // private static void addPartitioningSlider(MainFrame aptxFrame)
501 // JSlider slider = new JSlider();
506 public static ExternalTreeViewerBindingI<?> bindNodesToJalviewSequences(
507 final MainFrame aptxApp,
508 final AlignmentViewport jalviewAlignViewport,
509 final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
510 final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
512 JalviewBinding treeBinding = new JalviewBinding(aptxApp,
513 jalviewAlignViewport,
514 alignMappedToNodes, nodesMappedToAlign);
515 activeAptx.put(aptxApp, treeBinding);
520 public static MainFrame bindTreeViewFrameToJalview(
521 final MainFrame aptxApp)
525 aptxApp.setMinimumSize(new Dimension(width, height));
526 // aptxApp.setFont(Desktop.instance.getFont());
527 // aptxApp.getMainPanel().setFont(Desktop.instance.getFont());
528 String frameTitle = MessageManager.getString("label.aptx_title");
529 File treeFile = aptxApp.getMainPanel().getCurrentTreePanel()
531 if (treeFile != null)
533 frameTitle += MessageManager.formatMessage("label.aptx_title_append",
535 { treeFile.getAbsolutePath() });
537 Desktop.addInternalFrame(aptxApp, frameTitle, true, width, height, true,
543 public static Map<MainFrame, JalviewBinding> getAllAptxFrames()