Merge branch 'develop' of https://source.jalview.org/git/jalview.git into kjvdh/featu...
authorkjvdheide <kjvanderheide@dundee.ac.uk>
Thu, 25 Jan 2018 18:57:58 +0000 (18:57 +0000)
committerkjvdheide <kjvanderheide@dundee.ac.uk>
Thu, 25 Jan 2018 18:57:58 +0000 (18:57 +0000)
101 files changed:
.classpath
.gitmodules [new file with mode: 0644]
.project
.settings/org.eclipse.jdt.core.prefs
.settings/org.eclipse.jdt.ui.prefs
build.xml
hs_err_pid28190.log [new file with mode: 0644]
lib/forester.jar [new file with mode: 0644]
resources/_aptx_jalview_configuration_file.txt [new file with mode: 0644]
resources/lang/Messages.properties
src/jalview/analysis/AlignmentSorter.java
src/jalview/analysis/TreeAlgorithm.java [new file with mode: 0644]
src/jalview/analysis/TreeBuilder.java
src/jalview/analysis/TreeCalculator.java [new file with mode: 0644]
src/jalview/analysis/TreeModel.java
src/jalview/appletgui/OverviewPanel.java
src/jalview/appletgui/PCAPanel.java
src/jalview/appletgui/RedundancyPanel.java
src/jalview/appletgui/TreePanel.java
src/jalview/bin/Jalview.java
src/jalview/ext/archaeopteryx/AptxControlPanel.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/AptxFrame.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/AptxInit.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/AptxTreeBuilder.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/AptxTreePanel.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/JalviewBinding.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/Tree.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/TreeIterator.java [new file with mode: 0644]
src/jalview/ext/archaeopteryx/TreeNode.java [new file with mode: 0644]
src/jalview/ext/forester/DataConversions.java [new file with mode: 0644]
src/jalview/ext/forester/ForesterMatrix.java [new file with mode: 0644]
src/jalview/ext/forester/io/ForesterParser.java [new file with mode: 0644]
src/jalview/ext/forester/io/NexusFile.java [new file with mode: 0644]
src/jalview/ext/forester/io/PhyloXmlFile.java [new file with mode: 0644]
src/jalview/ext/forester/io/SupportedTreeFileFilter.java [new file with mode: 0644]
src/jalview/ext/forester/io/TreeDatabaseMenuBuilder.java [new file with mode: 0644]
src/jalview/ext/forester/io/UtilityMethods.java [new file with mode: 0644]
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/ext/treeviewer/LoadedTreeAssociationI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/LoadedTreeSequenceAssociation.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeBuilderI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeControlsI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeFrameI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeNodeI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreePanelI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeParserI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeViewerBindingI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeViewerConfigI.java [new file with mode: 0644]
src/jalview/ext/treeviewer/TreeViewerUtils.java [new file with mode: 0644]
src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AppJmol.java
src/jalview/gui/CalculationChooser.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/Console.java
src/jalview/gui/DasSourceBrowser.java
src/jalview/gui/Desktop.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/JalviewDialog.java
src/jalview/gui/OverviewPanel.java
src/jalview/gui/PaintRefresher.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/RedundancyPanel.java
src/jalview/gui/SplashScreen.java
src/jalview/gui/StructureViewerBase.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/TreePanel.java
src/jalview/gui/TreeParams.java [new file with mode: 0644]
src/jalview/gui/VamsasApplication.java
src/jalview/gui/WebserviceInfo.java
src/jalview/gui/WsPreferences.java
src/jalview/io/BioJsHTMLOutput.java
src/jalview/io/FileFormat.java
src/jalview/io/FileFormatI.java
src/jalview/io/FileLoader.java
src/jalview/io/HtmlSvgOutput.java
src/jalview/io/IdentifyFile.java
src/jalview/io/NewickFile.java
src/jalview/javascript/JSFunctionExec.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/math/Matrix.java
src/jalview/math/MatrixI.java
src/jalview/schemabinding/version2/JalviewModelSequence.java
src/jalview/util/AWTConsole.java
src/jalview/util/DBRefUtils.java
src/jalview/util/MappingUtils.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/DasSequenceFeatureFetcher.java
src/jalview/ws/jws1/Discoverer.java
src/jalview/ws/jws2/Jws2Discoverer.java
test/jalview/ext/archaeopteryx/AptxJalviewSequenceTreeTest.java [new file with mode: 0644]
test/jalview/ext/archaeopteryx/AptxPhylogenyTreeTest.java [new file with mode: 0644]
test/jalview/ext/archaeopteryx/TreeViewTest.java [new file with mode: 0644]
test/jalview/gui/FreeUpMemoryTest.java
test/jalview/io/NewickFileTests.java
utils/proguard.jar [deleted file]
utils/proguard_5.3.3.jar [new file with mode: 0755]

index d704f10..f4d387c 100644 (file)
@@ -69,5 +69,6 @@
        <classpathentry kind="lib" path="lib/biojava-core-4.1.0.jar"/>
        <classpathentry kind="lib" path="lib/biojava-ontology-4.1.0.jar"/>
        <classpathentry kind="lib" path="lib/groovy-all-2.4.12-indy.jar"/>
+       <classpathentry kind="lib" path="lib/forester.jar"/>
        <classpathentry kind="output" path="classes"/>
 </classpath>
diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..e69de29
index d0dfc7e..b24880a 100644 (file)
--- a/.project
+++ b/.project
@@ -3,6 +3,7 @@
        <name>Jalview Release 2.7</name>
        <comment></comment>
        <projects>
+               <project>forester</project>
        </projects>
        <buildSpec>
                <buildCommand>
index 8a5e7a7..12c11f0 100644 (file)
@@ -1,15 +1,16 @@
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=52
@@ -23,8 +24,10 @@ org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
@@ -34,6 +37,8 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration
 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
 org.eclipse.jdt.core.formatter.blank_lines_after_package=1
@@ -60,6 +65,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
 org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
 org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
 org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
 org.eclipse.jdt.core.formatter.comment.format_block_comments=false
 org.eclipse.jdt.core.formatter.comment.format_header=false
 org.eclipse.jdt.core.formatter.comment.format_html=true
@@ -92,6 +98,7 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
 org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
@@ -286,11 +293,24 @@ org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
 org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
 org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
 org.eclipse.jdt.core.formatter.tabulation.char=space
 org.eclipse.jdt.core.formatter.tabulation.size=2
 org.eclipse.jdt.core.formatter.use_on_off_tags=true
 org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
 org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
 org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
 org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
index 30e76be..699fd4a 100644 (file)
@@ -1,7 +1,7 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
 formatter_profile=_Jalview
-formatter_settings_version=12
+formatter_settings_version=13
 org.eclipse.jdt.ui.ignorelowercasenames=true
 org.eclipse.jdt.ui.importorder=jalview;java;javax;org;com;
 org.eclipse.jdt.ui.ondemandthreshold=99
index 4931cfb..e28ea5c 100755 (executable)
--- a/build.xml
+++ b/build.xml
     <!-- Anne's version needs 1.7 - should rebuild VARNA to java 1.6 for release -->
     <property name="j2sev" value="1.7+" />
     <!-- Java Compilation settings - source and target javac version -->
-    <property name="javac.source" value="1.7" />
-    <property name="javac.target" value="1.7" />
+    <property name="javac.source" value="1.8" />
+    <property name="javac.target" value="1.8" />
 
     <!-- Permissions for running Java applets and applications. -->
     <!-- Defaults are those suitable for deploying jalview webstart www.jalview.org -->
           <offline_allowed />
         </information>
         <resources>
-          <j2se version="1.7+" />
+          <j2se version="1.8+" />
           <jar main="true" href="jalview.jar"/>
           <fileset dir="${packageDir}">
             <exclude name="jalview.jar" />
 
     <jnlpf toFile="${jnlpFile}" />
     <!-- add the add-modules j2se attribute for java 9 -->
-    <replace file="${jnlpFile}" value="j2se version=&quot;1.7+&quot; initial-heap-size=&quot;${inih}&quot; max-heap-size=&quot;${maxh}&quot; java-vm-args=&quot;--add-modules=java.se.ee --illegal-access=warn&quot;">
-          <replacetoken>j2se version="1.7+"</replacetoken>
-           
+    <replace file="${jnlpFile}" value="j2se version=&quot;1.8+&quot; initial-heap-size=&quot;${inih}&quot; max-heap-size=&quot;${maxh}&quot; java-vm-args=&quot;--add-modules=java.se.ee&quot;">
+          <replacetoken>j2se version="1.8+"</replacetoken>
         </replace>
   </target>
 
       <include name="plugin.jar" />
     </fileset>
   </path>
-  <taskdef resource="proguard/ant/task.properties" classpath="utils/proguard.jar" />
+  <taskdef resource="proguard/ant/task.properties" classpath="utils/proguard_5.3.3.jar" />
 
   <proguard verbose="true" >
     <injar file="in.jar" />
