use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class ConvertedEdgeHop method proposal.
@Override
public double proposal() {
if (acg.getTotalConvCount() == 0)
return Double.NEGATIVE_INFINITY;
// Select recombination at random
Conversion recomb = chooseConversion();
// Choose whether to move departure or arrival point
boolean moveDeparture;
moveDeparture = recomb.getNode2().isRoot() || Randomizer.nextBoolean();
// Select new attachment point:
double u = Randomizer.nextDouble() * acg.getClonalFrameLength();
Node nodeBelow = null;
double newHeight = -1;
for (Node node : acg.getNodesAsArray()) {
if (node.isRoot())
continue;
if (u < node.getLength()) {
newHeight = node.getHeight() + u;
nodeBelow = node;
break;
}
u -= node.getLength();
}
if (newHeight < 0.0)
throw new IllegalStateException("Problem with recombinant edge " + "hop operator! This is a bug.");
// Check that new height does not lie out of bounds
if (moveDeparture) {
if (newHeight > recomb.getHeight2())
return Double.NEGATIVE_INFINITY;
else {
recomb.setHeight1(newHeight);
recomb.setNode1(nodeBelow);
}
} else {
if (newHeight < recomb.getHeight1())
return Double.NEGATIVE_INFINITY;
else {
recomb.setHeight2(newHeight);
recomb.setNode2(nodeBelow);
}
}
return 0.0;
}
use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class ConvertedEdgeSlide method proposal.
@Override
public double proposal() {
double logHR = 0.0;
if (acg.getTotalConvCount() == 0)
return Double.NEGATIVE_INFINITY;
// Select edge at random:
Conversion conv = chooseConversion();
// Decide whether to move departure or arrival point
boolean moveDeparture = Randomizer.nextBoolean();
// Get current (old) attachment height
double oldHeight;
if (moveDeparture) {
oldHeight = conv.getHeight1();
} else {
oldHeight = conv.getHeight2();
}
// Choose window:
double w = apertureSizeInput.get() * acg.getRoot().getHeight();
// Set new height
double newHeight = oldHeight + (Randomizer.nextDouble() - 0.5) * w;
// Check for boundary violation
if (moveDeparture) {
if (newHeight > conv.getHeight2() || newHeight > acg.getRoot().getHeight())
return Double.NEGATIVE_INFINITY;
} else {
if (newHeight < conv.getHeight1())
return Double.NEGATIVE_INFINITY;
}
// Get node below current (old) attachment point
Node nodeBelow;
if (moveDeparture)
nodeBelow = conv.getNode1();
else
nodeBelow = conv.getNode2();
// Choose node below new attachment point
if (newHeight < oldHeight) {
while (newHeight < nodeBelow.getHeight()) {
if (nodeBelow.isLeaf())
return Double.NEGATIVE_INFINITY;
if (Randomizer.nextBoolean())
nodeBelow = nodeBelow.getLeft();
else
nodeBelow = nodeBelow.getRight();
logHR += -Math.log(0.5);
}
} else {
while (!nodeBelow.isRoot() && newHeight > nodeBelow.getParent().getHeight()) {
nodeBelow = nodeBelow.getParent();
logHR += Math.log(0.5);
}
}
// Write changes back to recombination object
if (moveDeparture) {
conv.setHeight1(newHeight);
conv.setNode1(nodeBelow);
} else {
conv.setHeight2(newHeight);
conv.setNode2(nodeBelow);
}
return logHR;
}
use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class CFConvSwapExperiment method connectEdge.
public static void connectEdge(ConversionGraph acg, Node node, Node destEdgeBase, double destTime) {
if (node.isRoot())
throw new IllegalArgumentException("Programmer error: " + "root argument passed to connectEdge().");
Node parent = node.getParent();
if (destEdgeBase.isRoot()) {
parent.addChild(destEdgeBase);
} else {
Node grandParent = destEdgeBase.getParent();
grandParent.removeChild(destEdgeBase);
grandParent.addChild(parent);
parent.addChild(destEdgeBase);
}
parent.setHeight(destTime);
for (Locus locus : acg.getLoci()) {
for (Conversion conv : acg.getConversions(locus)) {
if (conv.getNode1() == destEdgeBase && conv.getHeight1() > destTime)
conv.setNode1(parent);
if (conv.getNode2() == destEdgeBase && conv.getHeight2() > destTime)
conv.setNode2(parent);
}
}
}
use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class AffectedSiteList method haveReachedAllMRCAs.
/**
* Test to see whether MRCA of every site has been found.
* This is actually pretty expensive. There's got to be a better way...
*
* @param activeCFNodes set of active CF nodes and the sites they represent
* @param activeConversions set of active conversions and the sites they represent
* @return true if all sites have found an MRCA, false otherwise
*/
protected boolean haveReachedAllMRCAs(Map<Node, Map<Locus, List<Integer>>> activeCFNodes, Map<Locus, Set<Conversion>> activeConversions) {
for (Locus locus : acg.getLoci()) {
List<Integer> startSites = new ArrayList<>();
List<Integer> endSites = new ArrayList<>();
for (Node node : activeCFNodes.keySet()) {
for (int i = 0; i < activeCFNodes.get(node).get(locus).size(); i += 2) {
startSites.add(activeCFNodes.get(node).get(locus).get(i));
endSites.add(activeCFNodes.get(node).get(locus).get(i + 1));
}
}
for (Conversion conv : activeConversions.get(locus)) {
for (int i = 0; i < affectedSites.get(conv).size(); i += 2) {
startSites.add(affectedSites.get(conv).get(i));
endSites.add(affectedSites.get(conv).get(i + 1));
}
}
Collections.sort(startSites);
Collections.sort(endSites);
for (int i = 0; i < startSites.size() - 1; i++) {
if (startSites.get(i + 1) < endSites.get(i))
return false;
}
}
return true;
}
use of beast.evolution.tree.Node in project bacter by tgvaughan.
the class CFEventList method updateEvents.
/**
* Assemble sorted list of events on clonal frame and a map from nodes
* to these events.
*/
public void updateEvents() {
if (!dirty)
return;
events.clear();
// Create event list
for (Node node : acg.getNodesAsArray()) {
Event event = new Event(node);
events.add(event);
}
// Sort events in increasing order of their times
Collections.sort(events, (Event o1, Event o2) -> {
if (o1.t < o2.t)
return -1;
if (o2.t < o1.t)
return 1;
return 0;
});
// Compute lineage counts:
int k = 0;
for (Event event : events) {
if (event.type == EventType.SAMPLE)
k += 1;
else
k -= 1;
event.lineages = k;
}
dirty = false;
}
Aggregations