[med-svn] [beast2-mcmc] 01/06: Imported Upstream version 2.4.4+dfsg

Andreas Tille tille at debian.org
Fri Dec 2 10:47: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 ef83e24a08a486b0c8a039ecabe3be4b0977abba
Author: Andreas Tille <tille at debian.org>
Date:   Fri Dec 2 11:16:42 2016 +0100

    Imported Upstream version 2.4.4+dfsg
---
 build.xml                                          |   4 +-
 release/common/README.txt                          |   4 +-
 release/common/VERSION HISTORY.txt                 |  15 +-
 src/beast/app/BEASTVersion.java                    |   2 +-
 src/beast/app/BEASTVersion2.java                   |   2 +-
 src/beast/app/beastapp/BeastLauncher.java          |   2 +-
 src/beast/app/beauti/AlignmentListInputEditor.java |  50 +----
 src/beast/app/beauti/BeautiAlignmentProvider.java  |   4 +
 src/beast/app/beauti/BeautiConfig.java             |   7 +-
 src/beast/app/beauti/BeautiDoc.java                |  77 +++++---
 src/beast/app/beauti/GuessPatternDialog.java       |  52 ++++--
 src/beast/app/beauti/MRCAPriorInputEditor.java     |   3 +
 src/beast/app/treeannotator/TreeAnnotator.java     | 201 ++++++++++++---------
 src/beast/app/treeannotator/TreeSetParser.java     |   3 +-
 src/beast/app/util/Utils6.java                     |  12 +-
 src/beast/evolution/operators/NodeReheight.java    |   2 +-
 src/beast/evolution/tree/Tree.java                 |  56 +++---
 .../evolution/tree/TreeWithMetaDataLogger.java     |  36 ++--
 src/beast/util/AddOnManager.java                   | 116 ++++++------
 src/beast/util/NexusParser.java                    |  32 ++--
 src/beast/util/TreeParser.java                     |  34 ++--
 src/beast/util/treeparser/Newick.g4                |   5 +-
 src/beast/util/treeparser/NewickBaseVisitor.java   |   2 +-
 src/beast/util/treeparser/NewickLexer.java         |  92 ++++++----
 src/beast/util/treeparser/NewickParser.java        |  27 +--
 src/beast/util/treeparser/NewickVisitor.java       |   2 +-
 .../evolution/alignment/FilteredAlignmentTest.java |  68 ++++++-
 src/test/beast/util/TreeParserTest.java            |  14 ++
 version.xml                                        |   2 +-
 29 files changed, 550 insertions(+), 376 deletions(-)

diff --git a/build.xml b/build.xml
index 420fe49..22b260a 100644
--- a/build.xml
+++ b/build.xml
@@ -242,8 +242,8 @@
 
 
     <!-- Release -->
-    <property name="version" value="2.4.3" />
-    <property name="version_number" value="2.4.3" />
+    <property name="version" value="2.4.4" />
+    <property name="version_number" value="2.4.4" />
     <property name="release_dir" value="release" />
     <property name="copyright" value="Beast 2 development team 2011-2016" />
 
diff --git a/release/common/README.txt b/release/common/README.txt
index 9e7954b..f2c540a 100644
--- a/release/common/README.txt
+++ b/release/common/README.txt
@@ -1,7 +1,7 @@
-                    BEAST v2.4.3 2016
+                    BEAST v2.4.4 2016
                  Beast 2 development team 2011-2016
 
-Last updated: August 2016
+Last updated: November 2016
 
 Contents:
 1) INTRODUCTION
diff --git a/release/common/VERSION HISTORY.txt b/release/common/VERSION HISTORY.txt
index c795a5c..77f811e 100644
--- a/release/common/VERSION HISTORY.txt	
+++ b/release/common/VERSION HISTORY.txt	
@@ -1,14 +1,23 @@
-                    BEAST v2.4.3 2016
+                    BEAST v2.4.4 2016
                  Beast 2 development team 2011-2016
 Version History
-Last updated: August 2016
+Last updated: November 2016
 
 All issues can be viewed at https://github.com/CompEvol/beast2/issues
 ================================================================================
+Version 2.4.4 November 2016
+	Fix that prevented starting any BEAST application on Mac Sierra
+	
+	Smooth out some issues with importing Nexus files in BEAUti
+	
+	TreeAnnotator fix for use with user defined trees to annotate
+	
+	Allow smaller log files by logging fewer significant digits of metadata
+
 Version 2.4.3 August 2016
 	
 	BEAUti
-		Support for tip data sampling by setting 'tipsonly' in MRCA Priors
+		Support for tip date sampling by setting 'tipsonly' in MRCA Priors
 		Allow packages to specify priors, e.g. multi-monophyletic constraints in BEASTLabs
 		Allow packages to specify file importers, which allows microsattelite support through the BEASTvntr package
 		Gamma distribution allows multiple parameterisations
