Ejemplo n.º 1
0
/** 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);
    }
}
Ejemplo n.º 2
0
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 );
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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");
    }


}
Ejemplo n.º 8
0
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;
}