diff --git a/hs_err_pid28190.log b/hs_err_pid28190.log
new file mode 100644 (file)
index 0000000..976d063
--- /dev/null
@@ -0,0 +1,642 @@
+#
+# A fatal error has been detected by the Java Runtime Environment:
+#
+#  SIGSEGV (0xb) at pc=0x0000000129be645f, pid=28190, tid=0x000000000000eb07
+#
+# JRE version: Java(TM) SE Runtime Environment (8.0_144-b01) (build 1.8.0_144-b01)
+# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode bsd-amd64 compressed oops)
+# Problematic frame:
+# C  [libawt_lwawt.dylib+0x1c45f]  OGLSD_SetScratchSurface+0x49
+#
+# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
+#
+# If you would like to submit a bug report, please visit:
+#   http://bugreport.java.com/bugreport/crash.jsp
+# The crash happened outside the Java Virtual Machine in native code.
+# See problematic frame for where to report the bug.
+#
+
+---------------  T H R E A D  ---------------
+
+Current thread (0x00007fb7d6a28000):  JavaThread "Java2D Queue Flusher" daemon [_thread_in_native, id=60167, stack(0x000070000a322000,0x000070000a422000)]
+
+siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000002
+
+Registers:
+RAX=0x0000000129c06d0e, RBX=0x0000000000000002, RCX=0x0000000000000047, RDX=0x0000000129c07258
+RSP=0x000070000a421730, RBP=0x000070000a421750, RSI=0x00007fb7dc2381e0, RDI=0x00007fb7d6a281f8
+R8 =0x00000000000002d5, R9 =0x000000000190822f, R10=0x000000010e0ee8f8, R11=0x000000010e6e8100
+R12=0x0000000000000000, R13=0x000070000a4218e8, R14=0x00007fb7d6a281f8, R15=0x00007fb7d6a28000
+RIP=0x0000000129be645f, EFLAGS=0x0000000000010202, ERR=0x0000000000000004
+  TRAPNO=0x000000000000000e
+
+Top of Stack: (sp=0x000070000a421730)
+0x000070000a421730:   00007fb7dc2381e0 0000000000000000
+0x000070000a421740:   00007fb7d6a5d610 00007fb7d6a28000
+0x000070000a421750:   000070000a4217d0 0000000129c06d36
+0x000070000a421760:   00007fb7d648b700 0000000200000001
+0x000070000a421770:   0000000000000000 000070000a421800
+0x000070000a421780:   0000000000000000 0000000000000000
+0x000070000a421790:   000070000a4217d0 00007fb7d6a5d620
+0x000070000a4217a0:   00000000005effd0 00007fb7d6a281f8
+0x000070000a4217b0:   000000016d2bc370 0000000000000000
+0x000070000a4217c0:   000070000a421968 00007fb7d6a28000
+0x000070000a4217d0:   000070000a421820 000000010e0ee96a
+0x000070000a4217e0:   00000006c00a3af8 000000010d138a00
+0x000070000a4217f0:   0000000000000064 0000000000000000
+0x000070000a421800:   0000000000000064 00007fb7d648b1e8
+0x000070000a421810:   000070000a421870 000000010cf501e8
+0x000070000a421820:   000070000a421940 000000010e6e86fc
+0x000070000a421830:   0000000000000001 00007fb7d648bea0
+0x000070000a421840:   00000006c00a3b00 00007fb7d6a28000
+0x000070000a421850:   00007fb7d6a28000 00000001258fda00
+0x000070000a421860:   000070000a421968 00007fb7d6a28000
+0x000070000a421870:   000070000a4218c0 000000010e2f2968
+0x000070000a421880:   00000006c00a3af8 000000010e5aafe6
+0x000070000a421890:   000070000a421940 000000010e6e815c
+0x000070000a4218a0:   000000012f278bb4 000070000a4218e8
+0x000070000a4218b0:   000000012f278c30 0000000000000000
+0x000070000a4218c0:   000070000a421940 000000010dbaf2bd
+0x000070000a4218d0:   000070000a421940 000000010dbaf2bd
+0x000070000a4218e0:   000000010dbaf2bd 00000006c00a3af8
+0x000070000a4218f0:   0000000000000001 00000006c00a3b80
+0x000070000a421900:   000070000a4218f0 000000012e64d689
+0x000070000a421910:   000070000a421968 000000012e64d820
+0x000070000a421920:   0000000000000000 000000012e64d790 
+
+Instructions: (pc=0x0000000129be645f)
+0x0000000129be643f:   c0 e9 82 00 00 00 48 8b 5e 10 48 85 db 75 0e bf
+0x0000000129be644f:   01 00 00 00 48 8d 15 67 7b 03 00 eb d6 49 89 fe
+0x0000000129be645f:   4c 8b 3b 30 c0 e8 21 a6 02 00 49 8b 3f 49 89 c4
+0x0000000129be646f:   48 8b 35 aa 02 06 00 30 c0 e8 51 a7 02 00 48 85 
+
+Register to memory mapping:
+
+RAX=0x0000000129c06d0e: Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer+0x612 in /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libawt_lwawt.dylib at 0x0000000129bca000
+RBX=0x0000000000000002 is an unknown value
+RCX=0x0000000000000047 is an unknown value
+RDX=0x0000000129c07258: Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer+0xb5c in /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libawt_lwawt.dylib at 0x0000000129bca000
+RSP=0x000070000a421730 is pointing into the stack for thread: 0x00007fb7d6a28000
+RBP=0x000070000a421750 is pointing into the stack for thread: 0x00007fb7d6a28000
+RSI=0x00007fb7dc2381e0 is an unknown value
+RDI=0x00007fb7d6a281f8 is an unknown value
+R8 =0x00000000000002d5 is an unknown value
+R9 =0x000000000190822f is an unknown value
+R10=0x000000010e0ee8f8 is at entry_point+56 in (nmethod*)0x000000010e0ee750
+R11=0x000000010e6e8100 is at entry_point+0 in (nmethod*)0x000000010e6e7f90
+R12=0x0000000000000000 is an unknown value
+R13=0x000070000a4218e8 is pointing into the stack for thread: 0x00007fb7d6a28000
+R14=0x00007fb7d6a281f8 is an unknown value
+R15=0x00007fb7d6a28000 is a thread
+
+
+Stack: [0x000070000a322000,0x000070000a422000],  sp=0x000070000a421730,  free space=1021k
+Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
+C  [libawt_lwawt.dylib+0x1c45f]  OGLSD_SetScratchSurface+0x49
+C  [libawt_lwawt.dylib+0x3cd36]  Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer+0x63a
+J 4748  sun.java2d.opengl.OGLRenderQueue.flushBuffer(JI)V (0 bytes) @ 0x000000010e0ee96a [0x000000010e0ee8c0+0xaa]
+J 3668 C1 sun.java2d.opengl.OGLRenderQueue.flushBuffer()V (41 bytes) @ 0x000000010e6e86fc [0x000000010e6e84a0+0x25c]
+J 3667 C1 sun.java2d.opengl.OGLRenderQueue.access$100(Lsun/java2d/opengl/OGLRenderQueue;)V (5 bytes) @ 0x000000010e6e815c [0x000000010e6e8100+0x5c]
+j  sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run()V+81
+v  ~StubRoutines::call_stub
+V  [libjvm.dylib+0x2ee70a]
+V  [libjvm.dylib+0x2eeeae]
+V  [libjvm.dylib+0x2ef05a]
+V  [libjvm.dylib+0x3497b1]
+V  [libjvm.dylib+0x56c0b3]
+V  [libjvm.dylib+0x56d7a0]
+V  [libjvm.dylib+0x48baee]
+C  [libsystem_pthread.dylib+0x393b]  _pthread_body+0xb4
+C  [libsystem_pthread.dylib+0x3887]  _pthread_body+0x0
+C  [libsystem_pthread.dylib+0x308d]  thread_start+0xd
+C  0x0000000000000000
+
+Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
+J 4748  sun.java2d.opengl.OGLRenderQueue.flushBuffer(JI)V (0 bytes) @ 0x000000010e0ee8f8 [0x000000010e0ee8c0+0x38]
+J 3668 C1 sun.java2d.opengl.OGLRenderQueue.flushBuffer()V (41 bytes) @ 0x000000010e6e86fc [0x000000010e6e84a0+0x25c]
+J 3667 C1 sun.java2d.opengl.OGLRenderQueue.access$100(Lsun/java2d/opengl/OGLRenderQueue;)V (5 bytes) @ 0x000000010e6e815c [0x000000010e6e8100+0x5c]
+j  sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run()V+81
+v  ~StubRoutines::call_stub
+
+---------------  P R O C E S S  ---------------
+
+Java Threads: ( => current thread )
+  0x00007fb7d92c2000 JavaThread "class jalview.workers.ConservationThread" [_thread_in_Java, id=84243, stack(0x000070000acc0000,0x000070000adc0000)]
+  0x00007fb7d6c86000 JavaThread "Image Fetcher 0" daemon [_thread_blocked, id=46819, stack(0x000070000abbd000,0x000070000acbd000)]
+  0x00007fb7d6996800 JavaThread "LoadFileThread" [_thread_blocked, id=71699, stack(0x000070000aaba000,0x000070000abba000)]
+  0x00007fb7d935c800 JavaThread "TimerQueue" daemon [_thread_blocked, id=81411, stack(0x000070000b14f000,0x000070000b24f000)]
+  0x00007fb7d6bc7800 JavaThread "DestroyJavaVM" [_thread_blocked, id=7171, stack(0x0000700008b54000,0x0000700008c54000)]
+  0x00007fb7d9213800 JavaThread "pool-1-thread-1" [_thread_blocked, id=70863, stack(0x000070000a934000,0x000070000aa34000)]
+  0x00007fb7d7389000 JavaThread "ConsoleTextAppendThread" daemon [_thread_blocked, id=69379, stack(0x000070000a831000,0x000070000a931000)]
+  0x00007fb7d7388000 JavaThread "ConsoleReader2Thread" daemon [_thread_blocked, id=68867, stack(0x000070000a72e000,0x000070000a82e000)]
+  0x00007fb7d7387800 JavaThread "ConsoleReader1Thread" daemon [_thread_blocked, id=68363, stack(0x000070000a62b000,0x000070000a72b000)]
+  0x00007fb7d7344800 JavaThread "AWT-EventQueue-0" [_thread_blocked, id=62987, stack(0x000070000a528000,0x000070000a628000)]
+  0x00007fb7d7313800 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=62479, stack(0x000070000a425000,0x000070000a525000)]
+=>0x00007fb7d6a28000 JavaThread "Java2D Queue Flusher" daemon [_thread_in_native, id=60167, stack(0x000070000a322000,0x000070000a422000)]
+  0x00007fb7da830800 JavaThread "AWT-Shutdown" [_thread_blocked, id=32287, stack(0x0000700009f10000,0x000070000a010000)]
+  0x00007fb7d69c8800 JavaThread "AppKit Thread" daemon [_thread_in_native, id=775, stack(0x00007fff54a39000,0x00007fff55239000)]
+  0x00007fb7d8065800 JavaThread "Service Thread" daemon [_thread_blocked, id=20995, stack(0x0000700009c87000,0x0000700009d87000)]
+  0x00007fb7d6800800 JavaThread "C1 CompilerThread3" daemon [_thread_blocked, id=20483, stack(0x0000700009b84000,0x0000700009c84000)]
+  0x00007fb7d8044800 JavaThread "C2 CompilerThread2" daemon [_thread_blocked, id=19971, stack(0x0000700009a81000,0x0000700009b81000)]
+  0x00007fb7d7044000 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=19459, stack(0x000070000997e000,0x0000700009a7e000)]
+  0x00007fb7d7011000 JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=18947, stack(0x000070000987b000,0x000070000997b000)]
+  0x00007fb7d702a800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=18435, stack(0x0000700009778000,0x0000700009878000)]
+  0x00007fb7d802a000 JavaThread "Finalizer" daemon [_thread_blocked, id=14595, stack(0x0000700009675000,0x0000700009775000)]
+  0x00007fb7d8027000 JavaThread "Reference Handler" daemon [_thread_blocked, id=14083, stack(0x0000700009572000,0x0000700009672000)]
+
+Other Threads:
+  0x00007fb7d9012800 VMThread [stack: 0x000070000946f000,0x000070000956f000] [id=13571]
+  0x00007fb7d8076000 WatcherThread [stack: 0x0000700009d8a000,0x0000700009e8a000] [id=21507]
+
+VM state:not at safepoint (normal execution)
+
+VM Mutex/Monitor currently owned by a thread: None
+
+Heap:
+ PSYoungGen      total 86528K, used 20241K [0x000000076ab00000, 0x0000000774800000, 0x00000007c0000000)
+  eden space 75776K, 15% used [0x000000076ab00000,0x000000076b683258,0x000000076f500000)
+  from space 10752K, 78% used [0x000000076f600000,0x000000076fe413f8,0x0000000770080000)
+  to   space 42496K, 0% used [0x0000000771e80000,0x0000000771e80000,0x0000000774800000)
+ ParOldGen       total 209920K, used 31492K [0x00000006c0000000, 0x00000006ccd00000, 0x000000076ab00000)
+  object space 209920K, 15% used [0x00000006c0000000,0x00000006c1ec11e8,0x00000006ccd00000)
+ Metaspace       used 37085K, capacity 37796K, committed 38016K, reserved 1083392K
+  class space    used 4752K, capacity 4927K, committed 4992K, reserved 1048576K
+
+Card table byte_map: [0x000000010ae5a000,0x000000010b65b000] byte_map_base: 0x000000010785a000
+
+Marking Bits: (ParMarkBitMap*) 0x000000010d4f35d0
+ Begin Bits: [0x000000011d0fd000, 0x00000001210fd000)
+ End Bits:   [0x00000001210fd000, 0x00000001250fd000)
+
+Polling page: 0x000000010aa87000
+
+CodeCache: size=245760Kb used=15978Kb max_used=15978Kb free=229781Kb
+ bounds [0x000000010dba7000, 0x000000010eb57000, 0x000000011cba7000]
+ total_blobs=5726 nmethods=5006 adapters=631
+ compilation: enabled
+
+Compilation events (10 events):
+Event: 1054.326 Thread 0x00007fb7d8044800 nmethod 5621 0x000000010eb34b10 code [0x000000010eb34c60, 0x000000010eb34cd8]
+Event: 1054.327 Thread 0x00007fb7d6800800 5622       3       javax.swing.DefaultButtonModel::isArmed (15 bytes)
+Event: 1054.327 Thread 0x00007fb7d6800800 nmethod 5622 0x000000010eb343d0 code [0x000000010eb34540, 0x000000010eb346f0]
+Event: 1054.346 Thread 0x00007fb7d6800800 5623 %     3       jalview.schemes.ResidueProperties::buildAmbiguityCodonSet @ 657 (878 bytes)
+Event: 1054.350 Thread 0x00007fb7d6800800 nmethod 5623% 0x000000010eb34d90 code [0x000000010eb357e0, 0x000000010eb3e3f8]
+Event: 1054.351 Thread 0x00007fb7d6800800 5624       3       jalview.schemes.ResidueProperties::buildAmbiguityCodonSet (878 bytes)
+Event: 1054.363 Thread 0x00007fb7d6800800 nmethod 5624 0x000000010eb45590 code [0x000000010eb45fc0, 0x000000010eb4e878]
+Event: 1054.363 Thread 0x00007fb7d6800800 5625       3       java.io.FileInputStream::finalize (22 bytes)
+Event: 1054.363 Thread 0x00007fb7d6800800 nmethod 5625 0x000000010eb33f50 code [0x000000010eb340c0, 0x000000010eb34348]
+Event: 1054.364 Thread 0x00007fb7d7011000 5626 %     4       jalview.schemes.ResidueProperties::buildAmbiguityCodonSet @ 575 (878 bytes)
+
+GC Heap History (10 events):
+Event: 8.499 GC heap before
+{Heap before GC invocations=3 (full 1):
+ PSYoungGen      total 76288K, used 65536K [0x000000076ab00000, 0x0000000770000000, 0x00000007c0000000)
+  eden space 65536K, 100% used [0x000000076ab00000,0x000000076eb00000,0x000000076eb00000)
+  from space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000)
+  to   space 10752K, 0% used [0x000000076f580000,0x000000076f580000,0x0000000770000000)
+ ParOldGen       total 121856K, used 7919K [0x00000006c0000000, 0x00000006c7700000, 0x000000076ab00000)
+  object space 121856K, 6% used [0x00000006c0000000,0x00000006c07bbd10,0x00000006c7700000)
+ Metaspace       used 32188K, capacity 32772K, committed 33024K, reserved 1077248K
+  class space    used 4214K, capacity 4351K, committed 4352K, reserved 1048576K
+Event: 8.510 GC heap after
+Heap after GC invocations=3 (full 1):
+ PSYoungGen      total 76288K, used 10746K [0x000000076ab00000, 0x0000000770d80000, 0x00000007c0000000)
+  eden space 65536K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076eb00000)
+  from space 10752K, 99% used [0x000000076f580000,0x000000076fffe850,0x0000000770000000)
+  to   space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000)
+ ParOldGen       total 121856K, used 24160K [0x00000006c0000000, 0x00000006c7700000, 0x000000076ab00000)
+  object space 121856K, 19% used [0x00000006c0000000,0x00000006c17980a8,0x00000006c7700000)
+ Metaspace       used 32188K, capacity 32772K, committed 33024K, reserved 1077248K
+  class space    used 4214K, capacity 4351K, committed 4352K, reserved 1048576K
+}
+Event: 28.095 GC heap before
+{Heap before GC invocations=4 (full 1):
+ PSYoungGen      total 76288K, used 76282K [0x000000076ab00000, 0x0000000770d80000, 0x00000007c0000000)
+  eden space 65536K, 100% used [0x000000076ab00000,0x000000076eb00000,0x000000076eb00000)
+  from space 10752K, 99% used [0x000000076f580000,0x000000076fffe850,0x0000000770000000)
+  to   space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000)
+ ParOldGen       total 121856K, used 24160K [0x00000006c0000000, 0x00000006c7700000, 0x000000076ab00000)
+  object space 121856K, 19% used [0x00000006c0000000,0x00000006c17980a8,0x00000006c7700000)
+ Metaspace       used 34471K, capacity 35178K, committed 35456K, reserved 1079296K
+  class space    used 4439K, capacity 4626K, committed 4736K, reserved 1048576K
+Event: 28.111 GC heap after
+Heap after GC invocations=4 (full 1):
+ PSYoungGen      total 76288K, used 10746K [0x000000076ab00000, 0x0000000770b00000, 0x00000007c0000000)
+  eden space 65536K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076eb00000)
+  from space 10752K, 99% used [0x000000076eb00000,0x000000076f57e870,0x000000076f580000)
+  to   space 10752K, 0% used [0x0000000770080000,0x0000000770080000,0x0000000770b00000)
+ ParOldGen       total 121856K, used 49145K [0x00000006c0000000, 0x00000006c7700000, 0x000000076ab00000)
+  object space 121856K, 40% used [0x00000006c0000000,0x00000006c2ffe560,0x00000006c7700000)
+ Metaspace       used 34471K, capacity 35178K, committed 35456K, reserved 1079296K
+  class space    used 4439K, capacity 4626K, committed 4736K, reserved 1048576K
+}
+Event: 28.286 GC heap before
+{Heap before GC invocations=5 (full 1):
+ PSYoungGen      total 76288K, used 21665K [0x000000076ab00000, 0x0000000770b00000, 0x00000007c0000000)
+  eden space 65536K, 16% used [0x000000076ab00000,0x000000076b5a9db8,0x000000076eb00000)
+  from space 10752K, 99% used [0x000000076eb00000,0x000000076f57e870,0x000000076f580000)
+  to   space 10752K, 0% used [0x0000000770080000,0x0000000770080000,0x0000000770b00000)
+ ParOldGen       total 121856K, used 49145K [0x00000006c0000000, 0x00000006c7700000, 0x000000076ab00000)
+  object space 121856K, 40% used [0x00000006c0000000,0x00000006c2ffe560,0x00000006c7700000)
+ Metaspace       used 34701K, capacity 35362K, committed 35456K, reserved 1079296K
+  class space    used 4482K, capacity 4662K, committed 4736K, reserved 1048576K
+Event: 28.293 GC heap after
+Heap after GC invocations=5 (full 1):
+ PSYoungGen      total 87552K, used 10724K [0x000000076ab00000, 0x0000000772080000, 0x00000007c0000000)
+  eden space 76800K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076f600000)
+  from space 10752K, 99% used [0x0000000770080000,0x0000000770af9260,0x0000000770b00000)
+  to   space 10752K, 0% used [0x000000076f600000,0x000000076f600000,0x0000000770080000)
+ ParOldGen       total 121856K, used 50465K [0x00000006c0000000, 0x00000006c7700000, 0x000000076ab00000)
+  object space 121856K, 41% used [0x00000006c0000000,0x00000006c3148700,0x00000006c7700000)
+ Metaspace       used 34701K, capacity 35362K, committed 35456K, reserved 1079296K
+  class space    used 4482K, capacity 4662K, committed 4736K, reserved 1048576K
+}
+Event: 28.293 GC heap before
+{Heap before GC invocations=6 (full 2):
+ PSYoungGen      total 87552K, used 10724K [0x000000076ab00000, 0x0000000772080000, 0x00000007c0000000)
+  eden space 76800K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076f600000)
+  from space 10752K, 99% used [0x0000000770080000,0x0000000770af9260,0x0000000770b00000)
+  to   space 10752K, 0% used [0x000000076f600000,0x000000076f600000,0x0000000770080000)
+ ParOldGen       total 121856K, used 50465K [0x00000006c0000000, 0x00000006c7700000, 0x000000076ab00000)
+  object space 121856K, 41% used [0x00000006c0000000,0x00000006c3148700,0x00000006c7700000)
+ Metaspace       used 34701K, capacity 35362K, committed 35456K, reserved 1079296K
+  class space    used 4482K, capacity 4662K, committed 4736K, reserved 1048576K
+Event: 28.336 GC heap after
+Heap after GC invocations=6 (full 2):
+ PSYoungGen      total 87552K, used 0K [0x000000076ab00000, 0x0000000772080000, 0x00000007c0000000)
+  eden space 76800K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076f600000)
+  from space 10752K, 0% used [0x0000000770080000,0x0000000770080000,0x0000000770b00000)
+  to   space 10752K, 0% used [0x000000076f600000,0x000000076f600000,0x0000000770080000)
+ ParOldGen       total 209920K, used 22383K [0x00000006c0000000, 0x00000006ccd00000, 0x000000076ab00000)
+  object space 209920K, 10% used [0x00000006c0000000,0x00000006c15dbcc8,0x00000006ccd00000)
+ Metaspace       used 34701K, capacity 35362K, committed 35456K, reserved 1079296K
+  class space    used 4482K, capacity 4662K, committed 4736K, reserved 1048576K
+}
+Event: 1054.355 GC heap before
+{Heap before GC invocations=7 (full 2):
+ PSYoungGen      total 87552K, used 76800K [0x000000076ab00000, 0x0000000772080000, 0x00000007c0000000)
+  eden space 76800K, 100% used [0x000000076ab00000,0x000000076f600000,0x000000076f600000)
+  from space 10752K, 0% used [0x0000000770080000,0x0000000770080000,0x0000000770b00000)
+  to   space 10752K, 0% used [0x000000076f600000,0x000000076f600000,0x0000000770080000)
+ ParOldGen       total 209920K, used 22383K [0x00000006c0000000, 0x00000006ccd00000, 0x000000076ab00000)
+  object space 209920K, 10% used [0x00000006c0000000,0x00000006c15dbcc8,0x00000006ccd00000)
+ Metaspace       used 37084K, capacity 37796K, committed 38016K, reserved 1083392K
+  class space    used 4752K, capacity 4927K, committed 4992K, reserved 1048576K
+Event: 1054.361 GC heap after
+Heap after GC invocations=7 (full 2):
+ PSYoungGen      total 86528K, used 8452K [0x000000076ab00000, 0x0000000774800000, 0x00000007c0000000)
+  eden space 75776K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076f500000)
+  from space 10752K, 78% used [0x000000076f600000,0x000000076fe413f8,0x0000000770080000)
+  to   space 42496K, 0% used [0x0000000771e80000,0x0000000771e80000,0x0000000774800000)
+ ParOldGen       total 209920K, used 31492K [0x00000006c0000000, 0x00000006ccd00000, 0x000000076ab00000)
+  object space 209920K, 15% used [0x00000006c0000000,0x00000006c1ec11e8,0x00000006ccd00000)
+ Metaspace       used 37084K, capacity 37796K, committed 38016K, reserved 1083392K
+  class space    used 4752K, capacity 4927K, committed 4992K, reserved 1048576K
+}
+
+Deoptimization events (10 events):
+Event: 1012.924 Thread 0x00007fb7d7344800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000010e9f3390 method=java.awt.LightweightDispatcher.processMouseEvent(Ljava/awt/event/MouseEvent;)Z @ 52
+Event: 1047.684 Thread 0x00007fb7d7344800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000010dd0e4a4 method=java.awt.font.FontRenderContext.equals(Ljava/awt/font/FontRenderContext;)Z @ 53
+Event: 1054.165 Thread 0x00007fb7d6996800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000010dd0ceac method=java.awt.EventQueue.setCurrentEventAndMostRecentTimeImpl(Ljava/awt/AWTEvent;)V @ 16
+Event: 1054.205 Thread 0x00007fb7d6996800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x000000010e197614 method=java.util.regex.Matcher.search(I)Z @ 86
+Event: 1054.205 Thread 0x00007fb7d6996800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x000000010e197614 method=java.util.regex.Matcher.search(I)Z @ 86
+Event: 1054.298 Thread 0x00007fb7d6996800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x000000010eacccb4 method=sun.java2d.loops.SurfaceType.pixelFor(ILjava/awt/image/ColorModel;)I @ 6
+Event: 1054.306 Thread 0x00007fb7d6996800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000010e19b9d4 method=java.awt.Component.isShowing()Z @ 20
+Event: 1054.306 Thread 0x00007fb7d6996800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000010ea97958 method=javax.swing.RepaintManager.addDirtyRegion0(Ljava/awt/Container;IIII)V @ 53
+Event: 1054.306 Thread 0x00007fb7d6996800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000010ea60790 method=javax.swing.RepaintManager.addDirtyRegion0(Ljava/awt/Container;IIII)V @ 53
+Event: 1054.306 Thread 0x00007fb7d6996800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000010ea46b30 method=javax.swing.RepaintManager.addDirtyRegion0(Ljava/awt/Container;IIII)V @ 53
+
+Internal exceptions (10 events):
+Event: 23.206 Thread 0x00007fb7d98fb800 Exception <a 'java/lang/ClassNotFoundException': com/sun/org/glassfish/hk2/osgiresourcelocator/ServiceLoader> (0x000000076e381ed8) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/classfile/systemDictionary.cp
+Event: 23.208 Thread 0x00007fb7d98fb800 Exception <a 'java/io/FileNotFoundException'> (0x000000076e3d4c68) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/prims/jni.cpp, line 709]
+Event: 23.492 Thread 0x00007fb7d98fb800 Exception <a 'java/lang/ClassNotFoundException': com/sun/org/glassfish/hk2/osgiresourcelocator/ServiceLoader> (0x000000076e616378) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/classfile/systemDictionary.cp
+Event: 23.495 Thread 0x00007fb7d98fb800 Exception <a 'java/lang/ClassNotFoundException': javax/servlet/ServletContext> (0x000000076e69f500) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/classfile/systemDictionary.cpp, line 210]
+Event: 23.718 Thread 0x00007fb7d98fb800 Exception <a 'java/lang/ClassNotFoundException': com/sun/org/glassfish/hk2/osgiresourcelocator/ServiceLoader> (0x000000076e722190) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/classfile/systemDictionary.cp
+Event: 23.719 Thread 0x00007fb7d98fb800 Exception <a 'java/io/FileNotFoundException'> (0x000000076e772ab8) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/prims/jni.cpp, line 709]
+Event: 23.847 Thread 0x00007fb7d98fb800 Exception <a 'java/lang/ClassNotFoundException': com/sun/org/glassfish/hk2/osgiresourcelocator/ServiceLoader> (0x000000076e9b3cd8) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/classfile/systemDictionary.cp
+Event: 23.850 Thread 0x00007fb7d98fb800 Exception <a 'java/lang/ClassNotFoundException': javax/servlet/ServletContext> (0x000000076ea3ab10) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/classfile/systemDictionary.cpp, line 210]
+Event: 28.222 Thread 0x00007fb7d68ba800 Exception <a 'java/io/FileNotFoundException'> (0x000000076b08b318) thrown at [/Users/java_re/workspace/8-2-build-macosx-x86_64/jdk8u144/9417/hotspot/src/share/vm/prims/jni.cpp, line 709]
+Event: 1047.684 Thread 0x00007fb7d7344800 Implicit null exception at 0x000000010dd0e2c2 to 0x000000010dd0e48d
+
+Events (10 events):
+Event: 1054.333 loading class jalview/schemes/RNAHelicesColour
+Event: 1054.333 loading class jalview/schemes/RNAHelicesColour done
+Event: 1054.334 loading class jalview/schemes/TCoffeeColourScheme
+Event: 1054.334 loading class jalview/schemes/TCoffeeColourScheme done
+Event: 1054.335 loading class jalview/schemes/Consensus
+Event: 1054.335 loading class jalview/schemes/Consensus done
+Event: 1054.335 loading class jalview/api/analysis/PairwiseScoreModelI
+Event: 1054.335 loading class jalview/api/analysis/PairwiseScoreModelI done
+Event: 1054.355 Executing VM operation: ParallelGCFailedAllocation
+Event: 1054.361 Executing VM operation: ParallelGCFailedAllocation done
+
+
+Dynamic libraries:
+0x000000004dd98000     /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
+0x000000004dd98000     /System/Library/Frameworks/Security.framework/Versions/A/Security
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
+0x000000004dd98000     /usr/lib/libz.1.dylib
+0x000000004dd98000     /usr/lib/libSystem.B.dylib
+0x000000004dd98000     /usr/lib/libobjc.A.dylib
+0x000000004dd98000     /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+0x000000004dd98000     /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
+0x000000004dd98000     /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
+0x000000004dd98000     /System/Library/Frameworks/CoreData.framework/Versions/A/CoreData
+0x000000004dd98000     /System/Library/PrivateFrameworks/RemoteViewServices.framework/Versions/A/RemoteViewServices
+0x000000004dd98000     /System/Library/PrivateFrameworks/UIFoundation.framework/Versions/A/UIFoundation
+0x000000004dd98000     /System/Library/PrivateFrameworks/DFRFoundation.framework/Versions/A/DFRFoundation
+0x000000004dd98000     /usr/lib/libenergytrace.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/SkyLight.framework/Versions/A/SkyLight
+0x000000004dd98000     /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics
+0x000000004dd98000     /usr/lib/libScreenReader.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate
+0x000000004dd98000     /System/Library/Frameworks/IOSurface.framework/Versions/A/IOSurface
+0x000000004dd98000     /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox
+0x000000004dd98000     /System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit
+0x000000004dd98000     /System/Library/PrivateFrameworks/DataDetectorsCore.framework/Versions/A/DataDetectorsCore
+0x000000004dd98000     /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox
+0x000000004dd98000     /usr/lib/libicucore.A.dylib
+0x000000004dd98000     /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SpeechRecognition.framework/Versions/A/SpeechRecognition
+0x000000004dd98000     /usr/lib/libauto.dylib
+0x000000004dd98000     /usr/lib/libxml2.2.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/CoreUI.framework/Versions/A/CoreUI
+0x000000004dd98000     /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio
+0x000000004dd98000     /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration
+0x000000004dd98000     /usr/lib/liblangid.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/A/MultitouchSupport
+0x000000004dd98000     /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
+0x000000004dd98000     /usr/lib/libDiagnosticMessagesClient.dylib
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
+0x000000004dd98000     /System/Library/PrivateFrameworks/PerformanceAnalysis.framework/Versions/A/PerformanceAnalysis
+0x000000004dd98000     /System/Library/PrivateFrameworks/GenerationalStorage.framework/Versions/A/GenerationalStorage
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL
+0x000000004dd98000     /System/Library/Frameworks/CoreImage.framework/Versions/A/CoreImage
+0x000000004dd98000     /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText
+0x000000004dd98000     /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
+0x000000004dd98000     /System/Library/PrivateFrameworks/Backup.framework/Versions/A/Backup
+0x000000004dd98000     /usr/lib/libarchive.2.dylib
+0x000000004dd98000     /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork
+0x000000004dd98000     /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration
+0x000000004dd98000     /usr/lib/libCRFSuite.dylib
+0x000000004dd98000     /usr/lib/libc++.1.dylib
+0x000000004dd98000     /usr/lib/libc++abi.dylib
+0x000000004dd98000     /usr/lib/system/libcache.dylib
+0x000000004dd98000     /usr/lib/system/libcommonCrypto.dylib
+0x000000004dd98000     /usr/lib/system/libcompiler_rt.dylib
+0x000000004dd98000     /usr/lib/system/libcopyfile.dylib
+0x000000004dd98000     /usr/lib/system/libcorecrypto.dylib
+0x000000004dd98000     /usr/lib/system/libdispatch.dylib
+0x000000004dd98000     /usr/lib/system/libdyld.dylib
+0x000000004dd98000     /usr/lib/system/libkeymgr.dylib
+0x000000004dd98000     /usr/lib/system/liblaunch.dylib
+0x000000004dd98000     /usr/lib/system/libmacho.dylib
+0x000000004dd98000     /usr/lib/system/libquarantine.dylib
+0x000000004dd98000     /usr/lib/system/libremovefile.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_asl.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_blocks.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_c.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_configuration.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_coreservices.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_coretls.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_dnssd.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_info.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_kernel.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_m.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_malloc.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_network.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_networkextension.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_notify.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_platform.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_pthread.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_sandbox.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_secinit.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_symptoms.dylib
+0x000000004dd98000     /usr/lib/system/libsystem_trace.dylib
+0x000000004dd98000     /usr/lib/system/libunwind.dylib
+0x000000004dd98000     /usr/lib/system/libxpc.dylib
+0x000000004dd98000     /usr/lib/libbsm.0.dylib
+0x000000004dd98000     /usr/lib/system/libkxld.dylib
+0x000000004dd98000     /usr/lib/libcoretls.dylib
+0x000000004dd98000     /usr/lib/libcoretls_cfhelpers.dylib
+0x000000004dd98000     /usr/lib/libOpenScriptingUtil.dylib
+0x000000004dd98000     /usr/lib/libpam.2.dylib
+0x000000004dd98000     /usr/lib/libsqlite3.dylib
+0x000000004dd98000     /usr/lib/libxar.1.dylib
+0x000000004dd98000     /usr/lib/libbz2.1.0.dylib
+0x000000004dd98000     /usr/lib/liblzma.5.dylib
+0x000000004dd98000     /usr/lib/libnetwork.dylib
+0x000000004dd98000     /usr/lib/libpcap.A.dylib
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/FSEvents
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices
+0x000000004dd98000     /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SharedFileList.framework/Versions/A/SharedFileList
+0x000000004dd98000     /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS
+0x000000004dd98000     /System/Library/PrivateFrameworks/NetAuth.framework/Versions/A/NetAuth
+0x000000004dd98000     /System/Library/PrivateFrameworks/login.framework/Versions/A/Frameworks/loginsupport.framework/Versions/A/loginsupport
+0x000000004dd98000     /System/Library/PrivateFrameworks/TCC.framework/Versions/A/TCC
+0x000000004dd98000     /usr/lib/libmecabra.dylib
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSync.framework/Versions/A/ColorSync
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LangAnalysis.framework/Versions/A/LangAnalysis
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vImage.framework/Versions/A/vImage
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/vecLib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBNNS.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libQuadrature.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvMisc.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLinearAlgebra.dylib
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libSparseBLAS.dylib
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontParser.dylib
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontRegistry.dylib
+0x000000004dd98000     /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib
+0x000000004dd98000     /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib
+0x000000004dd98000     /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libPng.dylib
+0x000000004dd98000     /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libGIF.dylib
+0x000000004dd98000     /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJP2.dylib
+0x000000004dd98000     /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libRadiance.dylib
+0x000000004dd98000     /usr/lib/libcompression.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/AppleJPEG.framework/Versions/A/AppleJPEG
+0x000000004dd98000     /usr/lib/libcups.2.dylib
+0x000000004dd98000     /System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos
+0x000000004dd98000     /System/Library/Frameworks/GSS.framework/Versions/A/GSS
+0x000000004dd98000     /usr/lib/libresolv.9.dylib
+0x000000004dd98000     /usr/lib/libiconv.2.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/Heimdal.framework/Versions/A/Heimdal
+0x000000004dd98000     /usr/lib/libheimdal-asn1.dylib
+0x000000004dd98000     /System/Library/Frameworks/OpenDirectory.framework/Versions/A/OpenDirectory
+0x000000004dd98000     /System/Library/PrivateFrameworks/CommonAuth.framework/Versions/A/CommonAuth
+0x000000004dd98000     /System/Library/Frameworks/OpenDirectory.framework/Versions/A/Frameworks/CFOpenDirectory.framework/Versions/A/CFOpenDirectory
+0x000000004dd98000     /System/Library/Frameworks/SecurityFoundation.framework/Versions/A/SecurityFoundation
+0x000000004dd98000     /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
+0x000000004dd98000     /usr/lib/libmarisa.dylib
+0x000000004dd98000     /usr/lib/libChineseTokenizer.dylib
+0x000000004dd98000     /usr/lib/libcmph.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/CoreEmoji.framework/Versions/A/CoreEmoji
+0x000000004dd98000     /System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement
+0x000000004dd98000     /usr/lib/libxslt.1.dylib
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Ink.framework/Versions/A/Ink
+0x000000004dd98000     /System/Library/PrivateFrameworks/TextureIO.framework/Versions/A/TextureIO
+0x000000004dd98000     /System/Library/Frameworks/Metal.framework/Versions/A/Metal
+0x000000004dd98000     /usr/lib/libate.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/GPUCompiler.framework/libmetal_timestamp.dylib
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCoreFSCache.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/IOAccelerator.framework/Versions/A/IOAccelerator
+0x000000004dd98000     /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo
+0x000000004dd98000     /usr/lib/libFosl_dynamic.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/MetalPerformanceShaders.framework/Versions/A/MetalPerformanceShaders
+0x000000004dd98000     /System/Library/PrivateFrameworks/FaceCore.framework/Versions/A/FaceCore
+0x000000004dd98000     /System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGFXShared.dylib
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLImage.dylib
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCVMSPluginSupport.dylib
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCoreVMClient.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/CrashReporterSupport.framework/Versions/A/CrashReporterSupport
+0x000000004dd98000     /System/Library/PrivateFrameworks/Sharing.framework/Versions/A/Sharing
+0x000000004dd98000     /System/Library/PrivateFrameworks/IconServices.framework/Versions/A/IconServices
+0x000000004dd98000     /System/Library/PrivateFrameworks/ProtocolBuffer.framework/Versions/A/ProtocolBuffer
+0x000000004dd98000     /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Apple80211
+0x000000004dd98000     /System/Library/Frameworks/CoreWLAN.framework/Versions/A/CoreWLAN
+0x000000004dd98000     /System/Library/PrivateFrameworks/CoreUtils.framework/Versions/A/CoreUtils
+0x000000004dd98000     /System/Library/Frameworks/IOBluetooth.framework/Versions/A/IOBluetooth
+0x000000004dd98000     /System/Library/PrivateFrameworks/CoreWiFi.framework/Versions/A/CoreWiFi
+0x000000004dd98000     /System/Library/Frameworks/CoreBluetooth.framework/Versions/A/CoreBluetooth
+0x000000004dd98000     /System/Library/Frameworks/CoreDisplay.framework/Versions/A/CoreDisplay
+0x000000004dd98000     /System/Library/PrivateFrameworks/IOPresentment.framework/Versions/A/IOPresentment
+0x000000004dd98000     /System/Library/PrivateFrameworks/DSExternalDisplay.framework/Versions/A/DSExternalDisplay
+0x000000004dd98000     /System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols
+0x000000004dd98000     /System/Library/PrivateFrameworks/CoreSymbolication.framework/Versions/A/CoreSymbolication
+0x000000004dd98000     /System/Library/PrivateFrameworks/Symbolication.framework/Versions/A/Symbolication
+0x000000004dd98000     /System/Library/PrivateFrameworks/AppleFSCompression.framework/Versions/A/AppleFSCompression
+0x000000004dd98000     /System/Library/PrivateFrameworks/SpeechRecognitionCore.framework/Versions/A/SpeechRecognitionCore
+0x000000004dd98000     /System/Library/PrivateFrameworks/ChunkingLibrary.framework/Versions/A/ChunkingLibrary
+0x000000010cc00000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/server/libjvm.dylib
+0x000000004dd98000     /usr/lib/libstdc++.6.dylib
+0x000000010aa44000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libverify.dylib
+0x000000010aa52000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libjava.dylib
+0x000000010aa91000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libzip.dylib
+0x0000000127b9d000     /System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport
+0x000000010bbea000     /System/Library/Frameworks/JavaVM.framework/Versions/A/Frameworks/JavaNativeFoundation.framework/Versions/A/JavaNativeFoundation
+0x0000000127bb7000     /System/Library/Frameworks/JavaVM.framework/Versions/A/JavaVM
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
+0x0000000127bc4000     /System/Library/PrivateFrameworks/JavaLaunching.framework/Versions/A/JavaLaunching
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CommonPanels.framework/Versions/A/CommonPanels
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Help.framework/Versions/A/Help
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Print.framework/Versions/A/Print
+0x000000004dd98000     /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SecurityHI.framework/Versions/A/SecurityHI
+0x0000000129a56000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libawt.dylib
+0x0000000129afe000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/./libmlib_image.dylib
+0x0000000129bca000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libawt_lwawt.dylib
+0x0000000129c81000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/./libosxapp.dylib
+0x000000004dd98000     /System/Library/Frameworks/ExceptionHandling.framework/Versions/A/ExceptionHandling
+0x000000004dd98000     /System/Library/PrivateFrameworks/CoreServicesInternal.framework/Versions/A/CoreServicesInternal
+0x000000004dd98000     /System/Library/CoreServices/RawCamera.bundle/Contents/MacOS/RawCamera
+0x000000004dd98000     /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vImage.framework/Versions/A/Libraries/libCGInterfaces.dylib
+0x000000004dd98000     /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libTrueTypeScaler.dylib
+0x000000012bcdb000     /System/Library/Frameworks/OpenGL.framework/Resources/GLEngine.bundle/GLEngine
+0x000000004dd98000     /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLProgrammability.dylib
+0x000000012bec0000     /System/Library/Extensions/AppleIntelHD5000GraphicsGLDriver.bundle/Contents/MacOS/AppleIntelHD5000GraphicsGLDriver
+0x000000004dd98000     /System/Library/PrivateFrameworks/GPUSupport.framework/Versions/A/Libraries/libGPUSupportMercury.dylib
+0x000000004dd98000     /System/Library/Extensions/GeForceGLDriver.bundle/Contents/MacOS/GeForceGLDriver
+0x000000004dd98000     /System/Library/Extensions/GeForceGLDriver.bundle/Contents/MacOS/libclh.dylib
+0x000000012a6a7000     /System/Library/Frameworks/OpenGL.framework/Resources//GLRendererFloat.bundle/GLRendererFloat
+0x000000004dd98000     /System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries/libcldcpuengine.dylib
+0x000000004dd98000     /usr/lib/libcrypto.0.9.8.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent
+0x000000004dd98000     /System/Library/Extensions/GeForceMTLDriver.bundle/Contents/MacOS/GeForceMTLDriver
+0x000000012c642000     /System/Library/Extensions/AppleIntelHD5000GraphicsMTLDriver.bundle/Contents/MacOS/AppleIntelHD5000GraphicsMTLDriver
+0x000000004dd98000     /System/Library/PrivateFrameworks/FamilyControls.framework/Versions/A/FamilyControls
+0x000000004dd98000     /System/Library/PrivateFrameworks/CommerceKit.framework/Versions/A/Frameworks/CommerceCore.framework/Versions/A/CommerceCore
+0x000000004dd98000     /System/Library/PrivateFrameworks/SystemAdministration.framework/Versions/A/SystemAdministration
+0x000000004dd98000     /System/Library/PrivateFrameworks/AppContainer.framework/Versions/A/AppContainer
+0x000000004dd98000     /System/Library/PrivateFrameworks/SecCodeWrapper.framework/Versions/A/SecCodeWrapper
+0x000000004dd98000     /System/Library/Frameworks/DirectoryService.framework/Versions/A/DirectoryService
+0x000000004dd98000     /System/Library/PrivateFrameworks/DiskImages.framework/Versions/A/DiskImages
+0x000000004dd98000     /System/Library/PrivateFrameworks/LoginUIKit.framework/Versions/A/Frameworks/LoginUICore.framework/Versions/A/LoginUICore
+0x000000004dd98000     /usr/lib/libCoreStorage.dylib
+0x000000004dd98000     /usr/lib/libcsfde.dylib
+0x000000004dd98000     /usr/lib/libodfde.dylib
+0x000000004dd98000     /System/Library/Frameworks/DiscRecording.framework/Versions/A/DiscRecording
+0x000000004dd98000     /usr/lib/libcurl.4.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/MediaKit.framework/Versions/A/MediaKit
+0x000000004dd98000     /System/Library/PrivateFrameworks/ProtectedCloudStorage.framework/Versions/A/ProtectedCloudStorage
+0x000000004dd98000     /System/Library/PrivateFrameworks/EFILogin.framework/Versions/A/EFILogin
+0x000000004dd98000     /usr/lib/libutil.dylib
+0x000000004dd98000     /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP
+0x000000004dd98000     /usr/lib/libsasl2.2.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/CoreDaemon.framework/Versions/B/CoreDaemon
+0x000000004dd98000     /System/Library/PrivateFrameworks/AppleSRP.framework/Versions/A/AppleSRP
+0x000000004dd98000     /System/Library/PrivateFrameworks/APFS.framework/Versions/A/APFS
+0x000000012da1c000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libfontmanager.dylib
+0x00000001297a9000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libosxui.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/ViewBridge.framework/Versions/A/ViewBridge
+0x000000004dd98000     /System/Library/PrivateFrameworks/XPCService.framework/Versions/A/XPCService
+0x000000004dd98000     /System/Library/PrivateFrameworks/AppSandbox.framework/Versions/A/AppSandbox
+0x000000004dd98000     /usr/lib/libsandbox.1.dylib
+0x000000004dd98000     /usr/lib/libMatch.1.dylib
+0x000000012f42b000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libnet.dylib
+0x000000012f47f000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libnio.dylib
+0x0000000166784000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libdcpr.dylib
+0x00000001667b2000     /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libsunec.dylib
+0x000000004dd98000     /System/Library/PrivateFrameworks/Shortcut.framework/Versions/A/Shortcut
+0x000000004dd98000     /System/Library/PrivateFrameworks/HelpData.framework/Versions/A/HelpData
+
+VM Arguments:
+jvm_args: -Dfile.encoding=UTF-8 
+java_command: jalview.bin.Jalview
+java_class_path (initial): /Users/kjvanderheide/Documents/Jalview development/classes:/Users/kjvanderheide/Documents/Jalview development/lib/activation.jar:/Users/kjvanderheide/Documents/Jalview development/lib/axis.jar:/Users/kjvanderheide/Documents/Jalview development/lib/commons-discovery.jar:/Users/kjvanderheide/Documents/Jalview development/lib/jaxrpc.jar:/Users/kjvanderheide/Documents/Jalview development/lib/jhall.jar:/Users/kjvanderheide/Documents/Jalview development/lib/mail.jar:/Users/kjvanderheide/Documents/Jalview development/lib/regex.jar:/Users/kjvanderheide/Documents/Jalview development/lib/saaj.jar:/Users/kjvanderheide/Documents/Jalview development/lib/wsdl4j.jar:/Users/kjvanderheide/Documents/Jalview development/lib/xercesImpl.jar:/Users/kjvanderheide/Documents/Jalview development/lib/castor-1.1-cycle-xml.jar:/Users/kjvanderheide/Documents/Jalview development/lib/JGoogleAnalytics_0.3.jar:/Users/kjvanderheide/Documents/Jalview development/lib/vamsas-client.jar:/Users/kjvanderheide/Documents/Jalview development/lib/commons-logging-1.1.1.jar:/Users/kjvanderheide/Documents/Jalview development/lib/apache-mime4j-0.6.jar:/Users/kjvanderheide/Documents/Jalview development/lib/httpclient-4.0.3.jar:/Users/kjvanderheide/Documents/Jalview development/lib/httpcore-4.0.1.jar:/Users/kjvanderheide/Documents/Jalview development/lib/httpmime-4.0.3.jar:/Users/kjvanderheide/Documents/Jalview development/lib/miglayout-4.0-swing.jar:/Users/kjvanderheide/Documents/Jalview development/lib/jswingreader-0.3.jar:/Users/kjvanderheide/Documents/Jalview development/lib/commons-codec-1.3.jar:/Users/kjvanderheide/Documents/Jalview development/lib/jdas-1.0.4.jar:/Users/kjvanderheide/Documents/Jalview development/lib/spring-core-3.0.5.RELEASE.jar:/Users/kjvanderheide/Documents/Jalview development/lib/spring-web-3.0.5.RELEASE.jar:/Users/kjvanderheide/Documents/Jalview development/lib:/Users/kjvanderheide/Documents/Jalview development/lib/jabaws-min-client-2.2.0.jar:/Users/kjvanderhe
+Launcher Type: SUN_STANDARD
+
+Environment Variables:
+PATH=/usr/bin:/bin:/usr/sbin:/sbin
+SHELL=/bin/bash
+
+Signal Handlers:
+SIGSEGV: [libjvm.dylib+0x5b26e5], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_ONSTACK|SA_RESTART|SA_SIGINFO
+SIGBUS: [libjvm.dylib+0x5b26e5], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGFPE: [libjvm.dylib+0x489100], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGPIPE: [libjvm.dylib+0x489100], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGXFSZ: [libjvm.dylib+0x489100], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGILL: [libjvm.dylib+0x489100], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none
+SIGUSR2: [libjvm.dylib+0x488c1e], sa_mask[0]=00100000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO
+SIGHUP: [libjvm.dylib+0x4871f5], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGINT: [libjvm.dylib+0x4871f5], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGTERM: [libjvm.dylib+0x4871f5], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+SIGQUIT: [libjvm.dylib+0x4871f5], sa_mask[0]=11111111011111110111111111111111, sa_flags=SA_RESTART|SA_SIGINFO
+
+
+---------------  S Y S T E M  ---------------
+
+OS:Bsduname:Darwin 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64
+rlimit: STACK 8192k, CORE 0k, NPROC 709, NOFILE 10240, AS infinity
+load average:1.63 2.07 2.13
+
+CPU:total 8 (initial active 8) (4 cores per cpu, 2 threads per core) family 6 model 70 stepping 1, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, rtm, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2
+
+Memory: 4k page, physical 16777216k(1152628k free)
+
+/proc/meminfo:
+
+
+vm_info: Java HotSpot(TM) 64-Bit Server VM (25.144-b01) for bsd-amd64 JRE (1.8.0_144-b01), built on Jul 21 2017 22:07:42 by "java_re" with gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
+
+time: Wed Nov 15 14:06:19 2017
+elapsed time: 1054 seconds (0d 0h 17m 34s)
+
diff --git a/lib/forester.jar b/lib/forester.jar
new file mode 100644 (file)
index 0000000..d848e04
Binary files /dev/null and b/lib/forester.jar differ
diff --git a/resources/_aptx_jalview_configuration_file.txt b/resources/_aptx_jalview_configuration_file.txt
new file mode 100644 (file)
index 0000000..b5b75b7
--- /dev/null
@@ -0,0 +1,503 @@
+#  PLEASE DON'T MOVE ME
+#  User Interface Look and Feel
+#  ----------------------------
+#  Possible values for 'native_ui'
+#    'yes' to use native (system) "look and feel"
+#    'no'  to use Archaeopteryx-style "look and feel", can set GUI colors via this file (see below)
+#    '?'   to use native (system) "look and feel" if Mac OS X with Java 1.5 is detected,
+#          Archaeopteryx-style "look and feel" otherwise
+
+native_ui: yes
+
+
+
+#  Default Values for Options
+#  --------------------------
+#  Minimal confidence value to be displayed: 'min_confidence_value':
+#     Example: 'min_confidence_value: 50.0' (a commonly used 
+#     value for bootstrap support)
+#
+#  Font family name: 'font_family':
+#     Example: 'font_family: Arial_Unicode_MS,Dialog,SansSerif,Sans,Arial,Helvetica'
+#     It is advisable to use more than one value for font_family (in
+#     decreasing order of preference). Font family names have to be
+#     comma separated (no spaces). Spaces in font names have to be
+#     replaced by underscores (e.g. 'Arial_Unicode_MS').
+#
+#  Font size: 'font_size':
+#     Example: 'font_size: 10'
+#
+#  Screen antialias: 'antialias_screen': values: 'yes'/'no'
+#
+#  Show Scale: 'show_scale': values: 'yes'/'no'
+#
+#  Show branch length branch values: 'show_branch_length_values': values: 'yes'/'no'
+#
+#  Cladogram display type: 'cladogram_type'
+#     Example: 'cladogram_type: non_lined_up'
+#     The three possible values are: lined_up
+#                                    non_lined_up
+#
+#  Default line width for PDF export: 'pdf_export_line_wdith':
+#     Example: 'pdf_export_line_width: 0.5'
+#
+#  Show overview: 'show_overview': values: 'yes'/'no'
+#
+#  Phylogeny graphics type: 'phylogeny_graphics_type':
+#     Example: 'phylogeny_graphics_type: euro_style'
+#     The eight possible values are: rectangular
+#                                    euro_style
+#                                    rounded
+#                                    curved
+#                                    triangular
+#                                    convex
+#                                    unrooted
+#                                    circular
+#
+#  Node label direction for circular and unrooted type: 'node_label_direction':
+#     Example: 'node_label_direction: horizontal'
+#     The two possible values are: horizontal
+#                                  radial
+#
+#  Show default node shape for internal nodes: 'show_default_node_shapes_internal': values: 'yes'/'no'
+#
+#  Show default node shape for external nodes: 'show_default_node_shapes_external': values: 'yes'/'no'
+#
+#  Default node shape size: 'default_node_size'
+#     Example: 'default_node_size: 6'
+#
+#  Default node shape type: 'default_node_shape'
+#     Example: 'default_node_shape: '
+#     Possible values: circle
+#                      rectangle
+#
+#  Default node shape fill: 'default_node_fill'
+#     Example: 'default_node_fill: '
+#     Possible values: solid
+#                      gradient
+#                      none
+#
+#  To determine what data field to return by clicking on "List Node Data": 'list_node_data_field'
+#     Possible values: node_name
+#                      sequence_name
+#                      gene_name
+#                      sequence_acc
+#                      sequence_mol_seq_fasta
+#                      sequence_symbol
+#                      taxonomy_scientific_name
+#                      taxonomy_code
+#                      domains
+#                      domains_collapsed
+#                      seq_annotations
+#                      go_term_ids
+#                      user_selected
+#
+#  To determine where to return data selected by user clicking on "List Node Data": 'list_node_data_in'
+#     Contents of buffer can be obtained with method 'getCurrentExternalNodesDataBuffer()' of
+#     classes org.forester.archaeopteryx.MainFrame and org.forester.archaeopteryx.ArchaeopteryxE
+#     Possible values: window (for output to window and buffer)
+#                      console (for output to console and buffer)
+#                      buffer_only (for output to buffer only)
+#
+#  To override label for menu item to return data of external nodes (default "List Node Data"): 'list_node_data_custom_label'
+#     Example: 'list_node_data_custom_label: Get_Node_Data'
+# 
+#  Taxonomy colorization of nodes (shapes) instead of labels: 'taxonomy_colorize_node_shapes': values: 'yes'/'no'
+#
+#  Do/not color labels same as branch length values: 'color_labels_same_as_branch_length_values': values: 'yes'/'no'
+#
+#  Do/not show domain labels: 'show_domain_labels': values: 'yes'/'no'
+#
+#  Do/not show reference sources for sequence annotation: 'show_seq_annotation_ref_sources': values: 'yes'/'no'
+#
+#  Number of fraction digits for branch length values: 'branch_length_value_digits'
+#
+#  Number of fraction digits for confidence values: 'confidence_value_digits'
+#
+#  To turn on/off background color gradient: background_gradient
+#     Example: 'background_gradient: yes'
+#
+#  To allow/not allow editing (cut, copy, and paste): allow_editing
+#     Example: 'allow_editing: yes'
+#
+#  To allow/not allow thicker strokes for very small trees: allow_thick_strokes
+#     Example: 'allow_thick_strokes: yes'
+#
+#  NH/NHX/Nexus file parsing
+#  -------------------------
+#  To replace underscores with spaces during NH/NHX/Nexus file parsing:
+#     'replace_underscores_in_nh_parsing', possible values are 'yes', 'no'
+#
+#  To extract UniProt taxonomy codes (e.g. CAEEL) or UniProt identifiers (or scientific names)
+#  from node names during NH/NHX/Nexus file parsing: 'taxonomy_extraction_in_nh_parsing'
+#     possible values are:
+#     'no'
+#     'pfam_strict'  (for e.g. MOUSE from BCL2_MOUSE/23-453, or [uniprot] 10090 from BCL2_10090/23-453)
+#     'pfam_relaxed' (for e.g. MOUSE from bax_MOUSE, or [uniprot] 10090 from bax_10090)
+#     'aggressive'   (for e.g. MOUSE from MOUSE, or [uniprot] 10090 from 10090, or Nematostella vectensis from xyz_Nematostella_vectensis)
+#
+#  Internal node labels are confidence values during NH/NHX/Nexus file parsing:
+#     'internal_labels_are_confidence_values', possible values are 'yes', 'no'
+#
+#  phyloXML parsing
+#  ----------------
+#  To ensure compatibility with all current and future 
+#  phyloXML applications and to detect malformatted and
+#  possibly erroneous data, it is strongly recommended
+#  to enable validation of all phyloXML files
+#  against the XSD Schema (see: http://www.phyloxml.org/),
+#  with:
+#  'validate_against_phyloxml_xsd_schema: true'
+
+
+min_confidence_value:                      0.0
+font_family:                               Arial_Unicode_MS,Dialog,SansSerif,Sans,Arial,Helvetica
+font_size:                                 12
+font_size_min:                             2
+font_size_max:                             20
+antialias_screen:                          yes
+show_scale:                                yes
+cladogram_type:                            non_lined_up
+phylogeny_graphics_type:                   rectangular
+node_label_direction:                      horizontal
+show_default_node_shapes_internal:         yes
+show_default_node_shapes_external:         yes
+show_node_shapes_for_nodes_with_vis_data:  yes 
+default_node_size:                         5
+default_node_shape:                        rectangle
+default_node_fill:                         solid
+pdf_export_line_width:                     0.5
+show_overview:                             yes
+overview_width:                            120
+overview_height:                           120
+overview_placement_type:                   upper_right
+color_labels_same_as_branch_length_values: no
+display_sequence_relations:                no
+show_domain_labels:                        yes
+line_up_renderable_data:                   yes
+right_align_domain_architectures:          no
+show_seq_annotation_ref_sources:           yes
+branch_length_value_digits:                3
+confidence_value_digits:                   2
+background_gradient:                       no
+allow_editing:                             yes
+allow_thick_strokes:                       no
+list_node_data_in:                         window
+list_node_data_field:                      user_selected
+list_node_data_custom_label:         
+#  NH/NHX/Nexus file parsing:
+internal_labels_are_confidence_values:     no
+replace_underscores_in_nh_parsing:         no
+taxonomy_extraction_in_nh_parsing:         no
+#  phyloXML parsing:
+validate_against_phyloxml_xsd_schema:      true
+
+
+#  Checkbox Display Selection
+#  --------------------------
+#  This is used to select which checkboxes to display
+#  and what their initial values should be.
+#  Format: 'name: display|nodisplay yes|no'
+#  Note: if an option is not displayed, it will not be enabled
+#
+#  For the following use '?' to let Archaeopteryx decide (depending on tree):
+#  - 'phylogram'
+#  - 'write_confidence_values'
+#  - 'write_events'
+
+phylogram:                      display   ?
+rollover:                       display   yes
+color_according_to_sequence:    display   no
+color_according_to_species:     display   no
+color_according_to_annotation:  display   no
+show_node_names:                display   yes
+show_seq_names:                 display   yes
+show_seq_symbols:               display   yes
+show_seq_acc:                   display   no
+show_gene_names:                display   yes
+show_taxonomy_code:             display   yes
+show_taxonomy_scientific_names: display   yes
+show_taxonomy_rank:             display   no
+show_taxonomy_common_names:     display   no
+show_taxonomy_images:           display   no
+show_annotations:               display   no
+write_confidence_values:        display   ?
+write_branch_length_values:     display   yes
+write_events:                   display   ?
+use_visual_styles:              display   yes
+width_branches:                 display   no
+show_domain_architectures:      display   no
+show_msa:                       display   no
+show_binary_characters:         display   no
+show_binary_character_counts:   display   no
+display_internal_data:          display   yes
+dynamically_hide_data:          display   yes
+show_relation_confidence:       display   no
+show_properties:                display   no
+show_vector_data:               display   no
+
+
+
+#  Combo-box Display Selection
+#  ---------------------------
+#  Format: 'name: display/nodisplay'
+click_to: display_node_data        display
+click_to: collapse_uncollapse      display
+click_to: uncollapse_all           display
+click_to: reroot                   display
+click_to: subtree                  display
+click_to: swap                     display
+click_to: order_subtree            display
+click_to: sort_descendants         display
+click_to: color_subtree            display
+click_to: change_node_font         display
+click_to: color_node_font          display
+click_to: open_seq_web             display
+click_to: open_pdb_web             display
+click_to: open_tax_web             display
+click_to: blast                    display
+click_to: cut_subtree              display
+click_to: copy_subtree             display
+click_to: paste_subtree            display
+click_to: delete                   display
+click_to: add_new_node             display
+click_to: edit_node_data           display
+click_to: select_nodes             display
+click_to: get_ext_descendents_data display
+
+#   Default click-to option (any of the above if set to "display")
+default_click_to: select_nodes
+
+
+
+#  Default Tree Display Colors
+#  ---------------------------
+
+display_color: background                 0xFFFFFF
+display_color: background_gradient_bottom 0xFFFFFF
+display_color: sequence                   0x111111
+display_color: taxonomy                   0x8D8D8D
+display_color: confidence                 0xAEAEAE
+display_color: branch_length              0x3A3A3A
+display_color: branch                     0x000000
+display_color: node_box                   0x000000
+display_color: collapsed                  0x000000
+display_color: matching_a                 0xCC6600
+display_color: matching_b                 0xCC70CC
+display_color: matching_a_and_b           0x0000CC
+display_color: duplication                0xFF00FF
+display_color: speciation                 0xFFFF00
+display_color: duplication_or_specation   0xFFAA20
+display_color: domain_label               0x939393
+display_color: domain_base                0x505050
+display_color: binary_domain_combinations 0x4169FF
+display_color: annotation                 0xFFCC00
+display_color: overview                   0x828282
+
+
+
+#  GUI (graphical user interface) Colors
+#  -------------------------------------
+#
+#  These are ignored if native (system) "look and feel"
+#  is being used ('native_ui: yes').
+
+gui_background_color:                 0x202020
+gui_checkbox_text_color:              0xDCDCDC
+gui_checkbox_and_button_active_color: 0xFF0000
+gui_button_text_color:                0xFFFFFF
+gui_button_background_color:          0x404040
+gui_menu_background_color:            0x000000
+gui_menu_text_color:                  0xFFFFFF
+gui_button_border_color:              0x000000
+
+
+#  Vector Data Display Colors and Sizes
+#  ------------------------------------
+vector_data_min_color:                0x0000FF
+vector_data_max_color:                0xFFFF00
+vector_data_mean_color:               0x000000
+vector_data_width:                    120
+vector_data_height:                   12
+
+
+#  Settings Specific for Archaeopteryx Applets (E and A)
+#  -----------------------------------------------------
+#  To automatically midpoint reroot trees upon loading: 'midpoint_reroot: yes'
+
+midpoint_reroot: yes
+
+
+
+#  Settings Specific for ArchaeopteryxE Applets
+#  --------------------------------------------
+#  To hide controls and menus: 'hide_controls_and_menus: yes'
+#  To use tabbed display     : 'use_tabbed_display: yes'
+
+hide_controls_and_menus: no
+use_tabbed_display:      yes
+
+
+
+#  Settings For Phylogenetic Inference
+#  -----------------------------------
+#  EXPERIMENTAL: DO NOT USE!!
+
+default_number_of_bootstrap_resamples: 100
+mafft_local:                            /bin/mafft
+fastme_local:                           /bin/fastme
+raxml_local:                            /bin/raxml
+
+
+
+#  Sequence colors
+#  ---------------
+#  Format: species_color: sequencename hexcolor
+sequence_color: Tubulin-alpha        0xEE0000
+sequence_color: Tubulin-beta         0x00EE00
+
+
+#  Species colors
+#  --------------
+#  Format: species_color: speciesname hexcolor
+species_color: BRAFL        0x00FFFF
+species_color: SPHGR        0x9620F0
+species_color: STRPU        0x9620F0
+species_color: CIOIN        0xFF1CAE
+species_color: CIOSA        0xFF2CAE
+species_color: BOVIN        0x5C3317
+species_color: CANFA        0x8B2323
+species_color: HUMAN        0xFF2400
+species_color: PANTR        0xCC2400
+species_color: MOUSE        0xFF7F00
+species_color: RAT          0xFFEF00
+species_color: MONDO        0xEE9A49
+species_color: ORNAN        0xCD853F
+species_color: XENLA        0x6BAA23
+species_color: XENTR        0x6BAA23
+species_color: CHICK        0xFFC125
+species_color: FUGRU        0x0000FF
+species_color: BRARE        0x0000DD
+species_color: DANRE        0x0000BB
+species_color: TETNG        0x0000AA
+species_color: ORYLA        0x000088
+species_color: GASAC        0x000066
+species_color: CAEEL        0x666699
+species_color: CAEBR        0xB0B0B0
+species_color: DROME        0x663366
+species_color: DROPS        0x996699
+species_color: APIME        0x7A7700
+species_color: AEDAE        0x8C5900
+species_color: TRICA        0x918E00
+species_color: NEMVE        0x0066CC
+species_color: HYDAT        0x3399FF
+species_color: HYDVU        0x3399FF
+species_color: LUBBA        0xF7B5CB
+species_color: GEOCY        0xF5A0BD
+species_color: AMPQE        0x009966
+species_color: SUBDO        0xC790B9
+species_color: MONBE        0xFC0FC0
+species_color: DICPU        0xFFCC33
+species_color: DICDI        0xFFCC00
+species_color: ENTHI        0x5959AB
+species_color: ARATH        0x00FF00
+species_color: POPTR        0x006400
+species_color: VITVI        0x00CD00
+species_color: GLYMA        0x00FF7F
+species_color: ORYSA        0x008B00
+species_color: ORYSJ        0x008C00
+species_color: SORBI        0x00EE76
+species_color: SELMO        0x238E23
+species_color: PHYPA        0x09F911
+species_color: OSTLU        0x7FFF00
+species_color: OSTTA        0x7FFF00
+species_color: OSTRC        0x7FFF00
+species_color: MICPU        0x66CD00
+species_color: MIC99        0x66CD00
+species_color: CHLRE        0xB3EE3A
+species_color: VOLCA        0xC0FF3E
+species_color: CHLSP        0x6B8E23
+species_color: CYAME        0xD02090
+species_color: YEAST        0xAAAAAA
+species_color: BACFR        0xFF0000
+species_color: BACTN        0xFFFF00
+species_color: MYXXD        0x0000FF
+species_color: STIAU        0x00FFFF
+species_color: BACOV        0x8C5900
+species_color: BACUN        0x66CD00
+species_color: PORGI        0x918E00
+# rank: Class
+species_color: Mammalia       0xFF0000
+species_color: mammals        0xFF0000
+# rank: Phylum
+species_color: Chordata       0x8470FF
+species_color: Echinodermata  0x6495ED
+species_color: Hemichordata   0x7EC0EE
+species_color: Arthropoda     0x7AC5CD
+species_color: Nematoda       0x7171C6
+species_color: Tardigrada     0x388E8E
+species_color: Annelida       0xC67171
+species_color: Mollusca       0x00F5FF
+species_color: Ctenophora     0xBBFFFF
+species_color: Cnidaria       0xFF83FA
+species_color: Placozoa       0xEED2EE
+species_color: Porifera       0xFF3E96
+species_color: Microsporidia  0x8B8378
+species_color: Ascomycota     0xFF6347
+species_color: Basidiomycota  0xFFD700
+species_color: Chlorophyta    0x00C78C
+species_color: Streptophyta   0x00C957
+# rank: Kingdom
+species_color: Viridiplantae  0x00FF00
+species_color: plants         0x00FF00
+species_color: Metazoa        0x0000FF
+species_color: animals        0x0000FF
+species_color: Fungi          0xFF9912
+# rank: Superkingdom
+species_color: Viruses        0xFFD700
+species_color: Bacteria       0x00FF00
+species_color: Archaea        0x0000FF
+species_color: Eukaryota      0xFF0000
+species_color: eukaryotes     0xFF0000
+
+
+
+#  Domain colors
+#  -------------
+domain_color: Cofilin_ADF     0xFC0FC0
+domain_color: TIR             0x900000
+domain_color: NACHT           0x202020
+domain_color: CARD            0xFF0000
+domain_color: Peptidase_C14   0x00FF00
+domain_color: Death           0x0000FF
+domain_color: DED             0x00FFFF
+domain_color: BIR             0xCCFF33
+domain_color: PAAD_DAPIN      0x9999CC
+domain_color: NB-ARC          0x500050
+domain_color: WD40            0x888888
+domain_color: RVT_1           0x999900
+domain_color: CBM_48          0xFF0000
+domain_color: Alpha-amylase   0x0000FF
+domain_color: Alpha-amylase_C 0x0080FF
+domain_color: CBM_48          0xFF0000
+domain_color: Alpha-amylase   0x0000FF
+domain_color: Alpha-amylase_C 0x0080FF
+domain_color: GDE_N           0x009000
+domain_color: GDE_C           0x00FF00
+domain_color: hGDE_N          0x990099
+domain_color: GDE_N_bis       0x007000
+domain_color: hGDE_central    0xFF8000
+domain_color: hGDE_amylase    0x0000EE
+domain_color: hDGE_amylase    0x0000EE
+
+
+
+#  Annotation colors
+#  -----------------
+annotation_color: dehydrogenase 0x0000FF
+annotation_color: kinase        0xFF00FF
+annotation_color: protease      0x009900
+annotation_color: transcription 0xAAAA00
+
+
+# END
\ No newline at end of file
index f526699..d159e81 100644 (file)
@@ -173,6 +173,8 @@ label.average_distance_identity = Average Distance Using % Identity
 label.neighbour_joining_identity = Neighbour Joining Using % Identity
 label.choose_calculation = Choose Calculation
 label.treecalc_title = {0} Using {1}
