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
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;
}
void SpeciesNarrowExchangeProposal::prune( TopologyNode *node, TopologyNode *child )
{
    // get the parent and brother node
    TopologyNode &parent = node->getParent();
    TopologyNode *brother = &node->getChild( 0 );
    if ( brother == child )
    {
        brother = &node->getChild( 1 );
    }
    // prune
    parent.removeChild( node );
    node->removeChild( brother );
    parent.addChild( brother );
    brother->setParent( &parent );
    
}
/**
 * Perform the proposal.
 *
 * \return The hastings ratio.
 */
double SpeciesNarrowExchangeProposal::doProposal( void )
{
    
    // empty the previous vectors
    storedGeneTreeNodes.clear();
    storedOldBrothers.clear();
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    Tree& tau = speciesTree->getValue();
    
    // pick a random node which is not the root and neithor a direct descendant of the root
    TopologyNode* node;
    do {
        double u = rng->uniform01();
        size_t index = size_t( std::floor(tau.getNumberOfNodes() * u) );
        node = &tau.getNode(index);
    } while ( node->isRoot() || node->getParent().isRoot() );
    
    TopologyNode& parent = node->getParent();
    TopologyNode& grandparent = parent.getParent();
    TopologyNode* uncle = &grandparent.getChild( 0 );
    // check if we got the correct child
    if ( uncle == &parent )
    {
        uncle = &grandparent.getChild( 1 );
    }
    TopologyNode* brother = &parent.getChild( 0 );
    // check if we got the correct child
    if ( brother == node )
    {
        brother = &parent.getChild( 1 );
    }
    
    // we need to work with the times
    double parent_age   = parent.getAge();
    double uncles_age   = uncle->getAge();
    
    if( uncles_age < parent_age )
    {
        failed = false;
        
        double lnHastingsRatio = 0.0;
        
        // now we store all necessary values
        storedChoosenNode   = node;
        storedUncle         = uncle;
        
        // now we need to find for each gene tree the nodes that need to be moved as well
        // only nodes that have a coalescent event within the lifetime of the parents populations
        // from lineages belonging to the chosen node with lineages belonging to the brother population
        // need to be changed
        for ( size_t i=0; i<geneTrees.size(); ++i )
        {
            // get the i-th gene tree
            Tree& geneTree = geneTrees[i]->getValue();
            
            std::vector<TopologyNode*> nodes = getNodesToChange(geneTree, *node, *brother );
            
            // get the set of nodes in my uncles populations
            // these are the nodes that are possible re-attachment points
            std::set<TopologyNode*> new_siblings = getOldestSubtreesNodesInPopulation(geneTree, *uncle);
            std::set<TopologyNode*> old_siblings = getOldestSubtreesNodesInPopulation(geneTree, *brother);
            
            for (size_t j=0; j<nodes.size(); ++j)
            {
                
                TopologyNode *the_gene_node = nodes[i];

                // first we need to compute the backward probability
                std::set<TopologyNode*> old_candidate_siblings = getPossibleSiblings(the_gene_node, old_siblings);
                
                // add the backward probability to the hastings ratio
                lnHastingsRatio += log( old_siblings.size() );
                
                // then we need to compute the forward probability
                std::set<TopologyNode*> new_candidate_siblings = getPossibleSiblings(the_gene_node, new_siblings);
                
                // add the forward  probability to the hastings ratio
                lnHastingsRatio += log( new_candidate_siblings.size() );
                
                // actually pick a new sibling
                size_t new_index = size_t( floor(rng->uniform01() * new_candidate_siblings.size() ) );
                std::set<TopologyNode*>::iterator it = new_candidate_siblings.begin();
                std::advance(it,new_index);
                TopologyNode *new_child = *it;
                
                // store nodes
                storedGeneTreeNodes.push_back( the_gene_node );
                TopologyNode &the_parent = the_gene_node->getParent();
                TopologyNode *old_brother = &the_parent.getChild( 0 );
                if ( old_brother == the_gene_node )
                {
                    old_brother = &the_parent.getChild( 1 );
                }
                storedOldBrothers.push_back( old_brother );
                
                // perform a prune and regraft move
                prune( &the_parent, the_gene_node );
                regraft( the_gene_node, new_child );
                
            }
            
            // Sebastian: This is only for debugging. It makes the code slower. Hopefully it is not necessary anymore.
            //        geneTrees[i]->touch( true );
            
        }
        
        
        // now exchange the two nodes
        grandparent.removeChild( uncle );
        parent.removeChild( node );
        grandparent.addChild( node );
        parent.addChild( uncle );
        node->setParent( &grandparent );
        uncle->setParent( &parent );
        
        return 0.0;
    }
    else
    {
        failed = true;
        return RbConstants::Double::neginf;
    }
    
}
Ejemplo n.º 5
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{