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 (p instanceof PhyloXmlParser)
133 // MainFrameApplication.warnIfNotPhyloXmlValidation(APTX_CONFIG);
135 Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser, treeFile);
136 MainFrame[] aptxFrames = new MainFrame[trees.length];
139 for (int i = 0; i < trees.length; i++)
141 Phylogeny tree = trees[i];
143 if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE)
145 PhylogenyMethods.transferInternalNodeNamesToConfidence(tree, "");
147 String treeTitle = treeFile.getName() + "[" + i + "]";
148 tree.setName(treeTitle);
149 aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle);
152 if (Desktop.instance != null)
154 Desktop.instance.stopLoading();
160 public static MainFrame[] createInstancesFromUrl(URL treeUrl,
161 AlignmentViewport viewport)
162 throws FileNotFoundException, IOException, RuntimeException
165 String treeTitle = treeUrl.getFile();
166 if (Desktop.instance != null)
168 Desktop.instance.startLoading(treeTitle);
170 Phylogeny[] trees = AptxUtil.readPhylogeniesFromUrl(treeUrl,
171 VALIDATE_PHYLOXML_XSD,
172 REPLACE_NHX_UNDERSCORES, INTERNAL_NUMBERS_AS_CONFIDENCE,
173 TAXONOMY_EXTRACTION, MIDPOINT_REROOT);
175 MainFrame[] aptxFrames = new MainFrame[trees.length];
176 for (int i = 0; i < trees.length; i++)
178 Phylogeny tree = trees[i];
179 aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle);
182 if (Desktop.instance != null)
184 Desktop.instance.stopLoading();
192 * Refactored from Forester's UrlTreeReader, this can be more efficient
194 * @param databaseIndex
198 public static MainFrame[] createInstancesFromDb(int databaseIndex,
199 AlignmentViewport viewport)
203 Phylogeny[] trees = null;
204 final WebservicesManager webservices_manager = WebservicesManager
206 final PhylogeniesWebserviceClient client = webservices_manager
207 .getAvailablePhylogeniesWebserviceClient(databaseIndex);
208 String identifier = JvOptionPane.showInternalInputDialog(
210 client.getInstructions() + "\n(Reference: "
211 + client.getReference() + ")",
212 client.getDescription(), JvOptionPane.QUESTION_MESSAGE);
214 if ((identifier != null) && (identifier.trim().length() > 0))
216 if (Desktop.instance != null)
218 Desktop.instance.startLoading(identifier);
221 identifier = identifier.trim();
222 if (client.isQueryInteger())
224 identifier = identifier.replaceAll("^\\D+", "");
229 id = Integer.parseInt(identifier);
230 } catch (final NumberFormatException e)
232 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
233 "Identifier is expected to be a number",
234 "Can not open URL", JvOptionPane.ERROR_MESSAGE);
235 return new MainFrame[0];
237 identifier = id + "";
239 boolean exception = false;
242 String url_str = client.getUrl();
243 url_str = url_str.replaceFirst(
244 PhylogeniesWebserviceClient.QUERY_PLACEHOLDER, identifier);
245 url = new URL(url_str);
246 PhylogenyParser parser = null;
247 switch (client.getReturnFormat())
249 case TOL_XML_RESPONSE:
250 parser = new TolParser();
253 parser = new NexusPhylogeniesParser();
254 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
257 parser = new NexusPhylogeniesParser();
258 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
259 ((NexusPhylogeniesParser) parser)
260 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
263 parser = new NexusPhylogeniesParser();
264 ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
265 ((NexusPhylogeniesParser) parser)
266 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
269 parser = new NHXParser();
271 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
272 ((NHXParser) parser).setReplaceUnderscores(true);
273 ((NHXParser) parser).setGuessRootedness(true);
275 case NH_EXTRACT_TAXONOMY:
276 parser = new NHXParser();
277 ((NHXParser) parser).setTaxonomyExtraction(
278 NHXParser.TAXONOMY_EXTRACTION.AGGRESSIVE);
279 ((NHXParser) parser).setReplaceUnderscores(false);
280 ((NHXParser) parser).setGuessRootedness(true);
283 parser = new NHXParser();
284 ((NHXParser) parser).setTaxonomyExtraction(
285 NHXParser.TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT);
286 ((NHXParser) parser).setReplaceUnderscores(false);
287 ((NHXParser) parser).setGuessRootedness(true);
290 parser = new NHXParser();
292 .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
293 ((NHXParser) parser).setReplaceUnderscores(false);
294 ((NHXParser) parser).setGuessRootedness(true);
297 parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
300 throw new IllegalArgumentException(
301 "unknown format: " + client.getReturnFormat());
304 // if (_main_frame.getMainPanel().getCurrentTreePanel() != null)
306 // _main_frame.getMainPanel().getCurrentTreePanel().setWaitCursor();
310 // _main_frame.getMainPanel().setWaitCursor();
312 trees = ForesterUtil.readPhylogeniesFromUrl(url, parser);
313 } catch (final MalformedURLException e)
316 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
317 "Malformed URL: " + url + "\n" + e.getLocalizedMessage(),
318 "Malformed URL", JvOptionPane.ERROR_MESSAGE);
319 } catch (final IOException e)
322 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
323 "Could not read from " + url + "\n"
324 + e.getLocalizedMessage(),
325 "Failed to read tree from " + client.getName() + " for "
327 JvOptionPane.ERROR_MESSAGE);
328 } catch (final NumberFormatException e)
331 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
332 "Could not read from " + url + "\n"
333 + e.getLocalizedMessage(),
334 "Failed to read tree from " + client.getName() + " for "
336 JvOptionPane.ERROR_MESSAGE);
337 } catch (final Exception e)
341 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
342 e.getLocalizedMessage(), "Unexpected Exception",
343 JvOptionPane.ERROR_MESSAGE);
346 // if (_main_frame.getCurrentTreePanel() != null)
348 // _main_frame.getCurrentTreePanel().setArrowCursor();
352 // _main_frame.getMainPanel().setArrowCursor();
355 if ((trees != null) && (trees.length > 0))
357 for (final Phylogeny phylogeny : trees)
359 if (!phylogeny.isEmpty())
361 if (client.getName().equals(WebserviceUtil.TREE_FAM_NAME))
363 phylogeny.setRerootable(false);
364 phylogeny.setRooted(true);
366 if (client.getProcessingInstructions() != null)
370 WebserviceUtil.processInstructions(client, phylogeny);
371 } catch (final PhyloXmlDataFormatException e)
373 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
374 "Error:\n" + e.getLocalizedMessage(), "Error",
375 JvOptionPane.ERROR_MESSAGE);
378 if (client.getNodeField() != null)
382 PhylogenyMethods.transferNodeNameToField(phylogeny,
383 client.getNodeField(), false);
384 } catch (final PhyloXmlDataFormatException e)
386 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
387 "Error:\n" + e.getLocalizedMessage(), "Error",
388 JvOptionPane.ERROR_MESSAGE);
391 phylogeny.setIdentifier(
392 new Identifier(identifier, client.getName()));
393 // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu());
394 // _main_frame.getMenuBarOfMainFrame()
395 // .add(_main_frame.getHelpMenu());
396 // _main_frame.getMainPanel().addPhylogenyInNewTab(phylogeny,
397 // _main_frame.getConfiguration(),
398 // new File(url.getFile()).getName(), url.toString());
400 MainFrame aptxApp = createAptxFrame(phylogeny, viewport,
402 String my_name_for_file = "";
403 if (!ForesterUtil.isEmpty(phylogeny.getName()))
405 my_name_for_file = new String(phylogeny.getName())
406 .replaceAll(" ", "_");
408 else if (phylogeny.getIdentifier() != null)
410 final StringBuffer sb = new StringBuffer();
412 .isEmpty(phylogeny.getIdentifier().getProvider()))
414 sb.append(phylogeny.getIdentifier().getProvider());
417 sb.append(phylogeny.getIdentifier().getValue());
418 my_name_for_file = new String(
419 sb.toString().replaceAll(" ", "_"));
421 // _main_frame.getMainPanel().getCurrentTreePanel()
422 // .setTreeFile(new File(my_name_for_file));
423 AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings(
424 phylogeny, aptxApp.getMainPanel().getControlPanel(),
426 // _main_frame.getMainPanel().getControlPanel().showWhole();
428 aptxApp.activateSaveAllIfNeeded();
434 JvOptionPane.showMessageDialog(null,
435 ForesterUtil.wordWrap(
436 "Failed to read in tree(s) from [" + url + "]", 80),
437 "Error", JvOptionPane.ERROR_MESSAGE);
439 if ((trees != null) && (trees.length > 0))
443 JvOptionPane.showMessageDialog(null,
444 ForesterUtil.wordWrap("Successfully read in "
445 + trees.length + " tree(s) from [" + url + "]",
447 "Success", JvOptionPane.INFORMATION_MESSAGE);
448 } catch (final Exception e)
450 // Not important if this fails, do nothing.
452 // _main_frame.getContentPane().repaint();
459 if (Desktop.instance != null)
461 Desktop.instance.stopLoading();
472 public static MainFrame createAptxFrame(
473 final Phylogeny aptxTree,
474 final AlignmentViewport jalviewAlignport, String treeTitle)
476 MainFrame aptxApp = Archaeopteryx.createApplication(aptxTree,
477 APTX_CONFIG, treeTitle);
479 LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation(
480 jalviewAlignport.getAlignment().getSequencesArray(), aptxTree);
481 bindAptxNodes.associateLeavesToSequences();
483 bindNodesToJalviewSequences(aptxApp, jalviewAlignport,
484 bindAptxNodes.getAlignmentWithNodes(),
485 bindAptxNodes.getNodesWithAlignment());
486 bindTreeViewFrameToJalview(aptxApp);
491 // private static void addPartitioningSlider(MainFrame aptxFrame)
493 // JSlider slider = new JSlider();
498 public static ExternalTreeViewerBindingI<?> bindNodesToJalviewSequences(
499 final MainFrame aptxApp,
500 final AlignmentViewport jalviewAlignViewport,
501 final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
502 final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
504 JalviewBinding treeBinding = new JalviewBinding(aptxApp,
505 jalviewAlignViewport,
506 alignMappedToNodes, nodesMappedToAlign);
507 activeAptx.put(aptxApp, treeBinding);
512 public static MainFrame bindTreeViewFrameToJalview(
513 final MainFrame aptxApp)
517 aptxApp.setMinimumSize(new Dimension(width, height));
518 // aptxApp.setFont(Desktop.instance.getFont());
519 // aptxApp.getMainPanel().setFont(Desktop.instance.getFont());
521 Desktop.addInternalFrame(aptxApp, "Archaeopteryx Tree View", true,
522 width, height, true, true);
528 public static Map<MainFrame, JalviewBinding> getAllAptxFrames()