+label.aptx_title = Archaeopteryx Tree View 
+label.aptx_title_append = of {0}
 label.tree_calc_av = Average Distance
 label.tree_calc_nj = Neighbour Joining
 label.select_score_model = Select score model
@@ -299,7 +301,11 @@ label.show_distances = Show distances
 label.mark_unassociated_leaves = Mark Unassociated Leaves
 label.fit_to_window = Fit To Window
 label.newick_format = Newick Format
-label.select_newick_like_tree_file = Select a newick-like tree file
+label.select_tree_file = Select a tree file
+label.treebase_study = TreeBASE Study
+label.treebase = TreeBASE
+label.treefam = TreeFam
+label.tree_of_life = Tree of Life
 label.colours = Colours
 label.view_mapping = View Mapping
 label.wireframe = Wireframe
@@ -387,7 +393,12 @@ label.not_enough_sequences = Not enough sequences
 label.selected_region_to_tree_may_only_contain_residues_or_gaps =  The selected region to create a tree may\nonly contain residues or gaps.\nTry using the Pad function in the edit menu,\nor one of the multiple sequence alignment web services.
 label.sequences_selection_not_aligned = Sequences in selection are not aligned
 label.problem_reading_tree_file =  Problem reading tree file
+label.tabs_detected_archaeopteryx = Warning, multiple trees detected in a single tree viewer instance. This will cause problems!
 label.possible_problem_with_tree_file = Possible problem with tree file
+label.aptx_config_not_found = Warning: tree viewer configuration file not found, continue anyway? (this WILL cause the viewer to look different)
+label.tree_url_example = Please enter a complete URL, for example \"http://www.jalview.org/examples/ferredoxin.nw\"
+label.from_database = From Database...
+label.load_tree_url = Tree from URL
 label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation = Please select at least three bases in at least one sequence in order to perform a cDNA translation.
 label.translation_failed = Translation Failed
 label.error_when_translating_sequences_submit_bug_report = Unfortunately, something went wrong when translating your sequences.\nPlease take a look in the Jalview java console\nand submit a bug report including the stacktrace.
@@ -417,7 +428,7 @@ label.input_alignment_from_url = Input Alignment From URL
 label.input_alignment = Input Alignment
 label.couldnt_import_as_vamsas_session = Couldn't import {0} as a new vamsas session.
 label.vamsas_document_import_failed = Vamsas Document Import Failed
-label.couldnt_locate = Couldn't locate {0}
+label.couldnt_locate = Could not locate {0}
 label.url_not_found = URL not found
 label.new_sequence_url_link = New sequence URL link
 label.cannot_edit_annotations_in_wrapped_view = Cannot edit annotations in wrapped view
@@ -559,10 +570,10 @@ label.select_copy_raw_html = Select this if you want to copy raw html
 label.share_data_vamsas_applications = Share data with other vamsas applications
 label.connect_to = Connect to
 label.join_existing_vamsas_session = Join an existing vamsas session
-label.from_url = from URL
+label.from_url = From URL
 label.any_trees_calculated_or_loaded_alignment_automatically_sort = When selected, any trees calculated or loaded onto the alignment will automatically sort the alignment
 label.sort_with_new_tree = Sort With New Tree
-label.from_textbox = from Textbox
+label.from_textbox = From Textbox
 label.window = Window
 label.preferences = Preferences
 label.tools = Tools
@@ -911,6 +922,8 @@ label.updating_vamsas_session = Updating vamsas session
 label.loading_file = Loading File: {0}
 label.edit_params = Edit {0}
 label.as_percentage = As Percentage
+error.database_id_has_letters = Database identifier ({0}) should contain only digits
+error.phyloxml_validation = phyloXML XSD-based validation is turned off (enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file)
 error.not_implemented = Not implemented
 error.no_such_method_as_clone1_for = No such method as clone1 for {0}
 error.null_from_clone1 = Null from clone1!
@@ -1068,6 +1081,7 @@ exception.couldnt_parse_sequence_line = Could not parse sequence line: {0}
 exception.unknown_annotation_detected = Unknown annotation detected: {0} {1}
 exception.couldnt_store_sequence_mappings = Couldn't store sequence mappings for {0}
 exception.matrix_too_many_iteration = Too many iterations in {0} (max is {1})
+exception.invalid_matrix_identifier = Sequence identifier {0} not found in distance matrix.
 exception.browser_not_found = Exception in finding browser: {0}
 exception.browser_unable_to_locate = Unable to locate browser: {0}
 exception.invocation_target_exception_creating_aedesc = InvocationTargetException while creating AEDesc: {0}
index b5cefe0..9f9b774 100755 (executable)
@@ -29,12 +29,15 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeNodeI;
 import jalview.util.QuickSort;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Routines for manipulating the order of a multiple sequence alignment TODO:
@@ -69,6 +72,8 @@ public class AlignmentSorter
 
   static TreeModel lastTree = null;
 
+  static TreeI lastExternalTree = null;
+
   static boolean sortTreeAscending = true;
 
   /*
@@ -182,7 +187,7 @@ public class AlignmentSorter
     List<SequenceI> algn;
     synchronized (algn = align.getSequences())
     {
-      List<SequenceI> tmp = new ArrayList<SequenceI>();
+      List<SequenceI> tmp = new ArrayList<>();
 
       for (int i = 0; i < seqs.length; i++)
       {
@@ -279,7 +284,7 @@ public class AlignmentSorter
   {
     // MAINTAINS ORIGNAL SEQUENCE ORDER,
     // ORDERS BY GROUP SIZE
-    List<SequenceGroup> groups = new ArrayList<SequenceGroup>();
+    List<SequenceGroup> groups = new ArrayList<>();
 
     if (groups.hashCode() != lastGroupHash)
     {
@@ -315,7 +320,7 @@ public class AlignmentSorter
 
     // NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER
     // /////////////////////////////////////////////
-    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    List<SequenceI> seqs = new ArrayList<>();
 
     for (int i = 0; i < groups.size(); i++)
     {
@@ -357,7 +362,7 @@ public class AlignmentSorter
     // tmp2 = tmp.retainAll(mask);
     // return tmp2.addAll(mask.removeAll(tmp2))
 
-    ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
+    ArrayList<SequenceI> seqs = new ArrayList<>();
     int i, idx;
     boolean[] tmask = new boolean[mask.size()];
 
@@ -436,9 +441,9 @@ public class AlignmentSorter
   {
     int nSeq = align.getHeight();
 
-    List<SequenceI> tmp = new ArrayList<SequenceI>();
+    List<SequenceI> tmp = new ArrayList<>();
 
-    tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences());
+    tmp = _sortByTree(tree.getTopNode(), tmp);
 
     if (tmp.size() != nSeq)
     {
@@ -461,6 +466,27 @@ public class AlignmentSorter
     return tmp;
   }
 
+
+
+  private static List<SequenceI> getOrderByTree(TreeI aptxTree,
+          Map<TreeNodeI, SequenceI> nodesWithBoundSeqs)
+  {
+    List<SequenceI> seqsByTreeOrder = new ArrayList<>();
+    if (!aptxTree.isEmpty())
+    {
+      for (final Iterator<TreeNodeI> iter = aptxTree
+              .iterateInPreOrder(); iter.hasNext();)
+      {
+        TreeNodeI treeNode = iter.next();
+        seqsByTreeOrder.add(nodesWithBoundSeqs.get(treeNode));
+      }
+
+    }
+    return seqsByTreeOrder;
+
+
+  }
+
   /**
    * Sorts the alignment by a given tree
    * 
@@ -496,6 +522,48 @@ public class AlignmentSorter
   }
 
   /**
+   * Sorts the alignment by a given tree from Archaeopteryx
+   * 
+   * @param align
+   *          alignment to order
+   * @param tree
+   *          tree which has
+   */
+  public static void sortByTree(AlignmentI align,
+          Map<TreeNodeI, SequenceI> nodesBoundToSequences,
+          TreeI treeI) throws IllegalArgumentException
+  {
+    List<SequenceI> tmp = getOrderByTree(treeI, nodesBoundToSequences);
+
+    if (!tmp.isEmpty())
+    {
+      if (lastExternalTree != treeI)
+      {
+        sortTreeAscending = true;
+        lastExternalTree = treeI;
+      }
+      else
+      {
+        sortTreeAscending = !sortTreeAscending;
+      }
+
+      if (sortTreeAscending)
+      {
+        setOrder(align, tmp);
+      }
+      else
+      {
+        setReverseOrder(align,
+                vectorSubsetToArray(tmp, align.getSequences()));
+      }
+    }
+    else
+    {
+      throw new IllegalArgumentException();
+    }
+  }
+
+  /**
    * DOCUMENT ME!
    * 
    * @param align
@@ -535,7 +603,7 @@ public class AlignmentSorter
    * @return DOCUMENT ME!
    */
   private static List<SequenceI> _sortByTree(SequenceNode node,
-          List<SequenceI> tmp, List<SequenceI> seqset)
+          List<SequenceI> tmp)
   {
     if (node == null)
     {
@@ -564,13 +632,15 @@ public class AlignmentSorter
     }
     else
     {
-      _sortByTree(left, tmp, seqset);
-      _sortByTree(right, tmp, seqset);
+      _sortByTree(left, tmp);
+      _sortByTree(right, tmp);
     }
 
     return tmp;
   }
 
+
+
   // Ordering Objects
   // Alignment.sortBy(OrderObj) - sequence of sequence pointer refs in
   // appropriate order
diff --git a/src/jalview/analysis/TreeAlgorithm.java b/src/jalview/analysis/TreeAlgorithm.java
new file mode 100644 (file)
index 0000000..7aaa913
--- /dev/null
@@ -0,0 +1,31 @@
+package jalview.analysis;
+
+public enum TreeAlgorithm
+{
+  NEIGHBOUR_JOINING("NJ", "Neighbour Joining"),
+  AVERAGE_DISTANCE("AV", "Average Distance (UPGMA)"),
+  MAXIMUM_PARSIMONY("MP", ("Maximum Parsimony")),
+  MAXIMUM_LIKELIHOOD("ML", "Maximum Likelihood"),
+  BAYESIAN("BY", "Bayesian Inference");
+
+  private final String abbreviation;
+
+  private final String name;
+
+  TreeAlgorithm(String abbreviatedName, String fullName)
+  {
+    this.abbreviation = abbreviatedName;
+    this.name = fullName;
+  }
+
+  public String getAbbreviation()
+  {
+    return abbreviation;
+  }
+
+  public String getName()
+  {
+    return name;
+  }
+
+}
index 0601dd9..c4a94eb 100644 (file)
@@ -67,13 +67,19 @@ public abstract class TreeBuilder
 
   double maxDistValue;
 
-  double maxheight;
+  double maxHeight;
 
   int ycount;
 
   Vector<SequenceNode> node;
 
-  private AlignmentView seqStrings;
+  protected ScoreModelI scoreModel;
+
+  protected SimilarityParamsI scoreParams;
+
+  private AlignmentViewport avport;
+
+  private AlignmentView seqStrings; // redundant? (see seqData)
 
   /**
    * Constructor
@@ -86,6 +92,7 @@ public abstract class TreeBuilder
           SimilarityParamsI scoreParameters)
   {
     int start, end;
+    avport = av;
     boolean selview = av.getSelectionGroup() != null
             && av.getSelectionGroup().getSize() > 1;
     seqStrings = av.getAlignmentView(selview);
@@ -125,20 +132,20 @@ public abstract class TreeBuilder
   {
     if (nd == null)
     {
-      return maxheight;
+      return maxHeight;
     }
 
     if ((nd.left() == null) && (nd.right() == null))
     {
       nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
 
-      if (nd.height > maxheight)
+      if (nd.height > maxHeight)
       {
         return nd.height;
       }
       else
       {
-        return maxheight;
+        return maxHeight;
       }
     }
     else
@@ -149,15 +156,15 @@ public abstract class TreeBuilder
       }
       else
       {
-        maxheight = 0;
+        maxHeight = 0;
         nd.height = (float) 0.0;
       }
 
-      maxheight = findHeight((SequenceNode) (nd.left()));
-      maxheight = findHeight((SequenceNode) (nd.right()));
+      maxHeight = findHeight((SequenceNode) (nd.left()));
+      maxHeight = findHeight((SequenceNode) (nd.right()));
     }
 
-    return maxheight;
+    return maxHeight;
   }
 
   /**
@@ -295,7 +302,11 @@ public abstract class TreeBuilder
    */
   protected void computeTree(ScoreModelI sm, SimilarityParamsI scoreOptions)
   {
-    distances = sm.findDistances(seqData, scoreOptions);
+
+    this.scoreModel = sm;
+    this.scoreParams = scoreOptions;
+
+    distances = scoreModel.findDistances(seqData, scoreParams);
 
     makeLeaves();
 
@@ -364,7 +375,7 @@ public abstract class TreeBuilder
 
   protected void init(AlignmentView seqView, int start, int end)
   {
-    this.node = new Vector<SequenceNode>();
+    this.node = new Vector<>();
     if (seqView != null)
     {
       this.seqData = seqView;
@@ -458,7 +469,7 @@ public abstract class TreeBuilder
    */
   void makeLeaves()
   {
-    clusters = new Vector<BitSet>();
+    clusters = new Vector<>();
 
     for (int i = 0; i < noseqs; i++)
     {
@@ -467,6 +478,7 @@ public abstract class TreeBuilder
       sn.setElement(sequences[i]);
       sn.setName(sequences[i].getName());
       node.addElement(sn);
+
       BitSet bs = new BitSet();
       bs.set(i);
       clusters.addElement(bs);
@@ -478,4 +490,24 @@ public abstract class TreeBuilder
     return seqStrings;
   }
 
+  public MatrixI getDistances()
+  {
+    return distances;
+  }
+
+  public ScoreModelI getScoreModel()
+  {
+    return scoreModel;
+  }
+
+  public SimilarityParamsI getScoreParams()
+  {
+    return scoreParams;
+  }
+
+  public AlignmentViewport getAvport()
+  {
+    return avport;
+  }
+
 }
diff --git a/src/jalview/analysis/TreeCalculator.java b/src/jalview/analysis/TreeCalculator.java
new file mode 100644 (file)
index 0000000..84deba2
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($Version-Rel$)
+ * Copyright (C) $Year-Rel$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.analysis;
+
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.SimilarityParamsI;
+import jalview.gui.AlignViewport;
+
+/**
+ * @author kjvanderheide
+ *
+ */
+public class TreeCalculator extends Thread// add threading
+{
+  SimilarityParamsI similarityParams;
+
+  String treeType;
+
+  String scoreModelName; // if tree computed
+
+  /**
+   * 
+   * @param treeAlgo
+   * @param substitutionMatrix
+   * @param calculateParams
+   */
+  public TreeCalculator(String treeAlgo, String substitutionMatrix,
+          SimilarityParamsI calculateParams)
+  {
+    this.treeType = treeAlgo;
+    this.scoreModelName = substitutionMatrix;
+    this.similarityParams = calculateParams;
+  }
+
+  /**
+   * 
+   * @param alignViewport
+   * @return
+   */
+  public TreeBuilder makeTree(AlignViewport alignViewport)
+  {
+    ScoreModelI sm = ScoreModels.getInstance().getScoreModel(scoreModelName,
+            alignViewport.getAlignPanel());
+
+    TreeBuilder builtTree = treeType.equals(TreeBuilder.NEIGHBOUR_JOINING)
+            ? new NJTree(alignViewport, sm, similarityParams)
+            : new AverageDistanceTree(alignViewport, sm, similarityParams);
+
+    return builtTree;
+
+  }
+
+  public SimilarityParamsI getSimilarityParams()
+  {
+    return similarityParams;
+  }
+
+  public void setSimilarityParams(SimilarityParamsI similarityParams)
+  {
+    this.similarityParams = similarityParams;
+  }
+
+  public String getTreeType()
+  {
+    return treeType;
+  }
+
+  public void setTreeType(String treeType)
+  {
+    this.treeType = treeType;
+  }
+
+  public String getScoreModelName()
+  {
+    return scoreModelName;
+  }
+
+  public void setScoreModelName(String scoreModelName)
+  {
+    this.scoreModelName = scoreModelName;
+  }
+
+
+
+
+}
index a50634e..1c19dbf 100644 (file)
@@ -80,8 +80,8 @@ public class TreeModel
   public TreeModel(SequenceI[] seqs, AlignmentView odata,
           NewickFile treefile)
   {
-    this(seqs, treefile.getTree(), treefile.HasDistances(),
-            treefile.HasBootstrap(), treefile.HasRootDistance());
+    this(seqs, treefile.getTree(), treefile.hasDistances(),
+            treefile.hasBootstrap(), treefile.hasRootDistance());
     seqData = odata;
 
     associateLeavesToSequences(seqs);
@@ -130,29 +130,27 @@ public class TreeModel
 
     Vector<SequenceNode> leaves = findLeaves(top);
 
-    int i = 0;
     int namesleft = seqs.length;
 
-    SequenceNode j;
-    SequenceI nam;
-    String realnam;
-    Vector<SequenceI> one2many = new Vector<SequenceI>();
+    SequenceI nodeSequence;
+    String nodeSequenceName;
+    Vector<SequenceI> one2many = new Vector<>();
     // int countOne2Many = 0;
-    while (i < leaves.size())
+
+    for (SequenceNode sn : leaves)
     {
-      j = leaves.elementAt(i++);
-      realnam = j.getName();
-      nam = null;
+      nodeSequenceName = sn.getName();
+      nodeSequence = null;
 
       if (namesleft > -1)
       {
-        nam = algnIds.findIdMatch(realnam);
+        nodeSequence = algnIds.findIdMatch(nodeSequenceName);
       }
 
-      if (nam != null)
+      if (nodeSequence != null)
       {
-        j.setElement(nam);
-        if (one2many.contains(nam))
+        sn.setElement(nodeSequence);
+        if (one2many.contains(nodeSequence))
         {
           // countOne2Many++;
           // if (jalview.bin.Cache.log.isDebugEnabled())
@@ -161,14 +159,14 @@ public class TreeModel
         }
         else
         {
-          one2many.addElement(nam);
+          one2many.addElement(nodeSequence);
           namesleft--;
         }
       }
       else
       {
-        j.setElement(new Sequence(realnam, "THISISAPLACEHLDER"));
-        j.setPlaceholder(true);
+        sn.setElement(new Sequence(nodeSequenceName, "THISISAPLACEHLDER"));
+        sn.setPlaceholder(true);
       }
     }
     // if (jalview.bin.Cache.log.isDebugEnabled() && countOne2Many>0) {
@@ -295,7 +293,7 @@ public class TreeModel
    */
   public Vector<SequenceNode> findLeaves(SequenceNode nd)
   {
-    Vector<SequenceNode> leaves = new Vector<SequenceNode>();
+    Vector<SequenceNode> leaves = new Vector<>();
     findLeaves(nd, leaves);
     return leaves;
   }
@@ -389,7 +387,7 @@ public class TreeModel
    */
   public List<SequenceNode> groupNodes(float threshold)
   {
-    List<SequenceNode> groups = new ArrayList<SequenceNode>();
+    List<SequenceNode> groups = new ArrayList<>();
     _groupNodes(groups, getTopNode(), threshold);
     return groups;
   }
index 8ce597d..7f9f670 100755 (executable)
@@ -235,7 +235,7 @@ public class OverviewPanel extends Panel implements Runnable,
 
       updateRunning = true;
     }
-    Thread thread = new Thread(this);
+    Thread thread = new Thread(this, "OverviewUpdate");
     thread.start();
     repaint();
     updateRunning = false;
index fc1d359..6c0ed73 100644 (file)
@@ -117,7 +117,7 @@ public class PCAPanel extends EmbmenuFrame
             MessageManager.getString("label.principal_component_analysis"),
             475, 400);
 
-    Thread worker = new Thread(this);
+    Thread worker = new Thread(this, "PCACalc");
     worker.start();
   }
 
@@ -220,7 +220,7 @@ public class PCAPanel extends EmbmenuFrame
         ScoreModelI scoreModel = ScoreModels.getInstance()
                 .getDefaultModel(false);
         pcaModel.setScoreModel(scoreModel);
-        new Thread(this).start();
+        new Thread(this, "PCARecalc").start();
       }
     }
     else if (evt.getSource() == protSetting)
@@ -231,7 +231,7 @@ public class PCAPanel extends EmbmenuFrame
         ScoreModelI scoreModel = ScoreModels.getInstance()
                 .getDefaultModel(true);
         pcaModel.setScoreModel(scoreModel);
-        new Thread(this).start();
+        new Thread(this, "PCARecalc").start();
       }
     }
   }
index bd36b0d..41bba33 100644 (file)
@@ -89,7 +89,7 @@ public class RedundancyPanel extends SliderPanel
 
     frame.addWindowListener(this);
 
-    Thread worker = new Thread(this);
+    Thread worker = new Thread(this, "RedundancyCalc");
     worker.start();
   }
 
index b5e3342..f6bc265 100644 (file)
@@ -207,12 +207,12 @@ public class TreePanel extends EmbmenuFrame
       {
         // Set default view, paying lip service to any overriding tree view
         // parameter settings
-        boolean showDist = newtree.HasDistances()
+        boolean showDist = newtree.hasDistances()
                 && av.applet.getDefaultParameter("showTreeDistances",
-                        newtree.HasDistances());
-        boolean showBoots = newtree.HasBootstrap()
+                        newtree.hasDistances());
+        boolean showBoots = newtree.hasBootstrap()
                 && av.applet.getDefaultParameter("showTreeBootstraps",
-                        newtree.HasBootstrap());
+                        newtree.hasBootstrap());
         distanceMenu.setState(showDist);
         bootstrapMenu.setState(showBoots);
         treeCanvas.setShowBootstrap(showBoots);
index 9ec0033..80b03ce 100755 (executable)
@@ -20,9 +20,6 @@
  */
 package jalview.bin;
 
-import groovy.lang.Binding;
-import groovy.util.GroovyScriptEngine;
-
 import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
@@ -66,6 +63,9 @@ import java.util.Vector;
 
 import javax.swing.UIManager;
 
