@@ -111,37 +111,48 @@ void SuperAlignment::computeQuartetSupports(IntVector &quartet, vector<int64_t>
111111}
112112
113113void 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