std::string PhylowoodNhxMonitor::buildNhxString(void) { std::stringstream nhxStrm; // begin nexus file nhxStrm << "#NEXUS" << "\n\n"; // phylowood settings block nhxStrm << "Begin phylowood;\n"; nhxStrm << "\tdrawtype pie\n"; nhxStrm << "\tmodeltype biogeography\n"; nhxStrm << "\tareatype discrete\n"; nhxStrm << "\tmaptype clean\n"; nhxStrm << "\tpieslicestyle even\n"; nhxStrm << "\tpiefillstyle outwards\n"; nhxStrm << "\ttimestart -" << tree->getValue().getRoot().getAge() << "\n"; nhxStrm << "\tmarkerradius " << 200 << "\n"; nhxStrm << "\tminareaval " << 0.1 << "\n"; nhxStrm << "End;\n\n"; // bayarea-fig block nhxStrm << "Begin bayarea-fig;\n"; nhxStrm << "\tmapheight\t100\n"; nhxStrm << "\tmapwidth\t150\n"; nhxStrm << "\tcanvasheight\t2000\n"; nhxStrm << "\tcanvaswidth\t1000\n"; nhxStrm << "\tminareaval\t0.15\n"; nhxStrm << "\tareacolors black\n"; nhxStrm << "\tareatypes"; for (unsigned i = 0; i < numCharacters; i++) nhxStrm << " 1"; nhxStrm << "\n"; nhxStrm << "\tareanames Default\n"; nhxStrm << "End;\n\n"; // taxa block nhxStrm << "Begin taxa;\n"; nhxStrm << "\tDimensions ntax=" << tree->getValue().getNumberOfTips() << ";\n"; nhxStrm << "\tTaxlabels\n"; for (unsigned i = 0; i < tree->getValue().getNumberOfNodes(); i++) { TopologyNode* p = &tree->getValue().getNode(i); if (p->isTip()) { nhxStrm << "\t\t" << p->getName() << "\n"; } } nhxStrm << "\t\t;\n"; nhxStrm << "End;\n\n"; // geo block nhxStrm << "Begin geo;\n"; nhxStrm << "\tDimensions ngeo=" << numCharacters << ";\n"; nhxStrm << "\tCoords\n"; for (unsigned i = 0; i < numCharacters; i++) { nhxStrm << "\t\t" << i << "\t" << geographicCoordinates[i][0] << "\t" << geographicCoordinates[i][1]; if (i < (numCharacters - 1)) nhxStrm << ","; nhxStrm << "\n"; } nhxStrm << "\t\t;\n"; nhxStrm << "End;\n\n"; // tree block nhxStrm << "Begin trees;\n"; nhxStrm << "\tTranslate\n"; for (unsigned i = 0; i < tree->getValue().getNumberOfNodes(); i++) { TopologyNode* p = &tree->getValue().getNode(i); if (p->isTip()) { nhxStrm << "\t\t" << p->getIndex() << "\t" << p->getName(); if (i < (tree->getValue().getNumberOfNodes() - 1)) nhxStrm << ","; nhxStrm << "\n"; } } nhxStrm << "\t\t;\n"; // write tree string std::string treeStr = ""; treeStr = buildExtendedNewick(); //buildExtendedNewick(&tree->getValue().getRoot()); std::cout << treeStr << "\n"; std::cout << "nhxStr\n" << treeStr << "\n"; nhxStrm << "tree TREE1 = " << treeStr << ";\n"; nhxStrm << "End;\n"; std::cout << "["; for (size_t i = 0; i < numCharacters; i++) { if (i != 0) std::cout << ","; std::cout << (double)childCharacterCounts[0][i] / numSamples; } std::cout << "]\n"; return nhxStrm.str(); }
void CharacterDependentCladoBirthDeathProcess::recursivelyDrawJointConditionalAncestralStates(const TopologyNode &node, std::vector<size_t>& startStates, std::vector<size_t>& endStates) { size_t node_index = node.getIndex(); if ( node.isTip() == true ) { const AbstractHomologousDiscreteCharacterData& data = static_cast<TreeDiscreteCharacterData*>(this->value)->getCharacterData(); const AbstractDiscreteTaxonData& taxon_data = data.getTaxonData( node.getName() ); endStates[node_index] = taxon_data.getCharacter(0).getStateIndex(); } else { const TopologyNode &left = node.getChild(0); size_t left_index = left.getIndex(); state_type left_likelihoods = partial_likelihoods[left_index]; const TopologyNode &right = node.getChild(1); size_t right_index = right.getIndex(); state_type right_likelihoods = partial_likelihoods[right_index]; // sample characters by their probability conditioned on the branch's start state going to end states state_type branch_conditional_probs = std::vector<double>(2 * num_states, 0); size_t start_state = startStates[node_index]; branch_conditional_probs[ num_states + start_state ] = 1.0; double dt = root_age->getValue() / NUM_TIME_SLICES; double endAge = node.getAge(); double beginAge = node.getParent().getAge(); double current_time_slice = floor(beginAge / dt); bool computed_at_least_one = false; // get cladogenesis event map (sparse speciation rate matrix) const DeterministicNode<MatrixReal>* cpn = static_cast<const DeterministicNode<MatrixReal>* >( cladogenesis_matrix ); const TypedFunction<MatrixReal>& tf = cpn->getFunction(); const AbstractCladogenicStateFunction* csf = dynamic_cast<const AbstractCladogenicStateFunction*>( &tf ); std::map<std::vector<unsigned>, double> eventMap = csf->getEventMap(); // first iterate forward along the branch subtending this node to get the // probabilities of the end states conditioned on the start state while (current_time_slice * dt >= endAge || !computed_at_least_one) { // populate pre-computed extinction probs into branch_conditional_probs if (current_time_slice > 0) { for (size_t i = 0; i < num_states; i++) { branch_conditional_probs[i] = extinction_probabilities[current_time_slice - 1][i]; } } CDCladoSEObserved ode = CDCladoSEObserved(extinction_rates, &Q->getValue(), eventMap, rate->getValue()); boost::numeric::odeint::bulirsch_stoer< state_type > stepper(1E-8, 0.0, 0.0, 0.0); boost::numeric::odeint::integrate_adaptive( stepper, ode , branch_conditional_probs , current_time_slice * dt , (current_time_slice + 1) * dt, dt ); computed_at_least_one = true; current_time_slice--; } std::map<std::vector<unsigned>, double> sample_probs; double sample_probs_sum = 0.0; std::map<std::vector<unsigned>, double>::iterator it; // iterate over each cladogenetic event possible for (it = eventMap.begin(); it != eventMap.end(); it++) { const std::vector<unsigned>& states = it->first; double speciation_rate = it->second; sample_probs[ states ] = 0.0; // we need to sample from the ancestor, left, and right states jointly, // so keep track of the probability of each clado event double prob = left_likelihoods[num_states + states[1]] * right_likelihoods[num_states + states[2]]; prob *= speciation_rate * branch_conditional_probs[num_states + states[0]]; sample_probs[ states ] += prob; sample_probs_sum += prob; } // finally, sample ancestor, left, and right character states from probs size_t a, l, r; RandomNumberGenerator* rng = GLOBAL_RNG; double u = rng->uniform01() * sample_probs_sum; for (it = sample_probs.begin(); it != sample_probs.end(); it++) { u -= it->second; if (u < 0.0) { const std::vector<unsigned>& states = it->first; a = states[0]; l = states[1]; r = states[2]; endStates[node_index] = a; startStates[left_index] = l; startStates[right_index] = r; break; } } // recurse towards tips recursivelyDrawJointConditionalAncestralStates(left, startStates, endStates); recursivelyDrawJointConditionalAncestralStates(right, startStates, endStates); } }
void StateDependentSpeciationExtinctionProcess::recursivelyDrawJointConditionalAncestralStates(const TopologyNode &node, std::vector<size_t>& startStates, std::vector<size_t>& endStates) { size_t node_index = node.getIndex(); if ( node.isTip() == true ) { const AbstractHomologousDiscreteCharacterData& data = static_cast<TreeDiscreteCharacterData*>(this->value)->getCharacterData(); const AbstractDiscreteTaxonData& taxon_data = data.getTaxonData( node.getName() ); const DiscreteCharacterState &char_state = taxon_data.getCharacter(0); // we need to treat ambiguous state differently if ( char_state.isAmbiguous() == false ) { endStates[node_index] = char_state.getStateIndex(); } else { // initialize the conditional likelihoods for this branch state_type branch_conditional_probs = std::vector<double>(2 * num_states, 0); size_t start_state = startStates[node_index]; branch_conditional_probs[ num_states + start_state ] = 1.0; // first calculate extinction likelihoods via a backward time pass double end_age = node.getParent().getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, true, true); // now calculate conditional likelihoods along branch in forward time end_age = node.getParent().getAge() - node.getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, false, false); double total_prob = 0.0; for (size_t i = 0; i < num_states; ++i) { if ( char_state.isMissingState() == true || char_state.isGapState() == true || char_state.isStateSet(i) == true ) { total_prob += branch_conditional_probs[i]; } } RandomNumberGenerator* rng = GLOBAL_RNG; size_t u = rng->uniform01() * total_prob; for (size_t i = 0; i < num_states; ++i) { if ( char_state.isMissingState() == true || char_state.isGapState() == true || char_state.isStateSet(i) == true ) { u -= branch_conditional_probs[i]; if ( u <= 0.0 ) { endStates[node_index] = i; break; } } } } } else { // sample characters by their probability conditioned on the branch's start state going to end states // initialize the conditional likelihoods for this branch state_type branch_conditional_probs = std::vector<double>(2 * num_states, 0); size_t start_state = startStates[node_index]; branch_conditional_probs[ num_states + start_state ] = 1.0; // first calculate extinction likelihoods via a backward time pass double end_age = node.getParent().getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, true, true); // now calculate conditional likelihoods along branch in forward time end_age = node.getParent().getAge() - node.getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, false, false); // TODO: if character mapping compute likelihoods for each time slice.... // double current_time_slice = floor(begin_age / dt); // bool computed_at_least_one = false; // // // first iterate forward along the branch subtending this node to get the // // probabilities of the end states conditioned on the start state // while (current_time_slice * dt >= end_age || !computed_at_least_one) // { // double begin_age_slice = current_time_slice * dt; // double end_age_slice = (current_time_slice + 1) * dt; // numericallyIntegrateProcess(branch_conditional_probs, begin_age_slice, end_age_slice, false); // // computed_at_least_one = true; // current_time_slice--; // } std::map<std::vector<unsigned>, double> event_map; std::vector<double> speciation_rates; if ( use_cladogenetic_events == true ) { // get cladogenesis event map (sparse speciation rate matrix) const DeterministicNode<MatrixReal>* cpn = static_cast<const DeterministicNode<MatrixReal>* >( cladogenesis_matrix ); const TypedFunction<MatrixReal>& tf = cpn->getFunction(); const AbstractCladogenicStateFunction* csf = dynamic_cast<const AbstractCladogenicStateFunction*>( &tf ); event_map = csf->getEventMap(); } else { speciation_rates = lambda->getValue(); } // get likelihoods of descendant nodes const TopologyNode &left = node.getChild(0); size_t left_index = left.getIndex(); state_type left_likelihoods = partial_likelihoods[left_index][active_likelihood[left_index]]; const TopologyNode &right = node.getChild(1); size_t right_index = right.getIndex(); state_type right_likelihoods = partial_likelihoods[right_index][active_likelihood[right_index]]; std::map<std::vector<unsigned>, double> sample_probs; double sample_probs_sum = 0.0; std::map<std::vector<unsigned>, double>::iterator it; // calculate probabilities for each state if ( use_cladogenetic_events == true ) { // iterate over each cladogenetic event possible // and initialize probabilities for each clado event for (it = event_map.begin(); it != event_map.end(); it++) { const std::vector<unsigned>& states = it->first; double speciation_rate = it->second; // we need to sample from the ancestor, left, and right states jointly, // so keep track of the probability of each clado event double prob = left_likelihoods[num_states + states[1]] * right_likelihoods[num_states + states[2]]; prob *= speciation_rate * branch_conditional_probs[num_states + states[0]]; sample_probs[ states ] = prob; sample_probs_sum += prob; } } else { for (size_t i = 0; i < num_states; i++) { double prob = left_likelihoods[num_states + i] * right_likelihoods[num_states + i] * speciation_rates[i]; prob *= branch_conditional_probs[num_states + i]; std::vector<unsigned> states = boost::assign::list_of(i)(i)(i); sample_probs[ states ] = prob; sample_probs_sum += prob; } } // finally, sample ancestor, left, and right character states from probs size_t a, l, r; if (sample_probs_sum == 0) { RandomNumberGenerator* rng = GLOBAL_RNG; size_t u = rng->uniform01() * sample_probs.size(); size_t v = 0; for (it = sample_probs.begin(); it != sample_probs.end(); it++) { if (u < v) { const std::vector<unsigned>& states = it->first; a = states[0]; l = states[1]; r = states[2]; endStates[node_index] = a; startStates[left_index] = l; startStates[right_index] = r; break; } v++; } } else { RandomNumberGenerator* rng = GLOBAL_RNG; double u = rng->uniform01() * sample_probs_sum; for (it = sample_probs.begin(); it != sample_probs.end(); it++) { u -= it->second; if (u < 0.0) { const std::vector<unsigned>& states = it->first; a = states[0]; l = states[1]; r = states[2]; endStates[node_index] = a; startStates[left_index] = l; startStates[right_index] = r; break; } } } // recurse towards tips recursivelyDrawJointConditionalAncestralStates(left, startStates, endStates); recursivelyDrawJointConditionalAncestralStates(right, startStates, endStates); } }