+import groovy.lang.Binding;
+import groovy.util.GroovyScriptEngine;
+
 /**
  * Main class for Jalview Application <br>
  * <br>
@@ -155,7 +155,7 @@ public class Jalview
             running--;
           }
         }
-      }).start();
+      }, "FeatureFetcher").start();
     }
 
     public synchronized boolean allFinished()
@@ -970,7 +970,7 @@ public class Jalview
     }
     try
     {
-      Map<String, Object> vbinding = new HashMap<String, Object>();
+      Map<String, Object> vbinding = new HashMap<>();
       vbinding.put("Jalview", this);
       if (af != null)
       {
@@ -1036,7 +1036,7 @@ public class Jalview
                         + nickname + "|" + url);
         if (source == null)
         {
-          source = new Vector<String>();
+          source = new Vector<>();
         }
         source.addElement(nickname);
       }
@@ -1054,7 +1054,7 @@ public class Jalview
       System.out.println("adding source '" + data + "'");
       if (source == null)
       {
-        source = new Vector<String>();
+        source = new Vector<>();
       }
       source.addElement(data);
     }
diff --git a/src/jalview/ext/archaeopteryx/AptxControlPanel.java b/src/jalview/ext/archaeopteryx/AptxControlPanel.java
new file mode 100644 (file)
index 0000000..2744908
--- /dev/null
@@ -0,0 +1,31 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.ext.treeviewer.TreeControlsI;
+
+import org.forester.archaeopteryx.ControlPanel;
+
+public class AptxControlPanel implements TreeControlsI
+{
+  ControlPanel aptxCp;
+
+  protected AptxControlPanel(ControlPanel aptxControlPanel)
+  {
+    aptxCp = aptxControlPanel;
+
+  }
+
+  @Override
+  public void defaultSettings()
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void displayEntireTree()
+  {
+    aptxCp.showWhole();
+
+  }
+
+}
diff --git a/src/jalview/ext/archaeopteryx/AptxFrame.java b/src/jalview/ext/archaeopteryx/AptxFrame.java
new file mode 100644 (file)
index 0000000..919d00e
--- /dev/null
@@ -0,0 +1,448 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.bin.Cache;
+import jalview.ext.treeviewer.TreeControlsI;
+import jalview.ext.treeviewer.TreeFrameI;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreePanelI;
+import jalview.ext.treeviewer.TreeViewerBindingI;
+import jalview.ext.treeviewer.TreeViewerUtils;
+import jalview.gui.Desktop;
+import jalview.gui.EPSOptions;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.util.ImageMaker;
+import jalview.util.MessageManager;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Font;
+import java.awt.Image;
+import java.awt.MenuComponent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.FileOutputStream;
+
+import javax.accessibility.AccessibleContext;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JRootPane;
+import javax.swing.JSeparator;
+import javax.swing.event.InternalFrameListener;
+
+import org.forester.archaeopteryx.Archaeopteryx;
+import org.forester.archaeopteryx.Configuration;
+import org.forester.archaeopteryx.MainFrame;
+import org.forester.phylogeny.Phylogeny;
+import org.jibble.epsgraphics.EpsGraphics2D;
+
+public class AptxFrame implements TreeFrameI
+{
+  private final MainFrame aptxFrame;
+
+  private TreeViewerBindingI viewBinding;
+
+  private TreePanelI aptxPanel;
+
+  private TreeControlsI aptxControls;
+
+
+  public AptxFrame(Phylogeny tree, Configuration aptxConfig,
+          String treeTitle)
+  {
+    this(Archaeopteryx.createApplication(tree,
+            aptxConfig,
+            treeTitle));
+
+  }
+
+
+  public AptxFrame(MainFrame aptx)
+  {
+
+    aptxFrame = aptx;
+    aptxPanel = new AptxTreePanel(
+            aptxFrame.getMainPanel().getCurrentTreePanel());
+    aptxControls = new AptxControlPanel(
+            aptxFrame.getMainPanel().getControlPanel());
+    adaptAptxGui(aptxFrame);
+
+  }
+  
+  /**
+   * Hides certain redundant Archaeopteryx GUI elements such as the menu items
+   * for reading in trees and adds extra items related to Jalview such as the
+   * tree sorting menu item.
+   * 
+   * 
+   * @param aptxFrame
+   */
+  protected void adaptAptxGui(MainFrame aptxFrame)
+  {
+    JMenuBar frameBar = aptxFrame.getJMenuBar();
+    boolean epsAdded = false;
+    for (int i = 0; i < frameBar.getMenuCount();i++) {
+      JMenu menu = frameBar.getMenu(i);
+      int menuCount = menu.getMenuComponentCount();
+
+      if (menu.getText().contains("File"))
+      {
+        // hide all "Read from ..." and "New" menu items and any Separators that
+        // come directly after them
+        Component previousComp = null;
+        for (int x = 0; x < menuCount; x++)
+        {
+          Component menuItem = menu.getMenuComponent(x);
+          if (previousComp instanceof JMenuItem)
+          {
+            JMenuItem previousMenuItem = (JMenuItem) previousComp;
+            if (previousMenuItem.getText().startsWith("Read")
+                    || previousMenuItem.getText()
+                            .startsWith("New")
+                    || previousMenuItem.getText()
+                            .startsWith("Close Tab"))
+            {
+              previousComp.setVisible(false);
+
+              if (menuItem instanceof JSeparator)
+              {
+                menuItem.setVisible(false);
+              }
+
+            }
+
+            if ((!epsAdded) && previousMenuItem.getText()
+                    .startsWith("Export to"))
+            {
+              JMenuItem exportEps = new JMenuItem("Export to EPS file...");
+              menu.add(exportEps, x);
+              exportEps.addActionListener(new ActionListener()
+              {
+
+                @Override
+                public void actionPerformed(ActionEvent e)
+                {
+                  epsTree_actionPerformed(e);
+
+                }
+                
+              });
+              epsAdded = true;
+
+            }
+          }
+          previousComp = menuItem;
+        }
+      }
+      else if (menu.getText().contains("Inference"))
+      {
+        menu.setVisible(false);
+      }
+      else if (menu.getText().contains("View"))
+      {
+        menu.addSeparator();
+        JMenuItem sortByTree = new JMenuItem("Sort alignment by tree");
+        JMenuItem refreshJalview = new JMenuItem(
+                "Filter alignment to show only currently visible sequences");
+
+        refreshJalview.setFont(menu.getFont());
+        refreshJalview.addActionListener(new ActionListener() {
+          
+          @Override
+          public void actionPerformed(ActionEvent e) {
+            TreeViewerBindingI bindingManager = TreeViewerUtils
+                    .getActiveTreeViews().get(AptxFrame.this);
+            bindingManager.actionPerformed(e);
+          }
+        });
+                
+        sortByTree.addActionListener(new ActionListener()
+        {
+
+          @Override
+          public void actionPerformed(ActionEvent e)
+          {
+            TreeViewerBindingI bindingManager = TreeViewerUtils
+                    .getActiveTreeViews().get(AptxFrame.this);
+            bindingManager.sortByTree_actionPerformed();
+
+          }
+
+        });
+
+        menu.add(sortByTree);
+        menu.add(refreshJalview);
+
+        sortByTree.setFont(menu.getFont());
+
+
+
+      }
+
+    }
+    // aptxFrame.validate();
+  }
+
+  public void epsTree_actionPerformed(ActionEvent e)
+  {
+    boolean accurateText = true;
+
+    String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
+            "Prompt each time");
+
+    // If we need to prompt, and if the GUI is visible then
+    // Prompt for EPS rendering style
+    if (renderStyle.equalsIgnoreCase("Prompt each time")
+            && !(System.getProperty("java.awt.headless") != null && System
+                    .getProperty("java.awt.headless").equals("true")))
+    {
+      EPSOptions eps = new EPSOptions();
+      renderStyle = eps.getValue();
+
+      if (renderStyle == null || eps.cancelled)
+      {
+        return;
+      }
+
+    }
+
+    if (renderStyle.equalsIgnoreCase("text"))
+    {
+      accurateText = false;
+    }
+
+    int width = getTreePanel().getWidth();
+    int height = getTreePanel().getHeight();
+
+    try
+    {
+      JalviewFileChooser chooser = new JalviewFileChooser(
+              ImageMaker.EPS_EXTENSION, ImageMaker.EPS_EXTENSION);
+      chooser.setFileView(new JalviewFileView());
+      chooser.setDialogTitle(
+              MessageManager.getString("label.create_eps_from_tree"));
+      chooser.setToolTipText(MessageManager.getString("action.save"));
+
+      int value = chooser.showSaveDialog(aptxFrame);
+
+      if (value != JalviewFileChooser.APPROVE_OPTION)
+      {
+        return;
+      }
+
+      Cache.setProperty("LAST_DIRECTORY",
+              chooser.getSelectedFile().getParent());
+
+      FileOutputStream out = new FileOutputStream(
+              chooser.getSelectedFile());
+      EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,
+              height);
+
+      pg.setAccurateTextMode(accurateText);
+
+      getTreePanel().paintToFile(pg, width, height);
+
+      pg.flush();
+      pg.close();
+    } catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+  @Override
+  public TreePanelI getTreePanel()
+  {
+    return aptxPanel;
+  }
+
+  @Override
+  public TreeI getTree()
+  {
+    return aptxPanel.getTree();
+  }
+
+  @Override
+  public void checkMultipleTrees()
+  {
+    aptxFrame.activateSaveAllIfNeeded();
+
+  }
+
+  @Override
+  public int getNumberOfTrees()
+  {
+    return aptxFrame.getMainPanel().getTabbedPane().getTabCount();
+  }
+
+  @Override
+  public TreeControlsI getTreeControls()
+  {
+    return aptxControls;
+  }
+
+  @Override
+  public AccessibleContext getAccessibleContext()
+  {
+    return aptxFrame.getAccessibleContext();
+  }
+
+  @Override
+  public JRootPane getRootPane()
+  {
+    return aptxFrame.getRootPane();
+  }
+
+  @Override
+  public void setContentPane(Container contentPane)
+  {
+    aptxFrame.setContentPane(contentPane);
+
+  }
+
+  @Override
+  public Container getContentPane()
+  {
+    return aptxFrame.getContentPane();
+  }
+
+  @Override
+  public void setLayeredPane(JLayeredPane layeredPane)
+  {
+    aptxFrame.setLayeredPane(layeredPane);
+
+  }
+
+  @Override
+  public JLayeredPane getLayeredPane()
+  {
+    return aptxFrame.getLayeredPane();
+  }
+
+  @Override
+  public void setGlassPane(Component glassPane)
+  {
+    aptxFrame.setGlassPane(glassPane);
+
+  }
+
+  @Override
+  public Component getGlassPane()
+  {
+    return aptxFrame.getGlassPane();
+  }
+
+  @Override
+  public boolean imageUpdate(Image img, int infoflags, int x, int y,
+          int width, int height)
+  {
+    return aptxFrame.imageUpdate(img, infoflags, x, y, width, height);
+  }
+
+  @Override
+  public Font getFont()
+  {
+    return aptxFrame.getFont();
+  }
+
+  @Override
+  public void remove(MenuComponent comp)
+  {
+    aptxFrame.remove(comp);
+
+  }
+
+  @Deprecated
+  @Override
+  public boolean postEvent(Event evt)
+  {
+    return aptxFrame.postEvent(evt);
+  }
+
+  @Override
+  public void addFrameListener(InternalFrameListener listener)
+  {
+    aptxFrame.addInternalFrameListener(listener);
+
+  }
+
+  @Override
+  public void removeFrameListener(InternalFrameListener listener)
+  {
+    aptxFrame.removeInternalFrameListener(listener);
+
+  }
+
+  @Override
+  public InternalFrameListener[] getFrameListeners()
+  {
+    return aptxFrame.getInternalFrameListeners();
+
+  }
+
+  @Override
+  public void repaint()
+  {
+    aptxFrame.repaint();
+
+  }
+
+  @Override
+  public void setMinimumSize(Dimension dimension)
+  {
+    aptxFrame.setMinimumSize(dimension);
+
+  }
+
+  @Override
+  public boolean isShowing()
+  {
+    return aptxFrame.isShowing();
+  }
+
+  @Override
+  public Container getTopLevelAncestor()
+  {
+    return aptxFrame.getTopLevelAncestor();
+  }
+
+  @Override
+  public void addFrameToJalview(String title, boolean makeVisible,
+          int width, int height, boolean resizable, boolean ignoreMinSize)
+  {
+    Desktop.addInternalFrame(aptxFrame, title, makeVisible, width, height,
+            resizable, ignoreMinSize);
+
+  }
+
+  @Override
+  public TreeViewerBindingI getViewBinding()
+  {
+    return viewBinding;
+  }
+
+  @Override
+  public void setViewBinding(TreeViewerBindingI alignmentBinding)
+  {
+    viewBinding = alignmentBinding;
+  }
+
+
+  @Override
+  public void setMaximumSize(Dimension maximumSize)
+  {
+    aptxFrame.setMaximumSize(maximumSize);
+
+  }
+
+  @Override
+  public void setPreferredSize(Dimension preferredSize)
+  {
+    aptxFrame.setPreferredSize(preferredSize);
+
+  }
+
+}
\ No newline at end of file
diff --git a/src/jalview/ext/archaeopteryx/AptxInit.java b/src/jalview/ext/archaeopteryx/AptxInit.java
new file mode 100644 (file)
index 0000000..9b89cea
--- /dev/null
@@ -0,0 +1,562 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.ext.forester.io.UtilityMethods;
+import jalview.ext.treeviewer.LoadedTreeAssociationI;
+import jalview.ext.treeviewer.LoadedTreeSequenceAssociation;
+import jalview.ext.treeviewer.TreeFrameI;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeViewerUtils;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.forester.archaeopteryx.AptxUtil;
+import org.forester.archaeopteryx.Configuration;
+import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;
+import org.forester.archaeopteryx.webservices.WebserviceUtil;
+import org.forester.io.parsers.PhylogenyParser;
+import org.forester.io.parsers.nexus.NexusPhylogeniesParser;
+import org.forester.io.parsers.nhx.NHXParser;
+import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
+import org.forester.io.parsers.phyloxml.PhyloXmlParser;
+import org.forester.io.parsers.tol.TolParser;
+import org.forester.io.parsers.util.ParserUtils;
+import org.forester.phylogeny.Phylogeny;
+import org.forester.phylogeny.PhylogenyMethods;
+import org.forester.phylogeny.data.Identifier;
+import org.forester.util.ForesterUtil;
+
+/**
+ * Static class for creating Archaeopteryx tree viewer instances from calculated
+ * trees and letting them be bound to Jalview.
+ * 
+ * @author kjvanderheide
+ *
+ */
+public final class AptxInit
+{
+  public final static InputStream CONFIG_LOC = AptxInit.class
+
+          .getResourceAsStream("/_aptx_jalview_configuration_file.txt");
+
+  public final static Configuration APTX_CONFIG = new Configuration(
+          CONFIG_LOC,
+          false, false);
+  // static
+  // {
+  // APTX_CONFIG.setBaseFontFamilyName(
+  // Desktop.instance.getFont().getFamily().replaceAll(" ", "_"));
+  // APTX_CONFIG.setBaseFontSize(Desktop.instance.getFont().getSize());
+  // }
+
+  private final static boolean VALIDATE_PHYLOXML_XSD = APTX_CONFIG
+          .isValidatePhyloXmlAgainstSchema();
+
+  private final static boolean REPLACE_NHX_UNDERSCORES = APTX_CONFIG
+          .isReplaceUnderscoresInNhParsing();
+
+  private final static boolean INTERNAL_NUMBERS_AS_CONFIDENCE = APTX_CONFIG
+          .isInternalNumberAreConfidenceForNhParsing();
+
+  private final static boolean MIDPOINT_REROOT = APTX_CONFIG
+          .isMidpointReroot();
+
+  private final static NHXParser.TAXONOMY_EXTRACTION TAXONOMY_EXTRACTION = APTX_CONFIG
+          .getTaxonomyExtraction();
+
+
+  public static TreeFrameI createInstanceFromNhx(String treeTitle,
+          String nhxString, AlignmentViewport viewport)
+          throws IOException
+  {
+    if (Desktop.instance != null)
+    {
+      Desktop.instance.startLoading(treeTitle);
+    }
+
+    Phylogeny aptxPhylogeny = Phylogeny
+            .createInstanceFromNhxString(nhxString);
+    aptxPhylogeny.setName(treeTitle);
+
+    TreeFrameI aptxFrame = createAptxFrame(aptxPhylogeny, viewport,
+            treeTitle);
+
+    if (Desktop.instance != null)
+    {
+      Desktop.instance.stopLoading();
+    }
+
+    return aptxFrame;
+
+  }
+
+  /**
+   * Refactored from Archaeopteryx.main
+   * 
+   * @param filePath
+   * @param viewport
+   * @return
+   * @throws IOException
+   * @throws FileNotFoundException
+   */
+  public static TreeFrameI[] createInstancesFromFile(File treeFile,
+          AlignmentViewport viewport)
+          throws FileNotFoundException, IOException
+  {
+    TreeFrameI[] aptxFrames = null;
+    if (UtilityMethods.canForesterReadFile(treeFile))
+    {
+
+      if (Desktop.instance != null)
+      {
+        Desktop.instance.startLoading(treeFile.getCanonicalPath());
+      }
+      boolean nhx_or_nexus = false;
+      final PhylogenyParser parser = ParserUtils
+              .createParserDependingOnFileType(treeFile,
+                      VALIDATE_PHYLOXML_XSD);
+      if (parser instanceof NHXParser)
+      {
+        nhx_or_nexus = true;
+        final NHXParser nhx = (NHXParser) parser;
+        nhx.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
+        nhx.setIgnoreQuotes(false);
+        nhx.setTaxonomyExtraction(TAXONOMY_EXTRACTION);
+      }
+      else if (parser instanceof NexusPhylogeniesParser)
+      {
+        nhx_or_nexus = true;
+        final NexusPhylogeniesParser nex = (NexusPhylogeniesParser) parser;
+        nex.setReplaceUnderscores(REPLACE_NHX_UNDERSCORES);
+        nex.setIgnoreQuotes(false);
+      }
+      else if (parser instanceof PhyloXmlParser)
+      {
+        if (VALIDATE_PHYLOXML_XSD == false)
+        {
+          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                  MessageManager.getString("error.phyloxml_validation"),
+                  MessageManager.getString("label.file_open_error"),
+                  JvOptionPane.WARNING_MESSAGE);
+        }
+      }
+      Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser,
+              treeFile);
+      aptxFrames = new TreeFrameI[trees.length];
+
+      for (int i = 0; i < trees.length; i++)
+      {
+        Phylogeny aptxPhylogeny = trees[i];
+
+        if (nhx_or_nexus && INTERNAL_NUMBERS_AS_CONFIDENCE)
+        {
+          PhylogenyMethods
+                  .transferInternalNodeNamesToConfidence(aptxPhylogeny, "");
+        }
+        String treeTitle = treeFile.getName() + "[" + i + "]";
+        aptxPhylogeny.setName(treeTitle);
+        aptxFrames[i] = createAptxFrame(aptxPhylogeny, viewport, treeTitle);
+
+      }
+      if (Desktop.instance != null)
+      {
+        Desktop.instance.stopLoading();
+      }
+    }
+    return aptxFrames;
+  }
+
+
+  public static TreeFrameI[] createInstancesFromFile(
+          String filePath,
+          AlignmentViewport viewport)
+          throws FileNotFoundException, IOException
+  {
+    File treeFile = new File(filePath);
+    return createInstancesFromFile(treeFile, viewport);
+
+    }
+
+  public static TreeFrameI[] createInstancesFromUrl(URL treeUrl,
+          AlignmentViewport viewport)
+          throws FileNotFoundException, IOException, RuntimeException
+  {
+    
+    String treeTitle = treeUrl.getFile();
+    if (Desktop.instance != null)
+    {
+      Desktop.instance.startLoading(treeTitle);
+    }
+    Phylogeny[] trees = AptxUtil.readPhylogeniesFromUrl(treeUrl,
+            VALIDATE_PHYLOXML_XSD,
+             REPLACE_NHX_UNDERSCORES, INTERNAL_NUMBERS_AS_CONFIDENCE,
+            TAXONOMY_EXTRACTION, MIDPOINT_REROOT);
+
+    TreeFrameI[] aptxFrames = new TreeFrameI[trees.length];
+    for (int i = 0; i < trees.length; i++)
+    {
+      Phylogeny aptxTree = trees[i];
+      aptxFrames[i] = createAptxFrame(aptxTree, viewport, treeTitle);
+    }
+
+    if (Desktop.instance != null)
+    {
+      Desktop.instance.stopLoading();
+    }
+
+    return aptxFrames;
+
+  }
+
+  /**
+   * Refactored from Forester's UrlTreeReader, this can be more efficient
+   * 
+   * @param databaseIndex
+   * @param viewport
+   * @return
+   */
+  public static TreeFrameI[] createInstancesFromDb(
+          PhylogeniesWebserviceClient treeDbClient, String identifier,
+          AlignmentViewport viewport)
+  {
+
+    URL url = null;
+    Phylogeny[] trees = null;
+    TreeFrameI[] aptxFrames = null;
+
+    if ((identifier != null) && (identifier.trim().length() > 0))
+    {
+      if (Desktop.instance != null)
+      {
+        Desktop.instance.startLoading(identifier);
+      }
+
+      identifier = identifier.trim();
+      if (treeDbClient.isQueryInteger())
+      {
+        identifier = identifier.replaceAll("^\\D+", "");
+
+        int id;
+        try
+        {
+          id = Integer.parseInt(identifier);
+        } catch (final NumberFormatException e)
+        {
+          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                  MessageManager.formatMessage(
+                          "error.database_id_has_letters", new String[]
+                          { identifier }),
+                  MessageManager.getString("label.invalid_url"),
+                  JvOptionPane.ERROR_MESSAGE);
+          return new TreeFrameI[0];
+        }
+        identifier = id + "";
+      }
+      boolean exception = false;
+      try
+      {
+        String url_str = treeDbClient.getUrl();
+        url_str = url_str.replaceFirst(
+                PhylogeniesWebserviceClient.QUERY_PLACEHOLDER, identifier);
+        url = new URL(url_str);
+        PhylogenyParser parser = null;
+        switch (treeDbClient.getReturnFormat())
+        {
+        case TOL_XML_RESPONSE:
+          parser = new TolParser();
+          break;
+        case NEXUS:
+          parser = new NexusPhylogeniesParser();
+          ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
+          break;
+        case TREEBASE_TREE:
+          parser = new NexusPhylogeniesParser();
+          ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
+          ((NexusPhylogeniesParser) parser)
+                  .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
+          break;
+        case TREEBASE_STUDY:
+          parser = new NexusPhylogeniesParser();
+          ((NexusPhylogeniesParser) parser).setReplaceUnderscores(true);
+          ((NexusPhylogeniesParser) parser)
+                  .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
+          break;
+        case NH:
+          parser = new NHXParser();
+          ((NHXParser) parser)
+                  .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
+          ((NHXParser) parser).setReplaceUnderscores(true);
+          ((NHXParser) parser).setGuessRootedness(true);
+          break;
+        case NH_EXTRACT_TAXONOMY:
+          parser = new NHXParser();
+          ((NHXParser) parser).setTaxonomyExtraction(
+                  NHXParser.TAXONOMY_EXTRACTION.AGGRESSIVE);
+          ((NHXParser) parser).setReplaceUnderscores(false);
+          ((NHXParser) parser).setGuessRootedness(true);
+          break;
+        case PFAM:
+          parser = new NHXParser();
+          ((NHXParser) parser).setTaxonomyExtraction(
+                  NHXParser.TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT);
+          ((NHXParser) parser).setReplaceUnderscores(false);
+          ((NHXParser) parser).setGuessRootedness(true);
+          break;
+        case NHX:
+          parser = new NHXParser();
+          ((NHXParser) parser)
+                  .setTaxonomyExtraction(NHXParser.TAXONOMY_EXTRACTION.NO);
+          ((NHXParser) parser).setReplaceUnderscores(false);
+          ((NHXParser) parser).setGuessRootedness(true);
+          break;
+        case PHYLOXML:
+          parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
+          break;
+        default:
+          throw new IllegalArgumentException(
+                  "unknown format: " + treeDbClient.getReturnFormat());
+        }
+        //
+        // if (_main_frame.getMainPanel().getCurrentTreePanel() != null)
+        // {
+        // _main_frame.getMainPanel().getCurrentTreePanel().setWaitCursor();
+        // }
+        // else
+        // {
+        // _main_frame.getMainPanel().setWaitCursor();
+        // }
+        trees = ForesterUtil.readPhylogeniesFromUrl(url, parser);
+        aptxFrames = new TreeFrameI[trees.length];
+      } catch (final MalformedURLException e)
+      {
+        exception = true;
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                MessageManager.formatMessage(
+                        "exception.unable_to_launch_url", new String[]
+                        { url.toString() }),
+                MessageManager.getString("label.invalid_url"),
+                JvOptionPane.ERROR_MESSAGE);
+        System.err.println(e.getLocalizedMessage());
+      } catch (final IOException e)
+      {
+        exception = true;
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                "Could not read from " + url + "\n"
+                        + e.getLocalizedMessage(),
+                "Failed to read tree from " + treeDbClient.getName() + " for "
+                        + identifier,
+                JvOptionPane.ERROR_MESSAGE);
+        System.err.println(e.getLocalizedMessage());
+      } catch (final NumberFormatException e)
+      {
+        exception = true;
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                "Could not read from " + url + "\n"
+                        + e.getLocalizedMessage(),
+                "Failed to read tree from " + treeDbClient.getName() + " for "
+                        + identifier,
+                JvOptionPane.ERROR_MESSAGE);
+        System.err.println(e.getLocalizedMessage());
+      } catch (final Exception e)
+      {
+        exception = true;
+        e.printStackTrace();
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                e.getLocalizedMessage(), "Unexpected Exception",
+                JvOptionPane.ERROR_MESSAGE);
+        System.err.println(e.getLocalizedMessage());
+      }
+      if ((trees != null) && (trees.length > 0))
+      {
+        int i = 0;
+        for (final Phylogeny aptxTree : trees)
+        {
+          if (!aptxTree.isEmpty())
+          {
+            if (treeDbClient.getName().equals(WebserviceUtil.TREE_FAM_NAME))
+            {
+              aptxTree.setRerootable(false);
+              aptxTree.setRooted(true);
+            }
+            if (treeDbClient.getProcessingInstructions() != null)
+            {
+              try
+              {
+                WebserviceUtil.processInstructions(treeDbClient,
+                        aptxTree);
+              } catch (final PhyloXmlDataFormatException e)
+              {
+                JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                        "Error:\n" + e.getLocalizedMessage(), "Error",
+                        JvOptionPane.ERROR_MESSAGE);
+              }
+            }
+            if (treeDbClient.getNodeField() != null)
+            {
+              try
+              {
+                PhylogenyMethods.transferNodeNameToField(aptxTree,
+                        treeDbClient.getNodeField(), false);
+              } catch (final PhyloXmlDataFormatException e)
+              {
+                JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                        "Error:\n" + e.getLocalizedMessage(), "Error",
+                        JvOptionPane.ERROR_MESSAGE);
+              }
+            }
+            aptxTree.setIdentifier(
+                    new Identifier(identifier, treeDbClient.getName()));
+            // _main_frame.getJMenuBar().remove(_main_frame.getHelpMenu());
+            // _main_frame.getMenuBarOfExternalTreeFrameI()
+            // .add(_main_frame.getHelpMenu());
+            // _main_frame.getMainPanel().addExternalTreeIInNewTab(ExternalTreeI,
+            // _main_frame.getConfiguration(),
+            // new File(url.getFile()).getName(), url.toString());
+
+
+            TreeFrameI aptxApp = createAptxFrame(aptxTree,
+                    viewport,
+                    url.getFile());
+            String my_name_for_file = "";
+            if (!ForesterUtil.isEmpty(aptxTree.getName()))
+            {
+              my_name_for_file = new String(aptxTree.getName())
+                      .replaceAll(" ", "_");
+            }
+            else if (aptxTree.getIdentifier() != null)
+            {
+              final StringBuffer sb = new StringBuffer();
+              if (!ForesterUtil
+                      .isEmpty(aptxTree.getIdentifier().getProvider()))
+              {
+                sb.append(aptxTree.getIdentifier().getProvider());
+                sb.append("_");
+              }
+              sb.append(aptxTree.getIdentifier().getValue());
+              my_name_for_file = new String(
+                      sb.toString().replaceAll(" ", "_"));
+            }
+            aptxApp.getTreePanel()
+                    .setTreeFile(new File(my_name_for_file));
+            // AptxUtil.lookAtSomeTreePropertiesForAptxControlSettings(
+            // aptxTree, aptxApp.getMainPanel().getControlPanel(),
+            // APTX_CONFIG);
+            aptxApp.getTreeControls().displayEntireTree();
+
+            aptxApp.checkMultipleTrees();
+            aptxFrames[i++] = aptxApp;
+          }
+        }
+      }
+      else if (!exception) // ..what?
+      {
+        JvOptionPane.showMessageDialog(null,
+                ForesterUtil.wordWrap(
+                        "Failed to read in tree(s) from [" + url + "]", 80),
+                "Error", JvOptionPane.ERROR_MESSAGE);
+      }
+      if ((trees != null) && (trees.length > 0))
+      {
+        try
+        {
+          JvOptionPane.showMessageDialog(null,
+                  ForesterUtil.wordWrap("Successfully read in "
+                          + trees.length + " tree(s) from [" + url + "]",
+                          80),
+                  "Success", JvOptionPane.INFORMATION_MESSAGE);
+        } catch (final Exception e)
+        {
+          // Not important if this fails, do nothing.
+        }
+      }
+    }
+
+
+    if (Desktop.instance != null)
+    {
+      Desktop.instance.stopLoading();
+    }
+    return aptxFrames;
+
+
+  }
+
+
+
+  public static TreeFrameI createAptxFrame(TreeI aptxTree,
+          AlignmentViewport jalviewAlignport, String treeTitle)
+  {
+    validateConfig(APTX_CONFIG);
+    TreeFrameI aptxApp = aptxTree
+            .createTreeViewerFromTree(treeTitle);
+    TreeI jalviewTree = aptxApp.getTree();
+    LoadedTreeAssociationI bindAptxNodes = new LoadedTreeSequenceAssociation(
+            jalviewAlignport.getAlignment().getSequencesArray(),
+            jalviewTree);
+    bindAptxNodes.associateLeavesToSequences();
+
+    TreeViewerUtils.associateNodesWithJalviewSequences(aptxApp, jalviewAlignport,
+            bindAptxNodes.getAlignmentWithNodes(),
+            bindAptxNodes.getNodesWithAlignment());
+    TreeViewerUtils.addTreeViewFrameToJalview(aptxApp);
+
+    // adaptAptxGui(aptxApp); //moved to AptxFrame
+    return aptxApp;
+  }
+
+
+  protected static TreeFrameI createAptxFrame(
+          final Phylogeny aptxTree,
+          final AlignmentViewport jalviewAlignport, String treeTitle)
+  {
+    validateConfig(APTX_CONFIG);
+    TreeFrameI aptxApp = new AptxFrame(aptxTree, APTX_CONFIG,
+            treeTitle);
+    TreeI jalviewTree = aptxApp.getTree();
+    LoadedTreeAssociationI bindAptxNodes = new LoadedTreeSequenceAssociation(
+            jalviewAlignport.getAlignment().getSequencesArray(),
+            jalviewTree);
+    bindAptxNodes.associateLeavesToSequences();
+
+    TreeViewerUtils.associateNodesWithJalviewSequences(aptxApp, jalviewAlignport,
+            bindAptxNodes.getAlignmentWithNodes(),
+            bindAptxNodes.getNodesWithAlignment());
+    TreeViewerUtils.addTreeViewFrameToJalview(aptxApp);
+
+    // adaptAptxGui(aptxApp); //moved to AptxFrame
+    return aptxApp;
+  }
+
+
+  private static boolean validateConfig(Configuration aptxConfig)
+  {
+    if (aptxConfig == null || aptxConfig.isCouldReadConfigFile() == false)
+    {
+      int keepGoing = JvOptionPane.showConfirmDialog(Desktop.desktop,
+              MessageManager.getString("label.aptx_config_not_found"),
+              MessageManager.formatMessage("label.couldnt_locate",
+                      new String[]
+                      { "_aptx_jalview_configuration_file" }),
+              JvOptionPane.YES_NO_CANCEL_OPTION);
+
+      if (keepGoing == JvOptionPane.CANCEL_OPTION
+              || keepGoing == JvOptionPane.CLOSED_OPTION
+              || keepGoing == JvOptionPane.NO_OPTION)
+      {
+        return false;
+      }
+
+    }
+    return true;
+  }
+
+
+}
diff --git a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java
new file mode 100644 (file)
index 0000000..1be7da3
--- /dev/null
@@ -0,0 +1,167 @@
+// package jalview.ext.archaeopteryx;
+//
+// import jalview.analysis.TreeBuilder;
+// import jalview.datamodel.SequenceI;
+// import jalview.ext.forester.ForesterMatrix;
+// import jalview.ext.treeviewer.TreeBuilderI;
+// import jalview.ext.treeviewer.TreeI;
+// import jalview.ext.treeviewer.TreeNodeI;
+// import jalview.util.MappingUtils;
+// import jalview.util.MessageManager;
+//
+// import java.util.HashMap;
+// import java.util.Map;
+//
+// import org.forester.evoinference.matrix.distance.DistanceMatrix;
+// import org.forester.phylogeny.Phylogeny;
+// import org.forester.phylogeny.PhylogenyNode;
+//
+/// **
+// * Class for converting trees made in Jalview (through TreeBuilder) to trees
+// * compatible with Forester (Phylogeny objects).
+// *
+// * Note that this currently demands a 1:1 relationship between tree nodes and
+// * the sequences used for generating them.
+// *
+// * @author kjvanderheide
+// *
+// */
+// public class AptxTreeBuilder
+// implements TreeBuilderI
+// {
+// protected final SequenceI[] sequences;
+//
+// protected final DistanceMatrix distances;
+//
+// protected final TreeBuilder jalviewTree;
+//
+// public String treeTitle;
+//
+// private final TreeI aptxTree;
+//
+// private TreeNodeI rootNode;
+//
+// private final Map<SequenceI, TreeNodeI> alignmentWithNodes;
+//
+// private final Map<TreeNodeI, SequenceI> nodesWithAlignment;
+//
+// public AptxTreeBuilder(final TreeBuilder calculatedTree)
+// {
+// jalviewTree = calculatedTree;
+// sequences = jalviewTree.getSequences();
+// distances = ForesterMatrix.convertJalviewToForester(
+// jalviewTree.getDistances(), sequences);
+//
+// aptxTree = new Tree(new Phylogeny());
+// rootNode = TreeNode.getUniqueWrapper(new PhylogenyNode());
+//
+// int amountOfSequences = distances.getSize();
+// alignmentWithNodes = new HashMap<>(amountOfSequences);
+// nodesWithAlignment = new HashMap<>(amountOfSequences);
+//
+//
+// }
+//
+// @Override
+// public TreeI buildTree(final TreeNodeI treeRoot)
+// {
+//
+// if (treeRoot != null)
+// {
+// rootNode = treeRoot;
+// }
+//
+// buildTree();
+//
+// return aptxTree;
+//
+// }
+//
+//
+// @Override
+// public TreeI buildTree()
+// {
+//
+// for (SequenceI sequence : sequences)
+// {
+//
+// TreeNodeI sequenceNode = TreeNode
+// .getUniqueWrapper(
+// new PhylogenyNode(sequence.getName()));
+//
+// sequenceNode.setSequence(sequence);
+//
+// MappingUtils.putWithDuplicationCheck(nodesWithAlignment,
+// sequenceNode, sequence);
+// MappingUtils.putWithDuplicationCheck(alignmentWithNodes,
+// sequence, sequenceNode);
+// rootNode.addAsChild(sequenceNode);
+// }
+//
+//
+// aptxTree.setRoot(rootNode);
+//
+// treeTitle = generateTreeName();
+// aptxTree.setTreeName(treeTitle);
+//
+// return aptxTree;
+//
+// }
+//
+// @Override
+// public Map<SequenceI, TreeNodeI> getAlignmentBoundNodes()
+// {
+// return alignmentWithNodes;
+// }
+//
+// @Override
+// public Map<TreeNodeI, SequenceI> getNodesBoundAlignment()
+// {
+// return nodesWithAlignment;
+// }
+//
+//
+// /**
+// * Formats a localised title for the tree panel, like
+// * <p>
+// * Neighbour Joining Using BLOSUM62
+// * <p>
+// * For a tree loaded from file, just uses the file name
+// *
+// * @return
+// */
+// @Override
+// public String generateTreeName() // Move this and add selection region to the
+// // title when applicable
+// {
+// if (treeTitle != null) // will currently never happen, loaded tree file will
+// // take a different path
+// {
+// return treeTitle;
+// }
+// else
+// {
+// /*
+// * i18n description of Neighbour Joining or Average Distance method
+// */
+// String treecalcnm = MessageManager
+// .getString("label.tree_calc_" + jalviewTree.getClass()
+// .getSimpleName().substring(0, 2).toLowerCase());
+// /*
+// * short score model name (long description can be too long)
+// */
+// String smn = jalviewTree.getScoreModel().getName();
+//
+// /*
+// * put them together as <method> Using <model>
+// */
+// final String ttl = MessageManager
+// .formatMessage("label.treecalc_title", treecalcnm, smn);
+// return ttl;
+// }
+// }
+//
+//
+//
+//
+// }
diff --git a/src/jalview/ext/archaeopteryx/AptxTreePanel.java b/src/jalview/ext/archaeopteryx/AptxTreePanel.java
new file mode 100644 (file)
index 0000000..77b2ddd
--- /dev/null
@@ -0,0 +1,223 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeNodeI;
+import jalview.ext.treeviewer.TreePanelI;
+import jalview.gui.PaintRefresher;
+
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.MenuComponent;
+import java.awt.Rectangle;
+import java.awt.event.MouseListener;
+import java.io.File;
+import java.util.Set;
+
+import javax.accessibility.AccessibleContext;
+
+public class AptxTreePanel implements TreePanelI
+{
+  private final org.forester.archaeopteryx.TreePanel treeView;
+
+  private final TreeI tree;
+
+  private String sequenceSetId;
+
+  protected AptxTreePanel(
+          org.forester.archaeopteryx.TreePanel aptxTreePanel)
+  {
+    treeView = aptxTreePanel;
+    tree = new Tree(treeView.getPhylogeny());
+  }
+
+  protected AptxTreePanel(
+          org.forester.archaeopteryx.TreePanel aptxTreePanel,
+          TreeI aptxTree)
+  {
+    treeView = aptxTreePanel;
+    tree = aptxTree;
+
+  }
+
+  @Override
+  public void setTreeFile(File file)
+  {
+    treeView.setTreeFile(file);
+  }
+
+  @Override
+  public TreeI getTree()
+  {
+    return tree;
+  }
+
+  @Override
+  public File getTreeFile()
+  {
+    return treeView.getTreeFile();
+  }
+
+  @Override
+  public TreeNodeI findNode(int x, int y)
+  {
+    return TreeNode.getUniqueWrapper(treeView.findNode(x, y));
+  }
+
+  @Override
+  public void setMatchingNodes(Set<Long> hashSet)
+  {
+    treeView.setFoundNodes0(hashSet);
+
+  }
+
+  @Override
+  public Set<Long> getMatchingNodes()
+  {
+    return treeView.getFoundNodes0();
+  }
+
+  @Override
+  public AccessibleContext getAccessibleContext()
+  {
+    return treeView.getAccessibleContext();
+  }
+
+  @Override
+  public Font getFont()
+  {
+    return treeView.getFont();
+  }
+
+  @Override
+  public void remove(MenuComponent comp)
+  {
+    treeView.remove(comp);
+
+  }
+
+  @Deprecated
+  @Override
+  public boolean postEvent(Event evt)
+  {
+    return treeView.postEvent(evt);
+  }
+
+  @Override
+  public void addMouseListener(MouseListener listener)
+  {
+    treeView.addMouseListener(listener);
+  }
+
+  @Override
+  public void removeMouseListener(MouseListener listener)
+  {
+    treeView.removeMouseListener(listener);
+
+  }
+
+  @Override
+  public MouseListener[] getMouseListeners()
+  {
+    return treeView.getMouseListeners();
+  }
+
+  @Override
+  public void repaint()
+  {
+    treeView.repaint();
+
+  }
+
+  @Override
+  public void registerWithPaintRefresher(String sequenceSetIdentifier)
+  {
+    sequenceSetId = sequenceSetIdentifier;
+    PaintRefresher.Register(treeView, sequenceSetIdentifier);
+
+  }
+
+  @Override
+  public void notifyPaintRefresher(String sequenceSetIdentifier,
+          boolean alignmentChanged, boolean validateSequences)
+  {
+    PaintRefresher.Refresh(treeView, sequenceSetIdentifier,
+            alignmentChanged, validateSequences);
+
+  }
+
+  @Override
+  public void notifyPaintRefresher(boolean alignmentChanged,
+          boolean validateSequences)
+  {
+    if (sequenceSetId != null)
+    {
+    PaintRefresher.Refresh(treeView, sequenceSetId, alignmentChanged,
+              validateSequences);
+    }
+    else
+    {
+      // throw some kind of exception
+    }
+
+  }
+
+  @Override
+  public int getWidth()
+  {
+    return treeView.getWidth();
+  }
+
+  @Override
+  public int getHeight()
+  {
+    return treeView.getHeight();
+  }
+
+  @Override
+  public void paintToFile(Graphics2D pg, int width, int height)
+  {
+    treeView.paintFile(pg, false, width, height, 0, 0);
+
+  }
+
+  @Override
+  public boolean showingSubTree()
+  {
+    return treeView.isCurrentTreeIsSubtree();
+  }
+
+  @Override
+  public Rectangle getVisibleArea()
+  {
+    return treeView.getVisibleRect();
+  }
+
+  @Override
+  public float getPartitionThreshold()
+  {
+    return treeView.getThreshold();
+  }
+
+  @Override
+  public void setMinimumSize(Dimension minimumSize)
+  {
+    treeView.setMinimumSize(minimumSize);
+
+  }
+
+  @Override
+  public void setMaximumSize(Dimension maximumSize)
+  {
+    treeView.setMaximumSize(maximumSize);
+
+  }
+
+  @Override
+  public void setPreferredSize(Dimension preferredSize)
+  {
+    treeView.setPreferredSize(preferredSize);
+
+  }
+}
diff --git a/src/jalview/ext/archaeopteryx/JalviewBinding.java b/src/jalview/ext/archaeopteryx/JalviewBinding.java
new file mode 100644 (file)
index 0000000..822f749
--- /dev/null
@@ -0,0 +1,747 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.analysis.AlignmentSorter;
+import jalview.analysis.Conservation;
+import jalview.api.AlignViewportI;
+import jalview.commands.CommandI;
+import jalview.commands.OrderCommand;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.ext.treeviewer.LoadedTreeSequenceAssociation;
+import jalview.ext.treeviewer.TreeFrameI;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeNodeI;
+import jalview.ext.treeviewer.TreePanelI;
+import jalview.ext.treeviewer.TreeViewerBindingI;
+import jalview.ext.treeviewer.TreeViewerUtils;
+import jalview.gui.AlignViewport;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.gui.PaintRefresher;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.UserColourScheme;
+import jalview.structure.SelectionSource;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.SwingUtilities;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+/**
+ * Class for binding the Archaeopteryx tree viewer to the Jalview alignment that
+ * it originates from, meaning that selecting sequences in the tree viewer also
+ * selects them in the alignment view and vice versa.
+ * 
+ * @author kjvanderheide
+ *
+ */
+public final class JalviewBinding
+        implements TreeViewerBindingI
+{
+  private final TreeFrameI aptxFrame;
+
+  private TreePanelI treeView;
+
+  private AlignmentViewport parentAvport;
+
+  private final StructureSelectionManager ssm;
+
+  private Map<SequenceI, TreeNodeI> sequencesBoundToNodes;
+
+  private Map<TreeNodeI, SequenceI> nodesBoundToSequences;
+
+  private float rootX;
+
+  private float furthestNodeX;
+
+  private int nrTreeGroups = 0;
+
+  private boolean applyToAllViews = false;
+
+  /**
+   * 
+   * @param archaeopteryx
+   * 
+   * @param jalviewAlignmentViewport
+   *          alignment viewport from which the tree was calculated.
+   * 
+   * @param alignMappedToNodes
+   *          map with sequences used to calculate the tree and matching tree
+   *          nodes as key, value pair respectively.
+   * 
+   * @param nodesMappedToAlign
+   *          map with tree nodes and matching sequences used to calculate the
+   *          tree as key, value pair respectively.
+   */
+  public JalviewBinding(final TreeFrameI archaeopteryx,
+          final AlignmentViewport jalviewAlignmentViewport,
+          final Map<SequenceI, TreeNodeI> alignMappedToNodes,
+          final Map<TreeNodeI, SequenceI> nodesMappedToAlign)
+  {
+
+    if (archaeopteryx.getNumberOfTrees() > 1)
+    {
+      JvOptionPane.showMessageDialog(Desktop.desktop,
+              MessageManager.getString("label.tabs_detected_archaeopteryx"),
+              MessageManager.getString("label.problem_reading_tree_file"),
+              JvOptionPane.WARNING_MESSAGE);
+
+    }
+
+    // deal with/prohibit null values here as that will cause problems
+    aptxFrame = archaeopteryx;
+    parentAvport = jalviewAlignmentViewport;
+    sequencesBoundToNodes = alignMappedToNodes;
+    nodesBoundToSequences = nodesMappedToAlign;
+
+    treeView = archaeopteryx.getTreePanel();
+    ssm = parentAvport.getStructureSelectionManager();
+    
+    aptxFrame.setViewBinding(this);
+    ssm.addSelectionListener(this);
+    treeView.addMouseListener(this);
+    treeView.registerWithPaintRefresher(
+            parentAvport.getSequenceSetId());
+
+    aptxFrame.addFrameListener(new InternalFrameAdapter()
+    {
+
+      @Override
+      public void internalFrameClosed(InternalFrameEvent e)
+      {
+        TreeViewerUtils.getActiveTreeViews().remove(aptxFrame);
+        ssm.removeSelectionListener(JalviewBinding.this);
+      }
+
+    });
+
+    // treeTabs.addChangeListener(new ChangeListener()
+    // {
+    //
+    // @Override
+    // public void stateChanged(ChangeEvent e)
+    // {
+    //
+    // SwingUtilities.invokeLater(new Runnable()
+    // {
+    //
+    // @Override
+    // /**
+    // * Resend the selection to the tree view when tabs get switched, this
+    // * has to be buried in invokeLater as Forester first resets the tree
+    // * view on switching tabs, without invokeLater this would get called
+    // * before Forester resets which would nullify the selection.
+    // */
+    // public void run()
+    // {
+    // treeView = archaeopteryx.getMainPanel().getCurrentTreePanel();
+    // parentAvport.sendSelection();
+    // // PaintRefresher.Refresh(treeView,
+    // // parentAvport.getSequenceSetId());
+    //
+    // }
+    // });
+    //
+    // }
+    //
+    // });
+
+  }
+
+  @Override
+  public void actionPerformed(ActionEvent e)
+  {
+    // reset hidden sequences first
+    parentAvport.showAllHiddenSeqs();
+
+    if (treeView.showingSubTree())
+    {
+      LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation(
+              parentAvport.getAlignment().getSequencesArray(),
+              treeView.getTree());
+      bindAptxNodes.associateLeavesToSequences();
+      sequencesBoundToNodes = bindAptxNodes.getAlignmentWithNodes();
+      nodesBoundToSequences = bindAptxNodes.getNodesWithAlignment();
+      TreeViewerUtils.associateNodesWithJalviewSequences(aptxFrame,
+              parentAvport, sequencesBoundToNodes, nodesBoundToSequences);
+
+      for (SequenceI seq : parentAvport.getAlignment().getSequencesArray())
+      {
+        if (!sequencesBoundToNodes.containsKey(seq))
+        {
+          parentAvport.hideSequence(new SequenceI[] { seq });
+        }
+      }
+    }
+
+    else
+    {
+
+      Rectangle visibleView = treeView.getVisibleArea();
+
+      for (TreeNodeI node : treeView.getTree().getRoot()
+              .getAllDescendants())
+      {
+        if (!(node.getXcoord() > visibleView.getMinX()
+                && node.getXcoord() < visibleView.getMaxX()
+                && node.getYcoord() > visibleView.getMinY()
+                && node.getYcoord() < visibleView.getMaxY()))
+        {
+          parentAvport
+                  .hideSequence(new SequenceI[]
+                  { nodesBoundToSequences.get(node) });
+        }
+      }
+
+    }
+
+
+
+  }
+
+  @Override
+  public void mouseClicked(MouseEvent e)
+  {
+    SwingUtilities.invokeLater(new Runnable() {
+
+      @Override
+      /**
+       * invokeLater so that this always runs after Forester's mouseClicked
+       */
+      public void run()
+      {
+        final TreeNodeI node = treeView.findNode(e.getX(),
+                e.getY());
+        if (node != null)
+        {
+          if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous
+          // selection if shift
+          // IS NOT pressed
+          {
+            parentAvport.setSelectionGroup(null);
+
+          }
+          showNodeSelectionOnAlign(node);
+        }
+        else
+        {
+
+          partitionTree(e.getX());
+      }
+        treeView.notifyPaintRefresher(parentAvport.getSequenceSetId(),
+                false, false);
+        treeView.repaint();
+
+
+
+      }
+    });
+
+
+  }
+
+  @Override
+  public void mousePressed(final MouseEvent e)
+  {
+
+  }
+  @Override
+  public void mouseReleased(MouseEvent e)
+  {
+  }
+
+  @Override
+  public void mouseEntered(MouseEvent e)
+  {
+  }
+
+  @Override
+  public void mouseExited(MouseEvent e)
+  {
+  }
+
+
+  @Override
+  public void selection(final SequenceGroup seqsel,
+          final ColumnSelection colsel, final HiddenColumns hidden,
+          final SelectionSource source)
+  {
+    if (source == parentAvport) // check if source is alignment from where the
+    // tree originates
+    {
+      treeView.setMatchingNodes(
+              new HashSet<Long>(seqsel.getSequences().size()));
+
+
+      for (SequenceI selectedSequence : seqsel.getSequences())
+      {
+        TreeNodeI matchingNode = sequencesBoundToNodes
+                .get(selectedSequence);
+        if (matchingNode != null)
+        {
+          treeView.getMatchingNodes().add(matchingNode.getId());
+
+
+          // if (!matchingNode.getBranchData().isHasBranchColor())
+          // {
+          // // Color foundNodesColour = treeView.getTreeColorSet()
+          // // .getFoundColor0();
+          // // matchingNode.getBranchData()
+          // // .setBranchColor(new BranchColor(foundNodesColour));
+          //
+          // }
+
+        }
+
+      }
+
+      treeView.repaint();
+    }
+
+
+  }
+
+  /**
+   * Partially refactored from TreeCanvas
+   */
+  public void partitionTree(final int x)
+  {
+    TreeI tree = treeView.getTree();
+
+    if (!tree.isEmpty())
+    {
+      // should be calculated on each partition as the tree can theoretically
+      // change in the meantime
+      TreeNodeI furthestNode = tree.getFurthestNode();
+      furthestNodeX = furthestNode.getXcoord();
+      rootX = tree.getRoot().getXcoord();
+
+      // don't bother if 0 distance tree or clicked x lies outside of tree
+      if (furthestNodeX != rootX && !(x > furthestNodeX))
+      {
+        float threshold = (x - rootX) / (furthestNodeX - rootX);
+        List<TreeNodeI> foundNodes = getNodesAboveThreshold(
+                threshold,
+                tree.getRoot());
+
+      }
+      else
+      {
+        // clear previous colours?
+      }
+    }
+
+
+  }
+
+  public List<TreeNodeI> getNodesAboveThreshold(float threshold,
+          TreeNodeI node)
+  {
+
+    List<TreeNodeI> nodesAboveThreshold = new ArrayList<>();
+
+    parentAvport.setSelectionGroup(null);
+    parentAvport.getAlignment().deleteAllGroups();
+    parentAvport.clearSequenceColours();
+    if (parentAvport.getCodingComplement() != null)
+    {
+      parentAvport.getCodingComplement().setSelectionGroup(null);
+      parentAvport.getCodingComplement().getAlignment().deleteAllGroups();
+      parentAvport.getCodingComplement().clearSequenceColours();
+    }
+
+
+    colourNodesAboveThreshold(nodesAboveThreshold, threshold,
+            node);
+    return nodesAboveThreshold;
+
+  }
+
+  /**
+   * Partially refactored from TreeCanvas colourGroups (can be made nicer).
+   * 
+   * @param nodeList
+   * @param threshold
+   * @param treeLength
+   * @param node
+   * @return
+   */
+  private List<TreeNodeI> colourNodesAboveThreshold(
+          List<TreeNodeI> nodeList, float threshold,
+          TreeNodeI node)
+  {
+
+    for (TreeNodeI childNode : node.getDirectChildren())
+    {
+      childNode.setBranchColor(Color.black);
+      float nodeCutoff = (childNode.getXcoord() - rootX)
+              / (furthestNodeX - rootX);
+
+      if (nodeCutoff > threshold)
+      {
+        nodeList.add(childNode);
+
+        Color randomColour = new Color((int) (Math.random() * 255),
+                (int) (Math.random() * 255), (int) (Math.random() * 255));
+        childNode.setBranchColor(randomColour);
+
+        List<SequenceI> groupSeqs = new ArrayList<>();
+        SequenceI seq = nodesBoundToSequences.get(childNode);
+        if (seq != null)
+        {
+          groupSeqs.add(seq);
+          parentAvport.setSequenceColour(seq, randomColour);
+        }
+
+        List<TreeNodeI> descendantNodes = childNode
+                .getAllDescendants();
+        // .forEach instead?
+        for (TreeNodeI descNode : descendantNodes)
+        {
+          seq = nodesBoundToSequences.get(descNode);
+          if (seq != null)
+          {
+            groupSeqs.add(seq);
+            parentAvport.setSequenceColour(seq, randomColour);
+          }
+
+          descNode.setBranchColor(randomColour);
+        }
+
+        if (groupSeqs != null)
+        {
+          nrTreeGroups++;
+          groupThresholdSequences(groupSeqs, randomColour);
+        }}
+
+      else
+      {
+        colourNodesAboveThreshold(nodeList, threshold, childNode);
+      }
+    }
+
+    for (AlignmentPanel associatedPanel : getAssociatedPanels())
+    {
+
+        associatedPanel.updateAnnotation();
+
+        final AlignViewportI codingComplement = associatedPanel.getAlignViewport()
+                .getCodingComplement();
+        if (codingComplement != null)
+        {
+          // GROSS
+          ((AlignViewport) codingComplement).getAlignPanel()
+                  .updateAnnotation();
+        }
+      }
+
+
+    return nodeList;
+  }
+
+  public void groupThresholdSequences(List<SequenceI> groupedSeqs,
+          Color groupColour)
+  {
+    SequenceGroup treeGroup = new SequenceGroup(groupedSeqs, null, null,
+            true, true, false, 0,
+            parentAvport.getAlignment().getWidth() - 1);
+
+    ColourSchemeI cs = null;
+    if (parentAvport.getGlobalColourScheme() != null)
+    {
+      if (parentAvport.getGlobalColourScheme() instanceof UserColourScheme)
+      {
+        cs = new UserColourScheme(
+                ((UserColourScheme) parentAvport.getGlobalColourScheme())
+                        .getColours());
+      }
+      else
+      {
+        cs = ColourSchemeProperty.getColourScheme(treeGroup,
+                ColourSchemeProperty.getColourName(
+                        parentAvport.getGlobalColourScheme()));
+      }
+
+    }
+    treeGroup.setColourScheme(cs);
+    treeGroup.getGroupColourScheme().setThreshold(
+            parentAvport.getResidueShading().getThreshold(),
+            parentAvport.isIgnoreGapsConsensus());
+
+    treeGroup.setName("Tree Group " + nrTreeGroups);
+    treeGroup.setIdColour(groupColour);
+
+    for (AlignmentPanel associatedPanel : getAssociatedPanels())
+    {
+      AlignViewportI altViewport = associatedPanel
+              .getAlignViewport();
+
+      if (altViewport.getGlobalColourScheme() != null
+              && altViewport.getResidueShading()
+                      .conservationApplied())
+      {
+        Conservation conserv = new Conservation(treeGroup.getName(),
+                treeGroup.getSequences(null), treeGroup.getStartRes(),
+                treeGroup.getEndRes());
+        conserv.calculate();
+        conserv.verdict(false, altViewport.getConsPercGaps());
+        treeGroup.getGroupColourScheme().setConservation(conserv);
+      }
+
+      altViewport.getAlignment().addGroup(treeGroup);
+      // TODO can we push all of the below into AlignViewportI?
+      final AlignViewportI codingComplement = altViewport
+              .getCodingComplement();
+      if (codingComplement != null)
+      {
+        SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(treeGroup,
+                parentAvport, codingComplement);
+        if (mappedGroup.getSequences().size() > 0)
+        {
+          codingComplement.getAlignment().addGroup(mappedGroup);
+          for (SequenceI seq : mappedGroup.getSequences())
+          {
+            codingComplement.setSequenceColour(seq, groupColour.brighter());
+          }
+        }
+      }
+
+    }
+
+  }
+
+  /**
+   * may or may not need an extra repaint on the alignment view (check what kira
+   * does)
+   */
+  @Override
+  public void showNodeSelectionOnAlign(final TreeNodeI node)
+  {
+
+      if (node.isInternal())
+      {
+        showMatchingChildSequences(node);
+      }
+
+      else
+      {
+        showMatchingSequence(node);
+      }
+
+
+    }
+
+
+
+
+
+  @Override
+  public void showMatchingSequence(final TreeNodeI nodeToMatch)
+  {
+    SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch);
+    if (matchingSequence != null)
+    {
+      long nodeId = nodeToMatch.getId();
+      addOrRemoveInSet(treeView.getMatchingNodes(), nodeId);
+      treeSelectionChanged(matchingSequence);
+      parentAvport.sendSelection();
+
+    }
+  }
+
+  @Override
+  public void showMatchingChildSequences(final TreeNodeI parentNode)
+  {
+    // redundancy here, Forester already iterates through tree to get all
+    // descendants
+    List<TreeNodeI> childNodes = parentNode.getAllDescendants();
+
+
+    for (TreeNodeI childNode : childNodes)
+    {
+      // childNode.getBranchData().setBranchColor(new BranchColor(Color.BLUE));
+
+      SequenceI matchingSequence = nodesBoundToSequences.get(childNode);
+      if (matchingSequence != null)
+      {
+        long nodeId = childNode.getId();
+        addOrRemoveInSet(treeView.getMatchingNodes(), nodeId);
+
+        treeSelectionChanged(matchingSequence);
+
+      }
+
+    }
+    parentAvport.sendSelection();
+
+
+  }
+
+  /**
+   * Refactored from TreeCanvas.
+   * 
+   * @param sequence
+   *          of the node selected in the tree viewer.
+   */
+  @Override
+  public void treeSelectionChanged(final SequenceI sequence)
+  {
+    if (!parentAvport.isClosed()) // alignment view could be closed
+    {
+      SequenceGroup selected = parentAvport.getSelectionGroup();
+
+      if (selected == null)
+      {
+        selected = new SequenceGroup();
+        parentAvport.setSelectionGroup(selected);
+      }
+
+      selected.setEndRes(parentAvport.getAlignment().getWidth() - 1);
+        selected.addOrRemove(sequence, true);
+    }
+
+  }
+
+  @Override
+  public void sortByTree_actionPerformed()
+  {
+
+    // if (applyToAllViews)
+
+      final ArrayList<CommandI> commands = new ArrayList<>();
+      for (AlignmentPanel ap : PaintRefresher
+              .getAssociatedPanels(parentAvport.getSequenceSetId()))
+      {
+        commands.add(sortAlignmentIn(ap.av.getAlignPanel()));
+        ap.alignFrame.addHistoryItem(new CommandI()
+        {
+
+          @Override
+          public void undoCommand(AlignmentI[] views)
+          {
+            for (CommandI tsort : commands)
+            {
+              tsort.undoCommand(views);
+            }
+          }
+
+          @Override
+          public int getSize()
+          {
+            return commands.size();
+          }
+
+          @Override
+          public String getDescription()
+          {
+            return "Tree Sort (many views)";
+          }
+
+          @Override
+          public void doCommand(AlignmentI[] views)
+          {
+
+            for (CommandI tsort : commands)
+            {
+              tsort.doCommand(views);
+            }
+          }
+        });
+
+        ap.alignFrame.updateEditMenuBar();
+      }
+    }
+  // else
+  // {
+  // alignPanel.alignFrame.addHistoryItem(sortAlignmentIn(alignPanel));
+  // }
+
+
+
+  @Override
+  public CommandI sortAlignmentIn(AlignmentPanel ap)
+  {
+    AlignmentViewport viewport = ap.av;
+    SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
+    try
+    {
+    AlignmentSorter.sortByTree(viewport.getAlignment(),
+            nodesBoundToSequences,
+              treeView.getTree());
+      CommandI undo;
+      undo = new OrderCommand("Tree Sort", oldOrder,
+              viewport.getAlignment());
+
+      ap.paintAlignment(true, false);
+      return undo;
+
+    } catch (Exception e)
+    {
+      System.err.println(e.getMessage());
+    }
+    return null;
+
+  }
+  
+
+
+  /**
+   * TO BE MOVED
+   * 
+   * @param set
+   * @param objectToCheck
+   */
+  public static <E> void addOrRemoveInSet(Set<E> set, E objectToCheck)
+  {
+    if (set.contains(objectToCheck))
+    {
+      set.remove(objectToCheck);
+    }
+    else
+    {
+      set.add(objectToCheck);
+    }
+
+  }
+
+  public AlignmentViewport getParentAvport()
+  {
+    return parentAvport;
+  }
+
+  public void setParentAvport(final AlignmentViewport parentAvport)
+  {
+    this.parentAvport = parentAvport;
+  }
+
+  public AlignmentPanel[] getAssociatedPanels()
+  {
+    return PaintRefresher
+            .getAssociatedPanels(parentAvport.getSequenceSetId());
+  }
+
+
+
+}
+
+
+
diff --git a/src/jalview/ext/archaeopteryx/Tree.java b/src/jalview/ext/archaeopteryx/Tree.java
new file mode 100644 (file)
index 0000000..8c1d0be
--- /dev/null
@@ -0,0 +1,199 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.datamodel.SequenceI;
+import jalview.ext.treeviewer.TreeFrameI;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeNodeI;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.forester.archaeopteryx.Archaeopteryx;
+import org.forester.io.writers.PhylogenyWriter;
+import org.forester.phylogeny.Phylogeny;
+import org.forester.phylogeny.PhylogenyMethods;
+import org.forester.phylogeny.PhylogenyNode;
+
+public class Tree implements TreeI
+{
+  private final Phylogeny tree;
+
+  // alternative to static maps in TreeNode
+  // private Map<PhylogenyNode, TreeNodeI> originalNodes = new HashMap<>(500);
+  // private Map<TreeNodeI, PhylogenyNode> wrappedNodes = new HashMap<>(500);
+
+  public Tree()
+  {
+    tree = new Phylogeny();
+  }
+
+  public Tree(Phylogeny aptxTree)
+  {
+    tree = aptxTree;
+    wrapAllTreeNodes();
+
+  }
+
+  private void wrapAllTreeNodes()
+  {
+    for (Iterator<PhylogenyNode> iterator = tree
+            .iteratorPostorder(); iterator.hasNext();)
+    {
+      PhylogenyNode foresterNode = iterator.next();
+      TreeNodeI treeNode = TreeNode
+              .getUniqueWrapper(foresterNode);
+
+    }
+  }
+
+  @Override
+  public TreeNodeI getRoot()
+  {
+    TreeNodeI root = TreeNode.getUniqueWrapper(tree.getRoot());
+    return root;
+  }
+
+  @Override
+  public void setTreeName(String name)
+  {
+    tree.setName(name);
+
+  }
+
+  @Override
+  public TreeNodeI getNodeWithName(String name)
+  {
+    return TreeNode.getUniqueWrapper(tree.getNode(name));
+
+  }
+
+  @Override
+  public String[] getAllLeafNames()
+  {
+    return tree.getAllExternalNodeNames();
+  }
+
+  @Override
+  public void setRerootable(boolean b)
+  {
+    tree.setRerootable(b);
+
+  }
+
+  @Override
+  public void setRooted(boolean b)
+  {
+    tree.setRooted(b);
+
+  }
+
+  @Override
+  public boolean isEmpty()
+  {
+    return tree.isEmpty();
+  }
+
+  @Override
+  public String getTreeName()
+  {
+    return tree.getName();
+  }
+
+  @Override
+  public void setRoot(TreeNodeI rootNode)
+  {
+    PhylogenyNode treeRoot = TreeNode.unwrapNode(rootNode);
+    tree.setRoot(treeRoot);
+    wrapAllTreeNodes();
+
+  }
+
+  @Override
+  public double getHeight(boolean adjustForCollapsedSubtrees)
+  {
+    return tree.calculateHeight(adjustForCollapsedSubtrees);
+  }
+
+  @Override
+  public Iterator<TreeNodeI> iterateInPreOrder()
+  {
+    Iterator<TreeNodeI> iter = new TreeIterator(
+            tree.iteratorPreorder());
+    return iter;
+  }
+
+  @Override
+  public Iterator<TreeNodeI> iterateInLevelOrder()
+  {
+    Iterator<TreeNodeI> iter = new TreeIterator(
+            tree.iteratorLevelOrder());
+    return iter;
+  }
+
+  @Override
+  public Iterator<TreeNodeI> iterateInPostOrder()
+  {
+    Iterator<TreeNodeI> iter = new TreeIterator(
+            tree.iteratorPostorder());
+    return iter;
+  }
+
+  @Override
+  public TreeNodeI getFurthestNode()
+  {
+    PhylogenyNode furthestNode = PhylogenyMethods
+            .calculateNodeWithMaxDistanceToRoot(tree);
+    return TreeNode.getUniqueWrapper(furthestNode);
+  }
+
+  @Override
+  public TreeFrameI createTreeViewerFromTree(String instanceTitle)
+  {
+    return new AptxFrame(Archaeopteryx.createApplication(tree,
+            AptxInit.APTX_CONFIG,
+            instanceTitle));
+  }
+
+  @Override
+  public List<SequenceI> getNodeSequences()
+  {
+    List<SequenceI> treeSeqs = new ArrayList<>();
+    Iterator<TreeNodeI> iter = iterateInPreOrder();
+    while (iter.hasNext())
+    {
+
+      SequenceI nodeSeq = iter.next().getSequence();
+      if (nodeSeq != null)
+      {
+        treeSeqs.add(nodeSeq);
+      }
+    }
+    return treeSeqs;
+  }
+
+  @Override
+  public TreeNodeI[] getAllNodes()
+  {
+    TreeNodeI[] treeNodes = new TreeNodeI[tree.getNodeCount()];
+    Iterator<TreeNodeI> iter = iterateInPreOrder();
+    int i = 0;
+    while (iter.hasNext())
+    {
+      treeNodes[i++] = iter.next();
+    }
+    return treeNodes;
+  }
+
+  @Override
+  public void writeToXml(File outputFile) throws IOException
+  {
+    PhylogenyWriter treeWriter = new PhylogenyWriter();
+    treeWriter.toPhyloXML(tree, 0, outputFile);
+
+
+  }
+
+}
diff --git a/src/jalview/ext/archaeopteryx/TreeIterator.java b/src/jalview/ext/archaeopteryx/TreeIterator.java
new file mode 100644 (file)
index 0000000..20c8fc8
--- /dev/null
@@ -0,0 +1,31 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.ext.treeviewer.TreeNodeI;
+
+import java.util.Iterator;
+
+import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
+
+public class TreeIterator implements Iterator<TreeNodeI>
+{
+  private final PhylogenyNodeIterator iter;
+
+  public TreeIterator(PhylogenyNodeIterator aptxIterator)
+  {
+    iter = aptxIterator;
+  }
+
+  @Override
+  public boolean hasNext()
+  {
+    return iter.hasNext();
+  }
+
+  @Override
+  public TreeNodeI next()
+  {
+    TreeNodeI node = TreeNode.getUniqueWrapper(iter.next());
+    return node;
+  }
+
+}
diff --git a/src/jalview/ext/archaeopteryx/TreeNode.java b/src/jalview/ext/archaeopteryx/TreeNode.java
new file mode 100644 (file)
index 0000000..752826b
--- /dev/null
@@ -0,0 +1,250 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.datamodel.SequenceI;
+import jalview.ext.forester.DataConversions;
+import jalview.ext.treeviewer.TreeNodeI;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.forester.phylogeny.PhylogenyMethods;
+import org.forester.phylogeny.PhylogenyNode;
+
+public class TreeNode implements TreeNodeI
+{
+  private final PhylogenyNode node;
+
+  private SequenceI nodeSeq;
+
+  private static Map<PhylogenyNode, TreeNodeI> originalNodes = new HashMap<>(
+          500); // prolly make this size dynamic?
+
+  private static Map<TreeNodeI, PhylogenyNode> wrappedNodes = new HashMap<>(
+          500);
+
+  /**
+   * Please don't use me directly.
+   * 
+   * @param aptxNode
+   */
+  private TreeNode(PhylogenyNode aptxNode)
+  {
+    node = aptxNode;
+    if (aptxNode.getNodeData().getSequence() != null)
+    {
+    nodeSeq = DataConversions
+              .createJalviewSequence(aptxNode);
+    }
+    originalNodes.put(aptxNode, this);
+    wrappedNodes.put(this, aptxNode);
+
+  }
+
+
+  @Override
+  public String getNodeName()
+  {
+    return node.getName();
+  }
+
+
+  @Override
+  public List<TreeNodeI> getAllDescendants()
+  {
+
+    List<PhylogenyNode> descNodes = PhylogenyMethods
+            .getAllDescendants(node);
+    return getUniqueWrappers(descNodes);
+    
+
+  }
+
+  @Override
+  public List<TreeNodeI> getExternalDescendants()
+  {
+    List<PhylogenyNode> extDescNodes = node.getAllExternalDescendants();
+    return getUniqueWrappers(extDescNodes);
+  }
+
+
+  @Override
+  public List<TreeNodeI> getDirectChildren()
+  {
+    List<PhylogenyNode> childNodes = node.getDescendants();
+    return getUniqueWrappers(childNodes);
+    
+
+  }
+
+
+
+  @Override
+  public void setSequence(SequenceI seq)
+  {
+    nodeSeq = seq;
+    org.forester.phylogeny.data.Sequence foresterFormatSeq = DataConversions
+            .createForesterSequence(seq, true);
+    node.getNodeData().setSequence(foresterFormatSeq);
+
+  }
+
+  @Override
+  public SequenceI getSequence()
+  {
+    return nodeSeq;
+  }
+
+  @Override
+  public void addAsChild(TreeNodeI childNode)
+  {
+    PhylogenyNode aptxNode = unwrapNode(childNode);
+
+    node.addAsChild(aptxNode);
+
+  }
+
+  @Override
+  public long getId()
+  {
+    return node.getId();
+  }
+
+  @Override
+  public float getXcoord()
+  {
+    return node.getXcoord();
+  }
+
+  @Override
+  public void setBranchColor(Color branchColor)
+  {
+    PhylogenyMethods.setBranchColorValue(node, branchColor);
+
+  }
+
+  @Override
+  public boolean isInternal()
+  {
+    return node.isInternal();
+  }
+
+  public static List<TreeNodeI> getUniqueWrappers(
+          List<PhylogenyNode> aptxNodes)
+  {
+    List<TreeNodeI> wrappedNodes = new ArrayList<>(
+            aptxNodes.size());
+
+    for (PhylogenyNode aptxNode : aptxNodes)
+    {
+      wrappedNodes.add(getUniqueWrapper(aptxNode));
+    }
+    return wrappedNodes;
+  }
+
+  /**
+   * This method should be used to create new wrappers as there is a possibility
+   * the Archaeopteryx node was already introduced to Jalview previously so this
+   * avoids giving one node duplicate wrappers
+   * 
+   * @param aptxNode
+   * @return
+   */
+  public static TreeNodeI getUniqueWrapper(
+          PhylogenyNode aptxNode)
+  {
+    if (aptxNode == null)
+    {
+      return null;
+    }
+    TreeNodeI wrappedNode = originalNodes.get(aptxNode);
+    if (wrappedNode == null)
+    {
+      wrappedNode = new TreeNode(aptxNode);
+    }
+    return wrappedNode;
+  }
+
+  /**
+   * Attempts to unwrap the given node, if the unwrapped node already exists it
+   * is simply returned as is. If it is not however, the wrapper will be used to
+   * create a new Archaeopteryx node. This way it becomes possible to construct
+   * new Archaeopteryx nodes from different tree viewers, as long as they
+   * implement the interface.
+   * 
+   * @param wrappedNode
+   * @return
+   */
+  protected static PhylogenyNode unwrapNode(TreeNodeI wrappedNode)
+  {
+    if (wrappedNode == null)
+    {
+      return null;
+    }
+    PhylogenyNode aptxNode = wrappedNodes.get(wrappedNode);
+    if (aptxNode == null)
+    {
+      // expand this
+      aptxNode = new PhylogenyNode(wrappedNode.getNodeName());
+
+    }
+    return aptxNode;
+
+  }
+
+
+  @Override
+  public int hashCode()
+  {
+    final int prime = 31;
+    int result = 1;
+    result = (int) (prime * result
+            + ((node == null) ? 0 : (node.hashCode() * getId())));
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj)
+  {
+    if (this == obj)
+    {
+      return true;
+    }
+    if (obj == null)
+    {
+      return false;
+    }
+    if (getClass() != obj.getClass())
+    {
+      return false;
+    }
+    TreeNode other = (TreeNode) obj;
+    if (node == null)
+    {
+      if (other.node != null)
+      {
+        return false;
+      }
+    }
+    if (getId() != other.getId())
+    {
+      return false;
+    }
+
+    if (!node.equals(other.node))
+    {
+      return false;
+    }
+    return true;
+  }
+
+
+  @Override
+  public float getYcoord()
+  {
+    return node.getYcoord();
+  }
+
+}
diff --git a/src/jalview/ext/forester/DataConversions.java b/src/jalview/ext/forester/DataConversions.java
new file mode 100644 (file)
index 0000000..a6ed3d9
--- /dev/null
@@ -0,0 +1,94 @@
+package jalview.ext.forester;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.math.MatrixI;
+
+import org.forester.evoinference.matrix.distance.DistanceMatrix;
+import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
+import org.forester.phylogeny.PhylogenyNode;
+
+public final class DataConversions
+{
+  public static org.forester.phylogeny.data.Sequence createForesterSequence(
+          final SequenceI jalviewSequence, final boolean sequenceIsAligned)
+  {
+    org.forester.phylogeny.data.Sequence foresterSeq = new org.forester.phylogeny.data.Sequence();
+
+    if (jalviewSequence.getDescription() != null)
+    {
+      foresterSeq.setName(jalviewSequence.getDescription());
+    }
+
+    // all tree sequences should be aligned already
+    foresterSeq.setMolecularSequenceAligned(sequenceIsAligned);
+
+    foresterSeq.setMolecularSequence(jalviewSequence.getSequenceAsString());
+    
+    // add checks for DNA or RNA (infer from forester itself?)
+    if (jalviewSequence.isProtein())
+    {
+      try
+      {
+        foresterSeq.setType("protein");
+      } catch (final PhyloXmlDataFormatException ignore)
+      {
+        // do nothing
+      }
+
+    }
+
+    return foresterSeq;
+
+  }
+
+  public static SequenceI createJalviewSequence(
+          PhylogenyNode foresterNode)
+  {
+    String seq = foresterNode.getNodeData().getSequence()
+            .getMolecularSequence();
+    String seqName = foresterNode.getName();
+
+    SequenceI jalviewSeq = new Sequence(seqName, seq, 1,
+            seq.length() + 1);
+    return jalviewSeq.deriveSequence();
+
+
+  }
+
+
+  // public static org.forester.phylogeny.data.Accession
+  // createForesterAccession(
+  // SequenceI jalviewSequence)
+  // {
+  //
+  //
+  // org.forester.phylogeny.data.Accession foresterAcs = new
+  // org.forester.phylogeny.data.Accession();
+  //
+  // return foresterAcs;
+  // }
+
+  public static DistanceMatrix createForesterDistanceMatrix(
+          final MatrixI jalviewInputMatrix,
+          final String[] matrixIdentifiers)
+  {
+
+    DistanceMatrix foresterMatrix = new ForesterMatrix(jalviewInputMatrix,
+            matrixIdentifiers);
+    return foresterMatrix;
+
+  }
+
+  public static DistanceMatrix createForesterDistanceMatrix(
+          final MatrixI jalviewInputMatrix,
+          final SequenceI[] matrixSequences)
+  {
+    DistanceMatrix foresterMatrix = new ForesterMatrix(jalviewInputMatrix,
+            matrixSequences);
+    return foresterMatrix;
+
+  }
+
+
+}
diff --git a/src/jalview/ext/forester/ForesterMatrix.java b/src/jalview/ext/forester/ForesterMatrix.java
new file mode 100644 (file)
index 0000000..a12dc1d
--- /dev/null
@@ -0,0 +1,184 @@
+package jalview.ext.forester;
+
+import jalview.datamodel.SequenceI;
+import jalview.math.MatrixI;
+import jalview.util.MessageManager;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.NoSuchElementException;
+import java.util.stream.IntStream;
+
+import org.forester.evoinference.matrix.distance.DistanceMatrix;
+import org.forester.util.ForesterUtil;
+import org.forester.util.IllegalFormatUseException;
+
+public class ForesterMatrix implements DistanceMatrix
+{
+  private final static NumberFormat PHYLIP_FORMATTER = new DecimalFormat(
+          "0.000000"); // straight from forester
+
+  private final MatrixI jalviewMatrix;
+
+  private final String[] identifiers;
+
+  public ForesterMatrix(final MatrixI jalviewInputMatrix,
+          final SequenceI[] matrixSequences)
+  {
+    this.jalviewMatrix = jalviewInputMatrix;
+    this.identifiers = new String[matrixSequences.length];
+
+    int i = 0;
+    for (SequenceI sequence : matrixSequences)
+    {
+      identifiers[i] = sequence.getName();
+      i++;
+    }
+
+  }
+
+  public ForesterMatrix(final MatrixI jalviewInputMatrix,
+          final String[] matrixIdentifiers)
+  {
+    this.jalviewMatrix = jalviewInputMatrix;
+    this.identifiers = matrixIdentifiers;
+
+  }
+
+  @Override
+  public String getIdentifier(final int i)
+  {
+    return identifiers[i]; // add handling if index is out of bounds
+  }
+
+
+  @Override
+  public int getIndex(final String identifier)
+  {
+    try {
+    return IntStream.range(0, identifiers.length)
+            .filter(x -> identifier.equals(identifiers[x])).findAny()
+              .getAsInt(); // stream to bypass otherwise having to duplicate the
+                           // list
+                           // with Arrays.aslist
+    }
+    catch (NoSuchElementException ex) {
+      throw new Error(MessageManager.formatMessage(
+              "exception.invalid_matrix_identifier", new String[]
+              { identifier }));
+    }
+  }
+
+  /**
+   * Returns the length of whichever is longest, columns or rows
+   */
+  @Override
+  public int getSize()
+  {
+    return jalviewMatrix.getValues().length;
+  }
+
+  /**
+   * See {@link MatrixI#getValue(int,int)} except that the order of column, row
+   * in the parameters is inverted here (as that is how forester demands it)
+   */
+  @Override
+  public double getValue(final int col, final int row)
+  {
+    return jalviewMatrix.getValue(row, col);
+  }
+
+  @Override
+  public void setIdentifier(final int i, final String identifier)
+  {
+    identifiers[i] = identifier;
+
+  }
+
+  /**
+   * See {@link MatrixI#setValue()} except that the order of column, row in the
+   * parameters is inverted here (as that is how forester demands it)
+   */
+  @Override
+  public void setValue(final int col, final int row, final double distance)
+  {
+    jalviewMatrix.setValue(row, col, distance);
+
+  }
+
+  @Override
+  public StringBuffer toStringBuffer(Format format)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /**
+   * See {@link MatrixI#getValues()}
+   */
+  @Override
+  public double[][] getValues()
+  {
+    return jalviewMatrix.getValues();
+  }
+
+  @Override
+  public void write(final Writer w) throws IOException // directly copied from
+                                                 // forester
+  {
+    w.write("    ");
+    w.write(getSize() + "");
+    w.write(ForesterUtil.LINE_SEPARATOR);
+    for (int row = 0; row < getSize(); ++row)
+    {
+      if (!ForesterUtil.isEmpty(getIdentifier(row)))
+      {
+        w.write(ForesterUtil.pad(getIdentifier(row), 10, ' ', false)
+                .toString());
+        w.write(' ');
+        w.write(' ');
+      }
+      else
+      {
+        throw new IllegalFormatUseException(
+                "Phylip format does not allow empty identifiers");
+      }
+      for (int col = 0; col < getSize(); ++col)
+      {
+        w.write(PHYLIP_FORMATTER.format(getValue(col, row)));
+        if (col < (getSize() - 1))
+        {
+          w.write(' ');
+          w.write(' ');
+        }
+      }
+      if (row < (getSize() - 1))
+      {
+        w.write(ForesterUtil.LINE_SEPARATOR);
+      }
+    }
+
+  }
+
+  public static DistanceMatrix convertJalviewToForester(
+          final MatrixI jalviewInputMatrix,
+          final SequenceI[] matrixSequences)
+  {
+    return DataConversions.createForesterDistanceMatrix(
+            jalviewInputMatrix, matrixSequences);
+
+  }
+
+  public static DistanceMatrix convertJalviewToForester(
+          final MatrixI jalviewInputMatrix,
+          final String[] matrixIdentifiers)
+  {
+    return DataConversions.createForesterDistanceMatrix(
+            jalviewInputMatrix, matrixIdentifiers);
+
+  }
+
+
+}
\ No newline at end of file
diff --git a/src/jalview/ext/forester/io/ForesterParser.java b/src/jalview/ext/forester/io/ForesterParser.java
new file mode 100644 (file)
index 0000000..b0c2bdb
--- /dev/null
@@ -0,0 +1,90 @@
+package jalview.ext.forester.io;
+
+import jalview.ext.archaeopteryx.AptxInit;
+import jalview.ext.archaeopteryx.Tree;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeParserI;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.forester.io.parsers.PhylogenyParser;
+import org.forester.io.parsers.nexus.NexusPhylogeniesParser;
+import org.forester.io.parsers.phyloxml.PhyloXmlParser;
+import org.forester.io.parsers.util.PhylogenyParserException;
+import org.forester.phylogeny.Phylogeny;
+
+public class ForesterParser
+        implements TreeParserI
+{
+  private final PhylogenyParser parser;
+
+  private TreeI[] parsedTrees;
+
+  protected ForesterParser(PhylogenyParser foresterParser, File file)
+          throws PhylogenyParserException, IOException
+  {
+    parser = foresterParser;
+    parser.setSource(file);
+  }
+
+  public static ForesterParser createNexusParser(File file)
+          throws PhylogenyParserException, IOException
+  {
+    NexusPhylogeniesParser nxParser = new NexusPhylogeniesParser();
+    nxParser.setReplaceUnderscores(
+            AptxInit.APTX_CONFIG.isReplaceUnderscoresInNhParsing());
+    nxParser.setIgnoreQuotes(false);
+    return new ForesterParser(nxParser, file);
+  }
+
+  public static ForesterParser createPhyloXmlParser(File file)
+          throws PhylogenyParserException, IOException
+  {
+    if (AptxInit.APTX_CONFIG.isValidatePhyloXmlAgainstSchema())
+    {
+    return new ForesterParser(
+              PhyloXmlParser.createPhyloXmlParserXsdValidating(), file);
+    }
+    else
+    {
+      return new ForesterParser(PhyloXmlParser.createPhyloXmlParser(),
+              file);
+    }
+  }
+
+  // ParserBasedPhylogenyFactory.getInstance().create(foresterParser, source)
+  @Override
+  public TreeI[] parse() throws IOException
+  {
+    Phylogeny[] foresterTrees = parser.parse();
+    parsedTrees = new TreeI[foresterTrees.length];
+
+    for (int i = 0; i < foresterTrees.length; i++)
+    {
+      parsedTrees[i] = new Tree(foresterTrees[i]);
+    }
+    return parsedTrees;
+
+  }
+
+  @Override
+  public void setSource(Object source) throws IOException
+  {
+    parser.setSource(source);
+
+  }
+
+  @Override
+  public String getName()
+  {
+    return parser.getName();
+  }
+
+
+  @Override
+  public TreeI[] getParsedTrees()
+  {
+    return parsedTrees;
+  }
+}
\ No newline at end of file
diff --git a/src/jalview/ext/forester/io/NexusFile.java b/src/jalview/ext/forester/io/NexusFile.java
new file mode 100644 (file)
index 0000000..7050f27
--- /dev/null
@@ -0,0 +1,47 @@
+package jalview.ext.forester.io;
+
+import jalview.datamodel.SequenceI;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeParserI;
+import jalview.io.AlignFile;
+import jalview.io.FileParse;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+public class NexusFile extends AlignFile
+{
+
+  public NexusFile(FileParse source) throws IOException
+  {
+    super(source);
+  }
+
+  @Override
+  public String print(SequenceI[] seqs, boolean jvsuffix)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /**
+   * This does not properly work for Nexus yet as Forester's parser doesn't
+   * parse the actual sequences to the tree.
+   */
+  @Override
+  public void parse() throws IOException
+  {
+    TreeParserI parser = ForesterParser
+            .createNexusParser(new File(getDataName()));
+    TreeI[] trees = parser.parse();
+    List<SequenceI> treeSeqs = trees[0].getNodeSequences();
+    for (SequenceI seq : treeSeqs)
+    {
+        seqs.add(seq);
+      }
+    }
+
+  }
+
+
diff --git a/src/jalview/ext/forester/io/PhyloXmlFile.java b/src/jalview/ext/forester/io/PhyloXmlFile.java
new file mode 100644 (file)
index 0000000..3cb3223
--- /dev/null
@@ -0,0 +1,42 @@
+package jalview.ext.forester.io;
+
+import jalview.datamodel.SequenceI;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeParserI;
+import jalview.io.AlignFile;
+import jalview.io.FileParse;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+public class PhyloXmlFile extends AlignFile
+{
+
+  public PhyloXmlFile(FileParse source) throws IOException
+  {
+    super(source);
+  }
+
+  @Override
+  public String print(SequenceI[] seqs, boolean jvsuffix)
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public void parse() throws IOException
+  {
+    TreeParserI parser = ForesterParser
+            .createPhyloXmlParser(new File(getDataName()));
+    TreeI[] trees = parser.parse();
+    List<SequenceI> treeSeqs = trees[0].getNodeSequences();
+    for (SequenceI seq : treeSeqs)
+      {
+        seqs.add(seq);
+      }
+
+  }
+
+}
diff --git a/src/jalview/ext/forester/io/SupportedTreeFileFilter.java b/src/jalview/ext/forester/io/SupportedTreeFileFilter.java
new file mode 100644 (file)
index 0000000..b077485
--- /dev/null
@@ -0,0 +1,37 @@
+package jalview.ext.forester.io;
+
+
+import javax.swing.filechooser.FileFilter;
+
+import org.forester.archaeopteryx.MainFrame;
+
+
+public enum SupportedTreeFileFilter
+{
+  NHFILTER(MainFrame.nhfilter), NHXFILTER(MainFrame.nhxfilter),
+  XMLFILTER(MainFrame.xmlfilter), TOLFILTER(MainFrame.tolfilter),
+  NEXUSFILTER(MainFrame.nexusfilter),
+  DEFAULTFILTER(MainFrame.defaultfilter);
+
+  private final FileFilter treeFilter;
+
+  SupportedTreeFileFilter(final FileFilter treeFilter)
+  {
+    this.treeFilter = treeFilter;
+
+  }
+
+  public void printSupportedFormats()
+  {
+    for (SupportedTreeFileFilter format : SupportedTreeFileFilter.values())
+    {
+      System.out.println(format.getTreeFilter().getDescription());
+    }
+  }
+
+  public FileFilter getTreeFilter()
+  {
+    return treeFilter;
+  }
+
+}
diff --git a/src/jalview/ext/forester/io/TreeDatabaseMenuBuilder.java b/src/jalview/ext/forester/io/TreeDatabaseMenuBuilder.java
new file mode 100644 (file)
index 0000000..3d11c8d
--- /dev/null
@@ -0,0 +1,48 @@
+package jalview.ext.forester.io;
+
+import java.util.List;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;
+import org.forester.archaeopteryx.webservices.WebservicesManager;
+
+public class TreeDatabaseMenuBuilder
+{
+  final WebservicesManager webservicesManager;
+
+
+  public TreeDatabaseMenuBuilder()
+
+  {
+    webservicesManager = WebservicesManager
+            .getInstance();
+
+  }
+
+  public JMenu createDbMenu()
+  {
+    JMenu treeDbMenu = new JMenu();
+    JMenuItem[] treeDatabaseMenuItems = new JMenuItem[webservicesManager
+                                          .getAvailablePhylogeniesWebserviceClients().size()];
+    
+    for (int i = 0; i < treeDatabaseMenuItems.length; ++i)
+    {
+      final PhylogeniesWebserviceClient client = webservicesManager
+              .getAvailablePhylogeniesWebserviceClient(i);
+      treeDatabaseMenuItems[i] = new JMenuItem(
+              client.getMenuName());
+      treeDbMenu.add(treeDatabaseMenuItems[i]);
+
+    }
+    return treeDbMenu;
+    
+  }
+
+  public List<PhylogeniesWebserviceClient> getTreeDatabases()
+  {
+    return webservicesManager.getAvailablePhylogeniesWebserviceClients();
+  }
+
+}
diff --git a/src/jalview/ext/forester/io/UtilityMethods.java b/src/jalview/ext/forester/io/UtilityMethods.java
new file mode 100644 (file)
index 0000000..3d7be38
--- /dev/null
@@ -0,0 +1,25 @@
+package jalview.ext.forester.io;
+
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.util.MessageManager;
+
+import java.io.File;
+
+import org.forester.util.ForesterUtil;
+
+public class UtilityMethods
+{
+  public static boolean canForesterReadFile(File treeFile)
+  {
+    final String err = ForesterUtil.isReadableFile(treeFile);
+    if (!ForesterUtil.isEmpty(err))
+    {
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, err,
+              MessageManager.getString("label.problem_reading_tree_file"),
+              JvOptionPane.WARNING_MESSAGE);
+      return false;
+    }
+    return true;
+  }
+}
index 00446f2..fd772ef 100644 (file)
@@ -76,9 +76,9 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private static final String ALPHACARBON = "CA";
 
