TreePartitions

class TreePartitions(inThing=None, skip=0, max=None, taxNames=None)

A container for tree bipartitions or splits.

Start it up like this:

tp = TreePartitions(inThing)

where inThing can be a file name, a Trees object, or a Tree object.

If you are reading from a file (generally a bootstrap or mcmc output), you can skip some trees at the beginning, and optionally after that read only a maximum number of trees, like this:

tp = TreePartitions('myFile', skip=1000, max=500)

Then you can do:

tp.writeSplits()  # in dot-star notation, like .***..***
t = tp.consensus()

All the input trees need to have the same taxa.

If your input trees are in more than one place, you can read in more trees with the method:

read(whatever, skip, max)

The default setting in p4 is to use any tree weights supplied. This will cause consensus trees created by p4 to differ from ones created using Paup as the default in Paup is to not consider tree weights. P4s behavior can be modified to mimic Paup using the following statement before creating a TreePartitions object.

var.nexus_getWeightCommandComments = 0
tp = TreePartitions(inThing)

If you want to restore the default behavior issue this command:

var.nexus_getWeightCommandComments = 1

Making consensus trees

P4 makes majority rule consensus trees with extra compatible splits. It is like PAUP does when you do the contree command like the following:

contree all/strict=no majrule=yes percent=50 le50=yes useTreeWts=yes;

or what MrBayes does when you do a sumt contype=allcompat.

Making cons trees uses this class, TreePartitions, which takes trees apart into their ‘splits’, aka components or tree bipartitions. So if you have a tree file with trees from an MCMC output or from a bootstrap, you can make a cons tree by the following:

tp = TreePartitions('yourFile')
t = tp.consensus()

If you want to skip some trees at the beginning of a file (often the burn-in for an MCMC), or if you want to read in a maximum number of trees (which might be useful for convergence testing when using an MCMC), you do something like:

tp = TreePartitions('yourFile', skip=100, max=200)

When you get a cons tree with the consensus() method, the support for splits is placed in Node.br.support attributes. This allows some flexibility in how the support is displayed. To see those support values when you draw the tree to the screen, you will need to transfer the support information to the node names, like this:

for n in t.iterInternalsNoRoot():
    n.name = "%.2f" % n.br.support # you can specify the precision

For nice eps drawings, you might want to put the support on the tree as the branch.name rather than the node.name, and you can do that with something like this:

for n in t.iterInternalsNoRoot():
    n.br.name = "%.0f" % (n.br.support * 100.) # convert to percent
combineWith(otherTreePartitionsObject)

Combine the info from another TreePartitions object into self.

Hack alert!

Only for topology info, not for model info. Attribute doModelComments from self needs to be set to zero, and attribute modelInfo from self needs to be set to None (by you, the user) or else it won’t work.

compareSplits(otherTP, noLeaves=True, minimumProportion=0.1, bothMustMeetMinimum=False)

Compare split support with another TreePartitions.

It returns a list of comparisons, each comparison being a list of 3 things:
  1. The split key
  2. The split string
  3. A list of the 2 supports

Lets say you have 2 MCMC runs, and you want to compare the split supports for them. You make a TreePartitions object for each, and then use this method to get a list of comparisons. A single comparison is the support from each of the two MCMC runs for a particular split. If one MCMC run has a split but the other does not, it will still make a pair, with one of the elements being zero.

noLeaves
means that trivial splits, ie for leaves, are excluded.
minimumProportion
  • If bothMustMeetMinimum is turned off, which is now the default (and is more informative), then a comparison is not included unless one support value is greater than or equal to the minimum proportion
  • If bothMustMeetMinimum is turned on, then a comparison is not included unless both supports are at or above the minimumProportion.
consensus(conTreeName='consensus', showRootInfo=0, minimumProportion=None)

Make a consensus tree.

This method assembles a Tree object from the tree partitions contained in self.splits. It makes a ‘majority-rule consensus with extra compatible splits’. It will use splits that have more than minimumProportion support (note that minimumProportion is given as a number between 0 and 1.0, often it will be 0.5, meaning 50%).

It returns the tree. Do it like this:

tp = TreePartitions('myTreeFile.nex')
tp.writeSplits() # If you want ...
t = tp.consensus()

The support for the splits (often the Bayesian posterior support or bootstrap support, as given in the attribute split.proportion) is put on the tree as node.br.support as a float, not a string. If you want to draw it later showing the support, you can format the float as you like (eg as percent) and put it on node.br.name (for example) for making a picture, or as node.name if you want to save it in Nexus format with that info included. You can do that like this:

for n in t.iterInternalsNoRoot():
    if n.br.support != None:
        # The signature '%.0f' gives zero decimal places;
        # change that if you want more precision.
        n.name = '%.0f' % (100. * n.br.support)
t.writeNexus('consTreeWithSupport.nex')

A feature of this consensus method is that the resulting tree is rooted on the majority root position of the input trees. (If there is more than one majority root position, it is rooted on the first majority root position, arbitrarily.) If showRootInfo is set, a table of root positions is printed out.

The resulting con tree is decorated with the rootCounts. With trifurcating roots, they get put in the node.rootCount, and that shows directly which nodes were roots. If it is a bifurcating root the root counts get put in node.br.biRootCount, and shows how many times, for those splits that made it into the cons tree, that the root was found on that branch.

Since the resulting tree often contains more info than can be accommodated in Newick format, you may want to save it by pickling it. Use:

t.tPickle()
dump()
getSplitForTaxNames(txNames)
makeTreeFromPartitions(partitions, taxNames=None, zeroBasedNumbering=True)

Make a tree from a list of partitions.

Each partition in the list of partitions is a list of taxon numbers (zero-based, or 1-based if the arg zeroBasedNumbering is set to False).

It needs taxNames set, which can be done as an arg in this method, or set before.

read(inThing, skip=0, max=None, taxNames=None)

Read in a tree, or some trees, or a file of trees.

Arg inThing can be a file name, a Tree instance, or a Trees instance. Args skip and max only come into play if inThing is a file.

writeSplits(fName=None, minimumProportion=0.05, doLeaves=True)

Write a table of splits, in dot-star notation.

Writes all the splits with a proportion >= the minimumProportion.