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)
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);
221 if ((identifier != null) && (identifier.trim().length() > 0))
223 if (Desktop.instance != null)
225 Desktop.instance.startLoading(identifier);
228 identifier = identifier.trim();
229 if (client.isQueryInteger())
231 identifier = identifier.replaceAll("^\\D+", "");
236 id = Integer.parseInt(identifier);
237 } catch (final NumberFormatException e)
239 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
240 "Identifier is expected to be a number",
241 "Can not open URL", JvOptionPane.ERROR_MESSAGE);
242 return new MainFrame[0];
244 identifier = id + "";
246 boolean exception = false;
249 String url_str = client.getUrl();
250 url_str = url_str.replaceFirst(
251 PhylogeniesWebserviceClient.QUERY_PLACEHOLDER, identifier);
252 url = new URL(url_str);
253 PhylogenyParser parser = null;
254 switch (client.getReturnFormat())
256 case TOL_XML_RESPONSE:
257 parser = new TolParser();
260 parser = new NexusPhylogeniesParser();
261 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
264 parser = new NexusPhylogeniesParser();
265 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
266 ((NexusPhylogeniesParser) parser)
267 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
270 parser = new NexusPhylogeniesParser();
271 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
272 ((NexusPhylogeniesParser) parser)
273 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
276 parser = new NHXParser();
278 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
279 ((NHXParser) parser).setReplaceUnderscores(true);
280 ((NHXParser) parser).setGuessRootedness(true);
282 case NH_EXTRACT_TAXONOMY:
283 parser = new NHXParser();
284 ((NHXParser) parser).setTaxonomyExtraction(
285 NHXParser.TAXONOMY_EXTRACTION.AGGRESSIVE);
286 ((NHXParser) parser).setReplaceUnderscores(false);
287 ((NHXParser) parser).setGuessRootedness(true);
290 parser = new NHXParser();
291 ((NHXParser) parser).setTaxonomyExtraction(
292 NHXParser.TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT);
293 ((NHXParser) parser).setReplaceUnderscores(false);
294 ((NHXParser) parser).setGuessRootedness(true);
297 parser = new NHXParser();
299 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
300 ((NHXParser) parser).setReplaceUnderscores(false);
301 ((NHXParser) parser).setGuessRootedness(true);
304 parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
307 throw new IllegalArgumentException(
308 "unknown format: " + client.getReturnFormat());
311 // if (_main_frame.getMainPanel().getCurrentTreePanel() != null)
313 // _main_frame.getMainPanel().getCurrentTreePanel().setWaitCursor();
317 // _main_frame.getMainPanel().setWaitCursor();
319 trees = ForesterUtil.readPhylogeniesFromUrl(url, parser);
320 } catch (final MalformedURLException e)
323 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
324 "Malformed URL: " + url + "\n" + e.getLocalizedMessage(),
325 "Malformed URL", JvOptionPane.ERROR_MESSAGE);
326 } catch (final IOException e)
329 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
330 "Could not read from " + url + "\n"
331 + e.getLocalizedMessage(),
332 "Failed to read tree from " + client.getName() + " for "
334 JvOptionPane.ERROR_MESSAGE);
335 } catch (final NumberFormatException e)
338 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
339 "Could not read from " + url + "\n"
340 + e.getLocalizedMessage(),
341 "Failed to read tree from " + client.getName() + " for "
343 JvOptionPane.ERROR_MESSAGE);
344 } catch (final Exception e)
348 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
349 e.getLocalizedMessage(), "Unexpected Exception",
350 JvOptionPane.ERROR_MESSAGE);
353 // if (_main_frame.getCurrentTreePanel() != null)
355 // _main_frame.getCurrentTreePanel().setArrowCursor();
359 // _main_frame.getMainPanel().setArrowCursor();
362 if ((trees != null) && (trees.length > 0))
364 for (final Phylogeny phylogeny : trees)
366 if (!phylogeny.isEmpty())
368 if (client.getName().equals(WebserviceUtil.TREE_FAM_NAME))
370 phylogeny.setRerootable(false);
371 phylogeny.setRooted(true);
373 if (client.getProcessingInstructions() != null)
377 WebserviceUtil.processInstructions(client, phylogeny);
378 } catch (final PhyloXmlDataFormatException e)
380 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
381 "Error:\n" + e.getLocalizedMessage(), "Error",
382 JvOptionPane.ERROR_MESSAGE);
385 if (client.getNodeField() != null)
389 PhylogenyMethods.transferNodeNameToField(phylogeny,
390 client.getNodeField(), false);
391 } catch (final PhyloXmlDataFormatException e)
393 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
394 "Error:\n" + e.getLocalizedMessage(), "Error",
395 JvOptionPane.ERROR_MESSAGE);
398 phylogeny.setIdentifier(
399 new Identifier(identifier, client.getName()));
400 // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu());
401 // _main_frame.getMenuBarOfMainFrame()
402 // .add(_main_frame.getHelpMenu());
403 // _main_frame.getMainPanel().addPhylogenyInNewTab(phylogeny,
404 // _main_frame.getConfiguration(),
405 // new File(url.getFile()).getName(), url.toString());
407 MainFrame aptxApp = createAptxFrame(phylogeny, viewport,
409 String my_name_for_file = "";
410 if (!ForesterUtil.isEmpty(phylogeny.getName()))
412 my_name_for_file = new String(phylogeny.getName())
413 .replaceAll(" ", "_");
415 else if (phylogeny.getIdentifier() != null)
417 final StringBuffer sb = new StringBuffer();
419 .isEmpty(phylogeny.getIdentifier().getProvider()))
421 sb.append(phylogeny.getIdentifier().getProvider());
424 sb.append(phylogeny.getIdentifier().getValue());
425 my_name_for_file = new String(
426 sb.toString().replaceAll(" ", "_"));
428 // _main_frame.getMainPanel().getCurrentTreePanel()
429 // .setTreeFile(new File(my_name_for_file));
430 AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings(
431 phylogeny, aptxApp.getMainPanel().getControlPanel(),
433 // _main_frame.getMainPanel().getControlPanel().showWhole();
435 aptxApp.activateSaveAllIfNeeded();
441 JvOptionPane.showMessageDialog(null,
442 ForesterUtil.wordWrap(
443 "Failed to read in tree(s) from [" + url + "]", 80),
444 "Error", JvOptionPane.ERROR_MESSAGE);
446 if ((trees != null) && (trees.length > 0))
450 JvOptionPane.showMessageDialog(null,
451 ForesterUtil.wordWrap("Successfully read in "
452 + trees.length + " tree(s) from [" + url + "]",
454 "Success", JvOptionPane.INFORMATION_MESSAGE);
455 } catch (final Exception e)
457 // Not important if this fails, do nothing.
459 // _main_frame.getContentPane().repaint();
466 if (Desktop.instance != null)
468 Desktop.instance.stopLoading();
479 public static MainFrame createAptxFrame(
480 final Phylogeny aptxTree,
481 final AlignmentViewport jalviewAlignport, String treeTitle)
483 MainFrame aptxApp = Archaeopteryx.createApplication(aptxTree,
484 APTX_CONFIG, treeTitle);
486 LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation(
487 jalviewAlignport.getAlignment().getSequencesArray(), aptxTree);
488 bindAptxNodes.associateLeavesToSequences();
490 bindNodesToJalviewSequences(aptxApp, jalviewAlignport,
491 bindAptxNodes.getAlignmentWithNodes(),
492 bindAptxNodes.getNodesWithAlignment());
493 bindTreeViewFrameToJalview(aptxApp);
498 // private static void addPartitioningSlider(MainFrame aptxFrame)
500 // JSlider slider = new JSlider();
505 public static ExternalTreeViewerBindingI<?> bindNodesToJalviewSequences(
506 final MainFrame aptxApp,
507 final AlignmentViewport jalviewAlignViewport,
508 final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
509 final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
511 JalviewBinding treeBinding = new JalviewBinding(aptxApp,
512 jalviewAlignViewport,
513 alignMappedToNodes, nodesMappedToAlign);
514 activeAptx.put(aptxApp, treeBinding);
519 public static MainFrame bindTreeViewFrameToJalview(
520 final MainFrame aptxApp)
524 aptxApp.setMinimumSize(new Dimension(width, height));
525 // aptxApp.setFont(Desktop.instance.getFont());
526 // aptxApp.getMainPanel().setFont(Desktop.instance.getFont());
527 String frameTitle = MessageManager.getString("label.aptx_title");
528 File treeFile = aptxApp.getMainPanel().getCurrentTreePanel()
530 if (treeFile != null)
532 frameTitle += MessageManager.formatMessage("label.aptx_title_append",
534 { treeFile.getAbsolutePath() });
536 Desktop.addInternalFrame(aptxApp, frameTitle, true, width, height, true,
542 public static Map<MainFrame, JalviewBinding> getAllAptxFrames()