-  private List<String> chainNames = new ArrayList<String>();
+  private List<String> chainNames = new ArrayList<>();
 
-  private Hashtable<String, String> chainFile = new Hashtable<String, String>();
+  private Hashtable<String, String> chainFile = new Hashtable<>();
 
   /*
    * Object through which we talk to Chimera
@@ -106,7 +106,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   /*
    * Map of ChimeraModel objects keyed by PDB full local file name
    */
-  private Map<String, List<ChimeraModel>> chimeraMaps = new LinkedHashMap<String, List<ChimeraModel>>();
+  private Map<String, List<ChimeraModel>> chimeraMaps = new LinkedHashMap<>();
 
   String lastHighlightCommand;
 
@@ -133,7 +133,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     String file = pe.getFile();
     try
     {
-      List<ChimeraModel> modelsToMap = new ArrayList<ChimeraModel>();
+      List<ChimeraModel> modelsToMap = new ArrayList<>();
       List<ChimeraModel> oldList = viewer.getModelList();
       boolean alreadyOpen = false;
 
@@ -226,7 +226,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
           // exit thread if Chimera Viewer is closed in Jalview
         }
       }
-    });
+    }, "ChimeraMonitor");
     chimeraMonitor.start();
   }
 
@@ -857,7 +857,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   protected List<AtomSpec> convertStructureResiduesToAlignment(
           List<String> structureSelection)
   {
-    List<AtomSpec> atomSpecs = new ArrayList<AtomSpec>();
+    List<AtomSpec> atomSpecs = new ArrayList<>();
     for (String atomSpec : structureSelection)
     {
       try
diff --git a/src/jalview/ext/treeviewer/LoadedTreeAssociationI.java b/src/jalview/ext/treeviewer/LoadedTreeAssociationI.java
new file mode 100644 (file)
index 0000000..19cf834
--- /dev/null
@@ -0,0 +1,22 @@
+package jalview.ext.treeviewer;
+
+import jalview.datamodel.SequenceI;
+
+import java.util.Map;
+
+/**
+ * Interface for associating the leaves of a loaded in (not calculated) tree to
+ * the alignment sequences in Jalview.
+ * 
+ * @author kjvanderheide
+ *
+ * 
+ */
+public interface LoadedTreeAssociationI
+{
+  public void associateLeavesToSequences();
+
+  public Map<SequenceI, TreeNodeI> getAlignmentWithNodes();
+
+  public Map<TreeNodeI, SequenceI> getNodesWithAlignment();
+}
diff --git a/src/jalview/ext/treeviewer/LoadedTreeSequenceAssociation.java b/src/jalview/ext/treeviewer/LoadedTreeSequenceAssociation.java
new file mode 100644 (file)
index 0000000..479e450
--- /dev/null
@@ -0,0 +1,115 @@
+package jalview.ext.treeviewer;
+
+import jalview.analysis.SequenceIdMatcher;
+import jalview.datamodel.SequenceI;
+import jalview.util.MappingUtils;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class LoadedTreeSequenceAssociation
+        implements LoadedTreeAssociationI
+{
+  SequenceI[] alignSequences;
+
+  TreeI tree;
+
+  Map<SequenceI, TreeNodeI> alignmentWithNodes;
+
+  Map<TreeNodeI, SequenceI> nodesWithAlignment;
+
+  public LoadedTreeSequenceAssociation(SequenceI[] alignmentSequences,
+          TreeI extTree)
+  {
+    alignSequences = alignmentSequences;
+    tree = extTree;
+    alignmentWithNodes = new HashMap<>(alignSequences.length);
+    nodesWithAlignment = new HashMap<>(alignSequences.length);
+
+  }
+
+  /**
+   * Tries to match sequences from Jalview with tree nodes in Archaeopteryx and
+   * fills in the tree node with sequence data if a match is found.
+   * 
+   * Partially refactored from the old Jalview TreeModel
+   * associateLeavesToSequences method.
+   *
+   * @param seqs
+   * @param aptxTree
+   */
+  @Override
+  public void associateLeavesToSequences()
+
+  {
+    SequenceIdMatcher algnIds = new SequenceIdMatcher(alignSequences);
+    SequenceI nodeSequence;
+    String nodeSequenceName;
+
+    if (!tree.isEmpty())
+    {
+      for (final Iterator<TreeNodeI> iter = tree
+              .iterateInPreOrder(); iter
+              .hasNext();)
+      {
+        TreeNodeI treeNode = iter.next();
+        nodeSequenceName = treeNode.getNodeName();
+
+        nodeSequence = algnIds.findIdMatch(nodeSequenceName);
+        if (nodeSequence != null)
+        {
+          // is there already a sequence present for the node?
+          // If so, does it actually match Jalview's sequence?
+          if (treeNode.getSequence() != null)
+          {
+            if (!(treeNode.getSequence().getSequenceAsString()
+                    .equals(nodeSequence.getSequenceAsString())))
+            {
+              System.err.println(
+                      "Sequence detected in tree node that does not match corresponding Jalview sequence:"
+                              + nodeSequenceName);
+              // which sequence gets precedence?
+
+            }
+
+          }
+          else
+          {
+          treeNode.setSequence(nodeSequence);
+          }
+          MappingUtils.putWithDuplicationCheck(alignmentWithNodes,
+                  nodeSequence, treeNode);
+          MappingUtils.putWithDuplicationCheck(nodesWithAlignment, treeNode,
+                  nodeSequence);
+
+
+        }
+
+    }
+
+    }
+  }
+
+
+
+  @Override
+  public Map<SequenceI, TreeNodeI> getAlignmentWithNodes()
+  {
+    return alignmentWithNodes;
+  }
+
+  @Override
+  public Map<TreeNodeI, SequenceI> getNodesWithAlignment()
+  {
+    return nodesWithAlignment;
+  }
+
+
+}
+
+
+
+
+
+
diff --git a/src/jalview/ext/treeviewer/TreeBuilderI.java b/src/jalview/ext/treeviewer/TreeBuilderI.java
new file mode 100644 (file)
index 0000000..37bad36
--- /dev/null
@@ -0,0 +1,23 @@
+package jalview.ext.treeviewer;
+
+import jalview.datamodel.SequenceI;
+
+import java.util.Map;
+
+/**
+ * @author kjvanderheide
+ *
+ */
+public interface TreeBuilderI
+{
+  public TreeI buildTree(TreeNodeI treeRoot);
+
+  public TreeI buildTree();
+
+  public Map<SequenceI, TreeNodeI> getAlignmentBoundNodes();
+
+  public Map<TreeNodeI, SequenceI> getNodesBoundAlignment();
+
+  public String generateTreeName();
+
+}
diff --git a/src/jalview/ext/treeviewer/TreeControlsI.java b/src/jalview/ext/treeviewer/TreeControlsI.java
new file mode 100644 (file)
index 0000000..9a209e7
--- /dev/null
@@ -0,0 +1,9 @@
+package jalview.ext.treeviewer;
+
+public interface TreeControlsI
+{
+  public void defaultSettings();
+
+  public void displayEntireTree();
+
+}
diff --git a/src/jalview/ext/treeviewer/TreeFrameI.java b/src/jalview/ext/treeviewer/TreeFrameI.java
new file mode 100644 (file)
index 0000000..fef927c
--- /dev/null
@@ -0,0 +1,52 @@
+package jalview.ext.treeviewer;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.MenuContainer;
+import java.awt.image.ImageObserver;
+
+import javax.accessibility.Accessible;
+import javax.swing.RootPaneContainer;
+import javax.swing.WindowConstants;
+import javax.swing.event.InternalFrameListener;
+
+public interface TreeFrameI
+        extends Accessible, WindowConstants, RootPaneContainer,
+        ImageObserver, MenuContainer
+{
+  public abstract TreePanelI getTreePanel();
+
+  public abstract TreeI getTree();
+
+  public abstract void checkMultipleTrees();
+
+  public abstract int getNumberOfTrees();
+
+  public TreeControlsI getTreeControls();
+
+  public void addFrameListener(InternalFrameListener listener);
+
+  public void removeFrameListener(InternalFrameListener listener);
+
+  public InternalFrameListener[] getFrameListeners();
+
+  public void repaint();
+
+  public boolean isShowing();
+
+  public Container getTopLevelAncestor();
+
+  public void addFrameToJalview(String title, boolean makeVisible,
+          int width, int height, boolean resizable, boolean ignoreMinSize);
+
+  public TreeViewerBindingI getViewBinding();
+
+  public void setViewBinding(TreeViewerBindingI alignmentBinding);
+
+  public void setMinimumSize(Dimension minimumSize);
+
+  public void setMaximumSize(Dimension maximumSize);
+
+  public void setPreferredSize(Dimension preferredSize);
+
+}
diff --git a/src/jalview/ext/treeviewer/TreeI.java b/src/jalview/ext/treeviewer/TreeI.java
new file mode 100644 (file)
index 0000000..702ff61
--- /dev/null
@@ -0,0 +1,48 @@
+package jalview.ext.treeviewer;
+
+import jalview.datamodel.SequenceI;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+public interface TreeI
+{
+  public TreeNodeI getRoot();
+
+  public TreeNodeI getNodeWithName(String name);
+
+  public TreeNodeI getFurthestNode();
+
+  public TreeNodeI[] getAllNodes();
+
+  public String[] getAllLeafNames();
+
+  public List<SequenceI> getNodeSequences();
+
+  public void setTreeName(String treeTitle);
+
+  public void setRerootable(boolean b);
+
+  public void setRooted(boolean b);
+
+  public boolean isEmpty();
+
+  public String getTreeName();
+
+  public void setRoot(TreeNodeI rootNode);
+
+  public double getHeight(boolean adjustForCollapsedSubtrees);
+
+  public Iterator<TreeNodeI> iterateInPreOrder();
+
+  public Iterator<TreeNodeI> iterateInLevelOrder();
+
+  public Iterator<TreeNodeI> iterateInPostOrder();
+
+  TreeFrameI createTreeViewerFromTree(String instanceTitle);
+
+  public void writeToXml(File outputFile) throws IOException;
+
+}
diff --git a/src/jalview/ext/treeviewer/TreeNodeI.java b/src/jalview/ext/treeviewer/TreeNodeI.java
new file mode 100644 (file)
index 0000000..89de82f
--- /dev/null
@@ -0,0 +1,35 @@
+package jalview.ext.treeviewer;
+
+import jalview.datamodel.SequenceI;
+
+import java.awt.Color;
+import java.util.List;
+
+public interface TreeNodeI
+{
+
+  public String getNodeName();
+
+  public List<TreeNodeI> getAllDescendants();
+
+  public List<TreeNodeI> getExternalDescendants();
+
+  public List<TreeNodeI> getDirectChildren();
+
+  public void setSequence(SequenceI seq);
+
+  public SequenceI getSequence();
+
+  public void addAsChild(TreeNodeI childNode);
+
+  public long getId();
+
+  public float getXcoord();
+
+  public float getYcoord();
+
+  public void setBranchColor(Color branchColor);
+
+  public boolean isInternal();
+
+}
diff --git a/src/jalview/ext/treeviewer/TreePanelI.java b/src/jalview/ext/treeviewer/TreePanelI.java
new file mode 100644 (file)
index 0000000..e0612d0
--- /dev/null
@@ -0,0 +1,63 @@
+package jalview.ext.treeviewer;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.MenuContainer;
+import java.awt.Rectangle;
+import java.awt.event.MouseListener;
+import java.io.File;
+import java.util.Set;
+
+import javax.accessibility.Accessible;
+
+public interface TreePanelI extends Accessible, MenuContainer
+{
+
+
+  public abstract void setTreeFile(File file);
+
+  public abstract File getTreeFile();
+
+  public abstract TreeI getTree();
+
+  public abstract TreeNodeI findNode(int x, int y);
+
+  public abstract void setMatchingNodes(Set<Long> matchingNodes);
+
+  public abstract Set<Long> getMatchingNodes();
+
+  public void addMouseListener(MouseListener listener);
+
+  public void removeMouseListener(MouseListener listener);
+
+  public MouseListener[] getMouseListeners();
+
+  public void repaint();
+
+  public void registerWithPaintRefresher(String sequenceSetIdentifier);
+
+  public void notifyPaintRefresher(boolean alignmentChanged,
+          boolean validateSequences);
+
+  public void notifyPaintRefresher(String newSeqSetIdentifier,
+          boolean alignmentChanged, boolean validateSequences);
+
+  public int getWidth();
+
+  public int getHeight();
+
+  public abstract void paintToFile(Graphics2D pg, int width, int height);
+
+  public boolean showingSubTree();
+
+  public float getPartitionThreshold();
+
+  public abstract Rectangle getVisibleArea();
+
+  public void setMinimumSize(Dimension minimumSize);
+
+  public void setMaximumSize(Dimension maximumSize);
+
+  public void setPreferredSize(Dimension preferredSize);
+
+}
diff --git a/src/jalview/ext/treeviewer/TreeParserI.java b/src/jalview/ext/treeviewer/TreeParserI.java
new file mode 100644 (file)
index 0000000..017d246
--- /dev/null
@@ -0,0 +1,15 @@
+package jalview.ext.treeviewer;
+
+import java.io.IOException;
+
+public interface TreeParserI
+ {
+  public TreeI[] parse() throws IOException;
+
+  public void setSource(Object source) throws IOException;
+
+  public String getName();
+
+  public TreeI[] getParsedTrees();
+
+ }
diff --git a/src/jalview/ext/treeviewer/TreeViewerBindingI.java b/src/jalview/ext/treeviewer/TreeViewerBindingI.java
new file mode 100644 (file)
index 0000000..da999c6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.treeviewer;
+
+import jalview.commands.CommandI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignmentPanel;
+import jalview.structure.SelectionListener;
+import jalview.structure.SelectionSource;
+
+import java.awt.event.ActionListener;
+import java.awt.event.MouseListener;
+
+/**
+ * 
+ * Interface for binding a tree viewer to Jalview alignments. Assumes a tree
+ * viewer will both want to receive and send selection events.
+ * 
+ * @author kjvanderheide
+ *
+ * 
+ */
+public interface TreeViewerBindingI
+        extends ActionListener, MouseListener, SelectionListener,
+        SelectionSource
+{
+  /**
+   * If a node is selected in the tree panel this method highlights the
+   * corresponding sequence in the Jalview alignment view. If an internal node
+   * is selected all child sequences get highlighted as well.
+   */
+  public void showNodeSelectionOnAlign(TreeNodeI node);
+
+  public void treeSelectionChanged(SequenceI sequence);
+
+  public void showMatchingSequence(TreeNodeI nodeToMatch);
+
+  public void showMatchingChildSequences(TreeNodeI parentNode);
+
+  public void sortByTree_actionPerformed();
+
+  public CommandI sortAlignmentIn(AlignmentPanel alignPanel);
+
+}
diff --git a/src/jalview/ext/treeviewer/TreeViewerConfigI.java b/src/jalview/ext/treeviewer/TreeViewerConfigI.java
new file mode 100644 (file)
index 0000000..29e4895
--- /dev/null
@@ -0,0 +1,6 @@
+package jalview.ext.treeviewer;
+
+public interface TreeViewerConfigI
+{
+
+}
diff --git a/src/jalview/ext/treeviewer/TreeViewerUtils.java b/src/jalview/ext/treeviewer/TreeViewerUtils.java
new file mode 100644 (file)
index 0000000..9531cf1
--- /dev/null
@@ -0,0 +1,63 @@
+package jalview.ext.treeviewer;
+
+import jalview.datamodel.SequenceI;
+import jalview.ext.archaeopteryx.JalviewBinding;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.awt.Dimension;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+public final class TreeViewerUtils
+{
+  private static Map<TreeFrameI, TreeViewerBindingI> activeViews = new HashMap<>();
+
+  public static TreeViewerBindingI associateNodesWithJalviewSequences(
+          final TreeFrameI treeFrame,
+          final AlignmentViewport jalviewAlignViewport,
+          final Map<SequenceI, TreeNodeI> alignMappedToNodes,
+          final Map<TreeNodeI, SequenceI> nodesMappedToAlign)
+  {
+    TreeViewerBindingI treeBinding = new JalviewBinding(treeFrame,
+            jalviewAlignViewport,
+            alignMappedToNodes, nodesMappedToAlign);
+    jalviewAlignViewport.setCurrentExtTree(treeFrame.getTree());
+    activeViews.put(treeFrame, treeFrame.getViewBinding());
+
+    return treeBinding;
+  }
+
+  public static TreeFrameI addTreeViewFrameToJalview(
+          final TreeFrameI treeFrame)
+  {
+    int width = 400;
+    int height = 550;
+    treeFrame.setMinimumSize(new Dimension(width, height));
+    // aptxApp.setFont(Desktop.instance.getFont());
+    // aptxApp.getMainPanel().setFont(Desktop.instance.getFont());
+    String frameTitle = MessageManager.getString("label.aptx_title");
+    File treeFile = treeFrame.getTreePanel().getTreeFile();
+    if (treeFile != null)
+    {
+      frameTitle += MessageManager.formatMessage("label.aptx_title_append",
+              new String[]
+              { treeFile.getAbsolutePath() });
+    }
+    // Usually redundant as this is done when associating nodes as well but that
+    // step could be bypassed
+    activeViews.put(treeFrame, treeFrame.getViewBinding());
+
+    treeFrame.addFrameToJalview(frameTitle, true, width, height, true,
+            false);
+    return treeFrame;
+  
+  }
+
+  public static Map<TreeFrameI, TreeViewerBindingI> getActiveTreeViews()
+  {
+    return activeViews;
+  }
+
+}
index 86710e1..0d0cce6 100644 (file)
@@ -901,7 +901,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
   public void transferToSequenceFetcher(String ids)
   {
     seqFetcher.getTextArea().setText(ids);
-    Thread worker = new Thread(seqFetcher);
+    Thread worker = new Thread(seqFetcher, "GFTSSeqFetcher");
     worker.start();
   }
 
index 053d91b..adb910b 100644 (file)
@@ -39,7 +39,7 @@ public class PDBFTSPanel extends GFTSPanel
   private static String defaultFTSFrameTitle = MessageManager
           .getString("label.pdb_sequence_fetcher");
 
-  private static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
+  private static Map<String, Integer> tempUserPrefs = new HashMap<>();
 
   private static final String PDB_FTS_CACHE_KEY = "CACHE.PDB_FTS";
 
@@ -190,7 +190,7 @@ public class PDBFTSPanel extends GFTSPanel
     // mainFrame.dispose();
     disableActionButtons();
     StringBuilder selectedIds = new StringBuilder();
-    HashSet<String> selectedIdsSet = new HashSet<String>();
+    HashSet<String> selectedIdsSet = new HashSet<>();
     int primaryKeyColIndex = 0;
     try
     {
@@ -222,7 +222,7 @@ public class PDBFTSPanel extends GFTSPanel
     String ids = selectedIds.toString();
     // System.out.println(">>>>>>>>>>>>>>>> selected Ids: " + ids);
     seqFetcher.getTextArea().setText(ids);
-    Thread worker = new Thread(seqFetcher);
+    Thread worker = new Thread(seqFetcher, "PDBFTSSeqFetcher");
     worker.start();
     delayAndEnableActionButtons();
   }
index 298688b..7029289 100644 (file)
@@ -26,6 +26,7 @@ import jalview.analysis.CrossRef;
 import jalview.analysis.Dna;
 import jalview.analysis.ParseProperties;
 import jalview.analysis.SequenceIdMatcher;
+import jalview.analysis.TreeModel;
 import jalview.api.AlignExportSettingI;
 import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
@@ -34,7 +35,6 @@ import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureSettingsControllerI;
 import jalview.api.SplitContainerI;
 import jalview.api.ViewStyleI;
-import jalview.api.analysis.SimilarityParamsI;
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.commands.CommandI;
@@ -53,6 +53,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.PDBEntry;
@@ -60,6 +61,11 @@ import jalview.datamodel.SeqCigar;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.ext.archaeopteryx.AptxInit;
+import jalview.ext.forester.io.SupportedTreeFileFilter;
+import jalview.ext.treeviewer.TreeFrameI;
+import jalview.ext.treeviewer.TreeViewerBindingI;
+import jalview.ext.treeviewer.TreeViewerUtils;
 import jalview.gui.ColourMenuHelper.ColourChangeListener;
 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
 import jalview.io.AlignmentProperties;
@@ -86,6 +92,7 @@ import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemes;
 import jalview.schemes.ResidueColourScheme;
 import jalview.schemes.TCoffeeColourScheme;
+import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.ViewportRanges;
@@ -98,6 +105,8 @@ import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.awt.BorderLayout;
 import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridLayout;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
 import java.awt.datatransfer.Clipboard;
@@ -123,6 +132,7 @@ import java.awt.print.PrinterJob;
 import java.beans.PropertyChangeEvent;
 import java.io.File;
 import java.io.FileWriter;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.URL;
 import java.util.ArrayList;
@@ -131,17 +141,26 @@ import java.util.Deque;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.StringTokenizer;
 import java.util.Vector;
 
 import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComboBox;
 import javax.swing.JEditorPane;
 import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
 import javax.swing.JLayeredPane;
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
+import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.SwingUtilities;
 
+import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;
+import org.forester.archaeopteryx.webservices.WebservicesManager;
+
 /**
  * DOCUMENT ME!
  * 
@@ -1501,7 +1520,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   /**
    * DOCUMENT ME!
    */
-  void updateEditMenuBar()
+  public void updateEditMenuBar()
   {
 
     if (viewport.getHistoryList().size() > 0)
@@ -3555,15 +3574,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   /**
    * Constructs a tree panel and adds it to the desktop
    * 
-   * @param type
-   *          tree type (NJ or AV)
-   * @param modelName
-   *          name of score model used to compute the tree
-   * @param options
-   *          parameters for the distance or similarity calculation
+   * @param params
+   * @param treeAlgo
+   * 
+   * @param tree
+   * 
+   * 
    */
-  void newTreePanel(String type, String modelName,
-          SimilarityParamsI options)
+  void newTreePanel(TreeModel tree, String treeAlgo,
+          String substitutionMatrix)
   {
     String frameTitle = "";
     TreePanel tp;
@@ -3575,7 +3594,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       SequenceGroup sg = viewport.getSelectionGroup();
 
       /* Decide if the selection is a column region */
-      for (SequenceI _s : sg.getSequences())
+      for (SequenceI _s : sg.getSequences()) // port this to Archaeopteryx?
       {
         if (_s.getLength() < sg.getEndRes())
         {
@@ -3599,7 +3618,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       }
     }
 
-    tp = new TreePanel(alignPanel, type, modelName, options);
+    tp = new TreePanel(alignPanel, tree, treeAlgo, substitutionMatrix);
     frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
 
     frameTitle += " from ";
@@ -3729,6 +3748,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
   }
 
+
   /**
    * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
    * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
@@ -3744,15 +3764,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     List<Component> comps = PaintRefresher.components
             .get(viewport.getSequenceSetId());
     List<TreePanel> treePanels = new ArrayList<>();
+
+    Map<TreeFrameI, TreeViewerBindingI> aptxFrames = TreeViewerUtils
+            .getActiveTreeViews();
+
     for (Component comp : comps)
     {
+      // old treepanels
       if (comp instanceof TreePanel)
       {
         treePanels.add((TreePanel) comp);
       }
+
     }
 
-    if (treePanels.size() < 1)
+    if (treePanels.isEmpty() && aptxFrames.isEmpty())
     {
       sortByTreeMenu.setVisible(false);
       return;
@@ -3760,6 +3786,42 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     sortByTreeMenu.setVisible(true);
 
+    for (Entry<TreeFrameI, TreeViewerBindingI> aptxFrameWithBinding : aptxFrames
+            .entrySet())
+    {
+      TreeFrameI aptxFrame = aptxFrameWithBinding.getKey();
+      TreeViewerBindingI binding = aptxFrameWithBinding.getValue();
+
+      // future support for multiple tabs
+      // for (org.forester.archaeopteryx.TreePanel aptxTree : aptxFrame
+      // .getMainPanel().getTreePanels())
+      {
+        final JMenuItem item = new JMenuItem(
+                aptxFrame.getTree().getTreeName());
+
+          item.addActionListener(new ActionListener()
+          {
+
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+            binding.sortByTree_actionPerformed(); // redundant here??
+            addHistoryItem(binding.sortAlignmentIn(alignPanel));
+            }
+
+          });
+        sortByTreeMenu.add(item);
+      }
+
+
+
+      }
+       
+
+           
+
+
+    // old treepanels
     for (final TreePanel tp : treePanels)
     {
       final JMenuItem item = new JMenuItem(tp.getTitle());
@@ -3877,14 +3939,81 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
   {
+    chooseTreeFile();
+  }
+
+  @Override
+  protected void loadTreeUrlItem_actionPerformed(ActionEvent e)
+  {
+    chooseTreeUrl();
+  }
+
+  @Override
+  protected void loadTreeBaseStudy_actionPerformed(ActionEvent e)
+  {
+    chooseTreeDb(0, null);
+
+  }
+
+  @Override
+  protected void loadTreeBase_actionPerformed(ActionEvent e)
+  {
+    chooseTreeDb(1, null);
+
+  }
+  @Override
+  protected void loadTreePfam_actionPerformed(ActionEvent e)
+  {
+
+    // only DBRefs of first sequence are checked for matching DB for now,
+    // iterating through them all seems excessive
+    SequenceI seq = viewport.getAlignment().getSequenceAt(0);
+    String dbId = null;
+    for (DBRefEntry pfamRef : DBRefUtils
+            .searchRefsForSource(seq.getDBRefs(), "pfam"))
+    {
+      if (pfamRef.getAccessionId().startsWith("PF"))
+      {
+        dbId = pfamRef.getAccessionId().replaceAll("[A-Za-z]", "");
+      }
+
+    }
+    chooseTreeDb(2, dbId);
+
+  }
+  @Override
+  protected void loadTreeFam_actionPerformed(ActionEvent e)
+  {
+    chooseTreeDb(3, null);
+
+  }
+
+  @Override
+  protected void loadTreeOfLife_actionPerformed(ActionEvent e)
+  {
+    chooseTreeDb(4, null);
+
+  }
+
+
+
+
+
+  public void chooseTreeFile()
+  {
     // Pick the tree file
     JalviewFileChooser chooser = new JalviewFileChooser(
             jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(
-            MessageManager.getString("label.select_newick_like_tree_file"));
+            MessageManager.getString("label.select_tree_file")); // modify
     chooser.setToolTipText(
-            MessageManager.getString("label.load_tree_file"));
+            MessageManager.getString("label.load_tree_for_sequence_set"));
+    for (SupportedTreeFileFilter treeFormat : SupportedTreeFileFilter
+            .values())
+    {
+      chooser.setFileFilter(treeFormat.getTreeFilter());
+    }
 
     int value = chooser.showOpenDialog(null);
 
@@ -3892,27 +4021,115 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       String filePath = chooser.getSelectedFile().getPath();
       Cache.setProperty("LAST_DIRECTORY", filePath);
-      NewickFile fin = null;
+      
+      
+      NewickFile fin = null; // old tree
       try
       {
-        fin = new NewickFile(filePath, DataSourceType.FILE);
-        viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
+        AptxInit.createInstancesFromFile(filePath, viewport);
+
+        // fin = new NewickFile(filePath, DataSourceType.FILE);
+        // viewport.setCurrentTree(viewport.getAlignPanel().alignFrame
+        // .showNewickTree(fin, filePath).getTree());
+
       } catch (Exception ex)
       {
-        JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
+        JvOptionPane.showMessageDialog(this, ex.getMessage(),
                 MessageManager.getString("label.problem_reading_tree_file"),
                 JvOptionPane.WARNING_MESSAGE);
         ex.printStackTrace();
       }
-      if (fin != null && fin.hasWarningMessage())
+
+    }
+  }
+
+  /**
+   * Break up and move to TreeParser?
+   */
+  public void chooseTreeUrl()
+  {
+
+    JLabel label = new JLabel(
+            MessageManager.getString("label.tree_url_example"));
+    // add "example" button
+    final JComboBox<String> history = new JComboBox<>();
+
+    JPanel panel = new JPanel(new GridLayout(2, 1));
+    panel.add(label);
+    panel.add(history);
+    history.setPreferredSize(new Dimension(400, 20));
+    history.setEditable(true);
+    history.addItem("http://www.");
+
+    String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
+
+    StringTokenizer st;
+
+    if (historyItems != null)
       {
-        JvOptionPane.showMessageDialog(Desktop.desktop,
-                fin.getWarningMessage(),
-                MessageManager
-                        .getString("label.possible_problem_with_tree_file"),
-                JvOptionPane.WARNING_MESSAGE);
+      st = new StringTokenizer(historyItems, "\t");
+
+      while (st.hasMoreTokens())
+      {
+        history.addItem(st.nextToken());
+      }
+      }
+
+    int reply = JvOptionPane.showInternalConfirmDialog(this, panel,
+            MessageManager.getString("label.load_tree_url"),
+            JvOptionPane.OK_CANCEL_OPTION);
+
+    if (reply == JvOptionPane.OK_OPTION)
+    {
+
+      String urlString = history.getSelectedItem().toString();
+      URL treeUrl;
+
+      try
+      {
+        FileFormatI format = null;
+
+        format = new IdentifyFile().identify(urlString, DataSourceType.URL);
+        // add actual use for the format identification (jalview .jar files)
+        treeUrl = new URL(urlString);
+        AptxInit.createInstancesFromUrl(treeUrl, viewport);
+
+      } catch (IOException | RuntimeException e)
+      {
+        JvOptionPane.showMessageDialog(this, MessageManager.formatMessage(
+                "exception.failed_to_read_data_from_source", new String[]
+                { urlString }),
+                MessageManager.getString("label.url_not_found"),
+                JvOptionPane.ERROR_MESSAGE);
+        e.printStackTrace();
       }
     }
+    else
+    {
+
+    }
+  }
+
+  /**
+   * Disgustingly hardcoded atm.
+   * 
+   * @param databaseIndex
+   */
+  public void chooseTreeDb(int databaseIndex, String defaultIdentifier)
+  {
+    final WebservicesManager webservices_manager = WebservicesManager
+            .getInstance();
+    final PhylogeniesWebserviceClient client = webservices_manager
+            .getAvailablePhylogeniesWebserviceClient(databaseIndex);
+    String identifier = JvOptionPane
+            .showInternalInputDialog(Desktop.desktop,
+                    client.getInstructions() + "\n(Reference: "
+                            + client.getReference() + ")",
+                    client.getDescription(), JvOptionPane.QUESTION_MESSAGE,
+                    null, null, defaultIdentifier)
+            .toString();
+
+    AptxInit.createInstancesFromDb(client, identifier, viewport);
   }
 
   public TreePanel showNewickTree(NewickFile nf, String treeTitle)
@@ -3978,6 +4195,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
   private boolean buildingMenu = false;
 
+  public void BuildTreeDbMenu()
+  {
+
+  }
   /**
    * Generates menu items and listener event actions for web service clients
    * 
@@ -4030,6 +4251,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
           final JMenu analymenu = new JMenu("Analysis");
           final JMenu dismenu = new JMenu("Protein Disorder");
+          final JMenu phylogenmenu = new JMenu("Phylogenetic inference");
+
           // JAL-940 - only show secondary structure prediction services from
           // the legacy server
           if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
@@ -4070,6 +4293,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           wsmenu.add(secstrmenu);
           wsmenu.add(dismenu);
           wsmenu.add(analymenu);
+          wsmenu.add(phylogenmenu);
           // No search services yet
           // wsmenu.add(seqsrchmenu);
 
@@ -4150,7 +4374,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         }
         buildingMenu = false;
       }
-    }).start();
+    }, "BuildWebService").start();
 
   }
 
@@ -4258,7 +4482,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
           final String source)
   {
-    new Thread(CrossRefAction.showProductsFor(sel, _odna, source, this))
+    new Thread(CrossRefAction.showProductsFor(sel, _odna, source, this),
+            "CrossReferences")
             .start();
   }
 
@@ -4537,7 +4762,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             ex.printStackTrace();
           }
         }
-      }).start();
+      }, "DropFile").start();
     }
   }
 
@@ -4908,7 +5133,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             });
             dbRefFetcher.fetchDBRefs(false);
           }
-        }).start();
+        }, "BuildFetchDBMenu").start();
 
       }
 
index 4d09084..c696765 100644 (file)
@@ -22,7 +22,6 @@ package jalview.gui;
 
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
-import jalview.analysis.TreeModel;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureColourI;
@@ -36,7 +35,6 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceGroup;
@@ -58,10 +56,8 @@ import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Rectangle;
-import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.Vector;
 
 import javax.swing.JInternalFrame;
 
@@ -545,7 +541,6 @@ public class AlignViewport extends AlignmentViewport
    * return the alignPanel containing the given viewport. Use this to get the
    * components currently handling the given viewport.
    * 
-   * @param av
    * @return null or an alignPanel guaranteed to have non-null alignFrame
    *         reference
    */
@@ -604,7 +599,7 @@ public class AlignViewport extends AlignmentViewport
     return validCharWidth;
   }
 
-  private Hashtable<String, AutoCalcSetting> calcIdParams = new Hashtable<String, AutoCalcSetting>();
+  private Hashtable<String, AutoCalcSetting> calcIdParams = new Hashtable<>();
 
   public AutoCalcSetting getCalcIdSettingsFor(String calcId)
   {
index fef7451..3dd9571 100644 (file)
@@ -218,7 +218,7 @@ public class AppJmol extends StructureViewerBase
     setSize(400, 400); // probably should be a configurable/dynamic default here
     initMenus();
     addingStructures = false;
-    worker = new Thread(this);
+    worker = new Thread(this, "OpenJmol");
     worker.start();
 
     this.addInternalFrameListener(new InternalFrameAdapter()
index e403dba..bae4986 100644 (file)
 package jalview.gui;
 
 import jalview.analysis.TreeBuilder;
+import jalview.analysis.TreeCalculator;
+import jalview.analysis.TreeModel;
 import jalview.analysis.scoremodels.ScoreModels;
 import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.SimilarityParamsI;
 import jalview.datamodel.SequenceGroup;
+import jalview.ext.archaeopteryx.AptxInit;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -43,6 +46,7 @@ import java.awt.event.FocusListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.beans.PropertyVetoException;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -103,7 +107,7 @@ public class CalculationChooser extends JPanel
 
   final ComboBoxTooltipRenderer renderer = new ComboBoxTooltipRenderer();
 
-  List<String> tips = new ArrayList<String>();
+  List<String> tips = new ArrayList<>();
 
   /*
    * the most recently opened PCA results panel
@@ -375,7 +379,7 @@ public class CalculationChooser extends JPanel
    */
   protected JComboBox<String> buildModelOptionsList()
   {
-    final JComboBox<String> scoreModelsCombo = new JComboBox<String>();
+    final JComboBox<String> scoreModelsCombo = new JComboBox<>();
     scoreModelsCombo.setRenderer(renderer);
 
     /*
@@ -418,7 +422,7 @@ public class CalculationChooser extends JPanel
   {
     Object curSel = comboBox.getSelectedItem();
     toolTips.clear();
-    DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
+    DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
 
     /*
      * now we can actually add entries to the combobox,
@@ -461,38 +465,73 @@ public class CalculationChooser extends JPanel
 
   /**
    * Open and calculate the selected tree or PCA on 'OK'
+   * 
+   * @throws IOException
    */
   protected void calculate_actionPerformed()
   {
     boolean doPCA = pca.isSelected();
-    String modelName = modelNames.getSelectedItem().toString();
+    String substitutionMatrix = modelNames.getSelectedItem().toString();
     SimilarityParamsI params = getSimilarityParameters(doPCA);
 
     if (doPCA)
     {
-      openPcaPanel(modelName, params);
+      openPcaPanel(substitutionMatrix, params);
     }
     else
     {
-      openTreePanel(modelName, params);
+      try
+      {
+        createTree(substitutionMatrix, params);
+      } catch (IOException e)
+      {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+
+
+
+
+
+
     }
 
     // closeFrame();
   }
 
-  /**
-   * Open a new Tree panel on the desktop
-   * 
-   * @param modelName
-   * @param params
-   */
-  protected void openTreePanel(String modelName, SimilarityParamsI params)
+  protected void createTree(String substitutionMatrix,
+          SimilarityParamsI params) throws IOException
+  {
+    String treeAlgo = determineTreeAlgo();
+    TreeCalculator treeCalculator = new TreeCalculator(treeAlgo,
+            substitutionMatrix, params);
+    TreeBuilder calculatedTree = treeCalculator.makeTree(af.getViewport());
+
+    // AptxInit.createInstanceFromCalculation(calculatedTree);
+
+    TreeModel tree = new TreeModel(calculatedTree);
+    jalview.io.NewickFile newick = new jalview.io.NewickFile(
+            tree.getTopNode());
+    String output = newick.print(tree.hasBootstrap(), tree.hasDistances(),
+            tree.hasRootDistance());
+    AptxInit.createInstanceFromNhx(af.getTitle(), output, 
+            af.getViewport());
+    // openTreePanel(tree, treeAlgo, substitutionMatrix);
+  }
+
+
+  protected String determineTreeAlgo() // to be modified & expanded
+  {
+    String treeAlgorithm = neighbourJoining.isSelected()
+            ? TreeBuilder.NEIGHBOUR_JOINING
+            : TreeBuilder.AVERAGE_DISTANCE;
+
+    return treeAlgorithm;
+
+  }
+
+  protected void checkEnoughSequences(AlignViewport viewport)
   {
-    /*
-     * gui validation shouldn't allow insufficient sequences here, but leave
-     * this check in in case this method gets exposed programmatically in future
-     */
-    AlignViewport viewport = af.getViewport();
     SequenceGroup sg = viewport.getSelectionGroup();
     if (sg != null && sg.getSize() < MIN_TREE_SELECTION)
     {
@@ -504,11 +543,25 @@ public class CalculationChooser extends JPanel
               JvOptionPane.WARNING_MESSAGE);
       return;
     }
+  }
 
-    String treeType = neighbourJoining.isSelected()
-            ? TreeBuilder.NEIGHBOUR_JOINING
-            : TreeBuilder.AVERAGE_DISTANCE;
-    af.newTreePanel(treeType, modelName, params);
+  /**
+   * Open a new Tree panel on the desktop
+   * 
+   * @param tree
+   * @param params
+   * @param treeAlgo
+   */
+  protected void openTreePanel(TreeModel tree, String treeAlgo,
+          String substitutionMatrix)
+  {
+    /*
+     * gui validation shouldn't allow insufficient sequences here, but leave
+     * this check in in case this method gets exposed programmatically in future
+     */
+    checkEnoughSequences(af.getViewport());
+
+    af.newTreePanel(tree, treeAlgo, substitutionMatrix);
   }
 
   /**
index 89de2e8..4b45459 100644 (file)
@@ -272,7 +272,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     initMenus();
 
     addingStructures = false;
-    worker = new Thread(this);
+    worker = new Thread(this, "OpenChimera");
     worker.start();
 
     this.addInternalFrameListener(new InternalFrameAdapter()
index 4c019a6..9d847a8 100644 (file)
@@ -138,15 +138,15 @@ public class Console extends WindowAdapter
 
     // Starting two seperate threads to read from the PipedInputStreams
     //
-    reader = new Thread(this);
+    reader = new Thread(this, "ConsoleReader1");
     reader.setDaemon(true);
     reader.start();
     //
-    reader2 = new Thread(this);
+    reader2 = new Thread(this, "ConsoleReader2");
     reader2.setDaemon(true);
     reader2.start();
     // and a thread to append text to the textarea
-    textAppender = new Thread(this);
+    textAppender = new Thread(this, "ConsoleTextAppend");
     textAppender.setDaemon(true);
     textAppender.start();
   }
@@ -255,7 +255,7 @@ public class Console extends WindowAdapter
     // We do it with a seperate Thread becasue we don't wan't to break a Thread
     // used by the Console.
     System.out.println("\nLets throw an error on this console");
-    errorThrower = new Thread(this);
+    errorThrower = new Thread(this, "ConsoleErrorLog");
     errorThrower.setDaemon(true);
     errorThrower.start();
   }
index 8570ac3..53204d4 100644 (file)
@@ -38,7 +38,6 @@ import java.util.Vector;
 
 import javax.swing.JCheckBox;
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
 import javax.swing.ListSelectionModel;
@@ -125,7 +124,7 @@ public class DasSourceBrowser extends GDasSourceBrowser
   {
     if (sourceRegistry == null)
     {
-      Thread worker = new Thread(this);
+      Thread worker = new Thread(this, "PaintDas");
       worker.start();
     }
   }
@@ -352,7 +351,7 @@ public class DasSourceBrowser extends GDasSourceBrowser
       }
     }
 
-    Vector<jalviewSourceI> selected = new Vector<jalviewSourceI>();
+    Vector<jalviewSourceI> selected = new Vector<>();
     for (String source : selectedSources)
     {
       jalviewSourceI srce = sourceRegistry.getSource(source);
@@ -369,16 +368,16 @@ public class DasSourceBrowser extends GDasSourceBrowser
   {
     saveProperties(jalview.bin.Cache.applicationProperties);
 
-    Thread worker = new Thread(this);
+    Thread worker = new Thread(this, "RepaintDas");
     worker.start();
   }
 
   private void setCapabilities(DasSourceRegistryI sourceRegistry2)
   {
-    Vector<String> authority = new Vector<String>();
-    Vector<String> type = new Vector<String>();
-    Vector<String> label = new Vector<String>();
-    Vector<String> taxIds = new Vector<String>();
+    Vector<String> authority = new Vector<>();
+    Vector<String> type = new Vector<>();
+    Vector<String> label = new Vector<>();
+    Vector<String> taxIds = new Vector<>();
     authority.add("Any");
     type.add("Any");
     label.add("Any");
index 128481c..6eea78d 100644 (file)
@@ -456,7 +456,7 @@ public class Desktop extends jalview.jbgui.GDesktop
                 fileFormat);
         Cache.log.debug("Filechooser init thread finished.");
       }
-    }).start();
+    }, "InitFileChooser").start();
     // Add the service change listener
     changeSupport.addJalviewPropertyChangeListener("services",
             new PropertyChangeListener()
@@ -575,7 +575,7 @@ public class Desktop extends jalview.jbgui.GDesktop
             Desktop.instance.setProgressBar(null, now);
             jvnews.showNews();
           }
-        }).start();
+        }, "ShowNewsWindow").start();
       }
     }
   }
@@ -1161,8 +1161,9 @@ public class Desktop extends jalview.jbgui.GDesktop
       if (format == null)
       {
         JvOptionPane.showInternalMessageDialog(Desktop.desktop,
-                MessageManager.formatMessage("label.couldnt_locate",
-                        new Object[]
+                MessageManager.formatMessage(
+                        "label.couldnt_locate",
+                        new String[]
                         { url }),
                 MessageManager.getString("label.url_not_found"),
                 JvOptionPane.WARNING_MESSAGE);
@@ -1271,7 +1272,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       {
         new SplashScreen(true);
       }
-    }).start();
+    }, "ShowAboutMenu").start();
   }
 
   public StringBuffer getAboutMessage(boolean shortv)
@@ -1613,7 +1614,7 @@ public class Desktop extends jalview.jbgui.GDesktop
           }
           setProgressBar(null, choice.hashCode());
         }
-      }).start();
+      }, "SaveJalviewProject").start();
     }
   }
 
@@ -1681,7 +1682,7 @@ public class Desktop extends jalview.jbgui.GDesktop
           }
           setProgressBar(null, choice.hashCode());
         }
-      }).start();
+      }, "LoadJalviewProject").start();
     }
   }
 
@@ -2191,7 +2192,7 @@ public class Desktop extends jalview.jbgui.GDesktop
                     dsktp.v_client.initial_update();
                   }
 
-                });
+                }, "VamsasSession");
                 rthr.start();
               }
             };
@@ -2311,7 +2312,7 @@ public class Desktop extends jalview.jbgui.GDesktop
   {
     UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
     // javax.swing.SwingUtilities.invokeLater(jvq);
-    new Thread(jvq).start();
+    new Thread(jvq, "CheckQuestionnaire").start();
   }
 
   public void checkURLLinks()
@@ -2424,7 +2425,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       this.showMemoryUsage = showMemory;
       if (showMemory)
       {
-        Thread worker = new Thread(this);
+        Thread worker = new Thread(this, "ShowMemoryUsage");
         worker.start();
       }
       repaint();
@@ -2849,7 +2850,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
       // JAL-940 - disabled JWS1 service configuration - always start discoverer
       // until we phase out completely
-      (t0 = new Thread(discoverer)).start();
+      (t0 = new Thread(discoverer, "Discoverer")).start();
     }
 
     if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
@@ -3005,7 +3006,7 @@ public class Desktop extends jalview.jbgui.GDesktop
           progress.setProgressBar(null, this.hashCode());
         }
       }
-    }).start();
+    }, "OpenURL").start();
   }
 
   public static WsParamSetManager wsparamManager = null;
index 4a15024..c0246c3 100644 (file)
@@ -37,10 +37,15 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.StructureViewerModel;
 import jalview.datamodel.StructureViewerModel.StructureData;
+import jalview.ext.archaeopteryx.AptxInit;
+import jalview.ext.treeviewer.TreeFrameI;
+import jalview.ext.treeviewer.TreeI;
+import jalview.ext.treeviewer.TreeViewerUtils;
 import jalview.ext.varna.RnaModel;
 import jalview.gui.StructureViewer.ViewerType;
 import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
+import jalview.io.NewickFile;
 import jalview.renderer.ResidueShaderI;
 import jalview.schemabinding.version2.AlcodMap;
 import jalview.schemabinding.version2.AlcodonFrame;
@@ -1095,10 +1100,36 @@ public class Jalview2XML
               jms.addTree(tree);
             }
           }
+
+        }
+      }
+    }
+    if (!storeDS && av.getCurrentExtTree() != null)
+    {
+      Set<TreeFrameI> externalTreeViews = TreeViewerUtils
+              .getActiveTreeViews()
+              .keySet();
+      for (TreeFrameI treeView : externalTreeViews)
+      {
+        TreeI tree = treeView.getTree();
+        try
+        {
+          tree.writeToXml(new File("word"));
+          copyFileToJar(jout, "word", "aptx-test");
+
+
+        } catch (IOException e)
+        {
+          // TODO Auto-generated catch block
+          e.printStackTrace();
         }
+
       }
+
     }
 
+
+
     // SAVE ANNOTATIONS
     /**
      * store forward refs from an annotationRow to any groups
@@ -1526,7 +1557,7 @@ public class Jalview2XML
 
                 String varnaStateFile = varna.getStateInfo(model.rna);
                 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
-                copyFileToJar(jout, varnaStateFile, jarEntryName);
+
                 rnaSessions.put(model, jarEntryName);
               }
               SecondaryStructure ss = new SecondaryStructure();
@@ -3532,12 +3563,33 @@ public class Jalview2XML
     if (loadTreesAndStructures)
     {
       loadTrees(jms, view, af, av, ap);
+      loadExternalTrees(jprovider, jms, av);
       loadPDBStructures(jprovider, jseqs, af, ap);
       loadRnaViewers(jprovider, jseqs, ap);
     }
     // and finally return.
     return af;
   }
+    
+  private void loadExternalTrees(jarInputStreamProvider jprovider,
+          JalviewModelSequence jms, AlignViewport av)
+  {
+    String treeFile = copyJarEntry(jprovider, "aptx-test", "aptx", null);
+    if (treeFile != null)
+    {
+    try
+    {
+      AptxInit.createInstancesFromFile(treeFile, av);
+    } catch (IOException e)
+    {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+      }
+    }
+    
+  }
+
+
 
   /**
    * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
@@ -3653,12 +3705,20 @@ public class Jalview2XML
       {
 
         Tree tree = jms.getTree(t);
+        NewickFile newick = new jalview.io.NewickFile(tree.getNewick());
+
+        TreeFrameI externalViewer = AptxInit.createInstanceFromNhx(
+                tree.getTitle(), tree.getNewick(),
+                av);
+
 
         TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
         if (tp == null)
         {
+
+
           tp = af.showNewickTree(
-                  new jalview.io.NewickFile(tree.getNewick()),
+                  newick,
                   tree.getTitle(), tree.getWidth(), tree.getHeight(),
                   tree.getXpos(), tree.getYpos());
           if (tree.getId() != null)
@@ -5333,7 +5393,7 @@ public class Jalview2XML
 
     if (this.frefedSequence == null)
     {
-      frefedSequence = new Vector<SeqFref>();
+      frefedSequence = new Vector<>();
     }
 
     viewportsAdded.clear();
index 05f5ffc..ccbe1ee 100644 (file)
@@ -66,7 +66,7 @@ public abstract class JalviewDialog extends JPanel
           frame.setVisible(true);
         }
 
-      }).start();
+      }, "UnblockedDialog").start();
     }
     else
     {
index 43b4310..0fbc04a 100755 (executable)
@@ -304,7 +304,7 @@ public class OverviewPanel extends JPanel
       return;
     }
 
-    Thread thread = new Thread(this);
+    Thread thread = new Thread(this, "UpdateOverview");
     thread.start();
     repaint();
 
index ced5544..06a2f65 100755 (executable)
@@ -39,7 +39,7 @@ import java.util.Map;
  */
 public class PaintRefresher
 {
-  static Map<String, List<Component>> components = new HashMap<String, List<Component>>();
+  static Map<String, List<Component>> components = new HashMap<>();
 
   /**
    * Add the given component to those registered under the given sequence set
@@ -60,7 +60,7 @@ public class PaintRefresher
     }
     else
     {
-      List<Component> vcoms = new ArrayList<Component>();
+      List<Component> vcoms = new ArrayList<>();
       vcoms.add(comp);
       components.put(seqSetId, vcoms);
     }
@@ -233,14 +233,14 @@ public class PaintRefresher
     }
   }
 
-  static AlignmentPanel[] getAssociatedPanels(String id)
+  public static AlignmentPanel[] getAssociatedPanels(String id)
   {
     List<Component> comps = components.get(id);
     if (comps == null)
     {
       return new AlignmentPanel[0];
     }
-    List<AlignmentPanel> tmp = new ArrayList<AlignmentPanel>();
+    List<AlignmentPanel> tmp = new ArrayList<>();
     for (Component comp : comps)
     {
       if (comp instanceof AlignmentPanel)
index 850a09a..21cc075 100644 (file)
@@ -885,7 +885,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
             showLink(url);
           }
 
-        }).start();
+        }, "ShowURLMenu").start();
       }
     });
 
@@ -931,7 +931,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
             }
           }
 
-        }).start();
+        }, "ShowGroupURLMenu").start();
       }
     });
 
index c4390c0..aa3d5b1 100755 (executable)
@@ -96,7 +96,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
     slider.setMaximum(100);
     slider.setValue(100);
 
-    Thread worker = new Thread(this);
+    Thread worker = new Thread(this, "CreateRedundancyPanel");
     worker.start();
 
     frame = new JInternalFrame();
index 22b697e..d74309b 100755 (executable)
@@ -80,12 +80,13 @@ public class SplashScreen extends JPanel
   {
     this.interactiveDialog = interactive;
     // show a splashscreen that will disapper
-    Thread t = new Thread(this);
+    Thread t = new Thread(this, "ShowSplashScreen");
     t.start();
   }
 
   MouseAdapter closer = new MouseAdapter()
   {
+    @Override
     public void mousePressed(MouseEvent evt)
     {
       try
@@ -196,6 +197,7 @@ public class SplashScreen extends JPanel
   /**
    * Create splash screen, display it and clear it off again.
    */
+  @Override
   public void run()
   {
     initSplashScreenWindow();
@@ -267,6 +269,7 @@ public class SplashScreen extends JPanel
       return new Dimension(image.getWidth(this) + 8, image.getHeight(this));
     }
 
+    @Override
     public void paintComponent(Graphics g)
     {
       g.setColor(Color.white);
index 31c20ed..c0769a0 100644 (file)
@@ -352,7 +352,7 @@ public abstract class StructureViewerBase extends GStructureViewer
             // and call ourselves again.
             addStructure(pdbentry, seqs, chains, align, alignFrame);
           }
-        }).start();
+        }, "Adding3DStructureQueue").start();
         return;
       }
     }
