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