[med-svn] [beast2-mcmc] 06/08: Imported Upstream version 2.4.1pre+dfsg

Andreas Tille tille at debian.org
Wed May 4 08:01:42 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository beast2-mcmc.

commit 0110375702f870fe075b1f2ccfb8465b9aeab5e7
Author: Andreas Tille <tille at debian.org>
Date:   Wed May 4 09:43:54 2016 +0200

    Imported Upstream version 2.4.1pre+dfsg
---
 build.xml                                          |  23 +++--
 examples/testUCLNclock.json                        |   2 +-
 release/Linux/bin/beast                            |  19 +++-
 release/Mac/install.png                            | Bin 17518 -> 17128 bytes
 release/Windows/AppStore_launch4j.xml              |   2 +-
 release/Windows/BEAST_launch4j.xml                 |   2 +-
 release/Windows/BEAUti_launch4j.xml                |   2 +-
 release/Windows/LogCombiner_launch4j.xml           |   2 +-
 release/Windows/TreeAnnotator_launch4j.xml         |   2 +-
 release/common/README.txt                          |   6 +-
 release/common/VERSION HISTORY.txt                 |  29 +++++-
 src/beast/app/BEASTVersion.java                    |   4 +-
 src/beast/app/beastapp/BeastLauncher.java          |  56 ++++++++---
 src/beast/app/beastapp/BeastMain.java              |  10 +-
 src/beast/app/beauti/AlignmentListInputEditor.java |  52 +++++-----
 src/beast/app/beauti/Beauti.java                   |  47 ++++++---
 src/beast/app/beauti/BeautiAlignmentProvider.java  |  12 ++-
 src/beast/app/beauti/BeautiDoc.java                | 101 +++++++++----------
 src/beast/app/beauti/BeautiLauncher.java           |   2 +
 src/beast/app/beauti/BeautiPanelConfig.java        |   2 +-
 src/beast/app/beauti/GuessPatternDialog.java       |  12 ++-
 src/beast/app/beauti/JPackageDialog.java           |   6 +-
 src/beast/app/beauti/TaxonSetInputEditor.java      |  36 ++++---
 src/beast/app/beauti/TipDatesInputEditor.java      |   2 +-
 src/beast/app/draw/InputEditorFactory.java         |   2 +-
 src/beast/app/draw/ListInputEditor.java            |   5 +-
 .../treeannotator/KernelDensityEstimator2D.java    |   2 +-
 src/beast/app/treeannotator/RealNumberField.java   |   2 +-
 src/beast/app/util/Utils.java                      | 107 +++++++++++++++++++++
 src/beast/app/util/Utils6.java                     |  12 +++
 src/beast/core/Input.java                          |   4 +
 src/beast/core/Logger.java                         |   7 +-
 src/beast/core/OperatorSchedule.java               |   2 -
 .../evolution/likelihood/BeagleTreeLikelihood.java |  80 ++++++++++++---
 .../likelihood/ThreadedTreeLikelihood.java         |   4 +-
 src/beast/evolution/likelihood/TreeLikelihood.java |   2 +-
 .../evolution/operators/DeltaExchangeOperator.java |  72 ++++++++------
 src/beast/evolution/operators/SubtreeSlide.java    |   2 +-
 .../evolution/sitemodel/SiteModelInterface.java    |   2 +-
 .../substitutionmodel/DefaultEigenSystem.java      |   6 +-
 .../evolution/substitutionmodel/Frequencies.java   |   9 +-
 src/beast/evolution/tree/RandomTree.java           |   6 +-
 src/beast/util/AddOnManager.java                   |  78 ++++++++++-----
 src/beast/util/ClusterTree.java                    |   3 +-
 src/beast/util/JSONProducer.java                   |  25 +++--
 src/beast/util/MersenneTwisterFast.java            |   4 +-
 src/beast/util/NexusParser.java                    |   2 +-
 src/beast/util/Package.java                        |   2 +-
 src/beast/util/PackageDependency.java              |   2 +-
 src/beast/util/Randomizer.java                     |   2 +-
 src/beast/util/TreeParser.java                     |   3 +-
 src/beast/util/XMLProducer.java                    |   4 +
 .../operator/DeltaExchangeOperatorTest.java        |  64 ++++++++++++
 .../beast/evolution/operator/TestOperator.java     |  52 ++++++++++
 src/test/beast/util/JSONTest.java                  |   6 +-
 templates/ClockModels.xml                          |  14 +--
 templates/Standard.xml                             |   2 +-
 templates/StarBeast.xml                            |   4 +-
 version.xml                                        |   2 +-
 59 files changed, 750 insertions(+), 276 deletions(-)

diff --git a/build.xml b/build.xml
index 821d599..ee8e6f8 100644
--- a/build.xml
+++ b/build.xml
@@ -90,6 +90,7 @@
         <delete file="${build}/beast/app/treeannotator/TreeAnnotatorLauncher.class" />
         <delete file="${build}/beast/app/util/Utils6.class" />
         <delete file="${build}/beast/app/BEASTVersion.class" />
+        <delete file="${build}/beast/app/util/Version.class" />
         <javac source="1.6"
                target="1.6"
                bootclasspath='/opt/jdk1.6.0_45/jre/lib/rt.jar'
@@ -103,6 +104,7 @@
             <include name="beast/**/*Launcher.java" />
             <include name="beast/**/Utils6.java" />
             <include name="beast/**/BEASTVersion.java" />
+            <include name="beast/**/Version.java" />
         </javac>
         <copy todir="${build}">
             <fileset dir="${src}" includes="**/*.properties" />
@@ -111,7 +113,7 @@
         <echo message="Successfully compiled." />
     </target>
 
-    <!-- make the beast.jar and beauti.jar -->
+    <!-- make the beast.jar -->
     <target name="dist_all_BEAST" depends="compile-all" description="create BEAST jar">
         <!-- Create the distribution directory -->
         <mkdir dir="${dist}" />
@@ -140,6 +142,7 @@
                 <include name="beast/**/*Launcher.class" />
                 <include name="beast/**/Utils6*.class" />
                 <include name="beast/**/BEASTVersion.class" />
+                <include name="beast/**/Version.class" />
                 <include name="beast/app/draw/icons/beauti.png"/>
             </fileset>
         </jar>
@@ -160,7 +163,7 @@
         <copy file="${dist}/beast.jar" todir="${release_dir}/package/lib/"/>
         <copy file="../beast2/version.xml" todir="${release_dir}/package/"/>
 
-        <jar jarfile="${release_dir}/package/beast.package.${version}.jar">
+        <jar jarfile="${release_dir}/package/beast.package.${version}.zip">
             <fileset dir="${release_dir}/package">
                 <include name="version.xml" />
                 <include name="lib/beast.jar" />
@@ -237,7 +240,7 @@
     <property name="version" value="2.4.0" />
     <property name="version_number" value="2.4.0" />
     <property name="release_dir" value="release" />
-    <property name="copyright" value="Beast 2 development team 2011-2015" />
+    <property name="copyright" value="Beast 2 development team 2011-2016" />
 
     <property name="BEAST_name" value="BEAST" />
     <property name="beast_name" value="beast" />
@@ -379,6 +382,7 @@
         <zip destfile="${Windows_dir}/${BEAST_name}.v${version}.zip">
             <zipfileset dir="${Windows_package_dir}" prefix="${BEAST_name}" />
         </zip>
+       <copy file="${Windows_dir}/${BEAST_name}.v${version}.zip" todir="../../tmp/" />
 
         <echo message="Windows version release is finished." />
     </target>
@@ -441,10 +445,14 @@
             </tar>-->
         <!-- [ANT Bug 550] the tar task change the mode of the executables files, have to tar manaully -->
         <echo message="Have to tar manaully, because [ANT Bug 550] the tar task change the mode of the executables files." />
-        <!-- tar -cvzf BEASTv1.x.x.tgz BEASTv1.x.x/ -->
-        <!-- cksum BEASTv1.x.x.tgz -->
-        <!-- tar -xvzf BEASTv1.x.x.tgz -->
+        <!-- tar -cvzf BEASTv1.x.x.tgz BEASTv2.x.x/ -->
+        <!-- cksum BEASTv2.x.x.tgz -->
+        <!-- tar -xvzf BEASTv2.x.x.tgz -->
         <echo message="Linux/Unix version release is finished." />
+        
+        <echo message="cd release/Linux"/>
+        <echo message="tar fcz BEAST.v${version}.tgz beast"/>
+        <echo message="cp BEAST.v${version}.tgz ~/tmp"/>
     </target>
 
     <!-- Define the appbundler task -->
@@ -661,6 +669,9 @@
         </exec>
 
         <delete file="${Mac_dir}/pack.temp.dmg"/>
+        
+       <copy file="${Mac_dir}/${BEAST_name} v${version}.dmg" tofile="../../tmp/${Mac_dir}/${BEAST_name}.v${version}.dmg" />
+
 
         <echo message="Mac version release is finished." />
     </target>
