コード例 #1
0
void StitchTreeFunction::recursivelyCleanPatchClade(TopologyNode* node, TopologyNode*& newRoot, std::set<Taxon>& remainingTaxa, size_t& index, size_t patchIndex)
{
    
    // remove self if found in remainingTaxa
    if (node->isTip())
    {
        std::set<Taxon>::iterator it = remainingTaxa.find( node->getTaxon() );
        if (it != remainingTaxa.end())
        {
            remainingTaxa.erase( node->getTaxon() );
            TopologyNode* parent = &node->getParent();
            std::vector<TopologyNode*> children = parent->getChildren();
            for (size_t i = 0; i < children.size(); i++)
            {
                children[i]->setParent(NULL);
                parent->removeChild(children[i]);
                
                if (children[i] != node)
                    newRoot = children[i];
                else
                    delete children[i];
            }
            
            // free old root node
            delete parent;
        }
        return;
    }
    
    // recurse towards tips
    std::vector<TopologyNode*> children = node->getChildren();
    for (size_t i = 0; i < children.size(); i++)
    {
        recursivelyCleanPatchClade(children[i], newRoot, remainingTaxa, index, patchIndex);
    }
    
    return;
}
コード例 #2
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;
}