use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class ConvertedEdgeHopContemp method proposal.
@Override
public double proposal() {
if (acg.getTotalConvCount() == 0)
return Double.NEGATIVE_INFINITY;
// Select recombination at random
Conversion conv = chooseConversion();
// Choose whether to move departure or arrival point
boolean moveDeparture = conv.getNode2().isRoot() || Randomizer.nextBoolean();
double pointHeight = moveDeparture ? conv.getHeight1() : conv.getHeight2();
Node convNode = moveDeparture ? conv.getNode1() : conv.getNode2();
// Find list of CF edges alive at pointHeight
List<Node> intersectingEdges = new ArrayList<>();
for (Node node : acg.getNodesAsArray()) {
if (node.isRoot() || node == convNode || node.getHeight() > pointHeight || node.getParent().getHeight() < pointHeight) {
continue;
}
intersectingEdges.add(node);
}
if (intersectingEdges.isEmpty())
return Double.NEGATIVE_INFINITY;
// Select new attachment point:
if (moveDeparture)
conv.setNode1(intersectingEdges.get(Randomizer.nextInt(intersectingEdges.size())));
else
conv.setNode2(intersectingEdges.get(Randomizer.nextInt(intersectingEdges.size())));
return 0.0;
}
use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class ConversionGraph method fromStringOld.
/**
* Load ACG from old string representation.
*
* @param str string representation of ACG
*/
@Deprecated
public void fromStringOld(String str) {
// Extract clonal frame and recombination components of string
Pattern cfPattern = Pattern.compile("^[^\\(]*(\\(.*)$");
Matcher cfMatcher = cfPattern.matcher(str);
if (!cfMatcher.find())
throw new RuntimeException("Error parsing ACG state string.");
// Process clonal frame
String sNewick = cfMatcher.group(cfMatcher.groupCount());
try {
TreeParser parser = new TreeParser();
parser.thresholdInput.setValue(1e-10, parser);
parser.offsetInput.setValue(0, parser);
setRoot(parser.parseNewick(sNewick));
} catch (Exception ex) {
Logger.getLogger(ConversionGraph.class.getName()).log(Level.SEVERE, null, ex);
}
initArrays();
Pattern convPattern = Pattern.compile("\\[&([^]]*)]");
Matcher convMatcher = convPattern.matcher(str);
// Process recombinations
for (Locus locus : getLoci()) convs.get(locus).clear();
while (convMatcher.find()) {
String[] elements = convMatcher.group(1).split(",");
Locus locus = getLocusByID(elements[0]);
if (locus == null)
throw new RuntimeException("Uknown locus id " + elements[0] + ". Aborting.");
Node node1 = getNode(Integer.parseInt(elements[1]));
int startLocus = Integer.parseInt(elements[2]);
double height1 = Double.parseDouble(elements[3]);
Node node2 = getNode(Integer.parseInt(elements[4]));
int endLocus = Integer.parseInt(elements[5]);
double height2 = Double.parseDouble(elements[6]);
Conversion conv = new Conversion(node1, height1, node2, height2, startLocus, endLocus, this, locus);
addConversion(conv);
}
if (isInvalid()) {
throw new IllegalArgumentException("Invalid ACG read from string. Aborting.");
}
}
use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class ConversionGraph method init.
/*
* Loggable implementation.
*/
@Override
public void init(PrintStream out) {
Node node = getRoot();
out.println("#NEXUS\n");
out.println("Begin taxa;");
out.println("\tDimensions ntax=" + getLeafNodeCount() + ";");
out.println("\t\tTaxlabels");
printTaxa(node, out, getNodeCount() / 2);
out.println("\t\t\t;");
out.println("End;\n");
out.println("Begin bacter;");
out.print("\tloci");
for (Locus locus : loci) out.print(" " + locus.getID() + ":" + locus.getSiteCount());
out.println(";\nEnd;\n");
out.println("Begin trees;");
out.println("\tTranslate");
printTranslate(node, out, getNodeCount() / 2);
out.print(";");
}
use of beast.evolution.tree.Node in project MultiTypeTree by tgvaughan.
the class StructuredCoalescentTreeDensity method updateEventSequence.
/**
* Determines the sequence of migration, coalescence and sampling events
* which make up the coloured tree.
*/
protected void updateEventSequence() {
// Clean up previous list:
eventList.clear();
lineageCountList.clear();
Node rootNode = mtTree.getRoot();
// Initialise map of active nodes to active change indices:
Map<Node, Integer> changeIdx = new HashMap<>();
changeIdx.put(rootNode, -1);
// Initialise lineage count per colour array:
Integer[] lineageCount = new Integer[migrationModel.getNTypes()];
for (int c = 0; c < migrationModel.getNTypes(); c++) if (c == ((MultiTypeNode) rootNode).getNodeType())
lineageCount[c] = 1;
else
lineageCount[c] = 0;
// Calculate event sequence:
while (!changeIdx.isEmpty()) {
SCEvent nextEvent = new SCEvent();
nextEvent.time = Double.NEGATIVE_INFINITY;
// Initial assignment not significant
nextEvent.node = rootNode;
// Determine next event
for (Node node : changeIdx.keySet()) if (changeIdx.get(node) < 0) {
if (node.isLeaf()) {
// Next event is a sample
if (node.getHeight() > nextEvent.time) {
nextEvent.time = node.getHeight();
nextEvent.kind = SCEventKind.SAMPLE;
nextEvent.type = ((MultiTypeNode) node).getNodeType();
nextEvent.node = node;
}
} else {
// Next event is a coalescence
if (node.getHeight() > nextEvent.time) {
nextEvent.time = node.getHeight();
nextEvent.kind = SCEventKind.COALESCE;
nextEvent.type = ((MultiTypeNode) node).getNodeType();
nextEvent.node = node;
}
}
} else {
// Next event is a migration
double thisChangeTime = ((MultiTypeNode) node).getChangeTime(changeIdx.get(node));
if (thisChangeTime > nextEvent.time) {
nextEvent.time = thisChangeTime;
nextEvent.kind = SCEventKind.MIGRATE;
nextEvent.destType = ((MultiTypeNode) node).getChangeType(changeIdx.get(node));
if (changeIdx.get(node) > 0)
nextEvent.type = ((MultiTypeNode) node).getChangeType(changeIdx.get(node) - 1);
else
nextEvent.type = ((MultiTypeNode) node).getNodeType();
nextEvent.node = node;
}
}
// Update active node list (changeIdx) and lineage count appropriately:
switch(nextEvent.kind) {
case COALESCE:
Node leftChild = nextEvent.node.getLeft();
Node rightChild = nextEvent.node.getRight();
changeIdx.remove(nextEvent.node);
changeIdx.put(leftChild, ((MultiTypeNode) leftChild).getChangeCount() - 1);
changeIdx.put(rightChild, ((MultiTypeNode) rightChild).getChangeCount() - 1);
lineageCount[nextEvent.type]++;
break;
case SAMPLE:
changeIdx.remove(nextEvent.node);
lineageCount[nextEvent.type]--;
break;
case MIGRATE:
lineageCount[nextEvent.destType]--;
lineageCount[nextEvent.type]++;
int oldIdx = changeIdx.get(nextEvent.node);
changeIdx.put(nextEvent.node, oldIdx - 1);
break;
}
// Add event to list:
eventList.add(nextEvent);
lineageCountList.add(Arrays.copyOf(lineageCount, lineageCount.length));
}
// Reverse event and lineage count lists (order them from tips to root):
eventList = Lists.reverse(eventList);
lineageCountList = Lists.reverse(lineageCountList);
}
use of beast.evolution.tree.Node in project MultiTypeTree by tgvaughan.
the class MultiTypeUniform method proposal.
/**
* Change the node height and return the hastings ratio.
*
* @return log of Hastings Ratio
*/
@Override
public double proposal() {
// Randomly select event on tree:
int event = Randomizer.nextInt(mtTree.getInternalNodeCount() + mtTree.getTotalNumberOfChanges());
MultiTypeNode node = null;
int changeIdx = -1;
if (event < mtTree.getInternalNodeCount()) {
node = (MultiTypeNode) mtTree.getNode(mtTree.getLeafNodeCount() + event);
if (!includeRootInput.get() && node.isRoot())
return Double.NEGATIVE_INFINITY;
} else {
event -= mtTree.getInternalNodeCount();
for (Node thisNode : mtTree.getNodesAsArray()) {
if (thisNode.isRoot())
continue;
if (event < ((MultiTypeNode) thisNode).getChangeCount()) {
node = (MultiTypeNode) thisNode;
changeIdx = event;
break;
}
event -= ((MultiTypeNode) thisNode).getChangeCount();
}
}
if (node == null)
throw new IllegalStateException("Event selection loop fell through!");
if (changeIdx == -1) {
if (node.isRoot()) {
// Scale distance root and closest event
double tmin = Math.max(((MultiTypeNode) node.getLeft()).getFinalChangeTime(), ((MultiTypeNode) node.getRight()).getFinalChangeTime());
double u = Randomizer.nextDouble();
double f = u * rootScaleFactorInput.get() + (1 - u) / rootScaleFactorInput.get();
double tnew = tmin + f * (node.getHeight() - tmin);
node.setHeight(tnew);
return -Math.log(f);
} else {
// Reposition node randomly between closest events
double tmin = Math.max(((MultiTypeNode) node.getLeft()).getFinalChangeTime(), ((MultiTypeNode) node.getRight()).getFinalChangeTime());
double tmax = node.getChangeCount() > 0 ? node.getChangeTime(0) : node.getParent().getHeight();
double u = Randomizer.nextDouble();
double tnew = u * tmin + (1.0 - u) * tmax;
node.setHeight(tnew);
return 0.0;
}
} else {
double tmin, tmax;
if (changeIdx + 1 < node.getChangeCount())
tmax = node.getChangeTime(changeIdx + 1);
else
tmax = node.getParent().getHeight();
if (changeIdx - 1 < 0)
tmin = node.getHeight();
else
tmin = node.getChangeTime(changeIdx - 1);
double u = Randomizer.nextDouble();
double tnew = u * tmin + (1 - u) * tmax;
node.setChangeTime(changeIdx, tnew);
return 0.0;
}
}
Aggregations