@@ -363,7 +363,7 @@ public abstract class StructureViewerBase extends GStructureViewer
     addingStructures = true;
     _started = false;
     alignAddedStructures = align;
-    worker = new Thread(this);
+    worker = new Thread(this, "Adding3DStructure");
     worker.start();
     return;
   }
index 7dc1a99..ec5d28f 100755 (executable)
@@ -542,7 +542,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
    */
   void startPrinting()
   {
-    Thread thread = new Thread(this);
+    Thread thread = new Thread(this, "PrintTreeCanvas");
     thread.start();
   }
 
@@ -981,7 +981,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
 
       Vector<SequenceNode> l = tree.findLeaves(groups.get(i));
 
-      Vector<SequenceI> sequences = new Vector<SequenceI>();
+      Vector<SequenceI> sequences = new Vector<>();
 
       for (int j = 0; j < l.size(); j++)
       {
index 2727db1..e8f78d8 100755 (executable)
 package jalview.gui;
 
 import jalview.analysis.AlignmentSorter;
-import jalview.analysis.AverageDistanceTree;
-import jalview.analysis.NJTree;
-import jalview.analysis.TreeBuilder;
 import jalview.analysis.TreeModel;
-import jalview.analysis.scoremodels.ScoreModels;
-import jalview.api.analysis.ScoreModelI;
-import jalview.api.analysis.SimilarityParamsI;
 import jalview.bin.Cache;
 import jalview.commands.CommandI;
 import jalview.commands.OrderCommand;
@@ -55,7 +49,6 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.image.BufferedImage;
 import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.io.FileOutputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -64,8 +57,6 @@ import javax.imageio.ImageIO;
 import javax.swing.ButtonGroup;
 import javax.swing.JMenuItem;
 import javax.swing.JRadioButtonMenuItem;
-import javax.swing.event.InternalFrameAdapter;
-import javax.swing.event.InternalFrameEvent;
 
 import org.jibble.epsgraphics.EpsGraphics2D;
 
@@ -77,14 +68,12 @@ import org.jibble.epsgraphics.EpsGraphics2D;
  */
 public class TreePanel extends GTreePanel
 {
-  String treeType;
+  String substitutionMatrix;
 
-  String scoreModelName; // if tree computed
+  String treeType;
 
   String treeTitle; // if tree loaded
 
-  SimilarityParamsI similarityParams;
-
   TreeCanvas treeCanvas;
 
   TreeModel tree;
@@ -95,28 +84,38 @@ public class TreePanel extends GTreePanel
    * Creates a new TreePanel object.
    * 
    * @param ap
-   * @param type
-   * @param modelName
-   * @param options
+   * @param tree
+   * @param treeType
+   * @param substitutionMatrix
    */
-  public TreePanel(AlignmentPanel ap, String type, String modelName,
-          SimilarityParamsI options)
+  public TreePanel(AlignmentPanel ap, TreeModel tree, String treeType,
+          String substitutionMatrix)
   {
     super();
-    this.similarityParams = options;
-    initTreePanel(ap, type, modelName, null, null);
+    this.treeType = treeType;
+    this.substitutionMatrix = substitutionMatrix;
+    this.tree = tree;
+    initTreePanel(ap, tree);
 
     // We know this tree has distances. JBPNote TODO: prolly should add this as
     // a userdefined default
     // showDistances(true);
   }
 
+  /**
+   * Creates a new TreePanel object.
+   * 
+   * @param alignPanel
+   * @param newtree
+   * @param theTitle
+   * @param inputData
+   */
   public TreePanel(AlignmentPanel alignPanel, NewickFile newtree,
           String theTitle, AlignmentView inputData)
   {
     super();
     this.treeTitle = theTitle;
-    initTreePanel(alignPanel, null, null, newtree, inputData);
+    initTreePanel(alignPanel, newtree, inputData);
   }
 
   public AlignmentI getAlignment()
@@ -129,50 +128,49 @@ public class TreePanel extends GTreePanel
     return treeCanvas.av;
   }
 
-  void initTreePanel(AlignmentPanel ap, String type, String modelName,
-          NewickFile newTree, AlignmentView inputData)
+  /**
+   * Initialize a tree panel based on a calculated tree
+   * 
+   * @param ap
+   * @param tree
+   */
+  void initTreePanel(AlignmentPanel ap, TreeModel tree)
   {
+    buildTreeCanvas(ap);
 
-    av = ap.av;
-    this.treeType = type;
-    this.scoreModelName = modelName;
+    TreeLoader tl = new TreeLoader(null, null);
+    tl.start();
 
-    treeCanvas = new TreeCanvas(this, ap, scrollPane);
-    scrollPane.setViewportView(treeCanvas);
+  }
 
-    PaintRefresher.Register(this, ap.av.getSequenceSetId());
+  /**
+   * Initialize a tree panel based on a loaded in tree file.
+   * 
+   * @param ap
+   * @param loadedTree
+   * @param inputData
+   */
+  void initTreePanel(AlignmentPanel ap, 
+          NewickFile loadedTree, AlignmentView inputData)
+  {
+    buildTreeCanvas(ap);
 
-    buildAssociatedViewMenu();
+    TreeLoader tl = new TreeLoader(loadedTree, inputData);
+    tl.start();
+  }
 
-    final PropertyChangeListener listener = addAlignmentListener();
+public void buildTreeCanvas(AlignmentPanel ap) { 
+     av = ap.av;
 
-    /*
-     * remove listener when window is closed, so that this
-     * panel can be garbage collected
-     */
-    addInternalFrameListener(new InternalFrameAdapter()
-    {
-      @Override
-      public void internalFrameClosed(InternalFrameEvent evt)
-      {
-        if (av != null)
-        {
-          av.removePropertyChangeListener(listener);
-        }
-      }
-    });
+    treeCanvas = new TreeCanvas(this, ap, scrollPane);
+    scrollPane.setViewportView(treeCanvas);
 
-    TreeLoader tl = new TreeLoader(newTree, inputData);
-    tl.start();
 
-  }
+    PaintRefresher.Register(this, ap.av.getSequenceSetId());
 
-  /**
-   * @return
-   */
-  protected PropertyChangeListener addAlignmentListener()
-  {
-    final PropertyChangeListener listener = new PropertyChangeListener()
+    buildAssociatedViewMenu();
+
+    av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
     {
       @Override
       public void propertyChange(PropertyChangeEvent evt)
@@ -199,9 +197,11 @@ public class TreePanel extends GTreePanel
           repaint();
         }
       }
-    };
-    av.addPropertyChangeListener(listener);
-    return listener;
+    });
+
+
+  
+
   }
 
   @Override