diff --git a/src/beast/app/BEASTVersion.java b/src/beast/app/BEASTVersion.java
index 44a8abd..609d8d7 100644
--- a/src/beast/app/BEASTVersion.java
+++ b/src/beast/app/BEASTVersion.java
@@ -19,7 +19,7 @@ public class BEASTVersion extends Version {
     /**
      * Version string: assumed to be in format x.x.x
      */
-    private static final String VERSION = "2.4.3";
+    private static final String VERSION = "2.4.4";
 
     private static final String DATE_STRING = "2002-2016";
 
diff --git a/src/beast/app/BEASTVersion2.java b/src/beast/app/BEASTVersion2.java
index d91d2b6..42aea5b 100644
--- a/src/beast/app/BEASTVersion2.java
+++ b/src/beast/app/BEASTVersion2.java
@@ -9,7 +9,7 @@ public class BEASTVersion2 extends BEASTVersion {
     /**
      * Version string: assumed to be in format x.x.x
      */
-    private static final String VERSION = "2.4.3";
+    private static final String VERSION = "2.4.4";
 
     private static final String DATE_STRING = "2002-2016";
 
diff --git a/src/beast/app/beastapp/BeastLauncher.java b/src/beast/app/beastapp/BeastLauncher.java
index ef96819..69d0c22 100644
--- a/src/beast/app/beastapp/BeastLauncher.java
+++ b/src/beast/app/beastapp/BeastLauncher.java
@@ -29,7 +29,7 @@ import beast.app.util.Utils6;
  * remainder of BEAST can be compiled against Java 1.8
  * **/
 public class BeastLauncher {
-	private static String getVersion() {return "2.4.3";}
+	private static String getVersion() {return "2.4.4";}
 	private static String getMajorVersion() {return "2.4";}
 	
 	private static String pathDelimiter;
diff --git a/src/beast/app/beauti/AlignmentListInputEditor.java b/src/beast/app/beauti/AlignmentListInputEditor.java
index 8d73a4f..61ccead 100644
--- a/src/beast/app/beauti/AlignmentListInputEditor.java
+++ b/src/beast/app/beauti/AlignmentListInputEditor.java
@@ -156,7 +156,7 @@ public class AlignmentListInputEditor extends ListInputEditor {
             	SwingUtilities.invokeLater(new Runnable() {
 					@Override
 					public void run() {
-		                addFiles(files);
+						addItem(files);
 					}
 				});
             }   // end filesDropped
@@ -219,46 +219,6 @@ public class AlignmentListInputEditor extends ListInputEditor {
         return buttonBox;
     }
 
-    private void addFiles(File[] fileArray) {
-        List<BEASTInterface> beastObjects = null;
-
-        List<BeautiAlignmentProvider> providers = doc.beautiConfig.alignmentProvider;
-        BeautiAlignmentProvider selectedProvider = null;
-        if (providers.size() == 1) {
-            selectedProvider = providers.get(0);
-        } else {
-            selectedProvider = (BeautiAlignmentProvider) JOptionPane.showInputDialog(this, "Select what to add",
-                    "Add partition",
-                    JOptionPane.QUESTION_MESSAGE, null, providers.toArray(),
-                    providers.get(0));
-            if (selectedProvider == null) {
-                return;
-            }
-        }
-
-        beastObjects = selectedProvider.getAlignments(doc, fileArray);
-
-        // create taxon sets, if any
-        if (beastObjects != null) {
-	        for (BEASTInterface o : beastObjects) {
-	        	if (o instanceof Alignment) {
-	        		try {
-						BeautiDoc.createTaxonSet((Alignment) o, doc);
-					} catch (Exception e) {
-						e.printStackTrace();
-					}
-	        	}
-	        }
-        }
-
-        // Component c = this;
-        if (beastObjects != null) {
-            refreshPanel();
-        }
-    }
-
-
-
 	/**
      * This method just adds the two buttons (with add()) and does not add any glue or struts before or after.
      * @param box
@@ -1095,13 +1055,17 @@ public class AlignmentListInputEditor extends ListInputEditor {
 
 	@Override
 	protected void addItem() {
-		List<BEASTInterface> beastObjects = doc.beautiConfig.selectAlignments(doc, this);
+		addItem(null);
+	} // addItem
+
+	private void addItem(File[] fileArray) {
+		List<BEASTInterface> beastObjects = doc.beautiConfig.selectAlignments(doc, this, fileArray);
 
 		// Component c = this;
 		if (beastObjects != null) {
 			refreshPanel();
 		}
-	} // addItem
+	}
 
 	void delItem() {
 		int[] selected = getTableRowSelection();
diff --git a/src/beast/app/beauti/BeautiAlignmentProvider.java b/src/beast/app/beauti/BeautiAlignmentProvider.java
index 44681f8..81d568d 100644
--- a/src/beast/app/beauti/BeautiAlignmentProvider.java
+++ b/src/beast/app/beauti/BeautiAlignmentProvider.java
@@ -116,6 +116,10 @@ public class BeautiAlignmentProvider extends BEASTObject {
      * @return
      */
     public List<BEASTInterface> getAlignments(BeautiDoc doc, File[] files) {
+		if (files == null) {
+			// merge "+ button" and "drag drop" function
+			return getAlignments(doc);
+		}
 		if (importers == null) {
 			initImporters();
 		}
diff --git a/src/beast/app/beauti/BeautiConfig.java b/src/beast/app/beauti/BeautiConfig.java
index 9101d0a..c5e5e09 100644
--- a/src/beast/app/beauti/BeautiConfig.java
+++ b/src/beast/app/beauti/BeautiConfig.java
@@ -1,6 +1,7 @@
 package beast.app.beauti;
 
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -165,11 +166,13 @@ public class BeautiConfig extends BEASTObject {
     }
 
     /**
+     * if fileArray == null, then use getAlignments(doc)
      * @param doc
      * @param parent
+     * @param fileArray
      * @return a list of alignments based on the user selected alignment provider
      */
-    public List<BEASTInterface> selectAlignments(BeautiDoc doc, JComponent parent) {
+    public List<BEASTInterface> selectAlignments(BeautiDoc doc, JComponent parent, File[] fileArray) {
         List<BeautiAlignmentProvider> providers = alignmentProvider;
         BeautiAlignmentProvider selectedProvider = null;
         if (providers.size() == 1) {
@@ -183,7 +186,7 @@ public class BeautiConfig extends BEASTObject {
                 return null;
             }
         }
-        List<BEASTInterface> beastObjects = selectedProvider.getAlignments(doc);
+        List<BEASTInterface> beastObjects = selectedProvider.getAlignments(doc, fileArray);
         // create taxon sets, if any
         if (beastObjects != null) {
 	        for (BEASTInterface o : beastObjects) {
diff --git a/src/beast/app/beauti/BeautiDoc.java b/src/beast/app/beauti/BeautiDoc.java
index c1a6d86..6b7a909 100644
--- a/src/beast/app/beauti/BeautiDoc.java
+++ b/src/beast/app/beauti/BeautiDoc.java
@@ -4,7 +4,6 @@ package beast.app.beauti;
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
@@ -69,8 +68,8 @@ import beast.evolution.substitutionmodel.SubstitutionModel;
 import beast.evolution.tree.TraitSet;
 import beast.evolution.tree.Tree;
 import beast.math.distributions.MRCAPrior;
+import beast.math.distributions.Normal;
 import beast.math.distributions.ParametricDistribution;
-import beast.math.distributions.Uniform;
 import beast.util.JSONProducer;
 import beast.util.NexusParser;
 import beast.util.XMLParser;
@@ -131,6 +130,11 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     private String templateName = null;
     private String templateFileName = STANDARD_TEMPLATE;
 
+    // used to scale *BEAST and StarBEAST2 species (tree) operator rates
+    // so that 20% of operator weights is dedicated to species operators
+    final private double speciesOperatorsFraction = 0.20;
+    private double speciesOperatorsScale = -1.0;
+
     Map<String, String> tipTextMap = new HashMap<>();
 
     /**
@@ -720,6 +724,11 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     public void save(File file) throws IOException  {
         determinePartitions();
         scrubAll(false, false);
+
+        if (autoUpdateOperatorWeights) {
+            reweightSpeciesPartitionOperators();
+        }
+
         // String xml = new XMLProducer().toXML(mcmc.get(), );
         String spec = null;
         if (file.getPath().toLowerCase().endsWith(".json")) {
@@ -730,6 +739,10 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         FileWriter outfile = new FileWriter(file);
         outfile.write(spec);
         outfile.close();
+
+        if (autoUpdateOperatorWeights) {
+            revertSpeciesPartitionOperators();
+        }
     } // save
 
     private String toJSON() {
@@ -1130,7 +1143,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
                 // process MRCA priors
                 for (String id : pluginmap.keySet()) {
-                    if (id.endsWith(".prior")) {
+                    if (id != null && id.endsWith(".prior")) {
                     	BEASTInterface beastObject = pluginmap.get(id);
                         if (beastObject instanceof MRCAPrior) {
                             MRCAPrior prior = (MRCAPrior) beastObject;
@@ -1177,7 +1190,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             templates.add(beautiConfig.hyperPriorTemplate);
             for (BEASTInterface beastObject : pluginmap.values()) {
                 if (beastObject instanceof RealParameter) {
-                    if (beastObject.getID().startsWith("parameter.")) {
+                    if (beastObject.getID() != null && beastObject.getID().startsWith("parameter.")) {
                         PartitionContext context = new PartitionContext(beastObject.getID().substring("parameter.".length()));
                         applyBeautiRules(templates, isInitial, context);
                     }
@@ -1195,10 +1208,6 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         } catch (Exception e) {
             Log.err.println(e.getMessage());
         }
-
-        if (autoUpdateOperatorWeights) {
-        	reweightSpeciesPartitionOperators();
-        }
     } // scrubAll
 
     protected void setUpActivePlugins() {
@@ -1494,33 +1503,43 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
       * *BEAST analyses, this bit of code has no effect.
       */
     private void reweightSpeciesPartitionOperators() {
-    	if (!(mcmc.get() instanceof MCMC)) {
-    		return;
-    	}
+    	if (!(mcmc.get() instanceof MCMC)) return;
+
     	List<Operator> speciesOperators = new ArrayList<>();
-    	double totalWeight = 0;
-    	double speciesWeight = 0;
+    	double geneOperatorsWeight = 0;
+    	double speciesOperatorsWeight = 0;
     	for (Operator operator : ((MCMC)mcmc.get()).operatorsInput.get()) {
 			if (operator.getID().endsWith("Species")) {
 				speciesOperators.add(operator);
-				speciesWeight += operator.getWeight();
+				speciesOperatorsWeight += operator.getWeight();
+			} else {
+			    geneOperatorsWeight += operator.getWeight();
 			}
-			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
-    		final double fraction = 0.2;
-    		//double scale = fraction/(1.0 - fraction) / (speciesWeight / (totalWeight - speciesWeight));
-    		double scale = fraction /(1-fraction) * ((totalWeight-speciesWeight) / speciesWeight);
+        // we have a Species-related operator AND an alignment
+    	if (speciesOperatorsWeight > 0 && geneOperatorsWeight > 0) {
+    	    final double targetWeight = (speciesOperatorsFraction * geneOperatorsWeight) / (1.0 - speciesOperatorsFraction);
+    		speciesOperatorsScale = targetWeight / speciesOperatorsWeight;
     		for (Operator operator : speciesOperators) {
-    			operator.m_pWeight.setValue(scale * operator.getWeight(), operator);
+    			operator.m_pWeight.setValue(operator.getWeight() * speciesOperatorsScale, operator);
     		}
+    	} else {
+    	    speciesOperatorsScale = -1.0;
     	}
-
 	}
 
+    private void revertSpeciesPartitionOperators() {
+        if (!(mcmc.get() instanceof MCMC)) return;
+        if (speciesOperatorsScale < 0.0) return;
+
+        for (Operator operator : ((MCMC)mcmc.get()).operatorsInput.get()) {
+            if (operator.getID().endsWith("Species")) {
+                operator.m_pWeight.setValue(operator.getWeight() / speciesOperatorsScale, operator);
+            }
+        }
+    }
+
 	public BEASTInterface addAlignmentWithSubnet(PartitionContext context, BeautiSubTemplate template)  {
         BEASTInterface data = template.createSubNet(context, true);
         alignments.add((Alignment) data);
@@ -2451,6 +2470,14 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
 	public void addMRCAPrior(MRCAPrior mrcaPrior) {
 			Tree tree = (Tree) pluginmap.get("Tree.t:" + alignments.get(0).getID());
+			if (tree == null) {
+				for (String key : pluginmap.keySet()) {
+					if (key.startsWith("Tree.t:")) {
+						tree = (Tree) pluginmap.get(key);
+						break;
+					}
+				}
+			}
 			// TODO: make sure we have the appropriate tree
 			CompoundDistribution prior = (CompoundDistribution) pluginmap.get("prior");
 			mrcaPrior.treeInput.setValue(tree, mrcaPrior);
@@ -2470,13 +2497,13 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 						taxaset.put(taxa.get(i).getID(), taxa.get(i));
 					}
 				}
-				if (distr instanceof Uniform && ((Uniform)distr).lowerInput.get() == ((Uniform)distr).upperInput.get()) {
+				if (distr instanceof Normal && (Double.isInfinite(((Normal)distr).sigmaInput.get().getValue()))) {
 					// it is a 'fixed' calibration, no need to add a distribution
 				} else {
 					prior.pDistributions.setValue(mrcaPrior, prior);
 				}
 			}
-			if (t.taxonsetInput.get().size() == 1) {
+			if (t.taxonsetInput.get().size() == 1 && distr != null) {
 				// it is a calibration on a tip -- better start sampling that tip
 		        TipDatesRandomWalker operator = new TipDatesRandomWalker();
 		        t.initAndValidate();
diff --git a/src/beast/app/beauti/GuessPatternDialog.java b/src/beast/app/beauti/GuessPatternDialog.java
index 4653762..3811c4b 100644
--- a/src/beast/app/beauti/GuessPatternDialog.java
+++ b/src/beast/app/beauti/GuessPatternDialog.java
@@ -1,10 +1,6 @@
 package beast.app.beauti;
 
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
+import java.awt.*;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -33,18 +29,25 @@ import beast.core.util.Log;
 
 public class GuessPatternDialog extends JDialog {
     private static final long serialVersionUID = 1L;
-    public static final String EXAMPLE_FORMAT = "<html>A proper trait file is tab delimited. <br>"
-            + "The first row is always <font color=red>traits</font> followed by the keyword <br>"
-            + "(e.g. <font color=red>species</font> in *BEAST) in the second column and separated <br>"
-            + "by <font color=red>tab</font>. The rest rows are mapping taxa to species, which list <br>"
-            + "taxon name in the first column and species name in the second column separated by <br>"
-            + "<font color=red>tab</font>. For example: <br>" + "traits\tspecies<br>" + "taxon1\tspeciesA<br>"
-            + "taxon2\tspeciesA<br>" + "taxon3\tspeciesB<br>" + "... ...<br>"
-            + "Once mapping file is loaded, the trait named by keyword <font color=red>species</font> <br>"
-            + "is displayed in the main panel, and the message of using *BEAST is also displayed on <br>"
-            + "the bottom of main frame.<br>"
-            + "For multi-alignment, the default of *BEAST is unlinking all models: substitution model, <br>"
-            + "clock model, and tree models.</html>";
+
+    private static String TRAIT_FILE_HELP_MESSAGE =
+            "This option allows trait values (such as species, tip dates and sample locations) " +
+                    "to be specified  using a file which links each taxon " +
+                    "with a trait value.  The file must contain one row per " +
+                    "taxon, with each row containing the taxon name and the " +
+                    "trait value separated by a TAB (not a space!) character.\n" +
+                    "\n" +
+                    "For instance, a file specifying the ages of three taxa named " +
+                    "taxonA, taxonB and taxonC should contain the following:\n" +
+                    "\n" +
+                    "taxonA 0.0\n" +
+                    "taxonB 0.1\n" +
+                    "taxonC 0.2\n" +
+                    "\n" +
+                    "where the gap between each taxon name and the numeric value " +
+                    "representing the age must be a TAB.";
+
+
 
     public enum Status {
         canceled, pattern, trait
@@ -206,8 +209,19 @@ public class GuessPatternDialog extends JDialog {
         JButton btnHelp = new JButton("?");
         btnHelp.setToolTipText("Show format of trait file");
         btnHelp.addActionListener(e -> {
-                JOptionPane.showMessageDialog(m_parent, EXAMPLE_FORMAT);
-            });
+	        JOptionPane pane = new JOptionPane() {
+        	    @Override
+        	    public int getMaxCharactersPerLineCount() {
+        	        return 70;
+        	    }
+	        };
+	        pane.setMessage(TRAIT_FILE_HELP_MESSAGE);
+	        pane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
+
+	        JDialog dialog = pane.createDialog(this, "Message");
+	        dialog.setModal(true);
+	        dialog.setVisible(true);
+        });
         GridBagConstraints gbc_btnHelp = new GridBagConstraints();
         gbc_btnHelp.insets = new Insets(0, 0, 5, 5);
         gbc_btnHelp.gridx = 4;
diff --git a/src/beast/app/beauti/MRCAPriorInputEditor.java b/src/beast/app/beauti/MRCAPriorInputEditor.java
index 18f0632..c8a00e5 100644
--- a/src/beast/app/beauti/MRCAPriorInputEditor.java
+++ b/src/beast/app/beauti/MRCAPriorInputEditor.java
@@ -166,6 +166,9 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
 				MRCAPrior prior = (MRCAPrior) list.get(itemNr);
 				doc.disconnect(prior, "prior", "distribution");
 				doc.disconnect(prior, "tracelog", "log");
+				if (prior.onlyUseTipsInput.get()) {
+					disableTipSampling();
+				}
 				doc.unregisterPlugin(prior);
 				refreshPanel();
 			}        	
diff --git a/src/beast/app/treeannotator/TreeAnnotator.java b/src/beast/app/treeannotator/TreeAnnotator.java
index 5601b64..791989c 100644
--- a/src/beast/app/treeannotator/TreeAnnotator.java
+++ b/src/beast/app/treeannotator/TreeAnnotator.java
@@ -25,23 +25,8 @@
 
 package beast.app.treeannotator;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
+import java.io.*;
+import java.util.*;
 
 import javax.swing.JFrame;
 
@@ -87,22 +72,85 @@ public class TreeAnnotator {
     	abstract boolean hasNext();
     	abstract Tree next() throws IOException;
     	abstract void reset() throws IOException;
+
+
+        String inputFileName;
+        int burninCount = 0;
+        int totalTrees = 0;
+        boolean isNexus = true;
+
+        /** determine number of trees in the file,
+    	 * and number of trees to skip as burnin
+    	 * @throws IOException
+    	 * @throws FileNotFoundException **/
+    	void countTrees(int burninPercentage) throws IOException  {
+            BufferedReader fin = new BufferedReader(new FileReader(new File(inputFileName)));
+            if (!fin.ready()) {
+            	throw new IOException("File appears empty");
+            }
+        	String str = fin.readLine();
+            if (!str.toUpperCase().trim().startsWith("#NEXUS")) {
+            	// the file contains a list of Newick trees instead of a list in Nexus format
+            	isNexus = false;
+            	if (str.trim().length() > 0) {
+            		totalTrees = 1;
+            	}
+            }
+            while (fin.ready()) {
+            	str = fin.readLine();
+                if (isNexus) {
+                    if (str.trim().toLowerCase().startsWith("tree ")) {
+                    	totalTrees++;
+                    }
+                } else if (str.trim().length() > 0) {
+            		totalTrees++;
+                }
+            }
+            fin.close();
+
+            burninCount = Math.max(0, (burninPercentage * totalTrees)/100);
+
+            progressStream.println("Processing " + (totalTrees - burninCount) + " trees from file" +
+                    (burninPercentage > 0 ? " after ignoring first " + burninPercentage + "% = " + burninCount + " trees." : "."));
+		}
+
     }    
     
     class FastTreeSet extends TreeSet {
     	int current = 0;
     	Tree [] trees;
-    	
+
     	public FastTreeSet(String inputFileName, int burninPercentage) throws IOException  {
-            progressStream.println("0              25             50             75            100");
-            progressStream.println("|--------------|--------------|--------------|--------------|");
-    		TreeSetParser parser = new TreeSetParser(burninPercentage, false);
-	      	Node [] roots = parser.parseFile(inputFileName);
-	      	trees = new Tree[roots.length];
-	      	int i = 0;
-	      	for (Node root : roots) {
-	      		trees[i++] = new Tree(root);
-	      	}
+            this.inputFileName = inputFileName;
+            countTrees(burninPercentage);
+
+            List<Tree> parsedTrees;
+            if (isNexus) {
+                NexusParser nexusParser = new NexusParser();
+                nexusParser.parseFile(new File(inputFileName));
+                parsedTrees = nexusParser.trees;
+            } else {
+                BufferedReader fin = new BufferedReader(new FileReader(inputFileName));
+                parsedTrees = new ArrayList<>();
+                while (fin.ready()) {
+                    String line = fin.readLine().trim();
+
+                    Tree thisTree;
+                    try {
+                        thisTree = new TreeParser(null, line, 0, false);
+                    } catch (ArrayIndexOutOfBoundsException e) {
+                        thisTree = new TreeParser(null, line, 1, false);
+                    }
+
+                    parsedTrees.add(thisTree);
+                }
+                fin.close();
+            }
+
+            int treesToUse = parsedTrees.size() - burninCount;
+	      	trees = new Tree[treesToUse];
+            for (int i=burninCount; i<parsedTrees.size(); i++)
+                trees[i-burninCount] = parsedTrees.get(i);
 		}
 
 		@Override
@@ -127,55 +175,19 @@ public class TreeAnnotator {
     	int lineNr;
         public Map<String, String> translationMap = null;
         public List<String> taxa;
-    	
-        int burninCount = 0;
-        int totalTrees = 0;
-        boolean isNexus = true;
-        BufferedReader fin;
-        String inputFileName;
+
         // label count origin for NEXUS trees
         int origin = -1;
-       
+
+        BufferedReader fin;
+
         MemoryFriendlyTreeSet(String inputFileName, int burninPercentage) throws IOException  {
     		this.inputFileName = inputFileName;
-    		init(burninPercentage);
-        	progressStream.println("Processing " + (totalTrees - burninCount) + " trees from file" +
-                    (burninPercentage > 0 ? " after ignoring first " + burninPercentage + "% = " + burninCount + " trees." : "."));
-    		
-    		
+    		countTrees(burninPercentage);
+
+            fin = new BufferedReader(new FileReader(inputFileName));
     	}
 
-    	/** determine number of trees in the file,
-    	 * and number of trees to skip as burnin 
-    	 * @throws IOException 
-    	 * @throws FileNotFoundException **/
-    	private void init(int burninPercentage) throws IOException  {
-            fin = new BufferedReader(new FileReader(new File(inputFileName)));
-            if (!fin.ready()) {
-            	throw new IOException("File appears empty");
-            }
-        	String str = nextLine();
-            if (!str.toUpperCase().trim().startsWith("#NEXUS")) {
-            	// the file contains a list of Newick trees instead of a list in Nexus format
-            	isNexus = false;
-            	if (str.trim().length() > 0) {
-            		totalTrees = 1;
-            	}
-            }
-            while (fin.ready()) {
-            	str = nextLine();
-                if (isNexus) {
-                    if (str.trim().toLowerCase().startsWith("tree ")) {
-                    	totalTrees++;
-                    }
-                } else if (str.trim().length() > 0) {
-            		totalTrees++;
-                }            	
-            }
-            fin.close();
-            
-            burninCount = Math.max(0, (burninPercentage * totalTrees)/100);
-		}
 
     	@Override
 		void reset() throws FileNotFoundException  {
@@ -415,7 +427,7 @@ public class TreeAnnotator {
 
 
     // Messages to stderr, output to stdout
-    private static PrintStream progressStream = Log.err;
+    static PrintStream progressStream = Log.err;
 
 //    private final String location1Attribute = "longLat1";
 //    private final String location2Attribute = "longLat2";
@@ -445,10 +457,6 @@ public class TreeAnnotator {
         totalTrees = 10000;
         totalTreesUsed = 0;
 
-        //progressStream.println("Reading trees (bar assumes 10,000 trees)...");
-
-        int stepSize = Math.max(totalTrees / 60, 1);
-
         try {
         	if (lowMemory) {
         		treeSet = new MemoryFriendlyTreeSet(inputFileName, burninPercentage);
@@ -461,7 +469,6 @@ public class TreeAnnotator {
         	return;
         }
 
-        
         if (targetOption != Target.USER_TARGET_TREE) {
             try {
             	treeSet.reset();
@@ -502,12 +509,26 @@ public class TreeAnnotator {
             cladeSystem.calculateCladeCredibilities(totalTreesUsed);
 
             progressStream.println("Total trees have " + totalTrees + ", where " + totalTreesUsed + " are used.");
-//            if (burninPercentage > 0) {
-//                progressStream.println("Ignoring first " + burninPercentage + "% trees.");
-//            }
 
             progressStream.println("Total unique clades: " + cladeSystem.getCladeMap().keySet().size());
             progressStream.println();
+        }  else {
+            // even when a user specificed target tree is provided we still need to count the totalTreesUsed for subsequent steps.
+            treeSet.reset();
+            while (treeSet.hasNext()) {
+                Tree tree = treeSet.next();
+                tree.getLeafNodeCount();
+                if (tree.getDirectAncestorNodeCount() > 0 && !SAmode) {
+                    SAmode = true;
+                    Log.err.println("A tree with a sampled ancestor is found. Turning on\n the sampled ancestor " +
+                            "summary analysis.");
+                    if (heightsOption == HeightsSummary.CA_HEIGHTS) {
+                        throw new RuntimeException("The common ancestor height is not \n available for trees with sampled " +
+                                "ancestors. Please choose \n another height summary option");
+                    }
+                }
+                totalTreesUsed++;
+            }
         }
 
         Tree targetTree = null;
@@ -555,13 +576,13 @@ public class TreeAnnotator {
         progressStream.println("0              25             50             75            100");
         progressStream.println("|--------------|--------------|--------------|--------------|");
 
-        stepSize = Math.max(totalTreesUsed / 60, 1);
+        int stepSize = Math.max(totalTreesUsed / 60, 1);
         int reported = 0;
 
         // this call increments the clade counts and it shouldn't
         // this is remedied with removeClades call after while loop below
         cladeSystem = new CladeSystem(targetTree);
-        int totalTreesUsed = 0;
+        int totalTreesUsedNew = 0;
         try {
             int counter = 0;
             treeSet.reset();
@@ -578,14 +599,13 @@ public class TreeAnnotator {
             	    }
                     progressStream.flush();
                 }
-                totalTreesUsed++;
+                totalTreesUsedNew++;
                 counter++;
         	}
         	
             cladeSystem.removeClades(targetTree.getRoot(), true);
-            //progressStream.println("totalTreesUsed=" + totalTreesUsed);
-            this.totalTreesUsed = totalTreesUsed;
-            cladeSystem.calculateCladeCredibilities(totalTreesUsed);
+            this.totalTreesUsed = totalTreesUsedNew;
+            cladeSystem.calculateCladeCredibilities(totalTreesUsedNew);
         } catch (Exception e) {
             Log.err.println("Error Parsing Input Tree: " + e.getMessage());
             return;
@@ -599,7 +619,7 @@ public class TreeAnnotator {
             annotateTree(cladeSystem, targetTree.getRoot(), null, heightsOption);
 
             if( heightsOption == HeightsSummary.CA_HEIGHTS ) {
-                setTreeHeightsByCA(targetTree);
+                setTreeHeightsByCA(targetTree, targetOption);
             }
         } catch (Exception e) {
         	e.printStackTrace();
@@ -639,7 +659,7 @@ public class TreeAnnotator {
 			processMetaData(child);
 		}
 		Set<String> metaDataNames = node.getMetaDataNames(); 
-		if (metaDataNames != null) {
+		if (metaDataNames != null && !metaDataNames.isEmpty()) {
 			String metadata = "";
 			for (String name : metaDataNames) {
 				Object value = node.getMetaData(name);
@@ -1490,7 +1510,7 @@ public class TreeAnnotator {
         boolean handleAttribute(Node node, String attributeName, double[] values);
     }
 
-    boolean setTreeHeightsByCA(Tree targetTree) throws IOException
+    boolean setTreeHeightsByCA(Tree targetTree, Target targetOption) throws IOException
              {
         progressStream.println("Setting node heights...");
         progressStream.println("0              25             50             75            100");
@@ -1554,7 +1574,10 @@ public class TreeAnnotator {
             counter++;
 
         }
-        targetTree.initAndValidate();
+
+        if (targetOption != Target.USER_TARGET_TREE)
+            targetTree.initAndValidate();
+
         cladeSystem.removeClades(targetTree.getRoot(), true);
         for (int k = 0; k < clades; ++k) {
             ths[k] /= totalTreesUsed;
diff --git a/src/beast/app/treeannotator/TreeSetParser.java b/src/beast/app/treeannotator/TreeSetParser.java
index af038c7..d42943c 100644
--- a/src/beast/app/treeannotator/TreeSetParser.java
+++ b/src/beast/app/treeannotator/TreeSetParser.java
@@ -30,6 +30,7 @@ import java.util.Vector;
 
 import beast.core.util.Log;
 import beast.evolution.tree.Node;
+import beast.evolution.tree.Tree;
 
 public class TreeSetParser {
 	/**
@@ -281,7 +282,7 @@ public class TreeSetParser {
 		String s = fin.readLine();
 		fileRead += s.length();
 		if (fileRead > fileMarked - 10) {
-			Log.warning.print("*");
+			TreeAnnotator.progressStream.print("*");
 			fileMarked += fileStep;
 			k++;
 		}
diff --git a/src/beast/app/util/Utils6.java b/src/beast/app/util/Utils6.java
index fb32c7e..eeb109d 100644
--- a/src/beast/app/util/Utils6.java
+++ b/src/beast/app/util/Utils6.java
@@ -119,12 +119,12 @@ public class Utils6 {
 			// /Library/Frameworks/CUDA.framework
 			// /Developer/NVIDIA
 			// /usr/local/cuda
+			// there is evidence of CUDA being installed on this computer
+			// try to create a BeagleTreeLikelihood using a separate process
+			try {
 			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";
@@ -157,9 +157,9 @@ public class Utils6 {
 				    	  return false;
 				      }
 				    }
-				    catch (Exception err) {
-				      err.printStackTrace();
-				    }
+				}
+		    catch (Exception err) {
+			      err.printStackTrace();
 			}
 			
 		}
diff --git a/src/beast/evolution/operators/NodeReheight.java b/src/beast/evolution/operators/NodeReheight.java
index 88b429b..845499a 100644
--- a/src/beast/evolution/operators/NodeReheight.java
+++ b/src/beast/evolution/operators/NodeReheight.java
@@ -40,7 +40,7 @@ public class NodeReheight extends TreeOperator {
         final List<Taxon> list = taxonSetInput.get().taxonsetInput.get();
         
         if (list.size() <= 1) {
-        	Log.warning.println("NodeReheight operator requires at least 2 taxa while the taxon set (id=" + taxonSetInput.get().getID() +") has only " + list.size() + " taxa. "
+        	Log.err.println("NodeReheight operator requires at least 2 taxa while the taxon set (id=" + taxonSetInput.get().getID() +") has only " + list.size() + " taxa. "
         			+ "If the XML file was set up in BEAUti, this probably means a taxon assignment needs to be set up in the taxonset panel.");
         	// assume we are in BEAUti, back off for now
         	return;
diff --git a/src/beast/evolution/tree/Tree.java b/src/beast/evolution/tree/Tree.java
index 7bd4715..964955d 100644
--- a/src/beast/evolution/tree/Tree.java
+++ b/src/beast/evolution/tree/Tree.java
@@ -60,7 +60,7 @@ public class Tree extends StateNode implements TreeInterface {
      * array of taxa names for the nodes in the tree
      * such that m_sTaxaNames[node.getNr()] == node.getID()*
      */
-    String[] m_sTaxaNames = null;
+    protected String[] m_sTaxaNames = null;
 
     /**
      * Trait set which specifies leaf node times.
@@ -111,8 +111,11 @@ public class Tree extends StateNode implements TreeInterface {
         // ensure all nodes have their taxon names set up
         String [] taxa = getTaxaNames();
         for (int i = 0; i < getNodeCount() && i < taxa.length; i++) {
-        	if (taxa[i] != null)
-        		m_nodes[i].setID(taxa[i]);
+            if( taxa[i] != null ) {
+                if( m_nodes[i].getID() == null ) {
+                    m_nodes[i].setID(taxa[i]);
+                }
+            }
         }
     }
 
@@ -332,27 +335,32 @@ public class Tree extends StateNode implements TreeInterface {
      */
     public String [] getTaxaNames() {
          if (m_sTaxaNames == null || (m_sTaxaNames.length == 1 && m_sTaxaNames[0] == null) || m_sTaxaNames.length == 0) {
-            final TaxonSet taxonSet = m_taxonset.get();
-            if (taxonSet != null) {
-                final List<String> txs = taxonSet.asStringList();
-                m_sTaxaNames = txs.toArray(new String[txs.size()]);
-            } else {
-                m_sTaxaNames = new String[getNodeCount()];
-                collectTaxaNames(getRoot());
-                List<String> taxaNames = new ArrayList<>();
-                for (String name : m_sTaxaNames) {
-                	if (name != null) {
-                		taxaNames.add(name);
-                	}
-                }
-                m_sTaxaNames = taxaNames.toArray(new String[]{});
-                
+             // take taxa from tree if one exists
+             if( root != null ) {
+                 m_sTaxaNames = new String[getNodeCount()];
+                 collectTaxaNames(getRoot());
+                 List<String> taxaNames = new ArrayList<>();
+                 for (String name : m_sTaxaNames) {
+                     if (name != null) {
+                         taxaNames.add(name);
+                     }
+                 }
+                 m_sTaxaNames = taxaNames.toArray(new String[]{});
+             } else {
+                 // no tree? use taxon set.
+                 final TaxonSet taxonSet = m_taxonset.get();
+                 if (taxonSet != null) {
+                     final List<String> txs = taxonSet.asStringList();
+                     m_sTaxaNames = txs.toArray(new String[txs.size()]);
+                 } else {
+                    Log.err("No taxa specified");
+                 }
             }
         }
 
         // sanity check
         if (m_sTaxaNames.length == 1 && m_sTaxaNames[0] == null) {
-            Log.warning.println("WARNING: tree interrogated for taxa, but the tree was not initialised properly. To fix this, specify the taxonset input");
+            Log.warning("WARNING: tree interrogated for taxa, but the tree was not initialised properly. To fix this, specify the taxonset input");
         }
         return m_sTaxaNames;
     }
@@ -948,7 +956,10 @@ public class Tree extends StateNode implements TreeInterface {
         }
         m_nodes = tmp;
         nodeCount--;
-        leafNodeCount--;
+        if (i < leafNodeCount)
+            leafNodeCount--;
+        else
+            internalNodeCount--;
     }
 
     /**
@@ -962,7 +973,10 @@ public class Tree extends StateNode implements TreeInterface {
         newNode.setNr(nodeCount);
         m_nodes = tmp;
         nodeCount++;
-        leafNodeCount++;
+        if (newNode.getChildCount() > 0)
+            internalNodeCount++;
+        else
+            leafNodeCount++;
     }
 
     public int getDirectAncestorNodeCount() {
diff --git a/src/beast/evolution/tree/TreeWithMetaDataLogger.java b/src/beast/evolution/tree/TreeWithMetaDataLogger.java
index 1a00e0e..74bc86b 100644
--- a/src/beast/evolution/tree/TreeWithMetaDataLogger.java
+++ b/src/beast/evolution/tree/TreeWithMetaDataLogger.java
@@ -14,6 +14,7 @@ import beast.core.Input.Validate;
 import beast.core.Loggable;
 import beast.core.StateNode;
 import beast.core.parameter.Parameter;
+import beast.core.parameter.RealParameter;
 import beast.evolution.branchratemodel.BranchRateModel;
 
 @Description("Logs tree annotated with metadata and/or rates")
@@ -23,7 +24,7 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
     final public Input<List<Function>> parameterInput = new Input<>("metadata", "meta data to be logged with the tree nodes",new ArrayList<>());
     final public Input<BranchRateModel.Base> clockModelInput = new Input<>("branchratemodel", "rate to be logged with branches of the tree");
     final public Input<Boolean> substitutionsInput = new Input<>("substitutions", "report branch lengths as substitutions (branch length times clock rate for the branch)", false);
-    final public Input<Integer> decimalPlacesInput = new Input<>("dp", "the number of decimal places to use writing branch lengths and rates, use -1 for full precision (default = full precision)", -1);
+    final public Input<Integer> decimalPlacesInput = new Input<>("dp", "the number of decimal places to use writing branch lengths, rates and real-valued metadata, use -1 for full precision (default = full precision)", -1);
 
     
     boolean someMetaDataNeedsLogging;
@@ -33,6 +34,15 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
 
     @Override
     public void initAndValidate() {
+        int dp = decimalPlacesInput.get();
+        if (dp < 0) {
+            df = null;
+        } else {
+            // just new DecimalFormat("#.######") (with dp time '#' after the decimal)
+            df = new DecimalFormat("#."+new String(new char[dp]).replace('\0', '#'));
+            df.setRoundingMode(RoundingMode.HALF_UP);
+        }
+
         if (parameterInput.get().size() == 0 && clockModelInput.get() == null) {
         	someMetaDataNeedsLogging = false;
         	return;
@@ -43,16 +53,6 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
         if (clockModelInput.get() != null) {
         	substitutions = substitutionsInput.get();
         }
-
-        int dp = decimalPlacesInput.get();
-
-        if (dp < 0) {
-            df = null;
-        } else {
-            // just new DecimalFormat("#.######") (with dp time '#' after the decimal)
-            df = new DecimalFormat("#."+new String(new char[dp]).replace('\0', '#'));
-            df.setRoundingMode(RoundingMode.HALF_UP);
-        }
     }
 
     @Override
@@ -120,14 +120,24 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
 		            	if (dim > 1) {
 			            	buf.append('{');
 			            	for (int i = 0; i < dim; i++) {
-				            	buf.append(p.getMatrixValue(node.labelNr, i));
+						if (metadata instanceof RealParameter) {
+							RealParameter rp = (RealParameter) metadata;
+							appendDouble(buf, rp.getMatrixValue(node.labelNr, i));
+						} else {
+							buf.append(p.getMatrixValue(node.labelNr, i));
+						}
 				            	if (i < dim - 1) {
 					            	buf.append(',');
 				            	}
 			            	}
 			            	buf.append('}');
 		            	} else {
-			            	buf.append(metadata.getArrayValue(node.labelNr));
+					if (metadata instanceof RealParameter) {
+						RealParameter rp = (RealParameter) metadata;
+						appendDouble(buf, rp.getArrayValue(node.labelNr));
+					} else {
+						buf.append(metadata.getArrayValue(node.labelNr));
+					}
 		            	}
 		            } else {
 		            	buf.append(metadata.getArrayValue(node.labelNr));
diff --git a/src/beast/util/AddOnManager.java b/src/beast/util/AddOnManager.java
index 05f55a9..ce326dc 100644
--- a/src/beast/util/AddOnManager.java
+++ b/src/beast/util/AddOnManager.java
@@ -846,69 +846,79 @@ public class AddOnManager {
         checkInstalledDependencies(packages);
 
         for (String jarDirName : getBeastDirectories()) {
-            File versionFile = new File(jarDirName + "/version.xml");
-            String packageNameAndVersion = null;
-            if (versionFile.exists()) {
-                try {
-                    // print name and version of package
-                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-                    Document doc = factory.newDocumentBuilder().parse(versionFile);
-                    Element addon = doc.getDocumentElement();
-                    packageNameAndVersion = addon.getAttribute("name") + " v" + addon.getAttribute("version");
-                    Log.warning.println("Loading package " + packageNameAndVersion);
-                } catch (Exception e) {
-                	// too bad, won't print out any info
+            try {
+                File versionFile = new File(jarDirName + "/version.xml");
+                String packageNameAndVersion = null;
+                if (versionFile.exists()) {
+                    try {
+                        // print name and version of package
+                        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                        Document doc = factory.newDocumentBuilder().parse(versionFile);
+                        Element addon = doc.getDocumentElement();
+                        packageNameAndVersion = addon.getAttribute("name") + " v" + addon.getAttribute("version");
+                        Log.warning.println("Loading package " + packageNameAndVersion);
+                    } catch (Exception e) {
+                        // too bad, won't print out any info
+
+                        // File is called version.xml, but is not a Beast2 version file
+                        // Log.debug.print("Skipping "+jarDirName+" (not a Beast2 package)");
+                    }
                 }
-            }
-            File jarDir = new File(jarDirName + "/lib");
-            if (!jarDir.exists()) {
-                jarDir = new File(jarDirName + "\\lib");
-            }
-            if (jarDir.exists() && jarDir.isDirectory()) {
-                for (String fileName : jarDir.list()) {
-                    if (fileName.endsWith(".jar")) {
-                        Log.debug.print("Probing: " + fileName + " ");
-                        // check that we are not reload existing classes
-                        String loadedClass = null;
-                        try {
-                            JarInputStream jarFile = new JarInputStream
-                                    (new FileInputStream(jarDir.getAbsolutePath() + "/" + fileName));
-                            JarEntry jarEntry;
-
-                            while (loadedClass == null) {
-                                jarEntry = jarFile.getNextJarEntry();
-                                if (jarEntry == null) {
-                                    break;
-                                }
-                                if ((jarEntry.getName().endsWith(".class"))) {
-                                    String className = jarEntry.getName().replaceAll("/", "\\.");
-                                    className = className.substring(0, className.lastIndexOf('.'));
-                                    try {
-                                        /*Object o =*/ Class.forName(className);
-                                        loadedClass = className;
-                                    } catch (Exception e) {
-                                        // TODO: handle exception
+                File jarDir = new File(jarDirName + "/lib");
+                if (!jarDir.exists()) {
+                    jarDir = new File(jarDirName + "\\lib");
+                }
+                if (jarDir.exists() && jarDir.isDirectory()) {
+                    for (String fileName : jarDir.list()) {
+                        if (fileName.endsWith(".jar")) {
+                            Log.debug.print("Probing: " + fileName + " ");
+                            // check that we are not reload existing classes
+                            String loadedClass = null;
+                            try {
+                                JarInputStream jarFile = new JarInputStream
+                                        (new FileInputStream(jarDir.getAbsolutePath() + "/" + fileName));
+                                JarEntry jarEntry;
+
+                                while (loadedClass == null) {
+                                    jarEntry = jarFile.getNextJarEntry();
+                                    if (jarEntry == null) {
+                                        break;
                                     }
-                                    if (loadedClass == null && packageNameAndVersion != null) {
-                                    	classToPackageMap.put(className, packageNameAndVersion);
+                                    if ((jarEntry.getName().endsWith(".class"))) {
+                                        String className = jarEntry.getName().replaceAll("/", "\\.");
+                                        className = className.substring(0, className.lastIndexOf('.'));
+                                        try {
+                                            /*Object o =*/
+                                            Class.forName(className);
+                                            loadedClass = className;
+                                        } catch (Exception e) {
+                                            // TODO: handle exception
+                                        }
+                                        if (loadedClass == null && packageNameAndVersion != null) {
+                                            classToPackageMap.put(className, packageNameAndVersion);
+                                        }
                                     }
                                 }
+                                jarFile.close();
+                            } catch (Exception e) {
+                                e.printStackTrace();
                             }
-                            jarFile.close();
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
 
 
-                        @SuppressWarnings("deprecation")
-                        URL url = new File(jarDir.getAbsolutePath() + "/" + fileName).toURL();
-                        if (loadedClass == null) {
-                            addURL(url);
-                        } else {
-                            Log.debug.println("Skip loading " + url + ": contains class " + loadedClass + " that is already loaded");
+                            @SuppressWarnings("deprecation")
+                            URL url = new File(jarDir.getAbsolutePath() + "/" + fileName).toURL();
+                            if (loadedClass == null) {
+                                addURL(url);
+                            } else {
+                                Log.debug.println("Skip loading " + url + ": contains class " + loadedClass + " that is already loaded");
+                            }
                         }
                     }
                 }
+            } catch (Exception e) {
+                // File exists, but cannot open the file for some reason
+                Log.debug.println("Skipping "+jarDirName+"/version.xml (unable to open file");
+                Log.warning.println("Skipping "+jarDirName+"/version.xml (unable to open file");
             }
         }
         externalJarsLoaded = true;
diff --git a/src/beast/util/NexusParser.java b/src/beast/util/NexusParser.java
index dbf9a79..75e13f1 100644
--- a/src/beast/util/NexusParser.java
+++ b/src/beast/util/NexusParser.java
@@ -19,6 +19,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import beast.core.BEASTInterface;
+import beast.core.parameter.RealParameter;
 import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.FilteredAlignment;
@@ -844,11 +845,20 @@ public class NexusParser {
             		// next get the calibration
             		str0 = strs[strs.length - 1].trim();
             		String [] strs3 = str0.split("[\\(,\\)]");
+            		RealParameter [] param = new RealParameter[strs3.length];
+            		for (int i = 1; i < strs3.length; i++) {
+            			try {
+            				param[i] = new RealParameter(strs3[i]);
+            				param[i].setID("param." + i);
+            			} catch (Exception  e) {
+							// ignore parsing errors
+						}
+            		}
             		ParametricDistribution distr  = null;
             		switch (strs3[0]) {
             		case "normal":
             			distr = new Normal();
-            			distr.initByName("mean", strs3[1], "sigma", strs3[2]);
+            			distr.initByName("mean", param[1], "sigma", param[2]);
             			distr.setID("Normal.0");
             			break;
             		case "uniform":
@@ -858,33 +868,33 @@ public class NexusParser {
             			break;
             		case "fixed":
             			// uniform with lower == upper
-            			distr = new Uniform();
-            			distr.initByName("lower", strs3[1], "upper", strs3[1]);
-            			distr.setID("Uniform.0");
+            			distr = new Normal();
+            			distr.initByName("mean", param[1], "sigma", "+Infinity");
+            			distr.setID("Normal.0");
             			break;
             		case "offsetlognormal":
             			distr = new LogNormalDistributionModel();
-            			distr.initByName("offset", strs3[1], "M", strs3[2], "S", strs3[3], "meanInRealSpace", true);
-            			distr.setID("LogNormal.0");
+            			distr.initByName("offset", strs3[1], "M", param[2], "S", param[3], "meanInRealSpace", true);
+            			distr.setID("LogNormalDistributionModel.0");
             			break;
             		case "lognormal":
             			distr = new LogNormalDistributionModel();
-            			distr.initByName("M", strs3[1], "S", strs3[2], "meanInRealSpace", true);
-            			distr.setID("LogNormal.0");
+            			distr.initByName("M", param[1], "S", param[2], "meanInRealSpace", true);
+            			distr.setID("LogNormalDistributionModel.0");
             			break;
             		case "offsetexponential":
             			distr = new Exponential();
-            			distr.initByName("offset", strs3[1], "mean", strs3[2]);
+            			distr.initByName("offset", strs3[1], "mean", param[2]);
             			distr.setID("Exponential.0");
             			break;
             		case "gamma":
             			distr = new Gamma();
-            			distr.initByName("alpha", strs3[1], "beta", strs3[2]);
+            			distr.initByName("alpha", param[1], "beta", param[2]);
             			distr.setID("Gamma.0");
             			break;
             		case "offsetgamma":
             			distr = new Gamma();
-            			distr.initByName("offset", strs3[1], "alpha", strs3[2], "beta", strs3[3]);
+            			distr.initByName("offset", strs3[1], "alpha", param[2], "beta", param[3]);
             			distr.setID("Gamma.0");
             			break;
             		default:
diff --git a/src/beast/util/TreeParser.java b/src/beast/util/TreeParser.java
index b46423e..8b496e7 100644
--- a/src/beast/util/TreeParser.java
+++ b/src/beast/util/TreeParser.java
@@ -164,7 +164,8 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
         }
 
         super.initAndValidate();
-        
+        m_sTaxaNames = null;
+
         if (sortNodesAlphabetically) {
 	        // correct for node ordering: ensure order is alphabetical
 	        for (int i = 0; i < getNodeCount() && i < labels.size(); i++) {
@@ -468,18 +469,21 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
                             }
                             node.setMetaData(key, stringValue);
                         } else if (attribctx.attribValue().vector() != null) {
-                        	try {
-	                        	String value = attribctx.attribValue().vector().getText();
-								String str = value.substring(1, value.length() - 1); 
-								String [] strs = str.split(",");
-								Double [] values = new Double[strs.length];
-								for (int j = 0; j < strs.length; j++) {
-									values[j] = Double.parseDouble(strs[j]); 
-								}
-								node.setMetaData(key, values);
-                        	} catch (Exception e) {
-                        		// ignore parsing errors
-                        	}
+                            try {
+
+                                List<NewickParser.AttribValueContext> elementContexts = attribctx.attribValue().vector().attribValue();
+
+                                Double[] values = new Double[elementContexts.size()];
+                                for (int i = 0; i < elementContexts.size(); i++)
+                                    values[i] = Double.parseDouble(elementContexts.get(i).getText());
+
+                                node.setMetaData(key, values);
+
+                            } catch (NumberFormatException ex) {
+                                throw new ParseCancellationException("Encountered vector-valued metadata entry with " +
+                                        "one or more non-numeric elements.");
+                            }
+
                         }
                     }
                 }
@@ -502,10 +506,6 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
                         || postCtx.label().number().INT() == null)
                     integerLeafLabels = false;
 
-                // RRB: next line is for debugging only?
-                @SuppressWarnings("unused")
-				String postText = postCtx.getText();
-
                 // Treat labels as node numbers in certain situations
                 if (!isLabelledNewickInput.get()
                         && postCtx.label().number() != null
diff --git a/src/beast/util/treeparser/Newick.g4 b/src/beast/util/treeparser/Newick.g4
index e22a143..708c2c5 100644
--- a/src/beast/util/treeparser/Newick.g4
+++ b/src/beast/util/treeparser/Newick.g4
@@ -16,14 +16,15 @@ attrib: attribKey=STRING '=' attribValue ;
 
 attribValue: number | STRING | vector;
 
-number: INT | FLOAT ;
+number: INT | FLOAT | FLOAT_SCI;
 
 vector: '{' attribValue (',' attribValue)* '}' ;
 
 
 // Lexer rules:
 
-FLOAT : '-'? NNINT ('.' D*) ([eE] '-'? D+)? ;
+FLOAT_SCI: '-'? ((NNINT? ('.' D+)) | (NNINT ('.' D+)?)) ([eE] '-'? D+);
+FLOAT : '-'? ((NNINT? ('.' D+)) | (NNINT ('.' D*)));
 INT : '-'? NNINT;
 fragment NNINT : '0' | NZD D* ;
 fragment NZD : [1-9] ;
diff --git a/src/beast/util/treeparser/NewickBaseVisitor.java b/src/beast/util/treeparser/NewickBaseVisitor.java
index 4503959..2c895e2 100644
--- a/src/beast/util/treeparser/NewickBaseVisitor.java
+++ b/src/beast/util/treeparser/NewickBaseVisitor.java
@@ -1,4 +1,4 @@
-// Generated from Newick.g4 by ANTLR 4.5.1
+// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.3
 package beast.util.treeparser;
 import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
 
diff --git a/src/beast/util/treeparser/NewickLexer.java b/src/beast/util/treeparser/NewickLexer.java
index de1ed93..5bf9938 100644
--- a/src/beast/util/treeparser/NewickLexer.java
+++ b/src/beast/util/treeparser/NewickLexer.java
@@ -1,4 +1,4 @@
-// Generated from Newick.g4 by ANTLR 4.5.1
+// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.3
 package beast.util.treeparser;
 import org.antlr.v4.runtime.Lexer;
 import org.antlr.v4.runtime.CharStream;
@@ -11,21 +11,21 @@ import org.antlr.v4.runtime.misc.*;
 
 @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
 public class NewickLexer extends Lexer {
-	static { RuntimeMetaData.checkVersion("4.5.1", RuntimeMetaData.VERSION); }
+	static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
 
 	protected static final DFA[] _decisionToDFA;
 	protected static final PredictionContextCache _sharedContextCache =
 		new PredictionContextCache();
 	public static final int
 		T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, 
-		T__9=10, FLOAT=11, INT=12, STRING=13, WHITESPACE=14;
+		T__9=10, FLOAT_SCI=11, FLOAT=12, INT=13, STRING=14, WHITESPACE=15;
 	public static String[] modeNames = {
 		"DEFAULT_MODE"
 	};
 
 	public static final String[] ruleNames = {
 		"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", 
-		"T__9", "FLOAT", "INT", "NNINT", "NZD", "D", "STRING", "WHITESPACE"
+		"T__9", "FLOAT_SCI", "FLOAT", "INT", "NNINT", "NZD", "D", "STRING", "WHITESPACE"
 	};
 
 	private static final String[] _LITERAL_NAMES = {
@@ -33,8 +33,8 @@ public class NewickLexer extends Lexer {
 		"'}'"
 	};
 	private static final String[] _SYMBOLIC_NAMES = {
-		null, null, null, null, null, null, null, null, null, null, null, "FLOAT", 
-		"INT", "STRING", "WHITESPACE"
+		null, null, null, null, null, null, null, null, null, null, null, "FLOAT_SCI", 
+		"FLOAT", "INT", "STRING", "WHITESPACE"
 	};
 	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
 
@@ -91,40 +91,56 @@ public class NewickLexer extends Lexer {
 	public ATN getATN() { return _ATN; }
 
 	public static final String _serializedATN =
-		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\20\u0081\b\1\4\2"+
+		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\21\u00a3\b\1\4\2"+
 		"\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+
 		"\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
-		"\t\22\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\7\3\b\3\b\3\t"+
-		"\3\t\3\n\3\n\3\13\3\13\3\f\5\f<\n\f\3\f\3\f\3\f\7\fA\n\f\f\f\16\fD\13"+
-		"\f\3\f\3\f\5\fH\n\f\3\f\6\fK\n\f\r\f\16\fL\5\fO\n\f\3\r\5\rR\n\r\3\r\3"+
-		"\r\3\16\3\16\3\16\7\16Y\n\16\f\16\16\16\\\13\16\5\16^\n\16\3\17\3\17\3"+
-		"\20\3\20\3\21\6\21e\n\21\r\21\16\21f\3\21\3\21\7\21k\n\21\f\21\16\21n"+
-		"\13\21\3\21\3\21\3\21\7\21s\n\21\f\21\16\21v\13\21\3\21\5\21y\n\21\3\22"+
-		"\6\22|\n\22\r\22\16\22}\3\22\3\22\4lt\2\23\3\3\5\4\7\5\t\6\13\7\r\b\17"+
-		"\t\21\n\23\13\25\f\27\r\31\16\33\2\35\2\37\2!\17#\20\3\2\7\4\2GGgg\3\2"+
-		"\63;\3\2\62;\n\2%%\'(,-/;C\\aac|~~\5\2\13\f\17\17\"\"\u008b\2\3\3\2\2"+
-		"\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3"+
-		"\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2"+
-		"\2\2!\3\2\2\2\2#\3\2\2\2\3%\3\2\2\2\5\'\3\2\2\2\7)\3\2\2\2\t+\3\2\2\2"+
-		"\13-\3\2\2\2\r/\3\2\2\2\17\62\3\2\2\2\21\64\3\2\2\2\23\66\3\2\2\2\258"+
-		"\3\2\2\2\27;\3\2\2\2\31Q\3\2\2\2\33]\3\2\2\2\35_\3\2\2\2\37a\3\2\2\2!"+
-		"x\3\2\2\2#{\3\2\2\2%&\7=\2\2&\4\3\2\2\2\'(\7*\2\2(\6\3\2\2\2)*\7.\2\2"+
-		"*\b\3\2\2\2+,\7+\2\2,\n\3\2\2\2-.\7<\2\2.\f\3\2\2\2/\60\7]\2\2\60\61\7"+
-		"(\2\2\61\16\3\2\2\2\62\63\7_\2\2\63\20\3\2\2\2\64\65\7?\2\2\65\22\3\2"+
-		"\2\2\66\67\7}\2\2\67\24\3\2\2\289\7\177\2\29\26\3\2\2\2:<\7/\2\2;:\3\2"+
-		"\2\2;<\3\2\2\2<=\3\2\2\2=>\5\33\16\2>B\7\60\2\2?A\5\37\20\2@?\3\2\2\2"+
-		"AD\3\2\2\2B@\3\2\2\2BC\3\2\2\2CN\3\2\2\2DB\3\2\2\2EG\t\2\2\2FH\7/\2\2"+
-		"GF\3\2\2\2GH\3\2\2\2HJ\3\2\2\2IK\5\37\20\2JI\3\2\2\2KL\3\2\2\2LJ\3\2\2"+
-		"\2LM\3\2\2\2MO\3\2\2\2NE\3\2\2\2NO\3\2\2\2O\30\3\2\2\2PR\7/\2\2QP\3\2"+
-		"\2\2QR\3\2\2\2RS\3\2\2\2ST\5\33\16\2T\32\3\2\2\2U^\7\62\2\2VZ\5\35\17"+
-		"\2WY\5\37\20\2XW\3\2\2\2Y\\\3\2\2\2ZX\3\2\2\2Z[\3\2\2\2[^\3\2\2\2\\Z\3"+
-		"\2\2\2]U\3\2\2\2]V\3\2\2\2^\34\3\2\2\2_`\t\3\2\2`\36\3\2\2\2ab\t\4\2\2"+
-		"b \3\2\2\2ce\t\5\2\2dc\3\2\2\2ef\3\2\2\2fd\3\2\2\2fg\3\2\2\2gy\3\2\2\2"+
-		"hl\7$\2\2ik\13\2\2\2ji\3\2\2\2kn\3\2\2\2lm\3\2\2\2lj\3\2\2\2mo\3\2\2\2"+
-		"nl\3\2\2\2oy\7$\2\2pt\7)\2\2qs\13\2\2\2rq\3\2\2\2sv\3\2\2\2tu\3\2\2\2"+
-		"tr\3\2\2\2uw\3\2\2\2vt\3\2\2\2wy\7)\2\2xd\3\2\2\2xh\3\2\2\2xp\3\2\2\2"+
-		"y\"\3\2\2\2z|\t\6\2\2{z\3\2\2\2|}\3\2\2\2}{\3\2\2\2}~\3\2\2\2~\177\3\2"+
-		"\2\2\177\u0080\b\22\2\2\u0080$\3\2\2\2\20\2;BGLNQZ]fltx}\3\b\2\2";
+		"\t\22\4\23\t\23\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\7\3"+
+		"\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\f\5\f>\n\f\3\f\5\fA\n\f\3\f\3\f\6\f"+
+		"E\n\f\r\f\16\fF\3\f\3\f\3\f\6\fL\n\f\r\f\16\fM\5\fP\n\f\5\fR\n\f\3\f\3"+
+		"\f\5\fV\n\f\3\f\6\fY\n\f\r\f\16\fZ\3\r\5\r^\n\r\3\r\5\ra\n\r\3\r\3\r\6"+
+		"\re\n\r\r\r\16\rf\3\r\3\r\3\r\7\rl\n\r\f\r\16\ro\13\r\5\rq\n\r\3\16\5"+
+		"\16t\n\16\3\16\3\16\3\17\3\17\3\17\7\17{\n\17\f\17\16\17~\13\17\5\17\u0080"+
+		"\n\17\3\20\3\20\3\21\3\21\3\22\6\22\u0087\n\22\r\22\16\22\u0088\3\22\3"+
+		"\22\7\22\u008d\n\22\f\22\16\22\u0090\13\22\3\22\3\22\3\22\7\22\u0095\n"+
+		"\22\f\22\16\22\u0098\13\22\3\22\5\22\u009b\n\22\3\23\6\23\u009e\n\23\r"+
+		"\23\16\23\u009f\3\23\3\23\4\u008e\u0096\2\24\3\3\5\4\7\5\t\6\13\7\r\b"+
+		"\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\2\37\2!\2#\20%\21\3\2\7\4\2"+
+		"GGgg\3\2\63;\3\2\62;\n\2%%\'(,-/;C\\aac|~~\5\2\13\f\17\17\"\"\u00b5\2"+
+		"\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2"+
+		"\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2"+
+		"\31\3\2\2\2\2\33\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\3\'\3\2\2\2\5)\3\2\2\2"+
+		"\7+\3\2\2\2\t-\3\2\2\2\13/\3\2\2\2\r\61\3\2\2\2\17\64\3\2\2\2\21\66\3"+
+		"\2\2\2\238\3\2\2\2\25:\3\2\2\2\27=\3\2\2\2\31]\3\2\2\2\33s\3\2\2\2\35"+
+		"\177\3\2\2\2\37\u0081\3\2\2\2!\u0083\3\2\2\2#\u009a\3\2\2\2%\u009d\3\2"+
+		"\2\2\'(\7=\2\2(\4\3\2\2\2)*\7*\2\2*\6\3\2\2\2+,\7.\2\2,\b\3\2\2\2-.\7"+
+		"+\2\2.\n\3\2\2\2/\60\7<\2\2\60\f\3\2\2\2\61\62\7]\2\2\62\63\7(\2\2\63"+
+		"\16\3\2\2\2\64\65\7_\2\2\65\20\3\2\2\2\66\67\7?\2\2\67\22\3\2\2\289\7"+
+		"}\2\29\24\3\2\2\2:;\7\177\2\2;\26\3\2\2\2<>\7/\2\2=<\3\2\2\2=>\3\2\2\2"+
+		">Q\3\2\2\2?A\5\35\17\2@?\3\2\2\2 at A\3\2\2\2AB\3\2\2\2BD\7\60\2\2CE\5!\21"+
+		"\2DC\3\2\2\2EF\3\2\2\2FD\3\2\2\2FG\3\2\2\2GR\3\2\2\2HO\5\35\17\2IK\7\60"+
+		"\2\2JL\5!\21\2KJ\3\2\2\2LM\3\2\2\2MK\3\2\2\2MN\3\2\2\2NP\3\2\2\2OI\3\2"+
+		"\2\2OP\3\2\2\2PR\3\2\2\2Q@\3\2\2\2QH\3\2\2\2RS\3\2\2\2SU\t\2\2\2TV\7/"+
+		"\2\2UT\3\2\2\2UV\3\2\2\2VX\3\2\2\2WY\5!\21\2XW\3\2\2\2YZ\3\2\2\2ZX\3\2"+
+		"\2\2Z[\3\2\2\2[\30\3\2\2\2\\^\7/\2\2]\\\3\2\2\2]^\3\2\2\2^p\3\2\2\2_a"+
+		"\5\35\17\2`_\3\2\2\2`a\3\2\2\2ab\3\2\2\2bd\7\60\2\2ce\5!\21\2dc\3\2\2"+
+		"\2ef\3\2\2\2fd\3\2\2\2fg\3\2\2\2gq\3\2\2\2hi\5\35\17\2im\7\60\2\2jl\5"+
+		"!\21\2kj\3\2\2\2lo\3\2\2\2mk\3\2\2\2mn\3\2\2\2nq\3\2\2\2om\3\2\2\2p`\3"+
+		"\2\2\2ph\3\2\2\2q\32\3\2\2\2rt\7/\2\2sr\3\2\2\2st\3\2\2\2tu\3\2\2\2uv"+
+		"\5\35\17\2v\34\3\2\2\2w\u0080\7\62\2\2x|\5\37\20\2y{\5!\21\2zy\3\2\2\2"+
+		"{~\3\2\2\2|z\3\2\2\2|}\3\2\2\2}\u0080\3\2\2\2~|\3\2\2\2\177w\3\2\2\2\177"+
+		"x\3\2\2\2\u0080\36\3\2\2\2\u0081\u0082\t\3\2\2\u0082 \3\2\2\2\u0083\u0084"+
+		"\t\4\2\2\u0084\"\3\2\2\2\u0085\u0087\t\5\2\2\u0086\u0085\3\2\2\2\u0087"+
+		"\u0088\3\2\2\2\u0088\u0086\3\2\2\2\u0088\u0089\3\2\2\2\u0089\u009b\3\2"+
+		"\2\2\u008a\u008e\7$\2\2\u008b\u008d\13\2\2\2\u008c\u008b\3\2\2\2\u008d"+
+		"\u0090\3\2\2\2\u008e\u008f\3\2\2\2\u008e\u008c\3\2\2\2\u008f\u0091\3\2"+
+		"\2\2\u0090\u008e\3\2\2\2\u0091\u009b\7$\2\2\u0092\u0096\7)\2\2\u0093\u0095"+
+		"\13\2\2\2\u0094\u0093\3\2\2\2\u0095\u0098\3\2\2\2\u0096\u0097\3\2\2\2"+
+		"\u0096\u0094\3\2\2\2\u0097\u0099\3\2\2\2\u0098\u0096\3\2\2\2\u0099\u009b"+
+		"\7)\2\2\u009a\u0086\3\2\2\2\u009a\u008a\3\2\2\2\u009a\u0092\3\2\2\2\u009b"+
+		"$\3\2\2\2\u009c\u009e\t\6\2\2\u009d\u009c\3\2\2\2\u009e\u009f\3\2\2\2"+
+		"\u009f\u009d\3\2\2\2\u009f\u00a0\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1\u00a2"+
+		"\b\23\2\2\u00a2&\3\2\2\2\30\2=@FMOQUZ]`fmps|\177\u0088\u008e\u0096\u009a"+
+		"\u009f\3\b\2\2";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {
diff --git a/src/beast/util/treeparser/NewickParser.java b/src/beast/util/treeparser/NewickParser.java
index 6833af0..66d6eaa 100644
--- a/src/beast/util/treeparser/NewickParser.java
+++ b/src/beast/util/treeparser/NewickParser.java
@@ -1,4 +1,4 @@
-// Generated from Newick.g4 by ANTLR 4.5.1
+// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.3
 package beast.util.treeparser;
 import org.antlr.v4.runtime.atn.*;
 import org.antlr.v4.runtime.dfa.DFA;
@@ -11,14 +11,14 @@ import java.util.ArrayList;
 
 @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
 public class NewickParser extends Parser {
-	static { RuntimeMetaData.checkVersion("4.5.1", RuntimeMetaData.VERSION); }
+	static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
 
 	protected static final DFA[] _decisionToDFA;
 	protected static final PredictionContextCache _sharedContextCache =
 		new PredictionContextCache();
 	public static final int
 		T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, 
-		T__9=10, FLOAT=11, INT=12, STRING=13, WHITESPACE=14;
+		T__9=10, FLOAT_SCI=11, FLOAT=12, INT=13, STRING=14, WHITESPACE=15;
 	public static final int
 		RULE_tree = 0, RULE_node = 1, RULE_post = 2, RULE_label = 3, RULE_meta = 4, 
 		RULE_attrib = 5, RULE_attribValue = 6, RULE_number = 7, RULE_vector = 8;
@@ -32,8 +32,8 @@ public class NewickParser extends Parser {
 		"'}'"
 	};
 	private static final String[] _SYMBOLIC_NAMES = {
-		null, null, null, null, null, null, null, null, null, null, null, "FLOAT", 
-		"INT", "STRING", "WHITESPACE"
+		null, null, null, null, null, null, null, null, null, null, null, "FLOAT_SCI", 
+		"FLOAT", "INT", "STRING", "WHITESPACE"
 	};
 	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
 
@@ -236,7 +236,7 @@ public class NewickParser extends Parser {
 			{
 			setState(40);
 			_la = _input.LA(1);
-			if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FLOAT) | (1L << INT) | (1L << STRING))) != 0)) {
+			if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FLOAT_SCI) | (1L << FLOAT) | (1L << INT) | (1L << STRING))) != 0)) {
 				{
 				setState(39);
 				label();
@@ -298,6 +298,7 @@ public class NewickParser extends Parser {
 		try {
 			setState(51);
 			switch (_input.LA(1)) {
+			case FLOAT_SCI:
 			case FLOAT:
 			case INT:
 				enterOuterAlt(_localctx, 1);
@@ -455,6 +456,7 @@ public class NewickParser extends Parser {
 		try {
 			setState(71);
 			switch (_input.LA(1)) {
+			case FLOAT_SCI:
 			case FLOAT:
 			case INT:
 				enterOuterAlt(_localctx, 1);
@@ -495,6 +497,7 @@ public class NewickParser extends Parser {
 	public static class NumberContext extends ParserRuleContext {
 		public TerminalNode INT() { return getToken(NewickParser.INT, 0); }
 		public TerminalNode FLOAT() { return getToken(NewickParser.FLOAT, 0); }
+		public TerminalNode FLOAT_SCI() { return getToken(NewickParser.FLOAT_SCI, 0); }
 		public NumberContext(ParserRuleContext parent, int invokingState) {
 			super(parent, invokingState);
 		}
@@ -515,7 +518,7 @@ public class NewickParser extends Parser {
 			{
 			setState(73);
 			_la = _input.LA(1);
-			if ( !(_la==FLOAT || _la==INT) ) {
+			if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FLOAT_SCI) | (1L << FLOAT) | (1L << INT))) != 0)) ) {
 			_errHandler.recoverInline(this);
 			} else {
 				consume();
@@ -594,13 +597,13 @@ public class NewickParser extends Parser {
 	}
 
 	public static final String _serializedATN =
-		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\20Y\4\2\t\2\4\3\t"+
+		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\21Y\4\2\t\2\4\3\t"+
 		"\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\3\2\3\2\5\2"+
 		"\27\n\2\3\2\3\2\3\3\3\3\3\3\3\3\7\3\37\n\3\f\3\16\3\"\13\3\3\3\3\3\5\3"+
 		"&\n\3\3\3\3\3\3\4\5\4+\n\4\3\4\5\4.\n\4\3\4\3\4\5\4\62\n\4\3\5\3\5\5\5"+
 		"\66\n\5\3\6\3\6\3\6\3\6\7\6<\n\6\f\6\16\6?\13\6\3\6\3\6\3\7\3\7\3\7\3"+
 		"\7\3\b\3\b\3\b\5\bJ\n\b\3\t\3\t\3\n\3\n\3\n\3\n\7\nR\n\n\f\n\16\nU\13"+
-		"\n\3\n\3\n\3\n\2\2\13\2\4\6\b\n\f\16\20\22\2\3\3\2\r\16Z\2\24\3\2\2\2"+
+		"\n\3\n\3\n\3\n\2\2\13\2\4\6\b\n\f\16\20\22\2\3\3\2\r\17Z\2\24\3\2\2\2"+
 		"\4%\3\2\2\2\6*\3\2\2\2\b\65\3\2\2\2\n\67\3\2\2\2\fB\3\2\2\2\16I\3\2\2"+
 		"\2\20K\3\2\2\2\22M\3\2\2\2\24\26\5\4\3\2\25\27\7\3\2\2\26\25\3\2\2\2\26"+
 		"\27\3\2\2\2\27\30\3\2\2\2\30\31\7\2\2\3\31\3\3\2\2\2\32\33\7\4\2\2\33"+
@@ -609,10 +612,10 @@ public class NewickParser extends Parser {
 		"%&\3\2\2\2&\'\3\2\2\2\'(\5\6\4\2(\5\3\2\2\2)+\5\b\5\2*)\3\2\2\2*+\3\2"+
 		"\2\2+-\3\2\2\2,.\5\n\6\2-,\3\2\2\2-.\3\2\2\2.\61\3\2\2\2/\60\7\7\2\2\60"+
 		"\62\5\20\t\2\61/\3\2\2\2\61\62\3\2\2\2\62\7\3\2\2\2\63\66\5\20\t\2\64"+
-		"\66\7\17\2\2\65\63\3\2\2\2\65\64\3\2\2\2\66\t\3\2\2\2\678\7\b\2\28=\5"+
+		"\66\7\20\2\2\65\63\3\2\2\2\65\64\3\2\2\2\66\t\3\2\2\2\678\7\b\2\28=\5"+
 		"\f\7\29:\7\5\2\2:<\5\f\7\2;9\3\2\2\2<?\3\2\2\2=;\3\2\2\2=>\3\2\2\2>@\3"+
-		"\2\2\2?=\3\2\2\2 at A\7\t\2\2A\13\3\2\2\2BC\7\17\2\2CD\7\n\2\2DE\5\16\b\2"+
-		"E\r\3\2\2\2FJ\5\20\t\2GJ\7\17\2\2HJ\5\22\n\2IF\3\2\2\2IG\3\2\2\2IH\3\2"+
+		"\2\2\2?=\3\2\2\2 at A\7\t\2\2A\13\3\2\2\2BC\7\20\2\2CD\7\n\2\2DE\5\16\b\2"+
+		"E\r\3\2\2\2FJ\5\20\t\2GJ\7\20\2\2HJ\5\22\n\2IF\3\2\2\2IG\3\2\2\2IH\3\2"+
 		"\2\2J\17\3\2\2\2KL\t\2\2\2L\21\3\2\2\2MN\7\13\2\2NS\5\16\b\2OP\7\5\2\2"+
 		"PR\5\16\b\2QO\3\2\2\2RU\3\2\2\2SQ\3\2\2\2ST\3\2\2\2TV\3\2\2\2US\3\2\2"+
 		"\2VW\7\f\2\2W\23\3\2\2\2\f\26 %*-\61\65=IS";
diff --git a/src/beast/util/treeparser/NewickVisitor.java b/src/beast/util/treeparser/NewickVisitor.java
index 9041257..b4dbd8b 100644
--- a/src/beast/util/treeparser/NewickVisitor.java
+++ b/src/beast/util/treeparser/NewickVisitor.java
@@ -1,4 +1,4 @@
-// Generated from Newick.g4 by ANTLR 4.5.1
+// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.3
 package beast.util.treeparser;
 import org.antlr.v4.runtime.tree.ParseTreeVisitor;
 
diff --git a/src/test/beast/evolution/alignment/FilteredAlignmentTest.java b/src/test/beast/evolution/alignment/FilteredAlignmentTest.java
index d23b823..656ec6a 100644
--- a/src/test/beast/evolution/alignment/FilteredAlignmentTest.java
+++ b/src/test/beast/evolution/alignment/FilteredAlignmentTest.java
@@ -290,20 +290,68 @@ public class FilteredAlignmentTest extends TestCase {
 
         assertEquals(alignmentToString(data2,0), alignmentToString(data4, 0));
         assertEquals(alignmentToString(data2,1), alignmentToString(data4, 1));
-}
+    }
     
-    String alignmentToString(Alignment data, int iTaxon) throws Exception {
-        int[] states = new int[data.getPatternCount()];
-//        for (int i = 0; i < data.getSiteCount(); i++) {
-//            int iPattern = data.getPatternIndex(i);
-//            int[] sitePattern = data.getPattern(iPattern);
-//            states[i] = sitePattern[iTaxon];
-//        }
+    
+    @Test
+    public void testReordered() throws Exception {
+    	// make sure the order of sites is not affected by filtering
+        Alignment data = getAlignmentNoTInHuman();
+        data.setID("data");
+
+        // second sequence not in alphabetical order
+        FilteredAlignment data2 = new FilteredAlignment();
+        data2.initByName("data", data, "filter", "3:6:1");
+
+        System.out.println("human\t" + alignmentToString(data2, 0) + "\n1chimp\t"
+                + alignmentToString(data2, 1));
+
+        assertEquals(alignmentToString(data2,0), "AACC");
+        assertEquals(alignmentToString(data2,1), "GTAC");
+
+        // first sequence not in alphabetical order
+        FilteredAlignment data3 = new FilteredAlignment();
+        data3.initByName("data", data, "filter", "11:14:1");
 
-        for (int i = 0; i < data.getPatternCount(); i++) {
-            int[] sitePattern = data.getPattern(i);
+        System.out.println("human\t" + alignmentToString(data3, 0) + "\n1chimp\t"
+                + alignmentToString(data3, 1));
+
+        assertEquals(alignmentToString(data3,0), "GGAA");
+        assertEquals(alignmentToString(data3,1), "GTAC");
+
+        // first sequence not in alphabetical order, repeat site
+        FilteredAlignment data4 = new FilteredAlignment();
+        data4.initByName("data", data, "filter", "3:16:4");
+
+        System.out.println("human\t" + alignmentToString(data4, 0) + "\n1chimp\t"
+                + alignmentToString(data4, 1));
+
+        assertEquals(alignmentToString(data4,0), "ACGA");
+        assertEquals(alignmentToString(data4,1), "GGGG");
+
+        // first and second sequence not in alphabetical order
+        FilteredAlignment data5 = new FilteredAlignment();
+        data5.initByName("data", data, "filter", "4:14:3");
+
+        System.out.println("human\t" + alignmentToString(data5, 0) + "\n1chimp\t"
+                + alignmentToString(data5, 1));
+
+        assertEquals(alignmentToString(data5,0), "ACGA");
+        assertEquals(alignmentToString(data5,1), "TGCA");
+    }
+
+    String alignmentToString(Alignment data, int iTaxon) throws Exception {
+        int[] states = new int[data.getSiteCount()];
+        for (int i = 0; i < data.getSiteCount(); i++) {
+            int iPattern = data.getPatternIndex(i);
+            int[] sitePattern = data.getPattern(iPattern);
             states[i] = sitePattern[iTaxon];
         }
+
+//        for (int i = 0; i < data.getPatternCount(); i++) {
+//            int[] sitePattern = data.getPattern(i);
+//            states[i] = sitePattern[iTaxon];
+//        }
         return data.getDataType().state2string(states);
     }
 }
diff --git a/src/test/beast/util/TreeParserTest.java b/src/test/beast/util/TreeParserTest.java
index d9d883f..29795ad 100644
--- a/src/test/beast/util/TreeParserTest.java
+++ b/src/test/beast/util/TreeParserTest.java
@@ -4,6 +4,7 @@ import org.junit.Assert;
 import org.junit.Test;
 
 import beast.util.TreeParser;
+import org.omg.CORBA.OBJ_ADAPTER;
 
 public class TreeParserTest {
 
@@ -110,4 +111,17 @@ public class TreeParserTest {
 
     }
 
+    @Test
+    public void testVectorMetadata() throws Exception {
+
+        String newick = "((A:1.0,B[&key={1,2,3}]:1.0):1.0,(C:1.0,D:1.0):1.0):0.0;";
+
+        boolean isLabeled = true;
+
+        TreeParser treeParser = new TreeParser(newick, false, false, isLabeled, 1);
+        Assert.assertTrue((treeParser.getNode(1).getMetaData("key") instanceof Double[])
+                && ((Double[])(treeParser.getNode(1).getMetaData("key"))).length == 3);
+
+    }
+
 }
diff --git a/version.xml b/version.xml
index 912afa0..6ee75a3 100644
--- a/version.xml
+++ b/version.xml
@@ -1 +1 @@
-<addon name='BEAST' version='2.4.2' url="https://github.com/CompEvol/beast2/releases/download/2.4.2pre/BEAST.v2.4.2.addon.zip"/>
+<addon name='BEAST' version='2.4.4' url="https://github.com/CompEvol/beast2/releases/download/2.4.4/BEAST.v2.4.4.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