9f2817e2c13d641084cd8716dd730f636222cc26
[jalview.git] / src / jalview / ext / archaeopteryx / AptxInit.java
1 package jalview.ext.archaeopteryx;
2
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;
11
12 import java.awt.Dimension;
13 import java.io.File;
14 import java.io.FileNotFoundException;
15 import java.io.IOException;
16 import java.net.MalformedURLException;
17 import java.net.URL;
18 import java.util.Map;
19
20 import org.forester.archaeopteryx.AptxUtil;
21 import org.forester.archaeopteryx.Archaeopteryx;
22 import org.forester.archaeopteryx.Configuration;
23 import org.forester.archaeopteryx.MainFrame;
24 import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;
25 import org.forester.archaeopteryx.webservices.WebserviceUtil;
26 import org.forester.archaeopteryx.webservices.WebservicesManager;
27 import org.forester.io.parsers.PhylogenyParser;
28 import org.forester.io.parsers.nexus.NexusPhylogeniesParser;
29 import org.forester.io.parsers.nhx.NHXParser;
30 import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
31 import org.forester.io.parsers.phyloxml.PhyloXmlParser;
32 import org.forester.io.parsers.tol.TolParser;
33 import org.forester.io.parsers.util.ParserUtils;
34 import org.forester.phylogeny.Phylogeny;
35 import org.forester.phylogeny.PhylogenyMethods;
36 import org.forester.phylogeny.PhylogenyNode;
37 import org.forester.phylogeny.data.Identifier;
38 import org.forester.util.ForesterUtil;
39
40 /**
41  * Static class for creating Archaeopteryx tree viewer instances from calculated
42  * trees and letting them be bound to Jalview.
43  * 
44  * @author kjvanderheide
45  *
46  */
47 public final class AptxInit
48 {
49
50   private final static Configuration APTX_CONFIG = new Configuration(
51           "_aptx_jalview_configuration_file", false, false, false);
52
53   private final static boolean VALIDATE_PHYLOXML_XSD = APTX_CONFIG
54           .isValidatePhyloXmlAgainstSchema();
55
56   private final static boolean REPLACE_NHX_UNDERSCORES = APTX_CONFIG
57           .isReplaceUnderscoresInNhParsing();
58
59   private final static boolean INTERNAL_NUMBERS_AS_CONFIDENCE = APTX_CONFIG
60           .isInternalNumberAreConfidenceForNhParsing();
61
62   private final static boolean MIDPOINT_REROOT = APTX_CONFIG
63           .isMidpointReroot();
64
65   private final static NHXParser.TAXONOMY_EXTRACTION TAXONOMY_EXTRACTION = APTX_CONFIG
66           .getTaxonomyExtraction();
67
68
69
70   public static MainFrame createInstanceFromCalculation(
71           final TreeBuilder calculatedTree)
72   {
73     ExternalTreeBuilderI<Phylogeny, PhylogenyNode> aptxTreeBuilder = new AptxTreeBuilder(
74             calculatedTree);
75
76     Phylogeny aptxTree = aptxTreeBuilder.buildTree();
77
78     MainFrame aptxApp = createAptxFrame(aptxTree,
79             calculatedTree.getAvport(), null);
80             
81     return aptxApp;
82   }
83
84   /**
85    * Refactored from Archaeopteryx.main
86    * 
87    * @param filePath
88    * @param viewport
89    * @return
90    * @throws IOException
91    * @throws FileNotFoundException
92    */
93   public static MainFrame[] createInstancesFromFile(String filePath,
94           AlignmentViewport viewport)
95           throws FileNotFoundException, IOException
96   {
97     File treeFile = new File(filePath);
98     final String err = ForesterUtil.isReadableFile(treeFile);
99     if (!ForesterUtil.isEmpty(err))
100     {
101       JvOptionPane.showMessageDialog(Desktop.desktop, err,
102               MessageManager.getString("label.problem_reading_tree_file"),
103               JvOptionPane.WARNING_MESSAGE);
104     }
105
106     if (Desktop.instance != null)
107     {
108       Desktop.instance.startLoading(filePath);
109     }
110     boolean nhx_or_nexus = false;
111     final PhylogenyParser p = ParserUtils.createParserDependingOnFileType(
112             treeFile, VALIDATE_PHYLOXML_XSD);
113     if (p instanceof NHXParser)
114     {
115       nhx_or_nexus = true;
116       final NHXParser nhx = (NHXParser) p;
117       nhx.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
118       nhx.setIgnoreQuotes(false);
119       nhx.setTaxonomyExtraction(TAXONOMY_EXTRACTION);
120     }
121     else if (p instanceof NexusPhylogeniesParser)
122     {
123       nhx_or_nexus = true;
124       final NexusPhylogeniesParser nex = (NexusPhylogeniesParser) p;
125       nex.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
126       nex.setIgnoreQuotes(false);
127     }
128 //    else if (p instanceof PhyloXmlParser)
129 //    {
130 //      MainFrameApplication.warnIfNotPhyloXmlValidation(APTX_CONFIG);
131 //    }
132     Phylogeny[] phylogenies = PhylogenyMethods.readPhylogenies(p, treeFile);
133     MainFrame[] aptxFrames = new MainFrame[phylogenies.length];
134     String treeTitle = treeFile.getName();
135
136     for (int i = 0; i < phylogenies.length; i++)
137       {
138       Phylogeny tree = phylogenies[i];
139
140       if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE)
141       {
142         PhylogenyMethods.transferInternalNodeNamesToConfidence(tree, "");
143       }
144
145       aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle);
146     }
147     if (Desktop.instance != null)
148     {
149       Desktop.instance.stopLoading();
150     }
151     return aptxFrames;
152     }
153
154
155   public static MainFrame[] createInstancesFromUrl(URL treeUrl,
156           AlignmentViewport viewport)
157           throws FileNotFoundException, IOException, RuntimeException
158   {
159     
160     String treeTitle = treeUrl.getFile();
161     if (Desktop.instance != null)
162     {
163       Desktop.instance.startLoading(treeTitle);
164     }
165     Phylogeny[] trees = AptxUtil.readPhylogeniesFromUrl(treeUrl,
166             VALIDATE_PHYLOXML_XSD,
167              REPLACE_NHX_UNDERSCORES, INTERNAL_NUMBERS_AS_CONFIDENCE,
168             TAXONOMY_EXTRACTION, MIDPOINT_REROOT);
169
170     MainFrame[] aptxFrames = new MainFrame[trees.length];
171     for (int i = 0; i < trees.length; i++)
172     {
173       Phylogeny tree = trees[i];
174       aptxFrames[i] = createAptxFrame(tree, viewport, treeTitle);
175     }
176
177     if (Desktop.instance != null)
178     {
179       Desktop.instance.stopLoading();
180     }
181
182     return aptxFrames;
183
184   }
185
186   /**
187    * Refactored from Forester's UrlTreeReader
188    * 
189    * @param databaseIndex
190    * @param viewport
191    * @return
192    */
193   public static MainFrame[] createInstancesFromDb(int databaseIndex,
194           AlignmentViewport viewport)
195   {
196     if (Desktop.desktop != null)
197     {
198       // Desktop.desktop.startLoading(treeTitle);
199     }
200
201     URL url = null;
202     Phylogeny[] trees = null;
203     final WebservicesManager webservices_manager = WebservicesManager
204             .getInstance();
205     final PhylogeniesWebserviceClient client = webservices_manager
206             .getAvailablePhylogeniesWebserviceClient(databaseIndex);
207     String identifier = JvOptionPane.showInternalInputDialog(
208             Desktop.desktop,
209             client.getInstructions() + "\n(Reference: "
210                     + client.getReference() + ")",
211             client.getDescription(), JvOptionPane.QUESTION_MESSAGE);
212     if ((identifier != null) && (identifier.trim().length() > 0))
213     {
214       identifier = identifier.trim();
215       if (client.isQueryInteger())
216       {
217         identifier = identifier.replaceAll("^\\D+", "");
218         int id = -1;
219         try
220         {
221           id = Integer.parseInt(identifier);
222         } catch (final NumberFormatException e)
223         {
224           id = -1;
225         }
226         if (id < 1)
227         {
228           JvOptionPane.showInternalMessageDialog(Desktop.desktop,
229                   "Identifier is expected to be a number",
230                   "Can not open URL", JvOptionPane.ERROR_MESSAGE);
231           return new MainFrame[0];
232         }
233         identifier = id + "";
234       }
235       boolean exception = false;
236       try
237       {
238         String url_str = client.getUrl();
239         url_str = url_str.replaceFirst(
240                 PhylogeniesWebserviceClient.QUERY_PLACEHOLDER, identifier);
241         url = new URL(url_str);
242         PhylogenyParser parser = null;
243         switch (client.getReturnFormat())
244         {
245         case TOL_XML_RESPONSE:
246           parser = new TolParser();
247           break;
248         case NEXUS:
249           parser = new NexusPhylogeniesParser();
250           ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
251           break;
252         case TREEBASE_TREE:
253           parser = new NexusPhylogeniesParser();
254           ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
255           ((NexusPhylogeniesParser) parser)
256                   .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
257           break;
258         case TREEBASE_STUDY:
259           parser = new NexusPhylogeniesParser();
260           ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
261           ((NexusPhylogeniesParser) parser)
262                   .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
263           break;
264         case NH:
265           parser = new NHXParser();
266           ((NHXParser) parser)
267                   .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
268           ((NHXParser) parser).setReplaceUnderscores(true);
269           ((NHXParser) parser).setGuessRootedness(true);
270           break;
271         case NH_EXTRACT_TAXONOMY:
272           parser = new NHXParser();
273           ((NHXParser) parser).setTaxonomyExtraction(
274                   NHXParser.TAXONOMY_EXTRACTION.AGGRESSIVE);
275           ((NHXParser) parser).setReplaceUnderscores(false);
276           ((NHXParser) parser).setGuessRootedness(true);
277           break;
278         case PFAM:
279           parser = new NHXParser();
280           ((NHXParser) parser).setTaxonomyExtraction(
281                   NHXParser.TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT);
282           ((NHXParser) parser).setReplaceUnderscores(false);
283           ((NHXParser) parser).setGuessRootedness(true);
284           break;
285         case NHX:
286           parser = new NHXParser();
287           ((NHXParser) parser)
288                   .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
289           ((NHXParser) parser).setReplaceUnderscores(false);
290           ((NHXParser) parser).setGuessRootedness(true);
291           break;
292         case PHYLOXML:
293           parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
294           break;
295         default:
296           throw new IllegalArgumentException(
297                   "unknown format: " + client.getReturnFormat());
298         }
299         //
300         // if (_main_frame.getMainPanel().getCurrentTreePanel() != null)
301         // {
302         // _main_frame.getMainPanel().getCurrentTreePanel().setWaitCursor();
303         // }
304         // else
305         // {
306         // _main_frame.getMainPanel().setWaitCursor();
307         // }
308         trees = ForesterUtil.readPhylogeniesFromUrl(url, parser);
309       } catch (final MalformedURLException e)
310       {
311         exception = true;
312         JvOptionPane.showInternalMessageDialog(Desktop.desktop,
313                 "Malformed URL: " + url + "\n" + e.getLocalizedMessage(),
314                 "Malformed URL", JvOptionPane.ERROR_MESSAGE);
315       } catch (final IOException e)
316       {
317         exception = true;
318         JvOptionPane.showInternalMessageDialog(Desktop.desktop,
319                 "Could not read from " + url + "\n"
320                         + e.getLocalizedMessage(),
321                 "Failed to read tree from " + client.getName() + " for "
322                         + identifier,
323                 JvOptionPane.ERROR_MESSAGE);
324       } catch (final NumberFormatException e)
325       {
326         exception = true;
327         JvOptionPane.showInternalMessageDialog(Desktop.desktop,
328                 "Could not read from " + url + "\n"
329                         + e.getLocalizedMessage(),
330                 "Failed to read tree from " + client.getName() + " for "
331                         + identifier,
332                 JvOptionPane.ERROR_MESSAGE);
333       } catch (final Exception e)
334       {
335         exception = true;
336         e.printStackTrace();
337         JvOptionPane.showInternalMessageDialog(Desktop.desktop,
338                 e.getLocalizedMessage(), "Unexpected Exception",
339                 JvOptionPane.ERROR_MESSAGE);
340       } finally
341       {
342         // if (_main_frame.getCurrentTreePanel() != null)
343         // {
344         // _main_frame.getCurrentTreePanel().setArrowCursor();
345         // }
346         // else
347         // {
348         // _main_frame.getMainPanel().setArrowCursor();
349         // }
350       }
351       if ((trees != null) && (trees.length > 0))
352       {
353         for (final Phylogeny phylogeny : trees)
354         {
355           if (!phylogeny.isEmpty())
356           {
357             if (client.getName().equals(WebserviceUtil.TREE_FAM_NAME))
358             {
359               phylogeny.setRerootable(false);
360               phylogeny.setRooted(true);
361             }
362             if (client.getProcessingInstructions() != null)
363             {
364               try
365               {
366                 WebserviceUtil.processInstructions(client, phylogeny);
367               } catch (final PhyloXmlDataFormatException e)
368               {
369                 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
370                         "Error:\n" + e.getLocalizedMessage(), "Error",
371                         JvOptionPane.ERROR_MESSAGE);
372               }
373             }
374             if (client.getNodeField() != null)
375             {
376               try
377               {
378                 PhylogenyMethods.transferNodeNameToField(phylogeny,
379                         client.getNodeField(), false);
380               } catch (final PhyloXmlDataFormatException e)
381               {
382                 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
383                         "Error:\n" + e.getLocalizedMessage(), "Error",
384                         JvOptionPane.ERROR_MESSAGE);
385               }
386             }
387             phylogeny.setIdentifier(
388                     new Identifier(identifier, client.getName()));
389             // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu());
390             // _main_frame.getMenuBarOfMainFrame()
391             // .add(_main_frame.getHelpMenu());
392             // _main_frame.getMainPanel().addPhylogenyInNewTab(phylogeny,
393             // _main_frame.getConfiguration(),
394             // new File(url.getFile()).getName(), url.toString());
395
396             MainFrame aptxApp = createAptxFrame(phylogeny, viewport,
397                     url.getFile());
398             String my_name_for_file = "";
399             if (!ForesterUtil.isEmpty(phylogeny.getName()))
400             {
401               my_name_for_file = new String(phylogeny.getName())
402                       .replaceAll(" ", "_");
403             }
404             else if (phylogeny.getIdentifier() != null)
405             {
406               final StringBuffer sb = new StringBuffer();
407               if (!ForesterUtil
408                       .isEmpty(phylogeny.getIdentifier().getProvider()))
409               {
410                 sb.append(phylogeny.getIdentifier().getProvider());
411                 sb.append("_");
412               }
413               sb.append(phylogeny.getIdentifier().getValue());
414               my_name_for_file = new String(
415                       sb.toString().replaceAll(" ", "_"));
416             }
417             // _main_frame.getMainPanel().getCurrentTreePanel()
418             // .setTreeFile(new File(my_name_for_file));
419             AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings(
420                     phylogeny, aptxApp.getMainPanel().getControlPanel(),
421                     APTX_CONFIG);
422             // _main_frame.getMainPanel().getControlPanel().showWhole();
423
424             aptxApp.activateSaveAllIfNeeded();
425           }
426         }
427       }
428       else if (!exception)
429       {
430         JvOptionPane.showMessageDialog(null,
431                 ForesterUtil.wordWrap(
432                         "Failed to read in tree(s) from [" + url + "]", 80),
433                 "Error", JvOptionPane.ERROR_MESSAGE);
434       }
435       if ((trees != null) && (trees.length > 0))
436       {
437         try
438         {
439           JvOptionPane.showMessageDialog(null,
440                   ForesterUtil.wordWrap("Successfully read in "
441                           + trees.length + " tree(s) from [" + url + "]",
442                           80),
443                   "Success", JvOptionPane.INFORMATION_MESSAGE);
444         } catch (final Exception e)
445         {
446           // Not important if this fails, do nothing.
447         }
448         // _main_frame.getContentPane().repaint();
449       }
450     }
451
452     System.gc();
453
454
455     if (Desktop.instance != null)
456     {
457       Desktop.instance.stopLoading();
458     }
459     return null;
460
461
462   }
463
464
465
466
467
468   public static MainFrame createAptxFrame(
469           final Phylogeny aptxTree,
470           final AlignmentViewport jalviewAlignport, String treeTitle)
471   {
472     MainFrame aptxApp = Archaeopteryx.createApplication(aptxTree,
473             APTX_CONFIG, treeTitle);
474     // addPartitioningSlider(aptxApp);
475
476
477     LoadedTreeAssociation bindAptxNodes = new LoadedTreeAssociation(
478             jalviewAlignport.getAlignment().getSequencesArray(), aptxTree);
479
480     bindAptxNodes.associateLeavesToSequences();
481     bindNodesToJalviewSequences(aptxApp, jalviewAlignport,
482             bindAptxNodes.getAlignmentWithNodes(),
483             bindAptxNodes.getNodesWithAlignment());
484     bindFrameToJalview(aptxApp);
485     return aptxApp;
486   }
487
488   // private static void addPartitioningSlider(MainFrame aptxFrame)
489   // {
490   // JSlider slider = new JSlider();
491   //
492   //
493   // }
494
495   public static ExternalTreeViewerBindingI<?> bindNodesToJalviewSequences(
496           final MainFrame aptxApp,
497           final AlignmentViewport jalviewAlignViewport,
498           final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
499           final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
500   {
501     return new JalviewBinding(aptxApp, jalviewAlignViewport,
502             alignMappedToNodes, nodesMappedToAlign);
503   }
504
505
506   public static MainFrame bindFrameToJalview(final MainFrame aptxApp)
507   {
508     int width = 400;
509     int height = 550;
510     aptxApp.setMinimumSize(new Dimension(width, height));
511     // aptxApp.setFont(Desktop.instance.getFont());
512     // aptxApp.getMainPanel().setFont(Desktop.instance.getFont());
513
514     Desktop.addInternalFrame(aptxApp, "Archaeopteryx Tree View", true,
515             width, height, true, true);
516
517     return aptxApp;
518
519   }
520
521
522
523 }