use of beast.evolution.tree.Node in project beast2 by CompEvol.
the class TreeIntervals method collectTimes.
/**
* extract coalescent times and tip information into array times from beast.tree.
*
* @param tree the beast.tree
* @param times the times of the nodes in the beast.tree
* @param childCounts the number of children of each node
*/
protected static void collectTimes(Tree tree, double[] times, int[] childCounts) {
Node[] nodes = tree.getNodesAsArray();
for (int i = 0; i < nodes.length; i++) {
Node node = nodes[i];
times[i] = node.getHeight();
childCounts[i] = node.isLeaf() ? 0 : 2;
}
}
use of beast.evolution.tree.Node in project beast2 by CompEvol.
the class TreeParser method translateLeafIds.
/**
* Given a map of name translations (string to string),
* rewrites all leaf ids that match a key in the map
* to the respective value in the matching key/value pair.
* If current leaf id is null, then interpret translation keys as node numbers (origin 1)
* and set leaf id of node n to map.get(n-1).
*
* @param translationMap map of name translations
*/
public void translateLeafIds(final Map<String, String> translationMap) {
for (final Node leaf : getExternalNodes()) {
String id = leaf.getID();
if (id == null || !integerLeafLabels) {
id = Integer.toString(leaf.getNr() + 1);
}
final String newId = translationMap.get(id);
if (newId != null) {
leaf.setID(newId);
}
}
}
use of beast.evolution.tree.Node in project beast2 by CompEvol.
the class NodeReheight method reconstructTree.
/**
* construct tree top down by joining heighest left and right nodes *
*/
private Node reconstructTree(final double[] heights, final int[] reverseOrder, final int from, final int to, final boolean[] hasParent) {
// nodeIndex = maxIndex(heights, 0, heights.length);
int nodeIndex = -1;
double max = Double.NEGATIVE_INFINITY;
for (int j = from; j < to; j++) {
if (max < heights[j] && !m_nodes[reverseOrder[j]].isLeaf()) {
max = heights[j];
nodeIndex = j;
}
}
if (nodeIndex < 0) {
return null;
}
final Node node = m_nodes[reverseOrder[nodeIndex]];
// int left = maxIndex(heights, 0, nodeIndex);
int left = -1;
max = Double.NEGATIVE_INFINITY;
for (int j = from; j < nodeIndex; j++) {
if (max < heights[j] && !hasParent[j]) {
max = heights[j];
left = j;
}
}
// int right = maxIndex(heights, nodeIndex+1, heights.length);
int right = -1;
max = Double.NEGATIVE_INFINITY;
for (int j = nodeIndex + 1; j < to; j++) {
if (max < heights[j] && !hasParent[j]) {
max = heights[j];
right = j;
}
}
node.setLeft(m_nodes[reverseOrder[left]]);
node.getLeft().setParent(node);
node.setRight(m_nodes[reverseOrder[right]]);
node.getRight().setParent(node);
if (node.getLeft().isLeaf()) {
heights[left] = Double.NEGATIVE_INFINITY;
}
if (node.getRight().isLeaf()) {
heights[right] = Double.NEGATIVE_INFINITY;
}
hasParent[left] = true;
hasParent[right] = true;
heights[nodeIndex] = Double.NEGATIVE_INFINITY;
reconstructTree(heights, reverseOrder, from, nodeIndex, hasParent);
reconstructTree(heights, reverseOrder, nodeIndex, to, hasParent);
return node;
}
use of beast.evolution.tree.Node in project beast2 by CompEvol.
the class NodeReheight method proposal.
@Override
public double proposal() {
final Tree tree = treeInput.get();
m_nodes = tree.getNodesAsArray();
final int nodeCount = tree.getNodeCount();
// randomly change left/right order
// we change the tree
tree.startEditing(this);
reorder(tree.getRoot());
// collect heights
final double[] heights = new double[nodeCount];
final int[] reverseOrder = new int[nodeCount];
collectHeights(tree.getRoot(), heights, reverseOrder, 0);
// change height of an internal node
int nodeIndex = Randomizer.nextInt(heights.length);
while (m_nodes[reverseOrder[nodeIndex]].isLeaf()) {
nodeIndex = Randomizer.nextInt(heights.length);
}
final double maxHeight = calcMaxHeight(reverseOrder, nodeIndex);
heights[nodeIndex] = Randomizer.nextDouble() * maxHeight;
m_nodes[reverseOrder[nodeIndex]].setHeight(heights[nodeIndex]);
// reconstruct tree from heights
final Node root = reconstructTree(heights, reverseOrder, 0, heights.length, new boolean[heights.length]);
assert checkConsistency(root, new boolean[heights.length]);
// System.err.println("Inconsisten tree");
// }
root.setParent(null);
tree.setRoot(root);
return 0;
}
use of beast.evolution.tree.Node in project beast2 by CompEvol.
the class ScaleOperator method proposal.
/**
* override this for proposals,
*
* @return log of Hastings Ratio, or Double.NEGATIVE_INFINITY if proposal should not be accepted *
*/
@Override
public double proposal() {
try {
double hastingsRatio;
final double scale = getScaler();
if (m_bIsTreeScaler) {
final Tree tree = treeInput.get(this);
if (rootOnlyInput.get()) {
final Node root = tree.getRoot();
final double newHeight = root.getHeight() * scale;
if (newHeight < Math.max(root.getLeft().getHeight(), root.getRight().getHeight())) {
return Double.NEGATIVE_INFINITY;
}
root.setHeight(newHeight);
return -Math.log(scale);
} else {
// scale the beast.tree
final int internalNodes = tree.scale(scale);
return Math.log(scale) * (internalNodes - 2);
}
}
// not a tree scaler, so scale a parameter
final boolean scaleAll = scaleAllInput.get();
final int specifiedDoF = degreesOfFreedomInput.get();
final boolean scaleAllIndependently = scaleAllIndependentlyInput.get();
final RealParameter param = parameterInput.get(this);
assert param.getLower() != null && param.getUpper() != null;
final int dim = param.getDimension();
if (scaleAllIndependently) {
// update all dimensions independently.
hastingsRatio = 0;
final BooleanParameter indicators = indicatorInput.get();
if (indicators != null) {
final int dimCount = indicators.getDimension();
final Boolean[] indicator = indicators.getValues();
final boolean impliedOne = dimCount == (dim - 1);
for (int i = 0; i < dim; i++) {
if ((impliedOne && (i == 0 || indicator[i - 1])) || (!impliedOne && indicator[i])) {
final double scaleOne = getScaler();
final double newValue = scaleOne * param.getValue(i);
hastingsRatio -= Math.log(scaleOne);
if (outsideBounds(newValue, param)) {
return Double.NEGATIVE_INFINITY;
}
param.setValue(i, newValue);
}
}
} else {
for (int i = 0; i < dim; i++) {
final double scaleOne = getScaler();
final double newValue = scaleOne * param.getValue(i);
hastingsRatio -= Math.log(scaleOne);
if (outsideBounds(newValue, param)) {
return Double.NEGATIVE_INFINITY;
}
param.setValue(i, newValue);
}
}
} else if (scaleAll) {
// update all dimensions
// hasting ratio is dim-2 times of 1dim case. would be nice to have a reference here
// for the proof. It is supposed to be somewhere in an Alexei/Nicholes article.
// all Values assumed independent!
final int computedDoF = param.scale(scale);
final int usedDoF = (specifiedDoF > 0) ? specifiedDoF : computedDoF;
hastingsRatio = (usedDoF - 2) * Math.log(scale);
} else {
hastingsRatio = -Math.log(scale);
// which position to scale
final int index;
final BooleanParameter indicators = indicatorInput.get();
if (indicators != null) {
final int dimCount = indicators.getDimension();
final Boolean[] indicator = indicators.getValues();
final boolean impliedOne = dimCount == (dim - 1);
// available bit locations. there can be hundreds of them. scan list only once.
final int[] loc = new int[dimCount + 1];
int locIndex = 0;
if (impliedOne) {
loc[locIndex] = 0;
++locIndex;
}
for (int i = 0; i < dimCount; i++) {
if (indicator[i]) {
loc[locIndex] = i + (impliedOne ? 1 : 0);
++locIndex;
}
}
if (locIndex > 0) {
final int rand = Randomizer.nextInt(locIndex);
index = loc[rand];
} else {
// no active indicators
return Double.NEGATIVE_INFINITY;
}
} else {
// any is good
index = Randomizer.nextInt(dim);
}
final double oldValue = param.getValue(index);
if (oldValue == 0) {
// Error: parameter has value 0 and cannot be scaled
return Double.NEGATIVE_INFINITY;
}
final double newValue = scale * oldValue;
if (outsideBounds(newValue, param)) {
// reject out of bounds scales
return Double.NEGATIVE_INFINITY;
}
param.setValue(index, newValue);
// provides a hook for subclasses
// cleanupOperation(newValue, oldValue);
}
return hastingsRatio;
} catch (Exception e) {
// whatever went wrong, we want to abort this operation...
return Double.NEGATIVE_INFINITY;
}
}
Aggregations