@@ -272,57 +272,59 @@ public class TreePanel extends GTreePanel
 
   class TreeLoader extends Thread
   {
-    private NewickFile newtree;
+    private NewickFile newTree;
 
     private AlignmentView odata = null;
 
     public TreeLoader(NewickFile newickFile, AlignmentView inputData)
     {
-      this.newtree = newickFile;
+      this.newTree = newickFile;
       this.odata = inputData;
 
-      if (newickFile != null)
+      if (newTree != null)
       {
         // Must be outside run(), as Jalview2XML tries to
         // update distance/bootstrap visibility at the same time
-        showBootstrap(newickFile.HasBootstrap());
-        showDistances(newickFile.HasDistances());
+        showBootstrap(newTree.hasBootstrap());
+        showDistances(newTree.hasDistances());
+
       }
+
     }
 
     @Override
     public void run()
     {
 
-      if (newtree != null)
+      if (newTree != null)
       {
         tree = new TreeModel(av.getAlignment().getSequencesArray(), odata,
-                newtree);
+                newTree);
         if (tree.getOriginalData() == null)
         {
           originalSeqData.setVisible(false);
         }
+
+
+
       }
-      else
-      {
-        ScoreModelI sm = ScoreModels.getInstance()
-                .getScoreModel(scoreModelName, treeCanvas.ap);
-        TreeBuilder njtree = treeType.equals(TreeBuilder.NEIGHBOUR_JOINING)
-                ? new NJTree(av, sm, similarityParams)
-                : new AverageDistanceTree(av, sm, similarityParams);
-        tree = new TreeModel(njtree);
-        showDistances(true);
-      }
+      showTree(tree);
 
+    }
+      
+    public void showTree(TreeModel tree)
+    {
       tree.reCount(tree.getTopNode());
       tree.findHeight(tree.getTopNode());
       treeCanvas.setTree(tree);
       treeCanvas.repaint();
+
       av.setCurrentTree(tree);
       if (av.getSortByTree())
       {
         sortByTree_actionPerformed();
       }
+
     }
   }
 
@@ -517,7 +519,7 @@ public class TreePanel extends GTreePanel
    * @param e
    */
   @Override
-  public void sortByTree_actionPerformed()
+  public void sortByTree_actionPerformed()// modify for Aptx
   {
 
     if (treeCanvas.applyToAllViews)
@@ -858,29 +860,31 @@ public class TreePanel extends GTreePanel
    * 
    * @return
    */
-  public String getPanelTitle()
+  public String getPanelTitle() // to be moved/fixed
   {
     if (treeTitle != null)
     {
       return treeTitle;
     }
-
-    /*
-     * i18n description of Neighbour Joining or Average Distance method
-     */
-    String treecalcnm = MessageManager
-            .getString("label.tree_calc_" + treeType.toLowerCase());
-
-    /*
-     * short score model name (long description can be too long)
-     */
-    String smn = scoreModelName;
-
-    /*
-     * put them together as <method> Using <model>
-     */
-    final String ttl = MessageManager.formatMessage("label.treecalc_title",
-            treecalcnm, smn);
-    return ttl;
+    else
+    {
+      /*
+       * i18n description of Neighbour Joining or Average Distance method
+       */
+      String treecalcnm = MessageManager
+              .getString("label.tree_calc_" + treeType.toLowerCase());
+
+      /*
+       * short score model name (long description can be too long)
+       */
+      String smn = substitutionMatrix;
+
+      /*
+       * put them together as <method> Using <model>
+       */
+      final String ttl = MessageManager
+              .formatMessage("label.treecalc_title", treecalcnm, smn);
+      return ttl;
+    }
   }
 }
diff --git a/src/jalview/gui/TreeParams.java b/src/jalview/gui/TreeParams.java
new file mode 100644 (file)
index 0000000..4f481d9
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($Version-Rel$)
+ * Copyright (C) $Year-Rel$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+/**
+ * @author kjvanderheide
+ *
+ */
+public class TreeParams implements OptsParametersContainerI
+{
+
+  @Override
+  public void refreshParamLayout()
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void argSetModified(Object modifiedElement, boolean b)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+}
index d2086e0..6003416 100644 (file)
@@ -326,7 +326,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
         Cache.log.info("Jalview finished updating to the Vamsas Session.");
       }
 
-    });
+    }, "UpdateVamsas");
     udthread.start();
   }
 
index 2fc08e1..a0191a5 100644 (file)
@@ -39,7 +39,6 @@ import java.util.Vector;
 import javax.swing.JComponent;
 import javax.swing.JEditorPane;
 import javax.swing.JInternalFrame;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JTabbedPane;
@@ -345,12 +344,13 @@ public class WebserviceInfo extends GWebserviceInfo
     AnimatedPanel ap = new AnimatedPanel();
     titlePanel.add(ap, BorderLayout.CENTER);
 
-    Thread thread = new Thread(ap);
+    Thread thread = new Thread(ap, "AnimatedPanel");
     thread.start();
     final WebserviceInfo thisinfo = this;
     frame.addInternalFrameListener(
             new javax.swing.event.InternalFrameAdapter()
             {
+              @Override
               public void internalFrameClosed(
                       javax.swing.event.InternalFrameEvent evt)
               {
@@ -676,6 +676,7 @@ public class WebserviceInfo extends GWebserviceInfo
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   protected void cancel_actionPerformed(ActionEvent e)
   {
     if (!serviceIsCancellable)
@@ -707,6 +708,7 @@ public class WebserviceInfo extends GWebserviceInfo
   {
     javax.swing.SwingUtilities.invokeLater(new Runnable()
     {
+      @Override
       public void run()
       {
         JvOptionPane.showInternalMessageDialog(Desktop.desktop, message,
@@ -756,6 +758,7 @@ public class WebserviceInfo extends GWebserviceInfo
 
     BufferedImage offscreen;
 
+    @Override
     public void run()
     {
       startTime = System.currentTimeMillis();
@@ -865,6 +868,7 @@ public class WebserviceInfo extends GWebserviceInfo
       }
     }
 
+    @Override
     public void paintComponent(Graphics g1)
     {
       drawPanel();
@@ -880,6 +884,7 @@ public class WebserviceInfo extends GWebserviceInfo
     renderAsHtml = b;
   }
 
+  @Override
   public void hyperlinkUpdate(HyperlinkEvent e)
   {
     Desktop.hyperlinkUpdate(e);
index 850ef21..2053091 100644 (file)
@@ -37,7 +37,6 @@ import java.util.List;
 import java.util.Vector;
 
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTable;
 import javax.swing.JTextField;
@@ -68,12 +67,12 @@ public class WsPreferences extends GWsPreferences
     wsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
     if (!wsUrls.isEmpty())
     {
-      oldUrls = new Vector<String>(wsUrls);
+      oldUrls = new Vector<>(wsUrls);
     }
     else
     {
       oldUrls = null;
-      wsUrls = new Vector<String>();
+      wsUrls = new Vector<>();
     }
     wsList.setDefaultRenderer(Integer.class, new JabaWSStatusRenderer());
     wsList.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
@@ -81,12 +80,12 @@ public class WsPreferences extends GWsPreferences
     rsbsUrls = jalview.ws.rest.RestClient.getRsbsDescriptions();
     if (rsbsUrls != null)
     {
-      oldRsbsUrls = new Vector<String>(rsbsUrls);
+      oldRsbsUrls = new Vector<>(rsbsUrls);
     }
     else
     {
       oldRsbsUrls = null;
-      rsbsUrls = new Vector<String>();
+      rsbsUrls = new Vector<>();
     }
     updateRsbsList();
     enableEnfinServices.setSelected(
@@ -568,7 +567,7 @@ public class WsPreferences extends GWsPreferences
         updateWsMenuConfig(false);
         refreshWsMenu(true);
       }
-    }).start();
+    }, "RefreshWebServices").start();
 
   }
 
@@ -604,7 +603,7 @@ public class WsPreferences extends GWsPreferences
           progressBar.setVisible(false);
           validate();
         }
-      }).start();
+      }, "RefreshWebServicesMenuProgressBar").start();
 
     }
     else
@@ -627,7 +626,7 @@ public class WsPreferences extends GWsPreferences
           Desktop.instance.setProgressBar(null, ct);
         }
 
-      }).start();
+      }, "RefreshWebServicesMenu").start();
     }
   }
 
@@ -676,7 +675,7 @@ public class WsPreferences extends GWsPreferences
         updateWsMenuConfig(false);
         refreshWsMenu(showProgressInDialog);
       }
-    }).start();
+    }, "UpdateAndRefreshWebServicesMenu").start();
 
   }
 }
index 52ce845..5374bb5 100644 (file)
@@ -84,7 +84,7 @@ public class BioJsHTMLOutput extends HTMLOutput
       e.printStackTrace();
       return;
     }
-    new Thread(this).start();
+    new Thread(this, "ExportBioJsHTML").start();
 
   }
 
@@ -94,7 +94,7 @@ public class BioJsHTMLOutput extends HTMLOutput
     File directory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
     Objects.requireNonNull(dirName, "dirName MUST not be null!");
     Objects.requireNonNull(directory, "directory MUST not be null!");
-    TreeMap<String, File> versionFileMap = new TreeMap<String, File>();
+    TreeMap<String, File> versionFileMap = new TreeMap<>();
 
     for (File file : directory.listFiles())
     {
index 4b33dbf..ceb72be 100644 (file)
@@ -22,6 +22,7 @@ package jalview.io;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
+import jalview.ext.forester.io.PhyloXmlFile;
 import jalview.ext.jmol.JmolParser;
 import jalview.structure.StructureImportSettings;
 
@@ -373,8 +374,67 @@ public enum FileFormat implements FileFormatI
     {
       return false;
     }
-  };
+  },
+  // Nexus("Nexus", "nex,nexus,nx,tre", true, true)
+  // {
+  //
+  // @Override
+  // public AlignmentFileReaderI getReader(FileParse source)
+  // throws IOException
+  // {
+  // return new NexusFile(source);
+  // }
+  //
+  // @Override
+  // public AlignmentFileWriterI getWriter(AlignmentI al)
+  // {
+  // // handle within Aptx?
+  // return null;
+  // }
+  //
+  // @Override
+  // public boolean isTextFormat()
+  // {
+  // return true;
+  // }
+  //
+  // @Override
+  // public boolean isTreeFile()
+  // {
+  // return true;
+  // }
+  //
+  // },
+  PhyloXML("PhyloXML", "phyloxml,phylo.xml,pxml", true, true)
+  {
+
+    @Override
+    public AlignmentFileReaderI getReader(FileParse source)
+            throws IOException
+    {
+      return new PhyloXmlFile(source);
+    }
+
+    @Override
+    public AlignmentFileWriterI getWriter(AlignmentI al)
+    {
+      // handle within Aptx?
+      return null;
+    }
+
+    @Override
+    public boolean isTextFormat()
+    {
+      return true;
+    }
+
+    @Override
+    public boolean isTreeFile()
+    {
+      return true;
+    }
 
+  };
   private boolean writable;
 
   private boolean readable;
@@ -447,6 +507,12 @@ public enum FileFormat implements FileFormatI
     return false;
   }
 
+  @Override
+  public boolean isTreeFile()
+  {
+    return false;
+  }
+
   /**
    * By default, answers true, indicating the format is one that can be
    * identified by IdentifyFile. Formats that cannot be identified should
index f7b6076..1e8ab1d 100644 (file)
@@ -80,4 +80,11 @@ public interface FileFormatI
    * @return
    */
   boolean isStructureFile();
+
+  /**
+   * Answers true if the file format can contain a phylogenetic tree.
+   * 
+   * @return
+   */
+  boolean isTreeFile();
 }
index f26d6da..8e7de3f 100755 (executable)
@@ -30,6 +30,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.ext.archaeopteryx.AptxInit;
 import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
 import jalview.gui.Desktop;
@@ -104,7 +105,7 @@ public class FileLoader implements Runnable
     this.protocol = protocol;
     this.format = format;
 
-    final Thread loader = new Thread(this);
+    final Thread loader = new Thread(this, "LoadFile");
 
     SwingUtilities.invokeLater(new Runnable()
     {
@@ -183,7 +184,7 @@ public class FileLoader implements Runnable
    */
   protected AlignFrame _LoadFileWaitTillLoaded()
   {
-    Thread loader = new Thread(this);
+    Thread loader = new Thread(this, "LoadFileWithWaiting");
     loader.start();
 
     while (loader.isAlive())
@@ -199,6 +200,7 @@ public class FileLoader implements Runnable
     return alignFrame;
   }
 
+  // add support for recently opened Aptx trees
   public void updateRecentlyOpened()
   {
     Vector recent = new Vector();
@@ -440,6 +442,13 @@ public class FileLoader implements Runnable
               alignFrame.getViewport()
                       .applyFeaturesStyle(proxyColourScheme);
             }
+            if (format.isTreeFile())
+            {
+              // make generic instead of Aptx specific?
+              AptxInit.createInstancesFromFile(file,
+                      alignFrame.getViewport());
+
+            }
             alignFrame.statusBar.setText(MessageManager.formatMessage(
                     "label.successfully_loaded_file", new String[]
                     { title }));
@@ -455,6 +464,7 @@ public class FileLoader implements Runnable
                       AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
             }
 
+
             try
             {
               alignFrame.setMaximum(jalview.bin.Cache
index 948578a..7d6ae4e 100644 (file)
@@ -67,7 +67,7 @@ public class HtmlSvgOutput extends HTMLOutput
       e.printStackTrace();
       return;
     }
-    new Thread(this).start();
+    new Thread(this, "ExportSvgHTML").start();
   }
 
   public int printUnwrapped(int pwidth, int pheight, int pi,
index ff959b0..1d0a3d2 100755 (executable)
@@ -334,15 +334,33 @@ public class IdentifyFile
           reply = FileFormat.Phylip;
           break;
         }
-        else
+        else if (!lineswereskipped && looksLikeJnetData(data))
         {
-          if (!lineswereskipped && looksLikeJnetData(data))
-          {
             reply = FileFormat.Jnet;
             break;
-          }
+
         }
+        else // phylogenetic file
+        {
+          String identifier = data.toLowerCase();
+          String secondLine = source.nextLine().toLowerCase();
+          if (identifier.startsWith("<phyloxml")
+                  || secondLine.startsWith("<phyloxml"))
+          {
+            reply = FileFormat.PhyloXML;
+            break;
+          }
+          // commented out, nexus parser is troublesome
 
+          // else if (((identifier.startsWith("nexus"))
+          // || (identifier.startsWith("#nexus"))
+          // || (identifier.startsWith("# nexus"))
+          // || (identifier.startsWith("begin"))))
+          // {
+          // reply = FileFormat.Nexus;
+          // break;
+          // }
+        }
         lineswereskipped = true; // this means there was some junk before any
         // key file signature
       }
index c414145..7444b5f 100755 (executable)
@@ -76,14 +76,14 @@ public class NewickFile extends FileParse
 {
   SequenceNode root;
 
-  private boolean HasBootstrap = false;
+  private boolean hasBootstrap = false;
 
-  private boolean HasDistances = false;
+  private boolean hasDistances = false;
 
-  private boolean RootHasDistance = false;
+  private boolean rootHasDistance = false;
 
   // File IO Flags
-  boolean ReplaceUnderscores = false;
+  boolean replaceUnderscores = false;
 
   boolean printRootInfo = true;
 
@@ -156,7 +156,7 @@ public class NewickFile extends FileParse
    */
   public NewickFile(SequenceNode newtree, boolean bootstrap)
   {
-    HasBootstrap = bootstrap;
+    hasBootstrap = bootstrap;
     root = newtree;
   }
 
@@ -174,8 +174,8 @@ public class NewickFile extends FileParse
           boolean distances)
   {
     root = newtree;
-    HasBootstrap = bootstrap;
-    HasDistances = distances;
+    hasBootstrap = bootstrap;
+    hasDistances = distances;
   }
 
   /**
@@ -194,9 +194,9 @@ public class NewickFile extends FileParse
           boolean distances, boolean rootdistance)
   {
     root = newtree;
-    HasBootstrap = bootstrap;
-    HasDistances = distances;
-    RootHasDistance = rootdistance;
+    hasBootstrap = bootstrap;
+    hasDistances = distances;
+    rootHasDistance = rootdistance;
   }
 
   /**
@@ -226,9 +226,9 @@ public class NewickFile extends FileParse
 
   // @tree annotations
   // These are set automatically by the reader
-  public boolean HasBootstrap()
+  public boolean hasBootstrap()
   {
-    return HasBootstrap;
+    return hasBootstrap;
   }
 
   /**
@@ -236,14 +236,14 @@ public class NewickFile extends FileParse
    * 
    * @return DOCUMENT ME!
    */
-  public boolean HasDistances()
+  public boolean hasDistances()
   {
-    return HasDistances;
+    return hasDistances;
   }
 
-  public boolean HasRootDistance()
+  public boolean hasRootDistance()
   {
-    return RootHasDistance;
+    return rootHasDistance;
   }
 
   /**
@@ -446,7 +446,7 @@ public class NewickFile extends FileParse
         {
           if (nodename == null)
           {
-            if (ReplaceUnderscores)
+            if (replaceUnderscores)
             {
               nodename = uqnodename.stringMatched(1).replace('_', ' ');
             }
@@ -479,7 +479,7 @@ public class NewickFile extends FileParse
             {
               bootstrap = (new Integer(nbootstrap.stringMatched(1)))
                       .intValue();
-              HasBootstrap = true;
+              hasBootstrap = true;
             } catch (Exception e)
             {
               Error = ErrorStringrange(Error, "Can't parse bootstrap value",
@@ -495,7 +495,7 @@ public class NewickFile extends FileParse
           try
           {
             distance = (new Float(ndist.stringMatched(1))).floatValue();
-            HasDistances = true;
+            hasDistances = true;
             nodehasdistance = true;
           } catch (Exception e)
           {
@@ -510,12 +510,12 @@ public class NewickFile extends FileParse
           // Write node info here
           c.setName(nodename);
           // Trees without distances still need a render distance
-          c.dist = (HasDistances) ? distance : DefDistance;
+          c.dist = (hasDistances) ? distance : DefDistance;
           // be consistent for internal bootstrap defaults too
-          c.setBootstrap((HasBootstrap) ? bootstrap : DefBootstrap);
+          c.setBootstrap((hasBootstrap) ? bootstrap : DefBootstrap);
           if (c == realroot)
           {
-            RootHasDistance = nodehasdistance; // JBPNote This is really
+            rootHasDistance = nodehasdistance; // JBPNote This is really
             // UGLY!!! Ensure root node gets
             // its given distance
           }
@@ -526,8 +526,8 @@ public class NewickFile extends FileParse
         {
           // Find a place to put the leaf
           SequenceNode newnode = new SequenceNode(null, c, nodename,
-                  (HasDistances) ? distance : DefDistance,
-                  (HasBootstrap) ? bootstrap : DefBootstrap, false);
+                  (hasDistances) ? distance : DefDistance,
+                  (hasBootstrap) ? bootstrap : DefBootstrap, false);
           parseNHXNodeProps(c, commentString2);
           commentString2 = null;
 
@@ -546,7 +546,7 @@ public class NewickFile extends FileParse
               // Insert a dummy node for polytomy
               // dummy nodes have distances
               SequenceNode newdummy = new SequenceNode(null, c, null,
-                      (HasDistances ? 0 : DefDistance), 0, true);
+                      (hasDistances ? 0 : DefDistance), 0, true);
               newdummy.SetChildren(c.left(), newnode);
               c.setLeft(newdummy);
             }
@@ -624,9 +624,9 @@ public class NewickFile extends FileParse
     // (root.right()!=null && root.isDummy())
     root = (SequenceNode) root.right().detach(); // remove the imaginary root.
 
-    if (!RootHasDistance)
+    if (!rootHasDistance)
     {
-      root.dist = (HasDistances) ? 0 : DefDistance;
+      root.dist = (hasDistances) ? 0 : DefDistance;
     }
   }
 
@@ -665,7 +665,7 @@ public class NewickFile extends FileParse
               v = iv.intValue(); // jalview only does integer bootstraps
               // currently
               c.setBootstrap(v);
-              HasBootstrap = true;
+              hasBootstrap = true;
             }
             // more codes here.
           } catch (Exception e)
@@ -722,11 +722,11 @@ public class NewickFile extends FileParse
   {
     synchronized (this)
     {
-      boolean boots = this.HasBootstrap;
-      this.HasBootstrap = withbootstraps;
+      boolean boots = this.hasBootstrap;
+      this.hasBootstrap = withbootstraps;
 
       String rv = print();
-      this.HasBootstrap = boots;
+      this.hasBootstrap = boots;
 
       return rv;
     }
@@ -748,11 +748,11 @@ public class NewickFile extends FileParse
   {
     synchronized (this)
     {
-      boolean dists = this.HasDistances;
-      this.HasDistances = withdists;
+      boolean dists = this.hasDistances;
+      this.hasDistances = withdists;
 
       String rv = print(withbootstraps);
-      this.HasDistances = dists;
+      this.hasDistances = dists;
 
       return rv;
     }
@@ -842,10 +842,10 @@ public class NewickFile extends FileParse
   private String printNodeField(SequenceNode c)
   {
     return ((c.getName() == null) ? "" : nodeName(c.getName()))
-            + ((HasBootstrap) ? ((c.getBootstrap() > -1)
+            + ((hasBootstrap) ? ((c.getBootstrap() > -1)
                     ? ((c.getName() != null ? " " : "") + c.getBootstrap())
                     : "") : "")
-            + ((HasDistances) ? (":" + c.dist) : "");
+            + ((hasDistances) ? (":" + c.dist) : "");
   }
 
   /**
@@ -860,13 +860,13 @@ public class NewickFile extends FileParse
   {
     return (printRootInfo)
             ? (((root.getName() == null) ? "" : nodeName(root.getName()))
-                    + ((HasBootstrap)
+                    + ((hasBootstrap)
                             ? ((root.getBootstrap() > -1)
                                     ? ((root.getName() != null ? " " : "")
                                             + +root.getBootstrap())
                                     : "")
                             : "")
-                    + ((RootHasDistance) ? (":" + root.dist) : ""))
+                    + ((rootHasDistance) ? (":" + root.dist) : ""))
             : "";
   }
 
index 29f3fa9..cfde4ae 100644 (file)
@@ -248,7 +248,8 @@ public class JSFunctionExec implements Runnable
     {
       if (executor == null)
       {
-        executor = new Thread(new JSFunctionExec(jvlite));
+        executor = new Thread(new JSFunctionExec(jvlite),
+                "JavaScript");
         executor.start();
       }
       synchronized (jsExecQueue)
index 86d0c85..2d3eaa4 100755 (executable)
@@ -199,7 +199,7 @@ public class GAlignFrame extends JInternalFrame
 
   private boolean showAutoCalculatedAbove = false;
 
-  private Map<KeyStroke, JMenuItem> accelerators = new HashMap<KeyStroke, JMenuItem>();
+  private Map<KeyStroke, JMenuItem> accelerators = new HashMap<>();
 
   private SplitContainerI splitFrame;
 
@@ -1077,11 +1077,10 @@ public class GAlignFrame extends JInternalFrame
       }
     });
 
-    JMenuItem loadTreeMenuItem = new JMenuItem(
-            MessageManager.getString("label.load_associated_tree"));
-    loadTreeMenuItem.setActionCommand(
-            MessageManager.getString("label.load_tree_for_sequence_set"));
-    loadTreeMenuItem.addActionListener(new ActionListener()
+    JMenuItem loadTreeFile = new JMenuItem(
+            MessageManager.getString("label.from_file"));
+
+    loadTreeFile.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
@@ -1090,6 +1089,89 @@ public class GAlignFrame extends JInternalFrame
       }
     });
 
+    JMenuItem loadTreeUrl = new JMenuItem(
+            MessageManager.getString("label.from_url"));
+    loadTreeUrl.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        loadTreeUrlItem_actionPerformed(e);
+      }
+    });
+
+
+
+    JMenuItem loadTreeBaseStudy = new JMenuItem(
+            MessageManager.getString("label.treebase_study"));
+    loadTreeBaseStudy.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        loadTreeBaseStudy_actionPerformed(e);
+
+      }    });
+
+
+
+    JMenuItem loadTreeBase = new JMenuItem(
+            MessageManager.getString("label.treebase"));
+    loadTreeBase.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        loadTreeBase_actionPerformed(e);
+
+      }
+
+
+    });
+    JMenuItem loadTreePfam = new JMenuItem(
+            MessageManager.getString("label.pfam"));
+    loadTreePfam.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        loadTreePfam_actionPerformed(e);
+
+      }
+
+    });
+    JMenuItem loadTreeFam = new JMenuItem(
+            MessageManager.getString("label.treefam"));
+    loadTreeFam.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        loadTreeFam_actionPerformed(e);
+
+      }
+
+    });
+
+    JMenuItem loadTreeOfLife = new JMenuItem(
+            MessageManager.getString("label.tree_of_life"));
+    loadTreeOfLife.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        loadTreeOfLife_actionPerformed(e);
+
+      }
+
+
+    });
+
     scaleAbove.setVisible(false);
     scaleAbove.setText(MessageManager.getString("action.scale_above"));
     scaleAbove.addActionListener(new ActionListener()
@@ -1683,7 +1765,27 @@ public class GAlignFrame extends JInternalFrame
 
     JMenu exportImageMenu = new JMenu(
             MessageManager.getString("label.export_image"));
+
+    JMenu loadTreeDb = new JMenu(
+            MessageManager.getString("label.from_database"));
+
+    JMenu loadTreeMenu = new JMenu(
+            MessageManager.getString("label.load_associated_tree"));
+    // loadTreeMenu.setToolTipText(
+    // MessageManager.getString("label.load_tree_for_sequence_set"));
+    
     JMenu fileMenu = new JMenu(MessageManager.getString("action.file"));
+
+    loadTreeDb.add(loadTreeBaseStudy);
+    loadTreeDb.add(loadTreeBase);
+    loadTreeDb.add(loadTreePfam);
+    loadTreeDb.add(loadTreeFam);
+    loadTreeDb.add(loadTreeOfLife);
+
+    loadTreeMenu.add(loadTreeFile);
+    loadTreeMenu.add(loadTreeUrl);
+    loadTreeMenu.add(loadTreeDb);
+
     alignFrameMenuBar.add(fileMenu);
     alignFrameMenuBar.add(editMenu);
     alignFrameMenuBar.add(selectMenu);
@@ -1708,7 +1810,7 @@ public class GAlignFrame extends JInternalFrame
     fileMenu.add(exportImageMenu);
     fileMenu.add(exportFeatures);
     fileMenu.add(exportAnnotations);
-    fileMenu.add(loadTreeMenuItem);
+    fileMenu.add(loadTreeMenu);
     fileMenu.add(associatedData);
     fileMenu.addSeparator();
     fileMenu.add(closeMenuItem);
@@ -1853,6 +1955,38 @@ public class GAlignFrame extends JInternalFrame
     // JAL-574
     // selectMenu.addSeparator();
     // selectMenu.add(listenToViewSelections);
+
+
+  }
+
+  protected void loadTreeOfLife_actionPerformed(ActionEvent e)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  protected void loadTreeFam_actionPerformed(ActionEvent e)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  protected void loadTreePfam_actionPerformed(ActionEvent e)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  protected void loadTreeBase_actionPerformed(ActionEvent e)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  protected void loadTreeBaseStudy_actionPerformed(ActionEvent e)
+  {
+    // TODO Auto-generated method stub
+
   }
 
   /**
@@ -2368,6 +2502,13 @@ public class GAlignFrame extends JInternalFrame
 
   }
 
+  protected void loadTreeUrlItem_actionPerformed(ActionEvent e)
+  {
+
+  }
+
+
+
   /**
    * Template method to handle the 'load T-Coffee scores' menu event.
    * <p>
index 8910c67..5c264a8 100755 (executable)
@@ -995,4 +995,11 @@ public class Matrix implements MatrixI
       }
     }
   }
+
+
+  @Override
+  public double[][] getValues()
+  {
+    return value;
+  }
 }
index 5b93c76..840e93b 100644 (file)
@@ -48,7 +48,7 @@ public interface MatrixI
   double getValue(int i, int j);
 
   /**
-   * Sets the value at row i, colum j
+   * Sets the value at row i, column j
    * 
    * @param i
    * @param j
@@ -63,6 +63,15 @@ public interface MatrixI
    */
   double[] getRow(int i);
 
