/** Build random binary tree to size num_taxa. The result is a draw from the uniform distribution on histories. */ void HeterogeneousRateBirthDeath::buildRandomBinaryHistory(std::vector<TopologyNode*> &tips) { if (tips.size() < num_taxa) { // Get the rng RandomNumberGenerator* rng = GLOBAL_RNG; // Randomly draw one node from the list of tips size_t index = static_cast<size_t>( floor(rng->uniform01()*tips.size()) ); // Get the node from the list TopologyNode* parent = tips.at(index); // Remove the randomly drawn node from the list tips.erase(tips.begin()+long(index)); // Add a left child TopologyNode* leftChild = new TopologyNode(0); parent->addChild(leftChild); leftChild->setParent(parent); tips.push_back(leftChild); // Add a right child TopologyNode* rightChild = new TopologyNode(0); parent->addChild(rightChild); rightChild->setParent(parent); tips.push_back(rightChild); // Recursive call to this function buildRandomBinaryHistory(tips); } }
TopologyNode* SpeciesTreeNodeSlideProposal::mauReconstructSub(Tree &tree, size_t from, size_t to, std::vector<TopologyNode*> &order, std::vector<bool>&wasSwaped) { if( from == to ) { return order[2*from]; } size_t node_index = -1; { double h = -1; for(size_t i = from; i < to; ++i) { double v = order[2 * i + 1]->getAge(); if( h < v ) { h = v; node_index = i; } } } TopologyNode* node = order[2 * node_index + 1]; TopologyNode& lchild = node->getChild( 0 ); TopologyNode& rchild = node->getChild( 1 ); TopologyNode* lTargetChild = mauReconstructSub(tree, from, node_index, order, wasSwaped); TopologyNode* rTargetChild = mauReconstructSub(tree, node_index+1, to, order, wasSwaped); if( wasSwaped[node_index] ) { TopologyNode* z = lTargetChild; lTargetChild = rTargetChild; rTargetChild = z; } if( &lchild != lTargetChild ) { // replace the left child node->removeChild( &lchild ); node->addChild( lTargetChild ); } if( &rchild != rTargetChild ) { // replace the right child node->removeChild( &rchild ); node->addChild( rTargetChild ); } return node; }
void SpeciesNarrowExchangeProposal::regraft( TopologyNode *node, TopologyNode *child ) { // regraft TopologyNode* newParent = &child->getParent(); newParent->removeChild( child ); newParent->addChild( node ); node->setParent( newParent ); node->addChild( child ); child->setParent( node ); }
void StitchTreeFunction::recursivelyStitchPatchClades(TopologyNode* node, size_t& index) { // stich patch clade to matching tip taxon if (node->isTip()) { for (size_t i = 0; i < patchTaxa.size(); i++) { if (node->getTaxon() == stitchTaxon[i]) { // remove the node TopologyNode* parent = &node->getParent(); parent->removeChild(node); node->setParent(NULL); delete node; // add the patch clade const Tree& t = patchClades->getValue()[i]; // this memory is freed when the stitch tree is deleted in updateStitchTree() TopologyNode* patchRoot = new TopologyNode( t.getRoot() ); // prune out non-patch taxa std::set<Taxon> remainingTaxa = prunedTaxa[i]; recursivelyCleanPatchClade(patchRoot, patchRoot, remainingTaxa, index, i); recursivelyIndexPatchClade(patchRoot, index, i); // add patch clade to base tree parent->addChild(patchRoot); patchRoot->setParent(parent); return; } } } // recurse towards tips std::vector<TopologyNode*> children = node->getChildren(); for (size_t i = 0; i < children.size(); i++) { recursivelyStitchPatchClades(children[i], index); } // assign index for first update only if (!haveIndex) { stitchTreeIndex[numPatches][node->getIndex()] = index++; } // set index as needed size_t old_index = node->getIndex(); node->setIndex( stitchTreeIndex[numPatches][old_index] ); return; }
TopologyNode* GibbsPruneAndRegraft::pruneAndRegraft(TopologyNode *brother, TopologyNode *newBrother, TopologyNode *parent, TopologyNode &grandparent) { // prune grandparent.removeChild( parent ); parent->removeChild( brother ); grandparent.addChild( brother ); brother->setParent( &grandparent ); // regraft TopologyNode* newGrandParent = &newBrother->getParent(); newGrandParent->removeChild( newBrother ); newGrandParent->addChild( parent ); parent->setParent( newGrandParent ); parent->addChild( newBrother ); newBrother->setParent( parent ); return newGrandParent; }
TopologyNode* NewickConverter::createNode(const std::string &n, std::vector<TopologyNode*> &nodes, std::vector<double> &brlens) { // create a string-stream and throw the string into it std::stringstream ss (std::stringstream::in | std::stringstream::out); ss << n; char c; ss.get(c); // the initial character has to be '(' if ( c != '(') { throw Exception("Error while converting Newick tree. We expected an opening parenthesis, but didn't get one."); } TopologyNode *node = new TopologyNode(); while ( ss.good() && ss.peek() != ')' ) { TopologyNode *childNode; if (ss.peek() == '(' ) { // we received an internal node int depth = 0; std::string child = ""; do { ss.get(c); child += c; if ( c == '(' ) { depth++; } else if ( c == ')' ) { depth--; } } while ( ss.good() && depth > 0 ); // construct the child node childNode = createNode( child, nodes, brlens ); } else { // construct the node childNode = new TopologyNode(); } // set the parent child relationship node->addChild( childNode ); childNode->setParent( node ); // read the optional label std::string lbl = ""; while ( ss.good() && (c = ss.peek()) != ':' && c != '[' && c != ';' && c != ',' && c != ')') { lbl += ss.get(); } childNode->setName( lbl ); // read the optional node parameters if ( ss.peek() == '[' ) { ss.ignore(); do { // ignore the '&' before parameter name if ( ss.peek() == '&') { ss.ignore(); } // read the parameter name std::string paramName = ""; while ( ss.good() && (c = ss.peek()) != '=' && c != ',') { paramName += ss.get(); } // ignore the equal sign between parameter name and value if ( ss.peek() == '=') { ss.ignore(); } // read the parameter name std::string paramValue = ""; while ( ss.good() && (c = ss.peek()) != ']' && c != ',') { paramValue += ss.get(); } // \todo: Needs implementation // childNode->addNodeParameter(paramName, paramValue); if(paramName == "index") childNode->setIndex(atoi(paramValue.c_str())); } while ( (c = ss.peek()) == ',' ); // ignore the final ']' if ( (c = ss.peek()) == ']' ) { ss.ignore(); } } // read the optional branch length if ( ss.peek() == ':' ) { ss.ignore(); std::string time = ""; while ( ss.good() && (c = ss.peek()) != ';' && c != ',' && c != ')' && c != ')' && c != '[') { time += ss.get(); } std::istringstream stm; stm.str(time); double d; stm >> d; if(d < 1E-10 ) d = 0.0; nodes.push_back( childNode ); brlens.push_back( d ); }else{
void AbstractRootedTreeDistribution::simulateClade(std::vector<TopologyNode *> &n, double age, double present) { // Get the rng RandomNumberGenerator* rng = GLOBAL_RNG; // get the minimum age double current_age = n[0]->getAge(); for (size_t i = 1; i < n.size(); ++i) { if ( current_age > n[i]->getAge() ) { current_age = n[i]->getAge(); } } while ( n.size() > 2 && current_age < age ) { // get all the nodes before the current age std::vector<TopologyNode*> active_nodes; for (size_t i = 0; i < n.size(); ++i) { if ( current_age >= n[i]->getAge() ) { active_nodes.push_back( n[i] ); } } // we need to get next age of a node larger than the current age double next_node_age = age; for (size_t i = 0; i < n.size(); ++i) { if ( current_age < n[i]->getAge() && n[i]->getAge() < next_node_age ) { next_node_age = n[i]->getAge(); } } // only simulate if there are at least to valid/active nodes if ( active_nodes.size() < 2 ) { current_age = next_node_age; } else { // now we simulate new ages double next_sim_age = simulateNextAge(active_nodes.size()-1, present-age, present-current_age, present); if ( next_sim_age < next_node_age ) { // randomly pick two nodes size_t index_left = static_cast<size_t>( floor(rng->uniform01()*active_nodes.size()) ); TopologyNode* left_child = active_nodes[index_left]; active_nodes.erase(active_nodes.begin()+long(index_left)); size_t index_right = static_cast<size_t>( floor(rng->uniform01()*active_nodes.size()) ); TopologyNode* right_right = active_nodes[index_right]; active_nodes.erase(active_nodes.begin()+long(index_right)); // erase the nodes also from the origin nodes vector n.erase(std::remove(n.begin(), n.end(), left_child), n.end()); n.erase(std::remove(n.begin(), n.end(), right_right), n.end()); // create a parent for the two TopologyNode *parent = new TopologyNode(); parent->addChild( left_child ); parent->addChild( right_right ); left_child->setParent( parent ); right_right->setParent( parent ); parent->setAge( next_sim_age ); // insert the parent to our list n.push_back( parent ); current_age = next_sim_age; } else { current_age = next_node_age; } } } if ( n.size() == 2 ) { // pick two nodes TopologyNode* left_child = n[0]; TopologyNode* right_right = n[1]; // erase the nodes also from the origin nodes vector n.clear(); // create a parent for the two TopologyNode *parent = new TopologyNode(); parent->addChild( left_child ); parent->addChild( right_right ); left_child->setParent( parent ); right_right->setParent( parent ); parent->setAge( age ); // insert the parent to our list n.push_back( parent ); } else { throw RbException("Unexpected number of taxa in constrained tree simulation"); } }
int PruneTreeFunction::recursivelyRetainTaxa(RevBayesCore::TopologyNode *node) { // tip node if (node->isTip()) { const std::vector<Taxon>& taxa = tau->getValue().getTaxa(); const Taxon& tipTaxon = taxa[node->getIndex()]; std::set<Taxon>::iterator it = retainedTaxa.find( tipTaxon ); // found it if (it != retainedTaxa.end()) { // std::cout << "retain\t" << node->getIndex() << "\t" << node << "\t" << tipTaxon.getName() << "\n"; return 1; } else { // std::cout << "prune\t" << node->getIndex() << "\t" << node << "\t" << tipTaxon.getName() << "\n"; return 0; } } int total_count = 0; int number_children_retained = 0; // determine if subclade has any retained taxa std::vector<TopologyNode*> children = node->getChildren(); std::vector<int> count( children.size(), 0 ); for (size_t i = 0; i < children.size(); i++) { // std::cout << "recurse\t" << node->getIndex() << "\t" << node << "\tfor child\t" << children[i]->getIndex() << "\t" << children[i] << "\n"; // count[i] = recursivelyRetainTaxa(children[i]); pruneCount[ children[i] ] = recursivelyRetainTaxa(children[i]); total_count += pruneCount[ children[i] ]; if (pruneCount[ children[i] ] > 0) number_children_retained++; } if (node->isRoot()) { TopologyNode* root = node; if (number_children_retained == 0) { } // if one daughter, patch over node else if (number_children_retained == 1) { std::vector<TopologyNode*> fresh_children = node->getChildren(); for (size_t i = 0; i < fresh_children.size(); i++) { // remove all of the node's children // NB: node->removeAllChildren() also calls delete node->removeChild(fresh_children[i]); // std::cout << "del-child\t" << fresh_children[i]->getIndex() << "\t" << fresh_children[i] << "\t" << fresh_children[i]->getTaxon().getName() << "\n"; } for (size_t i = 0; i < fresh_children.size(); i++) { if (pruneCount[ fresh_children[i] ] == 0) continue; root = fresh_children[i]; fresh_children[i]->setParent(NULL); // std::cout << "add-child\t" << fresh_children[i]->getIndex() << "\t" << fresh_children[i] << "\t" << fresh_children[i]->getTaxon().getName() << "\n"; } node->setParent(NULL); // free memory // delete node; // setRoot will free this memory } // check ntaxa > 2 bool good = true; if (!good) { throw RbException(""); } value->setRoot( root, true ); std::vector<TopologyNode*> nodes = value->getNodes(); // update tip nodes with stored taxon-index for (size_t i = 0; i < value->getNumberOfTips(); i++) { nodes[i]->setIndex( retainedIndices[ nodes[i]->getTaxon() ] ); } // value->setRoot( root, false ); value->setRoot(root, true); } else if (node->isInternal()) { // std::cout << "patch\t" << node->getIndex() << "\t" << node << "\n"; // if zero daughters, drop all daughters if (number_children_retained == 0) { node->removeAllChildren(); } // if one daughter, patch over node else if (number_children_retained == 1) { std::vector<TopologyNode*> fresh_children = node->getChildren(); TopologyNode* parent = &node->getParent(); // want to retain order of fresh_children for parent... std::vector<TopologyNode*> fresh_parent_children = parent->getChildren(); for (size_t i = 0; i < fresh_children.size(); i++) { // remove all of the node's children // NB: node->removeAllChildren() also calls delete node->removeChild(fresh_children[i]); // std::cout << "del-child\t" << pruneCount[ fresh_children[i] ] << "\t" << fresh_children[i]->getIndex() << "\t" << fresh_children[i] << "\t" << fresh_children[i]->getTaxon().getName() << "\n"; } for (size_t i = 0; i < fresh_children.size(); i++) { if ( pruneCount[ fresh_children[i] ] == 0) continue; fresh_children[i]->setParent(parent); parent->addChild(fresh_children[i]); // std::cout << "add-child\t" << pruneCount[ fresh_children[i] ] << "\t" << fresh_children[i]->getIndex() << "\t" << fresh_children[i] << "\t" << fresh_children[i]->getTaxon().getName() << "\n"; } node->setParent(NULL); parent->removeChild(node); // free memory delete node; } // if two or more daughters, do not prune // ... return total_count; } else { throw RbException("fnPruneTree encountered unexpected type of node!"); } return true; }