diff --git a/examples/testUCLNclock.json b/examples/testUCLNclock.json
index 7f90251..5bfbeb6 100644
--- a/examples/testUCLNclock.json
+++ b/examples/testUCLNclock.json
@@ -1,4 +1,4 @@
-{version: "2.3",
+{version: "2.4",
 namespace: "beast.core:beast.evolution.alignment:beast.evolution.tree.coalescent:beast.core.util:beast.evolution.nuc:beast.evolution.operators:beast.evolution.sitemodel:beast.evolution.substitutionmodel:beast.evolution.likelihood",
 
 beast: [
diff --git a/release/Linux/bin/beast b/release/Linux/bin/beast
index c6ee8c9..c947df4 100755
--- a/release/Linux/bin/beast
+++ b/release/Linux/bin/beast
@@ -29,4 +29,21 @@ if [ -z "$JAVA_HOME" ]; then
 else
   JAVA=$JAVA_HOME/bin/java
 fi
-$JAVA -Xms64m -Xmx4g -cp "$BEAST_LIB/launcher.jar" beast.app.beastapp.BeastLauncher $*
+
+
+# use BEAGL_LIB if the BEAGLE library is not in a standard location
+if [ -n "$BEAGLE_LIB" ]; then
+	if [ -n "$BEAST_EXTRA_LIBS" ]; then
+		BEAST_EXTRA_LIBS=$BEAST_EXTRA_LIBS:$BEAGLE_LIB
+	else
+		BEAST_EXTRA_LIBS=$BEAGLE_LIB
+	fi
+fi
+
+# use BEAST_EXTRA_LIBS variable to load BEAGLE and other libraries from non-default locations 
+# this assumes that the library path contains all these libraries (or are set through LD_LIBRARY_PATH)
+if [ -n "$BEAST_EXTRA_LIBS" ]; then 
+  $JAVA -Xms64m -Xmx4g -Djava.library.path=$BEAST_EXTRA_LIBS -cp "$BEAST_LIB/launcher.jar" beast.app.beastapp.BeastLauncher $*
+else	
+  $JAVA -Xms64m -Xmx4g -cp "$BEAST_LIB/launcher.jar" beast.app.beastapp.BeastLauncher $*
+fi
diff --git a/release/Mac/install.png b/release/Mac/install.png
index a409bf5..5649f43 100755
Binary files a/release/Mac/install.png and b/release/Mac/install.png differ
diff --git a/release/Windows/AppStore_launch4j.xml b/release/Windows/AppStore_launch4j.xml
index 0861c65..7426414 100644
--- a/release/Windows/AppStore_launch4j.xml
+++ b/release/Windows/AppStore_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>AppStore</fileDescription>
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>AppStore</productName>
     <internalName>AppStore</internalName>
     <originalFilename>AppStore.exe</originalFilename>
diff --git a/release/Windows/BEAST_launch4j.xml b/release/Windows/BEAST_launch4j.xml
index 5e7d5ca..ae6145c 100644
--- a/release/Windows/BEAST_launch4j.xml
+++ b/release/Windows/BEAST_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>BEAST2</fileDescription>    
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>BEAST2</productName>
     <internalName>BEAST2</internalName>
     <originalFilename>BEAST2.exe</originalFilename>    
diff --git a/release/Windows/BEAUti_launch4j.xml b/release/Windows/BEAUti_launch4j.xml
index e7b1f5d..c806677 100644
--- a/release/Windows/BEAUti_launch4j.xml
+++ b/release/Windows/BEAUti_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>BEAUti2</fileDescription>
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>BEAUti2</productName>
     <internalName>BEAUti2</internalName>
     <originalFilename>BEAUti2.exe</originalFilename>    
diff --git a/release/Windows/LogCombiner_launch4j.xml b/release/Windows/LogCombiner_launch4j.xml
index 40e6fff..acf9b92 100644
--- a/release/Windows/LogCombiner_launch4j.xml
+++ b/release/Windows/LogCombiner_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>LogCombiner</fileDescription>    
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>LogCombiner</productName>
     <internalName>LogCombiner</internalName>
     <originalFilename>LogCombiner.exe</originalFilename>    
diff --git a/release/Windows/TreeAnnotator_launch4j.xml b/release/Windows/TreeAnnotator_launch4j.xml
index 02982d1..be58c4f 100644
--- a/release/Windows/TreeAnnotator_launch4j.xml
+++ b/release/Windows/TreeAnnotator_launch4j.xml
@@ -12,7 +12,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>TreeAnnotator</fileDescription>    
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>TreeAnnotator</productName>
     <internalName>TreeAnnotator</internalName>
     <originalFilename>TreeAnnotator.exe</originalFilename>    
diff --git a/release/common/README.txt b/release/common/README.txt
index a19fbfb..bf68ffb 100644
--- a/release/common/README.txt
+++ b/release/common/README.txt
@@ -1,7 +1,7 @@
-                    BEAST v2.3.2 2015
-                 Beast 2 development team 2011-2015
+                    BEAST v2.4.0 2016
+                 Beast 2 development team 2011-2016
 
-Last updated: December 2015
+Last updated: March 2016
 
 Contents:
 1) INTRODUCTION
diff --git a/release/common/VERSION HISTORY.txt b/release/common/VERSION HISTORY.txt
index d5399e0..77610f2 100644
--- a/release/common/VERSION HISTORY.txt	
+++ b/release/common/VERSION HISTORY.txt	
@@ -1,10 +1,33 @@
-                    BEAST v2.3.2 2015
-                 Beast 2 development team 2011-2015
+                    BEAST v2.4.0 2016
+                 Beast 2 development team 2011-2016
 Version History
-Last updated: December 2015
+Last updated: March 2016
 
 All issues can be viewed at https://github.com/CompEvol/beast2/issues
 ================================================================================
+Version 2.4.0 February 2016
+    BEAST improved performance
+        up to 2x faster when using proportion invariant sites
+        improved threading support        
+        "instances" flag replaces beagle_instances
+        faster MRCAPrior handling
+        StartBeastStartState works with calibrations with other than CalibratedYule
+    
+    BEAUti
+        show mean of parametric distributions in priors panel
+        better taxon management preventing adding numbers to taxon names 
+        improved layout tip dates panel
+        improved package list errors
+        *BEAST clock cloning fix
+        Allow setting branch length as substitution option on tree logger
+        Improved JSON support
+        
+    Package manager
+       Allow BEAST to be upgraded as a package
+       Improved GUI
+    
+    For developers: http://beast2.org/2016/02/04/what-will-change-in-v2-4-0-for-developers/
+
 Version 2.3.2 December 2015
 	BEAUti
 		path corrected so Standard and StarBeast templates are visible under templates menu
diff --git a/src/beast/app/BEASTVersion.java b/src/beast/app/BEASTVersion.java
index 239cefa..999d551 100644
--- a/src/beast/app/BEASTVersion.java
+++ b/src/beast/app/BEASTVersion.java
@@ -19,9 +19,9 @@ public class BEASTVersion extends Version {
     /**
      * Version string: assumed to be in format x.x.x
      */
-    private static final String VERSION = "2.3.2";
+    private static final String VERSION = "2.4.0";
 
-    private static final String DATE_STRING = "2002-2015";
+    private static final String DATE_STRING = "2002-2016";
 
     private static final boolean IS_PRERELEASE = true;
 
diff --git a/src/beast/app/beastapp/BeastLauncher.java b/src/beast/app/beastapp/BeastLauncher.java
index 84b9515..c162ab0 100644
--- a/src/beast/app/beastapp/BeastLauncher.java
+++ b/src/beast/app/beastapp/BeastLauncher.java
@@ -1,34 +1,39 @@
 package beast.app.beastapp;
 
 
+
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.net.URLDecoder;
-import java.nio.file.Files;
 
 import javax.swing.JOptionPane;
 
 import beast.app.BEASTVersion;
 import beast.app.util.Utils;
-import beast.core.util.Log;
+import beast.app.util.Utils6;
 
 
 /**
  * Loads beast.jar and launches BEAST through the BEASTMain class
  * 
  * This class should be compiled against 1.6 and packaged by itself. The
- * remained of BEAST can be compiled against Java 1.8
+ * remainder of BEAST can be compiled against Java 1.8
  * **/
 public class BeastLauncher {
 
 	public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
 		if (javaVersionCheck("BEAST")) {
 			loadBEASTJars();
+			Utils.testCudaStatusOnMac();
 			BeastMain.main(args);
 		}
 	}
@@ -51,7 +56,7 @@ public class BeastLauncher {
 		String launcherJar = clu.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
 		// deal with special characters and spaces in path
 		launcherJar = URLDecoder.decode(launcherJar, "UTF-8");
-		Log.warning.println("jardir = " + launcherJar);
+		System.err.println("jardir = " + launcherJar);
 		File jarDir0 = new File(launcherJar).getParentFile();
 		while ((!foundOne) && (jarDir0 != null)) { // && jarDir0.exists() &&
 											// jarDir0.isDirectory()) {
@@ -67,7 +72,7 @@ public class BeastLauncher {
 		}
 		
 		if (!foundOne) {
-			Log.warning.println("WARNING: could not find beast.jar");
+			System.err.println("WARNING: could not find beast.jar");
 			// if beast.jar or its classes are not already in the class path (as is when launched e.g. as developer)
 			// the next line will fail
 		}
@@ -80,6 +85,10 @@ public class BeastLauncher {
 
 	private static void createBeastPackage(File jarDir0, String pathDelimiter) {
 		try {
+	        if (jarDir0.toString().toLowerCase().endsWith("lib")) {
+	        	jarDir0 = jarDir0.getParentFile();
+	        }
+
 			// create package user dir, if it not already exists
 	        File dir = new File(getPackageUserDir() + pathDelimiter + "BEAST" + pathDelimiter + "lib");
 	        if (!dir.exists()) {
@@ -91,17 +100,17 @@ public class BeastLauncher {
 	        
 	        File beastJar = new File(jarDir0 + pathDelimiter + "lib" + pathDelimiter + "beast.jar");
 	        File target = new File(dir + pathDelimiter + "beast.jar");
-	        Files.copy(beastJar.toPath(), target.toPath());
+	        copyFileUsingStream(beastJar, target);
 	        
 	        String version = "<addon name='BEAST' version='" + (new BEASTVersion()).getVersion() + "'>\n" +
 	        		"</addon>";
-	        FileWriter outfile = new FileWriter(getPackageUserDir() + pathDelimiter + "beast" + pathDelimiter + "version.xml");
+	        FileWriter outfile = new FileWriter(getPackageUserDir() + pathDelimiter + "BEAST" + pathDelimiter + "version.xml");
 	        outfile.write(version);
 	        outfile.close();
 
 	        File beastSrcJar = new File(jarDir0 + pathDelimiter + "lib" + pathDelimiter + "beast.src.jar");
 	        File srcTarget = new File(dir + pathDelimiter + "beast.src.jar");
-	        Files.copy(beastSrcJar.toPath(), srcTarget.toPath());
+	        copyFileUsingStream(beastSrcJar, srcTarget);
 
 	        // TODO: include templates?
 	        // if so, how to prevent clashes with templates in package and in installation dir?
@@ -112,9 +121,27 @@ public class BeastLauncher {
 		}
 
 	}
-
+	
+	// copy files using Java 6 code
+	private static void copyFileUsingStream(File source, File dest) throws IOException {
+
+	    InputStream is = null;
+	    OutputStream os = null;
+	    try {
+	        is = new FileInputStream(source);
+	        os = new FileOutputStream(dest);
+	        byte[] buffer = new byte[1024];
+	        int length;
+	        while ((length = is.read(buffer)) > 0) {
+	            os.write(buffer, 0, length);
+	        }
+	    } finally {
+	        is.close();
+	        os.close();
+	    }
+	}
 	private static boolean checkForBEAST(File jarDir, Object clu) throws IOException {
-		Log.warning.println("Checking out " + jarDir.getAbsolutePath());
+		System.err.println("Checking out " + jarDir.getAbsolutePath());
 		boolean foundOne = false;
 		if (jarDir.exists()) {
 			URL url = new URL("file://" + (isWindows() ? "/" : "") + jarDir.getAbsolutePath() + "/beast.jar");
@@ -127,7 +154,7 @@ public class BeastLauncher {
 					Method method = sysclass.getDeclaredMethod("addURL", parameters);
 					method.setAccessible(true);
 					method.invoke(sysLoader, new Object[] { url });
-					Log.warning.println("Loaded URL " + url);
+					System.err.println("Loaded URL " + url);
 					foundOne = true;
 				} catch (Throwable t) {
 					t.printStackTrace();
@@ -171,7 +198,7 @@ public class BeastLauncher {
 					} else {
 						JAVA_VERSION_MSG = JAVA_VERSION_MSG.replaceAll("<br>", "\n");
 						JAVA_VERSION_MSG = JAVA_VERSION_MSG.replaceAll("<[^<]*>", "");
-						Log.warning.println(JAVA_VERSION_MSG);
+						System.err.println(JAVA_VERSION_MSG);
 					}
 					return true;
 				}
@@ -189,14 +216,13 @@ public class BeastLauncher {
 	}
 
     public static String getPackageUserDir() {
-        
         if (System.getProperty("beast.user.package.dir") != null)
             return System.getProperty("beast.user.package.dir");
         
-        if (Utils.isWindows()) {
+        if (Utils6.isWindows()) {
             return System.getProperty("user.home") + "\\BEAST\\" + (new BEASTVersion()).getMajorVersion();
         }
-        if (Utils.isMac()) {
+        if (Utils6.isMac()) {
             return System.getProperty("user.home") + "/Library/Application Support/BEAST/" + (new BEASTVersion()).getMajorVersion();
         }
         // Linux and unices
diff --git a/src/beast/app/beastapp/BeastMain.java b/src/beast/app/beastapp/BeastMain.java
index 51ba2b6..b7f1807 100644
--- a/src/beast/app/beastapp/BeastMain.java
+++ b/src/beast/app/beastapp/BeastMain.java
@@ -257,7 +257,7 @@ public class BeastMain {
                         new Arguments.Option("validate", "Parse the XML, but do not run -- useful for debugging XML"),
                         // RRB: not sure what effect this option has
                         new Arguments.IntegerOption("errors", "Specify maximum number of numerical errors before stopping"),
-                        new Arguments.IntegerOption("threads", "The number of computational threads to use (default auto)"),
+                        new Arguments.IntegerOption("threads", "The number of computational threads to use (default 1), -1 for number of cores"),
                         new Arguments.Option("java", "Use Java only, no native implementations"),
                         new Arguments.Option("noerr", "Suppress all output to standard error"),
                         new Arguments.StringOption("loglevel", "LEVEL", "error,warning,info,debug,trace"),
@@ -273,6 +273,7 @@ public class BeastMain {
                         new Arguments.StringOption("beagle_scaling", new String[]{"default", "none", "dynamic", "always"},
                                 false, "BEAGLE: specify scaling scheme to use"),
                         new Arguments.Option("help", "Print this information and stop"),
+                        new Arguments.Option("version", "Print version and stop"),
                 });
 
         try {
@@ -285,6 +286,11 @@ public class BeastMain {
             System.exit(1);
         }
 
+        if (arguments.hasOption("version")) {
+        	Log.info.println((new BEASTVersion()).getVersionString());
+        	System.exit(0);
+        }
+
         if (arguments.hasOption("help")) {
             printUsage(arguments);
             System.exit(0);
@@ -304,7 +310,7 @@ public class BeastMain {
         long seed = Randomizer.getSeed();
         boolean useJava = false;
 
-        int threadCount = 0;
+        int threadCount = 1;
 
         if (arguments.hasOption("java")) {
             useJava = true;
diff --git a/src/beast/app/beauti/AlignmentListInputEditor.java b/src/beast/app/beauti/AlignmentListInputEditor.java
index 24cc766..41997cc 100644
--- a/src/beast/app/beauti/AlignmentListInputEditor.java
+++ b/src/beast/app/beauti/AlignmentListInputEditor.java
@@ -711,33 +711,31 @@ public class AlignmentListInputEditor extends ListInputEditor {
 				} else {
 					comp.setBackground(Color.white);
 				}
-			    JComponent jcomp = (JComponent)comp;
-			    if (comp == jcomp) {
-			    	switch (Index_col) {
-			    	case NAME_COLUMN:			    		
-		    		case CLOCKMODEL_COLUMN: 
-		    		case TREE_COLUMN: 
-		    		case SITEMODEL_COLUMN: 
-				        jcomp.setToolTipText("Set " + table.getColumnName(Index_col).toLowerCase() + " for this partition");
-						break;
-		    		case FILE_COLUMN:
-		    		case TAXA_COLUMN:
-		    		case SITES_COLUMN:
-		    		case TYPE_COLUMN:
-				        jcomp.setToolTipText("Report " + table.getColumnName(Index_col).toLowerCase() + " for this partition");
-						break;
-		    		case USE_AMBIGUITIES_COLUMN: 
-						jcomp.setToolTipText("<html>Flag whether to use ambiguities.<br>" +
-								"If not set, the treelikelihood will treat ambiguities in the<br>" +
-								"data as unknowns<br>" +
-								"If set, the treelikelihood will use ambiguities as equally<br>" +
-								"likely values for the tips.<br>" +
-								"This will make the computation twice as slow.</html>");
-						break;
-					default:
-				        jcomp.setToolTipText(null);
-			    	}
-			    }
+			    JComponent jcomp = (JComponent) comp;
+		    	switch (Index_col) {
+		    	case NAME_COLUMN:			    		
+	    		case CLOCKMODEL_COLUMN: 
+	    		case TREE_COLUMN: 
+	    		case SITEMODEL_COLUMN: 
+			        jcomp.setToolTipText("Set " + table.getColumnName(Index_col).toLowerCase() + " for this partition");
+					break;
+	    		case FILE_COLUMN:
+	    		case TAXA_COLUMN:
+	    		case SITES_COLUMN:
+	    		case TYPE_COLUMN:
+			        jcomp.setToolTipText("Report " + table.getColumnName(Index_col).toLowerCase() + " for this partition");
+					break;
+	    		case USE_AMBIGUITIES_COLUMN: 
+					jcomp.setToolTipText("<html>Flag whether to use ambiguities.<br>" +
+							"If not set, the treelikelihood will treat ambiguities in the<br>" +
+							"data as unknowns<br>" +
+							"If set, the treelikelihood will use ambiguities as equally<br>" +
+							"likely values for the tips.<br>" +
+							"This will make the computation twice as slow.</html>");
+					break;
+				default:
+			        jcomp.setToolTipText(null);
+		    	}
 				updateStatus();
 				return comp;
 			}
diff --git a/src/beast/app/beauti/Beauti.java b/src/beast/app/beauti/Beauti.java
index 5137330..3842a55 100644
--- a/src/beast/app/beauti/Beauti.java
+++ b/src/beast/app/beauti/Beauti.java
@@ -81,7 +81,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
     static public final String FILE_EXT = ".xml";
     static public final String FILE_EXT2 = ".json";
     static final String fileSep = System.getProperty("file.separator");
-    
+
     /**
      * document in document-view pattern. BTW this class is the view
      */
@@ -318,7 +318,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
         @Override
 		public void actionPerformed(ActionEvent ae) {
             File file = beast.app.util.Utils.getLoadFile("Load Beast XML File",
-                    new File(g_sDir), "Beast XML files", "xml");
+                    new File(g_sDir), "Beast XML files", "xml");//, "BEAST json file", "json");
             // JFileChooser fileChooser = new JFileChooser(g_sDir);
             // fileChooser.addChoosableFileFilter(ef1);
             // fileChooser.setDialogTitle("Load Beast XML File");
@@ -338,6 +338,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                             doc.getFileName().lastIndexOf(fileSep));
                 }
                 try {
+                	// TODO: deal with json files
                     doc.loadXML(new File(doc.getFileName()));
                     a_save.setEnabled(true);
                     a_saveas.setEnabled(true);
@@ -607,7 +608,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
         }
     } // class ActionHelp
-    
+
     class ActionMsgs extends MyAction {
         private static final long serialVersionUID = -1;
 
@@ -629,7 +630,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
 	        	JScrollPane scroller = new JScrollPane(textArea);
 	        	JOptionPane.showMessageDialog(frame, scroller);
         	}
-        }    	
+        }
     }
 
     class ActionCitation extends MyAction implements ClipboardOwner {
@@ -964,7 +965,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                                 fileName = fileName.substring(0, fileName.length() - 4);
                                 boolean duplicate = false;
                             	for (AbstractAction action : actions) {
-                            		String name = action.getValue(Action.NAME).toString(); 
+                            		String name = action.getValue(Action.NAME).toString();
                             		if (name.equals(fileName)) {
                             			duplicate = true;
                             		}
@@ -990,12 +991,12 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
         	if (new File(exampledir).exists()) {
 	        	AbstractAction action = new AbstractAction() {
 					private static final long serialVersionUID = 1L;
-	
+
 					@Override
 					public void actionPerformed(ActionEvent e) {
 						g_sDir = dir;
 					}
-	            	
+
 	            };
 	            String workDirInfo = "Set working directory to " + dir;
 	            String name = dir;
@@ -1085,10 +1086,32 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
     	return BEAUtiIntances > 0;
     }
 
+    private static String usage() {
+        return "java Beauti [options]\n" + "where options can be one of the following:\n"
+                + "-template [template file] : BEAUti template to be used. Default templates/Standard.xml\n"
+        		+ "-nex [nexus data file] : nexus file to be read using template, multiple -nex arguments are allowed\n"
+                + "-xmldat [beast xml file] : as -nex but with BEAST 1 or 2 xml file instead of nexus file\n"
+                + "-xml [beast file] : BEAST 2 XML file to be loaded\n"
+                + "-exitaction [writexml|usetemplate|usexml] : what to do after processing arguments\n"
+                + "-out [output file name] : file to be written\n"
+                + "-capture : captures stdout and stderr and make them available under Help/Messages menu\n"
+                + "-v, -version : print version\n"
+                + "-h, -help : print this help message\n";
+    }
+
+
     public static Beauti main2(String[] args) {
         try {
         	ByteArrayOutputStream baos = null;
             for (String arg : args) {
+            	if (arg.equals("-v") || arg.equals("-version")) {
+                    System.out.println((new BEASTVersion()).getVersionString());
+                    System.exit(0);
+            	}
+            	if (arg.equals("-h") || arg.equals("-help")) {
+                    System.out.println(usage());
+                    System.exit(0);
+            	}
             	if (arg.equals("-capture")) {
             		final PrintStream beautiLog = System.err;
                 	baos = new ByteArrayOutputStream() {
@@ -1103,26 +1126,26 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                 			super.write(b);
                 			beautiLog.write(b);
                 		};
-                		
+
                 		@Override
                 		public void write(byte[] b) throws java.io.IOException {
                 			super.write(b);
                 			beautiLog.write(b);
                 		};
-                		
+
                 		@Override
                 		public void flush() throws java.io.IOException {
                 			super.flush();
                 			beautiLog.flush();
                 		};
-                		
+
                 		@Override
                 		public void close() throws IOException {
                 			super.close();
                 			beautiLog.close();
                 		}
                 	};
-                	
+
                 	PrintStream p = new PrintStream(baos);
                 	System.setOut(p);
                 	System.setErr(p);
@@ -1133,7 +1156,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                 	Log.trace = p;
             	}
             }
-        	
+
             AddOnManager.loadExternalJars();
             if (!Utils.isMac()) {
             	Utils.loadUIManager();
diff --git a/src/beast/app/beauti/BeautiAlignmentProvider.java b/src/beast/app/beauti/BeautiAlignmentProvider.java
index 94a03cb..66e4fac 100644
--- a/src/beast/app/beauti/BeautiAlignmentProvider.java
+++ b/src/beast/app/beauti/BeautiAlignmentProvider.java
@@ -54,7 +54,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
 	 * return amount to which the provided matches an alignment 
 	 * The provider with the highest match will be used to edit the alignment 
 	 * */
-	int matches(Alignment alignment) {
+	protected int matches(Alignment alignment) {
 		return 1;
 	}
 	
@@ -161,6 +161,11 @@ public class BeautiAlignmentProvider extends BEASTObject {
                     break;
 			}
         }
+        addAlignments(doc, selectedBEASTObjects);
+        return selectedBEASTObjects;
+    }
+    
+    protected void addAlignments(BeautiDoc doc, List<BEASTInterface> selectedBEASTObjects) {
         for (BEASTInterface beastObject : selectedBEASTObjects) {
         	// ensure ID of alignment is unique
         	int k = 0;
@@ -173,7 +178,6 @@ public class BeautiAlignmentProvider extends BEASTObject {
         	sortByTaxonName(((Alignment) beastObject).sequenceInput.get());
             doc.addAlignmentWithSubnet((Alignment) beastObject, getStartTemplate());
         }
-        return selectedBEASTObjects;
     }
 
 	/** provide GUI for manipulating the alignment **/
@@ -196,11 +200,11 @@ public class BeautiAlignmentProvider extends BEASTObject {
 	
 	/** return template to apply to this new alignment.
 	 * By default, the partition template of the current beauti template is returned **/
-	BeautiSubTemplate getStartTemplate() {
+	protected BeautiSubTemplate getStartTemplate() {
 		return template.get();
 	}
 
-    private void sortByTaxonName(List<Sequence> seqs) {
+    protected void sortByTaxonName(List<Sequence> seqs) {
         Collections.sort(seqs, (Sequence o1, Sequence o2) -> {
                 return o1.taxonInput.get().compareTo(o2.taxonInput.get());
             }
diff --git a/src/beast/app/beauti/BeautiDoc.java b/src/beast/app/beauti/BeautiDoc.java
index 0574181..b58f7bf 100644
--- a/src/beast/app/beauti/BeautiDoc.java
+++ b/src/beast/app/beauti/BeautiDoc.java
@@ -101,7 +101,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
      */
 
     public boolean autoSetClockRate = true;
-        
+
     public boolean autoUpdateOperatorWeights = true;
 
     public boolean autoUpdateFixMeanSubstRate = true;
@@ -159,7 +159,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     public Set<Input<?>> linked;
 
     InputEditorFactory inputEditorFactory;
-    
+
     /** used to capture Stdout and Stderr **/
     static ByteArrayOutputStream baos = null;
 
@@ -186,7 +186,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     public String getTemplateName() {
         return templateName;
     }
-    
+
     public ActionOnExit parseArgs(String[] args) throws XMLParserException, SAXException, IOException, ParserConfigurationException  {
         ActionOnExit endState = ActionOnExit.UNKNOWN;
         String outputFileName = "beast.xml";
@@ -200,8 +200,6 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                 int old = i;
                 if (args[i].equals("")) {
                     i += 1;
-                } else if (args[i].equals("-h") || args[i].equals("-help")) {
-                    showUsageAndExit();
                 } else if (args[i].equals("-capture")) {
                 	// capture stderr and stdout
                 	// already done in beast.app.beauti.Beauti
@@ -289,16 +287,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return fileName.substring(0, fileName.length() - 4);
     }
 
-    void showUsageAndExit() {
-        System.out.println(usage());
-        System.exit(0);
-    }
 
-    String usage() {
-        return "java Beauti [options]\n" + "where options can be one of the following:\n"
-                + "-template [template file]\n" + "-nex [nexus data file]\n" + "-xmldat [beast xml file]\n"
-                + "-xml [beast file]\n" + "-out [output file name]\n" + "-exitaction [writexml|usetemplate|usexml]\n";
-    }
 
     private Set<BeautiDocListener> listeners = new HashSet<>();
 
@@ -346,14 +335,14 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         taxaset.remove(beastObject.getID());
         // directly remove beast object from HashMap
         // relies on hashes of String being unique (which they should be).
-        // is much more efficient (O(1)) than lookup in keySet (O(n)), 
-        // which matter when a lot of partitions are loaded 
+        // is much more efficient (O(1)) than lookup in keySet (O(n)),
+        // which matter when a lot of partitions are loaded
         // but less reliable since ID may have changed.
         String id = reversePluginmap.get(beastObject);
         if (id != null && pluginmap.containsKey(id)) {
             pluginmap.remove(id);
         }
-        
+
 //        String oldID = null;
 //        for (String id : pluginmap.keySet()) {
 //            if (pluginmap.get(id).equals(beastObject)) {
@@ -464,12 +453,12 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 //
 //			XMLProducer producer = new XMLProducer();
 //			producer.toRawXML(alignments.get(0));
-//			
+//
 //			Pplugin beastObject =  parser.parseFragment(xml, false);
 //			int i = xml.indexOf("<data");
 //			for (BEASTObject beastObject : pluginmap.values()) {
 //				if (beastObject instanceof Alignment) {
-//					
+//
 //				}
 //			}
 //			save(fileName);
@@ -485,7 +474,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     }
 
     /**
-     * public to allow access for unit test 
+     * public to allow access for unit test
      * @throws IOException *
      */
     public String processTemplate(String fileName) throws IOException {
@@ -714,7 +703,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     } // validateModel
 
     /**
-     * save specification in file 
+     * save specification in file
      * @throws IOException *
      */
     public void save(String fileName) throws IOException  {
@@ -722,7 +711,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     } // save
 
     /**
-     * save specification in file 
+     * save specification in file
      * @throws IOException *
      */
     public void save(File file) throws IOException  {
@@ -815,7 +804,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         beauti.allowLinking.setSelected(allowLinking);
         autoUpdateOperatorWeights = !beautiStatus.contains("noAutoUpdateOperatorWeights");
         beauti.autoUpdateOperatorWeights.setSelected(autoUpdateOperatorWeights);
-        autoUpdateFixMeanSubstRate = !beautiStatus.contains("noAutoUpdateFixMeanSubstRate"); 
+        autoUpdateFixMeanSubstRate = !beautiStatus.contains("noAutoUpdateFixMeanSubstRate");
         beauti.autoUpdateFixMeanSubstRate.setSelected(autoUpdateFixMeanSubstRate);
 
         // parse file
@@ -875,10 +864,10 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
     /**
      * Merge sequence data with xml specification.
-     * @throws ParserConfigurationException 
-     * @throws IOException 
-     * @throws SAXException 
-     * @throws XMLParserException 
+     * @throws ParserConfigurationException
+     * @throws IOException
+     * @throws SAXException
+     * @throws XMLParserException
      */
     void mergeSequences(String xml) throws XMLParserException, SAXException, IOException, ParserConfigurationException {
         if (xml == null) {
@@ -1110,17 +1099,17 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
 
             // set estimate flag on tree, only if tree occurs in a partition
-            for (BEASTInterface beastObject : pluginmap.values()) {
-                if (beastObject instanceof Tree) {
-                    Tree tree = (Tree) beastObject;
-                    tree.isEstimatedInput.setValue(false, tree);
-                }
-            }
-            for (BEASTInterface beastObject : pPartition[2]) {
-                // TODO: this might not be a valid type conversion from TreeInterface to Tree
-                Tree tree = (Tree) ((GenericTreeLikelihood) beastObject).treeInput.get();
-                tree.isEstimatedInput.setValue(true, tree);
-            }
+//            for (BEASTInterface beastObject : pluginmap.values()) {
+//                if (beastObject instanceof Tree) {
+//                    Tree tree = (Tree) beastObject;
+//                    tree.isEstimatedInput.setValue(false, tree);
+//                }
+//            }
+//            for (BEASTInterface beastObject : pPartition[2]) {
+//                // TODO: this might not be a valid type conversion from TreeInterface to Tree
+//                Tree tree = (Tree) ((GenericTreeLikelihood) beastObject).treeInput.get();
+//                tree.isEstimatedInput.setValue(true, tree);
+//            }
             if (pluginmap.containsKey("Tree.t:Species")) {
                 Tree tree = (Tree) pluginmap.get("Tree.t:Species");
                 tree.isEstimatedInput.setValue(true, tree);
@@ -1200,7 +1189,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         } catch (Exception e) {
             Log.err.println(e.getMessage());
         }
-        
+
         if (autoUpdateOperatorWeights) {
         	reweightSpeciesPartitionOperators();
         }
@@ -1213,17 +1202,17 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         if (pluginmap.containsKey("likelihood")) {
             collectPredecessors(pluginmap.get("likelihood"), likelihoodPredecessors);
         }
-        
-                
-        Log.warning.print("InPosterior=");
+
+
+        Log.trace.print("InPosterior=");
         for (BEASTInterface o : posteriorPredecessors) {
         	pluginmap.put(o.getID(), o);
-        	Log.warning.print(o.getID() + " ");
+        	Log.trace.print(o.getID() + " ");
         	//if (!pluginmap.containsKey(o)) {
         	//	System.err.println("MISSING: " + o.getID());
         	//}
         }
-        Log.warning.println();
+        Log.trace.println();
     }
 
     public static String translatePartitionNames(String str, PartitionContext partition) {
@@ -1237,18 +1226,18 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 		for (int i = 0; i < len; i++) {
 			char c = str.charAt(i);
 			if (c == '.' && i < len - 6) {
-				if (str.charAt(i + 2) == ':' && str.charAt(i + 3) == '$' && 
+				if (str.charAt(i + 2) == ':' && str.charAt(i + 3) == '$' &&
 						str.charAt(i + 4) == '(' && str.charAt(i + 5) == 'n' && str.charAt(i + 6) == ')') {
 					switch (str.charAt(i+1)) {
 					case 's': // .s:$(n)
 						sb.append(".s:").append(partition.siteModel);
 						i += 6;
 						break;
-					case 'c': 
+					case 'c':
 						sb.append(".c:").append(partition.clockModel);
 						i += 6;
 						break;
-					case 't': 
+					case 't':
 						sb.append(".t:").append(partition.tree);
 						i += 6;
 						break;
@@ -1323,7 +1312,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 	            }
 	        }
         }
-    	
+
         BEASTInterface likelihood = pluginmap.get("likelihood");
         if (likelihood instanceof CompoundDistribution) {
             int i = 0;
@@ -1494,15 +1483,15 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     }
 
     /**
-      * Reweight total weight of operators that work on the Species partition to 20% 
+      * Reweight total weight of operators that work on the Species partition to 20%
       * of total operator weights. This helps *BEAST analyses in convergence. For non
-      * *BEAST analyses, this bit of code has no effect. 
+      * *BEAST analyses, this bit of code has no effect.
       */
     private void reweightSpeciesPartitionOperators() {
     	if (!(mcmc.get() instanceof MCMC)) {
     		return;
     	}
-    	List<Operator> speciesOperators = new ArrayList<>(); 
+    	List<Operator> speciesOperators = new ArrayList<>();
     	double totalWeight = 0;
     	double speciesWeight = 0;
     	for (Operator operator : ((MCMC)mcmc.get()).operatorsInput.get()) {
@@ -1512,7 +1501,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 			}
 			totalWeight += operator.getWeight();
     	}
-    	
+
     	if (speciesWeight > 0 && speciesWeight < totalWeight) {
     		// we have a Species-related operator AND an alignment
     		// rescale weights so that 20% of operator weights is dedicated to Species operators
@@ -1523,7 +1512,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     			operator.m_pWeight.setValue(scale * operator.getWeight(), operator);
     		}
     	}
-		
+
 	}
 
 	public BEASTInterface addAlignmentWithSubnet(PartitionContext context, BeautiSubTemplate template)  {
@@ -1910,7 +1899,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                             	Object o2 = copy.getInput(input.getName()).get();
                             	boolean alreadyInList = false;
                             	if (o2 instanceof List) {
-                            		List<?> currentList = (List<?>) o2; 
+                            		List<?> currentList = (List<?>) o2;
 	                            	for (Object v : currentList) {
 	                            		if (v == value) {
 	                            			alreadyInList = true;
@@ -2419,7 +2408,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     }
 
     /** create taxonset, one taxon for each sequence in the alignment
-     * and assign taxonset to the alignment 
+     * and assign taxonset to the alignment
      * **/
     static void createTaxonSet(Alignment a, BeautiDoc doc) {
 		List<String> taxaNames = a.getTaxaNames();
@@ -2436,7 +2425,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 		doc.registerPlugin(taxonset);
 	}
 
-    /** create Taxon with given name, reuse if a taxon 
+    /** create Taxon with given name, reuse if a taxon
      *  with this name already exists
      **/
 	public Taxon getTaxon(String taxaName) {
diff --git a/src/beast/app/beauti/BeautiLauncher.java b/src/beast/app/beauti/BeautiLauncher.java
index ad06a68..f326e8c 100644
--- a/src/beast/app/beauti/BeautiLauncher.java
+++ b/src/beast/app/beauti/BeautiLauncher.java
@@ -5,6 +5,7 @@ import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 
 import beast.app.beastapp.BeastLauncher;
+import beast.app.util.Utils;
 import beast.app.util.Utils6;
 
 /** 
@@ -19,6 +20,7 @@ public class BeautiLauncher extends BeastLauncher {
 		Utils6.startSplashScreen();
 		if (javaVersionCheck("BEAUti")) {
 			loadBEASTJars();
+			Utils.testCudaStatusOnMac();
 			Beauti.main(args);
 		}
         Utils6.endSplashScreen();
diff --git a/src/beast/app/beauti/BeautiPanelConfig.java b/src/beast/app/beauti/BeautiPanelConfig.java
index 3e7efde..5b52baa 100644
--- a/src/beast/app/beauti/BeautiPanelConfig.java
+++ b/src/beast/app/beauti/BeautiPanelConfig.java
@@ -32,7 +32,7 @@ public class BeautiPanelConfig extends BEASTObject {
             "distribution/distribution[id='posterior']/traitset all posterior inputs with name traitset", Validate.REQUIRED);
 
     final public Input<Partition> hasPartitionsInput = new Input<>("hasPartitions", "flag to indicate the panel has" +
-            "a partition context (and hence a partition list), deafult none.  Possible values: " + Partition.values(), Partition.none, Partition.values());
+            "a partition context (and hence a partition list), deafult none.  Possible values: " + Arrays.toString(Partition.values()), Partition.none, Partition.values());
 
     final public Input<Boolean> addButtonsInput = new Input<>("addButtons", "flag to indicate buttons should be added, default true", true);
     final public Input<Boolean> isVisibleInput = new Input<>("isVisible", "flag to indicate panel is visible on startup, default true", true);
diff --git a/src/beast/app/beauti/GuessPatternDialog.java b/src/beast/app/beauti/GuessPatternDialog.java
index 48a54dc..88b61ac 100644
--- a/src/beast/app/beauti/GuessPatternDialog.java
+++ b/src/beast/app/beauti/GuessPatternDialog.java
@@ -540,14 +540,15 @@ public class GuessPatternDialog extends JDialog {
             try {
                 BufferedReader fin = new BufferedReader(new FileReader(txtFile.getText()));
                 StringBuffer buf = new StringBuffer();
-                // eat up header
-                fin.readLine();
+                // do not eat up header -- it might contain a useful entry, 
+                // but if not, it will not hurt
+                // fin.readLine();
                 // process data
                 while (fin.ready()) {
                     String str = fin.readLine();
                     str = str.replaceFirst("\t", "=") + ",";
                     // only add entries that are non-empty
-                    if (!str.matches("^\\s+=.*$")) {
+                    if (str.indexOf("=") > 0 && !str.matches("^\\s+=.*$")) {
                         buf.append(str);
                     }
                 }
@@ -556,6 +557,11 @@ public class GuessPatternDialog extends JDialog {
                 while (trait.endsWith(",")) {
                     trait = trait.substring(0, trait.length() - 1).trim();
                 }
+                
+               if (trait.trim().length() == 0) {
+            	   JOptionPane.showMessageDialog(m_parent, "Could not find traint information in the file. " +
+            			   "Perhaps this is not a tab-delimited but space file?");
+               }
             } catch (Exception e) {
                 JOptionPane.showMessageDialog(m_parent, "Loading trait from file failed:" + e.getMessage());
                 return Status.canceled;
diff --git a/src/beast/app/beauti/JPackageDialog.java b/src/beast/app/beauti/JPackageDialog.java
index 61467c2..ebcae34 100644
--- a/src/beast/app/beauti/JPackageDialog.java
+++ b/src/beast/app/beauti/JPackageDialog.java
@@ -37,13 +37,13 @@ public class JPackageDialog extends JPanel {
     PackageTable dataTable = null;
 
     TreeMap<String, Package> packageMap = new TreeMap<>((s1,s2)->{
-    	if (s1.equals(AddOnManager.BEAST_PACKAGE)) {
-    		if (s2.equals(AddOnManager.BEAST_PACKAGE)) {
+    	if (s1.equals(AddOnManager.BEAST_PACKAGE_NAME)) {
+    		if (s2.equals(AddOnManager.BEAST_PACKAGE_NAME)) {
     			return 0;
     		}
     		return -1;
     	}
-    	if (s2.equals(AddOnManager.BEAST_PACKAGE)) {
+    	if (s2.equals(AddOnManager.BEAST_PACKAGE_NAME)) {
     		return 1;
     	}
     	return s1.compareToIgnoreCase(s2);
diff --git a/src/beast/app/beauti/TaxonSetInputEditor.java b/src/beast/app/beauti/TaxonSetInputEditor.java
index baf4dbe..4eda6c9 100644
--- a/src/beast/app/beauti/TaxonSetInputEditor.java
+++ b/src/beast/app/beauti/TaxonSetInputEditor.java
@@ -316,8 +316,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
         for (Alignment alignment : getDoc().alignments) {
         	for (String id : alignment.getTaxaNames()) {
                 if (!taxonIDs.contains(id)) {
-	                Taxon taxon = new Taxon();
-	                taxon.setID(id);
+                	Taxon taxon = getDoc().getTaxon(id);
 	                taxa.add(taxon);
 	                taxonIDs.add(id);
         		}
@@ -325,12 +324,11 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             for (Sequence sequence : alignment.sequenceInput.get()) {
                 String id = sequence.taxonInput.get();
                 if (!taxonIDs.contains(id)) {
-                    Taxon taxon = new Taxon();
+                    Taxon taxon = getDoc().getTaxon(sequence.taxonInput.get());
                     // ensure sequence and taxon do not get same ID
                     if (sequence.getID().equals(sequence.taxonInput.get())) {
                         sequence.setID("_" + sequence.getID());
                     }
-                    taxon.setID(sequence.taxonInput.get());
                     taxa.add(taxon);
                     taxonIDs.add(id);
                 }
@@ -347,8 +345,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
                             TaxonSet set = map.get(match);
                             set.taxonsetInput.setValue(taxon, set);
                         } else {
-                            TaxonSet set = new TaxonSet();
-                            set.setID(match);
+                        	TaxonSet set = newTaxonSet(match);
                             set.taxonsetInput.setValue(taxon, set);
                             map.put(match, set);
                         }
@@ -370,7 +367,23 @@ public class TaxonSetInputEditor extends InputEditor.Base {
         return ignored;
     }
 
-    void parseTrait(String trait) {
+    private TaxonSet newTaxonSet(String match) {
+    	if (getDoc().taxaset.containsKey(match)) {
+    		Taxon t = doc.taxaset.get(match);
+    		if (t instanceof TaxonSet) {
+    			TaxonSet set = (TaxonSet) t;
+    			set.taxonsetInput.get().clear();
+    			return set;
+    		} else {
+    			// TODO handle situation where taxon and set have same name (issue #135)
+    		}
+    	}
+        TaxonSet set = new TaxonSet();
+        set.setID(match);
+		return set;
+	}
+
+	void parseTrait(String trait) {
     	Map<String,String> traitmap = new HashMap<>();
     	for (String line : trait.split(",")) {
     		String [] strs = line.split("=");
@@ -390,12 +403,11 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             for (Sequence sequence : alignment.sequenceInput.get()) {
                 String id = sequence.taxonInput.get();
                 if (!taxonIDs.contains(id)) {
-                    Taxon taxon = new Taxon();
+                    Taxon taxon = getDoc().getTaxon(sequence.taxonInput.get());
                     // ensure sequence and taxon do not get same ID
                     if (sequence.getID().equals(sequence.taxonInput.get())) {
                         sequence.setID("_" + sequence.getID());
                     }
-                    taxon.setID(sequence.taxonInput.get());
                     taxa.add(taxon);
                     taxonIDs.add(id);
                 }
@@ -412,8 +424,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
                             TaxonSet set = map.get(match);
                             set.taxonsetInput.setValue(taxon, set);
                         } else {
-                            TaxonSet set = new TaxonSet();
-                            set.setID(match);
+                            TaxonSet set = newTaxonSet(match);
                             set.taxonsetInput.setValue(taxon, set);
                             map.put(match, set);
                         }
@@ -530,8 +541,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             // new taxon set?
             if (!m_taxonMap.containsValue(taxonSetID)) {
                 // create new taxon set
-                TaxonSet taxonset = new TaxonSet();
-                taxonset.setID(taxonSetID);
+                TaxonSet taxonset = newTaxonSet(taxonSetID);
                 m_taxonset.add(taxonset);
             }
             m_taxonMap.put(lineageID, taxonSetID);
diff --git a/src/beast/app/beauti/TipDatesInputEditor.java b/src/beast/app/beauti/TipDatesInputEditor.java
index 6e611ee..bd656f7 100644
--- a/src/beast/app/beauti/TipDatesInputEditor.java
+++ b/src/beast/app/beauti/TipDatesInputEditor.java
@@ -141,7 +141,7 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
         samplingBox.add(comboBox);
 
         taxonsets = new ArrayList<>();
-        Taxon allTaxa = new Taxon();
+        Taxon allTaxa = getDoc().getTaxon(ALL_TAXA);
         allTaxa.setID(ALL_TAXA);
         taxonsets.add(allTaxa);
         List<String> taxonSetIDs = new ArrayList<>();
diff --git a/src/beast/app/draw/InputEditorFactory.java b/src/beast/app/draw/InputEditorFactory.java
index 711ea6c..10ff44d 100644
--- a/src/beast/app/draw/InputEditorFactory.java
+++ b/src/beast/app/draw/InputEditorFactory.java
@@ -152,7 +152,7 @@ public class InputEditorFactory {
         } else {
         	if (input.get() != null && !input.get().getClass().equals(inputClass)
         			&& !(input.get() instanceof ArrayList)) {
-        		Log.err.println(input.get().getClass() + " != " + inputClass);
+        		Log.trace.println(input.get().getClass() + " != " + inputClass);
         		inputClass = input.get().getClass();
         	}
         }
diff --git a/src/beast/app/draw/ListInputEditor.java b/src/beast/app/draw/ListInputEditor.java
index 0e1b93a..803c550 100644
--- a/src/beast/app/draw/ListInputEditor.java
+++ b/src/beast/app/draw/ListInputEditor.java
@@ -462,7 +462,10 @@ public class ListInputEditor extends InputEditor.Base {
                 BEASTInterface beastObject = (BEASTInterface) ((List<?>) m_input.get()).get(i);
                 beastObject.validateInputs();
                 m_validateLabels.get(i).setVisible(false);
-            } catch (IllegalArgumentException e) {
+            } catch (IndexOutOfBoundsException e) {
+            	// happens when m_validateLabels is not large enough, so there is nothing to show 
+            } catch (Exception e) {
+            	// something went wrong, so show label if available
                 if (m_validateLabels.size() > i) {
                     m_validateLabels.get(i).setToolTipText(e.getMessage());
                     m_validateLabels.get(i).setVisible(true);
diff --git a/src/beast/app/treeannotator/KernelDensityEstimator2D.java b/src/beast/app/treeannotator/KernelDensityEstimator2D.java
index 76a680c..dccb14f 100644
--- a/src/beast/app/treeannotator/KernelDensityEstimator2D.java
+++ b/src/beast/app/treeannotator/KernelDensityEstimator2D.java
@@ -257,7 +257,7 @@ public class KernelDensityEstimator2D implements ContourMaker {
 
         KernelDensityEstimator2D kde = new KernelDensityEstimator2D(x, y, 4);
 
-        System.out.println(kde.getXGrid());
+        System.out.println(Arrays.toString(kde.getXGrid()));
 //        System.out.println(new Vector(kde.getYGrid()));
 //        System.out.println(new Matrix(kde.getKDE()));
         System.exit(-1);
diff --git a/src/beast/app/treeannotator/RealNumberField.java b/src/beast/app/treeannotator/RealNumberField.java
index 72c65c9..506767c 100644
--- a/src/beast/app/treeannotator/RealNumberField.java
+++ b/src/beast/app/treeannotator/RealNumberField.java
@@ -128,7 +128,7 @@ public class RealNumberField extends JTextField implements FocusListener, Docume
         if (value == null && allowEmpty) {
             setText("");
         }
-        if (value == Double.NaN) {
+        if (Double.isNaN(value)) {
             setText(NaN);
         } else if (value == Double.POSITIVE_INFINITY) {
             setText(POSITIVE_INFINITY);
diff --git a/src/beast/app/util/Utils.java b/src/beast/app/util/Utils.java
index e63b6ee..16e571d 100644
--- a/src/beast/app/util/Utils.java
+++ b/src/beast/app/util/Utils.java
@@ -3,6 +3,7 @@ package beast.app.util;
 import java.awt.Component;
 import java.awt.Font;
 import java.awt.Graphics;
+import java.awt.GraphicsEnvironment;
 import java.awt.Image;
 import java.awt.Toolkit;
 import java.io.BufferedReader;
@@ -18,6 +19,7 @@ import java.util.Set;
 
 import javax.swing.ImageIcon;
 import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
 import javax.swing.LookAndFeel;
 import javax.swing.UIManager;
 import javax.swing.UnsupportedLookAndFeelException;
@@ -26,6 +28,13 @@ import javax.swing.filechooser.FileNameExtensionFilter;
 import beast.app.beauti.BeautiPanel;
 import beast.app.beauti.BeautiPanelConfig;
 import beast.core.util.Log;
+import beast.evolution.alignment.Alignment;
+import beast.evolution.alignment.Sequence;
+import beast.evolution.likelihood.BeagleTreeLikelihood;
+import beast.evolution.sitemodel.SiteModel;
+import beast.evolution.substitutionmodel.JukesCantor;
+import beast.util.AddOnManager;
+import beast.util.TreeParser;
 
 /**
  * @author Andrew Rambaut
@@ -320,4 +329,102 @@ public class Utils {
 	    }
 	
 	}
+
+	
+	public static boolean testCudaStatusOnMac() {
+		String cudaStatusOnMac = "<html>It appears you have CUDA installed, but your computer hardware does not support it.<br>"
+				+ "You need to remove CUDA before BEAST/BEAUti can start.<br>"
+				+ "To remove CUDA, delete the following folders by typing in a terminal:<br>"
+				+ "rm -r /Library/Frameworks/CUDA.framework<br>"
+				+ "rm -r /Developer/NVIDIA<br>"
+				+ "rm -r /usr/local/cuda<br>"
+				+ "You may need 'sudo rm' instead of 'rm'</html>";
+				
+		if (isMac()) {
+			// check any of these directories exist
+			// /Library/Frameworks/CUDA.framework
+			// /Developer/NVIDIA
+			// /usr/local/cuda
+			if (new File("/Library/Frameworks/CUDA.framework").exists() ||
+					new File("/Developer/NVIDIA").exists() ||
+					new File("/usr/local/cuda").exists()) {
+				// there is evidence of CUDA being installed on this computer
+				// try to create a BeagleTreeLikelihood using a separate process
+				try {
+				      String java = System.getenv("java.home");
+				      if (java == null) {
+				    	  java ="/usr/bin/java";
+				      } else {
+				    	  java += "/bin/java";
+				      }
+				      String beastJar = AddOnManager.getPackageUserDir();
+				      beastJar += "/" + "BEAST" + "/" + "lib" + "/" + "beast.jar";
+				      if (!new File(beastJar).exists()) {
+				    	  Log.debug.println("Could not find beast.jar, giving up testCudaStatusOnMac");
+				    	  return true;
+				      }
+				      //beastJar = "\"" + beastJar + "\"";
+				      //beastJar = "/Users/remco/workspace/beast2/build/dist/beast.jar";
+				      Process p = Runtime.getRuntime().exec(new String[]{java , "-cp" , beastJar , "beast.app.util.Utils"});
+				      BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
+				      String line;
+				      while ((line = input.readLine()) != null) {
+				        Log.debug.println(line);
+				      }
+				      input.close();
+				      if (p.exitValue() != 0) {
+				    	  if (GraphicsEnvironment.isHeadless()) {
+				    		  cudaStatusOnMac = cudaStatusOnMac.replaceAll("<br>", "\n");
+				    		  cudaStatusOnMac = cudaStatusOnMac.replaceAll("<.?html>","\n");
+				    		  Log.warning.println("WARNING: " + cudaStatusOnMac);
+				    	  } else {
+				    		  JOptionPane.showMessageDialog(null, cudaStatusOnMac);
+				    	  }
+				    	  return false;
+				      }
+				    }
+				    catch (Exception err) {
+				      err.printStackTrace();
+				    }
+			}
+			
+		}
+		return true;
+	}
+	
+	
+    public static void main(String[] args) {
+		try {
+			Sequence a = new Sequence("A", "A");
+	        Sequence b = new Sequence("B", "A");
+	        Sequence c = new Sequence("C", "A");
+	        Sequence d = new Sequence("D", "A");
+
+	        Alignment data = new Alignment();
+	        data.initByName("sequence", a, "sequence", b, "sequence", c, "sequence", d, "dataType", "nucleotide");
+
+	        TreeParser tree = new TreeParser();
+	        tree.initByName("taxa", data,
+	                "newick", "(((A:1,B:1):1,C:2):1,D:3)",
+	                "IsLabelledNewick", true);
+
+	        JukesCantor JC = new JukesCantor();
+	        JC.initAndValidate();
+
+	        SiteModel siteModel = new SiteModel();
+	        siteModel.initByName("mutationRate", "1.0", "gammaCategoryCount", 1, "substModel", JC);
+
+	    	BeagleTreeLikelihood likelihood = new BeagleTreeLikelihood();
+	        likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+    	
+    	System.out.println("Success");
+    	// if we got this far, exit with status 0
+		System.exit(0);
+	}
+
 }
diff --git a/src/beast/app/util/Utils6.java b/src/beast/app/util/Utils6.java
index 8cf4ba5..0f67209 100644
--- a/src/beast/app/util/Utils6.java
+++ b/src/beast/app/util/Utils6.java
@@ -98,4 +98,16 @@ public class Utils6 {
 	        return null;
 	    }
 	}
+
+    public static boolean isMac() {
+        return System.getProperty("os.name").toLowerCase().startsWith("mac");
+    }
+
+    public static boolean isWindows() {
+        return System.getProperty("os.name").toLowerCase().startsWith("windows");
+    }
+
+    public static boolean isLinux() {
+        return System.getProperty("os.name").toLowerCase().startsWith("linux");
+    }
 }
diff --git a/src/beast/core/Input.java b/src/beast/core/Input.java
index 44b4715..bde8d06 100644
--- a/src/beast/core/Input.java
+++ b/src/beast/core/Input.java
@@ -748,5 +748,9 @@ public class Input<T> {
                 break;
         }
     } // validate
+    
+    public String toString() {
+    	return String.format("Input(\"%s\")", name);
+    }
 
 } // class Input
diff --git a/src/beast/core/Logger.java b/src/beast/core/Logger.java
index c652f67..7f04e48 100644
--- a/src/beast/core/Logger.java
+++ b/src/beast/core/Logger.java
@@ -38,6 +38,7 @@ import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -66,8 +67,8 @@ public class Logger extends BEASTObject {
     final public Input<BEASTObject> modelInput = new Input<>("model", "Model to log at the top of the log. " +
             "If specified, XML will be produced for the model, commented out by # at the start of a line. " +
             "Alignments are suppressed. This way, the log file documents itself. ");
-    final public Input<LOGMODE> modeInput = new Input<>("mode", "logging mode, one of " + LOGMODE.values(), LOGMODE.autodetect, LOGMODE.values());
-    final public Input<SORTMODE> sortModeInput = new Input<>("sort", "sort items to be logged, one of " + SORTMODE.values(), SORTMODE.none, SORTMODE.values());
+    final public Input<LOGMODE> modeInput = new Input<>("mode", "logging mode, one of " + Arrays.toString(LOGMODE.values()), LOGMODE.autodetect, LOGMODE.values());
+    final public Input<SORTMODE> sortModeInput = new Input<>("sort", "sort items to be logged, one of " + Arrays.toString(SORTMODE.values()), SORTMODE.none, SORTMODE.values());
     final public Input<Boolean> sanitiseHeadersInput = new Input<>("sanitiseHeaders", "whether to remove any clutter introduced by Beauti" , false);
 
     final public Input<List<BEASTObject>> loggersInput = new Input<>("log",
@@ -141,7 +142,7 @@ public class Logger extends BEASTObject {
         } else if (mode.equals(LOGMODE.compound)) {
         	this.mode = LOGMODE.compound;
         } else {
-            throw new IllegalArgumentException("Mode '" + mode + "' is not supported. Choose one of " + LOGMODE.values());
+            throw new IllegalArgumentException("Mode '" + mode + "' is not supported. Choose one of " + Arrays.toString(LOGMODE.values()));
         }
 
         if (everyInput.get() != null) {
diff --git a/src/beast/core/OperatorSchedule.java b/src/beast/core/OperatorSchedule.java
index a2e191c..20ff8ee 100644
--- a/src/beast/core/OperatorSchedule.java
+++ b/src/beast/core/OperatorSchedule.java
@@ -154,8 +154,6 @@ public class OperatorSchedule extends BEASTObject {
         formatter.format(headerFormat, PR_ACCEPT);
         out.println(": The acceptance probability (" + NUM_ACCEPT + " as a fraction of the total proposals for this operator).");
         out.println();
-        
-        formatter.close();
     }
 
     protected static String prettyPrintOperator(
diff --git a/src/beast/evolution/likelihood/BeagleTreeLikelihood.java b/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
index 8fd9a67..abd4fc6 100644
--- a/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
+++ b/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
@@ -34,6 +34,7 @@ import beagle.BeagleFlag;
 import beagle.BeagleInfo;
 import beagle.InstanceDetails;
 import beagle.ResourceDetails;
+import beast.core.CalculationNode;
 import beast.core.Description;
 import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
@@ -82,6 +83,9 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
     int m_nStateCount;
     int m_nNodeCount;
     
+    private double [] currentCategoryRates;
+    private double [] storedCurrentCategoryRates;
+    
     private int invariantCategory = -1;
 
     @Override
@@ -139,6 +143,16 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 	        		break;
 	        	}
 	        }
+	        if (constantPattern.size() > dataInput.get().getPatternCount()) {
+	        	// if there are many more constant patterns than patterns (each pattern can
+	        	// have a number of constant patters, one for each state) it is less efficient
+	        	// to just calculate the TreeLikelihood for constant sites than optimising
+	        	Log.debug("switch off constant sites optimisiation: calculating through separate TreeLikelihood category (as in the olden days)");
+	        	invariantCategory = -1;
+	        	proportionInvariant = 0;
+	        	constantPattern = null;
+	        	categoryRates = m_siteModel.getCategoryRates(null);
+	        }
         }        
 
         this.categoryCount = m_siteModel.getCategoryCount() - (invariantCategory >= 0 ? 1 : 0);
@@ -349,7 +363,9 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
         // set up sitemodel
         
         beagle.setCategoryRates(categoryRates);
-
+        currentCategoryRates = categoryRates;
+        storedCurrentCategoryRates = categoryRates.clone();
+        
         return true;
     }
 
@@ -499,10 +515,30 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
     @Override
     protected boolean requiresRecalculation() {
         hasDirt = Tree.IS_CLEAN;
+        
+        double[] categoryRates = m_siteModel.getCategoryRates(null);
+        if (constantPattern != null) {
+            double [] tmp = new double [categoryRates.length - 1];
+            for (int k = 0; k < invariantCategory; k++) {
+            	tmp[k] = categoryRates[k];
+            }
+            for (int k = invariantCategory + 1; k < categoryRates.length; k++) {
+            	tmp[k-1] = categoryRates[k];
+            }
+            categoryRates = tmp;
+        }
+        for (int i = 0; i < categoryRates.length; i++) {
+        	if (categoryRates[i] != currentCategoryRates[i]) {
+        		updateSiteModel = true;
+        		break;
+        	}
+        }
+        //updateSiteModel |= m_siteModel.isDirtyCalculation();
 
-        updateSiteModel |= m_siteModel.isDirtyCalculation();
-        updateSubstitutionModel |= substitutionModel.isDirtyCalculation();
-
+        if (substitutionModel instanceof CalculationNode) {
+        	updateSubstitutionModel |= ((CalculationNode) substitutionModel).isDirtyCalculation();
+        }
+        
         if (dataInput.get().isDirtyCalculation()) {
             hasDirt = Tree.IS_FILTHY;
             return true;
@@ -535,12 +571,21 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
         }
         super.store();
         System.arraycopy(m_branchLengths, 0, storedBranchLengths, 0, m_branchLengths.length);
+        System.arraycopy(currentCategoryRates, 0, storedCurrentCategoryRates, 0, currentCategoryRates.length);
     }
 
     @Override
     public void restore() {
-        updateSiteModel = true; // this is required to upload the categoryRates to BEAGLE after the restore
-
+        for (int i = 0; i < currentCategoryRates.length; i++) {
+        	if (currentCategoryRates[i] != storedCurrentCategoryRates[i]) {
+        		updateSiteModel = true; // this is required to upload the categoryRates to BEAGLE after the restore
+        		break;
+        	}
+        }
+        double [] tmp = storedCurrentCategoryRates;
+        storedCurrentCategoryRates = currentCategoryRates;
+        currentCategoryRates = tmp;
+        
         partialBufferHelper.restoreState();
         eigenBufferHelper.restoreState();
         matrixBufferHelper.restoreState();
@@ -642,6 +687,7 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 	            categoryRates = tmp;
 	        }
             beagle.setCategoryRates(categoryRates);
+            currentCategoryRates = categoryRates;
         }
 
         for (int i = 0; i < eigenCount; i++) {
@@ -724,11 +770,18 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                 beagle.getSiteLogLikelihoods(patternLogLikelihoods);
                 int [] patternWeights = dataInput.get().getWeights();
                 proportionInvariant = m_siteModel.getProportionInvariant();
-                for (int k : constantPattern) {
-                	int i = k / m_nStateCount;
-                	int j = k % m_nStateCount;
-                	logL += patternWeights[i] * (Math.log(Math.exp(patternLogLikelihoods[i]) + proportionInvariant * frequencies[j]) - patternLogLikelihoods[i]);
-                }
+                
+                
+    	        for (int k : constantPattern) {
+    	        	int i = k / m_nStateCount;
+    	        	int j = k % m_nStateCount;
+    	        	patternLogLikelihoods[i] = (Math.log(Math.exp(patternLogLikelihoods[i]) + proportionInvariant * frequencies[j]));
+    	        }
+        	
+	            logL = 0.0;
+	            for (int i = 0; i < patternCount; i++) {
+	                logL += patternLogLikelihoods[i] * patternWeights[i];
+	            }
             }
 
             if (Double.isNaN(logL) || Double.isInfinite(logL)) {
@@ -971,11 +1024,6 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
     
     /**
-     * the pattern likelihoods
-     */
-    protected double[] patternLogLikelihoods = null;
-
-    /**
      * the number of rate categories
      */
     protected int categoryCount;
diff --git a/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java b/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
index f584f82..f485262 100644
--- a/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
+++ b/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
@@ -73,7 +73,7 @@ public class ThreadedTreeLikelihood extends GenericTreeLikelihood {
     final public Input<Scaling> scalingInput = new Input<>("scaling", "type of scaling to use, one of " + Arrays.toString(Scaling.values()) + ". If not specified, the -beagle_scaling flag is used.", Scaling._default, Scaling.values());
     
     /** private list of likelihoods, to notify framework of TreeLikelihoods being created in initAndValidate() **/
-    final private Input<List<TreeLikelihood>> likelihoodsInput = new Input<>("xxx","",new ArrayList<>());
+    final private Input<List<TreeLikelihood>> likelihoodsInput = new Input<>("*","",new ArrayList<>());
     
     @Override
     public List<Input<?>> listInputs() {
@@ -283,7 +283,7 @@ public class ThreadedTreeLikelihood extends GenericTreeLikelihood {
   		  	try {
 	            logPByThread[threadNr] = likelihood.calculateLogP();
   		  	} catch (Exception e) {
-  		  		System.err.println("Something went wrong ith thread " + threadNr);
+  		  		System.err.println("Something went wrong in thread " + threadNr);
 				e.printStackTrace();
 				System.exit(0);
 			}
diff --git a/src/beast/evolution/likelihood/TreeLikelihood.java b/src/beast/evolution/likelihood/TreeLikelihood.java
index c30afbc..fafb5fe 100644
--- a/src/beast/evolution/likelihood/TreeLikelihood.java
+++ b/src/beast/evolution/likelihood/TreeLikelihood.java
@@ -68,7 +68,7 @@ public class TreeLikelihood extends GenericTreeLikelihood {
      * BEASTObject associated with inputs. Since none of the inputs are StateNodes, it
      * is safe to link to them only once, during initAndValidate.
      */
-    SubstitutionModel.Base substitutionModel;
+    SubstitutionModel substitutionModel;
     protected SiteModel.Base m_siteModel;
     protected BranchRateModel.Base branchRateModel;
 
diff --git a/src/beast/evolution/operators/DeltaExchangeOperator.java b/src/beast/evolution/operators/DeltaExchangeOperator.java
index df55d25..add9f7a 100644
--- a/src/beast/evolution/operators/DeltaExchangeOperator.java
+++ b/src/beast/evolution/operators/DeltaExchangeOperator.java
@@ -137,6 +137,47 @@ public class DeltaExchangeOperator extends Operator {
     @Override
     public final double proposal() {
     	int[] parameterWeights = weights();
+    	final int dim = parameterWeights.length;
+    	
+    	// Find the number of weights that are nonzero
+    	int nonZeroWeights = 0;
+    	for (int i: parameterWeights) {
+    		if (i != 0) {
+    			++nonZeroWeights;
+    		}
+    	}
+    	
+        if (nonZeroWeights <= 1) {
+        	// it is impossible to select two distinct entries in this case, so there is nothing to propose 
+        	return 0.0;
+        }
+    	
+        // Generate indices for the values to be modified
+        int dim1 = Randomizer.nextInt(nonZeroWeights);
+        int dim2 = Randomizer.nextInt(nonZeroWeights-1);
+        if (dim2 >= dim1) {
+        	++dim2;
+        }
+        if (nonZeroWeights<dim) {
+        	// There are zero weights, so we need to increase dim1 and dim2 accordingly.
+        	int nonZerosBeforeDim1 = dim1;
+        	int nonZerosBeforeDim2 = dim2;
+        	dim1 = 0;
+        	dim2 = 0;
+        	while (nonZerosBeforeDim1 > 0 | parameterWeights[dim1] == 0 ) {
+        		if (parameterWeights[dim1] != 0) {
+        			--nonZerosBeforeDim1;
+        		}
+        		++dim1;
+        	}
+        	while (nonZerosBeforeDim2 > 0 | parameterWeights[dim2] == 0 ) {
+        		if (parameterWeights[dim2] != 0) {
+        			--nonZerosBeforeDim2;
+        		}
+        		++dim2;
+        	}
+        }
+
         double logq = 0.0;
 
         if (compoundParameter == null) { // one parameter case
@@ -150,18 +191,6 @@ public class DeltaExchangeOperator extends Operator {
                 realparameter = parameterInput.get().get(0);
             }
 
-            final int dim = (realparameter != null ? realparameter.getDimension() : intparameter.getDimension());
-            if (dim <= 1) {
-            	// it is impossible to select two distinct entries in this case, so there is nothing to propose 
-            	return 0.0;
-            }
-
-            final int dim1 = Randomizer.nextInt(dim);
-            int dim2 = dim1;
-            while (dim1 == dim2) {
-                dim2 = Randomizer.nextInt(dim);
-            }
-
             if (intparameter == null) {
                 // operate on real parameter
                 double scalar1 = realparameter.getValue(dim1);
@@ -217,19 +246,6 @@ public class DeltaExchangeOperator extends Operator {
 
         } else { // compound parameter case
 
-            // get two dimensions
-            final int dim = compoundParameter.getDimension();
-            if (dim <= 1) {
-            	// it is impossible to select two distinct entries in this case, so there is nothing to propose 
-            	return 0.0;
-            }
-
-            final int dim1 = Randomizer.nextInt(dim);
-            int dim2 = dim1;
-            while (dim1 == dim2) {
-                dim2 = Randomizer.nextInt(dim);
-            }
-
             if (intparameterInput.get().isEmpty()) {
                 // operate on real parameter
                 double scalar1 = (Double) compoundParameter.getValue(dim1);
@@ -315,9 +331,9 @@ public class DeltaExchangeOperator extends Operator {
     public void optimize(final double logAlpha) {
         // must be overridden by operator implementation to have an effect
         if (autoOptimize) {
-            double delta = calcDelta(logAlpha);
-            delta += Math.log(delta);
-            delta = Math.exp(delta);
+            double _delta = calcDelta(logAlpha);
+            _delta += Math.log(delta);
+            delta = Math.exp(_delta);
             if (isIntegerOperator) {
             	// when delta < 0.5
             	// Randomizer.nextInt((int) Math.round(delta)) becomes
diff --git a/src/beast/evolution/operators/SubtreeSlide.java b/src/beast/evolution/operators/SubtreeSlide.java
index 2bb72bc..61e84ce 100644
--- a/src/beast/evolution/operators/SubtreeSlide.java
+++ b/src/beast/evolution/operators/SubtreeSlide.java
@@ -250,7 +250,7 @@ public class SubtreeSlide extends TreeOperator {
      */
     @Override
     public void optimize(final double logAlpha) {
-        if (optimiseInput.get() && ! Double.isInfinite(logAlpha) ) {
+        if (optimiseInput.get()) {
             double delta = calcDelta(logAlpha);
             delta += Math.log(size);
             final double f = Math.exp(delta);
diff --git a/src/beast/evolution/sitemodel/SiteModelInterface.java b/src/beast/evolution/sitemodel/SiteModelInterface.java
index a7877c6..16a83b7 100644
--- a/src/beast/evolution/sitemodel/SiteModelInterface.java
+++ b/src/beast/evolution/sitemodel/SiteModelInterface.java
@@ -35,7 +35,7 @@ public interface SiteModelInterface {
 
     @Description(value = "Base implementation of a site model with substitution model and rate categories.", isInheritable = false)
     public abstract class Base extends CalculationNode implements SiteModelInterface {
-    	final public Input<SubstitutionModel.Base> substModelInput =
+    	final public Input<SubstitutionModel> substModelInput =
                 new Input<>("substModel", "substitution model along branches in the beast.tree", null, Validate.REQUIRED);
 
     	/**
diff --git a/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java b/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
index 142405f..f733ba3 100644
--- a/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
+++ b/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
@@ -2,6 +2,7 @@ package beast.evolution.substitutionmodel;
 
 import beast.core.util.Log;
 import beast.math.MachineAccuracy;
+import java.util.Arrays;
 
 /**
  * A default Eigen decomposition system
@@ -178,7 +179,10 @@ public class DefaultEigenSystem implements EigenSystem {
                 }
                 if (itn == 0) {
                     /* eigenvalues have not converged */
-                    Log.warning.println("Eigenvalues not converged");
+                    Log.warning.println("Eigenvalues not converged for Q-matrix");
+                    for (i = 0; i < n; i++) {
+                    	Log.warning.println(Arrays.toString(h[i]));
+                    }
                     throw new ArithmeticException();
                 }
                 y = h[na - 1][na - 1];
diff --git a/src/beast/evolution/substitutionmodel/Frequencies.java b/src/beast/evolution/substitutionmodel/Frequencies.java
index 4f06b46..d49221d 100644
--- a/src/beast/evolution/substitutionmodel/Frequencies.java
+++ b/src/beast/evolution/substitutionmodel/Frequencies.java
@@ -73,10 +73,11 @@ public class Frequencies extends CalculationNode {
      * return up to date frequencies *
      */
     public double[] getFreqs() {
-        if (needsUpdate) {
-
-            update();
-        }
+    	synchronized (this) {
+            if (needsUpdate) {
+                update();
+            }			
+		}
 
         return freqs;
     }
diff --git a/src/beast/evolution/tree/RandomTree.java b/src/beast/evolution/tree/RandomTree.java
index c5158c1..351f82d 100644
--- a/src/beast/evolution/tree/RandomTree.java
+++ b/src/beast/evolution/tree/RandomTree.java
@@ -420,7 +420,7 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
                 final Set<Node> candidates = new HashSet<>();
                 int i = 0;
                 for (String taxon : taxa) {
-                    final Node node = new Node();
+                    final Node node = newNode();
                     node.setNr(i);
                     node.setID(taxon);
                     node.setHeight(0.0);
@@ -560,7 +560,7 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
                 int k = nodeList.size() - 1;
                 final Node left = nodeList.remove(k);
                 final Node right = nodeList.get(k-1);
-                final Node newNode = new Node();
+                final Node newNode = newNode();
                 newNode.setNr(nextNodeNr++);   // multiple tries may generate an excess of nodes assert(nextNodeNr <= nrOfTaxa*2-1);
                 newNode.setHeight(h + dt);
                 newNode.setLeft(left);
@@ -691,7 +691,7 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
         final Node left = nodeList.get(node1);
         final Node right = nodeList.get(node2);
 
-        final Node newNode = new Node();
+        final Node newNode = newNode();
 //		System.err.println(2 * m_taxa.get().getNrTaxa() - nodeList.size());
         newNode.setNr(nextNodeNr++);   // multiple tries may generate an excess of nodes assert(nextNodeNr <= nrOfTaxa*2-1);
         newNode.setHeight(height);
diff --git a/src/beast/util/AddOnManager.java b/src/beast/util/AddOnManager.java
index 3132022..9f1ab5e 100644
--- a/src/beast/util/AddOnManager.java
+++ b/src/beast/util/AddOnManager.java
@@ -82,10 +82,10 @@ public class AddOnManager {
     public final static String[] IMPLEMENTATION_DIR = {"beast", "snap"};
     public final static String TO_DELETE_LIST_FILE = "toDeleteList";
     public final static String TO_INSTALL_LIST_FILE = "toInstallList";
-    public final static String BEAST_PACKAGE = "BEAST";
+    public final static String BEAST_PACKAGE_NAME = "BEAST";
 
-//    public final static String PACKAGES_XML = "https://raw.githubusercontent.com/CompEvol/CBAN/master/packages.xml";
-    public final static String PACKAGES_XML = "file:///Users/remco/workspace/beast2/packages.xml";
+    public final static String PACKAGES_XML = "https://raw.githubusercontent.com/CompEvol/CBAN/master/packages.xml";
+//    public final static String PACKAGES_XML = "file:///Users/remco/workspace/beast2/packages.xml";
 
     public static final String INSTALLED = "installed";
     public static final String NOT_INSTALLED = "not installed";
@@ -282,19 +282,23 @@ public class AddOnManager {
             }
         }
 
-        // Manually set currently-installed BEAST 2 version (won't have to do this soon!)
-
-//        Package beastPkg;
-//        if (packageMap.containsKey(BEAST_PACKAGE))
-//            beastPkg = packageMap.get(BEAST_PACKAGE);
-//        else {
-//            beastPkg = new Package(BEAST_PACKAGE);
-//            packageMap.put(BEAST_PACKAGE, beastPkg);
-//        }
-//
-//        PackageVersion beastPkgVersion = new PackageVersion(beastVersion.getVersion());
-//        Set<PackageDependency> beastPkgDeps = new TreeSet<>();
-//        beastPkg.setInstalled(beastPkgVersion, beastPkgDeps);
+        // Manually set currently-installed BEAST 2 version if not already set
+        // This can happen when the BEAST package is not installed (perhaps due to 
+        // file access issues)
+        Package beastPkg;
+        if (packageMap.containsKey(BEAST_PACKAGE_NAME)) {
+            beastPkg = packageMap.get(BEAST_PACKAGE_NAME);
+        } else {
+            beastPkg = new Package(BEAST_PACKAGE_NAME);
+            packageMap.put(BEAST_PACKAGE_NAME, beastPkg);
+        }
+
+        if (!beastPkg.isInstalled()) {
+            PackageVersion beastPkgVersion = new PackageVersion(beastVersion.getVersion());
+            Set<PackageDependency> beastPkgDeps = new TreeSet<>();
+            beastPkg.setInstalled(beastPkgVersion, beastPkgDeps);
+        }
+
     }
 
     /**
@@ -437,6 +441,8 @@ public class AddOnManager {
      * @throws IOException if URL cannot be accessed for some reason
      */
     public static Map<String, String> installPackages(Map<Package, PackageVersion> packagesToInstall, boolean useAppDir, String customDir) throws IOException {
+    	closeClassLoader();
+    	
         Map<String, String> dirList = new HashMap<>();
 
         for (Map.Entry<Package, PackageVersion> entry : packagesToInstall.entrySet()) {
@@ -512,6 +518,7 @@ public class AddOnManager {
      * @throws IOException thrown if packages cannot be deleted and delete list file cannot be written
      */
     public static String uninstallPackage(Package pkg, boolean useAppDir, String customDir) throws IOException {
+    	closeClassLoader();
 
         String dirName = (useAppDir ? getPackageSystemDir() : getPackageUserDir()) + "/" + pkg.getName();
         if (customDir != null) {
@@ -534,7 +541,32 @@ public class AddOnManager {
     }
 
 
-    private static void deleteRecursively(File file, List<File> deleteFailed) {
+    /**
+     * Close class loader so that locks on jar files are released, which may prevent
+     * files being replaced on Windows.
+     * http://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html#close%28%29
+     * 
+     * This allows smooth upgrading of BEAST versions using the package manager. Without 
+     * this, there is no way to upgrade BEAST since the AddOnManager is part of the 
+     * BEAST.jar file that is loaded and needs to be replaced.
+     * 
+     * Side effect is that after installing a package, opening a new BEAUti instance
+     * will fail (Windows only).
+     * 
+     */
+    private static void closeClassLoader() {
+    	try {
+    		if (Utils.isWindows()) {
+    			URLClassLoader sysLoader = (URLClassLoader) AddOnManager.class.getClassLoader();
+    			sysLoader.close();
+    		}
+		} catch (IOException e) {
+			Log.warning.println("Could not close ClassLoader: " + e.getMessage());
+		}
+		
+	}
+
+	private static void deleteRecursively(File file, List<File> deleteFailed) {
         if (file.isDirectory()) {
             File[] files = file.listFiles();
             for (File f : files) {
@@ -1294,10 +1326,10 @@ public class AddOnManager {
         // sort result
         result.addAll(names);
         Collections.sort(result, (s1, s2) -> {
-        	if (s1.equals(BEAST_PACKAGE)) {
+        	if (s1.equals(BEAST_PACKAGE_NAME)) {
         		return -1;
         	}
-        	if (s2.equals(BEAST_PACKAGE)) {
+        	if (s2.equals(BEAST_PACKAGE_NAME)) {
         		return 1;
         	}
         	return s1.compareTo(s2);
@@ -1349,10 +1381,10 @@ public class AddOnManager {
 
         // sort result
         Collections.sort(result, (s1, s2) -> {
-        	if (s1.equals(BEAST_PACKAGE)) {
+        	if (s1.equals(BEAST_PACKAGE_NAME)) {
         		return -1;
         	}
-        	if (s2.equals(BEAST_PACKAGE)) {
+        	if (s2.equals(BEAST_PACKAGE_NAME)) {
         		return 1;
         	}
         	return s1.compareTo(s2);
@@ -1433,7 +1465,7 @@ public class AddOnManager {
 
         // Print formatted package information
         for (Package pkg : packageList) {
-        	if (pkg.getName().equals(BEAST_PACKAGE)) {
+        	if (pkg.getName().equals(BEAST_PACKAGE_NAME)) {
         		ps.printf(nameFormat, pkg.getName()); ps.print(sep);
 		        ps.printf(statusFormat, pkg.getStatusString()); ps.print(sep);
 		        ps.printf(latestFormat, pkg.isAvailable() ? pkg.getLatestVersion() : "NA"); ps.print(sep);
@@ -1447,7 +1479,7 @@ public class AddOnManager {
         
         // Print formatted package information
         for (Package pkg : packageList) {
-        	if (!pkg.getName().equals(BEAST_PACKAGE)) {
+        	if (!pkg.getName().equals(BEAST_PACKAGE_NAME)) {
 	            ps.printf(nameFormat, pkg.getName()); ps.print(sep);
 	            ps.printf(statusFormat, pkg.getStatusString()); ps.print(sep);
 	            ps.printf(latestFormat, pkg.isAvailable() ? pkg.getLatestVersion() : "NA"); ps.print(sep);
diff --git a/src/beast/util/ClusterTree.java b/src/beast/util/ClusterTree.java
index a02ac4c..72257c0 100644
--- a/src/beast/util/ClusterTree.java
+++ b/src/beast/util/ClusterTree.java
@@ -28,6 +28,7 @@ package beast.util;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
@@ -70,7 +71,7 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
     double EPSILON = 1e-10;
 
     final public Input<Type> clusterTypeInput = new Input<>("clusterType", "type of clustering algorithm used for generating initial beast.tree. " +
-            "Should be one of " + Type.values() + " (default " + Type.average + ")", Type.average, Type.values());
+            "Should be one of " + Arrays.toString(Type.values()) + " (default " + Type.average + ")", Type.average, Type.values());
     final public Input<Alignment> dataInput = new Input<>("taxa", "alignment data used for calculating distances for clustering");
 
     final public Input<Distance> distanceInput = new Input<>("distance", "method for calculating distance between two sequences (default Jukes Cantor)");
diff --git a/src/beast/util/JSONProducer.java b/src/beast/util/JSONProducer.java
index 22464f6..8309a6f 100644
--- a/src/beast/util/JSONProducer.java
+++ b/src/beast/util/JSONProducer.java
@@ -20,7 +20,10 @@ import beast.app.BEASTVersion;
 import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.State;
+import beast.core.parameter.BooleanParameter;
+import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.Parameter;
+import beast.core.parameter.RealParameter;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.tree.TraitSet;
 
@@ -307,6 +310,10 @@ public class JSONProducer {
                 	buf.append(buf2);
                 }
             	return;
+            } else if (input.getName().startsWith("*")) {
+        		// this can happen with private inputs, like in ThreadedTreeLikelihood
+        		// and * is not a valid XML attribute name
+            	return;
             } else if (value instanceof List) {
                 if (!isShort) {
                 	StringBuffer buf2 = new StringBuffer();
@@ -338,7 +345,7 @@ public class JSONProducer {
             		
             		// Parameters can use short hand notation if they are not in the state 
             		// Note this means lower and upper bounds are lost -- no problem for BEAST, but maybe for BEAUti
-            		if (value instanceof Parameter.Base) {
+            		if (value instanceof BooleanParameter || value instanceof IntegerParameter || value instanceof RealParameter) {
             			Parameter.Base parameter = (Parameter.Base) value;
             			boolean isInState = false;
             			for (Object o : parameter.getOutputs()) {
@@ -347,12 +354,16 @@ public class JSONProducer {
             					break;
             				}
             			}
-            			if (!isInState) {
-            				if (isShort) {
-                                buf.append(" " + input.getName() + ": \"" + parameter.getValue() + "\"");
-            				} else {
-            					return;
-            				}
+            			if (!isInState && parameter.getDimension() == 1 && parameter.getMinorDimension1() == 1) {
+            				// if not in state, bounds do not matter
+            				//if ((parameter instanceof RealParameter && parameter.getLower().equals(Double.NEGATIVE_INFINITY) && parameter.getUpper().equals(Double.POSITIVE_INFINITY)) ||
+            				//	(parameter instanceof IntegerParameter && parameter.getLower().equals(Integer.MIN_VALUE + 1) && parameter.getUpper().equals(Integer.MAX_VALUE - 1))) {
+	            				if (isShort) {
+	                                buf.append(" " + input.getName() + ": \"" + parameter.getValue() + "\"");
+	            				} else {
+	            					return;
+	            				}
+            				//}
             			}
             		}
             		
diff --git a/src/beast/util/MersenneTwisterFast.java b/src/beast/util/MersenneTwisterFast.java
index 5071480..6a73d84 100644
--- a/src/beast/util/MersenneTwisterFast.java
+++ b/src/beast/util/MersenneTwisterFast.java
@@ -585,7 +585,7 @@ public class MersenneTwisterFast implements Serializable {
         // Check for invalid input values
 
         if (a <= 0.0) throw new IllegalArgumentException();
-        if (lambda <= 0.0) new IllegalArgumentException();
+        if (lambda <= 0.0) throw new IllegalArgumentException();
 
         if (a < 1.0) { // CASE A: Acceptance rejection algorithm gs
             b = 1.0 + 0.36788794412 * a;              // Step 1
@@ -750,7 +750,7 @@ public class MersenneTwisterFast implements Serializable {
      * @param lambda mean of Poissonian distribution
      * @return Draw from Pois(lambda). Note: returns a double for historical reasons.
      */
-    public double nextPoisson(double lambda) {
+    public long nextPoisson(double lambda) {
         if (lambda<12)
             return poissonian_icdf(lambda);
 
diff --git a/src/beast/util/NexusParser.java b/src/beast/util/NexusParser.java
index bf88ce9..290574e 100644
--- a/src/beast/util/NexusParser.java
+++ b/src/beast/util/NexusParser.java
@@ -435,7 +435,7 @@ public class NexusParser {
         //reading CHARSTATELABELS block
         if (str.toLowerCase().contains("charstatelabels")) {
             if (!alignment.dataTypeInput.get().equals("standard")) {
-                new Exception("If CHARSTATELABELS block is specified then DATATYPE has to be Standard");
+                throw new IllegalArgumentException("If CHARSTATELABELS block is specified then DATATYPE has to be Standard");
             }
             StandardData standardDataType = (StandardData)alignment.userDataTypeInput.get();
             int[] maxNumberOfStates = new int[] {0};
diff --git a/src/beast/util/Package.java b/src/beast/util/Package.java
index d0e6ac8..3c95e0c 100644
--- a/src/beast/util/Package.java
+++ b/src/beast/util/Package.java
@@ -175,7 +175,7 @@ public class Package {
         String depString = "";
         for (PackageDependency packageDependency : availableVersionDeps.lastEntry().getValue()) {
             String s = packageDependency.dependencyName;
-            if (!s.equalsIgnoreCase(AddOnManager.BEAST_PACKAGE)) {
+            if (!s.equalsIgnoreCase(AddOnManager.BEAST_PACKAGE_NAME)) {
                 depString +=  s + ", ";
             }
         }
diff --git a/src/beast/util/PackageDependency.java b/src/beast/util/PackageDependency.java
index e5c6208..9797843 100644
--- a/src/beast/util/PackageDependency.java
+++ b/src/beast/util/PackageDependency.java
@@ -45,7 +45,7 @@ public class PackageDependency {
                              PackageVersion minimumVersion,
                              PackageVersion maximumVersion) {
     	if (dependencyName.equals("beast2")) {
-    		dependencyName = AddOnManager.BEAST_PACKAGE;
+    		dependencyName = AddOnManager.BEAST_PACKAGE_NAME;
     	}
         this.dependencyName = dependencyName;
         
diff --git a/src/beast/util/Randomizer.java b/src/beast/util/Randomizer.java
index 5b83172..522148f 100644
--- a/src/beast/util/Randomizer.java
+++ b/src/beast/util/Randomizer.java
@@ -251,7 +251,7 @@ public class Randomizer {
      * @param lambda mean of Poissonian distribution
      * @return sample (as double for historical reasons)
      */
-    public static double nextPoisson(double lambda) {
+    public static long nextPoisson(double lambda) {
         synchronized (random) {
             return random.nextPoisson(lambda);
         }
diff --git a/src/beast/util/TreeParser.java b/src/beast/util/TreeParser.java
index 4e65d22..daa7cea 100644
--- a/src/beast/util/TreeParser.java
+++ b/src/beast/util/TreeParser.java
@@ -463,8 +463,9 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
                                     attribctx.attribValue().number().getText()));
                         } else if (attribctx.attribValue().STRING() != null) {
                             String stringValue = attribctx.attribValue().STRING().getText();
-                            if (stringValue.startsWith("\"") || stringValue.startsWith("\'"));
+                            if (stringValue.startsWith("\"") || stringValue.startsWith("\'")) {
                                 stringValue = stringValue.substring(1, stringValue.length()-1);
+                            }
                             node.setMetaData(key, stringValue);
                         } else {
                             // BEAST doesn't do anything with vectors yet.
diff --git a/src/beast/util/XMLProducer.java b/src/beast/util/XMLProducer.java
index 4d77783..0429ba9 100644
--- a/src/beast/util/XMLProducer.java
+++ b/src/beast/util/XMLProducer.java
@@ -946,6 +946,10 @@ public class XMLProducer extends XMLParser {
                 	}
                 }
             	return;
+            } else if (input.getName().startsWith("*")) {
+        		// this can happen with private inputs, like in ThreadedTreeLikelihood
+        		// and * is not a valid XML attribute name
+        		return;
             } else if (value instanceof List) {
                 if (!isShort) {
                 	int k = 0;
diff --git a/src/test/beast/evolution/operator/DeltaExchangeOperatorTest.java b/src/test/beast/evolution/operator/DeltaExchangeOperatorTest.java
new file mode 100644
index 0000000..0801d65
--- /dev/null
+++ b/src/test/beast/evolution/operator/DeltaExchangeOperatorTest.java
@@ -0,0 +1,64 @@
+/**
+ * 
+ */
+package test.beast.evolution.operator;
+
+import org.junit.Test;
+
+import beast.core.State;
+import beast.core.parameter.IntegerParameter;
+import beast.core.parameter.RealParameter;
+import beast.evolution.operators.DeltaExchangeOperator;
+
+/**
+ * @author gereon
+ *
+ */
+public class DeltaExchangeOperatorTest extends TestOperator {
+
+	@Test
+	public void testKeepsSum() {
+		DeltaExchangeOperator operator = new DeltaExchangeOperator(); 
+		RealParameter parameter = new RealParameter(new Double[] {1., 1., 1., 1.});
+		register(operator,
+				"parameter", parameter);
+		for (int i=0; i<100; ++i) {
+			operator.proposal();
+		}
+		double i = 0;
+		for (Double p : parameter.getValues()) {
+			i += p;
+		}
+		assertEquals("The DeltaExchangeOperator should not change the sum of a parameter", i, 4, 0.00001);
+	}
+	
+	@Test
+	public void testKeepsWeightedSum() {
+		RealParameter parameter = new RealParameter(new Double[] {1., 1., 1., 1.});
+		register(new DeltaExchangeOperator(),
+				"weightvector", new IntegerParameter(new Integer[] {0, 1, 2, 1}),
+				"parameter", parameter);
+		Double[] p = parameter.getValues();
+		assertEquals("The DeltaExchangeOperator should not change the sum of a parameter",
+				0*p[1]+1*p[1]+2*p[2]+1*p[3], 4, 0.00001);
+	}
+	
+	@Test
+	public void testCanOperate() {
+		// Test whether a validly initialised operator may make proposals
+		State state = new State();
+		RealParameter parameter = new RealParameter(new Double[] { 1., 1., 1., 1. });
+		state.initByName("stateNode", parameter);
+		state.initialise();
+		DeltaExchangeOperator d = new DeltaExchangeOperator();
+		// An invalid operator should either fail in initByName or make valid
+		// proposals
+		try {
+			d.initByName("parameter", parameter);
+		} catch (RuntimeException e) {
+			return;
+		}
+		d.proposal();
+	}
+
+}
diff --git a/src/test/beast/evolution/operator/TestOperator.java b/src/test/beast/evolution/operator/TestOperator.java
new file mode 100644
index 0000000..b7352d7
--- /dev/null
+++ b/src/test/beast/evolution/operator/TestOperator.java
@@ -0,0 +1,52 @@
+/**
+ * 
+ */
+package test.beast.evolution.operator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+
+import beast.core.Operator;
+import beast.core.State;
+import beast.core.StateNode;
+import junit.framework.TestCase;
+
+/**
+ * @author gereon
+ *
+ */
+public abstract class TestOperator extends TestCase {
+
+	static public void register(Operator operator, final Object... operands) {
+		HashMap<String, StateNode> operandsMap;
+		operandsMap = new HashMap<String, StateNode>();
+		if (operands.length % 2 == 1) {
+			throw new RuntimeException("Expected even number of arguments, name-value pairs");
+		}
+		for (int i = 0; i < operands.length; i += 2) {
+			if (operands[i] instanceof String) {
+				final String name = (String) operands[i];
+				if (operands[i + 1] instanceof StateNode) {
+					final StateNode node = (StateNode) operands[i + 1];
+					operandsMap.put(name, node);
+				} else {
+					throw new IllegalArgumentException("Expected a StateNode in " + (i + 1) + "th argument ");
+				}
+			} else {
+				throw new IllegalArgumentException("Expected a String in " + i + "th argument ");
+			}
+		}
+		State state = new State();
+		state.initByName("stateNode", new ArrayList<StateNode>(operandsMap.values()));
+		state.initialise();
+		Object[] operandsAndWeight = new Object[operands.length + 2];
+		for (int i = 0; i < operands.length; ++i) {
+			operandsAndWeight[i] = operands[i];
+		}
+		operandsAndWeight[operands.length] = "weight";
+		operandsAndWeight[operands.length + 1] = "1";
+		operator.initByName(operandsAndWeight);
+		operator.validateInputs();
+	}
+}
diff --git a/src/test/beast/util/JSONTest.java b/src/test/beast/util/JSONTest.java
index 2257ea1..09ffdd8 100644
--- a/src/test/beast/util/JSONTest.java
+++ b/src/test/beast/util/JSONTest.java
@@ -35,7 +35,7 @@ public class JSONTest extends TestCase {
     @Test
     public void testJSONFragmentParsing() throws Exception {
     	JSONParser parser = new JSONParser();
-    	String json = "{version: \"2.3\",\n" + 
+    	String json = "{version: \"2.4\",\n" + 
     			"\n" + 
     			"beast: [\n" + 
     			"{spec:\"beast.core.parameter.RealParameter\",\n" +
@@ -76,7 +76,7 @@ public class JSONTest extends TestCase {
     	
     	
     	// test that default value for param1 comes through
-    	String json2 = "{version: \"2.3\",\n" + 
+    	String json2 = "{version: \"2.4\",\n" + 
     			"namespace: \"beast.core:beast.evolution.alignment:beast.evolution.tree.coalescent:beast.core.util:beast.evolution.nuc:beast.evolution.operators:beast.evolution.sitemodel:beast.evolution.substitutionmodel:beast.evolution.likelihood\",\n" + 
     			"\n" + 
     			"beast: [\n" + 
@@ -103,7 +103,7 @@ public class JSONTest extends TestCase {
     	
 
     	// test that array of doubles comes through in second constructor
-    	String json3 = "{version: \"2.3\",\n" + 
+    	String json3 = "{version: \"2.4\",\n" + 
     			"namespace: \"beast.core:beast.evolution.alignment:beast.evolution.tree.coalescent:beast.core.util:beast.evolution.nuc:beast.evolution.operators:beast.evolution.sitemodel:beast.evolution.substitutionmodel:beast.evolution.likelihood\",\n" + 
     			"\n" + 
     			"beast: [\n" + 
diff --git a/templates/ClockModels.xml b/templates/ClockModels.xml
index 7de69b4..80d1860 100644
--- a/templates/ClockModels.xml
+++ b/templates/ClockModels.xml
@@ -83,13 +83,13 @@
                 c:$(n)
             </connect>
             <connect srcID='ExpCategoriesRandomWalk.c:$(n)' targetID='mcmc' inputName='operator'
-                     if='inlikelihood(expRateCategories.c:$(n))'>Randomly change categories of partition c:$(n)
+                     if='inlikelihood(expRateCategories.c:$(n)) and expRateCategories.c:$(n)/estimate=true'>Randomly change categories of partition c:$(n)
             </connect>
             <connect srcID='ExpCategoriesSwapOperator.c:$(n)' targetID='mcmc' inputName='operator'
-                     if='inlikelihood(expRateCategories.c:$(n))'>Swap categories of partition c:$(n)
+                     if='inlikelihood(expRateCategories.c:$(n)) and expRateCategories.c:$(n)/estimate=true'>Swap categories of partition c:$(n)
             </connect>
             <connect srcID='ExpCategoriesUniform.c:$(n)' targetID='mcmc' inputName='operator'
-                     if='inlikelihood(expRateCategories.c:$(n))'>Uniformly draw categories of partition c:$(n)
+                     if='inlikelihood(expRateCategories.c:$(n)) and expRateCategories.c:$(n)/estimate=true'>Uniformly draw categories of partition c:$(n)
             </connect>
             <connect srcID='relaxedUpDownOperatorExp.c:$(n)' targetID='mcmc' inputName='operator'
                      if='nooperator(FixMeanRatesOperator) and inlikelihood(ucedMean.c:$(n)) and inlikelihood(Tree.t:$(n)) and ucedMean.c:$(n)/estimate=true and Tree.t:$(n)/estimate=true'>
@@ -161,16 +161,16 @@
                 c:$(n)
             </connect>
             <connect srcID='ucldStdevScaler.c:$(n)' targetID='mcmc' inputName='operator'
-                     if='inlikelihood(ucldStdev.c:$(n))'>Scale stdev of rate of partition c:$(n)
+                     if='inlikelihood(ucldStdev.c:$(n)) and ucldStdev.c:$(n)/estimate=true'>Scale stdev of rate of partition c:$(n)
             </connect>
             <connect srcID='CategoriesRandomWalk.c:$(n)' targetID='mcmc' inputName='operator'
-                     if='inlikelihood(rateCategories.c:$(n))'>Randomly change categories of partition c:$(n)
+                     if='inlikelihood(rateCategories.c:$(n)) and rateCategories.c:$(n)/estimate=true'>Randomly change categories of partition c:$(n)
             </connect>
             <connect srcID='CategoriesSwapOperator.c:$(n)' targetID='mcmc' inputName='operator'
-                     if='inlikelihood(rateCategories.c:$(n))'>Swap categories of partition c:$(n)
+                     if='inlikelihood(rateCategories.c:$(n)) and rateCategories.c:$(n)/estimate=true'>Swap categories of partition c:$(n)
             </connect>
             <connect srcID='CategoriesUniform.c:$(n)' targetID='mcmc' inputName='operator'
-                     if='inlikelihood(rateCategories.c:$(n))'>Uniformly draw categories of partition c:$(n)
+                     if='inlikelihood(rateCategories.c:$(n)) and rateCategories.c:$(n)/estimate=true'>Uniformly draw categories of partition c:$(n)
             </connect>
             <connect srcID='relaxedUpDownOperator.c:$(n)' targetID='mcmc' inputName='operator'
                      if='nooperator(FixMeanRatesOperator) and inlikelihood(ucldMean.c:$(n)) and ucldMean.c:$(n)/estimate=true and Tree.t:$(n)/estimate=true'>
diff --git a/templates/Standard.xml b/templates/Standard.xml
index 4ee839b..e8e79f2 100644
--- a/templates/Standard.xml
+++ b/templates/Standard.xml
@@ -331,7 +331,7 @@
             <distribution spec="CompoundDistribution" id="prior">
 				<mergepoint id='aux-priors'/>
             </distribution>
-            <distribution spec="CompoundDistribution" id="likelihood">
+            <distribution spec="CompoundDistribution" id="likelihood" useThreads="true">
 				<mergepoint id='aux-likelihoods'/>
             </distribution>
         </distribution>
diff --git a/templates/StarBeast.xml b/templates/StarBeast.xml
index a32718f..9929c92 100644
--- a/templates/StarBeast.xml
+++ b/templates/StarBeast.xml
@@ -161,7 +161,7 @@
 		<alignmentProvider id="Import Alignment" spec='BeautiAlignmentProvider' template='@StarBEASTPartitionTemplate'/>
 
 
-        <partitiontemplate id='StarBEASTPartitionTemplate' spec='BeautiSubTemplate' class='beast.evolution.likelihood.TreeLikelihood' mainid='mcmc'>
+        <partitiontemplate id='StarBEASTPartitionTemplate' spec='BeautiSubTemplate' class='beast.evolution.likelihood.ThreadedTreeLikelihood' mainid='mcmc'>
 <![CDATA[
 
 		    <distribution id='treePrior.t:$(n)' spec='GeneTreeForSpeciesTreeDistribution' tree='@Tree.t:$(n)' speciesTree='@Tree.t:Species' speciesTreePrior='@SpeciesTreePopSize.Species'/>
@@ -369,7 +369,7 @@
 		            <distr spec="beast.math.distributions.OneOnX"/>
 		        </distribution>
             </distribution>
-            <distribution spec="CompoundDistribution" id="likelihood">
+            <distribution spec="CompoundDistribution" id="likelihood" useThreads="true">
 				<mergepoint id='aux-likelihoods'/>
             </distribution>
         </distribution>
diff --git a/version.xml b/version.xml
index cc9b99b..9af90d5 100644
--- a/version.xml
+++ b/version.xml
@@ -1 +1 @@
-<addon name='BEAST' version='2.4.0' url="file:///Users/remco/tmp/BEAST.package.2.4.0.zip"/>
+<addon name='BEAST' version='2.4.0' url="https://github.com/CompEvol/beast2/releases/download/2.4.0pre/BEAST.v2.4.0.addon.zip"/>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/beast2-mcmc.git



More information about the debian-med-commit mailing list