Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit cd41adf

Browse files
committed
modify site concordance factor to work on multifurcating trees
1 parent 6fd0c7d commit cd41adf

File tree

1 file changed

+55
-21
lines changed

1 file changed

+55
-21
lines changed

tree/discordance.cpp

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -111,37 +111,48 @@ void SuperAlignment::computeQuartetSupports(IntVector &quartet, vector<int64_t>
111111
}
112112

113113
void PhyloTree::computeSiteConcordance(Branch &branch, int nquartets, int *rstream) {
114-
vector<IntVector> taxa;
115-
taxa.resize(4);
114+
vector<IntVector> left_taxa, right_taxa;
115+
//taxa.resize(4);
116116

117117
// extract the taxa from the two left subtrees
118+
left_taxa.resize(branch.first->neighbors.size()-1);
118119
int id = 0;
119120
FOR_NEIGHBOR_DECLARE(branch.first, branch.second, it) {
120121
// 2018-12-11: do not consider internal branch at the root
121122
if (rooted && (*it)->node == root)
122123
return;
123-
getTaxaID(taxa[id], (*it)->node, branch.first);
124+
getTaxaID(left_taxa[id], (*it)->node, branch.first);
124125
id++;
125-
if (id > 2)
126-
outError(__func__, " only work with bifurcating tree");
126+
// if (id > 2)
127+
// outError(__func__, " only work with bifurcating tree");
127128
}
129+
ASSERT(id == left_taxa.size());
128130

129131
// extract the taxa from the two right subtrees
132+
right_taxa.resize(branch.second->neighbors.size()-1);
133+
id = 0;
130134
FOR_NEIGHBOR(branch.second, branch.first, it) {
131135
// 2018-12-11: do not consider internal branch at the root
132136
if (rooted && (*it)->node == root)
133137
return;
134-
getTaxaID(taxa[id], (*it)->node, branch.second);
138+
getTaxaID(right_taxa[id], (*it)->node, branch.second);
135139
id++;
136-
if (id > 4)
137-
outError(__func__, " only work with bifurcating tree");
140+
// if (id > 4)
141+
// outError(__func__, " only work with bifurcating tree");
138142
}
139143

140-
ASSERT(id == 4);
144+
ASSERT(id == right_taxa.size());
141145

142146
// 2018-12-11: remove root taxon from taxa for rooted tree
143147
if (rooted) {
144-
for (auto it = taxa.begin(); it != taxa.end(); it++)
148+
vector<IntVector>::iterator it;
149+
for (it = left_taxa.begin(); it != left_taxa.end(); it++)
150+
for (auto it2 = it->begin(); it2 != it->end(); it2++)
151+
if (*it2 == leafNum-1) {
152+
it->erase(it2);
153+
break;
154+
}
155+
for (it = right_taxa.begin(); it != right_taxa.end(); it++)
145156
for (auto it2 = it->begin(); it2 != it->end(); it2++)
146157
if (*it2 == leafNum-1) {
147158
it->erase(it2);
@@ -173,31 +184,54 @@ void PhyloTree::computeSiteConcordance(Branch &branch, int nquartets, int *rstre
173184
name_map[(*part_aln)->getSeqName(i)] = i;
174185

175186
// check that at least one taxon from each subtree is present in partition tree
176-
for (auto it = taxa.begin(); it != taxa.end(); it++) {
177-
bool present = false;
187+
vector<IntVector>::iterator it;
188+
int left_count = 0, right_count = 0;
189+
for (it = left_taxa.begin(); it != left_taxa.end(); it++) {
178190
for (auto it2 = it->begin(); it2 != it->end(); it2++) {
179191
if (name_map.find(taxname[*it2]) != name_map.end()) {
180-
present = true;
192+
left_count++;
181193
break;
182194
}
183195
}
184-
if (!present) {
185-
// not decisive
186-
support[part*3+3] = support[part*3+4] = support[part*3+5] = -1;
187-
break;
196+
}
197+
for (it = right_taxa.begin(); it != right_taxa.end(); it++) {
198+
for (auto it2 = it->begin(); it2 != it->end(); it2++) {
199+
if (name_map.find(taxname[*it2]) != name_map.end()) {
200+
right_count++;
201+
break;
202+
}
188203
}
189204
}
205+
if (left_count < 2 || right_count < 2) {
206+
// not decisive
207+
support[part*3+3] = support[part*3+4] = support[part*3+5] = -1;
208+
break;
209+
}
190210
}
191211
}
192212
Neighbor *nei = branch.second->findNeighbor(branch.first);
193213
for (i = 0; i < nquartets; i++) {
194-
int j;
195214
// get a random quartet
196215
IntVector quartet;
197-
quartet.resize(taxa.size());
198-
for (j = 0; j < taxa.size(); j++) {
199-
quartet[j] = taxa[j][random_int(taxa[j].size(), rstream)];
216+
quartet.resize(4);
217+
int left_id0 = 0, left_id1 = 1, right_id0 = 0, right_id1 = 1;
218+
if (left_taxa.size() > 2) {
219+
left_id0 = random_int(left_taxa.size(), rstream);
220+
do {
221+
left_id1 = random_int(left_taxa.size(), rstream);
222+
} while (left_id0 == left_id1);
200223
}
224+
if (right_taxa.size() > 2) {
225+
right_id0 = random_int(right_taxa.size(), rstream);
226+
do {
227+
right_id1 = random_int(right_taxa.size(), rstream);
228+
} while (right_id0 == right_id1);
229+
}
230+
quartet[0] = left_taxa[left_id0][random_int(left_taxa[left_id0].size(), rstream)];
231+
quartet[1] = left_taxa[left_id1][random_int(left_taxa[left_id1].size(), rstream)];
232+
quartet[2] = right_taxa[right_id0][random_int(right_taxa[right_id0].size(), rstream)];
233+
quartet[3] = right_taxa[right_id1][random_int(right_taxa[right_id1].size(), rstream)];
234+
201235
support[0] = support[1] = support[2] = 0;
202236
aln->computeQuartetSupports(quartet, support);
203237
size_t sum = support[0] + support[1] + support[2];

0 commit comments

Comments
 (0)