+  /**
+   * Answers all values present in the Matrix ordered by row,column
+   * 
+   * @return the double array containing the values ordered in {row values} per
+   *         column
+   */
+  double[][] getValues();
+
+
   MatrixI copy();
 
   MatrixI transpose();
index c7c02c5..2585df0 100644 (file)
@@ -56,6 +56,11 @@ public class JalviewModelSequence implements java.io.Serializable
    */
   private jalview.schemabinding.version2.FeatureSettings _featureSettings;
 
+  /**
+   * List of external trees
+   */
+  private java.util.Vector<jalview.ext.treeviewer.TreeFrameI> _extTreeList;
+
   // ----------------/
   // - Constructors -/
   // ----------------/
@@ -68,6 +73,7 @@ public class JalviewModelSequence implements java.io.Serializable
     this._viewportList = new java.util.Vector();
     this._userColoursList = new java.util.Vector();
     this._treeList = new java.util.Vector();
+    this._extTreeList = new java.util.Vector<>();
   }
 
   // -----------/
@@ -159,6 +165,27 @@ public class JalviewModelSequence implements java.io.Serializable
   }
 
   /**
+   * Unused.
+   * 
+   * @param treeViewer
+   */
+  public void addExtTreeViewer(jalview.ext.treeviewer.TreeFrameI treeViewer)
+  {
+    this._extTreeList.add(treeViewer);
+  }
+
+  /**
+   * Unused.
+   * 
+   * @param index
+   * @param treeViewer
+   */
+  public void addExtTreeViewer(final int index,
+          jalview.ext.treeviewer.TreeFrameI treeViewer)
+  {
+    this._extTreeList.add(index, treeViewer);
+  }
+  /**
    * 
    * 
    * @param vUserColours
@@ -427,6 +454,48 @@ public class JalviewModelSequence implements java.io.Serializable
   }
 
   /**
+   * Unused.
+   * 
+   * @param index
+   * @return
+   * @throws java.lang.IndexOutOfBoundsException
+   */
+  public jalview.ext.treeviewer.TreeFrameI getExtTreeViewer(final int index)
+          throws java.lang.IndexOutOfBoundsException
+  {
+    // check bounds for index
+    if (index < 0 || index >= this._extTreeList.size())
+    {
+      throw new IndexOutOfBoundsException("getExtTreeViewer: Index value '"
+              + index + "' not in range [0.."
+              + (this._extTreeList.size() - 1) + "]");
+    }
+
+    return _extTreeList.get(index);
+  }
+
+  /**
+   * Unused.
+   * 
+   * @return
+   */
+  public jalview.ext.treeviewer.TreeFrameI[] getExtTreeViewer()
+  {
+    jalview.ext.treeviewer.TreeFrameI[] array = new jalview.ext.treeviewer.TreeFrameI[0];
+    return this._extTreeList.toArray(array);
+  }
+
+  /**
+   * Unused.
+   * 
+   * @return
+   */
+  public int getExtTreeViewerCount()
+  {
+    return this._extTreeList.size();
+  }
+
+  /**
    * Method getUserColours.
    * 
    * @param index
index 6698414..8f45eaa 100644 (file)
@@ -72,10 +72,10 @@ public class AWTConsole extends WindowAdapter
     // create all components and add them
     frame = new Frame("Java Console");
     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-    Dimension frameSize = new Dimension((int) (screenSize.width / 2),
-            (int) (screenSize.height / 2));
-    int x = (int) (frameSize.width / 2);
-    int y = (int) (frameSize.height / 2);
+    Dimension frameSize = new Dimension(screenSize.width / 2,
+            screenSize.height / 2);
+    int x = frameSize.width / 2;
+    int y = frameSize.height / 2;
     frame.setBounds(x, y, frameSize.width, frameSize.height);
 
     textArea = new TextArea();
@@ -125,11 +125,11 @@ public class AWTConsole extends WindowAdapter
 
     // Starting two seperate threads to read from the PipedInputStreams
     //
-    reader = new Thread(this);
+    reader = new Thread(this, "AWTConsoleReader1");
     reader.setDaemon(true);
     reader.start();
     //
-    reader2 = new Thread(this);
+    reader2 = new Thread(this, "AWTConsoleReader2");
     reader2.setDaemon(true);
     reader2.start();
 
@@ -142,17 +142,20 @@ public class AWTConsole extends WindowAdapter
             .getLocalGraphicsEnvironment();
     String[] fontNames = ge.getAvailableFontFamilyNames();
     for (int n = 0; n < fontNames.length; n++)
+    {
       System.out.println(fontNames[n]);
+    }
     // Testing part: simple an error thrown anywhere in this JVM will be printed
     // on the Console
     // We do it with a seperate Thread becasue we don't wan't to break a Thread
     // used by the Console.
     System.out.println("\nLets throw an error on this console");
-    errorThrower = new Thread(this);
+    errorThrower = new Thread(this, "AWTConsoleErrorLog");
     errorThrower.setDaemon(true);
     errorThrower.start();
   }
 
+  @Override
   public synchronized void windowClosed(WindowEvent evt)
   {
     quit = true;
@@ -174,17 +177,20 @@ public class AWTConsole extends WindowAdapter
     System.exit(0);
   }
 
+  @Override
   public synchronized void windowClosing(WindowEvent evt)
   {
     frame.setVisible(false); // default behaviour of JFrame
     frame.dispose();
   }
 
+  @Override
   public synchronized void actionPerformed(ActionEvent evt)
   {
     textArea.setText("");
   }
 
+  @Override
   public synchronized void run()
   {
     try
@@ -203,7 +209,9 @@ public class AWTConsole extends WindowAdapter
           textArea.append(input);
         }
         if (quit)
+        {
           return;
+        }
       }
 
       while (Thread.currentThread() == reader2)
@@ -220,7 +228,9 @@ public class AWTConsole extends WindowAdapter
           textArea.append(input);
         }
         if (quit)
+        {
           return;
+        }
       }
     } catch (Exception e)
     {
@@ -251,7 +261,9 @@ public class AWTConsole extends WindowAdapter
     {
       int available = in.available();
       if (available == 0)
+      {
         break;
+      }
       byte b[] = new byte[available];
       in.read(b);
       input = input + new String(b, 0, b.length);
index 50a34fc..203b4e7 100755 (executable)
@@ -43,9 +43,9 @@ public class DBRefUtils
   /*
    * lookup from lower-case form of a name to its canonical (standardised) form
    */
-  private static Map<String, String> canonicalSourceNameLookup = new HashMap<String, String>();
+  private static Map<String, String> canonicalSourceNameLookup = new HashMap<>();
 
-  private static Map<String, String> dasCoordinateSystemsLookup = new HashMap<String, String>();
+  private static Map<String, String> dasCoordinateSystemsLookup = new HashMap<>();
 
   static
   {
@@ -65,6 +65,8 @@ public class DBRefUtils
     canonicalSourceNameLookup.put("ensembl-tr", DBRefSource.ENSEMBL);
     canonicalSourceNameLookup.put("ensembl-gn", DBRefSource.ENSEMBL);
 
+    canonicalSourceNameLookup.put("pfam", DBRefSource.PFAM);
+
     // Make sure we have lowercase entries for all canonical string lookups
     Set<String> keys = canonicalSourceNameLookup.keySet();
     for (String k : keys)
@@ -97,13 +99,13 @@ public class DBRefUtils
     {
       return dbrefs;
     }
-    HashSet<String> srcs = new HashSet<String>();
+    HashSet<String> srcs = new HashSet<>();
     for (String src : sources)
     {
       srcs.add(src.toUpperCase());
     }
 
-    List<DBRefEntry> res = new ArrayList<DBRefEntry>();
+    List<DBRefEntry> res = new ArrayList<>();
     for (DBRefEntry dbr : dbrefs)
     {
       String source = getCanonicalName(dbr.getSource());
@@ -218,7 +220,7 @@ public class DBRefUtils
   static List<DBRefEntry> searchRefs(DBRefEntry[] refs, DBRefEntry entry,
           DbRefComp comparator)
   {
-    List<DBRefEntry> rfs = new ArrayList<DBRefEntry>();
+    List<DBRefEntry> rfs = new ArrayList<>();
     if (refs == null || entry == null)
     {
       return rfs;
@@ -594,7 +596,7 @@ public class DBRefUtils
   public static List<DBRefEntry> searchRefsForSource(DBRefEntry[] dbRefs,
           String source)
   {
-    List<DBRefEntry> matches = new ArrayList<DBRefEntry>();
+    List<DBRefEntry> matches = new ArrayList<>();
     if (dbRefs != null && source != null)
     {
       for (DBRefEntry dbref : dbRefs)
@@ -644,7 +646,7 @@ public class DBRefUtils
       // nothing to do
       return;
     }
-    List<DBRefEntry> selfs = new ArrayList<DBRefEntry>();
+    List<DBRefEntry> selfs = new ArrayList<>();
     {
       DBRefEntry[] selfArray = selectDbRefs(!sequence.isProtein(),
               sequence.getDBRefs());
@@ -664,11 +666,11 @@ public class DBRefUtils
         selfs.remove(p);
       }
     }
-    List<DBRefEntry> toPromote = new ArrayList<DBRefEntry>();
+    List<DBRefEntry> toPromote = new ArrayList<>();
 
     for (DBRefEntry p : pr)
     {
-      List<String> promType = new ArrayList<String>();
+      List<String> promType = new ArrayList<>();
       if (sequence.isProtein())
       {
         switch (getCanonicalName(p.getSource()))
index 9c5c109..78a833e 100644 (file)
@@ -990,4 +990,23 @@ public final class MappingUtils
       }
     }
   }
+
+
+  public static <K, V> Map<K, V> putWithDuplicationCheck(Map<K, V> map, K key,
+          V value)
+  {
+    if (!map.containsKey(key))
+    {
+      map.put(key, value);
+    }
+    else
+    {
+      jalview.bin.Cache.log.warn(
+              "Attempt to add duplicate entry detected for map with key: "
+                      + key.toString() + " and value: " + value.toString());
+    }
+  
+    return map;
+    
+  }
 }
index a0cbff4..d79cdce 100644 (file)
@@ -43,6 +43,7 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.ext.treeviewer.TreeI;
 import jalview.renderer.ResidueShader;
 import jalview.renderer.ResidueShaderI;
 import jalview.schemes.ColourSchemeI;
@@ -956,6 +957,7 @@ public abstract class AlignmentViewport
     changeSupport = null;
     ranges = null;
     currentTree = null;
+    currentExtTree = null;
     selectionGroup = null;
     setAlignment(null);
   }
@@ -2879,6 +2881,8 @@ public abstract class AlignmentViewport
 
   protected TreeModel currentTree = null;
 
+  protected TreeI currentExtTree = null;
+
   @Override
   public boolean hasSearchResults()
   {
@@ -2939,7 +2943,7 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public void setCurrentTree(TreeModel tree)
+  public void setCurrentTree(TreeModel tree) // adapt to Aptx
   {
     currentTree = tree;
   }
@@ -2949,4 +2953,15 @@ public abstract class AlignmentViewport
   {
     return currentTree;
   }
+
+  public TreeI getCurrentExtTree()
+  {
+    return currentExtTree;
+  }
+
+  public void setCurrentExtTree(TreeI externalTree)
+  {
+    currentExtTree = externalTree;
+  }
+
 }
index fb8864d..c01b99c 100644 (file)
@@ -117,7 +117,7 @@ public class DBRefFetcher implements Runnable
           DbSourceProxy[] sources, FeatureSettings featureSettings,
           boolean isNucleotide)
   {
-    listeners = new ArrayList<FetchFinishedListenerI>();
+    listeners = new ArrayList<>();
     this.progressWindow = progressIndicatorFrame;
     alseqs = new SequenceI[seqs.length];
     SequenceI[] ds = new SequenceI[seqs.length];
@@ -163,7 +163,7 @@ public class DBRefFetcher implements Runnable
   {
     // af.featureSettings_actionPerformed(null);
     String[] defdb = null;
-    List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
+    List<DbSourceProxy> selsources = new ArrayList<>();
     Vector<jalviewSourceI> dasselsrc = (featureSettings != null)
             ? featureSettings.getSelectedSources()
             : new DasSourceBrowser().getSelectedSources();
@@ -189,7 +189,7 @@ public class DBRefFetcher implements Runnable
     {
       defdb = DBRefSource.PROTEINDBS;
     }
-    List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
+    List<DbSourceProxy> srces = new ArrayList<>();
     for (String ddb : defdb)
     {
       List<DbSourceProxy> srcesfordb = sfetcher.getSourceProxy(ddb);
@@ -267,7 +267,7 @@ public class DBRefFetcher implements Runnable
     // TODO can we not simply write
     // if (waitTillFinished) { run(); } else { new Thread(this).start(); }
 
-    Thread thread = new Thread(this);
+    Thread thread = new Thread(this, "FetchDBRef");
     thread.start();
     running = true;
 
@@ -309,14 +309,14 @@ public class DBRefFetcher implements Runnable
       }
       else if (seqs == null)
       {
-        seqs = new Vector<SequenceI>();
+        seqs = new Vector<>();
         seqs.addElement(seq);
       }
 
     }
     else
     {
-      seqs = new Vector<SequenceI>();
+      seqs = new Vector<>();
       seqs.addElement(seq);
     }
 
@@ -355,9 +355,9 @@ public class DBRefFetcher implements Runnable
       e.printStackTrace();
     }
 
-    Vector<SequenceI> sdataset = new Vector<SequenceI>(
+    Vector<SequenceI> sdataset = new Vector<>(
             Arrays.asList(dataset));
-    List<String> warningMessages = new ArrayList<String>();
+    List<String> warningMessages = new ArrayList<>();
 
     int db = 0;
     while (sdataset.size() > 0 && db < dbSources.length)
@@ -369,8 +369,8 @@ public class DBRefFetcher implements Runnable
       SequenceI[] currSeqs = new SequenceI[sdataset.size()];
       sdataset.copyInto(currSeqs);// seqs that are to be validated against
       // dbSources[db]
-      Vector<String> queries = new Vector<String>(); // generated queries curSeq
-      seqRefs = new Hashtable<String, Vector<SequenceI>>();
+      Vector<String> queries = new Vector<>(); // generated queries curSeq
+      seqRefs = new Hashtable<>();
 
       int seqIndex = 0;
 
@@ -572,7 +572,7 @@ public class DBRefFetcher implements Runnable
     {
       // Work out which sequences this sequence matches,
       // taking into account all accessionIds and names in the file
-      Vector<SequenceI> sequenceMatches = new Vector<SequenceI>();
+      Vector<SequenceI> sequenceMatches = new Vector<>();
       // look for corresponding accession ids
       DBRefEntry[] entryRefs = DBRefUtils
               .selectRefs(retrievedSeq.getDBRefs(), new String[]
@@ -824,7 +824,7 @@ public class DBRefFetcher implements Runnable
    */
   private SequenceI[] recoverDbSequences(SequenceI[] sequencesArray)
   {
-    Vector<SequenceI> nseq = new Vector<SequenceI>();
+    Vector<SequenceI> nseq = new Vector<>();
     for (int i = 0; sequencesArray != null
             && i < sequencesArray.length; i++)
     {
index c661e2c..21af021 100644 (file)
@@ -212,7 +212,8 @@ public class DasSequenceFeatureFetcher
 
       if (reply == JvOptionPane.YES_OPTION)
       {
-        Thread thread = new Thread(new FetchDBRefs());
+        Thread thread = new Thread(new FetchDBRefs(),
+                "FetchDBReferenceManager");
         thread.start();
       }
       else
@@ -230,7 +231,7 @@ public class DasSequenceFeatureFetcher
   private void _startFetching()
   {
     running = true;
-    new Thread(new FetchSeqFeatures()).start();
+    new Thread(new FetchSeqFeatures(), "FetchSeqFeatures").start();
   }
 
   class FetchSeqFeatures implements Runnable
index ea883c8..51e7b1a 100644 (file)
@@ -379,7 +379,7 @@ public class Discoverer implements Runnable
   public void run()
   {
     final Discoverer discoverer = this;
-    Thread discoverThread = new Thread()
+    Thread discoverThread = new Thread() // no function?
     {
       @Override
       public void run()
index 5319eab..9bc8713 100644 (file)
@@ -178,7 +178,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     running = true;
 
     // first set up exclusion list if needed
-    final Set<String> ignoredServices = new HashSet<String>();
+    final Set<String> ignoredServices = new HashSet<>();
     for (String ignored : Cache
             .getDefault("IGNORED_JABAWS_SERVICETYPES", "").split("\\|"))
     {
@@ -217,9 +217,9 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     {
       validServiceUrls.removeAllElements();
     }
-    ArrayList<String> svctypes = new ArrayList<String>();
+    ArrayList<String> svctypes = new ArrayList<>();
 
-    List<JabaWsServerQuery> qrys = new ArrayList<JabaWsServerQuery>();
+    List<JabaWsServerQuery> qrys = new ArrayList<>();
     for (final String jwsserver : getServiceUrls())
     {
       JabaWsServerQuery squery = new JabaWsServerQuery(this, jwsserver);
@@ -237,7 +237,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
 
       }
       qrys.add(squery);
-      new Thread(squery).start();
+      new Thread(squery, "JabaQuery").start();
     }
     boolean finished = true;
     do
@@ -285,7 +285,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
                   + svctypes.indexOf(svc.serviceType);
         }
         jalview.util.QuickSort.sort(spos, svcs);
-        services = new Vector<Jws2Instance>();
+        services = new Vector<>();
         for (Jws2Instance svc : svcs)
         {
           if (!ignoredServices.contains(svc.serviceType))
@@ -312,7 +312,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   {
     if (services == null)
     {
-      services = new Vector<Jws2Instance>();
+      services = new Vector<>();
     }
     System.out.println(
             "Discovered service: " + jwsservers + " " + service.toString());
@@ -329,7 +329,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     service.hasParameters();
     if (validServiceUrls == null)
     {
-      validServiceUrls = new Vector<String>();
+      validServiceUrls = new Vector<>();
     }
     validServiceUrls.add(jwsservers);
   }
@@ -363,10 +363,10 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
      * for moment we keep them separate.
      */
     JMenu atpoint;
-    List<Jws2Instance> enumerableServices = new ArrayList<Jws2Instance>();
+    List<Jws2Instance> enumerableServices = new ArrayList<>();
     // jws2al.removeAll();
-    Map<String, Jws2Instance> preferredHosts = new HashMap<String, Jws2Instance>();
-    Map<String, List<Jws2Instance>> alternates = new HashMap<String, List<Jws2Instance>>();
+    Map<String, Jws2Instance> preferredHosts = new HashMap<>();
+    Map<String, List<Jws2Instance>> alternates = new HashMap<>();
     for (Jws2Instance service : services.toArray(new Jws2Instance[0]))
     {
       if (!isRecalculable(service.action))
@@ -395,7 +395,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
         {
           if (ph == null)
           {
-            ph = new ArrayList<Jws2Instance>();
+            ph = new ArrayList<>();
           }
           ph.add(service);
           alternates.put(service.serviceType, ph);
@@ -458,7 +458,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
                   changeSupport.firePropertyChange("services",
                           new Vector<Jws2Instance>(), services);
                 };
-              }).start();
+              }, "LoadPreferredService").start();
 
             }
           });
@@ -483,17 +483,17 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
      */
     JMenu atpoint;
 
-    List<String> hostLabels = new ArrayList<String>();
-    Hashtable<String, String> lasthostFor = new Hashtable<String, String>();
-    Hashtable<String, ArrayList<Jws2Instance>> hosts = new Hashtable<String, ArrayList<Jws2Instance>>();
-    ArrayList<String> hostlist = new ArrayList<String>();
+    List<String> hostLabels = new ArrayList<>();
+    Hashtable<String, String> lasthostFor = new Hashtable<>();
+    Hashtable<String, ArrayList<Jws2Instance>> hosts = new Hashtable<>();
+    ArrayList<String> hostlist = new ArrayList<>();
     for (Jws2Instance service : enumerableServices)
     {
       ArrayList<Jws2Instance> hostservices = hosts.get(service.getHost());
       if (hostservices == null)
       {
         hosts.put(service.getHost(),
-                hostservices = new ArrayList<Jws2Instance>());
+                hostservices = new ArrayList<>());
         hostlist.add(service.getHost());
       }
       hostservices.add(service);
@@ -581,7 +581,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   {
     if (args.length > 0)
     {
-      testUrls = new ArrayList<String>();
+      testUrls = new ArrayList<>();
       for (String url : args)
       {
         testUrls.add(url);
@@ -685,7 +685,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
       // return test urls, if there are any, instead of touching cache
       return testUrls;
     }
-    List<String> urls = new ArrayList<String>();
+    List<String> urls = new ArrayList<>();
 
     if (this.preferredUrl != null)
     {
@@ -734,7 +734,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   public Vector<Jws2Instance> getServices()
   {
     return (services == null) ? new Vector<Jws2Instance>()
-            : new Vector<Jws2Instance>(services);
+            : new Vector<>(services);
   }
 
   /**
@@ -839,7 +839,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   {
     if (urlsWithoutServices == null)
     {
-      urlsWithoutServices = new Vector<String>();
+      urlsWithoutServices = new Vector<>();
     }
 
     if ((invalidServiceUrls == null
@@ -859,7 +859,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   {
     if (invalidServiceUrls == null)
     {
-      invalidServiceUrls = new Vector<String>();
+      invalidServiceUrls = new Vector<>();
     }
     if (!invalidServiceUrls.contains(jwsservers))
     {
@@ -947,7 +947,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
    */
   public Jws2Instance getPreferredServiceFor(String[] serviceURLs)
   {
-    HashSet<String> urls = new HashSet<String>();
+    HashSet<String> urls = new HashSet<>();
     urls.addAll(Arrays.asList(serviceURLs));
     Jws2Instance match = null;
     if (services != null)
@@ -974,7 +974,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     return match;
   }
 
-  Map<String, Map<String, String>> preferredServiceMap = new HashMap<String, Map<String, String>>();;
+  Map<String, Map<String, String>> preferredServiceMap = new HashMap<>();;
 
   /**
    * get current preferred service of the given type, or global default
@@ -1026,12 +1026,12 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     String afid = (af == null) ? "" : af.getViewport().getSequenceSetId();
     if (preferredServiceMap == null)
     {
-      preferredServiceMap = new HashMap<String, Map<String, String>>();
+      preferredServiceMap = new HashMap<>();
     }
     Map<String, String> prefmap = preferredServiceMap.get(afid);
     if (prefmap == null)
     {
-      prefmap = new HashMap<String, String>();
+      prefmap = new HashMap<>();
       preferredServiceMap.put(afid, prefmap);
     }
     prefmap.put(serviceType, selectedServer.getHost());
diff --git a/test/jalview/ext/archaeopteryx/AptxJalviewSequenceTreeTest.java b/test/jalview/ext/archaeopteryx/AptxJalviewSequenceTreeTest.java
new file mode 100644 (file)
index 0000000..eb92df9
--- /dev/null
@@ -0,0 +1,134 @@
+// package jalview.ext.archaeopteryx;
+//
+// import static org.testng.Assert.assertEquals;
+// import static org.testng.Assert.assertTrue;
+//
+// import jalview.analysis.NJTree;
+// import jalview.analysis.TreeBuilder;
+// import jalview.analysis.scoremodels.ScoreModels;
+// import jalview.analysis.scoremodels.SimilarityParams;
+// import jalview.api.analysis.ScoreModelI;
+// import jalview.api.analysis.SimilarityParamsI;
+// import jalview.bin.Jalview;
+// import jalview.datamodel.Alignment;
+// import jalview.datamodel.AlignmentI;
+// import jalview.datamodel.Sequence;
+// import jalview.datamodel.SequenceI;
+// import jalview.gui.AlignViewport;
+//
+// import org.forester.archaeopteryx.MainFrame;
+// import org.forester.archaeopteryx.TreePanel;
+// import org.forester.phylogeny.Phylogeny;
+// import org.testng.annotations.BeforeClass;
+// import org.testng.annotations.Test;
+//
+// public class AptxJalviewSequenceTreeTest extends TreeViewTest
+// {
+// TreeBuilder jalviewTree;
+//
+// TreePanel treePanel;
+//
+// Phylogeny tree;
+//
+// MainFrame aptx;
+//
+// Jalview jalview;
+//
+// @Override
+// @BeforeClass(alwaysRun = true)
+// public void setUpTree()
+// {
+// SequenceI seq1 = new Sequence("Seq1", "ABCDEFGHIJ");
+// SequenceI seq2 = new Sequence("Seq2", "ABCDEFTHIJ");
+// SequenceI seq3 = new Sequence("Seq3", "BCFWDHIJ");
+// SequenceI seq4 = new Sequence("Seq4", "WTHISTHIS");
+//
+// AlignmentI al = new Alignment(
+// new SequenceI[]
+// { seq1, seq2, seq3, seq4 });
+// AlignViewport alignViewport = new AlignViewport(al);
+//
+// ScoreModelI scoreModel = ScoreModels.getInstance().getBlosum62();
+// SimilarityParamsI similarityParams = new SimilarityParams(true, true,
+// true, false);
+//
+// jalviewTree = new NJTree(alignViewport, scoreModel,
+// similarityParams);
+// }
+//
+// @Override
+// @BeforeClass(dependsOnMethods = { "setUpTree" })
+// public void createTreeView()
+// {
+// treeView = AptxInit.createInstanceFromCalculation(jalviewTree);
+// aptx = (MainFrame) treeView; // still pretty ugly
+//
+// treePanel = aptx.getMainPanel().getCurrentTreePanel();
+// tree = treePanel.getPhylogeny();
+//
+// }
+//
+// @Override
+// public void testTreeLoaded()
+// {
+// assertTrue(tree != null);
+//
+// }
+//
+// @Override
+// public void testTreeTitle()
+// {
+// assertTrue(tree.getName().contains("Neighbour Joining Using BLOSUM62"));
+//
+// }
+//
+// @Override
+// public void testChildNodesCount()
+// {
+// assertEquals(
+// tree.getNode("Seq2").getParent().getNumberOfExternalNodes(), 2);
+//
+// }
+//
+// @Override
+// public void testExistingBranchName()
+// {
+// tree.getNode("Seq4");
+//
+// }
+//
+// @Override
+// public void testChildToParentBranchLength()
+// {
+// assertEquals(tree.getNode("Seq1").getDistanceToParent(), 5.25);
+//
+// }
+//
+// @Test(
+// groups = "Functional",
+// expectedExceptions = IllegalArgumentException.class)
+// public void testInvalidBranchName()
+// {
+// tree.getNode("I shouldn't exist");
+//
+// }
+//
+// @Override
+// public void testNodeToRootBranchLength()
+// {
+// assertEquals(tree.getNode("Seq3").calculateDistanceToRoot(), 19.13);
+//
+// }
+//
+// @Override
+// public void testDistantNodeToRootBranchLength()
+// {
+// assertEquals(tree.getNode("Seq2").calculateDistanceToRoot(),
+// 3.75 + 35.75 + 19.13);
+//
+// }
+//
+//
+//
+//
+// }
diff --git a/test/jalview/ext/archaeopteryx/AptxPhylogenyTreeTest.java b/test/jalview/ext/archaeopteryx/AptxPhylogenyTreeTest.java
new file mode 100644 (file)
index 0000000..4163e3d
--- /dev/null
@@ -0,0 +1,154 @@
+// package jalview.ext.archaeopteryx;
+//
+// import static org.testng.Assert.assertEquals;
+// import static org.testng.Assert.assertTrue;
+//
+// import jalview.gui.Desktop;
+//
+// import org.forester.archaeopteryx.Archaeopteryx;
+// import org.forester.archaeopteryx.MainFrame;
+// import org.forester.archaeopteryx.TreePanel;
+// import org.forester.phylogeny.Phylogeny;
+// import org.forester.phylogeny.PhylogenyNode;
+// import org.testng.annotations.BeforeClass;
+// import org.testng.annotations.Test;
+//
+// public class AptxPhylogenyTreeTest extends TreeViewTest
+// {
+// final Phylogeny inputTree = new Phylogeny();
+//
+// final PhylogenyNode rootNode = new PhylogenyNode("root");
+//
+// final PhylogenyNode ancestor1Node = new PhylogenyNode("ancestor 1");
+//
+// final PhylogenyNode ancestor2Node = new PhylogenyNode("leaf 2");
+//
+// final PhylogenyNode leaf1aNode = new PhylogenyNode("leaf 1a");
+//
+// final PhylogenyNode leaf1bNode = new PhylogenyNode("leaf 1b");
+//
+// final PhylogenyNode leaf1cNode = new PhylogenyNode("leaf 1c");
+//
+// Phylogeny tree;
+//
+// TreePanel treePanel;
+//
+// MainFrame aptx;
+//
+//
+// @Override
+// @BeforeClass(alwaysRun = true)
+// public void setUpTree()
+// {
+// ancestor1Node.addAsChild(leaf1aNode);
+// ancestor1Node.addAsChild(leaf1bNode);
+// ancestor1Node.addAsChild(leaf1cNode);
+//
+// rootNode.addAsChild(ancestor1Node);
+// rootNode.addAsChild(ancestor2Node);
+//
+// leaf1aNode.setDistanceToParent(2);
+// leaf1bNode.setDistanceToParent(3);
+// leaf1cNode.setDistanceToParent(4);
+//
+// ancestor1Node.setDistanceToParent(36);
+// ancestor2Node.setDistanceToParent(42);
+//
+// inputTree.setName("test");
+// inputTree.setRoot(rootNode);
+// inputTree.setRooted(true);
+//
+// }
+//
+// @Override
+// @BeforeClass(dependsOnMethods = { "setUpJalview", "setUpTree" })
+// public void createTreeView()
+// {
+// treeView = Archaeopteryx.createApplication(inputTree);
+// aptx = (MainFrame) treeView; // pretty ugly
+// treePanel = aptx.getMainPanel().getCurrentTreePanel();
+// tree = treePanel.getPhylogeny();
+//
+// Desktop.addInternalFrame(aptx, "Archaeopteryx", 500, 500);
+//
+// }
+//
+//
+//
+// @Test(groups = "Functional")
+// public void testMainPanelExists()
+// {
+// assertTrue(aptx.getMainPanel() != null);
+// }
+//
+// @Test(groups = "Functional")
+// public void testTreePanelExists()
+// {
+// assertTrue(treePanel != null);
+// }
+//
+// @Override
+// public void testTreeTitle()
+// {
+// assertTrue(tree.getName().equals("test"));
+//
+// }
+//
+// @Test(
+// groups = "Functional",
+// expectedExceptions = IllegalArgumentException.class)
+// public void testInvalidBranchName()
+// {
+// tree.getNode("I shouldn't exist");
+//
+// }
+//
+// @Override
+// public void testExistingBranchName()
+// {
+// tree.getNode("leaf 2");
+//
+// }
+//
+// @Override
+// public void testTreeLoaded()
+// {
+// assertTrue(tree != null);
+// }
+//
+// @Override
+// public void testChildNodesCount()
+// {
+// assertEquals(tree.getNode("ancestor 1").getNumberOfExternalNodes(), 3);
+//
+// }
+//
+// @Override
+// public void testChildToParentBranchLength()
+// {
+// assertEquals(tree.getNode("leaf 1a").getDistanceToParent(), 2.0);
+//
+// }
+//
+// @Override
+// public void testNodeToRootBranchLength()
+// {
+// assertEquals(tree.getNode("leaf 2").getDistanceToParent(), 42.0);
+//
+// }
+//
+// @Override
+// public void testDistantNodeToRootBranchLength()
+// {
+// assertEquals(tree.getNode("leaf 1c").calculateDistanceToRoot(),
+// 4.0 + 36.0);
+//
+// }
+//
+//
+//
+//
+//
+//
+//
+// }
diff --git a/test/jalview/ext/archaeopteryx/TreeViewTest.java b/test/jalview/ext/archaeopteryx/TreeViewTest.java
new file mode 100644 (file)
index 0000000..87c32e4
--- /dev/null
@@ -0,0 +1,75 @@
+package jalview.ext.archaeopteryx;
+
+import static org.testng.Assert.assertTrue;
+
+import jalview.bin.Jalview;
+import jalview.ext.treeviewer.TreeFrameI;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public abstract class TreeViewTest
+{
+  Jalview jalview;
+
+  TreeFrameI treeView;
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  public abstract void setUpTree();
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJalview()
+  {
+    String[] args = new String[0];
+    Jalview.main(args);
+  }
+
+  public abstract void createTreeView();
+
+  @Test(groups = "Functional")
+  public void testTreeViewExists()
+  {
+    assertTrue(treeView != null);
+  }
+
+  @Test(groups = "Functional")
+  public void testTreeViewBoundToJalview()
+  {
+    assertTrue(treeView.getTopLevelAncestor() instanceof Desktop);
+  }
+
+  @Test(groups = "Functional")
+  public void testShowingTreeView()
+  {
+    assertTrue(treeView.isShowing());
+  }
+
+  @Test(groups = "Functional")
+  public abstract void testTreeLoaded();
+
+  @Test(groups = "Functional")
+  public abstract void testTreeTitle();
+
+  @Test(groups = "Functional")
+  public abstract void testExistingBranchName();
+
+  @Test(groups = "Functional")
+  public abstract void testChildNodesCount();
+
+  @Test(groups = "Functional")
+  public abstract void testChildToParentBranchLength();
+
+  @Test(groups = "Functional")
+  public abstract void testNodeToRootBranchLength();
+
+  @Test(groups = "Functional")
+  public abstract void testDistantNodeToRootBranchLength();
+}
index e93bfac..4398cf1 100644 (file)
@@ -161,7 +161,14 @@ public class FreeUpMemoryTest
     af.openTreePcaDialog();
     CalculationChooser dialog = af.alignPanel.getCalculationDialog();
     dialog.openPcaPanel("BLOSUM62", dialog.getSimilarityParameters(true));
-    dialog.openTreePanel("BLOSUM62", dialog.getSimilarityParameters(false));
+    try
+    {
+      dialog.createTree("BLOSUM62", dialog.getSimilarityParameters(false));
+    } catch (IOException e)
+    {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
 
     /*
      * wait until Tree and PCA have been computed
index a92f5fb..1cbe5ac 100644 (file)
@@ -109,8 +109,8 @@ public class NewickFileTests
       SequenceNode tree = nf.getTree();
       AssertJUnit.assertTrue(stage + "Null Tree", tree != null);
       stage = "Creating newick file from testTree " + treename;
-      String gentree = new NewickFile(tree).print(nf.HasBootstrap(),
-              nf.HasDistances());
+      String gentree = new NewickFile(tree).print(nf.hasBootstrap(),
+              nf.hasDistances());
       AssertJUnit.assertTrue(stage + "Empty string generated",
               gentree != null && gentree.trim().length() > 0);
       stage = "Parsing regenerated testTree " + treename;
diff --git a/utils/proguard.jar b/utils/proguard.jar
deleted file mode 100755 (executable)
index dfb7f29..0000000
Binary files a/utils/proguard.jar and /dev/null differ
diff --git a/utils/proguard_5.3.3.jar b/utils/proguard_5.3.3.jar
new file mode 100755 (executable)
index 0000000..08f4a4c
Binary files /dev/null and b/utils/proguard_5.3.3.jar differ