1 package jalview.ext.archaeopteryx;
3 import jalview.analysis.TreeBuilder;
4 import jalview.datamodel.SequenceI;
5 import jalview.ext.forester.UtilityMethods;
6 import jalview.ext.treeviewer.ExternalLoadedTreeAssociationI;
7 import jalview.ext.treeviewer.ExternalTreeBuilderI;
8 import jalview.ext.treeviewer.ExternalTreeFrame;
9 import jalview.ext.treeviewer.ExternalTreeI;
10 import jalview.ext.treeviewer.ExternalTreeNodeI;
11 import jalview.ext.treeviewer.ExternalTreeViewerBindingI;
12 import jalview.ext.treeviewer.LoadedTreeSequenceAssociation;
13 import jalview.gui.Desktop;
14 import jalview.gui.JvOptionPane;
15 import jalview.util.MessageManager;
16 import jalview.viewmodel.AlignmentViewport;
18 import java.awt.Dimension;
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.net.MalformedURLException;
24 import java.util.HashMap;
27 import org.forester.archaeopteryx.AptxUtil;
28 import org.forester.archaeopteryx.Configuration;
29 import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;
30 import org.forester.archaeopteryx.webservices.WebserviceUtil;
31 import org.forester.io.parsers.PhylogenyParser;
32 import org.forester.io.parsers.nexus.NexusPhylogeniesParser;
33 import org.forester.io.parsers.nhx.NHXParser;
34 import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
35 import org.forester.io.parsers.phyloxml.PhyloXmlParser;
36 import org.forester.io.parsers.tol.TolParser;
37 import org.forester.io.parsers.util.ParserUtils;
38 import org.forester.phylogeny.Phylogeny;
39 import org.forester.phylogeny.PhylogenyMethods;
40 import org.forester.phylogeny.data.Identifier;
41 import org.forester.util.ForesterUtil;
44 * Static class for creating Archaeopteryx tree viewer instances from calculated
45 * trees and letting them be bound to Jalview.
47 * @author kjvanderheide
50 public final class AptxInit
52 public final static Configuration APTX_CONFIG = new Configuration(
53 "_aptx_jalview_configuration_file",
56 private final static boolean VALIDATE_PHYLOXML_XSD = APTX_CONFIG
57 .isValidatePhyloXmlAgainstSchema();
59 private final static boolean REPLACE_NHX_UNDERSCORES = APTX_CONFIG
60 .isReplaceUnderscoresInNhParsing();
62 private final static boolean INTERNAL_NUMBERS_AS_CONFIDENCE = APTX_CONFIG
63 .isInternalNumberAreConfidenceForNhParsing();
65 private final static boolean MIDPOINT_REROOT = APTX_CONFIG
68 private final static NHXParser.TAXONOMY_EXTRACTION TAXONOMY_EXTRACTION = APTX_CONFIG
69 .getTaxonomyExtraction();
71 private static Map<ExternalTreeFrame, ExternalTreeViewerBindingI> activeAptx = new HashMap<>();
76 public static ExternalTreeFrame createInstanceFromCalculation(
77 final TreeBuilder calculatedTree)
79 ExternalTreeBuilderI aptxTreeBuilder = new AptxTreeBuilder(
82 ExternalTreeI aptxTree = aptxTreeBuilder.buildTree();
84 ExternalTreeFrame aptxApp = createAptxFrame(aptxTree,
85 calculatedTree.getAvport(), null);
92 * Refactored from Archaeopteryx.main
98 * @throws FileNotFoundException
100 public static ExternalTreeFrame[] createInstancesFromFile(
102 AlignmentViewport viewport)
103 throws FileNotFoundException, IOException
105 File treeFile = new File(filePath);
106 ExternalTreeFrame[] aptxFrames = null;
107 if (UtilityMethods.canForesterReadFile(treeFile))
110 if (Desktop.instance != null)
112 Desktop.instance.startLoading(filePath);
114 boolean nhx_or_nexus = false;
115 final PhylogenyParser parser = ParserUtils
116 .createParserDependingOnFileType(
117 treeFile, VALIDATE_PHYLOXML_XSD);
118 if (parser instanceof NHXParser)
121 final NHXParser nhx = (NHXParser) parser;
122 nhx.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
123 nhx.setIgnoreQuotes(false);
124 nhx.setTaxonomyExtraction(TAXONOMY_EXTRACTION);
126 else if (parser instanceof NexusPhylogeniesParser)
129 final NexusPhylogeniesParser nex = (NexusPhylogeniesParser) parser;
130 nex.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
131 nex.setIgnoreQuotes(false);
133 else if (parser instanceof PhyloXmlParser)
135 if (VALIDATE_PHYLOXML_XSD == false)
137 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
138 MessageManager.getString("error.phyloxml_validation"),
139 MessageManager.getString("label.file_open_error"),
140 JvOptionPane.WARNING_MESSAGE );
143 Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser,
145 aptxFrames = new ExternalTreeFrame[trees.length];
148 for (int i = 0; i < trees.length; i++)
150 Phylogeny aptxPhylogeny = trees[i];
152 if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE)
154 PhylogenyMethods.transferInternalNodeNamesToConfidence(aptxPhylogeny,
157 String treeTitle = treeFile.getName() + "[" + i + "]";
158 aptxPhylogeny.setName(treeTitle);
159 aptxFrames[i] = createAptxFrame(aptxPhylogeny, viewport, treeTitle);
162 if (Desktop.instance != null)
164 Desktop.instance.stopLoading();
171 public static ExternalTreeFrame[] createInstancesFromUrl(URL treeUrl,
172 AlignmentViewport viewport)
173 throws FileNotFoundException, IOException, RuntimeException
176 String treeTitle = treeUrl.getFile();
177 if (Desktop.instance != null)
179 Desktop.instance.startLoading(treeTitle);
181 Phylogeny[] trees = AptxUtil.readPhylogeniesFromUrl(treeUrl,
182 VALIDATE_PHYLOXML_XSD,
183 REPLACE_NHX_UNDERSCORES, INTERNAL_NUMBERS_AS_CONFIDENCE,
184 TAXONOMY_EXTRACTION, MIDPOINT_REROOT);
186 ExternalTreeFrame[] aptxFrames = new ExternalTreeFrame[trees.length];
187 for (int i = 0; i < trees.length; i++)
189 Phylogeny aptxTree = trees[i];
190 aptxFrames[i] = createAptxFrame(aptxTree, viewport, treeTitle);
193 if (Desktop.instance != null)
195 Desktop.instance.stopLoading();
203 * Refactored from Forester's UrlTreeReader, this can be more efficient
205 * @param databaseIndex
209 public static ExternalTreeFrame[] createInstancesFromDb(
210 PhylogeniesWebserviceClient treeDbClient, String identifier,
211 AlignmentViewport viewport)
215 Phylogeny[] trees = null;
216 ExternalTreeFrame[] aptxFrames = null;
218 if ((identifier != null) && (identifier.trim().length() > 0))
220 if (Desktop.instance != null)
222 Desktop.instance.startLoading(identifier);
225 identifier = identifier.trim();
226 if (treeDbClient.isQueryInteger())
228 identifier = identifier.replaceAll("^\\D+", "");
233 id = Integer.parseInt(identifier);
234 } catch (final NumberFormatException e)
236 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
237 MessageManager.formatMessage(
238 "error.database_id_has_letters", new String[]
240 MessageManager.getString("label.invalid_url"),
241 JvOptionPane.ERROR_MESSAGE);
242 return new ExternalTreeFrame[0];
244 identifier = id + "";
246 boolean exception = false;
249 String url_str = treeDbClient.getUrl();
250 url_str = url_str.replaceFirst(
251 PhylogeniesWebserviceClient.QUERY_PLACEHOLDER, identifier);
252 url = new URL(url_str);
253 PhylogenyParser parser = null;
254 switch (treeDbClient.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: " + treeDbClient.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 aptxFrames = new ExternalTreeFrame[trees.length];
321 } catch (final MalformedURLException e)
324 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
325 MessageManager.formatMessage(
326 "exception.unable_to_launch_url", new String[]
328 MessageManager.getString("label.invalid_url"),
329 JvOptionPane.ERROR_MESSAGE);
330 System.err.println(e.getLocalizedMessage());
331 } catch (final IOException e)
334 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
335 "Could not read from " + url + "\n"
336 + e.getLocalizedMessage(),
337 "Failed to read tree from " + treeDbClient.getName() + " for "
339 JvOptionPane.ERROR_MESSAGE);
340 System.err.println(e.getLocalizedMessage());
341 } catch (final NumberFormatException e)
344 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
345 "Could not read from " + url + "\n"
346 + e.getLocalizedMessage(),
347 "Failed to read tree from " + treeDbClient.getName() + " for "
349 JvOptionPane.ERROR_MESSAGE);
350 System.err.println(e.getLocalizedMessage());
351 } catch (final Exception e)
355 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
356 e.getLocalizedMessage(), "Unexpected Exception",
357 JvOptionPane.ERROR_MESSAGE);
358 System.err.println(e.getLocalizedMessage());
360 if ((trees != null) && (trees.length > 0))
363 for (final Phylogeny aptxTree : trees)
365 if (!aptxTree.isEmpty())
367 if (treeDbClient.getName().equals(WebserviceUtil.TREE_FAM_NAME))
369 aptxTree.setRerootable(false);
370 aptxTree.setRooted(true);
372 if (treeDbClient.getProcessingInstructions() != null)
376 WebserviceUtil.processInstructions(treeDbClient,
378 } catch (final PhyloXmlDataFormatException e)
380 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
381 "Error:\n" + e.getLocalizedMessage(), "Error",
382 JvOptionPane.ERROR_MESSAGE);
385 if (treeDbClient.getNodeField() != null)
389 PhylogenyMethods.transferNodeNameToField(aptxTree,
390 treeDbClient.getNodeField(), false);
391 } catch (final PhyloXmlDataFormatException e)
393 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
394 "Error:\n" + e.getLocalizedMessage(), "Error",
395 JvOptionPane.ERROR_MESSAGE);
398 aptxTree.setIdentifier(
399 new Identifier(identifier, treeDbClient.getName()));
400 // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu());
401 // _main_frame.getMenuBarOfExternalTreeFrameI()
402 // .add(_main_frame.getHelpMenu());
403 // _main_frame.getMainPanel().addExternalTreeIInNewTab(ExternalTreeI,
404 // _main_frame.getConfiguration(),
405 // new File(url.getFile()).getName(), url.toString());
408 ExternalTreeFrame aptxApp = createAptxFrame(aptxTree,
411 String my_name_for_file = "";
412 if (!ForesterUtil.isEmpty(aptxTree.getName()))
414 my_name_for_file = new String(aptxTree.getName())
415 .replaceAll(" ", "_");
417 else if (aptxTree.getIdentifier() != null)
419 final StringBuffer sb = new StringBuffer();
421 .isEmpty(aptxTree.getIdentifier().getProvider()))
423 sb.append(aptxTree.getIdentifier().getProvider());
426 sb.append(aptxTree.getIdentifier().getValue());
427 my_name_for_file = new String(
428 sb.toString().replaceAll(" ", "_"));
430 aptxApp.getTreePanel()
431 .setTreeFile(new File(my_name_for_file));
432 // AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings(
433 // aptxTree, aptxApp.getMainPanel().getControlPanel(),
435 aptxApp.getTreeControls().displayEntireTree();
437 aptxApp.checkMultipleTrees();
438 aptxFrames[i++] = aptxApp;
442 else if (!exception) // ..what?
444 JvOptionPane.showMessageDialog(null,
445 ForesterUtil.wordWrap(
446 "Failed to read in tree(s) from [" + url + "]", 80),
447 "Error", JvOptionPane.ERROR_MESSAGE);
449 if ((trees != null) && (trees.length > 0))
453 JvOptionPane.showMessageDialog(null,
454 ForesterUtil.wordWrap("Successfully read in "
455 + trees.length + " tree(s) from [" + url + "]",
457 "Success", JvOptionPane.INFORMATION_MESSAGE);
458 } catch (final Exception e)
460 // Not important if this fails, do nothing.
462 // _main_frame.getContentPane().repaint();
469 if (Desktop.instance != null)
471 Desktop.instance.stopLoading();
480 public static ExternalTreeFrame createAptxFrame(ExternalTreeI aptxTree,
481 AlignmentViewport jalviewAlignport, String treeTitle)
483 validateConfig(APTX_CONFIG);
484 ExternalTreeFrame aptxApp = aptxTree
485 .createTreeViewerFromTree(treeTitle);
486 ExternalTreeI jalviewTree = aptxApp.getTree();
487 ExternalLoadedTreeAssociationI bindAptxNodes = new LoadedTreeSequenceAssociation(
488 jalviewAlignport.getAlignment().getSequencesArray(),
490 bindAptxNodes.associateLeavesToSequences();
492 bindNodesToJalviewSequences(aptxApp, jalviewAlignport,
493 bindAptxNodes.getAlignmentWithNodes(),
494 bindAptxNodes.getNodesWithAlignment());
495 bindTreeViewFrameToJalview(aptxApp);
497 // adaptAptxGui(aptxApp); //moved to AptxFrame
502 protected static ExternalTreeFrame createAptxFrame(
503 final Phylogeny aptxTree,
504 final AlignmentViewport jalviewAlignport, String treeTitle)
506 validateConfig(APTX_CONFIG);
507 ExternalTreeFrame aptxApp = new AptxFrame(aptxTree, APTX_CONFIG,
509 ExternalTreeI jalviewTree = aptxApp.getTree();
510 ExternalLoadedTreeAssociationI bindAptxNodes = new LoadedTreeSequenceAssociation(
511 jalviewAlignport.getAlignment().getSequencesArray(),
513 bindAptxNodes.associateLeavesToSequences();
515 bindNodesToJalviewSequences(aptxApp, jalviewAlignport,
516 bindAptxNodes.getAlignmentWithNodes(),
517 bindAptxNodes.getNodesWithAlignment());
518 bindTreeViewFrameToJalview(aptxApp);
520 // adaptAptxGui(aptxApp); //moved to AptxFrame
525 protected static ExternalTreeViewerBindingI bindNodesToJalviewSequences(
526 final ExternalTreeFrame aptxApp,
527 final AlignmentViewport jalviewAlignViewport,
528 final Map<SequenceI, ExternalTreeNodeI> alignMappedToNodes,
529 final Map<ExternalTreeNodeI, SequenceI> nodesMappedToAlign)
531 ExternalTreeViewerBindingI treeBinding = new JalviewBinding(aptxApp,
532 jalviewAlignViewport,
533 alignMappedToNodes, nodesMappedToAlign);
534 activeAptx.put(aptxApp, treeBinding);
539 protected static ExternalTreeFrame bindTreeViewFrameToJalview(
540 final ExternalTreeFrame aptxApp)
544 aptxApp.setMinimumSize(new Dimension(width, height));
545 // aptxApp.setFont(Desktop.instance.getFont());
546 // aptxApp.getMainPanel().setFont(Desktop.instance.getFont());
547 String frameTitle = MessageManager.getString("label.aptx_title");
548 File treeFile = aptxApp.getTreePanel().getTreeFile();
549 if (treeFile != null)
551 frameTitle += MessageManager.formatMessage("label.aptx_title_append",
553 { treeFile.getAbsolutePath() });
555 aptxApp.addFrameToJalview(frameTitle, true, width, height, true,
561 private static boolean validateConfig(Configuration aptxConfig)
563 if (aptxConfig == null || aptxConfig.isCouldReadConfigFile() == false)
565 int keepGoing = JvOptionPane.showConfirmDialog(Desktop.desktop,
566 MessageManager.getString("label.aptx_config_not_found"),
567 MessageManager.formatMessage("label.couldnt_locate",
569 { "_aptx_jalview_configuration_file" }),
570 JvOptionPane.YES_NO_CANCEL_OPTION);
572 if (keepGoing == JvOptionPane.CANCEL_OPTION
573 || keepGoing == JvOptionPane.CLOSED_OPTION
574 || keepGoing == JvOptionPane.NO_OPTION)
585 public static Map<ExternalTreeFrame, ExternalTreeViewerBindingI> getAllAptxFrames()